Rename, move some json stuff to header

This commit is contained in:
Chris Marsh 2017-07-24 10:54:47 -07:00
parent 449584b9c9
commit 88ab85c81e
5 changed files with 87 additions and 84 deletions

View file

@ -79,7 +79,7 @@ extern "C" void Discord_UpdateConnection()
} }
else { else {
// reads // reads
rapidjson::Document message; JsonDocument message;
while (Connection->Read(message)) { while (Connection->Read(message)) {
auto nonce = message.FindMember("nonce"); auto nonce = message.FindMember("nonce");
if (nonce != message.MemberEnd() && nonce->value.IsString()) { if (nonce != message.MemberEnd() && nonce->value.IsString()) {

View file

@ -34,7 +34,7 @@ void RpcConnection::Open()
} }
if (state == State::SentHandshake) { if (state == State::SentHandshake) {
rapidjson::Document message; JsonDocument message;
if (Read(message)) { if (Read(message)) {
auto cmd = message.FindMember("cmd"); auto cmd = message.FindMember("cmd");
if (cmd == message.MemberEnd() || !cmd->value.IsString()) { if (cmd == message.MemberEnd() || !cmd->value.IsString()) {
@ -86,7 +86,7 @@ bool RpcConnection::Write(const void* data, size_t length)
return true; return true;
} }
bool RpcConnection::Read(rapidjson::Document& message) bool RpcConnection::Read(JsonDocument& message)
{ {
if (state != State::Connected && state != State::SentHandshake) { if (state != State::Connected && state != State::SentHandshake) {
return false; return false;

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "connection.h" #include "connection.h"
#include "rapidjson/document.h" #include "serialization.h"
// I took this from the buffer size libuv uses for named pipes; I suspect ours would usually be much smaller. // I took this from the buffer size libuv uses for named pipes; I suspect ours would usually be much smaller.
constexpr size_t MaxRpcFrameSize = 64 * 1024; constexpr size_t MaxRpcFrameSize = 64 * 1024;
@ -50,5 +50,5 @@ struct RpcConnection {
void Open(); void Open();
void Close(); void Close();
bool Write(const void* data, size_t length); bool Write(const void* data, size_t length);
bool Read(rapidjson::Document& message); bool Read(JsonDocument& message);
}; };

View file

@ -1,85 +1,7 @@
#include "serialization.h"
#include "connection.h" #include "connection.h"
#include "discord-rpc.h" #include "discord-rpc.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/internal/itoa.h"
// I want to use as few allocations as I can get away with, and to do that with RapidJson, you need to supply some of
// your own allocators for stuff rather than use the defaults
class LinearAllocator {
public:
char* buffer_;
char* end_;
LinearAllocator() {
assert(0); // needed for some default case in rapidjson, should not use
}
LinearAllocator(char* buffer, size_t size) : buffer_(buffer), end_(buffer + size) {}
static const bool kNeedFree = false;
void* Malloc(size_t size)
{
char* res = buffer_;
buffer_ += size;
if (buffer_ > end_) {
buffer_ = res;
return nullptr;
}
return res;
}
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
{
if (newSize == 0) {
return nullptr;
}
// allocate how much you need in the first place
assert(!originalPtr && !originalSize);
return Malloc(newSize);
}
static void Free(void* ptr) { /* shrug */ }
};
template<int Size>
class FixedLinearAllocator : public LinearAllocator {
public:
char fixedBuffer_[Size];
FixedLinearAllocator() : LinearAllocator(fixedBuffer_, Size) {}
static const bool kNeedFree = false;
};
// wonder why this isn't a thing already, maybe I missed it
class DirectStringBuffer {
public:
typedef typename char Ch;
char* buffer_;
char* end_;
char* current_;
DirectStringBuffer(char* buffer, size_t maxLen)
: buffer_(buffer)
, end_(buffer + maxLen)
, current_(buffer)
{}
void Put(char c)
{
if (current_ < end_) {
*current_++ = c;
}
}
void Flush() {}
size_t GetSize() const
{
return current_ - buffer_;
}
};
using Encoding = rapidjson::UTF8<char>;
// Writer appears to need about 16 bytes per nested object level (with 64bit size_t)
using WriterAllocator = FixedLinearAllocator<2048>;
constexpr size_t WriterNestingLevels = 2048 / 16;
using JsonWriter = rapidjson::Writer<DirectStringBuffer, Encoding, Encoding, WriterAllocator, rapidjson::kWriteNoFlags>;
// it's ever so slightly faster to not have to strlen the key // it's ever so slightly faster to not have to strlen the key
template<typename T> template<typename T>
void WriteKey(JsonWriter& w, T& k) { void WriteKey(JsonWriter& w, T& k) {

View file

@ -2,6 +2,11 @@
#include <stdint.h> #include <stdint.h>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/internal/itoa.h"
// if only there was a standard library function for this // if only there was a standard library function for this
template<size_t Len> template<size_t Len>
inline size_t StringCopy(char (&dest)[Len], const char* src) { inline size_t StringCopy(char (&dest)[Len], const char* src) {
@ -23,3 +28,79 @@ size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char*
struct DiscordRichPresence; struct DiscordRichPresence;
size_t JsonWriteRichPresenceObj(char* dest, size_t maxLen, int nonce, int pid, const DiscordRichPresence* presence); size_t JsonWriteRichPresenceObj(char* dest, size_t maxLen, int nonce, int pid, const DiscordRichPresence* presence);
size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName); size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName);
// I want to use as few allocations as I can get away with, and to do that with RapidJson, you need to supply some of
// your own allocators for stuff rather than use the defaults
class LinearAllocator {
public:
char* buffer_;
char* end_;
LinearAllocator() {
assert(0); // needed for some default case in rapidjson, should not use
}
LinearAllocator(char* buffer, size_t size) : buffer_(buffer), end_(buffer + size) {}
static const bool kNeedFree = false;
void* Malloc(size_t size)
{
char* res = buffer_;
buffer_ += size;
if (buffer_ > end_) {
buffer_ = res;
return nullptr;
}
return res;
}
void* Realloc(void* originalPtr, size_t originalSize, size_t newSize)
{
if (newSize == 0) {
return nullptr;
}
// allocate how much you need in the first place
assert(!originalPtr && !originalSize);
return Malloc(newSize);
}
static void Free(void* ptr) { /* shrug */ }
};
template<int Size>
class FixedLinearAllocator : public LinearAllocator {
public:
char fixedBuffer_[Size];
FixedLinearAllocator() : LinearAllocator(fixedBuffer_, Size) {}
static const bool kNeedFree = false;
};
// wonder why this isn't a thing already, maybe I missed it
class DirectStringBuffer {
public:
typedef typename char Ch;
char* buffer_;
char* end_;
char* current_;
DirectStringBuffer(char* buffer, size_t maxLen)
: buffer_(buffer)
, end_(buffer + maxLen)
, current_(buffer)
{}
void Put(char c)
{
if (current_ < end_) {
*current_++ = c;
}
}
void Flush() {}
size_t GetSize() const
{
return current_ - buffer_;
}
};
using UTF8 = rapidjson::UTF8<char>;
// Writer appears to need about 16 bytes per nested object level (with 64bit size_t)
using WriterAllocator = FixedLinearAllocator<2048>;
constexpr size_t WriterNestingLevels = 2048 / (2 * sizeof(size_t));
using JsonWriter = rapidjson::Writer<DirectStringBuffer, UTF8, UTF8, WriterAllocator, rapidjson::kWriteNoFlags>;
using JsonDocument = rapidjson::GenericDocument<UTF8>;