64324e329e
Summary: As you know, almost all compilers support "pragma once" keyword instead of using include guards. To be keep consistency between header files, all header files are edited. Besides this, try to fix some warnings about loss of data. Pull Request resolved: https://github.com/facebook/rocksdb/pull/4339 Differential Revision: D9654990 Pulled By: ajkr fbshipit-source-id: c2cf3d2d03a599847684bed81378c401920ca848
180 lines
4.3 KiB
C++
180 lines
4.3 KiB
C++
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
// (found in the LICENSE.Apache file in the root directory).
|
|
|
|
/*
|
|
* This header file defines FbsonInBuffer and FbsonOutStream classes.
|
|
*
|
|
* ** Input Buffer **
|
|
* FbsonInBuffer is a customer input buffer to wrap raw character buffer. Its
|
|
* object instances are used to create std::istream objects interally.
|
|
*
|
|
* ** Output Stream **
|
|
* FbsonOutStream is a custom output stream classes, to contain the FBSON
|
|
* serialized binary. The class is conveniently used to specialize templates of
|
|
* FbsonParser and FbsonWriter.
|
|
*
|
|
* @author Tian Xia <tianx@fb.com>
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#ifndef __STDC_FORMAT_MACROS
|
|
#define __STDC_FORMAT_MACROS
|
|
#endif
|
|
|
|
#if defined OS_WIN && !defined snprintf
|
|
#define snprintf _snprintf
|
|
#endif
|
|
|
|
#include <inttypes.h>
|
|
#include <iostream>
|
|
|
|
namespace fbson {
|
|
|
|
// lengths includes sign
|
|
#define MAX_INT_DIGITS 11
|
|
#define MAX_INT64_DIGITS 20
|
|
#define MAX_DOUBLE_DIGITS 23 // 1(sign)+16(significant)+1(decimal)+5(exponent)
|
|
|
|
/*
|
|
* FBSON's implementation of input buffer
|
|
*/
|
|
class FbsonInBuffer : public std::streambuf {
|
|
public:
|
|
FbsonInBuffer(const char* str, uint32_t len) {
|
|
// this is read buffer and the str will not be changed
|
|
// so we use const_cast (ugly!) to remove constness
|
|
char* pch(const_cast<char*>(str));
|
|
setg(pch, pch, pch + len);
|
|
}
|
|
};
|
|
|
|
/*
|
|
* FBSON's implementation of output stream.
|
|
*
|
|
* This is a wrapper of a char buffer. By default, the buffer capacity is 1024
|
|
* bytes. We will double the buffer if realloc is needed for writes.
|
|
*/
|
|
class FbsonOutStream : public std::ostream {
|
|
public:
|
|
explicit FbsonOutStream(uint32_t capacity = 1024)
|
|
: std::ostream(nullptr),
|
|
head_(nullptr),
|
|
size_(0),
|
|
capacity_(capacity),
|
|
alloc_(true) {
|
|
if (capacity_ == 0) {
|
|
capacity_ = 1024;
|
|
}
|
|
|
|
head_ = (char*)malloc(capacity_);
|
|
}
|
|
|
|
FbsonOutStream(char* buffer, uint32_t capacity)
|
|
: std::ostream(nullptr),
|
|
head_(buffer),
|
|
size_(0),
|
|
capacity_(capacity),
|
|
alloc_(false) {
|
|
assert(buffer && capacity_ > 0);
|
|
}
|
|
|
|
~FbsonOutStream() {
|
|
if (alloc_) {
|
|
free(head_);
|
|
}
|
|
}
|
|
|
|
void put(char c) { write(&c, 1); }
|
|
|
|
void write(const char* c_str) { write(c_str, (uint32_t)strlen(c_str)); }
|
|
|
|
void write(const char* bytes, uint32_t len) {
|
|
if (len == 0)
|
|
return;
|
|
|
|
if (size_ + len > capacity_) {
|
|
realloc(len);
|
|
}
|
|
|
|
memcpy(head_ + size_, bytes, len);
|
|
size_ += len;
|
|
}
|
|
|
|
// write the integer to string
|
|
void write(int i) {
|
|
// snprintf automatically adds a NULL, so we need one more char
|
|
if (size_ + MAX_INT_DIGITS + 1 > capacity_) {
|
|
realloc(MAX_INT_DIGITS + 1);
|
|
}
|
|
|
|
int len = snprintf(head_ + size_, MAX_INT_DIGITS + 1, "%d", i);
|
|
assert(len > 0);
|
|
size_ += len;
|
|
}
|
|
|
|
// write the 64bit integer to string
|
|
void write(int64_t l) {
|
|
// snprintf automatically adds a NULL, so we need one more char
|
|
if (size_ + MAX_INT64_DIGITS + 1 > capacity_) {
|
|
realloc(MAX_INT64_DIGITS + 1);
|
|
}
|
|
|
|
int len = snprintf(head_ + size_, MAX_INT64_DIGITS + 1, "%" PRIi64, l);
|
|
assert(len > 0);
|
|
size_ += len;
|
|
}
|
|
|
|
// write the double to string
|
|
void write(double d) {
|
|
// snprintf automatically adds a NULL, so we need one more char
|
|
if (size_ + MAX_DOUBLE_DIGITS + 1 > capacity_) {
|
|
realloc(MAX_DOUBLE_DIGITS + 1);
|
|
}
|
|
|
|
int len = snprintf(head_ + size_, MAX_DOUBLE_DIGITS + 1, "%.15g", d);
|
|
assert(len > 0);
|
|
size_ += len;
|
|
}
|
|
|
|
pos_type tellp() const { return size_; }
|
|
|
|
void seekp(pos_type pos) { size_ = (uint32_t)pos; }
|
|
|
|
const char* getBuffer() const { return head_; }
|
|
|
|
pos_type getSize() const { return tellp(); }
|
|
|
|
private:
|
|
void realloc(uint32_t len) {
|
|
assert(capacity_ > 0);
|
|
|
|
capacity_ *= 2;
|
|
while (capacity_ < size_ + len) {
|
|
capacity_ *= 2;
|
|
}
|
|
|
|
if (alloc_) {
|
|
char* new_buf = (char*)::realloc(head_, capacity_);
|
|
assert(new_buf);
|
|
head_ = new_buf;
|
|
} else {
|
|
char* new_buf = (char*)::malloc(capacity_);
|
|
assert(new_buf);
|
|
memcpy(new_buf, head_, size_);
|
|
head_ = new_buf;
|
|
alloc_ = true;
|
|
}
|
|
}
|
|
|
|
private:
|
|
char* head_;
|
|
uint32_t size_;
|
|
uint32_t capacity_;
|
|
bool alloc_;
|
|
};
|
|
|
|
} // namespace fbson
|