Files
simdjson-simdjson/include/simdjson/document.h
T
2020-02-18 08:37:07 -08:00

112 lines
3.1 KiB
C++

#ifndef SIMDJSON_DOCUMENT_H
#define SIMDJSON_DOCUMENT_H
#include <cstring>
#include <memory>
#include "simdjson/common_defs.h"
#include "simdjson/simdjson.h"
#include "simdjson/padded_string.h"
#define JSON_VALUE_MASK 0xFFFFFFFFFFFFFF
#define DEFAULT_MAX_DEPTH 1024 // a JSON document with a depth exceeding 1024 is probably de facto invalid
namespace simdjson {
template<size_t max_depth> class document_iterator;
class document_parser;
class document {
public:
// create a document container with zero capacity, parser will allocate capacity as needed
document()=default;
~document()=default;
// this is a move only class
document(document &&p) = default;
document(const document &p) = delete;
document &operator=(document &&o) = default;
document &operator=(const document &o) = delete;
using iterator = document_iterator<DEFAULT_MAX_DEPTH>;
class parser;
class doc_result;
class doc_ref_result;
//
// Tell whether this document has been parsed, or is just empty.
//
bool is_initialized() {
return tape && string_buf;
}
// print the json to std::ostream (should be valid)
// return false if the tape is likely wrong (e.g., you did not parse a valid
// JSON).
WARN_UNUSED
bool print_json(std::ostream &os, size_t max_depth=DEFAULT_MAX_DEPTH) const;
WARN_UNUSED
bool dump_raw_tape(std::ostream &os) const;
//
// Parse a JSON document.
//
// If you will be parsing more than one JSON document, it's recommended to create a
// document::parser object instead, keeping internal buffers around for efficiency reasons.
//
// Throws invalid_json if the JSON is invalid.
//
static doc_result parse(const uint8_t *buf, size_t len, bool realloc_if_needed = true);
static doc_result parse(const char *buf, size_t len, bool realloc_if_needed = true);
static doc_result parse(const std::string &s, bool realloc_if_needed = true);
static doc_result parse(const padded_string &s);
std::unique_ptr<uint64_t[]> tape;
std::unique_ptr<uint8_t[]> string_buf;// should be at least byte_capacity
private:
bool set_capacity(size_t len);
};
class document::doc_result {
private:
doc_result(document &&_doc, error_code _error) : doc(std::move(_doc)), error(_error) { }
doc_result(document &&_doc) : doc(std::move(_doc)), error(SUCCESS) { }
doc_result(error_code _error) : doc(), error(_error) { }
friend class document;
public:
~doc_result()=default;
operator bool() noexcept { return error == SUCCESS; }
operator document() {
if (!*this) {
throw invalid_json(error);
}
return std::move(doc);
}
document doc;
error_code error;
};
class document::doc_ref_result {
public:
doc_ref_result(document &_doc, error_code _error) : doc(_doc), error(_error) { }
~doc_ref_result()=default;
operator bool() noexcept { return error == SUCCESS; }
operator document&() {
if (!*this) {
throw invalid_json(error);
}
return doc;
}
document& doc;
error_code error;
};
} // namespace simdjson
#include "simdjson/document_parser.h"
#include "simdjson/document_iterator.h"
#endif // SIMDJSON_DOCUMENT_H