17#ifndef FLATBUFFERS_UTIL_H_
18#define FLATBUFFERS_UTIL_H_
26#ifndef FLATBUFFERS_PREFER_PRINTF
48 return static_cast<unsigned int>(x - a) <=
static_cast<unsigned int>(b - a);
64 return ((c & 0xDF) == (alpha & 0xDF));
83 return static_cast<char>(::toupper(
static_cast<unsigned char>(c)));
87 return static_cast<char>(::tolower(
static_cast<unsigned char>(c)));
92#ifdef FLATBUFFERS_PREFER_PRINTF
93template<
typename T>
size_t IntToDigitCount(T t) {
94 size_t digit_count = 0;
96 if (t < 0) digit_count++;
98 if (-1 < t && t < 1) digit_count++;
100 T eps = std::numeric_limits<T>::epsilon();
101 while (t <= (-1 + eps) || (1 - eps) <= t) {
108template<
typename T>
size_t NumToStringWidth(T t,
int precision = 0) {
109 size_t string_width = IntToDigitCount(t);
111 if (precision) string_width += (precision + 1);
116std::string NumToStringImplWrapper(T t,
const char *fmt,
int precision = 0) {
117 size_t string_width = NumToStringWidth(t, precision);
118 std::string
s(string_width, 0x00);
120 snprintf(
const_cast<char *
>(
s.data()), (
s.size() + 1), fmt, string_width, t);
131 #ifndef FLATBUFFERS_PREFER_PRINTF
132 std::stringstream ss;
136 auto v =
static_cast<long long>(t);
137 return NumToStringImplWrapper(v,
"%.*lld");
156 #ifndef FLATBUFFERS_PREFER_PRINTF
159 std::stringstream ss;
163 ss << std::setprecision(precision);
167 auto v =
static_cast<double>(t);
168 auto s = NumToStringImplWrapper(v,
"%0.*f", precision);
172 auto p = s.find_last_not_of(
'0');
173 if (
p != std::string::npos) {
175 s.resize(
p + (s[
p] ==
'.' ? 2 : 1));
194 #ifndef FLATBUFFERS_PREFER_PRINTF
195 std::stringstream ss;
196 ss << std::setw(xdigits) << std::setfill(
'0') << std::hex << std::uppercase
200 return NumToStringImplWrapper(i,
"%.*X", xdigits);
207#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && (FLATBUFFERS_LOCALE_INDEPENDENT > 0)
208 class ClassicLocale {
210 typedef _locale_t locale_type;
212 typedef locale_t locale_type;
217 static ClassicLocale instance_;
219 static locale_type Get() {
return instance_.locale_; }
223 #define __strtoull_impl(s, pe, b) _strtoui64_l(s, pe, b, ClassicLocale::Get())
224 #define __strtoll_impl(s, pe, b) _strtoi64_l(s, pe, b, ClassicLocale::Get())
225 #define __strtod_impl(s, pe) _strtod_l(s, pe, ClassicLocale::Get())
226 #define __strtof_impl(s, pe) _strtof_l(s, pe, ClassicLocale::Get())
228 #define __strtoull_impl(s, pe, b) strtoull_l(s, pe, b, ClassicLocale::Get())
229 #define __strtoll_impl(s, pe, b) strtoll_l(s, pe, b, ClassicLocale::Get())
230 #define __strtod_impl(s, pe) strtod_l(s, pe, ClassicLocale::Get())
231 #define __strtof_impl(s, pe) strtof_l(s, pe, ClassicLocale::Get())
234 #define __strtod_impl(s, pe) strtod(s, pe)
235 #define __strtof_impl(s, pe) static_cast<float>(strtod(s, pe))
237 #define __strtoull_impl(s, pe, b) _strtoui64(s, pe, b)
238 #define __strtoll_impl(s, pe, b) _strtoi64(s, pe, b)
240 #define __strtoull_impl(s, pe, b) strtoull(s, pe, b)
241 #define __strtoll_impl(s, pe, b) strtoll(s, pe, b)
260FLATBUFFERS_SUPPRESS_UBSAN(
"float-cast-overflow")
264#undef __strtoull_impl
285 const bool check_errno =
true) {
296 if (check_errno) errno = 0;
299 if ((*endptr !=
'\0') || (endptr == str)) {
304 if (check_errno && errno)
return false;
315 auto done = (end != str) && (*end ==
'\0');
317 if (done && std::isnan(*val)) { *val = std::numeric_limits<T>::quiet_NaN(); }
330 static_assert(
sizeof(T) <
sizeof(int64_t),
"unexpected type T");
338 *val =
static_cast<T
>(max);
347 *val =
static_cast<T
>(i64);
369 s = (s > str) ? (s - 1) : s;
399 return s ==
"nan" || s ==
"+nan" || s ==
"-nan";
403 return s ==
"inf" || s ==
"+inf" || s ==
"infinity" || s ==
"+infinity";
407 return s ==
"-inf" || s ==
"-infinity";
429bool LoadFile(
const char *name,
bool binary, std::string *buf);
436bool SaveFile(
const char *name,
const char *buf,
size_t len,
bool binary);
442inline bool SaveFile(
const char *name,
const std::string &buf,
bool binary) {
443 return SaveFile(name, buf.c_str(), buf.size(), binary);
467 const std::string &prefix_to_remove);
472 const std::string &filename);
488 const std::string &filepath);
494inline int ToUTF8(uint32_t ucc, std::string *out) {
497 for (
int i = 0; i < 6; i++) {
499 uint32_t max_bits = 6 + i * 5 +
static_cast<int>(!i);
500 if (ucc < (1u << max_bits)) {
502 uint32_t remain_bits = i * 6;
504 (*out) +=
static_cast<char>((0xFE << (max_bits - remain_bits)) |
505 (ucc >> remain_bits));
507 for (
int j = i - 1; j >= 0; j--) {
508 (*out) +=
static_cast<char>(((ucc >> (j * 6)) & 0x3F) | 0x80);
525 for (
int mask = 0x80; mask >= 0x04; mask >>= 1) {
532 if ((
static_cast<unsigned char>(**in) << len) & 0x80)
534 if (!len)
return *(*in)++;
536 if (len < 2 || len > 4) {
return -1; }
538 int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
539 for (
int i = 0; i < len - 1; i++) {
540 if ((**in & 0xC0) != 0x80)
return -1;
542 ucc |= *(*in)++ & 0x3F;
546 if (ucc >= 0xD800 && ucc <= 0xDFFF) {
return -1; }
551 if (ucc < 0x0080 || ucc > 0x07FF) {
return -1; }
555 if (ucc < 0x0800 || ucc > 0xFFFF) {
return -1; }
559 if (ucc < 0x10000 || ucc > 0x10FFFF) {
return -1; }
565#ifndef FLATBUFFERS_PREFER_PRINTF
570inline std::string
WordWrap(
const std::string in,
size_t max_length,
571 const std::string wrapped_line_prefix,
572 const std::string wrapped_line_suffix) {
573 std::istringstream in_stream(in);
574 std::string wrapped, line, word;
579 while (in_stream >> word) {
580 if ((line.length() + 1 + word.length() + wrapped_line_suffix.length()) <
584 wrapped += line + wrapped_line_suffix +
"\n";
585 line = wrapped_line_prefix + word;
594inline bool EscapeString(
const char *s,
size_t length, std::string *_text,
595 bool allow_non_utf8,
bool natural_utf8) {
596 std::string &text = *_text;
598 for (uoffset_t i = 0; i < length; i++) {
601 case '\n': text +=
"\\n";
break;
602 case '\t': text +=
"\\t";
break;
603 case '\r': text +=
"\\r";
break;
604 case '\b': text +=
"\\b";
break;
605 case '\f': text +=
"\\f";
break;
606 case '\"': text +=
"\\\"";
break;
607 case '\\': text +=
"\\\\";
break;
609 if (c >=
' ' && c <=
'~') {
613 const char *utf8 = s + i;
616 if (allow_non_utf8) {
637 text.append(s + i,
static_cast<size_t>(utf8 - s - i));
638 }
else if (ucc <= 0xFFFF) {
642 }
else if (ucc <= 0x10FFFF) {
645 uint32_t base = ucc - 0x10000;
646 auto high_surrogate = (base >> 10) + 0xD800;
647 auto low_surrogate = (base & 0x03FF) + 0xDC00;
654 i =
static_cast<uoffset_t
>(utf8 - s - 1);
666 const std::string &wrapped_line_prefix,
667 const std::string &wrapped_line_suffix) {
668 std::string text = wrapped_line_prefix;
669 size_t start_offset = 0;
670 const char *s =
reinterpret_cast<const char *
>(buffer);
671 for (
size_t i = 0; s && i < buffer_size; i++) {
673 bool have_more = i + 1 < buffer_size;
676 if (have_more) { text +=
','; }
679 text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
680 text += wrapped_line_suffix;
682 start_offset = text.size();
683 text += wrapped_line_prefix;
686 text += wrapped_line_suffix;
697 std::string *_value =
nullptr);
701 std::string *_value =
nullptr);
#define FLATBUFFERS_ASSERT
bool StringToNumber< int64_t >(const char *str, int64_t *val)
std::string StripFileName(const std::string &filepath)
LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function)
int ToUTF8(uint32_t ucc, std::string *out)
std::string GetExtension(const std::string &filepath)
bool SaveFile(const char *name, const char *buf, size_t len, bool binary)
FLATBUFFERS_CONSTEXPR char kPathSeparator
bool check_ascii_range(char x, char a, char b)
std::string ConvertCase(const std::string &input, Case output_case, Case input_case=Case::kSnake)
std::string StripPath(const std::string &filepath)
std::string NumToString(T t)
bool(* FileExistsFunction)(const char *filename)
bool StringToIntegerImpl(T *val, const char *const str, const int base=0, const bool check_errno=true)
std::string IntToStringHex(int i, int xdigits)
std::string NumToString< double >(double t)
int64_t StringToInt(const char *s, int base=10)
std::string AbsolutePath(const std::string &filepath)
bool StringIsFlatbufferNan(const std::string &s)
std::string BufferToHexText(const void *buffer, size_t buffer_size, size_t max_length, const std::string &wrapped_line_prefix, const std::string &wrapped_line_suffix)
std::string NumToString< float >(float t)
bool EscapeString(const char *s, size_t length, std::string *_text, bool allow_non_utf8, bool natural_utf8)
std::string NumToString< signed char >(signed char t)
std::string WordWrap(const std::string in, size_t max_length, const std::string wrapped_line_prefix, const std::string wrapped_line_suffix)
bool StringToNumber< uint64_t >(const char *str, uint64_t *val)
std::string StripPrefix(const std::string &filepath, const std::string &prefix_to_remove)
std::string ConCatPathFileName(const std::string &path, const std::string &filename)
std::string NumToString< char >(char t)
bool FileExists(const char *name)
bool StringIsFlatbufferPositiveInfinity(const std::string &s)
std::string RelativeToRootPath(const std::string &project, const std::string &filepath)
bool StringIsFlatbufferNegativeInfinity(const std::string &s)
bool DirExists(const char *name)
bool StringToNumber(const char *s, T *val)
std::string NumToString< unsigned char >(unsigned char t)
std::string RemoveStringQuotes(const std::string &s)
FileExistsFunction SetFileExistsFunction(FileExistsFunction file_exists_function)
int FromUTF8(const char **in)
bool StringToFloatImpl(T *val, const char *const str)
bool(* LoadFileFunction)(const char *filename, bool binary, std::string *dest)
bool is_alpha_char(char c, char alpha)
std::string StripExtension(const std::string &filepath)
uint64_t StringToUInt(const char *s, int base=10)
bool LoadFile(const char *name, bool binary, std::string *buf)
std::string FloatToString(T t, int precision)
std::string PosixPath(const char *path)
void strtoval_impl(int64_t *val, const char *str, char **endptr, int base)
bool is_alpha_upper(char c)
void EnsureDirExists(const std::string &filepath)
bool ReadEnvironmentVariable(const char *var_name, std::string *_value=nullptr)
bool SetGlobalTestLocale(const char *locale_name, std::string *_value=nullptr)
#define __strtoll_impl(s, pe, b)
#define __strtoull_impl(s, pe, b)
#define __strtod_impl(s, pe)
#define __strtof_impl(s, pe)