/* * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. */ #include #include "media.hpp" #include "typeconv.hpp" namespace keel { [[nodiscard]] static ox::Result findConverter( ox::Vector const&converters, ox::CRStringView srcTypeName, int srcTypeVersion, ox::CRStringView dstTypeName, int dstTypeVersion) noexcept { for (auto &c : converters) { if (c->matches(srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion)) { return c; } } return OxError(1, "Could not find converter"); }; static ox::Result> convert( [[maybe_unused]] keel::Context &ctx, ox::Vector const&converters, [[maybe_unused]] const ox::Buffer &srcBuffer, [[maybe_unused]] ox::CRStringView srcTypeName, [[maybe_unused]] int srcTypeVersion, [[maybe_unused]] ox::CRStringView dstTypeName, [[maybe_unused]] int dstTypeVersion) noexcept { // look for direct converter auto [c, err] = findConverter(converters, srcTypeName, srcTypeVersion, dstTypeName, dstTypeVersion); if (!err) { return c->convertBuffToPtr(ctx, srcBuffer); } // try to chain multiple converters for (const auto &subConverter : converters) { if (!subConverter->dstMatches(dstTypeName, dstTypeVersion)) { continue; } const auto [intermediate, chainErr] = convert(ctx, converters, srcBuffer, srcTypeName, srcTypeVersion, subConverter->srcTypeName(), subConverter->srcTypeVersion()); if (!chainErr) { return subConverter->convertPtrToPtr(ctx, *intermediate); } } return OxError(1, "Could not convert between types"); } ox::Result> convert( [[maybe_unused]] keel::Context &ctx, [[maybe_unused]] const ox::Buffer &srcBuffer, [[maybe_unused]] ox::CRStringView dstTypeName, [[maybe_unused]] int dstTypeVersion) noexcept { #ifndef OX_BARE_METAL oxRequire(hdr, readAssetHeader(srcBuffer)); return convert( ctx, ctx.converters, srcBuffer, hdr.clawHdr.typeName, hdr.clawHdr.typeVersion, dstTypeName, dstTypeVersion); #else return OxError(1, "Operation not supported on this platform"); #endif } }