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