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 #ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
32 #define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
33 
34 #include <string>
35 #include <utility>
36 
37 #include <google/protobuf/port.h>
38 #include <google/protobuf/stubs/strutil.h>
39 
40 // Must be included last.
41 #include <google/protobuf/port_def.inc>
42 
43 #ifdef SWIG
44 #error "You cannot SWIG proto headers"
45 #endif
46 
47 namespace google {
48 namespace protobuf {
49 
50 class Arena;
51 
52 namespace internal {
53 
54 // InlinedStringField wraps a std::string instance and exposes an API similar to
55 // ArenaStringPtr's wrapping of a std::string* instance.  As std::string is
56 // never allocated on the Arena, we expose only the *NoArena methods of
57 // ArenaStringPtr.
58 //
59 // default_value parameters are taken for consistency with ArenaStringPtr, but
60 // are not used for most methods.  With inlining, these should be removed from
61 // the generated binary.
62 class PROTOBUF_EXPORT InlinedStringField {
63  public:
64   InlinedStringField() PROTOBUF_ALWAYS_INLINE;
65   explicit InlinedStringField(const std::string& default_value);
66 
67   void AssignWithDefault(const std::string* default_value,
68                          const InlinedStringField& from) PROTOBUF_ALWAYS_INLINE;
69 
ClearToEmpty(const std::string * default_value,Arena *)70   void ClearToEmpty(const std::string* default_value,
71                     Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
72     ClearToEmptyNoArena(default_value);
73   }
ClearNonDefaultToEmpty()74   void ClearNonDefaultToEmpty() PROTOBUF_ALWAYS_INLINE {
75     ClearNonDefaultToEmptyNoArena();
76   }
ClearToEmptyNoArena(const std::string *)77   void ClearToEmptyNoArena(const std::string* /*default_value*/)
78       PROTOBUF_ALWAYS_INLINE {
79     ClearNonDefaultToEmptyNoArena();
80   }
81   void ClearNonDefaultToEmptyNoArena() PROTOBUF_ALWAYS_INLINE;
82 
ClearToDefault(const std::string * default_value,Arena *)83   void ClearToDefault(const std::string* default_value,
84                       Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
85     ClearToDefaultNoArena(default_value);
86   }
87   void ClearToDefaultNoArena(const std::string* default_value)
88       PROTOBUF_ALWAYS_INLINE;
89 
Destroy(const std::string * default_value,Arena *)90   void Destroy(const std::string* default_value,
91                Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
92     DestroyNoArena(default_value);
93   }
94   void DestroyNoArena(const std::string* default_value) PROTOBUF_ALWAYS_INLINE;
95 
Get()96   const std::string& Get() const PROTOBUF_ALWAYS_INLINE { return GetNoArena(); }
97   const std::string& GetNoArena() const PROTOBUF_ALWAYS_INLINE;
98 
Mutable(const std::string * default_value,Arena *)99   std::string* Mutable(const std::string* default_value,
100                        Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
101     return MutableNoArena(default_value);
102   }
103   std::string* MutableNoArena(const std::string* default_value)
104       PROTOBUF_ALWAYS_INLINE;
105 
Release(const std::string * default_value,Arena *)106   std::string* Release(const std::string* default_value, Arena* /*arena*/) {
107     return ReleaseNoArena(default_value);
108   }
ReleaseNonDefault(const std::string * default_value,Arena *)109   std::string* ReleaseNonDefault(const std::string* default_value,
110                                  Arena* /*arena*/) {
111     return ReleaseNonDefaultNoArena(default_value);
112   }
ReleaseNoArena(const std::string * default_value)113   std::string* ReleaseNoArena(const std::string* default_value) {
114     return ReleaseNonDefaultNoArena(default_value);
115   }
116   std::string* ReleaseNonDefaultNoArena(const std::string* default_value);
117 
Set(const std::string * default_value,StringPiece value,Arena *)118   void Set(const std::string* default_value, StringPiece value,
119            Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
120     SetNoArena(default_value, value);
121   }
SetLite(const std::string * default_value,StringPiece value,Arena *)122   void SetLite(const std::string* default_value, StringPiece value,
123                Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
124     SetNoArena(default_value, value);
125   }
126   void SetNoArena(const std::string* default_value,
127                   StringPiece value) PROTOBUF_ALWAYS_INLINE;
128 
Set(const std::string * default_value,const std::string & value,Arena *)129   void Set(const std::string* default_value, const std::string& value,
130            Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
131     SetNoArena(default_value, value);
132   }
SetLite(const std::string * default_value,const std::string & value,Arena *)133   void SetLite(const std::string* default_value, const std::string& value,
134                Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
135     SetNoArena(default_value, value);
136   }
137   void SetNoArena(const std::string* default_value,
138                   const std::string& value) PROTOBUF_ALWAYS_INLINE;
139 
140   void SetNoArena(const std::string* default_value,
141                   std::string&& value) PROTOBUF_ALWAYS_INLINE;
SetAllocated(const std::string * default_value,std::string * value,Arena *)142   void SetAllocated(const std::string* default_value, std::string* value,
143                     Arena* /*arena*/) {
144     SetAllocatedNoArena(default_value, value);
145   }
146   void SetAllocatedNoArena(const std::string* default_value,
147                            std::string* value);
148   void Swap(InlinedStringField* from) PROTOBUF_ALWAYS_INLINE;
149   std::string* UnsafeMutablePointer();
150   void UnsafeSetDefault(const std::string* default_value);
151   std::string* UnsafeArenaRelease(const std::string* default_value,
152                                   Arena* arena);
153   void UnsafeArenaSetAllocated(const std::string* default_value,
154                                std::string* value, Arena* arena);
155 
IsDefault(const std::string *)156   bool IsDefault(const std::string* /*default_value*/) { return false; }
157 
158  private:
159   std::string value_;
160 };
161 
InlinedStringField()162 inline InlinedStringField::InlinedStringField() {}
163 
InlinedStringField(const std::string & default_value)164 inline InlinedStringField::InlinedStringField(const std::string& default_value)
165     : value_(default_value) {}
166 
AssignWithDefault(const std::string *,const InlinedStringField & from)167 inline void InlinedStringField::AssignWithDefault(
168     const std::string* /*default_value*/, const InlinedStringField& from) {
169   value_ = from.value_;
170 }
171 
GetNoArena()172 inline const std::string& InlinedStringField::GetNoArena() const {
173   return value_;
174 }
175 
MutableNoArena(const std::string *)176 inline std::string* InlinedStringField::MutableNoArena(const std::string*) {
177   return &value_;
178 }
179 
SetAllocatedNoArena(const std::string * default_value,std::string * value)180 inline void InlinedStringField::SetAllocatedNoArena(
181     const std::string* default_value, std::string* value) {
182   if (value == NULL) {
183     value_.assign(*default_value);
184   } else {
185     value_.assign(std::move(*value));
186     delete value;
187   }
188 }
189 
DestroyNoArena(const std::string *)190 inline void InlinedStringField::DestroyNoArena(const std::string*) {
191   // This is invoked from the generated message's ArenaDtor, which is used to
192   // clean up objects not allocated on the Arena.
193   this->~InlinedStringField();
194 }
195 
ClearNonDefaultToEmptyNoArena()196 inline void InlinedStringField::ClearNonDefaultToEmptyNoArena() {
197   value_.clear();
198 }
199 
ClearToDefaultNoArena(const std::string * default_value)200 inline void InlinedStringField::ClearToDefaultNoArena(
201     const std::string* default_value) {
202   value_.assign(*default_value);
203 }
204 
ReleaseNonDefaultNoArena(const std::string * default_value)205 inline std::string* InlinedStringField::ReleaseNonDefaultNoArena(
206     const std::string* default_value) {
207   std::string* released = new std::string(*default_value);
208   value_.swap(*released);
209   return released;
210 }
211 
SetNoArena(const std::string *,StringPiece value)212 inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
213                                            StringPiece value) {
214   value_.assign(value.data(), value.length());
215 }
216 
SetNoArena(const std::string *,const std::string & value)217 inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
218                                            const std::string& value) {
219   value_.assign(value);
220 }
221 
SetNoArena(const std::string *,std::string && value)222 inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
223                                            std::string&& value) {
224   value_.assign(std::move(value));
225 }
226 
Swap(InlinedStringField * from)227 inline void InlinedStringField::Swap(InlinedStringField* from) {
228   value_.swap(from->value_);
229 }
230 
UnsafeMutablePointer()231 inline std::string* InlinedStringField::UnsafeMutablePointer() {
232   return &value_;
233 }
234 
UnsafeSetDefault(const std::string * default_value)235 inline void InlinedStringField::UnsafeSetDefault(
236     const std::string* default_value) {
237   value_.assign(*default_value);
238 }
239 
UnsafeArenaRelease(const std::string * default_value,Arena *)240 inline std::string* InlinedStringField::UnsafeArenaRelease(
241     const std::string* default_value, Arena* /*arena*/) {
242   return ReleaseNoArena(default_value);
243 }
244 
UnsafeArenaSetAllocated(const std::string * default_value,std::string * value,Arena *)245 inline void InlinedStringField::UnsafeArenaSetAllocated(
246     const std::string* default_value, std::string* value, Arena* /*arena*/) {
247   if (value == NULL) {
248     value_.assign(*default_value);
249   } else {
250     value_.assign(*value);
251   }
252 }
253 
254 }  // namespace internal
255 }  // namespace protobuf
256 }  // namespace google
257 
258 #include <google/protobuf/port_undef.inc>
259 
260 #endif  // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
261