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