mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
112 lines
3.1 KiB
C++
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
|