1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "experimental/skrive/src/reader/StreamReader.h" 9cb93a386Sopenharmony_ci#include "include/core/SkStream.h" 10cb93a386Sopenharmony_ci#include "include/core/SkString.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#include <vector> 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_cinamespace skrive::internal { 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cinamespace { 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciclass BinaryReader final : public StreamReader { 19cb93a386Sopenharmony_cipublic: 20cb93a386Sopenharmony_ci explicit BinaryReader(std::unique_ptr<SkStreamAsset> stream) 21cb93a386Sopenharmony_ci : fStream(std::move(stream)) {} 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ciprivate: 24cb93a386Sopenharmony_ci bool validateSize(size_t sz) const { 25cb93a386Sopenharmony_ci const auto next_pos = fStream->getPosition() + sz, 26cb93a386Sopenharmony_ci block_end = fBlockStack.empty() ? fStream->getLength() 27cb93a386Sopenharmony_ci : fBlockStack.back().block_end; 28cb93a386Sopenharmony_ci return next_pos <= block_end; 29cb93a386Sopenharmony_ci } 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ci uint16_t readId(const char label[]) override { 32cb93a386Sopenharmony_ci return this->readUInt16(label); 33cb93a386Sopenharmony_ci } 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci bool readBool(const char[]) override { 36cb93a386Sopenharmony_ci uint8_t v; 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci return validateSize(sizeof(v)) && fStream->readU8(&v) 39cb93a386Sopenharmony_ci ? v == 1 40cb93a386Sopenharmony_ci : false; 41cb93a386Sopenharmony_ci } 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci float readFloat(const char[]) override { 44cb93a386Sopenharmony_ci float v; 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci return validateSize(sizeof(v)) && fStream->readScalar(&v) 47cb93a386Sopenharmony_ci ? v 48cb93a386Sopenharmony_ci : 0.0f; 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci uint8_t readUInt8(const char[]) override { 52cb93a386Sopenharmony_ci uint8_t v; 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ci return validateSize(sizeof(v)) && fStream->readU8(&v) 55cb93a386Sopenharmony_ci ? v 56cb93a386Sopenharmony_ci : 0; 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci uint16_t readUInt16(const char[]) override { 60cb93a386Sopenharmony_ci uint16_t v; 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci return validateSize(sizeof(v)) && fStream->readU16(&v) 63cb93a386Sopenharmony_ci ? v 64cb93a386Sopenharmony_ci : 0; 65cb93a386Sopenharmony_ci } 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci uint32_t readUInt32(const char[]) override { 68cb93a386Sopenharmony_ci uint32_t v; 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci return validateSize(sizeof(v)) && fStream->readU32(&v) 71cb93a386Sopenharmony_ci ? v 72cb93a386Sopenharmony_ci : 0; 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci SkString readString(const char[]) override { 76cb93a386Sopenharmony_ci uint32_t length; 77cb93a386Sopenharmony_ci if (!validateSize(sizeof(length)) || !fStream->readU32(&length)) { 78cb93a386Sopenharmony_ci return SkString(); 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci SkString str(length); 82cb93a386Sopenharmony_ci return validateSize(length) && fStream->read(str.writable_str(), length) == length 83cb93a386Sopenharmony_ci ? str 84cb93a386Sopenharmony_ci : SkString(); 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci size_t readFloatArray(const char[], float dst[], size_t count) override { 88cb93a386Sopenharmony_ci if (!validateSize(count * sizeof(float))) { 89cb93a386Sopenharmony_ci return 0; 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci return fStream->read(dst, count * sizeof(float)) / sizeof(float); 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci uint8_t readLength8() override { 96cb93a386Sopenharmony_ci return this->readUInt8(nullptr); 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci uint16_t readLength16() override { 100cb93a386Sopenharmony_ci return this->readUInt16(nullptr); 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_ci // nops 104cb93a386Sopenharmony_ci bool openArray(const char[]) override { return true; } 105cb93a386Sopenharmony_ci void closeArray() override {} 106cb93a386Sopenharmony_ci bool openObject(const char[]) override { return true; } 107cb93a386Sopenharmony_ci void closeObject() override {} 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci BlockType openBlock() override { 110cb93a386Sopenharmony_ci uint8_t block_type; 111cb93a386Sopenharmony_ci uint32_t block_size; 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_ci if (this->validateSize(sizeof(block_type) + sizeof(block_size)) && 114cb93a386Sopenharmony_ci fStream->readU8 (&block_type) && 115cb93a386Sopenharmony_ci fStream->readU32(&block_size)) { 116cb93a386Sopenharmony_ci const auto block_end = std::min(fStream->getPosition() + block_size, 117cb93a386Sopenharmony_ci fStream->getLength()); 118cb93a386Sopenharmony_ci fBlockStack.push_back({block_end}); 119cb93a386Sopenharmony_ci return static_cast<BlockType>(block_type); 120cb93a386Sopenharmony_ci } 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci return BlockType::kEoB; 123cb93a386Sopenharmony_ci } 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ci void closeBlock() override { 126cb93a386Sopenharmony_ci SkASSERT(!fBlockStack.empty()); 127cb93a386Sopenharmony_ci SkASSERT(fStream->getPosition() <= fBlockStack.back().block_end); 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci if (fStream->getPosition() < fBlockStack.back().block_end) { 130cb93a386Sopenharmony_ci const auto skip = fBlockStack.back().block_end - fStream->getPosition(); 131cb93a386Sopenharmony_ci SkDebugf("!! skipping %zu bytes in block\n", skip); 132cb93a386Sopenharmony_ci fStream->skip(skip); 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ci fBlockStack.pop_back(); 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci const std::unique_ptr<SkStreamAsset> fStream; 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_ci struct BlockRec { 141cb93a386Sopenharmony_ci size_t block_end; 142cb93a386Sopenharmony_ci }; 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci std::vector<BlockRec> fBlockStack; 145cb93a386Sopenharmony_ci}; 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_ci} // namespace 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_cistd::unique_ptr<StreamReader> MakeBinaryStreamReader(std::unique_ptr<SkStreamAsset> stream) { 150cb93a386Sopenharmony_ci return std::make_unique<BinaryReader>(std::move(stream)); 151cb93a386Sopenharmony_ci} 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ci} // namespace skrive::internal 154