LCOV - code coverage report
Current view: top level - usr/include/google/protobuf - arenastring.h (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 7 53 13.2 %
Date: 2023-11-06 10:06:49 Functions: 2 13 15.4 %

          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             : #ifndef GOOGLE_PROTOBUF_ARENASTRING_H__
      32             : #define GOOGLE_PROTOBUF_ARENASTRING_H__
      33             : 
      34             : #include <string>
      35             : 
      36             : #include <google/protobuf/arena.h>
      37             : #include <google/protobuf/stubs/common.h>
      38             : #include <google/protobuf/stubs/fastmem.h>
      39             : #include <google/protobuf/stubs/logging.h>
      40             : #include <google/protobuf/stubs/port.h>
      41             : 
      42             : // This is the implementation of arena string fields written for the open-source
      43             : // release. The ArenaStringPtr struct below is an internal implementation class
      44             : // and *should not be used* by user code. It is used to collect string
      45             : // operations together into one place and abstract away the underlying
      46             : // string-field pointer representation, so that (for example) an alternate
      47             : // implementation that knew more about ::std::string's internals could integrate more
      48             : // closely with the arena allocator.
      49             : 
      50             : namespace google {
      51             : namespace protobuf {
      52             : namespace internal {
      53             : 
      54             : template <typename T>
      55             : class TaggedPtr {
      56             :  public:
      57             :   void Set(T* p) { ptr_ = reinterpret_cast<uintptr_t>(p); }
      58             :   T* Get() const { return reinterpret_cast<T*>(ptr_); }
      59             : 
      60             :   bool IsNull() { return ptr_ == 0; }
      61             : 
      62             :  private:
      63             :   uintptr_t ptr_;
      64             : };
      65             : 
      66             : struct LIBPROTOBUF_EXPORT ArenaStringPtr {
      67             :   inline void Set(const ::std::string* default_value,
      68             :                   const ::std::string& value, ::google::protobuf::Arena* arena) {
      69             :     if (ptr_ == default_value) {
      70             :       CreateInstance(arena, &value);
      71             :     } else {
      72             :       *ptr_ = value;
      73             :     }
      74             :   }
      75             : 
      76             :   inline void SetLite(const ::std::string* default_value,
      77             :                       const ::std::string& value,
      78             :                       ::google::protobuf::Arena* arena) {
      79             :     Set(default_value, value, arena);
      80             :   }
      81             : 
      82             :   // Basic accessors.
      83             :   inline const ::std::string& Get() const { return *ptr_; }
      84             : 
      85           0 :   inline ::std::string* Mutable(const ::std::string* default_value,
      86             :                            ::google::protobuf::Arena* arena) {
      87           0 :     if (ptr_ == default_value) {
      88           0 :       CreateInstance(arena, default_value);
      89             :     }
      90           0 :     return ptr_;
      91             :   }
      92             : 
      93             :   // Release returns a ::std::string* instance that is heap-allocated and is not
      94             :   // Own()'d by any arena. If the field was not set, it returns NULL. The caller
      95             :   // retains ownership. Clears this field back to NULL state. Used to implement
      96             :   // release_<field>() methods on generated classes.
      97             :   inline ::std::string* Release(const ::std::string* default_value,
      98             :                            ::google::protobuf::Arena* arena) {
      99             :     if (ptr_ == default_value) {
     100             :       return NULL;
     101             :     }
     102             :     return ReleaseNonDefault(default_value, arena);
     103             :   }
     104             : 
     105             :   // Similar to Release, but ptr_ cannot be the default_value.
     106             :   inline ::std::string* ReleaseNonDefault(
     107             :       const ::std::string* default_value, ::google::protobuf::Arena* arena) {
     108             :     GOOGLE_DCHECK(!IsDefault(default_value));
     109             :     ::std::string* released = NULL;
     110             :     if (arena != NULL) {
     111             :       // ptr_ is owned by the arena.
     112             :       released = new ::std::string;
     113             :       released->swap(*ptr_);
     114             :     } else {
     115             :       released = ptr_;
     116             :     }
     117             :     ptr_ = const_cast< ::std::string* >(default_value);
     118             :     return released;
     119             :   }
     120             : 
     121             :   // UnsafeArenaRelease returns a ::std::string*, but it may be arena-owned (i.e.
     122             :   // have its destructor already registered) if arena != NULL. If the field was
     123             :   // not set, this returns NULL. This method clears this field back to NULL
     124             :   // state. Used to implement unsafe_arena_release_<field>() methods on
     125             :   // generated classes.
     126             :   inline ::std::string* UnsafeArenaRelease(const ::std::string* default_value,
     127             :                                       ::google::protobuf::Arena* /* arena */) {
     128             :     if (ptr_ == default_value) {
     129             :       return NULL;
     130             :     }
     131             :     ::std::string* released = ptr_;
     132             :     ptr_ = const_cast< ::std::string* >(default_value);
     133             :     return released;
     134             :   }
     135             : 
     136             :   // Takes a string that is heap-allocated, and takes ownership. The string's
     137             :   // destructor is registered with the arena. Used to implement
     138             :   // set_allocated_<field> in generated classes.
     139             :   inline void SetAllocated(const ::std::string* default_value,
     140             :                            ::std::string* value, ::google::protobuf::Arena* arena) {
     141             :     if (arena == NULL && ptr_ != default_value) {
     142             :       Destroy(default_value, arena);
     143             :     }
     144             :     if (value != NULL) {
     145             :       ptr_ = value;
     146             :       if (arena != NULL) {
     147             :         arena->Own(value);
     148             :       }
     149             :     } else {
     150             :       ptr_ = const_cast< ::std::string* >(default_value);
     151             :     }
     152             :   }
     153             : 
     154             :   // Takes a string that has lifetime equal to the arena's lifetime. The arena
     155             :   // must be non-null. It is safe only to pass this method a value returned by
     156             :   // UnsafeArenaRelease() on another field of a message in the same arena. Used
     157             :   // to implement unsafe_arena_set_allocated_<field> in generated classes.
     158             :   inline void UnsafeArenaSetAllocated(const ::std::string* default_value,
     159             :                                       ::std::string* value,
     160             :                                       ::google::protobuf::Arena* /* arena */) {
     161             :     if (value != NULL) {
     162             :       ptr_ = value;
     163             :     } else {
     164             :       ptr_ = const_cast< ::std::string* >(default_value);
     165             :     }
     166             :   }
     167             : 
     168             :   // Swaps internal pointers. Arena-safety semantics: this is guarded by the
     169             :   // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is
     170             :   // 'unsafe' if called directly.
     171             :   GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) {
     172             :     std::swap(ptr_, other->ptr_);
     173             :   }
     174             :   GOOGLE_PROTOBUF_ATTRIBUTE_ALWAYS_INLINE void Swap(
     175             :       ArenaStringPtr* other, const ::std::string* default_value, Arena* arena) {
     176             : #ifndef NDEBUG
     177             :     // For debug builds, we swap the contents of the string, rather than the
     178             :     // string instances themselves.  This invalidates previously taken const
     179             :     // references that are (per our documentation) invalidated by calling Swap()
     180             :     // on the message.
     181             :     //
     182             :     // If both strings are the default_value, swapping is uninteresting.
     183             :     // Otherwise, we use ArenaStringPtr::Mutable() to access the string, to
     184             :     // ensure that we do not try to mutate default_value itself.
     185           0 :     if (IsDefault(default_value) && other->IsDefault(default_value)) {
     186           0 :       return;
     187             :     }
     188             : 
     189           0 :     ::std::string* this_ptr = Mutable(default_value, arena);
     190           0 :     ::std::string* other_ptr = other->Mutable(default_value, arena);
     191             : 
     192           0 :     this_ptr->swap(*other_ptr);
     193             : #else
     194             :     std::swap(ptr_, other->ptr_);
     195             : #endif
     196             :   }
     197             : 
     198             :   // Frees storage (if not on an arena).
     199             :   inline void Destroy(const ::std::string* default_value,
     200             :                       ::google::protobuf::Arena* arena) {
     201             :     if (arena == NULL && ptr_ != default_value) {
     202             :       delete ptr_;
     203             :     }
     204             :   }
     205             : 
     206             :   // Clears content, but keeps allocated string if arena != NULL, to avoid the
     207             :   // overhead of heap operations. After this returns, the content (as seen by
     208             :   // the user) will always be the empty string. Assumes that |default_value|
     209             :   // is an empty string.
     210             :   inline void ClearToEmpty(const ::std::string* default_value,
     211             :                            ::google::protobuf::Arena* /* arena */) {
     212             :     if (ptr_ == default_value) {
     213             :       // Already set to default (which is empty) -- do nothing.
     214             :     } else {
     215             :       ptr_->clear();
     216             :     }
     217             :   }
     218             : 
     219             :   // Clears content, assuming that the current value is not the empty string
     220             :   // default.
     221             :   inline void ClearNonDefaultToEmpty() {
     222             :     ptr_->clear();
     223             :   }
     224             :   inline void ClearNonDefaultToEmptyNoArena() {
     225             :     ptr_->clear();
     226             :   }
     227             : 
     228             :   // Clears content, but keeps allocated string if arena != NULL, to avoid the
     229             :   // overhead of heap operations. After this returns, the content (as seen by
     230             :   // the user) will always be equal to |default_value|.
     231             :   inline void ClearToDefault(const ::std::string* default_value,
     232             :                              ::google::protobuf::Arena* /* arena */) {
     233             :     if (ptr_ == default_value) {
     234             :       // Already set to default -- do nothing.
     235             :     } else {
     236             :       // Have another allocated string -- rather than throwing this away and
     237             :       // resetting ptr_ to the canonical default string instance, we just reuse
     238             :       // this instance.
     239             :       *ptr_ = *default_value;
     240             :     }
     241             :   }
     242             : 
     243             :   // Called from generated code / reflection runtime only. Resets value to point
     244             :   // to a default string pointer, with the semantics that this ArenaStringPtr
     245             :   // does not own the pointed-to memory. Disregards initial value of ptr_ (so
     246             :   // this is the *ONLY* safe method to call after construction or when
     247             :   // reinitializing after becoming the active field in a oneof union).
     248          49 :   inline void UnsafeSetDefault(const ::std::string* default_value) {
     249             :     // Casting away 'const' is safe here: accessors ensure that ptr_ is only
     250             :     // returned as a const if it is equal to default_value.
     251          49 :     ptr_ = const_cast< ::std::string* >(default_value);
     252          49 :   }
     253             : 
     254             :   // The 'NoArena' variants of methods below assume arena == NULL and are
     255             :   // optimized to provide very little overhead relative to a raw string pointer
     256             :   // (while still being in-memory compatible with other code that assumes
     257             :   // ArenaStringPtr). Note the invariant that a class instance that has only
     258             :   // ever been mutated by NoArena methods must *only* be in the String state
     259             :   // (i.e., tag bits are not used), *NEVER* ArenaString. This allows all
     260             :   // tagged-pointer manipulations to be avoided.
     261           0 :   inline void SetNoArena(const ::std::string* default_value,
     262             :                          const ::std::string& value) {
     263           0 :     if (ptr_ == default_value) {
     264           0 :       CreateInstanceNoArena(&value);
     265             :     } else {
     266           0 :       *ptr_ = value;
     267             :     }
     268           0 :   }
     269             : 
     270             : #if LANG_CXX11
     271           0 :   void SetNoArena(const ::std::string* default_value, ::std::string&& value) {
     272           0 :     if (IsDefault(default_value)) {
     273           0 :       ptr_ = new ::std::string(std::move(value));
     274             :     } else {
     275           0 :       *ptr_ = std::move(value);
     276             :     }
     277           0 :   }
     278             : #endif
     279             : 
     280             :   void AssignWithDefault(const ::std::string* default_value, ArenaStringPtr value);
     281             : 
     282           0 :   inline const ::std::string& GetNoArena() const { return *ptr_; }
     283             : 
     284           0 :   inline ::std::string* MutableNoArena(const ::std::string* default_value) {
     285           0 :     if (ptr_ == default_value) {
     286           0 :       CreateInstanceNoArena(default_value);
     287             :     }
     288           0 :     return ptr_;
     289             :   }
     290             : 
     291             :   inline ::std::string* ReleaseNoArena(const ::std::string* default_value) {
     292             :     if (ptr_ == default_value) {
     293             :       return NULL;
     294             :     } else {
     295             :       return ReleaseNonDefaultNoArena(default_value);
     296             :     }
     297             :   }
     298             : 
     299             :   inline ::std::string* ReleaseNonDefaultNoArena(
     300             :       const ::std::string* default_value) {
     301             :     GOOGLE_DCHECK(!IsDefault(default_value));
     302             :     ::std::string* released = ptr_;
     303             :     ptr_ = const_cast< ::std::string* >(default_value);
     304             :     return released;
     305             :   }
     306             : 
     307             : 
     308             :   inline void SetAllocatedNoArena(const ::std::string* default_value,
     309             :                                   ::std::string* value) {
     310             :     if (ptr_ != default_value) {
     311             :       delete ptr_;
     312             :     }
     313             :     if (value != NULL) {
     314             :       ptr_ = value;
     315             :     } else {
     316             :       ptr_ = const_cast< ::std::string* >(default_value);
     317             :     }
     318             :   }
     319             : 
     320           0 :   inline void DestroyNoArena(const ::std::string* default_value) {
     321           0 :     if (ptr_ != default_value) {
     322           0 :       delete ptr_;
     323             :     }
     324           0 :   }
     325             : 
     326           0 :   inline void ClearToEmptyNoArena(const ::std::string* default_value) {
     327           0 :     if (ptr_ == default_value) {
     328             :       // Nothing: already equal to default (which is the empty string).
     329             :     } else {
     330           0 :       ptr_->clear();
     331             :     }
     332           0 :   }
     333             : 
     334             :   inline void ClearToDefaultNoArena(const ::std::string* default_value) {
     335             :     if (ptr_ == default_value) {
     336             :       // Nothing: already set to default.
     337             :     } else {
     338             :       // Reuse existing allocated instance.
     339             :       *ptr_ = *default_value;
     340             :     }
     341             :   }
     342             : 
     343             :   // Internal accessor used only at parse time to provide direct access to the
     344             :   // raw pointer from the shared parse routine (in the non-arenas case). The
     345             :   // parse routine does the string allocation in order to save code size in the
     346             :   // generated parsing code.
     347           0 :   inline ::std::string** UnsafeRawStringPointer() {
     348           0 :     return &ptr_;
     349             :   }
     350             : 
     351           0 :   inline bool IsDefault(const ::std::string* default_value) const {
     352           0 :     return ptr_ == default_value;
     353             :   }
     354             : 
     355             :   // Internal accessors!!!!
     356             :   void UnsafeSetTaggedPointer(TaggedPtr< ::std::string> value) {
     357             :     ptr_ = value.Get();
     358             :   }
     359             :   // Generated code only! An optimization, in certain cases the generated
     360             :   // code is certain we can obtain a string with no default checks and
     361             :   // tag tests.
     362             :   ::std::string* UnsafeMutablePointer() { return ptr_; }
     363             : 
     364             :  private:
     365             :   ::std::string* ptr_;
     366             : 
     367             :   GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
     368         886 :   void CreateInstance(::google::protobuf::Arena* arena,
     369             :                       const ::std::string* initial_value) {
     370         886 :     GOOGLE_DCHECK(initial_value != NULL);
     371             :     // uses "new ::std::string" when arena is nullptr
     372         886 :     ptr_ = Arena::Create< ::std::string >(arena, *initial_value);
     373         886 :   }
     374             :   GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE
     375           0 :   void CreateInstanceNoArena(const ::std::string* initial_value) {
     376           0 :     GOOGLE_DCHECK(initial_value != NULL);
     377           0 :     ptr_ = new ::std::string(*initial_value);
     378           0 :   }
     379             : };
     380             : 
     381             : }  // namespace internal
     382             : }  // namespace protobuf
     383             : 
     384             : 
     385             : 
     386             : namespace protobuf {
     387             : namespace internal {
     388             : 
     389           0 : inline void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value,
     390             :                                        ArenaStringPtr value) {
     391           0 :   const ::std::string* me = *UnsafeRawStringPointer();
     392           0 :   const ::std::string* other = *value.UnsafeRawStringPointer();
     393             :   // If the pointers are the same then do nothing.
     394           0 :   if (me != other) {
     395           0 :     SetNoArena(default_value, value.GetNoArena());
     396             :   }
     397           0 : }
     398             : 
     399             : }  // namespace internal
     400             : }  // namespace protobuf
     401             : 
     402             : }  // namespace google
     403             : #endif  // GOOGLE_PROTOBUF_ARENASTRING_H__

Generated by: LCOV version 1.16