1/*
2 * Copyright 2020 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "experimental/skrive/src/reader/StreamReader.h"
9
10#include "include/core/SkStream.h"
11
12#include <cstring>
13
14namespace skrive::internal {
15
16static constexpr char   kBinaryPrefix[]   = "FLARE";
17static constexpr size_t kBinaryPrefixSize = sizeof(kBinaryPrefix) - 1;
18
19extern std::unique_ptr<StreamReader> MakeJsonStreamReader(const char[], size_t);
20extern std::unique_ptr<StreamReader> MakeBinaryStreamReader(std::unique_ptr<SkStreamAsset>);
21
22std::unique_ptr<StreamReader> StreamReader::Make(const sk_sp<SkData>& data) {
23    if (data->size() >= kBinaryPrefixSize &&
24        !memcmp(data->data(), kBinaryPrefix, kBinaryPrefixSize)) {
25        auto reader = SkMemoryStream::Make(data);
26        reader->skip(kBinaryPrefixSize);
27
28        return MakeBinaryStreamReader(std::move(reader));
29    }
30
31    return MakeJsonStreamReader(static_cast<const char*>(data->data()), data->size());
32}
33
34std::unique_ptr<StreamReader> StreamReader::Make(std::unique_ptr<SkStreamAsset> stream) {
35    char buf[kBinaryPrefixSize];
36
37    if (stream->read(buf, kBinaryPrefixSize) == kBinaryPrefixSize) {
38        if (!strncmp(buf, kBinaryPrefix, kBinaryPrefixSize)) {
39            // binary stream - we can stay in streaming mode
40            return MakeBinaryStreamReader(std::move(stream));
41        }
42    } else {
43        // stream too short to hold anything useful
44        return nullptr;
45    }
46
47    if (!stream->rewind()) {
48        SkDebugf("!! failed to rewind stream.\n");
49        return nullptr;
50    }
51
52    // read to memory to figure what we're dealing with
53    return StreamReader::Make(SkData::MakeFromStream(stream.get(), stream->getLength()));
54}
55
56SkV2 StreamReader::readV2(const char label[]) {
57    SkV2 v2{0,0};
58
59    this->readFloatArray(label, reinterpret_cast<float*>(&v2), 2);
60
61    return v2;
62}
63
64SkColor4f StreamReader::readColor(const char label[]) {
65    SkColor4f color{0,0,0,1};
66
67    this->readFloatArray(label, reinterpret_cast<float*>(&color), 4);
68
69    return color;
70}
71
72} // namespace skrive::internal
73