/
usr
/
include
/
google
/
protobuf
/
/usr/include/google/protobuf
mkdir
upload
Name
Size
Mode
Actions
io/
-
0755
rm
stubs/
-
0755
rm
util/
-
0755
rm
any.h
6181
0644
edit
dl
rm
any.pb.h
17726
0644
edit
dl
rm
any.proto
5878
0644
edit
dl
rm
api.pb.h
64196
0644
edit
dl
rm
api.proto
7734
0644
edit
dl
rm
arena.h
31329
0644
edit
dl
rm
arenastring.h
14674
0644
edit
dl
rm
arena_impl.h
14316
0644
edit
dl
rm
descriptor.h
96357
0644
edit
dl
rm
descriptor.pb.h
587894
0644
edit
dl
rm
descriptor.proto
37986
0644
edit
dl
rm
descriptor_database.h
19379
0644
edit
dl
rm
duration.pb.h
9865
0644
edit
dl
rm
duration.proto
4888
0644
edit
dl
rm
dynamic_message.h
9986
0644
edit
dl
rm
empty.pb.h
7683
0644
edit
dl
rm
empty.proto
2422
0644
edit
dl
rm
extension_set.h
78461
0644
edit
dl
rm
extension_set_inl.h
12756
0644
edit
dl
rm
field_mask.pb.h
11825
0644
edit
dl
rm
field_mask.proto
8192
0644
edit
dl
rm
generated_enum_reflection.h
3954
0644
edit
dl
rm
generated_enum_util.h
3266
0644
edit
dl
rm
generated_message_reflection.h
12880
0644
edit
dl
rm
generated_message_table_driven.h
12610
0644
edit
dl
rm
generated_message_util.h
9560
0644
edit
dl
rm
has_bits.h
3528
0644
edit
dl
rm
implicit_weak_message.h
7014
0644
edit
dl
rm
inlined_string_field.h
9332
0644
edit
dl
rm
map.h
46287
0644
edit
dl
rm
map_entry.h
7276
0644
edit
dl
rm
map_entry_lite.h
26016
0644
edit
dl
rm
map_field.h
31208
0644
edit
dl
rm
map_field_inl.h
14512
0644
edit
dl
rm
map_field_lite.h
7559
0644
edit
dl
rm
map_type_handler.h
39082
0644
edit
dl
rm
message.h
61613
0644
edit
dl
rm
message_lite.h
25964
0644
edit
dl
rm
metadata.h
1857
0644
edit
dl
rm
metadata_lite.h
8260
0644
edit
dl
rm
parse_context.h
29812
0644
edit
dl
rm
port.h
2050
0644
edit
dl
rm
port_def.inc
17039
0644
edit
dl
rm
port_undef.inc
3498
0644
edit
dl
rm
reflection.h
22717
0644
edit
dl
rm
reflection_ops.h
3686
0644
edit
dl
rm
repeated_field.h
101032
0644
edit
dl
rm
service.h
13159
0644
edit
dl
rm
source_context.pb.h
12740
0644
edit
dl
rm
source_context.proto
2352
0644
edit
dl
rm
struct.pb.h
43629
0644
edit
dl
rm
struct.proto
3780
0644
edit
dl
rm
text_format.h
28948
0644
edit
dl
rm
timestamp.pb.h
9928
0644
edit
dl
rm
timestamp.proto
6200
0644
edit
dl
rm
type.pb.h
105722
0644
edit
dl
rm
type.proto
6129
0644
edit
dl
rm
unknown_field_set.h
14401
0644
edit
dl
rm
wire_format.h
17660
0644
edit
dl
rm
wire_format_lite.h
84033
0644
edit
dl
rm
wrappers.pb.h
61421
0644
edit
dl
rm
wrappers.proto
4035
0644
edit
dl
rm
Edit:
/usr/include/google/protobuf/message_lite.h
(25964B)
// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Authors: wink@google.com (Wink Saville), // kenton@google.com (Kenton Varda) // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. // // Defines MessageLite, the abstract interface implemented by all (lite // and non-lite) protocol message objects. #ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__ #define GOOGLE_PROTOBUF_MESSAGE_LITE_H__ #include <climits> #include <string> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/arena.h> #include <google/protobuf/metadata_lite.h> #include <google/protobuf/stubs/once.h> #include <google/protobuf/port.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/port_def.inc> #ifdef SWIG #error "You cannot SWIG proto headers" #endif namespace google { namespace protobuf { template <typename T> class RepeatedPtrField; namespace io { class CodedInputStream; class CodedOutputStream; class ZeroCopyInputStream; class ZeroCopyOutputStream; } // namespace io namespace internal { // See parse_context.h for explanation class ParseContext; class RepeatedPtrFieldBase; class WireFormatLite; class WeakFieldMap; // We compute sizes as size_t but cache them as int. This function converts a // computed size to a cached size. Since we don't proceed with serialization // if the total size was > INT_MAX, it is not important what this function // returns for inputs > INT_MAX. However this case should not error or // GOOGLE_CHECK-fail, because the full size_t resolution is still returned from // ByteSizeLong() and checked against INT_MAX; we can catch the overflow // there. inline int ToCachedSize(size_t size) { return static_cast<int>(size); } // We mainly calculate sizes in terms of size_t, but some functions that // compute sizes return "int". These int sizes are expected to always be // positive. This function is more efficient than casting an int to size_t // directly on 64-bit platforms because it avoids making the compiler emit a // sign extending instruction, which we don't want and don't want to pay for. inline size_t FromIntSize(int size) { // Convert to unsigned before widening so sign extension is not necessary. return static_cast<unsigned int>(size); } // For cases where a legacy function returns an integer size. We GOOGLE_DCHECK() // that the conversion will fit within an integer; if this is false then we // are losing information. inline int ToIntSize(size_t size) { GOOGLE_DCHECK_LE(size, static_cast<size_t>(INT_MAX)); return static_cast<int>(size); } // This type wraps a variable whose constructor and destructor are explicitly // called. It is particularly useful for a global variable, without its // constructor and destructor run on start and end of the program lifetime. // This circumvents the initial construction order fiasco, while keeping // the address of the empty string a compile time constant. // // Pay special attention to the initialization state of the object. // 1. The object is "uninitialized" to begin with. // 2. Call Construct() or DefaultConstruct() only if the object is // uninitialized. After the call, the object becomes "initialized". // 3. Call get() and get_mutable() only if the object is initialized. // 4. Call Destruct() only if the object is initialized. // After the call, the object becomes uninitialized. template <typename T> class ExplicitlyConstructed { public: void DefaultConstruct() { new (&union_) T(); } template <typename... Args> void Construct(Args&&... args) { new (&union_) T(std::forward<Args>(args)...); } void Destruct() { get_mutable()->~T(); } constexpr const T& get() const { return reinterpret_cast<const T&>(union_); } T* get_mutable() { return reinterpret_cast<T*>(&union_); } private: // Prefer c++14 aligned_storage, but for compatibility this will do. union AlignedUnion { char space[sizeof(T)]; int64 align_to_int64; void* align_to_ptr; } union_; }; // Default empty string object. Don't use this directly. Instead, call // GetEmptyString() to get the reference. PROTOBUF_EXPORT extern ExplicitlyConstructed<std::string> fixed_address_empty_string; PROTOBUF_EXPORT inline const std::string& GetEmptyStringAlreadyInited() { return fixed_address_empty_string.get(); } PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& str); } // namespace internal // Interface to light weight protocol messages. // // This interface is implemented by all protocol message objects. Non-lite // messages additionally implement the Message interface, which is a // subclass of MessageLite. Use MessageLite instead when you only need // the subset of features which it supports -- namely, nothing that uses // descriptors or reflection. You can instruct the protocol compiler // to generate classes which implement only MessageLite, not the full // Message interface, by adding the following line to the .proto file: // // option optimize_for = LITE_RUNTIME; // // This is particularly useful on resource-constrained systems where // the full protocol buffers runtime library is too big. // // Note that on non-constrained systems (e.g. servers) when you need // to link in lots of protocol definitions, a better way to reduce // total code footprint is to use optimize_for = CODE_SIZE. This // will make the generated code smaller while still supporting all the // same features (at the expense of speed). optimize_for = LITE_RUNTIME // is best when you only have a small number of message types linked // into your binary, in which case the size of the protocol buffers // runtime itself is the biggest problem. // // Users must not derive from this class. Only the protocol compiler and // the internal library are allowed to create subclasses. class PROTOBUF_EXPORT MessageLite { public: inline MessageLite() {} virtual ~MessageLite() = default; // Basic Operations ------------------------------------------------ // Get the name of this message type, e.g. "foo.bar.BazProto". virtual std::string GetTypeName() const = 0; // Construct a new instance of the same type. Ownership is passed to the // caller. virtual MessageLite* New() const = 0; // Construct a new instance on the arena. Ownership is passed to the caller // if arena is a NULL. Default implementation for backwards compatibility. virtual MessageLite* New(Arena* arena) const; // Get the arena, if any, associated with this message. Virtual method // required for generic operations but most arena-related operations should // use the GetArena() generated-code method. Default implementation // to reduce code size by avoiding the need for per-type implementations // when types do not implement arena support. Arena* GetArena() const { return _internal_metadata_.arena(); } // Get a pointer that may be equal to this message's arena, or may not be. // If the value returned by this method is equal to some arena pointer, then // this message is on that arena; however, if this message is on some arena, // this method may or may not return that arena's pointer. As a tradeoff, // this method may be more efficient than GetArena(). The intent is to allow // underlying representations that use e.g. tagged pointers to sometimes // store the arena pointer directly, and sometimes in a more indirect way, // and allow a fastpath comparison against the arena pointer when it's easy // to obtain. void* GetMaybeArenaPointer() const { return _internal_metadata_.raw_arena_ptr(); } // Clear all fields of the message and set them to their default values. // Clear() avoids freeing memory, assuming that any memory allocated // to hold parts of the message will be needed again to hold the next // message. If you actually want to free the memory used by a Message, // you must delete it. virtual void Clear() = 0; // Quickly check if all required fields have values set. virtual bool IsInitialized() const = 0; // This is not implemented for Lite messages -- it just returns "(cannot // determine missing fields for lite message)". However, it is implemented // for full messages. See message.h. virtual std::string InitializationErrorString() const; // If |other| is the exact same class as this, calls MergeFrom(). Otherwise, // results are undefined (probably crash). virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0; // These methods return a human-readable summary of the message. Note that // since the MessageLite interface does not support reflection, there is very // little information that these methods can provide. They are shadowed by // methods of the same name on the Message interface which provide much more // information. The methods here are intended primarily to facilitate code // reuse for logic that needs to interoperate with both full and lite protos. // // The format of the returned string is subject to change, so please do not // assume it will remain stable over time. std::string DebugString() const; std::string ShortDebugString() const { return DebugString(); } // MessageLite::DebugString is already Utf8 Safe. This is to add compatibility // with Message. std::string Utf8DebugString() const { return DebugString(); } // Parsing --------------------------------------------------------- // Methods for parsing in protocol buffer format. Most of these are // just simple wrappers around MergeFromCodedStream(). Clear() will be // called before merging the input. // Fill the message with a protocol buffer parsed from the given input // stream. Returns false on a read error or if the input is in the wrong // format. A successful return does not indicate the entire input is // consumed, ensure you call ConsumedEntireMessage() to check that if // applicable. bool ParseFromCodedStream(io::CodedInputStream* input); // Like ParseFromCodedStream(), but accepts messages that are missing // required fields. bool ParsePartialFromCodedStream(io::CodedInputStream* input); // Read a protocol buffer from the given zero-copy input stream. If // successful, the entire input will be consumed. bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); // Like ParseFromZeroCopyStream(), but accepts messages that are missing // required fields. bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input); // Parse a protocol buffer from a file descriptor. If successful, the entire // input will be consumed. bool ParseFromFileDescriptor(int file_descriptor); // Like ParseFromFileDescriptor(), but accepts messages that are missing // required fields. bool ParsePartialFromFileDescriptor(int file_descriptor); // Parse a protocol buffer from a C++ istream. If successful, the entire // input will be consumed. bool ParseFromIstream(std::istream* input); // Like ParseFromIstream(), but accepts messages that are missing // required fields. bool ParsePartialFromIstream(std::istream* input); // Read a protocol buffer from the given zero-copy input stream, expecting // the message to be exactly "size" bytes long. If successful, exactly // this many bytes will have been consumed from the input. bool MergePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are // missing required fields. bool MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are // missing required fields. bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); // Parses a protocol buffer contained in a string. Returns true on success. // This function takes a string in the (non-human-readable) binary wire // format, matching the encoding output by MessageLite::SerializeToString(). // If you'd like to convert a human-readable string into a protocol buffer // object, see google::protobuf::TextFormat::ParseFromString(). bool ParseFromString(const std::string& data); // Like ParseFromString(), but accepts messages that are missing // required fields. bool ParsePartialFromString(const std::string& data); // Parse a protocol buffer contained in an array of bytes. bool ParseFromArray(const void* data, int size); // Like ParseFromArray(), but accepts messages that are missing // required fields. bool ParsePartialFromArray(const void* data, int size); // Reads a protocol buffer from the stream and merges it into this // Message. Singular fields read from the what is // already in the Message and repeated fields are appended to those // already present. // // It is the responsibility of the caller to call input->LastTagWas() // (for groups) or input->ConsumedEntireMessage() (for non-groups) after // this returns to verify that the message's end was delimited correctly. // // ParseFromCodedStream() is implemented as Clear() followed by // MergeFromCodedStream(). bool MergeFromCodedStream(io::CodedInputStream* input); // Like MergeFromCodedStream(), but succeeds even if required fields are // missing in the input. // // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream() // followed by IsInitialized(). bool MergePartialFromCodedStream(io::CodedInputStream* input); // Merge a protocol buffer contained in a string. bool MergeFromString(const std::string& data); // Serialization --------------------------------------------------- // Methods for serializing in protocol buffer format. Most of these // are just simple wrappers around ByteSize() and SerializeWithCachedSizes(). // Write a protocol buffer of this message to the given output. Returns // false on a write error. If the message is missing required fields, // this may GOOGLE_CHECK-fail. bool SerializeToCodedStream(io::CodedOutputStream* output) const; // Like SerializeToCodedStream(), but allows missing required fields. bool SerializePartialToCodedStream(io::CodedOutputStream* output) const; // Write the message to the given zero-copy output stream. All required // fields must be set. bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const; // Like SerializeToZeroCopyStream(), but allows missing required fields. bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const; // Serialize the message and store it in the given string. All required // fields must be set. bool SerializeToString(std::string* output) const; // Like SerializeToString(), but allows missing required fields. bool SerializePartialToString(std::string* output) const; // Serialize the message and store it in the given byte array. All required // fields must be set. bool SerializeToArray(void* data, int size) const; // Like SerializeToArray(), but allows missing required fields. bool SerializePartialToArray(void* data, int size) const; // Make a string encoding the message. Is equivalent to calling // SerializeToString() on a string and using that. Returns the empty // string if SerializeToString() would have returned an error. // Note: If you intend to generate many such strings, you may // reduce heap fragmentation by instead re-using the same string // object with calls to SerializeToString(). std::string SerializeAsString() const; // Like SerializeAsString(), but allows missing required fields. std::string SerializePartialAsString() const; // Serialize the message and write it to the given file descriptor. All // required fields must be set. bool SerializeToFileDescriptor(int file_descriptor) const; // Like SerializeToFileDescriptor(), but allows missing required fields. bool SerializePartialToFileDescriptor(int file_descriptor) const; // Serialize the message and write it to the given C++ ostream. All // required fields must be set. bool SerializeToOstream(std::ostream* output) const; // Like SerializeToOstream(), but allows missing required fields. bool SerializePartialToOstream(std::ostream* output) const; // Like SerializeToString(), but appends to the data to the string's // existing contents. All required fields must be set. bool AppendToString(std::string* output) const; // Like AppendToString(), but allows missing required fields. bool AppendPartialToString(std::string* output) const; // Computes the serialized size of the message. This recursively calls // ByteSizeLong() on all embedded messages. // // ByteSizeLong() is generally linear in the number of fields defined for the // proto. virtual size_t ByteSizeLong() const = 0; // Legacy ByteSize() API. PROTOBUF_DEPRECATED_MSG("Please use ByteSizeLong() instead") int ByteSize() const { return internal::ToIntSize(ByteSizeLong()); } // Serializes the message without recomputing the size. The message must not // have changed since the last call to ByteSize(), and the value returned by // ByteSize must be non-negative. Otherwise the results are undefined. void SerializeWithCachedSizes(io::CodedOutputStream* output) const { output->SetCur(_InternalSerialize(output->Cur(), output->EpsCopy())); } // Functions below here are not part of the public interface. It isn't // enforced, but they should be treated as private, and will be private // at some future time. Unfortunately the implementation of the "friend" // keyword in GCC is broken at the moment, but we expect it will be fixed. // Like SerializeWithCachedSizes, but writes directly to *target, returning // a pointer to the byte immediately after the last byte written. "target" // must point at a byte array of at least ByteSize() bytes. Whether to use // deterministic serialization, e.g., maps in sorted order, is determined by // CodedOutputStream::IsDefaultSerializationDeterministic(). uint8* SerializeWithCachedSizesToArray(uint8* target) const; // Returns the result of the last call to ByteSize(). An embedded message's // size is needed both to serialize it (because embedded messages are // length-delimited) and to compute the outer message's size. Caching // the size avoids computing it multiple times. // // ByteSize() does not automatically use the cached size when available // because this would require invalidating it every time the message was // modified, which would be too hard and expensive. (E.g. if a deeply-nested // sub-message is changed, all of its parents' cached sizes would need to be // invalidated, which is too much work for an otherwise inlined setter // method.) virtual int GetCachedSize() const = 0; virtual const char* _InternalParse(const char* /*ptr*/, internal::ParseContext* /*ctx*/) { return nullptr; } protected: template <typename T> static T* CreateMaybeMessage(Arena* arena) { return Arena::CreateMaybeMessage<T>(arena); } inline explicit MessageLite(Arena* arena) : _internal_metadata_(arena) {} internal::InternalMetadata _internal_metadata_; public: enum ParseFlags { kMerge = 0, kParse = 1, kMergePartial = 2, kParsePartial = 3, kMergeWithAliasing = 4, kParseWithAliasing = 5, kMergePartialWithAliasing = 6, kParsePartialWithAliasing = 7 }; template <ParseFlags flags, typename T> bool ParseFrom(const T& input); // Fast path when conditions match (ie. non-deterministic) // uint8* _InternalSerialize(uint8* ptr) const; virtual uint8* _InternalSerialize(uint8* ptr, io::EpsCopyOutputStream* stream) const = 0; // Identical to IsInitialized() except that it logs an error message. bool IsInitializedWithErrors() const { if (IsInitialized()) return true; LogInitializationErrorMessage(); return false; } private: // TODO(gerbens) make this a pure abstract function virtual const void* InternalGetTable() const { return NULL; } friend class internal::WireFormatLite; friend class Message; friend class internal::WeakFieldMap; void LogInitializationErrorMessage() const; bool MergeFromImpl(io::CodedInputStream* input, ParseFlags parse_flags); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); }; namespace internal { template <bool alias> bool MergeFromImpl(StringPiece input, MessageLite* msg, MessageLite::ParseFlags parse_flags); extern template bool MergeFromImpl<false>(StringPiece input, MessageLite* msg, MessageLite::ParseFlags parse_flags); extern template bool MergeFromImpl<true>(StringPiece input, MessageLite* msg, MessageLite::ParseFlags parse_flags); template <bool alias> bool MergeFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg, MessageLite::ParseFlags parse_flags); extern template bool MergeFromImpl<false>(io::ZeroCopyInputStream* input, MessageLite* msg, MessageLite::ParseFlags parse_flags); extern template bool MergeFromImpl<true>(io::ZeroCopyInputStream* input, MessageLite* msg, MessageLite::ParseFlags parse_flags); struct BoundedZCIS { io::ZeroCopyInputStream* zcis; int limit; }; template <bool alias> bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, MessageLite::ParseFlags parse_flags); extern template bool MergeFromImpl<false>(BoundedZCIS input, MessageLite* msg, MessageLite::ParseFlags parse_flags); extern template bool MergeFromImpl<true>(BoundedZCIS input, MessageLite* msg, MessageLite::ParseFlags parse_flags); template <typename T> struct SourceWrapper; template <bool alias, typename T> bool MergeFromImpl(const SourceWrapper<T>& input, MessageLite* msg, MessageLite::ParseFlags parse_flags) { return input.template MergeInto<alias>(msg, parse_flags); } } // namespace internal template <MessageLite::ParseFlags flags, typename T> bool MessageLite::ParseFrom(const T& input) { if (flags & kParse) Clear(); constexpr bool alias = (flags & kMergeWithAliasing) != 0; return internal::MergeFromImpl<alias>(input, this, flags); } // =================================================================== // Shutdown support. // Shut down the entire protocol buffers library, deleting all static-duration // objects allocated by the library or by generated .pb.cc files. // // There are two reasons you might want to call this: // * You use a draconian definition of "memory leak" in which you expect // every single malloc() to have a corresponding free(), even for objects // which live until program exit. // * You are writing a dynamically-loaded library which needs to clean up // after itself when the library is unloaded. // // It is safe to call this multiple times. However, it is not safe to use // any other part of the protocol buffers library after // ShutdownProtobufLibrary() has been called. Furthermore this call is not // thread safe, user needs to synchronize multiple calls. PROTOBUF_EXPORT void ShutdownProtobufLibrary(); namespace internal { // Register a function to be called when ShutdownProtocolBuffers() is called. PROTOBUF_EXPORT void OnShutdown(void (*func)()); // Run an arbitrary function on an arg PROTOBUF_EXPORT void OnShutdownRun(void (*f)(const void*), const void* arg); template <typename T> T* OnShutdownDelete(T* p) { OnShutdownRun([](const void* pp) { delete static_cast<const T*>(pp); }, p); return p; } } // namespace internal } // namespace protobuf } // namespace google #include <google/protobuf/port_undef.inc> #endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__
Save
cmd:
run