File: json_wrapper.cc

package info (click to toggle)
golang-github-google-certificate-transparency 0.0~git20160709.0.0f6e3d1~ds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 5,676 kB
  • sloc: cpp: 35,278; python: 11,838; java: 1,911; sh: 1,885; makefile: 950; xml: 520; ansic: 225
file content (77 lines) | stat: -rw-r--r-- 2,290 bytes parent folder | download
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
#include "json_wrapper.h"

#include <memory>

using std::unique_ptr;


JsonObject::JsonObject(evbuffer* buffer) : obj_(NULL) {
  const unique_ptr<json_tokener, void (*)(json_tokener*)> tokener(
      json_tokener_new(), json_tokener_free);

  evbuffer_ptr ptr;
  evbuffer_ptr_set(buffer, &ptr, 0, EVBUFFER_PTR_SET);

  unsigned amount_consumed(0);

  while (!obj_ && amount_consumed < evbuffer_get_length(buffer)) {
    evbuffer_iovec chunk;

    if (evbuffer_peek(buffer, -1, &ptr, &chunk, 1) < 1) {
      // No more data.
      break;
    }

    // This function can be called repeatedly with each chunk of
    // data. It keeps its state in "*tokener", and will return a
    // non-NULL value once it finds a full object. If it returns NULL
    // and the error is "json_tokener_continue", this simply means
    // that it hasn't yet found an object, we just need to keep
    // calling it with more data.
    obj_ = json_tokener_parse_ex(tokener.get(),
                                 static_cast<char*>(chunk.iov_base),
                                 chunk.iov_len);

    // Check for a parsing error.
    if (!obj_ &&
        json_tokener_get_error(tokener.get()) != json_tokener_continue) {
      VLOG(1) << "json_tokener_parse_ex: "
              << json_tokener_error_desc(
                     json_tokener_get_error(tokener.get()));
      break;
    }

    if (obj_) {
      // At the end of the parsing, we might not have consumed all the
      // bytes in the iovec.
      amount_consumed += tokener->char_offset;
      // No need to update "ptr" here, we're done.
    } else {
      amount_consumed += chunk.iov_len;
      evbuffer_ptr_set(buffer, &ptr, chunk.iov_len, EVBUFFER_PTR_ADD);
    }
  }

  // If the parsing was successful, drain the number of bytes
  // consumed.
  if (obj_) {
    evbuffer_drain(buffer, amount_consumed);
  }
}


JsonObject::JsonObject(const JsonArray& from, int offset, json_type type) {
  obj_ = json_object_array_get_idx(from.obj_, offset);
  if (obj_ != NULL) {
    if (!json_object_is_type(obj_, type)) {
      LOG(ERROR) << "Don't understand index " << offset << ": "
                 << from.ToJson();
      obj_ = NULL;
      return;
    }
  } else {
    LOG(ERROR) << "No index " << offset;
    return;
  }
  json_object_get(obj_);
}