/* * upb - a minimalist implementation of protocol buffers. * * Copyright (c) 2009 Google Inc. See LICENSE for details. * Author: Josh Haberman * * 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 #include // 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(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 To down_cast(From* f); // Casts to a direct subclass. If the class does not actually match the given // subtype, returns NULL. template 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_ */