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// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// from google3/strings/substitute.h 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <string> 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h> 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace strings { 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// strings::Substitute() 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// strings::SubstituteAndAppend() 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Kind of like StringPrintf, but different. 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Example: 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// string GetMessage(string first_name, string last_name, int age) { 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// return strings::Substitute("My name is $0 $1 and I am $2 years old.", 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// first_name, last_name, age); 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// } 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Differences from StringPrintf: 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * The format string does not identify the types of arguments. 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Instead, the magic of C++ deals with this for us. See below 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// for a list of accepted types. 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Substitutions in the format string are identified by a '$' 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// followed by a digit. So, you can use arguments out-of-order and 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// use the same argument multiple times. 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * It's much faster than StringPrintf. 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Supported types: 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Strings (const char*, const string&) 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Note that this means you do not have to add .c_str() to all of 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// your strings. In fact, you shouldn't; it will be slower. 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * int32, int64, uint32, uint64: Formatted using SimpleItoa(). 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * float, double: Formatted using SimpleFtoa() and SimpleDtoa(). 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * bool: Printed as "true" or "false". 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SubstituteAndAppend() is like Substitute() but appends the result to 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// *output. Example: 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// string str; 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// strings::SubstituteAndAppend(&str, 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "My name is $0 $1 and I am $2 years old.", 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// first_name, last_name, age); 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Substitute() is significantly faster than StringPrintf(). For very 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// large strings, it may be orders of magnitude faster. 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ---------------------------------------------------------------------- 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace internal { // Implementation details. 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass SubstituteArg { 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(const char* value) 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(value), size_(strlen(text_)) {} 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(const string& value) 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(value.data()), size_(value.size()) {} 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Indicates that no argument was given. 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline explicit SubstituteArg() 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(NULL), size_(-1) {} 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Primitives 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We don't overload for signed and unsigned char because if people are 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // explicitly declaring their chars as signed or unsigned then they are 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // probably actually using them as 8-bit integers and would probably 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // prefer an integer representation. But, we don't really know. So, we 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // make the caller decide what to do. 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(char value) 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(scratch_), size_(1) { scratch_[0] = value; } 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(short value) 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(unsigned short value) 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(int value) 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(unsigned int value) 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {} 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(long value) 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {} 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(unsigned long value) 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {} 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(long long value) 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(unsigned long long value) 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {} 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(float value) 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {} 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(double value) 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {} 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline SubstituteArg(bool value) 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : text_(value ? "true" : "false"), size_(strlen(text_)) {} 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline const char* data() const { return text_; } 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline int size() const { return size_; } 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* text_; 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size_; 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char scratch_[kFastToBufferSize]; 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace internal 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLIBPROTOBUF_EXPORT string Substitute( 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* format, 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg0 = internal::SubstituteArg(), 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg1 = internal::SubstituteArg(), 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg2 = internal::SubstituteArg(), 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg3 = internal::SubstituteArg(), 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg4 = internal::SubstituteArg(), 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg5 = internal::SubstituteArg(), 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg6 = internal::SubstituteArg(), 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg7 = internal::SubstituteArg(), 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg8 = internal::SubstituteArg(), 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg9 = internal::SubstituteArg()); 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLIBPROTOBUF_EXPORT void SubstituteAndAppend( 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* output, const char* format, 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg0 = internal::SubstituteArg(), 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg1 = internal::SubstituteArg(), 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg2 = internal::SubstituteArg(), 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg3 = internal::SubstituteArg(), 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg4 = internal::SubstituteArg(), 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg5 = internal::SubstituteArg(), 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg6 = internal::SubstituteArg(), 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg7 = internal::SubstituteArg(), 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg8 = internal::SubstituteArg(), 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const internal::SubstituteArg& arg9 = internal::SubstituteArg()); 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace strings 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_ 171