Cockatrice/oracle/src/raw_json_scanner.h
tooomm 5d025ca0bd
Some checks are pending
CodeQL / Analyze (cpp) (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
Build Desktop / Configure (push) Waiting to run
Build Desktop / Debian 13 (push) Blocked by required conditions
Build Desktop / Debian 12 (push) Blocked by required conditions
Build Desktop / Fedora 44 (push) Blocked by required conditions
Build Desktop / Fedora 43 (push) Blocked by required conditions
Build Desktop / Servatrice_Debian 12 (push) Blocked by required conditions
Build Desktop / Ubuntu 26.04 (push) Blocked by required conditions
Build Desktop / Ubuntu 24.04 (push) Blocked by required conditions
Build Desktop / Arch (push) Blocked by required conditions
Build Desktop / macOS 13 Intel (push) Blocked by required conditions
Build Desktop / macOS 14 (push) Blocked by required conditions
Build Desktop / macOS 15 (push) Blocked by required conditions
Build Desktop / macOS 26 Debug (push) Blocked by required conditions
Build Desktop / Windows 10 (push) Blocked by required conditions
Build Docker / Servatrice (arm) (push) Waiting to run
Build Docker / Servatrice (x86) (push) Waiting to run
Build Docker / Publish multi-platform Servatrice image (push) Blocked by required conditions
Use capitalized app names (#7255)
* use capitalized app name

* update urls

* app description

* Update main.cpp
2026-09-12 17:30:46 +02:00

89 lines
No EOL
3.2 KiB
C++

#ifndef RAW_JSON_SCANNER_H
#define RAW_JSON_SCANNER_H
#include <QByteArray>
#include <QList>
#include <QString>
#include <functional>
namespace RawJson
{
/**
* @brief The byte extent of a set's object inside the scanned document, plus
* the size of its cards array. This is the slice SetToDownload needs for lazy
* per-set parsing; the metadata strings live in SetRange alongside it.
*/
struct SetDataRange
{
/** @brief Byte offset of the set's object within the scanned buffer. */
qsizetype start = -1;
/** @brief Byte length of the set's object, including the surrounding braces. */
qsizetype length = 0;
/** @brief Number of entries in the set's "cards" array. */
int cardCount = 0;
};
struct SetRange
{
/** @brief The byte slice of this set within the document. */
SetDataRange dataRange;
QString code;
QString name;
QString type;
QString releaseDate;
};
struct ScanError
{
bool isError() const
{
return !message.isEmpty();
}
QString message;
};
/**
* @brief Optional progress callback receiving @c (bytesRead, totalBytes) while
* the document is walked. Invoked from the scanning thread; the caller decides
* how the throttled offsets are relayed to a GUI event loop.
*/
using ScanProgressCallback = std::function<void(qsizetype bytesRead, qsizetype totalBytes)>;
/**
* @brief Scans a full MTGJSON document without materializing the JSON tree.
*
* Splits the top-level "data" object into per-set byte ranges and reads each
* set's metadata directly from the raw bytes. The Oracle importer can then
* parse one set at a time during import, keeping peak memory far below a single
* QJsonDocument::fromJson() over the whole file.
*
* The whole document is structurally validated while scanning (strings,
* escapes, braces, and a trailing-content check) and nesting depth is capped at
* 1024 to match QJsonDocument, so pathologically deep documents fail shallowly
* instead of exhausting the stack. Verdicts agree with QJsonDocument::fromJson
* on structurally malformed input; unlike Qt, string metadata fields
* ("name", "type", "releaseDate", "code") tolerate null / non-string values by
* defaulting to empty rather than rejecting the whole document, so one broken
* set cannot abort the import of the rest.
*
* Following QJsonDocument::fromJson's convention, the parsed ranges are
* returned by value and any failure is reported through the @p error out
* parameter.
*
* @param json The raw MTGJSON document bytes.
* @param error Out parameter. Set to an error ScanError when the document
* cannot be parsed, otherwise left empty. Passing a null
* pointer disables error reporting.
* @param progress Optional progress callback. When non-empty it is invoked as
* the scanner advances through the document, throttled to a
* tiny fraction of the total size.
* @return The detected per-set ranges, or an empty list on failure.
*/
QList<SetRange> scanSetRanges(const QByteArray &json,
ScanError *error = nullptr,
const ScanProgressCallback &progress = ScanProgressCallback());
} // namespace RawJson
#endif // RAW_JSON_SCANNER_H