Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
5.5 KiB
202 lines
5.5 KiB
/* |
|
* upb - a minimalist implementation of protocol buffers. |
|
* |
|
* Copyright (c) 2009 Google Inc. See LICENSE for details. |
|
* Author: Josh Haberman <jhaberman@gmail.com> |
|
* |
|
* This file contains shared definitions that are widely used across upb. |
|
* |
|
* This is a mixed C/C++ interface that offers a full API to both languages. |
|
* See the top-level README for more information. |
|
*/ |
|
|
|
#ifndef UPB_H_ |
|
#define UPB_H_ |
|
|
|
#include <stdbool.h> |
|
#include <stddef.h> |
|
|
|
// inline if possible, emit standalone code if required. |
|
#ifdef __cplusplus |
|
#define UPB_INLINE inline |
|
#else |
|
#define UPB_INLINE static inline |
|
#endif |
|
|
|
#if __STDC_VERSION__ >= 199901L |
|
#define UPB_C99 |
|
#endif |
|
|
|
#if ((defined(__cplusplus) && __cplusplus >= 201103L) || \ |
|
defined(__GXX_EXPERIMENTAL_CXX0X__)) && !defined(UPB_NO_CXX11) |
|
#define UPB_CXX11 |
|
#endif |
|
|
|
#ifdef UPB_CXX11 |
|
#define UPB_DISALLOW_POD_OPS(class_name) \ |
|
class_name() = delete; \ |
|
~class_name() = delete; \ |
|
class_name(const class_name&) = delete; \ |
|
void operator=(const class_name&) = delete; |
|
#else |
|
#define UPB_DISALLOW_POD_OPS(class_name) \ |
|
class_name(); \ |
|
~class_name(); \ |
|
class_name(const class_name&); \ |
|
void operator=(const class_name&); |
|
#endif |
|
|
|
#ifdef __GNUC__ |
|
#define UPB_NORETURN __attribute__((__noreturn__)) |
|
#else |
|
#define UPB_NORETURN |
|
#endif |
|
|
|
#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) |
|
#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) |
|
|
|
#define UPB_UNUSED(var) (void)var |
|
|
|
// For asserting something about a variable when the variable is not used for |
|
// anything else. This prevents "unused variable" warnings when compiling in |
|
// debug mode. |
|
#define UPB_ASSERT_VAR(var, predicate) UPB_UNUSED(var); assert(predicate) |
|
|
|
|
|
/* Casts **********************************************************************/ |
|
|
|
// Upcasts for C. For downcasts see the definitions of the subtypes. |
|
#define UPB_UPCAST(obj) (&(obj)->base) |
|
#define UPB_UPCAST2(obj) UPB_UPCAST(UPB_UPCAST(obj)) |
|
|
|
#ifdef __cplusplus |
|
|
|
// Downcasts for C++. We can't use C++ inheritance directly and maintain |
|
// compatibility with C. So our inheritance is undeclared in C++. |
|
// Specializations of these casting functions are defined for appropriate type |
|
// pairs, and perform the necessary checks. |
|
// |
|
// Example: |
|
// upb::Def* def = <...>; |
|
// upb::MessageDef* = upb::dyn_cast<upb::MessageDef*>(def); |
|
// |
|
// For upcasts, see the Upcast() method in the types themselves. |
|
|
|
namespace upb { |
|
|
|
// Casts to a direct subclass. The caller must know that cast is correct; an |
|
// incorrect cast will throw an assertion failure. |
|
template<class To, class From> To down_cast(From* f); |
|
|
|
// Casts to a direct subclass. If the class does not actually match the given |
|
// subtype, returns NULL. |
|
template<class To, class From> To dyn_cast(From* f); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
/* upb::Status ****************************************************************/ |
|
|
|
#ifdef __cplusplus |
|
namespace upb { class Status; } |
|
typedef upb::Status upb_status; |
|
#else |
|
struct upb_status; |
|
typedef struct upb_status upb_status; |
|
#endif |
|
|
|
typedef enum { |
|
UPB_OK, // The operation completed successfully. |
|
UPB_SUSPENDED, // The operation was suspended and may be resumed later. |
|
UPB_ERROR, // An error occurred. |
|
} upb_success_t; |
|
|
|
typedef struct { |
|
const char *name; |
|
// Writes a NULL-terminated string to "buf" containing an error message for |
|
// the given error code, returning false if the message was too large to fit. |
|
bool (*code_to_string)(int code, char *buf, size_t len); |
|
} upb_errorspace; |
|
|
|
#ifdef __cplusplus |
|
|
|
class upb::Status { |
|
public: |
|
typedef upb_success_t Success; |
|
|
|
Status(); |
|
~Status(); |
|
|
|
bool ok() const; |
|
bool eof() const; |
|
|
|
const char *GetString() const; |
|
void SetEof(); |
|
void SetErrorLiteral(const char* msg); |
|
void Clear(); |
|
|
|
private: |
|
#else |
|
struct upb_status { |
|
#endif |
|
bool error; |
|
bool eof_; |
|
|
|
// Specific status code defined by some error space (optional). |
|
int code; |
|
upb_errorspace *space; |
|
|
|
// Error message (optional). |
|
const char *str; // NULL when no message is present. NULL-terminated. |
|
char *buf; // Owned by the status. |
|
size_t bufsize; |
|
}; |
|
|
|
#define UPB_STATUS_INIT {UPB_OK, false, 0, NULL, NULL, NULL, 0} |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
void upb_status_init(upb_status *status); |
|
void upb_status_uninit(upb_status *status); |
|
|
|
bool upb_ok(const upb_status *status); |
|
bool upb_eof(const upb_status *status); |
|
|
|
// Any of the functions that write to a status object allow status to be NULL, |
|
// to support use cases where the function's caller does not care about the |
|
// status message. |
|
void upb_status_clear(upb_status *status); |
|
void upb_status_seterrliteral(upb_status *status, const char *msg); |
|
void upb_status_seterrf(upb_status *status, const char *msg, ...); |
|
void upb_status_setcode(upb_status *status, upb_errorspace *space, int code); |
|
void upb_status_seteof(upb_status *status); |
|
// The returned string is invalidated by any other call into the status. |
|
const char *upb_status_getstr(const upb_status *status); |
|
void upb_status_copy(upb_status *to, const upb_status *from); |
|
|
|
#ifdef __cplusplus |
|
} // extern "C" |
|
|
|
namespace upb { |
|
|
|
// C++ Wrappers |
|
inline Status::Status() { upb_status_init(this); } |
|
inline Status::~Status() { upb_status_uninit(this); } |
|
inline bool Status::ok() const { return upb_ok(this); } |
|
inline bool Status::eof() const { return upb_eof(this); } |
|
inline const char *Status::GetString() const { return upb_status_getstr(this); } |
|
inline void Status::SetEof() { upb_status_seteof(this); } |
|
inline void Status::SetErrorLiteral(const char* msg) { |
|
upb_status_seterrliteral(this, msg); |
|
} |
|
inline void Status::Clear() { upb_status_clear(this); } |
|
|
|
} // namespace upb |
|
|
|
#endif |
|
|
|
#endif /* UPB_H_ */
|
|
|