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