summaryrefslogtreecommitdiff
path: root/bindings/cpp/upb/handlers.hpp
blob: a366c3d64071871d68acf0d2a87e183fa994a50b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//
// upb - a minimalist implementation of protocol buffers.
//
// Copyright (c) 2011 Google Inc.  See LICENSE for details.
// Author: Josh Haberman <jhaberman@gmail.com>
//
// upb::Handlers is a generic visitor-like interface for iterating over a
// stream of protobuf data.  You can register function pointers that will be
// called for each message and/or field as the data is being parsed or iterated
// over, without having to know the source format that we are parsing from.
// This decouples the parsing logic from the processing logic.

#ifndef UPB_HANDLERS_HPP
#define UPB_HANDLERS_HPP

#include "upb/handlers.h"

#include "upb/upb.hpp"

namespace upb {

typedef upb_fieldtype_t FieldType;
typedef upb_flow_t Flow;
typedef upb_sflow_t SubFlow;
class MessageHandlers;
class MessageDef;
class FieldDef;

class FieldHandlers : public upb_fhandlers {
 public:
  typedef upb_value_handler ValueHandler;
  typedef upb_startfield_handler StartFieldHandler;
  typedef upb_endfield_handler EndFieldHandler;

  // The FieldHandlers will live at least as long as the upb::Handlers to
  // which it belongs, but can be Ref'd/Unref'd to make it live longer (which
  // will prolong the life of the underlying upb::Handlers also).
  void Ref()   { upb_fhandlers_ref(this); }
  void Unref() { upb_fhandlers_unref(this); }

  // Functions to set this field's handlers.
  // These return "this" so they can be conveniently chained, eg.
  //   message_handlers->NewField(...)
  //       ->SetStartSequenceHandler(&StartSequence),
  //       ->SetEndSequenceHandler(&EndSequence),
  //       ->SetValueHandler(&Value);
  FieldHandlers* SetValueHandler(ValueHandler* h) {
    upb_fhandlers_setvalue(this, h); return this;
  }
  FieldHandlers* SetStartSequenceHandler(StartFieldHandler* h) {
    upb_fhandlers_setstartseq(this, h); return this;
  }
  FieldHandlers* SetEndSequenceHandler(EndFieldHandler* h) {
    upb_fhandlers_setendseq(this, h); return this;
  }
  FieldHandlers* SetStartSubmessageHandler(StartFieldHandler* h) {
    upb_fhandlers_setstartsubmsg(this, h); return this;
  }
  FieldHandlers* SetEndSubmessageHandler(EndFieldHandler* h) {
    upb_fhandlers_setendsubmsg(this, h); return this;
  }

  // Get/Set the field's bound value, which will be passed to its handlers.
  Value GetBoundValue() const { return upb_fhandlers_getfval(this); }
  FieldHandlers* SetBoundValue(Value val) {
    upb_fhandlers_setfval(this, val); return this;
  }

  // Returns the MessageHandlers to which we belong.
  MessageHandlers* GetMessageHandlers() const;
  // Returns the MessageHandlers for this field's submessage (invalid to call
  // unless this field's type UPB_TYPE(MESSAGE) or UPB_TYPE(GROUP).
  MessageHandlers* GetSubMessageHandlers() const;
  // If set to >=0, the given hasbit will be set after the value callback is
  // called (offset relative to the current closure).
  int32_t GetHasbit() const { return upb_fhandlers_gethasbit(this); }
  void SetHasbit(int32_t bit) { upb_fhandlers_sethasbit(this, bit); }

 private:
  UPB_DISALLOW_CONSTRUCT_AND_DESTRUCT(FieldHandlers);
};

class MessageHandlers : public upb_mhandlers {
 public:
  typedef upb_startmsg_handler StartMessageHandler;
  typedef upb_endmsg_handler EndMessageHandler;

  static MessageHandlers* Cast(upb_mhandlers* mh) {
    return static_cast<MessageHandlers*>(mh);
  }
  static const MessageHandlers* Cast(const upb_mhandlers* mh) {
    return static_cast<const MessageHandlers*>(mh);
  }

  // The MessageHandlers will live at least as long as the upb::Handlers to
  // which it belongs, but can be Ref'd/Unref'd to make it live longer (which
  // will prolong the life of the underlying upb::Handlers also).
  void Ref()    { upb_mhandlers_ref(this); }
  void Unref()  { upb_mhandlers_unref(this); }

  // Functions to set this message's handlers.
  // These return "this" so they can be conveniently chained, eg.
  //   handlers->NewMessageHandlers()
  //       ->SetStartMessageHandler(&StartMessage)
  //       ->SetEndMessageHandler(&EndMessage);
  MessageHandlers* SetStartMessageHandler(StartMessageHandler* h) {
    upb_mhandlers_setstartmsg(this, h); return this;
  }
  MessageHandlers* SetEndMessageHandler(EndMessageHandler* h) {
    upb_mhandlers_setendmsg(this, h); return this;
  }

  // Functions to create new FieldHandlers for this message.
  FieldHandlers* NewFieldHandlers(uint32_t fieldnum, FieldType type,
                                  bool repeated) {
    return static_cast<FieldHandlers*>(
        upb_mhandlers_newfhandlers(this, fieldnum, type, repeated));
  }

  // Like the previous but for MESSAGE or GROUP fields.  For GROUP fields, the
  // given submessage must not have any fields with this field number.
  FieldHandlers* NewFieldHandlersForSubmessage(uint32_t n, const char *name,
                                               FieldType type, bool repeated,
                                               MessageHandlers* subm) {
    (void)name;
    return static_cast<FieldHandlers*>(
        upb_mhandlers_newfhandlers_subm(this, n, type, repeated, subm));
  }

 private:
  UPB_DISALLOW_CONSTRUCT_AND_DESTRUCT(MessageHandlers);
};

class Handlers : public upb_handlers {
 public:
  // Creates a new Handlers instance.
  static Handlers* New() { return static_cast<Handlers*>(upb_handlers_new()); }

  void Ref()   { upb_handlers_ref(this); }
  void Unref() { upb_handlers_unref(this); }

  // Returns a new MessageHandlers object.  The first such message that is
  // obtained will be the top-level message for this Handlers object.
  MessageHandlers* NewMessageHandlers() {
    return static_cast<MessageHandlers*>(upb_handlers_newmhandlers(this));
  }

  // Convenience function for registering handlers for all messages and fields
  // in a MessageDef and all its children.  For every registered message,
  // OnMessage will be called on the visitor with newly-created MessageHandlers
  // and MessageDef. Likewise with OnField will be called with newly-created
  // FieldHandlers and FieldDef for each field.
  class MessageRegistrationVisitor {
   public:
    virtual ~MessageRegistrationVisitor() {}
    virtual void OnMessage(MessageHandlers* mh, const MessageDef* m) = 0;
    virtual void OnField(FieldHandlers* fh, const FieldDef* f) = 0;
  };
  MessageHandlers* RegisterMessageDef(const MessageDef& m,
                                      MessageRegistrationVisitor* visitor);

 private:
  UPB_DISALLOW_CONSTRUCT_AND_DESTRUCT(Handlers);
};

inline MessageHandlers* FieldHandlers::GetMessageHandlers() const {
  return static_cast<MessageHandlers*>(upb_fhandlers_getmsg(this));
}

inline MessageHandlers* FieldHandlers::GetSubMessageHandlers() const {
  return static_cast<MessageHandlers*>(upb_fhandlers_getsubmsg(this));
}

}  // namespace upb

#endif
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback