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
33namespace folly {
34namespace bser {
35
36class FOLLY_EXPORT BserDecodeError : public std::runtime_error {
37 public:
38 using std::runtime_error::runtime_error;
39};
40
41enum 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};
56extern const uint8_t kMagic[2];
57
58struct 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.
87folly::dynamic parseBser(folly::StringPiece);
88folly::dynamic parseBser(folly::ByteRange);
89folly::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
95size_t decodePduLength(const folly::IOBuf*);
96
97folly::fbstring toBser(folly::dynamic const&, const serialization_opts&);
98std::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