summaryrefslogtreecommitdiff
path: root/bindings/cpp/upb/pb/decoder.hpp
blob: 05bcb8a78750eceef8d66c3cf6b13e53744d7c61 (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
//
// upb - a minimalist implementation of protocol buffers.
//
// Copyright (c) 2011 Google Inc.  See LICENSE for details.
// Author: Josh Haberman <jhaberman@gmail.com>
//
// upb::Decoder is a high performance, streaming decoder for protobuf
// data that works by getting its input data from a ubp::ByteRegion and calling
// into a upb::Handlers.
//
// A DecoderPlan contains whatever data structures and generated (JIT-ted) code
// are necessary to decode protobuf data of a specific type to a specific set
// of handlers.  By generating the plan ahead of time, we avoid having to
// redo this work every time we decode.
//
// A DecoderPlan is threadsafe, meaning that it can be used concurrently by
// different upb::Decoders in different threads.  However, the upb::Decoders are
// *not* thread-safe.

#ifndef UPB_PB_DECODER_HPP
#define UPB_PB_DECODER_HPP

#include "upb/pb/decoder.h"

#include "upb/bytestream.hpp"
#include "upb/upb.hpp"

namespace upb {

class DecoderPlan : public upb_decoderplan {
 public:
  static DecoderPlan* New(Handlers* h, bool allow_jit) {
    return static_cast<DecoderPlan*>(upb_decoderplan_new(h, allow_jit));
  }
  void Unref() { upb_decoderplan_unref(this); }

  // Returns true if the plan contains JIT-ted code.  This may not be the same
  // as the "allowjit" parameter to the constructor if support for JIT-ting was
  // not compiled in.
  bool HasJitCode() { return upb_decoderplan_hasjitcode(this); }

 private:
  DecoderPlan() {}  // Only constructed by New
};

class Decoder : public upb_decoder {
 public:
  Decoder() { upb_decoder_init(this); }
  ~Decoder() { upb_decoder_uninit(this); }

  // Resets the plan that the decoder will parse from.  This will also reset the
  // decoder's input to be uninitialized -- ResetInput() must be called before
  // parsing can occur.  The plan must live until the decoder is destroyed or
  // reset to a different plan.
  //
  // Must be called before ResetInput() or Decode().
  void ResetPlan(DecoderPlan* plan, int32_t msg_offset) {
    upb_decoder_resetplan(this, plan, msg_offset);
  }

  // Resets the input of the decoder.  This puts it in a state where it has not
  // seen any data, and expects the next data to be from the beginning of a new
  // protobuf.
  //
  // ResetInput() must be called before Decode() but may be called more than
  // once.  "input" must live until the decoder destroyed or ResetInput is
  // called again.  "c" is the closure that will be passed to the handlers.
  void ResetInput(ByteRegion* byte_region, void* c) {
    upb_decoder_resetinput(this, byte_region, c);
  }

  // Decodes serialized data (calling Handlers as the data is parsed) until
  // error or EOF (see status() for details).
  Success Decode() { return upb_decoder_decode(this); }

  const upb::Status& status() {
    return static_cast<const upb::Status&>(*upb_decoder_status(this));
  }
};

}  // namespace upb

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