mirror of
https://github.com/MaskRay/ccls.git
synced 2025-04-01 22:42:11 +00:00
132 lines
3.4 KiB
C++
132 lines
3.4 KiB
C++
#pragma once
|
|
|
|
#include "serializer.h"
|
|
|
|
#include <assert.h>
|
|
|
|
class BinaryReader : public Reader {
|
|
const char* p_;
|
|
|
|
template <typename T>
|
|
T Get() {
|
|
auto ret = *reinterpret_cast<const T*>(p_);
|
|
p_ += sizeof(T);
|
|
return ret;
|
|
}
|
|
|
|
uint64_t VarUInt() {
|
|
auto x = *reinterpret_cast<const uint8_t*>(p_++);
|
|
if (x < 253)
|
|
return x;
|
|
if (x == 253)
|
|
return Get<uint16_t>();
|
|
if (x == 254)
|
|
return Get<uint32_t>();
|
|
return Get<uint64_t>();
|
|
}
|
|
int64_t VarInt() {
|
|
uint64_t x = VarUInt();
|
|
return int64_t(x >> 1 ^ -(x & 1));
|
|
}
|
|
|
|
public:
|
|
BinaryReader(std::string_view buf) : p_(buf.data()) {}
|
|
SerializeFormat Format() const override {
|
|
return SerializeFormat::Binary;
|
|
}
|
|
|
|
bool IsBool() override { return true; }
|
|
// Abuse how the function is called in serializer.h
|
|
bool IsNull() override { return !*p_++; }
|
|
bool IsInt() override { return true; }
|
|
bool IsInt64() override { return true; }
|
|
bool IsUInt64() override { return true; }
|
|
bool IsDouble() override { return true; }
|
|
bool IsString() override { return true; }
|
|
|
|
void GetNull() override {}
|
|
bool GetBool() override { return Get<bool>(); }
|
|
int GetInt() override { return VarInt(); }
|
|
int64_t GetInt64() override { return VarInt(); }
|
|
uint8_t GetUInt8() override { return Get<uint8_t>(); }
|
|
uint32_t GetUInt32() override { return VarUInt(); }
|
|
uint64_t GetUInt64() override { return VarUInt(); }
|
|
double GetDouble() override { return Get<double>(); }
|
|
std::string GetString() override {
|
|
if (auto n = VarUInt()) {
|
|
std::string ret(p_, n);
|
|
p_ += n;
|
|
return ret;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
bool HasMember(const char* x) override { return true; }
|
|
std::unique_ptr<Reader> operator[](const char* x) override { return {}; }
|
|
|
|
void IterArray(std::function<void(Reader&)> fn) override {
|
|
for (auto n = VarUInt(); n; n--)
|
|
fn(*this);
|
|
}
|
|
|
|
void Member(const char*, std::function<void()> fn) override {
|
|
fn();
|
|
}
|
|
};
|
|
|
|
class BinaryWriter : public Writer {
|
|
std::string buf_;
|
|
|
|
template <typename T>
|
|
void Pack(T x) {
|
|
auto i = buf_.size();
|
|
buf_.resize(i + sizeof(x));
|
|
*reinterpret_cast<T*>(buf_.data() + i) = x;
|
|
}
|
|
|
|
void VarUInt(uint64_t n) {
|
|
if (n < 253)
|
|
Pack<uint8_t>(n);
|
|
else if (n < 65536) {
|
|
Pack<uint8_t>(253);
|
|
Pack<uint16_t>(n);
|
|
} else if (n < 4294967296) {
|
|
Pack<uint8_t>(254);
|
|
Pack<uint32_t>(n);
|
|
} else {
|
|
Pack<uint8_t>(255);
|
|
Pack<uint64_t>(n);
|
|
}
|
|
}
|
|
void VarInt(int64_t n) {
|
|
VarUInt(uint64_t(n) << 1 ^ n >> 63);
|
|
}
|
|
|
|
public:
|
|
SerializeFormat Format() const override {
|
|
return SerializeFormat::Binary;
|
|
}
|
|
std::string Take() { return std::move(buf_); }
|
|
|
|
void Null() override { Pack(uint8_t(0)); }
|
|
void Bool(bool x) override { Pack(x); }
|
|
void Int(int x) override { VarInt(x); }
|
|
void Int64(int64_t x) override { VarInt(x); }
|
|
void UInt8(uint8_t x) override { Pack(x); }
|
|
void UInt32(uint32_t x) override { VarUInt(x); }
|
|
void UInt64(uint64_t x) override { VarUInt(x); }
|
|
void Double(double x) override { Pack(x); }
|
|
void String(const char* x) override { String(x, strlen(x)); }
|
|
void String(const char* x, size_t len) override {
|
|
VarUInt(len);
|
|
auto i = buf_.size();
|
|
buf_.resize(i + len);
|
|
memcpy(buf_.data() + i, x, len);
|
|
}
|
|
void StartArray(size_t n) override { VarUInt(n); }
|
|
void EndArray() override {}
|
|
void StartObject() override {}
|
|
void EndObject() override {}
|
|
void Key(const char* name) override {}
|
|
};
|