blob: 28c933c2185b4037ecfaf0528fbb4045131b4145 [file] [log] [blame]
Parker Schuh149161a2016-03-16 21:57:21 -07001#ifndef AOS_PROTOBUF_STACK_ARENA_H_
2#define AOS_PROTOBUF_STACK_ARENA_H_
3#include "google/protobuf/arena.h"
4
5namespace aos {
6namespace protobuf {
7
8void* FatalArenaBlockAlloc(size_t);
9
10void FatalArenaBlockDealloc(void*, size_t);
11
12// This class manages a protobuf arena which uses an internal buffer
13// (allocated as part of the object) of size buffer_size.
14//
15// Protos allocated from this arena must not use more than buffer_size
16// worth of data.
17//
18// Also worth noting is that sizeof(google::protobuf::Arena::Block)
19// is used up out of the buffer for internal protobuf related usage, so
20// overallocate accordingly.
21template <size_t buffer_size>
22class StackProtoArena {
23 public:
24 StackProtoArena() :
25 arena_(GetArenaOptions(&data_[0])) {}
26
27 google::protobuf::Arena* arena() { return &arena_; }
28
29 // For convienence:
30 template <typename T>
31 T* CreateMessage() {
32 return google::protobuf::Arena::CreateMessage<T>(&arena_);
33 }
34 private:
35 static google::protobuf::ArenaOptions GetArenaOptions(char* data) {
36 // Expecting RVO to kick in.
37 google::protobuf::ArenaOptions options;
38 options.initial_block = data;
39 options.initial_block_size = buffer_size;
40 options.block_alloc = &FatalArenaBlockAlloc;
41 options.block_dealloc = FatalArenaBlockDealloc;
42 return options;
43 }
44
45 char data_[buffer_size];
46 google::protobuf::Arena arena_;
47};
48
49} // namespace protobuf
50} // namespace aos
51
52#endif // AOS_PROTOBUF_STACK_ARENA_H_