1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2011 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMatrixPriv.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkReader32.h"
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkString.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkWriter32.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkWriter32::writeMatrix(const SkMatrix& matrix) {
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t size = SkMatrixPriv::WriteToMemory(matrix, nullptr);
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(SkAlign4(size) == size);
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkMatrixPriv::WriteToMemory(matrix, this->reserve(size));
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *  Strings are stored as: length[4-bytes] + string_data + '\0' + pad_to_mul_4
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotconst char* SkReader32::readString(size_t* outLen) {
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t len = this->readU32();
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const void* ptr = this->peek();
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // skip over the string + '\0' and then pad to a multiple of 4
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t alignedSize = SkAlign4(len + 1);
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->skip(alignedSize);
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (outLen) {
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        *outLen = len;
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return (const char*)ptr;
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsize_t SkReader32::readIntoString(SkString* copy) {
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    size_t len;
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* ptr = this->readString(&len);
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (copy) {
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        copy->set(ptr, len);
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return len;
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkWriter32::writeString(const char str[], size_t len) {
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (nullptr == str) {
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        str = "";
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        len = 0;
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if ((long)len < 0) {
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        len = strlen(str);
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // [ 4 byte len ] [ str ... ] [1 - 4 \0s]
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    uint32_t* ptr = this->reservePad(sizeof(uint32_t) + len + 1);
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    *ptr = SkToU32(len);
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    char* chars = (char*)(ptr + 1);
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    memcpy(chars, str, len);
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    chars[len] = '\0';
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsize_t SkWriter32::WriteStringSize(const char* str, size_t len) {
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if ((long)len < 0) {
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        SkASSERT(str);
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        len = strlen(str);
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const size_t lenBytes = 4;    // we use 4 bytes to record the length
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // add 1 since we also write a terminating 0
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkAlign4(lenBytes + len + 1);
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SkWriter32::growToAtLeast(size_t size) {
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const bool wasExternal = (fExternal != nullptr) && (fData == fExternal);
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fCapacity = 4096 + SkTMax(size, fCapacity + (fCapacity / 2));
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fInternal.realloc(fCapacity);
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fData = fInternal.get();
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (wasExternal) {
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // we were external, so copy in the data
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        memcpy(fData, fExternal, fUsed);
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkData> SkWriter32::snapshotAsData() const {
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkData::MakeWithCopy(fData, fUsed);
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
89