17 #ifndef FLATBUFFERS_UTIL_H_ 18 #define FLATBUFFERS_UTIL_H_ 25 #ifndef FLATBUFFERS_PREFER_PRINTF 27 #else // FLATBUFFERS_PREFER_PRINTF 30 #endif // FLATBUFFERS_PREFER_PRINTF 33 # ifndef WIN32_LEAN_AND_MEAN 34 # define WIN32_LEAN_AND_MEAN 42 # undef interface // This is also important because of reasons 47 #include <sys/types.h> 53 #ifdef FLATBUFFERS_PREFER_PRINTF 54 template<
typename T>
size_t IntToDigitCount(T t) {
55 size_t digit_count = 0;
57 if (t < 0) digit_count++;
59 if (-1 < t && t < 1) digit_count++;
61 T eps = std::numeric_limits<float>::epsilon();
62 while (t <= (-1 + eps) || (1 - eps) <= t) {
69 template<
typename T>
size_t NumToStringWidth(T t,
int precision = 0) {
70 size_t string_width = IntToDigitCount(t);
72 if (precision) string_width += (precision + 1);
76 template<
typename T> std::string NumToStringImplWrapper(T t,
const char* fmt,
78 size_t string_width = NumToStringWidth(t, precision);
79 std::string s(string_width, 0x00);
81 snprintf(const_cast<char*>(s.data()), (s.size()+1), fmt, precision, t);
84 #endif // FLATBUFFERS_PREFER_PRINTF 91 #ifndef FLATBUFFERS_PREFER_PRINTF 95 #else // FLATBUFFERS_PREFER_PRINTF 96 auto v =
static_cast<long long>(t);
97 return NumToStringImplWrapper(v,
"%.*lld");
98 #endif // FLATBUFFERS_PREFER_PRINTF 108 #if defined(FLATBUFFERS_CPP98_STL) 109 template<>
inline std::string NumToString<long long>(
long long t) {
111 snprintf(buf,
sizeof(buf),
"%lld", t);
112 return std::string(buf);
116 inline std::string NumToString<unsigned long long>(
unsigned long long t) {
118 snprintf(buf,
sizeof(buf),
"%llu", t);
119 return std::string(buf);
121 #endif // defined(FLATBUFFERS_CPP98_STL) 126 #ifndef FLATBUFFERS_PREFER_PRINTF 129 std::stringstream ss;
133 ss << std::setprecision(precision);
136 #else // FLATBUFFERS_PREFER_PRINTF 137 auto v =
static_cast<double>(t);
138 auto s = NumToStringImplWrapper(v,
"%0.*f", precision);
139 #endif // FLATBUFFERS_PREFER_PRINTF 142 auto p = s.find_last_not_of(
'0');
143 if (p != std::string::npos) {
145 s.resize(p + (s[p] ==
'.' ? 2 : 1));
162 #ifndef FLATBUFFERS_PREFER_PRINTF 163 std::stringstream ss;
164 ss << std::setw(xdigits) << std::setfill(
'0') << std::hex << std::uppercase
167 #else // FLATBUFFERS_PREFER_PRINTF 168 return NumToStringImplWrapper(i,
"%.*X", xdigits);
169 #endif // FLATBUFFERS_PREFER_PRINTF 174 inline int64_t
StringToInt(
const char *str,
char **endptr =
nullptr,
178 return _strtoi64(str, endptr, base);
180 return strtoll(str, endptr, base);
190 return _strtoui64(str, endptr, base);
192 return strtoull(str, endptr, base);
216 bool LoadFile(
const char *name,
bool binary, std::string *buf);
223 inline bool SaveFile(
const char *name,
const char *buf,
size_t len,
225 std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out);
226 if (!ofs.is_open())
return false;
235 inline bool SaveFile(
const char *name,
const std::string &buf,
bool binary) {
236 return SaveFile(name, buf.c_str(), buf.size(), binary);
256 size_t i = filepath.find_last_of(
".");
257 return i != std::string::npos ? filepath.substr(0, i) : filepath;
262 size_t i = filepath.find_last_of(
".");
263 return i != std::string::npos ? filepath.substr(i + 1) :
"";
267 inline std::string
StripPath(
const std::string &filepath) {
268 size_t i = filepath.find_last_of(PathSeparatorSet);
269 return i != std::string::npos ? filepath.substr(i + 1) : filepath;
274 size_t i = filepath.find_last_of(PathSeparatorSet);
275 return i != std::string::npos ? filepath.substr(0, i) :
"";
281 const std::string &filename) {
282 std::string filepath = path;
283 if (filepath.length()) {
284 char &filepath_last_character =
string_back(filepath);
285 if (filepath_last_character == kPathSeparatorWindows) {
287 }
else if (filepath_last_character != kPathSeparator) {
291 filepath += filename;
293 if (filepath[0] ==
'.' && filepath[1] == kPathSeparator) {
294 filepath.erase(0, 2);
301 std::string p = path;
302 std::replace(p.begin(), p.end(),
'\\',
'/');
313 (void)_mkdir(filepath.c_str());
315 mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP);
324 #ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION 328 char abs_path[MAX_PATH];
329 return GetFullPathNameA(filepath.c_str(), MAX_PATH, abs_path,
nullptr)
331 char abs_path[PATH_MAX];
332 return realpath(filepath.c_str(), abs_path)
336 #endif // FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION 344 inline int ToUTF8(uint32_t ucc, std::string *out) {
347 for (
int i = 0; i < 6; i++) {
349 uint32_t max_bits = 6 + i * 5 +
static_cast<int>(!i);
350 if (ucc < (1u << max_bits)) {
352 uint32_t remain_bits = i * 6;
354 (*out) +=
static_cast<char>((0xFE << (max_bits - remain_bits)) |
355 (ucc >> remain_bits));
357 for (
int j = i - 1; j >= 0; j--) {
358 (*out) +=
static_cast<char>(((ucc >> (j * 6)) & 0x3F) | 0x80);
375 for (
int mask = 0x80; mask >= 0x04; mask >>= 1) {
382 if ((static_cast<unsigned char>(**in) << len) & 0x80)
return -1;
383 if (!len)
return *(*in)++;
385 if (len < 2 || len > 4) {
return -1; }
387 int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
388 for (
int i = 0; i < len - 1; i++) {
389 if ((**in & 0xC0) != 0x80)
return -1;
391 ucc |= *(*in)++ & 0x3F;
395 if (ucc >= 0xD800 && ucc <= 0xDFFF) {
return -1; }
400 if (ucc < 0x0080 || ucc > 0x07FF) {
return -1; }
404 if (ucc < 0x0800 || ucc > 0xFFFF) {
return -1; }
408 if (ucc < 0x10000 || ucc > 0x10FFFF) {
return -1; }
414 #ifndef FLATBUFFERS_PREFER_PRINTF 419 inline std::string
WordWrap(
const std::string in,
size_t max_length,
420 const std::string wrapped_line_prefix,
421 const std::string wrapped_line_suffix) {
422 std::istringstream in_stream(in);
423 std::string wrapped, line, word;
428 while (in_stream >> word) {
429 if ((line.length() + 1 + word.length() + wrapped_line_suffix.length()) <
433 wrapped += line + wrapped_line_suffix +
"\n";
434 line = wrapped_line_prefix + word;
441 #endif // !FLATBUFFERS_PREFER_PRINTF 443 inline bool EscapeString(
const char *s,
size_t length, std::string *_text,
444 bool allow_non_utf8,
bool natural_utf8) {
445 std::string &text = *_text;
447 for (uoffset_t i = 0; i < length; i++) {
450 case '\n': text +=
"\\n";
break;
451 case '\t': text +=
"\\t";
break;
452 case '\r': text +=
"\\r";
break;
453 case '\b': text +=
"\\b";
break;
454 case '\f': text +=
"\\f";
break;
455 case '\"': text +=
"\\\"";
break;
456 case '\\': text +=
"\\\\";
break;
458 if (c >=
' ' && c <=
'~') {
462 const char *utf8 = s + i;
465 if (allow_non_utf8) {
486 text.append(s + i, static_cast<size_t>(utf8 - s - i));
487 }
else if (ucc <= 0xFFFF) {
491 }
else if (ucc <= 0x10FFFF) {
494 uint32_t base = ucc - 0x10000;
495 auto high_surrogate = (base >> 10) + 0xD800;
496 auto low_surrogate = (base & 0x03FF) + 0xDC00;
503 i =
static_cast<uoffset_t
>(utf8 - s - 1);
515 #endif // FLATBUFFERS_UTIL_H_ std::string IntToStringHex(int i, int xdigits)
std::string AbsolutePath(const std::string &filepath)
bool(* FileExistsFunction)(const char *filename)
static const char kPathSeparatorWindows
bool FileExists(const char *name)
bool DirExists(const char *name)
std::string NumToString< signed char >(signed char t)
static const char kPathSeparator
uint64_t StringToUInt(const char *str, char **endptr=nullptr, int base=10)
bool LoadFile(const char *name, bool binary, std::string *buf)
bool(* LoadFileFunction)(const char *filename, bool binary, std::string *dest)
std::string GetExtension(const std::string &filepath)
bool EscapeString(const char *s, size_t length, std::string *_text, bool allow_non_utf8, bool natural_utf8)
std::string ConCatPathFileName(const std::string &path, const std::string &filename)
std::string PosixPath(const char *path)
static const char * PathSeparatorSet
LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function)
std::string WordWrap(const std::string in, size_t max_length, const std::string wrapped_line_prefix, const std::string wrapped_line_suffix)
void EnsureDirExists(const std::string &filepath)
#define FLATBUFFERS_ASSERT
FileExistsFunction SetFileExistsFunction(FileExistsFunction file_exists_function)
Simple class for manipulating paths on Linux/Windows/Mac OS.
int FromUTF8(const char **in)
std::string NumToString(T t)
std::string NumToString< unsigned char >(unsigned char t)
std::string NumToString< float >(float t)
std::string StripPath(const std::string &filepath)
int64_t StringToInt(const char *str, char **endptr=nullptr, int base=10)
char & string_back(std::string &value)
std::string FloatToString(T t, int precision)
std::string NumToString< double >(double t)
std::string StripExtension(const std::string &filepath)
std::string StripFileName(const std::string &filepath)
int ToUTF8(uint32_t ucc, std::string *out)
bool SaveFile(const char *name, const char *buf, size_t len, bool binary)