YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/rocksdb/third-party/fbson/FbsonStream.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  Copyright (c) 2011-present, Facebook, Inc.
3
 *  All rights reserved.
4
 *
5
 *  This source code is licensed under the BSD-style license found in the
6
 *  LICENSE file in the root directory of this source tree. An additional grant
7
 *  of patent rights can be found in the PATENTS file in the same directory.
8
 *
9
 * The following only applies to changes made to this file as part of YugaByte development.
10
 *
11
 * Portions Copyright (c) YugaByte, Inc.
12
 *
13
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
14
 * in compliance with the License.  You may obtain a copy of the License at
15
 *
16
 * http://www.apache.org/licenses/LICENSE-2.0
17
 *
18
 * Unless required by applicable law or agreed to in writing, software distributed under the License
19
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
20
 * or implied.  See the License for the specific language governing permissions and limitations
21
 * under the License.
22
 *
23
 *
24
 */
25
26
/*
27
 * This header file defines FbsonInBuffer and FbsonOutStream classes.
28
 *
29
 * ** Input Buffer **
30
 * FbsonInBuffer is a customer input buffer to wrap raw character buffer. Its
31
 * object instances are used to create std::istream objects interally.
32
 *
33
 * ** Output Stream **
34
 * FbsonOutStream is a custom output stream classes, to contain the FBSON
35
 * serialized binary. The class is conveniently used to specialize templates of
36
 * FbsonParser and FbsonWriter.
37
 *
38
 * @author Tian Xia <tianx@fb.com>
39
 */
40
41
#ifndef FBSON_FBSONSTREAM_H
42
#define FBSON_FBSONSTREAM_H
43
44
#ifndef __STDC_FORMAT_MACROS
45
#define __STDC_FORMAT_MACROS
46
#endif
47
48
#if defined OS_WIN && !defined snprintf
49
#define snprintf _snprintf
50
#endif
51
52
#include <inttypes.h>
53
#include <iostream>
54
55
namespace fbson {
56
57
// lengths includes sign
58
0
#define MAX_INT_DIGITS 11
59
0
#define MAX_INT64_DIGITS 20
60
0
#define MAX_DOUBLE_DIGITS 23 // 1(sign)+16(significant)+1(decimal)+5(exponent)
61
62
/*
63
 * FBSON's implementation of input buffer
64
 */
65
class FbsonInBuffer : public std::streambuf {
66
 public:
67
54
  FbsonInBuffer(const char* str, uint32_t len) {
68
    // this is read buffer and the str will not be changed
69
    // so we use const_cast (ugly!) to remove constness
70
54
    char* pch(const_cast<char*>(str));
71
54
    setg(pch, pch, pch + len);
72
54
  }
73
};
74
75
/*
76
 * FBSON's implementation of output stream.
77
 *
78
 * This is a wrapper of a char buffer. By default, the buffer capacity is 1024
79
 * bytes. We will double the buffer if realloc is needed for writes.
80
 */
81
class FbsonOutStream : public std::ostream {
82
 public:
83
  explicit FbsonOutStream(uint32_t capacity = 1024)
84
      : std::ostream(nullptr),
85
        head_(nullptr),
86
        size_(0),
87
        capacity_(capacity),
88
146
        alloc_(true) {
89
146
    if (capacity_ == 0) {
90
0
      capacity_ = 1024;
91
0
    }
92
93
146
    head_ = (char*)malloc(capacity_);
94
146
  }
95
96
  FbsonOutStream(char* buffer, uint32_t capacity)
97
      : std::ostream(nullptr),
98
        head_(buffer),
99
        size_(0),
100
        capacity_(capacity),
101
0
        alloc_(false) {
102
0
    assert(buffer && capacity_ > 0);
103
0
  }
Unexecuted instantiation: fbson::FbsonOutStream::FbsonOutStream(char*, unsigned int)
Unexecuted instantiation: fbson::FbsonOutStream::FbsonOutStream(char*, unsigned int)
104
105
146
  ~FbsonOutStream() {
106
146
    if (alloc_) {
107
146
      free(head_);
108
146
    }
109
146
  }
110
111
1.04k
  void put(char c) { write(&c, 1); }
112
113
0
  void write(const char* c_str) { write(c_str, (uint32_t)strlen(c_str)); }
114
115
2.11k
  void write(const char* bytes, uint32_t len) {
116
2.11k
    if (len == 0)
117
1
      return;
118
119
2.11k
    if (size_ + len > capacity_) {
120
0
      realloc(len);
121
0
    }
122
123
2.11k
    memcpy(head_ + size_, bytes, len);
124
2.11k
    size_ += len;
125
2.11k
  }
126
127
  // write the integer to string
128
0
  void write(int i) {
129
    // snprintf automatically adds a NULL, so we need one more char
130
0
    if (size_ + MAX_INT_DIGITS + 1 > capacity_) {
131
0
      realloc(MAX_INT_DIGITS + 1);
132
0
    }
133
134
0
    int len = snprintf(head_ + size_, MAX_INT_DIGITS + 1, "%d", i);
135
0
    assert(len > 0);
136
0
    size_ += len;
137
0
  }
138
139
  // write the 64bit integer to string
140
0
  void write(int64_t l) {
141
    // snprintf automatically adds a NULL, so we need one more char
142
0
    if (size_ + MAX_INT64_DIGITS + 1 > capacity_) {
143
0
      realloc(MAX_INT64_DIGITS + 1);
144
0
    }
145
146
0
    int len = snprintf(head_ + size_, MAX_INT64_DIGITS + 1, "%" PRIi64, l);
147
0
    assert(len > 0);
148
0
    size_ += len;
149
0
  }
150
151
  // write the double to string
152
0
  void write(double d) {
153
    // snprintf automatically adds a NULL, so we need one more char
154
0
    if (size_ + MAX_DOUBLE_DIGITS + 1 > capacity_) {
155
0
      realloc(MAX_DOUBLE_DIGITS + 1);
156
0
    }
157
158
0
    int len = snprintf(head_ + size_, MAX_DOUBLE_DIGITS + 1, "%.15g", d);
159
0
    assert(len > 0);
160
0
    size_ += len;
161
0
  }
162
163
865
  pos_type tellp() const { return size_; }
164
165
692
  void seekp(pos_type pos) { size_ = (uint32_t)pos; }
166
167
155
  const char* getBuffer() const { return head_; }
168
169
236
  pos_type getSize() const { return tellp(); }
170
171
 private:
172
0
  void realloc(uint32_t len) {
173
0
    assert(capacity_ > 0);
174
175
0
    capacity_ *= 2;
176
0
    while (capacity_ < size_ + len) {
177
0
      capacity_ *= 2;
178
0
    }
179
180
0
    if (alloc_) {
181
0
      char* new_buf = (char*)::realloc(head_, capacity_);
182
0
      assert(new_buf);
183
0
      head_ = new_buf;
184
0
    } else {
185
0
      char* new_buf = (char*)::malloc(capacity_);
186
0
      assert(new_buf);
187
0
      memcpy(new_buf, head_, size_);
188
0
      head_ = new_buf;
189
0
      alloc_ = true;
190
0
    }
191
0
  }
192
193
 private:
194
  char* head_;
195
  uint32_t size_;
196
  uint32_t capacity_;
197
  bool alloc_;
198
};
199
200
} // namespace fbson
201
202
#endif // FBSON_FBSONSTREAM_H