1 | /* |
2 | * Copyright 2016-present Facebook, Inc. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | #pragma once |
17 | #include <folly/CPortability.h> |
18 | #include <folly/Optional.h> |
19 | #include <folly/dynamic.h> |
20 | #include <folly/io/IOBuf.h> |
21 | #include <folly/io/IOBufQueue.h> |
22 | #include <unordered_map> |
23 | |
24 | /* This is an implementation of the BSER binary serialization scheme. |
25 | * BSER was created as a binary, local-system-only representation of |
26 | * JSON values. It is more space efficient in its output text than JSON, |
27 | * and cheaper to decode. |
28 | * It has no requirement that string values be UTF-8. |
29 | * BSER was created for use with Watchman. |
30 | * https://facebook.github.io/watchman/docs/bser.html |
31 | */ |
32 | |
33 | namespace folly { |
34 | namespace bser { |
35 | |
36 | class FOLLY_EXPORT BserDecodeError : public std::runtime_error { |
37 | public: |
38 | using std::runtime_error::runtime_error; |
39 | }; |
40 | |
41 | enum class BserType : int8_t { |
42 | Array = 0, |
43 | Object, |
44 | String, |
45 | Int8, |
46 | Int16, |
47 | Int32, |
48 | Int64, |
49 | Real, |
50 | True, |
51 | False, |
52 | Null, |
53 | Template, |
54 | Skip, |
55 | }; |
56 | extern const uint8_t kMagic[2]; |
57 | |
58 | struct serialization_opts { |
59 | serialization_opts(); |
60 | |
61 | // Whether to sort keys of object values before serializing them. |
62 | // Note that this is potentially slow and that it does not apply |
63 | // to templated arrays defined via defineTemplate; its keys are always |
64 | // emitted in the order defined by the template. |
65 | bool sort_keys; |
66 | |
67 | // incremental growth size for the underlying Appender when allocating |
68 | // storage for the encoded output |
69 | size_t growth_increment; |
70 | |
71 | // BSER allows generating a more space efficient representation of a list of |
72 | // object values. These are stored as an "object template" listing the keys |
73 | // of the objects ahead of the objects themselves. The objects are then |
74 | // serialized without repeating the key string for each element. |
75 | // |
76 | // You may use the templates field to associate a template with an |
77 | // array. You should construct this map after all mutations have been |
78 | // performed on the dynamic instance that you intend to serialize as bser, |
79 | // as it captures the address of the dynamic to match at encoding time. |
80 | // https://facebook.github.io/watchman/docs/bser.html#array-of-templated-objects |
81 | using TemplateMap = std::unordered_map<const folly::dynamic*, folly::dynamic>; |
82 | folly::Optional<TemplateMap> templates; |
83 | }; |
84 | |
85 | // parse a BSER value from a variety of sources. |
86 | // The complete BSER data must be present to succeed. |
87 | folly::dynamic parseBser(folly::StringPiece); |
88 | folly::dynamic parseBser(folly::ByteRange); |
89 | folly::dynamic parseBser(const folly::IOBuf*); |
90 | |
91 | // When reading incrementally, it is useful to know how much data to |
92 | // read to fully decode a BSER pdu. |
93 | // Throws std::out_of_range if more data needs to be read to decode |
94 | // the header, or throws a runtime_error if the header is invalid |
95 | size_t decodePduLength(const folly::IOBuf*); |
96 | |
97 | folly::fbstring toBser(folly::dynamic const&, const serialization_opts&); |
98 | std::unique_ptr<folly::IOBuf> toBserIOBuf( |
99 | folly::dynamic const&, |
100 | const serialization_opts&); |
101 | } // namespace bser |
102 | } // namespace folly |
103 | |
104 | /* vim:ts=2:sw=2:et: |
105 | */ |
106 | |