OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
(...skipping 19 matching lines...) Expand all Loading... |
30 | 30 |
31 #ifndef GOOGLE_PROTOBUF_ARENASTRING_H__ | 31 #ifndef GOOGLE_PROTOBUF_ARENASTRING_H__ |
32 #define GOOGLE_PROTOBUF_ARENASTRING_H__ | 32 #define GOOGLE_PROTOBUF_ARENASTRING_H__ |
33 | 33 |
34 #include <string> | 34 #include <string> |
35 | 35 |
36 #include <google/protobuf/stubs/logging.h> | 36 #include <google/protobuf/stubs/logging.h> |
37 #include <google/protobuf/stubs/common.h> | 37 #include <google/protobuf/stubs/common.h> |
38 #include <google/protobuf/stubs/fastmem.h> | 38 #include <google/protobuf/stubs/fastmem.h> |
39 #include <google/protobuf/arena.h> | 39 #include <google/protobuf/arena.h> |
| 40 #include <google/protobuf/generated_message_util.h> |
40 | 41 |
41 | 42 |
42 | 43 |
43 // This is the implementation of arena string fields written for the open-source | 44 // This is the implementation of arena string fields written for the open-source |
44 // release. The ArenaStringPtr struct below is an internal implementation class | 45 // release. The ArenaStringPtr struct below is an internal implementation class |
45 // and *should not be used* by user code. It is used to collect string | 46 // and *should not be used* by user code. It is used to collect string |
46 // operations together into one place and abstract away the underlying | 47 // operations together into one place and abstract away the underlying |
47 // string-field pointer representation, so that (for example) an alternate | 48 // string-field pointer representation, so that (for example) an alternate |
48 // implementation that knew more about ::std::string's internals could integrate
more | 49 // implementation that knew more about ::std::string's internals could integrate
more |
49 // closely with the arena allocator. | 50 // closely with the arena allocator. |
50 | 51 |
51 namespace google { | 52 namespace google { |
52 namespace protobuf { | 53 namespace protobuf { |
53 namespace internal { | 54 namespace internal { |
54 | 55 |
55 struct LIBPROTOBUF_EXPORT ArenaStringPtr { | 56 struct LIBPROTOBUF_EXPORT ArenaStringPtr { |
56 inline void Set(const ::std::string* default_value, | 57 inline void Set(const ::std::string* default_value, |
57 const ::std::string& value, ::google::protobuf::Arena* arena)
{ | 58 const ::std::string& value, ::google::protobuf::Arena* arena)
{ |
58 if (ptr_ == default_value) { | 59 if (ptr_ == default_value) { |
59 CreateInstance(arena, &value); | 60 CreateInstance(arena, &value); |
60 } else { | 61 } else { |
61 *ptr_ = value; | 62 *ptr_ = value; |
62 } | 63 } |
63 } | 64 } |
64 | 65 |
65 // Basic accessors. | 66 // Basic accessors. |
66 inline const ::std::string& Get() const { return *ptr_; } | 67 inline const ::std::string& Get(const ::std::string* /* default_value */) cons
t { |
| 68 return *ptr_; |
| 69 } |
67 | 70 |
68 inline ::std::string* Mutable(const ::std::string* default_value, | 71 inline ::std::string* Mutable(const ::std::string* default_value, |
69 ::google::protobuf::Arena* arena) { | 72 ::google::protobuf::Arena* arena) { |
70 if (ptr_ == default_value) { | 73 if (ptr_ == default_value) { |
71 CreateInstance(arena, default_value); | 74 CreateInstance(arena, default_value); |
72 } | 75 } |
73 return ptr_; | 76 return ptr_; |
74 } | 77 } |
75 | 78 |
76 // Release returns a ::std::string* instance that is heap-allocated and is not | 79 // Release returns a ::std::string* instance that is heap-allocated and is not |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 } | 143 } |
141 } | 144 } |
142 | 145 |
143 // Swaps internal pointers. Arena-safety semantics: this is guarded by the | 146 // Swaps internal pointers. Arena-safety semantics: this is guarded by the |
144 // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is | 147 // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is |
145 // 'unsafe' if called directly. | 148 // 'unsafe' if called directly. |
146 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) { | 149 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) { |
147 std::swap(ptr_, other->ptr_); | 150 std::swap(ptr_, other->ptr_); |
148 } | 151 } |
149 | 152 |
150 // Frees storage (if not on an arena). | 153 // Frees storage (if not on an arena) and sets field to default value. |
151 inline void Destroy(const ::std::string* default_value, | 154 inline void Destroy(const ::std::string* default_value, |
152 ::google::protobuf::Arena* arena) { | 155 ::google::protobuf::Arena* arena) { |
153 if (arena == NULL && ptr_ != default_value) { | 156 if (arena == NULL && ptr_ != default_value) { |
154 delete ptr_; | 157 delete ptr_; |
155 } | 158 } |
| 159 ptr_ = const_cast< ::std::string* >(default_value); |
156 } | 160 } |
157 | 161 |
158 // Clears content, but keeps allocated string if arena != NULL, to avoid the | 162 // Clears content, but keeps allocated string if arena != NULL, to avoid the |
159 // overhead of heap operations. After this returns, the content (as seen by | 163 // overhead of heap operations. After this returns, the content (as seen by |
160 // the user) will always be the empty string. Assumes that |default_value| | 164 // the user) will always be the empty string. Assumes that |default_value| |
161 // is an empty string. | 165 // is an empty string. |
162 inline void ClearToEmpty(const ::std::string* default_value, | 166 inline void ClearToEmpty(const ::std::string* default_value, |
163 ::google::protobuf::Arena* /* arena */) { | 167 ::google::protobuf::Arena* /* arena */) { |
164 if (ptr_ == default_value) { | 168 if (ptr_ == default_value) { |
165 // Already set to default (which is empty) -- do nothing. | 169 // Already set to default (which is empty) -- do nothing. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 // tagged-pointer manipulations to be avoided. | 207 // tagged-pointer manipulations to be avoided. |
204 inline void SetNoArena(const ::std::string* default_value, | 208 inline void SetNoArena(const ::std::string* default_value, |
205 const ::std::string& value) { | 209 const ::std::string& value) { |
206 if (ptr_ == default_value) { | 210 if (ptr_ == default_value) { |
207 CreateInstanceNoArena(&value); | 211 CreateInstanceNoArena(&value); |
208 } else { | 212 } else { |
209 *ptr_ = value; | 213 *ptr_ = value; |
210 } | 214 } |
211 } | 215 } |
212 | 216 |
213 #if LANG_CXX11 | |
214 void SetNoArena(const ::std::string* default_value, ::std::string&& value) { | |
215 if (IsDefault(default_value)) { | |
216 ptr_ = new ::std::string(std::move(value)); | |
217 } else { | |
218 *ptr_ = std::move(value); | |
219 } | |
220 } | |
221 #endif | |
222 | |
223 void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr valu
e); | 217 void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr valu
e); |
224 | 218 |
225 inline const ::std::string& GetNoArena() const { return *ptr_; } | 219 inline const ::std::string& GetNoArena(const ::std::string* /* default_value *
/) const { |
| 220 return *ptr_; |
| 221 } |
226 | 222 |
227 ::std::string* MutableNoArena(const ::std::string* default_value); | 223 ::std::string* MutableNoArena(const ::std::string* default_value); |
228 | 224 |
229 inline ::std::string* ReleaseNoArena(const ::std::string* default_value) { | 225 inline ::std::string* ReleaseNoArena(const ::std::string* default_value) { |
230 if (ptr_ == default_value) { | 226 if (ptr_ == default_value) { |
231 return NULL; | 227 return NULL; |
232 } else { | 228 } else { |
233 ::std::string* released = ptr_; | 229 ::std::string* released = ptr_; |
234 ptr_ = const_cast< ::std::string* >(default_value); | 230 ptr_ = const_cast< ::std::string* >(default_value); |
235 return released; | 231 return released; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 } | 264 } |
269 | 265 |
270 // Internal accessor used only at parse time to provide direct access to the | 266 // Internal accessor used only at parse time to provide direct access to the |
271 // raw pointer from the shared parse routine (in the non-arenas case). The | 267 // raw pointer from the shared parse routine (in the non-arenas case). The |
272 // parse routine does the string allocation in order to save code size in the | 268 // parse routine does the string allocation in order to save code size in the |
273 // generated parsing code. | 269 // generated parsing code. |
274 inline ::std::string** UnsafeRawStringPointer() { | 270 inline ::std::string** UnsafeRawStringPointer() { |
275 return &ptr_; | 271 return &ptr_; |
276 } | 272 } |
277 | 273 |
278 inline bool IsDefault(const ::std::string* default_value) const { | |
279 return ptr_ == default_value; | |
280 } | |
281 | |
282 private: | 274 private: |
283 ::std::string* ptr_; | 275 ::std::string* ptr_; |
284 | 276 |
285 GOOGLE_ATTRIBUTE_NOINLINE void CreateInstance(::google::protobuf::Arena* arena
, | 277 GOOGLE_ATTRIBUTE_NOINLINE void CreateInstance(::google::protobuf::Arena* arena
, |
286 const ::std::string* initial_value) { | 278 const ::std::string* initial_value) { |
287 GOOGLE_DCHECK(initial_value != NULL); | 279 // Assumes ptr_ is not NULL. |
288 ptr_ = new ::std::string(*initial_value); | 280 if (initial_value != NULL) { |
| 281 ptr_ = new ::std::string(*initial_value); |
| 282 } else { |
| 283 ptr_ = new ::std::string(); |
| 284 } |
289 if (arena != NULL) { | 285 if (arena != NULL) { |
290 arena->Own(ptr_); | 286 arena->Own(ptr_); |
291 } | 287 } |
292 } | 288 } |
293 GOOGLE_ATTRIBUTE_NOINLINE void CreateInstanceNoArena(const ::std::string* init
ial_value) { | 289 GOOGLE_ATTRIBUTE_NOINLINE void CreateInstanceNoArena(const ::std::string* init
ial_value) { |
294 GOOGLE_DCHECK(initial_value != NULL); | 290 if (initial_value != NULL) { |
295 ptr_ = new ::std::string(*initial_value); | 291 ptr_ = new ::std::string(*initial_value); |
| 292 } else { |
| 293 ptr_ = new ::std::string(); |
| 294 } |
296 } | 295 } |
297 }; | 296 }; |
298 | 297 |
299 } // namespace internal | 298 } // namespace internal |
300 } // namespace protobuf | 299 } // namespace protobuf |
301 | 300 |
302 | 301 |
303 | 302 |
304 } // namespace google | 303 } // namespace google |
305 #endif // GOOGLE_PROTOBUF_ARENASTRING_H__ | 304 #endif // GOOGLE_PROTOBUF_ARENASTRING_H__ |
OLD | NEW |