blob: 28c933c2185b4037ecfaf0528fbb4045131b4145 [file] [log] [blame]
#ifndef AOS_PROTOBUF_STACK_ARENA_H_
#define AOS_PROTOBUF_STACK_ARENA_H_
#include "google/protobuf/arena.h"
namespace aos {
namespace protobuf {
void* FatalArenaBlockAlloc(size_t);
void FatalArenaBlockDealloc(void*, size_t);
// This class manages a protobuf arena which uses an internal buffer
// (allocated as part of the object) of size buffer_size.
//
// Protos allocated from this arena must not use more than buffer_size
// worth of data.
//
// Also worth noting is that sizeof(google::protobuf::Arena::Block)
// is used up out of the buffer for internal protobuf related usage, so
// overallocate accordingly.
template <size_t buffer_size>
class StackProtoArena {
public:
StackProtoArena() :
arena_(GetArenaOptions(&data_[0])) {}
google::protobuf::Arena* arena() { return &arena_; }
// For convienence:
template <typename T>
T* CreateMessage() {
return google::protobuf::Arena::CreateMessage<T>(&arena_);
}
private:
static google::protobuf::ArenaOptions GetArenaOptions(char* data) {
// Expecting RVO to kick in.
google::protobuf::ArenaOptions options;
options.initial_block = data;
options.initial_block_size = buffer_size;
options.block_alloc = &FatalArenaBlockAlloc;
options.block_dealloc = FatalArenaBlockDealloc;
return options;
}
char data_[buffer_size];
google::protobuf::Arena arena_;
};
} // namespace protobuf
} // namespace aos
#endif // AOS_PROTOBUF_STACK_ARENA_H_