]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/third-party/fbson/FbsonStream.h
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
7 * This header file defines FbsonInBuffer and FbsonOutStream classes.
10 * FbsonInBuffer is a customer input buffer to wrap raw character buffer. Its
11 * object instances are used to create std::istream objects interally.
14 * FbsonOutStream is a custom output stream classes, to contain the FBSON
15 * serialized binary. The class is conveniently used to specialize templates of
16 * FbsonParser and FbsonWriter.
18 * @author Tian Xia <tianx@fb.com>
23 #ifndef __STDC_FORMAT_MACROS
24 #define __STDC_FORMAT_MACROS
27 #if defined OS_WIN && !defined snprintf
28 #define snprintf _snprintf
36 // lengths includes sign
37 #define MAX_INT_DIGITS 11
38 #define MAX_INT64_DIGITS 20
39 #define MAX_DOUBLE_DIGITS 23 // 1(sign)+16(significant)+1(decimal)+5(exponent)
42 * FBSON's implementation of input buffer
44 class FbsonInBuffer
: public std::streambuf
{
46 FbsonInBuffer(const char* str
, uint32_t len
) {
47 // this is read buffer and the str will not be changed
48 // so we use const_cast (ugly!) to remove constness
49 char* pch(const_cast<char*>(str
));
50 setg(pch
, pch
, pch
+ len
);
55 * FBSON's implementation of output stream.
57 * This is a wrapper of a char buffer. By default, the buffer capacity is 1024
58 * bytes. We will double the buffer if realloc is needed for writes.
60 class FbsonOutStream
: public std::ostream
{
62 explicit FbsonOutStream(uint32_t capacity
= 1024)
63 : std::ostream(nullptr),
72 head_
= (char*)malloc(capacity_
);
75 FbsonOutStream(char* buffer
, uint32_t capacity
)
76 : std::ostream(nullptr),
81 assert(buffer
&& capacity_
> 0);
90 void put(char c
) { write(&c
, 1); }
92 void write(const char* c_str
) { write(c_str
, (uint32_t)strlen(c_str
)); }
94 void write(const char* bytes
, uint32_t len
) {
98 if (size_
+ len
> capacity_
) {
102 memcpy(head_
+ size_
, bytes
, len
);
106 // write the integer to string
108 // snprintf automatically adds a NULL, so we need one more char
109 if (size_
+ MAX_INT_DIGITS
+ 1 > capacity_
) {
110 realloc(MAX_INT_DIGITS
+ 1);
113 int len
= snprintf(head_
+ size_
, MAX_INT_DIGITS
+ 1, "%d", i
);
118 // write the 64bit integer to string
119 void write(int64_t l
) {
120 // snprintf automatically adds a NULL, so we need one more char
121 if (size_
+ MAX_INT64_DIGITS
+ 1 > capacity_
) {
122 realloc(MAX_INT64_DIGITS
+ 1);
125 int len
= snprintf(head_
+ size_
, MAX_INT64_DIGITS
+ 1, "%" PRIi64
, l
);
130 // write the double to string
131 void write(double d
) {
132 // snprintf automatically adds a NULL, so we need one more char
133 if (size_
+ MAX_DOUBLE_DIGITS
+ 1 > capacity_
) {
134 realloc(MAX_DOUBLE_DIGITS
+ 1);
137 int len
= snprintf(head_
+ size_
, MAX_DOUBLE_DIGITS
+ 1, "%.15g", d
);
142 pos_type
tellp() const { return size_
; }
144 void seekp(pos_type pos
) { size_
= (uint32_t)pos
; }
146 const char* getBuffer() const { return head_
; }
148 pos_type
getSize() const { return tellp(); }
151 void realloc(uint32_t len
) {
152 assert(capacity_
> 0);
155 while (capacity_
< size_
+ len
) {
160 char* new_buf
= (char*)::realloc(head_
, capacity_
);
164 char* new_buf
= (char*)::malloc(capacity_
);
166 memcpy(new_buf
, head_
, size_
);