blob: f3ba4850b3abcdeb14348ea1cbd6a615ab491a70 [file] [log] [blame]
djsollen@google.com2b2ede32012-04-12 13:24:04 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "SkOrderedReadBuffer.h"
10#include "SkTypeface.h"
11
12
robertphillips@google.com4bdfb8c2012-06-12 21:23:49 +000013SkOrderedReadBuffer::SkOrderedReadBuffer(const void* data, size_t size) {
djsollen@google.com2b2ede32012-04-12 13:24:04 +000014 fReader.setMemory(data, size);
15}
16
17SkTypeface* SkOrderedReadBuffer::readTypeface() {
18 uint32_t index = fReader.readU32();
19 if (0 == index || index > (unsigned)fTFCount) {
20 if (index) {
21 SkDebugf("====== typeface index %d\n", index);
22 }
23 return NULL;
24 } else {
25 SkASSERT(fTFArray);
26 return fTFArray[index - 1];
27 }
28}
29
30SkRefCnt* SkOrderedReadBuffer::readRefCnt() {
31 uint32_t index = fReader.readU32();
32 if (0 == index || index > (unsigned)fRCCount) {
33 return NULL;
34 } else {
35 SkASSERT(fRCArray);
36 return fRCArray[index - 1];
37 }
38}
39
40SkFlattenable* SkOrderedReadBuffer::readFlattenable() {
41 SkFlattenable::Factory factory = NULL;
42
43 if (fFactoryCount > 0) {
44 int32_t index = fReader.readU32();
45 if (0 == index) {
46 return NULL; // writer failed to give us the flattenable
47 }
48 index = -index; // we stored the negative of the index
49 index -= 1; // we stored the index-base-1
50 SkASSERT(index < fFactoryCount);
51 factory = fFactoryArray[index];
52 } else if (fFactoryTDArray) {
53 const int32_t* peek = (const int32_t*)fReader.peek();
54 if (*peek <= 0) {
55 int32_t index = fReader.readU32();
56 if (0 == index) {
57 return NULL; // writer failed to give us the flattenable
58 }
59 index = -index; // we stored the negative of the index
60 index -= 1; // we stored the index-base-1
61 factory = (*fFactoryTDArray)[index];
62 } else {
63 const char* name = fReader.readString();
64 factory = SkFlattenable::NameToFactory(name);
65 if (factory) {
66 SkASSERT(fFactoryTDArray->find(factory) < 0);
67 *fFactoryTDArray->append() = factory;
68 } else {
69// SkDebugf("can't find factory for [%s]\n", name);
70 }
71 // if we didn't find a factory, that's our failure, not the writer's,
72 // so we fall through, so we can skip the sizeRecorded data.
73 }
74 } else {
75 factory = (SkFlattenable::Factory)readFunctionPtr();
76 if (NULL == factory) {
77 return NULL; // writer failed to give us the flattenable
78 }
79 }
80
81 // if we get here, factory may still be null, but if that is the case, the
82 // failure was ours, not the writer.
83 SkFlattenable* obj = NULL;
84 uint32_t sizeRecorded = fReader.readU32();
85 if (factory) {
86 uint32_t offset = fReader.offset();
87 obj = (*factory)(*this);
88 // check that we read the amount we expected
89 uint32_t sizeRead = fReader.offset() - offset;
90 if (sizeRecorded != sizeRead) {
91 // we could try to fix up the offset...
92 sk_throw();
93 }
94 } else {
95 // we must skip the remaining data
96 fReader.skip(sizeRecorded);
97 }
98 return obj;
99}
100
101void* SkOrderedReadBuffer::readFunctionPtr() {
reed@google.com34342f62012-06-25 14:36:28 +0000102 SkASSERT(!this->isCrossProcess());
103
djsollen@google.com2b2ede32012-04-12 13:24:04 +0000104 void* proc;
105 fReader.read(&proc, sizeof(proc));
106 return proc;
107}