API — ICoreEssentials/Serialization
The public contract of 11 header(s) under ICoreEssentials/Serialization — 16 class/struct definition(s), 277 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
ICoreBinaryStream.h#
ICoreEssentials/Serialization/ICoreBinaryStream.h
ICoreBinaryWriter / ICoreBinaryReader -- fixed-width binary records.
The writer appends integers of 8, 16, 32 and 64 bits and IEEE-754 float32 and float64 values in a chosen byte order; the reader takes them back out. They are for file formats: STL, PLY, glTF's .bin, a geometry map.
ICoreBinaryWriter w; // little-endian by default w.writeUInt32(0x49334D50u); w.writeFloat64(0.1); w.writeFloat64Array(points, 3 * count);
ICoreBinaryReader r(w.toByteArray()); std::uint32_t magic = r.readUInt32(); double x = r.readFloat64(); // the same bits that went in
ICoreBinaryWriter#
ICoreBinaryStream.h:52 · class · pImpl · 32 declaration(s)
class ICoreBinaryWriter {
public:
explicit ICoreBinaryWriter(ICoreByteOrder order = ICoreByteOrder::LittleEndian);
~ICoreBinaryWriter();
ICoreBinaryWriter(const ICoreBinaryWriter&) = delete;
ICoreBinaryWriter& operator=(const ICoreBinaryWriter&) = delete;
ICoreBinaryWriter(ICoreBinaryWriter&&) noexcept;
ICoreBinaryWriter& operator=(ICoreBinaryWriter&&) noexcept;
// The order of every later write; bytes already written stay as they are.
void setByteOrder(ICoreByteOrder order) noexcept;
[[nodiscard]] ICoreByteOrder byteOrder() const noexcept;
void writeUInt8(std::uint8_t value);
void writeInt8(std::int8_t value);
void writeUInt16(std::uint16_t value);
void writeInt16(std::int16_t value);
void writeUInt32(std::uint32_t value);
void writeInt32(std::int32_t value);
void writeUInt64(std::uint64_t value);
void writeInt64(std::int64_t value);
void writeFloat32(float value);
void writeFloat64(double value);
// `count` values in a row, the same bytes as `count` single writes.
void writeUInt16Array(const std::uint16_t* values, std::size_t count);
void writeUInt32Array(const std::uint32_t* values, std::size_t count);
void writeUInt64Array(const std::uint64_t* values, std::size_t count);
void writeFloat32Array(const float* values, std::size_t count);
void writeFloat64Array(const double* values, std::size_t count);
// Raw bytes, as they are: byte order does not apply.
void writeBytes(const void* data, std::size_t size);
void writeBytes(const ICoreByteArray& data);
// Overwrites a value already written at `offset`, for a length or a
// checksum known only after what follows it. Returns false, and changes
// nothing, when the value would not lie wholly inside what was written.
[[nodiscard]] bool patchUInt32(std::size_t offset, std::uint32_t value);
[[nodiscard]] bool patchUInt64(std::size_t offset, std::uint64_t value);
[[nodiscard]] std::size_t size() const noexcept;
void reserve(std::size_t size);
void clear() noexcept;
// The bytes written so far. constData() is valid until the next write.
[[nodiscard]] const unsigned char* constData() const noexcept;
[[nodiscard]] ICoreByteArray toByteArray() const;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreBinaryReader#
ICoreBinaryStream.h:107 · class · pImpl · 31 declaration(s)
class ICoreBinaryReader {
public:
// Reads `data`. ICoreByteArray is implicitly shared, so this copies no bytes.
explicit ICoreBinaryReader(const ICoreByteArray& data,
ICoreByteOrder order = ICoreByteOrder::LittleEndian);
// Reads `size` bytes at `data`, which must stay valid for the reader's life.
ICoreBinaryReader(const void* data, std::size_t size,
ICoreByteOrder order = ICoreByteOrder::LittleEndian);
~ICoreBinaryReader();
ICoreBinaryReader(const ICoreBinaryReader&) = delete;
ICoreBinaryReader& operator=(const ICoreBinaryReader&) = delete;
ICoreBinaryReader(ICoreBinaryReader&&) noexcept;
ICoreBinaryReader& operator=(ICoreBinaryReader&&) noexcept;
void setByteOrder(ICoreByteOrder order) noexcept;
[[nodiscard]] ICoreByteOrder byteOrder() const noexcept;
// False once any read, seek or skip has failed; it never turns true again.
[[nodiscard]] bool ok() const noexcept;
[[nodiscard]] std::size_t size() const noexcept;
[[nodiscard]] std::size_t position() const noexcept;
[[nodiscard]] std::size_t remaining() const noexcept;
[[nodiscard]] bool atEnd() const noexcept;
// Moves to `position` (at most size()) or forward by `count`. Past the end
// they fail as a read does, and the position does not move.
bool seek(std::size_t position);
bool skip(std::size_t count);
// Each returns the value read, or 0 when it failed (see the header note).
std::uint8_t readUInt8();
std::int8_t readInt8();
std::uint16_t readUInt16();
std::int16_t readInt16();
std::uint32_t readUInt32();
std::int32_t readInt32();
std::uint64_t readUInt64();
std::int64_t readInt64();
float readFloat32();
double readFloat64();
// All-or-nothing: true and `count` values in `out`, or false and `out`
// untouched.
bool readUInt16Array(std::uint16_t* out, std::size_t count);
bool readUInt32Array(std::uint32_t* out, std::size_t count);
bool readUInt64Array(std::uint64_t* out, std::size_t count);
bool readFloat32Array(float* out, std::size_t count);
bool readFloat64Array(double* out, std::size_t count);
// Raw bytes, as they are. The ICoreByteArray form returns an empty array
// when it fails.
bool readBytes(void* out, std::size_t size);
[[nodiscard]] ICoreByteArray readByteArray(std::size_t size);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
File-scope declarations#
// Enumerator values are pinned (Platform SDK ABI rule).
enum class ICoreByteOrder : int {
LittleEndian = 0,
BigEndian = 1,
};
ICoreCompression.h#
ICoreEssentials/Serialization/ICoreCompression.h
ICoreCompression -- deflate and inflate, raw or in zlib or gzip framing.
ICoreByteArray packed = ICoreCompression::compress(bytes, ICoreCompressionFormat::Gzip);
ICoreByteArray back; ICoreCompressionError why; if (!ICoreCompression::decompress(packed, ICoreCompressionFormat::Gzip, back, &why)) { // why says what was wrong; back is empty }
THE THREE FORMATS. RawDeflate is RFC 1951 with nothing around it (what ZIP entries hold). Zlib is RFC 1950: a two-byte header, the deflate stream and an Adler-32 of the data (what PNG and PDF hold). Gzip is RFC 1952: a ten-byte header, the deflate stream, then the CRC-32 and the length of the data (a
ICoreCompression#
ICoreCompression.h:65 · class · 2 declaration(s)
class ICoreCompression {
public:
ICoreCompression() = delete;
static constexpr int defaultLevel = 6;
static constexpr std::size_t unlimited = static_cast<std::size_t>(-1);
// The compressed bytes. Empty only when the level is outside 0..9 or memory
// ran out: every valid stream, even of no data, is at least two bytes long.
[[nodiscard]] static ICoreByteArray compress(const ICoreByteArray& data,
ICoreCompressionFormat format,
int level = defaultLevel);
[[nodiscard]] static ICoreByteArray compress(const void* data, std::size_t size,
ICoreCompressionFormat format,
int level = defaultLevel);
// True with the data in `out`, or false with `out` empty and the reason in
// `*error` (when it is not null).
[[nodiscard]] static bool decompress(const ICoreByteArray& data,
ICoreCompressionFormat format,
ICoreByteArray& out,
ICoreCompressionError* error = nullptr,
std::size_t maxSize = unlimited);
[[nodiscard]] static bool decompress(const void* data, std::size_t size,
ICoreCompressionFormat format,
ICoreByteArray& out,
ICoreCompressionError* error = nullptr,
std::size_t maxSize = unlimited);
// A short English phrase for the error, for a log line or a message.
[[nodiscard]] static const char* errorText(ICoreCompressionError error) noexcept;
};
};
File-scope declarations#
// Enumerator values are pinned (Platform SDK ABI rule).
enum class ICoreCompressionFormat : int {
RawDeflate = 0,
Zlib = 1,
Gzip = 2,
};
enum class ICoreCompressionError : int {
None = 0,
InvalidArgument = 1, // a level outside 0..9, or a null pointer with a size
Truncated = 2, // the input ends inside the stream
Corrupt = 3, // not a valid stream: a bad header or bad deflate data
ChecksumMismatch= 4, // Adler-32 (zlib), or CRC-32 or length (gzip), disagree
TrailingData = 5, // bytes follow the end of the stream
TooLarge = 6, // the output would pass maxSize
OutOfMemory = 7,
};
ICoreCsv.h#
ICoreEssentials/Serialization/ICoreCsv.h
ICoreCsv / ICoreCsvReader -- comma-separated values (RFC 4180).
Reading a whole document:
std::optional<std::vector<ICoreCsv::Row>> rows = ICoreCsv::parse(text);
Reading a large file in chunks, one row at a time:
ICoreCsvReader reader; reader.addData(chunk); // as many times as needed ICoreCsv::Row row; while (reader.readRow(row)) { ... } // rows complete so far reader.finish(); // at end of input while (reader.readRow(row)) { ... } // the last row, if unterminated
ICoreCsv#
ICoreCsv.h:54 · class · 6 declaration(s)
Opened by row PS5.12 of the Platform SDK product plan.
class ICoreCsv {
public:
ICoreCsv() = delete;
using Row = std::vector<std::string>;
[[nodiscard]] static std::optional<std::vector<Row>> parse(std::string_view text);
[[nodiscard]] static std::optional<std::vector<Row>> parse(std::string_view text, char delimiter);
// std::nullopt only for a forbidden delimiter.
[[nodiscard]] static std::optional<std::string> format(const std::vector<Row>& rows);
[[nodiscard]] static std::optional<std::string> format(const std::vector<Row>& rows, char delimiter);
// One row, CRLF-terminated.
[[nodiscard]] static std::optional<std::string> formatRow(const Row& row, char delimiter);
};
};
ICoreCsvReader#
ICoreCsv.h:71 · class · pImpl · 11 declaration(s)
class ICoreCsvReader {
public:
ICoreCsvReader();
explicit ICoreCsvReader(char delimiter);
~ICoreCsvReader();
ICoreCsvReader(const ICoreCsvReader&) = delete;
ICoreCsvReader& operator=(const ICoreCsvReader&) = delete;
// More input. Ignored after finish() or an error.
void addData(std::string_view chunk);
// Declares the end of input, completing an unterminated last row.
void finish();
// Moves the next complete row into `row` and returns true, or returns false
// when no complete row is available yet (or an error stopped reading).
[[nodiscard]] bool readRow(ICoreCsv::Row& row);
[[nodiscard]] bool hasError() const noexcept;
// The 1-based line of the first error, or 0 when there is none.
[[nodiscard]] std::int64_t errorLine() const noexcept;
// A sentence describing the first error; empty when there is none.
[[nodiscard]] std::string errorString() const;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreJsonArray.h#
ICoreEssentials/Serialization/ICoreJsonArray.h
ICoreJsonArray#
ICoreJsonArray.h:44 · class · pImpl · nested const_iterator · 21 declaration(s)
ICoreJsonArray -- an ordered list of JSON values.
class ICoreJsonArray {
public:
ICoreJsonArray();
~ICoreJsonArray();
// ⚠ COPY ONLY, AND THE MOVES ARE ABSENT ON PURPOSE. Declaring the copy
// suppresses the implicit moves, so `ICoreJsonArray b = std::move(a)`
// copies and leaves `a` intact and usable. A pointer-stealing move would
// leave `a` holding a null Impl, and every method here dereferences it --
// where the old std::vector member left a moved-from array EMPTY and
// perfectly valid. Nothing in the tree moves one of these.
ICoreJsonArray(const ICoreJsonArray& other);
ICoreJsonArray& operator=(const ICoreJsonArray& other);
ICoreJsonArray(std::initializer_list<ICoreJsonValue> values);
// --- reading ------------------------------------------------------------
[[nodiscard]] bool isEmpty() const;
[[nodiscard]] std::ptrdiff_t size() const;
[[nodiscard]] std::ptrdiff_t count() const;
// Out of range yields an undefined value, as QJsonArray::at() did rather
// than reading past the end.
[[nodiscard]] ICoreJsonValue at(std::ptrdiff_t i) const;
[[nodiscard]] ICoreJsonValue first() const;
[[nodiscard]] ICoreJsonValue last() const;
[[nodiscard]] ICoreJsonValue operator[](std::ptrdiff_t i) const;
[[nodiscard]] bool contains(const ICoreJsonValue& value) const;
// --- writing ------------------------------------------------------------
void append(const ICoreJsonValue& value);
void removeAt(std::ptrdiff_t i);
// --- iteration ----------------------------------------------------------
class const_iterator {
public:
// The array pointer and the index, measured on this tree: two 8-byte
// trivially-copyable members. Pinned by static_asserts in the .cpp, so
// a change to either is a build error rather than a silent overrun.
static constexpr std::size_t kStateSize = 16;
static constexpr std::size_t kStateAlign = 8;
const_iterator(const ICoreJsonArray* a, std::ptrdiff_t i);
ICoreJsonValue operator*() const;
const_iterator& operator++();
bool operator==(const const_iterator& o) const;
bool operator!=(const const_iterator& o) const;
private:
alignas(kStateAlign) std::byte m_storage[kStateSize];
};
[[nodiscard]] const_iterator begin() const;
[[nodiscard]] const_iterator end() const;
[[nodiscard]] const_iterator constBegin() const;
[[nodiscard]] const_iterator constEnd() const;
bool operator==(const ICoreJsonArray& other) const;
bool operator!=(const ICoreJsonArray& other) const;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreJsonDocument.h#
ICoreEssentials/Serialization/ICoreJsonDocument.h
ICoreJsonParseError#
ICoreJsonDocument.h:54 · class · pImpl · 6 declaration(s)
ICoreJsonDocument (+ ICoreJsonParseError) -- a whole JSON document, and the parser and writer for the family.
class ICoreJsonParseError {
public:
ICoreJsonParseError();
~ICoreJsonParseError();
// Copy only; see ICoreJsonArray.h on why the moves are not declared.
ICoreJsonParseError(const ICoreJsonParseError& other);
ICoreJsonParseError& operator=(const ICoreJsonParseError& other);
[[nodiscard]] bool hasError() const;
[[nodiscard]] ICoreString errorString() const;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreJsonDocument#
ICoreJsonDocument.h:80 · class · pImpl · 15 declaration(s)
class ICoreJsonDocument {
public:
enum JsonFormat { Indented, Compact };
ICoreJsonDocument();
~ICoreJsonDocument();
// Copy only; see ICoreJsonArray.h on why the moves are not declared.
// fromJson() returns a local by value, which C++17 elides.
ICoreJsonDocument(const ICoreJsonDocument& other);
ICoreJsonDocument& operator=(const ICoreJsonDocument& other);
explicit ICoreJsonDocument(const ICoreJsonObject& o);
explicit ICoreJsonDocument(const ICoreJsonArray& a);
static ICoreJsonDocument fromJson(const ICoreByteArray& json);
static ICoreJsonDocument fromJson(const ICoreByteArray& json, ICoreJsonParseError* error);
[[nodiscard]] ICoreByteArray toJson(JsonFormat format = Indented) const;
[[nodiscard]] bool isNull() const;
[[nodiscard]] bool isEmpty() const;
[[nodiscard]] bool isObject() const;
[[nodiscard]] bool isArray() const;
[[nodiscard]] ICoreJsonObject object() const;
[[nodiscard]] ICoreJsonArray array() const;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreJsonObject.h#
ICoreEssentials/Serialization/ICoreJsonObject.h
ICoreJsonObject#
ICoreJsonObject.h:73 · class · pImpl · nested Ref, const_iterator · 22 declaration(s)
ICoreJsonObject -- a JSON object: string keys to values.
class ICoreJsonObject {
public:
ICoreJsonObject();
~ICoreJsonObject();
// Copy only -- see the note on ICoreJsonArray's: declaring the copy
// suppresses the implicit moves, and a moved-from object with a null Impl
// would crash where the old vector member left it empty and valid.
ICoreJsonObject(const ICoreJsonObject& other);
ICoreJsonObject& operator=(const ICoreJsonObject& other);
ICoreJsonObject(std::initializer_list<std::pair<ICoreString, ICoreJsonValue>> entries);
// --- reading ------------------------------------------------------------
[[nodiscard]] bool isEmpty() const;
[[nodiscard]] std::ptrdiff_t size() const;
[[nodiscard]] std::ptrdiff_t count() const;
[[nodiscard]] bool contains(const ICoreString& key) const;
// A missing key yields UNDEFINED, as QJsonObject::value() does. Call sites
// lean on it: `obj.value(k).toString()` on an absent key gives "" rather
// than inserting anything.
[[nodiscard]] ICoreJsonValue value(const ICoreString& key) const;
[[nodiscard]] ICoreList<ICoreString> keys() const;
// --- writing ------------------------------------------------------------
// Replaces an existing key rather than duplicating it, which is also what
// makes a parsed document's duplicate keys resolve last-wins, as Qt's do.
void insert(const ICoreString& key, const ICoreJsonValue& value);
void remove(const ICoreString& key);
ICoreJsonValue take(const ICoreString& key);
// --- subscript ----------------------------------------------------------
class Ref {
public:
Ref(ICoreJsonObject* owner, ICoreString key);
~Ref();
// The full set, because a Ref had every one of these implicitly before
// the unique_ptr member deleted them. It is a proxy call sites build,
// assign through and drop on the same line, so none of them is hot.
Ref(const Ref& other);
Ref& operator=(const Ref& other);
Ref& operator=(const ICoreJsonValue& value);
operator ICoreJsonValue() const;
private:
class Impl;
std::unique_ptr<Impl> impl;
};
Ref operator[](const ICoreString& key);
[[nodiscard]] ICoreJsonValue operator[](const ICoreString& key) const;
// --- iteration ----------------------------------------------------------
class const_iterator {
public:
// The owner pointer and the index, measured on this tree: two 8-byte
// trivially-copyable members. Pinned by static_asserts in the .cpp, so
// a change to either is a build error rather than a silent overrun.
static constexpr std::size_t kStateSize = 16;
static constexpr std::size_t kStateAlign = 8;
const_iterator(const ICoreJsonObject* o, std::ptrdiff_t i);
[[nodiscard]] ICoreString key() const;
[[nodiscard]] ICoreJsonValue value() const;
const_iterator& operator++();
bool operator==(const const_iterator& o) const;
bool operator!=(const const_iterator& o) const;
private:
alignas(kStateAlign) std::byte m_storage[kStateSize];
};
[[nodiscard]] const_iterator begin() const;
[[nodiscard]] const_iterator end() const;
[[nodiscard]] const_iterator constBegin() const;
[[nodiscard]] const_iterator constEnd() const;
bool operator==(const ICoreJsonObject& other) const;
bool operator!=(const ICoreJsonObject& other) const;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreJsonValue.h#
ICoreEssentials/Serialization/ICoreJsonValue.h
ICoreJsonValue#
ICoreJsonValue.h:71 · class · pImpl · 32 declaration(s)
class ICoreJsonValue {
public:
// The two JSON "empties". Spelled as an enum so the call site reads
// ICoreJsonValue::Null exactly as it read QJsonValue::Null.
enum SpecialValue { Null, Undefined };
ICoreJsonValue();
~ICoreJsonValue();
ICoreJsonValue(const ICoreJsonValue& other);
ICoreJsonValue(ICoreJsonValue&& other) noexcept;
ICoreJsonValue& operator=(const ICoreJsonValue& other);
ICoreJsonValue& operator=(ICoreJsonValue&& other) noexcept;
explicit ICoreJsonValue(SpecialValue v);
ICoreJsonValue(bool b);
ICoreJsonValue(int n);
ICoreJsonValue(std::int64_t n);
ICoreJsonValue(double d);
ICoreJsonValue(const char* s);
ICoreJsonValue(const ICoreString& s);
ICoreJsonValue(const ICoreJsonObject& o);
ICoreJsonValue(const ICoreJsonArray& a);
// --- interrogation ------------------------------------------------------
[[nodiscard]] bool isNull() const;
[[nodiscard]] bool isUndefined() const;
[[nodiscard]] bool isBool() const;
[[nodiscard]] bool isDouble() const;
[[nodiscard]] bool isString() const;
[[nodiscard]] bool isObject() const;
[[nodiscard]] bool isArray() const;
// --- extraction ---------------------------------------------------------
[[nodiscard]] ICoreString toString() const;
[[nodiscard]] ICoreString toString(const ICoreString& defaultValue) const;
[[nodiscard]] bool toBool(bool defaultValue = false) const;
// Integral doubles only -- see the coercion note.
[[nodiscard]] int toInt(int defaultValue = 0) const;
[[nodiscard]] std::int64_t toInteger(std::int64_t defaultValue = 0) const;
[[nodiscard]] double toDouble(double defaultValue = 0.0) const;
[[nodiscard]] ICoreJsonObject toObject() const;
[[nodiscard]] ICoreJsonArray toArray() const;
bool operator==(const ICoreJsonValue& other) const;
bool operator!=(const ICoreJsonValue& other) const;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreSettings.h#
ICoreEssentials/Serialization/ICoreSettings.h
ICoreSettings#
ICoreSettings.h:55 · class · pImpl · 16 declaration(s)
ICoreSettings -- a persisted key/value file, in QSettings' INI dialect.
class ICoreSettings {
public:
explicit ICoreSettings(const ICoreString& path);
~ICoreSettings();
ICoreSettings(const ICoreSettings&) = delete;
ICoreSettings& operator=(const ICoreSettings&) = delete;
[[nodiscard]] bool hasError() const;
[[nodiscard]] bool contains(const ICoreString& key) const;
[[nodiscard]] ICoreVariant value(const ICoreString& key) const;
[[nodiscard]] ICoreVariant value(const ICoreString& key,
const ICoreVariant& defaultValue) const;
void setValue(const ICoreString& key, const ICoreVariant& value);
void remove(const ICoreString& key);
// --- groups and arrays --------------------------------------------------
void beginGroup(const ICoreString& prefix);
void endGroup();
int beginReadArray(const ICoreString& prefix);
void beginWriteArray(const ICoreString& prefix, int size = -1);
void setArrayIndex(int i);
void endArray();
void sync();
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreXmlStreamReader.h#
ICoreEssentials/Serialization/ICoreXmlStreamReader.h
ICoreXmlStreamReader -- a pull parser for XML 1.0 with namespaces.
ICoreXmlStreamReader xml(text); while (xml.readNextStartElement()) { if (xml.name() == "item") { auto id = xml.attribute("id"); std::string label = xml.readElementText(); } else { xml.skipCurrentElement(); } } if (xml.hasError()) { ... xml.errorString(), xml.lineNumber() ... }
readNext() moves to the next token and returns its type. A start tag and an
ICoreXmlAttribute#
ICoreXmlStreamReader.h:52 · struct · 0 declaration(s)
Opened by row PS5.22 of the Platform SDK product plan.
struct ICoreXmlAttribute {
public:
std::string qualifiedName;
std::string name; // local name
std::string prefix;
std::string namespaceUri;
std::string value; // decoded
};
};
ICoreXmlStreamReader#
ICoreXmlStreamReader.h:60 · class · pImpl · 28 declaration(s)
class ICoreXmlStreamReader {
public:
enum class Token {
NoToken = 0,
Invalid = 1,
StartDocument = 2,
EndDocument = 3,
StartElement = 4,
EndElement = 5,
Characters = 6,
Comment = 7,
ProcessingInstruction = 8,
DTD = 9
};
enum class Error {
NoError = 0,
NotWellFormed = 1,
PrematureEndOfDocument = 2,
UnsupportedEncoding = 3,
UnexpectedElement = 4 // readElementText() met a child element
};
ICoreXmlStreamReader();
explicit ICoreXmlStreamReader(std::string_view document); // complete input
~ICoreXmlStreamReader();
ICoreXmlStreamReader(const ICoreXmlStreamReader&) = delete;
ICoreXmlStreamReader& operator=(const ICoreXmlStreamReader&) = delete;
void addData(std::string_view chunk);
void finish();
Token readNext();
[[nodiscard]] Token tokenType() const noexcept;
[[nodiscard]] bool atEnd() const noexcept;
// Advances to the next StartElement inside the current element; false at
// the current element's end (or at an error).
bool readNextStartElement();
// At a StartElement: skips to its matching EndElement.
void skipCurrentElement();
// At a StartElement: the concatenated text up to the matching EndElement,
// which becomes the current token. A child element is an error.
std::string readElementText();
[[nodiscard]] std::string name() const;
[[nodiscard]] std::string prefix() const;
[[nodiscard]] std::string qualifiedName() const;
[[nodiscard]] std::string namespaceUri() const;
// Characters, Comment, DTD and the data of a ProcessingInstruction.
[[nodiscard]] std::string text() const;
[[nodiscard]] bool isCDATA() const noexcept;
[[nodiscard]] bool isWhitespace() const noexcept;
// The target of a ProcessingInstruction.
[[nodiscard]] std::string processingInstructionTarget() const;
// The attributes of the current StartElement, xmlns declarations excluded.
[[nodiscard]] std::vector<ICoreXmlAttribute> attributes() const;
[[nodiscard]] std::optional<std::string> attribute(std::string_view qualifiedName) const;
// From the XML declaration, when there is one.
[[nodiscard]] std::string documentVersion() const;
[[nodiscard]] bool hasError() const noexcept;
[[nodiscard]] Error error() const noexcept;
[[nodiscard]] std::string errorString() const;
// 1-based position of the current token, or of the error.
[[nodiscard]] std::int64_t lineNumber() const noexcept;
[[nodiscard]] std::int64_t columnNumber() const noexcept;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreXmlStreamWriter.h#
ICoreEssentials/Serialization/ICoreXmlStreamWriter.h
ICoreXmlStreamWriter -- builds a well-formed XML 1.0 document.
ICoreXmlStreamWriter xml; xml.setAutoFormatting(true); xml.writeStartDocument(); xml.writeStartElement("library"); xml.writeAttribute("version", "2"); xml.writeTextElement("title", "Fish & Chips"); xml.writeEndDocument(); // closes every open element std::string text = xml.toString();
Text and attribute values are escaped for you: & < > in text, and also " and the line-break and tab characters in attributes (as 	), so a value reads back exactly as written. writeCDATA() splits a "]]>" in its
ICoreXmlStreamWriter#
ICoreXmlStreamWriter.h:43 · class · pImpl · 23 declaration(s)
Opened by row PS5.22 of the Platform SDK product plan.
class ICoreXmlStreamWriter {
public:
ICoreXmlStreamWriter();
~ICoreXmlStreamWriter();
ICoreXmlStreamWriter(const ICoreXmlStreamWriter&) = delete;
ICoreXmlStreamWriter& operator=(const ICoreXmlStreamWriter&) = delete;
void setAutoFormatting(bool enabled);
[[nodiscard]] bool autoFormatting() const noexcept;
void setIndent(int spaces);
[[nodiscard]] int indent() const noexcept;
// <?xml version="1.0" encoding="UTF-8"?>
void writeStartDocument();
void writeEndDocument();
void writeStartElement(std::string_view qualifiedName);
void writeEmptyElement(std::string_view qualifiedName);
void writeEndElement();
void writeTextElement(std::string_view qualifiedName, std::string_view text);
void writeAttribute(std::string_view qualifiedName, std::string_view value);
void writeNamespace(std::string_view namespaceUri, std::string_view prefix);
void writeDefaultNamespace(std::string_view namespaceUri);
void writeCharacters(std::string_view text);
void writeCDATA(std::string_view text);
void writeComment(std::string_view text);
void writeProcessingInstruction(std::string_view target, std::string_view data);
[[nodiscard]] bool hasError() const noexcept;
// The document so far.
[[nodiscard]] std::string toString() const;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreZipArchive.h#
ICoreEssentials/Serialization/ICoreZipArchive.h
ICoreZipReader / ICoreZipWriter -- ZIP archives, in memory.
ICoreZipWriter w; w.addFile("[Content_Types].xml", types); w.addFile("3D/3dmodel.model", model); ICoreByteArray archive = w.finish();
ICoreZipReader r; if (!r.open(archive)) { ... r.error() ... } for (std::size_t i = 0; i < r.count(); ++i) { r.name(i); r.size(i); } ICoreByteArray model; if (!r.read("3D/3dmodel.model", model)) { ... }
What 3MF (an OPC package) and USDZ need, and what any
.zipholds: entries
ICoreZipReader#
ICoreZipArchive.h:78 · class · pImpl · 20 declaration(s)
class ICoreZipReader {
public:
static constexpr std::uint64_t unlimited = static_cast<std::uint64_t>(-1);
ICoreZipReader();
~ICoreZipReader();
ICoreZipReader(const ICoreZipReader&) = delete;
ICoreZipReader& operator=(const ICoreZipReader&) = delete;
ICoreZipReader(ICoreZipReader&&) noexcept;
ICoreZipReader& operator=(ICoreZipReader&&) noexcept;
// Reads the central directory of `archive`, which the reader keeps (the
// array is implicitly shared, so no bytes are copied). False, and nothing
// open, when it is not a readable ZIP archive.
[[nodiscard]] bool open(const ICoreByteArray& archive);
void close();
[[nodiscard]] bool isOpen() const noexcept;
// The last failure of open() or read(); None after a success.
[[nodiscard]] ICoreZipError error() const noexcept;
// The entries, in central-directory order. An index out of range answers
// an empty name, zeros and Other.
[[nodiscard]] std::size_t count() const noexcept;
[[nodiscard]] ICoreString name(std::size_t index) const;
[[nodiscard]] std::uint64_t size(std::size_t index) const noexcept;
[[nodiscard]] std::uint64_t compressedSize(std::size_t index) const noexcept;
[[nodiscard]] std::uint32_t crc32(std::size_t index) const noexcept;
[[nodiscard]] ICoreZipMethod method(std::size_t index) const noexcept;
[[nodiscard]] bool isDirectory(std::size_t index) const noexcept;
[[nodiscard]] bool isEncrypted(std::size_t index) const noexcept;
// Where the entry's data starts, in bytes from the start of the archive
// (past its local header); 0 when the local header cannot be read.
[[nodiscard]] std::uint64_t dataOffset(std::size_t index) const noexcept;
// The index of the first entry named exactly `name`, or -1.
[[nodiscard]] std::ptrdiff_t indexOf(const ICoreString& name) const;
// True with the entry's data in `out`, or false with `out` empty and the
// reason in error().
[[nodiscard]] bool read(std::size_t index, ICoreByteArray& out,
std::uint64_t maxSize = unlimited);
[[nodiscard]] bool read(const ICoreString& name, ICoreByteArray& out,
std::uint64_t maxSize = unlimited);
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreZipWriter#
ICoreZipArchive.h:129 · class · pImpl · 12 declaration(s)
class ICoreZipWriter {
public:
ICoreZipWriter();
~ICoreZipWriter();
ICoreZipWriter(const ICoreZipWriter&) = delete;
ICoreZipWriter& operator=(const ICoreZipWriter&) = delete;
ICoreZipWriter(ICoreZipWriter&&) noexcept;
ICoreZipWriter& operator=(ICoreZipWriter&&) noexcept;
// The time stamp of every entry added after this call, as the ZIP format
// stores it (MS-DOS form: years 1980..2107, even seconds -- an odd second
// is written one lower). False, and nothing changed, when out of range.
[[nodiscard]] bool setModifiedTime(int year, int month, int day,
int hour, int minute, int second);
// 0 or 1: no alignment. Otherwise a power of two up to 32,768: every entry
// added after this call has its data start on a multiple of it. False, and
// nothing changed, for any other value.
[[nodiscard]] bool setDataAlignment(std::uint32_t alignment);
// Writes ZIP64 records for every entry and for the end of the archive even
// when nothing needs them. They are written anyway where the archive needs
// them; this is for readers that must be shown ZIP64 without 4 GiB of data.
void setForceZip64(bool force) noexcept;
// Adds one entry. False, and nothing added, for an invalid or duplicate
// name, a level outside 0..9, or a writer already finished. Deflated
// entries are deflated even when that makes them larger.
[[nodiscard]] bool addFile(const ICoreString& name, const ICoreByteArray& data,
ICoreZipMethod method = ICoreZipMethod::Deflated,
int level = 6);
// A directory entry; a trailing '/' is added when `name` has none.
[[nodiscard]] bool addDirectory(const ICoreString& name);
[[nodiscard]] std::size_t count() const noexcept;
[[nodiscard]] ICoreZipError error() const noexcept;
// Writes the central directory and returns the whole archive. The writer is
// finished afterwards: every later add fails with NotOpen and finish()
// returns an empty array.
[[nodiscard]] ICoreByteArray finish();
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
File-scope declarations#
// Enumerator values are pinned (Platform SDK ABI rule). The two methods carry
// their numbers from the ZIP specification (APPNOTE.TXT 4.4.5).
enum class ICoreZipMethod : int {
Stored = 0,
Deflated = 8,
Other = -1, // the reader's answer for any other method; read() refuses it
};
enum class ICoreZipError : int {
None = 0,
InvalidArgument = 1, // a level outside 0..9, an index out of range, a bad alignment
NotAnArchive = 2, // no end-of-central-directory record, or one that cannot describe this data
Corrupt = 3, // a damaged directory, local header or deflate stream
ChecksumMismatch = 4, // the data's CRC-32 or size disagrees with the directory
UnsupportedMethod = 5,
Encrypted = 6,
NotFound = 7, // read(name): no entry has that name
TooLarge = 8, // the entry is larger than maxSize
InvalidName = 9, // empty, absolute, a backslash, a NUL, or over 65,535 bytes
DuplicateName = 10,
NotOpen = 11, // the reader holds no archive, or the writer already finished
OutOfMemory = 12,
};