Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // from google3/strings/substitute.h
33 :
34 : #include <string>
35 : #include <google/protobuf/stubs/common.h>
36 : #include <google/protobuf/stubs/strutil.h>
37 :
38 : #ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
39 : #define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
40 :
41 : namespace google {
42 : namespace protobuf {
43 : namespace strings {
44 :
45 : // ----------------------------------------------------------------------
46 : // strings::Substitute()
47 : // strings::SubstituteAndAppend()
48 : // Kind of like StringPrintf, but different.
49 : //
50 : // Example:
51 : // string GetMessage(string first_name, string last_name, int age) {
52 : // return strings::Substitute("My name is $0 $1 and I am $2 years old.",
53 : // first_name, last_name, age);
54 : // }
55 : //
56 : // Differences from StringPrintf:
57 : // * The format string does not identify the types of arguments.
58 : // Instead, the magic of C++ deals with this for us. See below
59 : // for a list of accepted types.
60 : // * Substitutions in the format string are identified by a '$'
61 : // followed by a digit. So, you can use arguments out-of-order and
62 : // use the same argument multiple times.
63 : // * It's much faster than StringPrintf.
64 : //
65 : // Supported types:
66 : // * Strings (const char*, const string&)
67 : // * Note that this means you do not have to add .c_str() to all of
68 : // your strings. In fact, you shouldn't; it will be slower.
69 : // * int32, int64, uint32, uint64: Formatted using SimpleItoa().
70 : // * float, double: Formatted using SimpleFtoa() and SimpleDtoa().
71 : // * bool: Printed as "true" or "false".
72 : //
73 : // SubstituteAndAppend() is like Substitute() but appends the result to
74 : // *output. Example:
75 : //
76 : // string str;
77 : // strings::SubstituteAndAppend(&str,
78 : // "My name is $0 $1 and I am $2 years old.",
79 : // first_name, last_name, age);
80 : //
81 : // Substitute() is significantly faster than StringPrintf(). For very
82 : // large strings, it may be orders of magnitude faster.
83 : // ----------------------------------------------------------------------
84 :
85 : namespace internal { // Implementation details.
86 :
87 : class SubstituteArg {
88 : public:
89 : inline SubstituteArg(const char* value)
90 0 : : text_(value), size_(strlen(text_)) {}
91 : inline SubstituteArg(const string& value)
92 104858 : : text_(value.data()), size_(value.size()) {}
93 :
94 : // Indicates that no argument was given.
95 : inline explicit SubstituteArg()
96 16262 : : text_(NULL), size_(-1) {}
97 :
98 : // Primitives
99 : // We don't overload for signed and unsigned char because if people are
100 : // explicitly declaring their chars as signed or unsigned then they are
101 : // probably actually using them as 8-bit integers and would probably
102 : // prefer an integer representation. But, we don't really know. So, we
103 : // make the caller decide what to do.
104 : inline SubstituteArg(char value)
105 : : text_(scratch_), size_(1) { scratch_[0] = value; }
106 : inline SubstituteArg(short value)
107 : : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
108 : inline SubstituteArg(unsigned short value)
109 : : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
110 11775 : inline SubstituteArg(int value)
111 11775 : : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
112 : inline SubstituteArg(unsigned int value)
113 : : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
114 : inline SubstituteArg(long value)
115 : : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {}
116 : inline SubstituteArg(unsigned long value)
117 : : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {}
118 0 : inline SubstituteArg(long long value)
119 0 : : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
120 : inline SubstituteArg(unsigned long long value)
121 : : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
122 : inline SubstituteArg(float value)
123 : : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {}
124 : inline SubstituteArg(double value)
125 : : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {}
126 : inline SubstituteArg(bool value)
127 : : text_(value ? "true" : "false"), size_(strlen(text_)) {}
128 :
129 : inline const char* data() const { return text_; }
130 : inline int size() const { return size_; }
131 :
132 : private:
133 : const char* text_;
134 : int size_;
135 : char scratch_[kFastToBufferSize];
136 : };
137 :
138 : } // namespace internal
139 :
140 : LIBPROTOBUF_EXPORT string Substitute(
141 : const char* format,
142 : const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
143 : const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
144 : const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
145 : const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
146 : const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
147 : const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
148 : const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
149 : const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
150 : const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
151 : const internal::SubstituteArg& arg9 = internal::SubstituteArg());
152 :
153 : LIBPROTOBUF_EXPORT void SubstituteAndAppend(
154 : string* output, const char* format,
155 : const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
156 : const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
157 : const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
158 : const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
159 : const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
160 : const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
161 : const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
162 : const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
163 : const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
164 : const internal::SubstituteArg& arg9 = internal::SubstituteArg());
165 :
166 : } // namespace strings
167 : } // namespace protobuf
168 : } // namespace google
169 :
170 : #endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
|