1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// from google3/strings/strutil.cc 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h> 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <errno.h> 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <float.h> // FLT_DIG and DBL_DIG 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <limits> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <limits.h> 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <stdio.h> 39d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <iterator> 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _WIN32 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// MSVC has only _snprintf, not snprintf. 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// MinGW has both snprintf and _snprintf, but they appear to be different 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// functions. The former is buggy. When invoked like so: 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// char buffer[32]; 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f); 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// it prints "1.23000e+10". This is plainly wrong: %g should never print 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// trailing zeros after the decimal point. For some reason this bug only 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// occurs with some input values, not all. In any case, _snprintf does the 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// right thing, so we use it. 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define snprintf _snprintf 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool IsNaN(double value) { 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // NaN is never equal to anything, even itself. 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return value != value; 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// These are defined as macros on some platforms. #undef them so that we can 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// redefine them. 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef isxdigit 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef isprint 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// The definitions of these in ctype.h change based on locale. Since our 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// string manipulation is all in relation to the protocol buffer and C++ 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// languages, we always want to use the C locale. So, we re-define these 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// exactly as we want them. 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool isxdigit(char c) { 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return ('0' <= c && c <= '9') || 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ('a' <= c && c <= 'f') || 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ('A' <= c && c <= 'F'); 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline bool isprint(char c) { 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return c >= 0x20 && c <= 0x7E; 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// StripString 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Replaces any occurrence of the character 'remove' (or the characters 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in 'remove') with the character 'replacewith'. 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid StripString(string* s, const char* remove, char replacewith) { 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char * str_start = s->c_str(); 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char * str = str_start; 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (str = strpbrk(str, remove); 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville str != NULL; 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville str = strpbrk(str + 1, remove)) { 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (*s)[str - str_start] = replacewith; 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// StringReplace() 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Replace the "old" pattern with the "new" pattern in a string, 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// and append the result to "res". If replace_all is false, 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// it only replaces the first instance of "old." 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid StringReplace(const string& s, const string& oldsub, 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& newsub, bool replace_all, 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* res) { 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (oldsub.empty()) { 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville res->append(s); // if empty, append the given string. 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string::size_type start_pos = 0; 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string::size_type pos; 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville pos = s.find(oldsub, start_pos); 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (pos == string::npos) { 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville res->append(s, start_pos, pos - start_pos); 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville res->append(newsub); 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville start_pos = pos + oldsub.size(); // start searching again after the "old" 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } while (replace_all); 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville res->append(s, start_pos, s.length() - start_pos); 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// StringReplace() 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Give me a string and two patterns "old" and "new", and I replace 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the first instance of "old" in the string with "new", if it 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// exists. If "global" is true; call this repeatedly until it 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// fails. RETURN a new string, regardless of whether the replacement 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// happened or not. 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring StringReplace(const string& s, const string& oldsub, 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& newsub, bool replace_all) { 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string ret; 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville StringReplace(s, oldsub, newsub, replace_all, &ret); 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return ret; 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SplitStringUsing() 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Split a string using a character delimiter. Append the components 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to 'result'. 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Note: For multi-character delimiters, this routine will split on *ANY* of 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the characters in the string, not the entire string as a single delimiter. 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate <typename ITR> 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic inline 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid SplitStringToIteratorUsing(const string& full, 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* delim, 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ITR& result) { 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Optimize the common case where delim is a single character. 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (delim[0] != '\0' && delim[1] == '\0') { 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char c = delim[0]; 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* p = full.data(); 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* end = p + full.size(); 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (p != end) { 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (*p == c) { 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++p; 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* start = p; 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (++p != end && *p != c); 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *result++ = string(start, p - start); 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string::size_type begin_index, end_index; 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville begin_index = full.find_first_not_of(delim); 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (begin_index != string::npos) { 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville end_index = full.find_first_of(delim, begin_index); 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (end_index == string::npos) { 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *result++ = full.substr(begin_index); 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *result++ = full.substr(begin_index, (end_index - begin_index)); 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville begin_index = full.find_first_not_of(delim, end_index); 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid SplitStringUsing(const string& full, 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* delim, 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string>* result) { 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville back_insert_iterator< vector<string> > it(*result); 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SplitStringToIteratorUsing(full, delim, it); 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// JoinStrings() 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This merges a vector of string components with delim inserted 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// as separaters between components. 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate <class ITERATOR> 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic void JoinStringsIterator(const ITERATOR& start, 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const ITERATOR& end, 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* delim, 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* result) { 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(result != NULL); 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->clear(); 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int delim_length = strlen(delim); 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Precompute resulting length so we can reserve() memory in one shot. 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int length = 0; 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (ITERATOR iter = start; iter != end; ++iter) { 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (iter != start) { 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville length += delim_length; 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville length += iter->size(); 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->reserve(length); 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Now combine everything. 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (ITERATOR iter = start; iter != end; ++iter) { 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (iter != start) { 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->append(delim, delim_length); 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->append(iter->data(), iter->size()); 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid JoinStrings(const vector<string>& components, 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* delim, 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string * result) { 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville JoinStringsIterator(components.begin(), components.end(), delim, result); 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// UnescapeCEscapeSequences() 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This does all the unescaping that C does: \ooo, \r, \n, etc 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns length of resulting string. 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// The implementation of \x parses any positive number of hex digits, 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// but it is an error if the value requires more than 8 bits, and the 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// result is truncated to 8 bits. 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// The second call stores its errors in a supplied string vector. 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// If the string vector pointer is NULL, it reports the errors with LOG(). 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7')) 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline int hex_digit_to_int(char c) { 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /* Assume ASCII. */ 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61); 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville assert(isxdigit(c)); 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int x = static_cast<unsigned char>(c); 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (x > '9') { 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville x += 9; 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return x & 0xf; 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol buffers doesn't ever care about errors, but I don't want to remove 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the code. 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false) 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint UnescapeCEscapeSequences(const char* source, char* dest) { 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return UnescapeCEscapeSequences(source, dest, NULL); 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint UnescapeCEscapeSequences(const char* source, char* dest, 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string> *errors) { 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(errors == NULL) << "Error reporting not implemented."; 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char* d = dest; 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* p = source; 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Small optimization for case where source = dest and there's no escaping 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while ( p == d && *p != '\0' && *p != '\\' ) 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville p++, d++; 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (*p != '\0') { 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (*p != '\\') { 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *d++ = *p++; 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch ( *++p ) { // skip past the '\\' 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '\0': 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOG_STRING(ERROR, errors) << "String cannot end with \\"; 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *d = '\0'; 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return d - dest; // we're done with p 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 'a': *d++ = '\a'; break; 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 'b': *d++ = '\b'; break; 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 'f': *d++ = '\f'; break; 288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 'n': *d++ = '\n'; break; 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 'r': *d++ = '\r'; break; 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 't': *d++ = '\t'; break; 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 'v': *d++ = '\v'; break; 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '\\': *d++ = '\\'; break; 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '?': *d++ = '\?'; break; // \? Who knew? 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '\'': *d++ = '\''; break; 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '"': *d++ = '\"'; break; 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '0': case '1': case '2': case '3': // octal digit: 1 to 3 digits 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '4': case '5': case '6': case '7': { 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char ch = *p - '0'; 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if ( IS_OCTAL_DIGIT(p[1]) ) 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ch = ch * 8 + *++p - '0'; 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if ( IS_OCTAL_DIGIT(p[1]) ) // safe (and easy) to do this twice 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ch = ch * 8 + *++p - '0'; // now points at last digit 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *d++ = ch; 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 'x': case 'X': { 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!isxdigit(p[1])) { 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (p[1] == '\0') { 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOG_STRING(ERROR, errors) << "String cannot end with \\x"; 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOG_STRING(ERROR, errors) << 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\\x cannot be followed by non-hex digit: \\" << *p << p[1]; 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned int ch = 0; 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char *hex_start = p; 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (isxdigit(p[1])) // arbitrarily many hex digits 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ch = (ch << 4) + hex_digit_to_int(*++p); 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (ch > 0xFF) 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOG_STRING(ERROR, errors) << "Value of " << 322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits"; 323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *d++ = ch; 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if 0 // TODO(kenton): Support \u and \U? Requires runetochar(). 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 'u': { 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // \uhhhh => convert 4 hex digits to UTF-8 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char32 rune = 0; 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char *hex_start = p; 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < 4; ++i) { 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (isxdigit(p[1])) { // Look one char ahead. 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville rune = (rune << 4) + hex_digit_to_int(*++p); // Advance p. 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOG_STRING(ERROR, errors) 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "\\u must be followed by 4 hex digits: \\" 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << string(hex_start, p+1-hex_start); 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville d += runetochar(d, &rune); 342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case 'U': { 345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // \Uhhhhhhhh => convert 8 hex digits to UTF-8 346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char32 rune = 0; 347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char *hex_start = p; 348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < 8; ++i) { 349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (isxdigit(p[1])) { // Look one char ahead. 350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Don't change rune until we're sure this 351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // is within the Unicode limit, but do advance p. 352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char32 newrune = (rune << 4) + hex_digit_to_int(*++p); 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (newrune > 0x10FFFF) { 354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOG_STRING(ERROR, errors) 355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "Value of \\" 356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << string(hex_start, p + 1 - hex_start) 357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << " exceeds Unicode limit (0x10FFFF)"; 358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville rune = newrune; 361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOG_STRING(ERROR, errors) 364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "\\U must be followed by 8 hex digits: \\" 365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << string(hex_start, p+1-hex_start); 366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville d += runetochar(d, &rune); 370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: 374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOG_STRING(ERROR, errors) << "Unknown escape sequence: \\" << *p; 375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville p++; // read past letter we escaped 377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *d = '\0'; 380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return d - dest; 381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// UnescapeCEscapeString() 385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This does the same thing as UnescapeCEscapeSequences, but creates 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// a new string. The caller does not need to worry about allocating 387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// a dest buffer. This should be used for non performance critical 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// tasks such as printing debug messages. It is safe for src and dest 389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to be the same. 390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// The second call stores its errors in a supplied string vector. 392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// If the string vector pointer is NULL, it reports the errors with LOG(). 393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// In the first and second calls, the length of dest is returned. In the 395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the third call, the new string is returned. 396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint UnescapeCEscapeString(const string& src, string* dest) { 398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return UnescapeCEscapeString(src, dest, NULL); 399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint UnescapeCEscapeString(const string& src, string* dest, 402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string> *errors) { 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scoped_array<char> unescaped(new char[src.size() + 1]); 404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors); 405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(dest); 406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dest->assign(unescaped.get(), len); 407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return len; 408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring UnescapeCEscapeString(const string& src) { 411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scoped_array<char> unescaped(new char[src.size() + 1]); 412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), NULL); 413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return string(unescaped.get(), len); 414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// CEscapeString() 418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// CHexEscapeString() 419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copies 'src' to 'dest', escaping dangerous characters using 420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// C-style escape sequences. This is very useful for preparing query 421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// flags. 'src' and 'dest' should not overlap. The 'Hex' version uses 422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// hexadecimal rather than octal sequences. 423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the number of bytes written to 'dest' (not including the \0) 424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// or -1 if there was insufficient space. 425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. 427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 428d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleint CEscapeInternal(const char* src, int src_len, char* dest, 429d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int dest_len, bool use_hex, bool utf8_safe) { 430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* src_end = src + src_len; 431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int used = 0; 432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool last_hex_escape = false; // true if last output char was \xNN 433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (; src < src_end; src++) { 435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dest_len - used < 2) // Need space for two letter escape 436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return -1; 437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool is_hex_escape = false; 439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (*src) { 440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break; 441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break; 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '\t': dest[used++] = '\\'; dest[used++] = 't'; break; 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break; 444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '\'': dest[used++] = '\\'; dest[used++] = '\''; break; 445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break; 446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: 447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that if we emit \xNN and the src character after that is a hex 448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // digit then that digit must be escaped too to prevent it being 449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // interpreted as part of the character code by C. 450d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if ((!utf8_safe || static_cast<uint8>(*src) < 0x80) && 451d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (!isprint(*src) || 452d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville (last_hex_escape && isxdigit(*src)))) { 453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dest_len - used < 4) // need space for 4 letter escape 454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return -1; 455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"), 456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static_cast<uint8>(*src)); 457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville is_hex_escape = use_hex; 458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville used += 4; 459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dest[used++] = *src; break; 461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville last_hex_escape = is_hex_escape; 464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dest_len - used < 1) // make sure that there is room for \0 467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return -1; 468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dest[used] = '\0'; // doesn't count towards return value though 470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return used; 471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint CEscapeString(const char* src, int src_len, char* dest, int dest_len) { 474d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return CEscapeInternal(src, src_len, dest, dest_len, false, false); 475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// CEscape() 479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// CHexEscape() 480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copies 'src' to result, escaping dangerous characters using 481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// C-style escape sequences. This is very useful for preparing query 482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// flags. 'src' and 'dest' should not overlap. The 'Hex' version 483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// hexadecimal rather than octal sequences. 484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped. 486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring CEscape(const string& src) { 488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int dest_length = src.size() * 4 + 1; // Maximum possible expansion 489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scoped_array<char> dest(new char[dest_length]); 490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int len = CEscapeInternal(src.data(), src.size(), 491d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville dest.get(), dest_length, false, false); 492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK_GE(len, 0); 493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return string(dest.get(), len); 494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 496d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace strings { 497d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 498d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestring Utf8SafeCEscape(const string& src) { 499d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const int dest_length = src.size() * 4 + 1; // Maximum possible expansion 500d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville scoped_array<char> dest(new char[dest_length]); 501d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const int len = CEscapeInternal(src.data(), src.size(), 502d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville dest.get(), dest_length, false, true); 503d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_DCHECK_GE(len, 0); 504d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return string(dest.get(), len); 505d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 506d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 507d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestring CHexEscape(const string& src) { 508d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const int dest_length = src.size() * 4 + 1; // Maximum possible expansion 509d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville scoped_array<char> dest(new char[dest_length]); 510d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const int len = CEscapeInternal(src.data(), src.size(), 511d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville dest.get(), dest_length, true, false); 512d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_DCHECK_GE(len, 0); 513d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return string(dest.get(), len); 514d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 515d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 516d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} // namespace strings 517d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// strto32_adaptor() 520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// strtou32_adaptor() 521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Implementation of strto[u]l replacements that have identical 522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// overflow and underflow characteristics for both ILP-32 and LP-64 523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// platforms, including errno preservation in error-free calls. 524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint32 strto32_adaptor(const char *nptr, char **endptr, int base) { 527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int saved_errno = errno; 528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno = 0; 529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const long result = strtol(nptr, endptr, base); 530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (errno == ERANGE && result == LONG_MIN) { 531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return kint32min; 532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (errno == ERANGE && result == LONG_MAX) { 533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return kint32max; 534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (errno == 0 && result < kint32min) { 535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno = ERANGE; 536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return kint32min; 537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (errno == 0 && result > kint32max) { 538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno = ERANGE; 539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return kint32max; 540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (errno == 0) 542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno = saved_errno; 543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return static_cast<int32>(result); 544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleuint32 strtou32_adaptor(const char *nptr, char **endptr, int base) { 547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int saved_errno = errno; 548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno = 0; 549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const unsigned long result = strtoul(nptr, endptr, base); 550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (errno == ERANGE && result == ULONG_MAX) { 551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return kuint32max; 552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (errno == 0 && result > kuint32max) { 553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno = ERANGE; 554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return kuint32max; 555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (errno == 0) 557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno = saved_errno; 558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return static_cast<uint32>(result); 559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FastIntToBuffer() 563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FastInt64ToBuffer() 564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FastHexToBuffer() 565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FastHex64ToBuffer() 566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FastHex32ToBuffer() 567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Offset into buffer where FastInt64ToBuffer places the end of string 570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// null character. Also used by FastInt64ToBufferLeft. 571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kFastInt64ToBufferOffset = 21; 572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar *FastInt64ToBuffer(int64 i, char* buffer) { 574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We could collapse the positive and negative sections, but that 575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // would be slightly slower for positive numbers... 576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 22 bytes is enough to store -2**64, -18446744073709551616. 577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char* p = buffer + kFastInt64ToBufferOffset; 578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '\0'; 579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (i >= 0) { 580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { 581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + i % 10; 582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i /= 10; 583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } while (i > 0); 584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return p + 1; 585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // On different platforms, % and / have different behaviors for 587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // negative numbers, so we need to jump through hoops to make sure 588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we don't divide negative numbers. 589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (i > -10) { 590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i = -i; 591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + i; 592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p = '-'; 593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return p; 594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Make sure we aren't at MIN_INT, in which case we can't say i = -i 596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i = i + 10; 597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i = -i; 598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + i % 10; 599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Undo what we did a moment ago 600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i = i / 10 + 1; 601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { 602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + i % 10; 603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i /= 10; 604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } while (i > 0); 605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p = '-'; 606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return p; 607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Offset into buffer where FastInt32ToBuffer places the end of string 612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// null character. Also used by FastInt32ToBufferLeft 613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const int kFastInt32ToBufferOffset = 11; 614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Yes, this is a duplicate of FastInt64ToBuffer. But, we need this for the 616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// compiler to generate 32 bit arithmetic instructions. It's much faster, at 617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// least with 32 bit binaries. 618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar *FastInt32ToBuffer(int32 i, char* buffer) { 619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We could collapse the positive and negative sections, but that 620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // would be slightly slower for positive numbers... 621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 12 bytes is enough to store -2**32, -4294967296. 622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char* p = buffer + kFastInt32ToBufferOffset; 623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '\0'; 624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (i >= 0) { 625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { 626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + i % 10; 627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i /= 10; 628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } while (i > 0); 629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return p + 1; 630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // On different platforms, % and / have different behaviors for 632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // negative numbers, so we need to jump through hoops to make sure 633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we don't divide negative numbers. 634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (i > -10) { 635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i = -i; 636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + i; 637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p = '-'; 638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return p; 639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Make sure we aren't at MIN_INT, in which case we can't say i = -i 641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i = i + 10; 642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i = -i; 643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + i % 10; 644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Undo what we did a moment ago 645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i = i / 10 + 1; 646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { 647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + i % 10; 648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i /= 10; 649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } while (i > 0); 650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p = '-'; 651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return p; 652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar *FastHexToBuffer(int i, char* buffer) { 657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i; 658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const char *hexdigits = "0123456789abcdef"; 660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char *p = buffer + 21; 661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '\0'; 662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { 663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = hexdigits[i & 15]; // mod by 16 664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville i >>= 4; // divide by 16 665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } while (i > 0); 666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return p + 1; 667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) { 670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const char *hexdigits = "0123456789abcdef"; 671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[num_byte] = '\0'; 672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = num_byte - 1; i >= 0; i--) { 673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[i] = hexdigits[uint32(value) & 0xf]; 674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value >>= 4; 675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar *FastHex64ToBuffer(uint64 value, char* buffer) { 680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InternalFastHexToBuffer(value, buffer, 16); 681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar *FastHex32ToBuffer(uint32 value, char* buffer) { 684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InternalFastHexToBuffer(value, buffer, 8); 685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic inline char* PlaceNum(char* p, int num, char prev_sep) { 688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + num % 10; 689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = '0' + num / 10; 690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *p-- = prev_sep; 691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return p; 692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FastInt32ToBufferLeft() 696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FastUInt32ToBufferLeft() 697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FastInt64ToBufferLeft() 698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FastUInt64ToBufferLeft() 699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Like the Fast*ToBuffer() functions above, these are intended for speed. 701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Unlike the Fast*ToBuffer() functions, however, these functions write 702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// their output to the beginning of the buffer (hence the name, as the 703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// output is left-aligned). The caller is responsible for ensuring that 704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the buffer has enough space to hold the output. 705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns a pointer to the end of the string (i.e. the null character 707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// terminating the string). 708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic const char two_ASCII_digits[100][2] = { 711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'}, 712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'}, 713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'}, 714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'}, 715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'}, 716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'}, 717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'}, 718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'}, 719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'}, 720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'}, 721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'}, 722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'}, 723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'}, 724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'}, 725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'}, 726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'}, 727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'}, 728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'}, 729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'}, 730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'} 731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar* FastUInt32ToBufferLeft(uint32 u, char* buffer) { 734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int digits; 735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char *ASCII_digits = NULL; 736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The idea of this implementation is to trim the number of divides to as few 737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // as possible by using multiplication and subtraction rather than mod (%), 738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // and by outputting two digits at a time rather than one. 739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The huge-number case is first, in the hopes that the compiler will output 740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // that case in one branch-free block of code, and only output conditional 741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // branches into it from below. 742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u >= 1000000000) { // >= 1,000,000,000 743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 100000000; // 100,000,000 744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASCII_digits = two_ASCII_digits[digits]; 745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[0] = ASCII_digits[0]; 746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[1] = ASCII_digits[1]; 747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer += 2; 748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillesublt100_000_000: 749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u -= digits * 100000000; // 100,000,000 750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillelt100_000_000: 751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 1000000; // 1,000,000 752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASCII_digits = two_ASCII_digits[digits]; 753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[0] = ASCII_digits[0]; 754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[1] = ASCII_digits[1]; 755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer += 2; 756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillesublt1_000_000: 757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u -= digits * 1000000; // 1,000,000 758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillelt1_000_000: 759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 10000; // 10,000 760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASCII_digits = two_ASCII_digits[digits]; 761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[0] = ASCII_digits[0]; 762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[1] = ASCII_digits[1]; 763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer += 2; 764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillesublt10_000: 765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u -= digits * 10000; // 10,000 766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillelt10_000: 767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 100; 768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASCII_digits = two_ASCII_digits[digits]; 769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[0] = ASCII_digits[0]; 770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[1] = ASCII_digits[1]; 771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer += 2; 772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillesublt100: 773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u -= digits * 100; 774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillelt100: 775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u; 776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASCII_digits = two_ASCII_digits[digits]; 777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[0] = ASCII_digits[0]; 778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[1] = ASCII_digits[1]; 779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer += 2; 780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledone: 781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer = 0; 782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u < 100) { 786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u; 787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u >= 10) goto lt100; 788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer++ = '0' + digits; 789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville goto done; 790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u < 10000) { // 10,000 792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u >= 1000) goto lt10_000; 793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 100; 794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer++ = '0' + digits; 795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville goto sublt100; 796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u < 1000000) { // 1,000,000 798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u >= 100000) goto lt1_000_000; 799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 10000; // 10,000 800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer++ = '0' + digits; 801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville goto sublt10_000; 802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u < 100000000) { // 100,000,000 804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u >= 10000000) goto lt100_000_000; 805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 1000000; // 1,000,000 806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer++ = '0' + digits; 807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville goto sublt1_000_000; 808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we already know that u < 1,000,000,000 810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 100000000; // 100,000,000 811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer++ = '0' + digits; 812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville goto sublt100_000_000; 813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar* FastInt32ToBufferLeft(int32 i, char* buffer) { 816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint32 u = i; 817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (i < 0) { 818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer++ = '-'; 819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u = -i; 820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FastUInt32ToBufferLeft(u, buffer); 822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar* FastUInt64ToBufferLeft(uint64 u64, char* buffer) { 825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int digits; 826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char *ASCII_digits = NULL; 827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint32 u = static_cast<uint32>(u64); 829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (u == u64) return FastUInt32ToBufferLeft(u, buffer); 830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint64 top_11_digits = u64 / 1000000000; 832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer = FastUInt64ToBufferLeft(top_11_digits, buffer); 833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u = u64 - (top_11_digits * 1000000000); 834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 10000000; // 10,000,000 836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK_LT(digits, 100); 837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASCII_digits = two_ASCII_digits[digits]; 838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[0] = ASCII_digits[0]; 839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[1] = ASCII_digits[1]; 840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer += 2; 841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u -= digits * 10000000; // 10,000,000 842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 100000; // 100,000 843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASCII_digits = two_ASCII_digits[digits]; 844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[0] = ASCII_digits[0]; 845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[1] = ASCII_digits[1]; 846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer += 2; 847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u -= digits * 100000; // 100,000 848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 1000; // 1,000 849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASCII_digits = two_ASCII_digits[digits]; 850fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[0] = ASCII_digits[0]; 851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[1] = ASCII_digits[1]; 852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer += 2; 853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u -= digits * 1000; // 1,000 854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u / 10; 855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASCII_digits = two_ASCII_digits[digits]; 856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[0] = ASCII_digits[0]; 857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[1] = ASCII_digits[1]; 858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer += 2; 859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u -= digits * 10; 860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville digits = u; 861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer++ = '0' + digits; 862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer = 0; 863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar* FastInt64ToBufferLeft(int64 i, char* buffer) { 867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint64 u = i; 868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (i < 0) { 869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer++ = '-'; 870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville u = -i; 871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FastUInt64ToBufferLeft(u, buffer); 873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SimpleItoa() 877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Description: converts an integer to a string. 878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Return value: string 880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring SimpleItoa(int i) { 883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kFastToBufferSize]; 884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return (sizeof(i) == 4) ? 885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastInt32ToBuffer(i, buffer) : 886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastInt64ToBuffer(i, buffer); 887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring SimpleItoa(unsigned int i) { 890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kFastToBufferSize]; 891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return string(buffer, (sizeof(i) == 4) ? 892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastUInt32ToBufferLeft(i, buffer) : 893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastUInt64ToBufferLeft(i, buffer)); 894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring SimpleItoa(long i) { 897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kFastToBufferSize]; 898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return (sizeof(i) == 4) ? 899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastInt32ToBuffer(i, buffer) : 900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastInt64ToBuffer(i, buffer); 901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring SimpleItoa(unsigned long i) { 904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kFastToBufferSize]; 905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return string(buffer, (sizeof(i) == 4) ? 906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastUInt32ToBufferLeft(i, buffer) : 907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastUInt64ToBufferLeft(i, buffer)); 908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring SimpleItoa(long long i) { 911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kFastToBufferSize]; 912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return (sizeof(i) == 4) ? 913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastInt32ToBuffer(i, buffer) : 914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastInt64ToBuffer(i, buffer); 915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring SimpleItoa(unsigned long long i) { 918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kFastToBufferSize]; 919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return string(buffer, (sizeof(i) == 4) ? 920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastUInt32ToBufferLeft(i, buffer) : 921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FastUInt64ToBufferLeft(i, buffer)); 922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SimpleDtoa() 926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SimpleFtoa() 927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DoubleToBuffer() 928fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FloatToBuffer() 929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// We want to print the value without losing precision, but we also do 930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// not want to print more digits than necessary. This turns out to be 931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// trickier than it sounds. Numbers like 0.2 cannot be represented 932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// exactly in binary. If we print 0.2 with a very large precision, 933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167". 934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// On the other hand, if we set the precision too low, we lose 935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// significant digits when printing numbers that actually need them. 936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// It turns out there is no precision value that does the right thing 937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// for all numbers. 938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Our strategy is to first try printing with a precision that is never 940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// over-precise, then parse the result with strtod() to see if it 941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// matches. If not, we print again with a precision that will always 942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// give a precise result, but may use more digits than necessary. 943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// An arguably better strategy would be to use the algorithm described 945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in "How to Print Floating-Point Numbers Accurately" by Steele & 946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// White, e.g. as implemented by David M. Gay's dtoa(). It turns out, 947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// however, that the following implementation is about as fast as 948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DMG's code. Furthermore, DMG's code locks mutexes, which means it 949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// will not scale well on multi-core machines. DMG's code is slightly 950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// more accurate (in that it will never use more digits than 951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// necessary), but this is probably irrelevant for most users. 952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Rob Pike and Ken Thompson also have an implementation of dtoa() in 954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// third_party/fmt/fltfmt.cc. Their implementation is similar to this 955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// one in that it makes guesses and then uses strtod() to check them. 956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Their implementation is faster because they use their own code to 957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// generate the digits in the first place rather than use snprintf(), 958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// thus avoiding format string parsing overhead. However, this makes 959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// it considerably more complicated than the following implementation, 960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// and it is embedded in a larger library. If speed turns out to be 961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// an issue, we could re-implement this in terms of their 962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// implementation. 963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring SimpleDtoa(double value) { 966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kDoubleToBufferSize]; 967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DoubleToBuffer(value, buffer); 968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring SimpleFtoa(float value) { 971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kFloatToBufferSize]; 972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FloatToBuffer(value, buffer); 973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic inline bool IsValidFloatChar(char c) { 976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return ('0' <= c && c <= '9') || 977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville c == 'e' || c == 'E' || 978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville c == '+' || c == '-'; 979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DelocalizeRadix(char* buffer) { 982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fast check: if the buffer has a normal decimal point, assume no 983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // translation is needed. 984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (strchr(buffer, '.') != NULL) return; 985fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 986fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Find the first unknown character. 987fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (IsValidFloatChar(*buffer)) ++buffer; 988fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 989fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (*buffer == '\0') { 990fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // No radix character found. 991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We are now pointing at the locale-specific radix character. Replace it 995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // with '.'. 996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *buffer = '.'; 997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++buffer; 998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!IsValidFloatChar(*buffer) && *buffer != '\0') { 1000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // It appears the radix was a multi-byte character. We need to remove the 1001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // extra bytes. 1002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char* target = buffer; 1003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0'); 1004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memmove(target, buffer, strlen(buffer) + 1); 1005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar* DoubleToBuffer(double value, char* buffer) { 1009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all 1010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // platforms these days. Just in case some system exists where DBL_DIG 1011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // is significantly larger -- and risks overflowing our buffer -- we have 1012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // this assert. 1013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big); 1014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value == numeric_limits<double>::infinity()) { 1016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strcpy(buffer, "inf"); 1017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 1018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value == -numeric_limits<double>::infinity()) { 1019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strcpy(buffer, "-inf"); 1020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 1021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (IsNaN(value)) { 1022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strcpy(buffer, "nan"); 1023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 1024fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int snprintf_result = 1027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value); 1028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The snprintf should never overflow because the buffer is significantly 1030fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // larger than the precision we asked for. 1031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); 1032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We need to make parsed_value volatile in order to force the compiler to 1034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // write it out to the stack. Otherwise, it may keep the value in a 1035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // register, and if it does that, it may keep it as a long double instead 1036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // of a double. This long double may have extra bits that make it compare 1037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // unequal to "value" even though it would be exactly equal if it were 1038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // truncated to a double. 1039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville volatile double parsed_value = strtod(buffer, NULL); 1040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (parsed_value != value) { 1041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int snprintf_result = 1042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value); 1043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Should never overflow; see above. 1045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize); 1046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DelocalizeRadix(buffer); 1049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 1050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool safe_strtof(const char* str, float* value) { 1053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char* endptr; 1054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errno = 0; // errno only gets set on errors 1055d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#if defined(_WIN32) || defined (__hpux) // has no strtof() 1056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = strtod(str, &endptr); 1057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 1058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = strtof(str, &endptr); 1059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 1060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return *str != 0 && *endptr == 0 && errno == 0; 1061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillechar* FloatToBuffer(float value, char* buffer) { 1064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all 1065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // platforms these days. Just in case some system exists where FLT_DIG 1066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // is significantly larger -- and risks overflowing our buffer -- we have 1067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // this assert. 1068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big); 1069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value == numeric_limits<double>::infinity()) { 1071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strcpy(buffer, "inf"); 1072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 1073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value == -numeric_limits<double>::infinity()) { 1074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strcpy(buffer, "-inf"); 1075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 1076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (IsNaN(value)) { 1077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strcpy(buffer, "nan"); 1078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 1079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int snprintf_result = 1082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value); 1083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The snprintf should never overflow because the buffer is significantly 1085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // larger than the precision we asked for. 1086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); 1087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville float parsed_value; 1089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) { 1090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int snprintf_result = 1091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value); 1092fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Should never overflow; see above. 1094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize); 1095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DelocalizeRadix(buffer); 1098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 1099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 1102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// NoLocaleStrtod() 1103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This code will make you cry. 1104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 1105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns a string identical to *input except that the character pointed to 1107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// by radix_pos (which should be '.') is replaced with the locale-specific 1108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// radix character. 1109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring LocalizeRadix(const char* input, const char* radix_pos) { 1110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Determine the locale-specific radix character by calling sprintf() to 1111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // print the number 1.5, then stripping off the digits. As far as I can 1112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // tell, this is the only portable, thread-safe way to get the C library 1113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // to divuldge the locale's radix character. No, localeconv() is NOT 1114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // thread-safe. 1115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char temp[16]; 1116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size = sprintf(temp, "%.1f", 1.5); 1117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK_EQ(temp[0], '1'); 1118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK_EQ(temp[size-1], '5'); 1119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK_LE(size, 6); 1120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Now replace the '.' in the input with it. 1122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result; 1123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.reserve(strlen(input) + size - 3); 1124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append(input, radix_pos); 1125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append(temp + 1, size - 2); 1126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append(radix_pos + 1); 1127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledouble NoLocaleStrtod(const char* text, char** original_endptr) { 1131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We cannot simply set the locale to "C" temporarily with setlocale() 1132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // as this is not thread-safe. Instead, we try to parse in the current 1133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // locale first. If parsing stops at a '.' character, then this is a 1134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // pretty good hint that we're actually in some other locale in which 1135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // '.' is not the radix character. 1136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char* temp_endptr; 1138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville double result = strtod(text, &temp_endptr); 1139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (original_endptr != NULL) *original_endptr = temp_endptr; 1140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (*temp_endptr != '.') return result; 1141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Parsing halted on a '.'. Perhaps we're in a different locale? Let's 1143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // try to replace the '.' with a locale-specific radix character and 1144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // try again. 1145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string localized = LocalizeRadix(text, temp_endptr); 1146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* localized_cstr = localized.c_str(); 1147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char* localized_endptr; 1148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result = strtod(localized_cstr, &localized_endptr); 1149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if ((localized_endptr - localized_cstr) > 1150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (temp_endptr - text)) { 1151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This attempt got further, so replacing the decimal must have helped. 1152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Update original_endptr to point at the right location. 1153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (original_endptr != NULL) { 1154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // size_diff is non-zero if the localized radix has multiple bytes. 1155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size_diff = localized.size() - strlen(text); 1156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // const_cast is necessary to match the strtod() interface. 1157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *original_endptr = const_cast<char*>( 1158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville text + (localized_endptr - localized_cstr - size_diff)); 1159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 1166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 1167