131 lines
3.6 KiB
C++
131 lines
3.6 KiB
C++
/*
|
|
* Copyright 2015 - 2025 gary@drinkingtea.net
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include <ox/std/buffer.hpp>
|
|
|
|
#include "read.hpp"
|
|
|
|
namespace ox {
|
|
|
|
ox::Result<ox::StringView> readClawTypeId(ox::BufferView buff) noexcept {
|
|
auto buffRaw = buff.data();
|
|
auto buffLen = buff.size();
|
|
size_t outSz{};
|
|
const auto s1End = ox::strchr(buffRaw, ';', buffLen);
|
|
if (!s1End) {
|
|
return ox::Error(1, "Could not read Claw header");
|
|
}
|
|
auto const fmtSz = static_cast<std::size_t>(s1End - buffRaw) + 1;
|
|
buffRaw += fmtSz;
|
|
buffLen -= fmtSz;
|
|
outSz += fmtSz;
|
|
auto const s2End = ox::strchr(buffRaw, ';', buffLen);
|
|
if (!s2End) {
|
|
return ox::Error(2, "Could not read Claw header");
|
|
}
|
|
auto const s2Size = static_cast<std::size_t>(s2End - buffRaw) + 1;
|
|
buffRaw += s2Size;
|
|
buffLen -= s2Size;
|
|
outSz += s2Size;
|
|
auto const s3End = ox::strchr(buffRaw, ';', buffLen) + 1;
|
|
if (!s3End) {
|
|
return ox::Error(3, "Could not read Claw header");
|
|
}
|
|
auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
|
|
buffRaw += s3Size;
|
|
buffLen -= s3Size;
|
|
outSz += s3Size;
|
|
return {{buff.data() + fmtSz, outSz - fmtSz - 1}};
|
|
}
|
|
|
|
Result<ClawHeader> readClawHeader(ox::BufferView buff) noexcept {
|
|
auto buffRaw = buff.data();
|
|
auto buffLen = buff.size();
|
|
const auto s1End = ox::strchr(buffRaw, ';', buffLen);
|
|
if (!s1End) {
|
|
return ox::Error(1, "Could not read Claw header");
|
|
}
|
|
auto const s1Size = static_cast<std::size_t>(s1End - buffRaw);
|
|
StringView const fmt(buffRaw, s1Size);
|
|
buffRaw += s1Size + 1;
|
|
buffLen -= s1Size + 1;
|
|
|
|
auto const s2End = ox::strchr(buffRaw, ';', buffLen);
|
|
if (!s2End) {
|
|
return ox::Error(2, "Could not read Claw header");
|
|
}
|
|
auto const s2Size = static_cast<std::size_t>(s2End - buffRaw);
|
|
StringView const typeName(buffRaw, s2Size);
|
|
buffRaw += s2Size + 1;
|
|
buffLen -= s2Size + 1;
|
|
|
|
auto const s3End = ox::strchr(buffRaw, ';', buffLen);
|
|
if (!s3End) {
|
|
return ox::Error(3, "Could not read Claw header");
|
|
}
|
|
auto const s3Size = static_cast<std::size_t>(s3End - buffRaw);
|
|
StringView const versionStr(buffRaw, s3Size);
|
|
buffRaw += s3Size + 1;
|
|
buffLen -= s3Size + 1;
|
|
ClawHeader hdr;
|
|
if (fmt == "M2") {
|
|
hdr.fmt = ClawFormat::Metal;
|
|
} else if (fmt == "O1") {
|
|
hdr.fmt = ClawFormat::Organic;
|
|
} else {
|
|
return ox::Error(4, "Claw format does not match any supported format/version combo");
|
|
}
|
|
hdr.typeName = typeName;
|
|
std::ignore = ox::atoi(versionStr).copyTo(hdr.typeVersion);
|
|
hdr.data = buffRaw;
|
|
hdr.dataSize = buffLen;
|
|
return hdr;
|
|
}
|
|
|
|
Result<BufferView> stripClawHeader(ox::BufferView buff) noexcept {
|
|
OX_REQUIRE(header, readClawHeader(buff));
|
|
return {{header.data, header.dataSize}};
|
|
}
|
|
|
|
Result<ModelObject> readClaw(TypeStore &ts, BufferView buff) noexcept {
|
|
OX_REQUIRE(header, readClawHeader(buff));
|
|
auto const [t, tdErr] = ts.getLoad(
|
|
header.typeName, header.typeVersion, header.typeParams);
|
|
if (tdErr) {
|
|
return ox::Error(3, "Could not load type descriptor");
|
|
}
|
|
ModelObject obj;
|
|
OX_RETURN_ERROR(obj.setType(t));
|
|
switch (header.fmt) {
|
|
case ClawFormat::Metal:
|
|
{
|
|
ox::BufferReader br({header.data, header.dataSize});
|
|
MetalClawReader reader(br);
|
|
ModelHandlerInterface handler(&reader);
|
|
OX_RETURN_ERROR(model(&handler, &obj));
|
|
return obj;
|
|
}
|
|
case ClawFormat::Organic:
|
|
{
|
|
#ifdef OX_USE_STDLIB
|
|
OrganicClawReader reader({header.data, header.dataSize});
|
|
ModelHandlerInterface handler(&reader);
|
|
OX_RETURN_ERROR(model(&handler, &obj));
|
|
return obj;
|
|
#else
|
|
break;
|
|
#endif
|
|
}
|
|
case ClawFormat::None:
|
|
return ox::Error(1);
|
|
}
|
|
return ox::Error(1);
|
|
}
|
|
|
|
}
|