strutil.h revision d0332953cda33fb4f8e24ebff9c49159b69c43d6
123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Protocol Buffers - Google's data interchange format
223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// http://code.google.com/p/protobuf/
423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//
523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Redistribution and use in source and binary forms, with or without
623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// modification, are permitted provided that the following conditions are
723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// met:
823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//
923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//     * Redistributions of source code must retain the above copyright
1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// notice, this list of conditions and the following disclaimer.
1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//     * Redistributions in binary form must reproduce the above
1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// in the documentation and/or other materials provided with the
1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// distribution.
1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// this software without specific prior written permission.
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// from google3/strings/strutil.h
3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include <stdlib.h>
3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include <vector>
3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include <google/protobuf/stubs/common.h>
3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace google {
4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace protobuf {
4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#ifdef _MSC_VER
4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#define strtoll  _strtoi64
4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#define strtoull _strtoui64
4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#elif defined(__DECCXX) && defined(__osf__)
4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit.
4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#define strtoll strtol
4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#define strtoull strtoul
5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
5223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ----------------------------------------------------------------------
5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ascii_isalnum()
5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    Check if an ASCII character is alphanumeric.  We can't use ctype's
5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    isalnum() because it is affected by locale.  This function is applied
5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    to identifiers in the protocol buffer language, not to natural-language
5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    strings, so locale should not be taken into account.
5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ascii_isdigit()
5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    Like above, but only accepts digits.
6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ----------------------------------------------------------------------
6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)inline bool ascii_isalnum(char c) {
6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return ('a' <= c && c <= 'z') ||
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)         ('A' <= c && c <= 'Z') ||
6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)         ('0' <= c && c <= '9');
6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)inline bool ascii_isdigit(char c) {
6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return ('0' <= c && c <= '9');
7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ----------------------------------------------------------------------
7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// HasPrefixString()
7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    Check if a string begins with a given prefix.
7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// StripPrefixString()
7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    Given a string and a putative prefix, returns the string minus the
7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    prefix string if the prefix matches, otherwise the original
7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    string.
7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ----------------------------------------------------------------------
8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)inline bool HasPrefixString(const string& str,
8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                            const string& prefix) {
8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return str.size() >= prefix.size() &&
8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)         str.compare(0, prefix.size(), prefix) == 0;
8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)inline string StripPrefixString(const string& str, const string& prefix) {
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (HasPrefixString(str, prefix)) {
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return str.substr(prefix.size());
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return str;
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// HasSuffixString()
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    Return true if str ends in suffix.
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// StripSuffixString()
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    Given a string and a putative suffix, returns the string minus the
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    suffix string if the suffix matches, otherwise the original
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    string.
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)inline bool HasSuffixString(const string& str,
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                            const string& suffix) {
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return str.size() >= suffix.size() &&
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)         str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)inline string StripSuffixString(const string& str, const string& suffix) {
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (HasSuffixString(str, suffix)) {
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return str.substr(0, str.size() - suffix.size());
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return str;
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// StripString
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    Replaces any occurrence of the character 'remove' (or the characters
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    in 'remove') with the character 'replacewith'.
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    Good for keeping html characters or protocol characters (\t) out
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    of places where they might cause a problem.
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove,
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    char replacewith);
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// LowerString()
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// UpperString()
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    Convert the characters in "s" to lowercase or uppercase.  ASCII-only:
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    these functions intentionally ignore locale because they are applied to
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    identifiers used in the Protocol Buffer language, not to natural-language
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    strings.
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)inline void LowerString(string * s) {
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  string::iterator end = s->end();
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (string::iterator i = s->begin(); i != end; ++i) {
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // tolower() changes based on locale.  We don't want this!
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdochinline void UpperString(string * s) {
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  string::iterator end = s->end();
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (string::iterator i = s->begin(); i != end; ++i) {
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // toupper() changes based on locale.  We don't want this!
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if ('a' <= *i && *i <= 'z') *i += 'A' - 'a';
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ----------------------------------------------------------------------
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// StringReplace()
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    Give me a string and two patterns "old" and "new", and I replace
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    the first instance of "old" in the string with "new", if it
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//    exists.  RETURN a new string, regardless of whether the replacement
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    happened or not.
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ----------------------------------------------------------------------
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
159116680a4aac90f2aa7413d9095a592090648e557Ben MurdochLIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub,
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                        const string& newsub, bool replace_all);
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ----------------------------------------------------------------------
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// SplitStringUsing()
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    Split a string using a character delimiter. Append the components
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    to 'result'.  If there are consecutive delimiters, this function skips
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    over all of them.
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ----------------------------------------------------------------------
168116680a4aac90f2aa7413d9095a592090648e557Ben MurdochLIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim,
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                         vector<string>* res);
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ----------------------------------------------------------------------
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// JoinStrings()
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    These methods concatenate a vector of strings into a C++ string, using
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    the C-string "delim" as a separator between components. There are two
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    flavors of the function, one flavor returns the concatenated string,
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    another takes a pointer to the target string. In the latter case the
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    target string is cleared and overwritten.
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ----------------------------------------------------------------------
179116680a4aac90f2aa7413d9095a592090648e557Ben MurdochLIBPROTOBUF_EXPORT void JoinStrings(const vector<string>& components,
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    const char* delim, string* result);
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdochinline string JoinStrings(const vector<string>& components,
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          const char* delim) {
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  string result;
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  JoinStrings(components, delim, &result);
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return result;
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// ----------------------------------------------------------------------
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// UnescapeCEscapeSequences()
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    Copies "source" to "dest", rewriting C-style escape sequences
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//    equivalents.  "dest" must be sufficiently large to hold all
19423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    the characters in the rewritten string (i.e. at least as large
19523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    as strlen(source) + 1 should be safe, since the replacements
19623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    are always shorter than the original escaped sequences).  It's
19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    safe for source and dest to be the same.  RETURNS the length
19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    of dest.
19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//
20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    It allows hex sequences \xhh, or generally \xhhhhh with an
20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    arbitrary number of hex digits, but all of them together must
20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    specify a value of a single byte (e.g. \x0045 is equivalent
20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    to \x45, and \x1234 is erroneous).
20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//
20523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    It also allows escape sequences of the form \uhhhh (exactly four
20623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight
20723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    hex digits, upper or lower case) to specify a Unicode code
20823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    point. The dest array will contain the UTF8-encoded version of
20923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    that code-point (e.g., if source contains \u2019, then dest will
21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    contain the three bytes 0xE2, 0x80, and 0x99). For the inverse
21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    transformation, use UniLib::UTF8EscapeString
21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    (util/utf8/unilib.h), not CEscapeString.
21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    Errors: In the first form of the call, errors are reported with
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    LOG(ERROR). The same is true for the second form of the call if
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    the pointer to the string vector is NULL; otherwise, error
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    messages are stored in the vector. In either case, the effect on
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    the dest array is not defined, but rest of the source will be
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    processed.
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    ----------------------------------------------------------------------
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest);
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest,
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                vector<string> *errors);
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// UnescapeCEscapeString()
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    This does the same thing as UnescapeCEscapeSequences, but creates
22923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    a new string. The caller does not need to worry about allocating
23023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    a dest buffer. This should be used for non performance critical
23123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    tasks such as printing debug messages. It is safe for src and dest
23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    to be the same.
23323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//
23423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    The second call stores its errors in a supplied string vector.
23523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    If the string vector pointer is NULL, it reports the errors with LOG().
23623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//
23723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    In the first and second calls, the length of dest is returned. In the
23823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    the third call, the new string is returned.
23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ----------------------------------------------------------------------
24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
24123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest);
24223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest,
24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                             vector<string> *errors);
24423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src);
24523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
24623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ----------------------------------------------------------------------
24723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// CEscapeString()
24823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    Copies 'src' to 'dest', escaping dangerous characters using
24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    C-style escape sequences. This is very useful for preparing query
25023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    flags. 'src' and 'dest' should not overlap.
25123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    Returns the number of bytes written to 'dest' (not including the \0)
25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    or -1 if there was insufficient space.
25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//
25423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
25523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ----------------------------------------------------------------------
25623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len,
25723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                     char* dest, int dest_len);
25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
25923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ----------------------------------------------------------------------
26023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// CEscape()
26123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    More convenient form of CEscapeString: returns result as a "string".
26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    This version is slower than CEscapeString() because it does more
26323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    allocation.  However, it is much more convenient to use in
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    non-speed-critical code like logging messages etc.
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LIBPROTOBUF_EXPORT string CEscape(const string& src);
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace strings {
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Like CEscape() but does not escape bytes with the upper bit set.
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LIBPROTOBUF_EXPORT string Utf8SafeCEscape(const string& src);
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Like CEscape() but uses hex (\x) escapes instead of octals.
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LIBPROTOBUF_EXPORT string CHexEscape(const string& src);
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace strings
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// strto32()
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// strtou32()
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// strto64()
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// strtou64()
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    Architecture-neutral plug compatible replacements for strtol() and
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    strtoul().  Long's have different lengths on ILP-32 and LP-64
283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    platforms, so using these is safer, from the point of view of
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    overflow behavior, than using the standard libc functions.
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr,
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                         int base);
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr,
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           int base);
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)inline int32 strto32(const char *nptr, char **endptr, int base) {
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (sizeof(int32) == sizeof(long))
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return strtol(nptr, endptr, base);
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  else
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return strto32_adaptor(nptr, endptr, base);
296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)inline uint32 strtou32(const char *nptr, char **endptr, int base) {
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (sizeof(uint32) == sizeof(unsigned long))
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return strtoul(nptr, endptr, base);
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  else
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return strtou32_adaptor(nptr, endptr, base);
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// For now, long long is 64-bit on all the platforms we care about, so these
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// functions can simply pass the call to strto[u]ll.
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)inline int64 strto64(const char *nptr, char **endptr, int base) {
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long),
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        sizeof_int64_is_not_sizeof_long_long);
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return strtoll(nptr, endptr, base);
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)inline uint64 strtou64(const char *nptr, char **endptr, int base) {
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long),
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        sizeof_uint64_is_not_sizeof_long_long);
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return strtoull(nptr, endptr, base);
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ----------------------------------------------------------------------
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// FastIntToBuffer()
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// FastHexToBuffer()
322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// FastHex64ToBuffer()
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// FastHex32ToBuffer()
324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// FastTimeToBuffer()
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    These are intended for speed.  FastIntToBuffer() assumes the
326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    integer is non-negative.  FastHexToBuffer() puts output in
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    hex rather than decimal.  FastTimeToBuffer() puts the output
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    into RFC822 format.
329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format,
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    padded to exactly 16 bytes (plus one byte for '\0')
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format,
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//    padded to exactly 8 bytes (plus one byte for '\0')
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
33623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//       All functions take the output buffer as an arg.
33723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    They all return a pointer to the beginning of the output,
33823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)//    which may not be the beginning of the input buffer.
33923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// ----------------------------------------------------------------------
34023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
34123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Suggested buffer size for FastToBuffer functions.  Also works with
34223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// DoubleToBuffer() and FloatToBuffer().
34323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)static const int kFastToBufferSize = 32;
34423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
34523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)LIBPROTOBUF_EXPORT char* FastInt32ToBuffer(int32 i, char* buffer);
34623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)LIBPROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer);
34723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)char* FastUInt32ToBuffer(uint32 i, char* buffer);  // inline below
34823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)char* FastUInt64ToBuffer(uint64 i, char* buffer);  // inline below
34923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)LIBPROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer);
35023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)LIBPROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer);
35123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)LIBPROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer);
35223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
35323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// at least 22 bytes long
35423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)inline char* FastIntToBuffer(int i, char* buffer) {
35523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return (sizeof(i) == 4 ?
35623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
35723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
35823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)inline char* FastUIntToBuffer(unsigned int i, char* buffer) {
35923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return (sizeof(i) == 4 ?
36023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
36123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
36223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)inline char* FastLongToBuffer(long i, char* buffer) {
363  return (sizeof(i) == 4 ?
364          FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
365}
366inline char* FastULongToBuffer(unsigned long i, char* buffer) {
367  return (sizeof(i) == 4 ?
368          FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
369}
370
371// ----------------------------------------------------------------------
372// FastInt32ToBufferLeft()
373// FastUInt32ToBufferLeft()
374// FastInt64ToBufferLeft()
375// FastUInt64ToBufferLeft()
376//
377// Like the Fast*ToBuffer() functions above, these are intended for speed.
378// Unlike the Fast*ToBuffer() functions, however, these functions write
379// their output to the beginning of the buffer (hence the name, as the
380// output is left-aligned).  The caller is responsible for ensuring that
381// the buffer has enough space to hold the output.
382//
383// Returns a pointer to the end of the string (i.e. the null character
384// terminating the string).
385// ----------------------------------------------------------------------
386
387LIBPROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer);
388LIBPROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer);
389LIBPROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer);
390LIBPROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer);
391
392// Just define these in terms of the above.
393inline char* FastUInt32ToBuffer(uint32 i, char* buffer) {
394  FastUInt32ToBufferLeft(i, buffer);
395  return buffer;
396}
397inline char* FastUInt64ToBuffer(uint64 i, char* buffer) {
398  FastUInt64ToBufferLeft(i, buffer);
399  return buffer;
400}
401
402// ----------------------------------------------------------------------
403// SimpleItoa()
404//    Description: converts an integer to a string.
405//
406//    Return value: string
407// ----------------------------------------------------------------------
408LIBPROTOBUF_EXPORT string SimpleItoa(int i);
409LIBPROTOBUF_EXPORT string SimpleItoa(unsigned int i);
410LIBPROTOBUF_EXPORT string SimpleItoa(long i);
411LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i);
412LIBPROTOBUF_EXPORT string SimpleItoa(long long i);
413LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i);
414
415// ----------------------------------------------------------------------
416// SimpleDtoa()
417// SimpleFtoa()
418// DoubleToBuffer()
419// FloatToBuffer()
420//    Description: converts a double or float to a string which, if
421//    passed to NoLocaleStrtod(), will produce the exact same original double
422//    (except in case of NaN; all NaNs are considered the same value).
423//    We try to keep the string short but it's not guaranteed to be as
424//    short as possible.
425//
426//    DoubleToBuffer() and FloatToBuffer() write the text to the given
427//    buffer and return it.  The buffer must be at least
428//    kDoubleToBufferSize bytes for doubles and kFloatToBufferSize
429//    bytes for floats.  kFastToBufferSize is also guaranteed to be large
430//    enough to hold either.
431//
432//    Return value: string
433// ----------------------------------------------------------------------
434LIBPROTOBUF_EXPORT string SimpleDtoa(double value);
435LIBPROTOBUF_EXPORT string SimpleFtoa(float value);
436
437LIBPROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer);
438LIBPROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer);
439
440// In practice, doubles should never need more than 24 bytes and floats
441// should never need more than 14 (including null terminators), but we
442// overestimate to be safe.
443static const int kDoubleToBufferSize = 32;
444static const int kFloatToBufferSize = 24;
445
446// ----------------------------------------------------------------------
447// NoLocaleStrtod()
448//   Exactly like strtod(), except it always behaves as if in the "C"
449//   locale (i.e. decimal points must be '.'s).
450// ----------------------------------------------------------------------
451
452LIBPROTOBUF_EXPORT double NoLocaleStrtod(const char* text, char** endptr);
453
454}  // namespace protobuf
455}  // namespace google
456
457#endif  // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
458
459
460