SkPdfNativeObject.h revision 2af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5df
1cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com/*
2cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Copyright 2013 Google Inc.
3cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com *
4cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Use of this source code is governed by a BSD-style license that can be
5cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * found in the LICENSE file.
6cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com */
7cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com
8cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#ifndef SkPdfNativeObject_DEFINED
9cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#define SkPdfNativeObject_DEFINED
10571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
11571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#include <stdint.h>
12571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#include <string.h>
13571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
14c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkMatrix.h"
15571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#include "SkPdfConfig.h"
163aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com#include "SkPdfNativeTokenizer.h"
17c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkPdfNYI.h"
18c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkPdfUtils.h"
19c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkRect.h"
20c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkString.h"
21c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkTDArray.h"
22c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkTDict.h"
23571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
24571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comclass SkPdfDictionary;
25571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comclass SkPdfStream;
26571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comclass SkPdfAllocator;
27571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
28c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com// TODO(edisonn): remove these constants and clean up the code.
29571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#define kFilteredStreamBit 0
30571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#define kUnfilteredStreamBit 1
312ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com#define kOwnedStreamBit 2
32571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
332af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com/** \class SkPdfNativeObject
342af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *
352af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *  The SkPdfNativeObject class is used to store a pdf object. Classes that inherit it are not
362af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *  allowed to add fields.
372af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *
382af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *  SkPdfAllocator will allocate them in chunks and will free them in destructor.
392af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *
402af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *  You can allocate one on the stack, as long as you call reset() at the end, and any objects it
412af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *  points to in an allocator. But if your object is a simple one, like number, then
422af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *  putting it on stack will be just fine.
432af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *
442af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com */
453aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comclass SkPdfNativeObject {
46571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com public:
47571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com     enum ObjectType {
48af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         // The type will have only one of these values, but for error reporting, we make it an enum
49af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         // so it can easily report that something was expected to be one of a few types
50af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kInvalid_PdfObjectType = 1 << 1,
51af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com
52af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kBoolean_PdfObjectType = 1 << 2,
53af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kInteger_PdfObjectType = 1 << 3,
54af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kReal_PdfObjectType = 1 << 4,
55af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         _kNumber_PdfObjectType = kInteger_PdfObjectType | kReal_PdfObjectType,
56af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kString_PdfObjectType = 1 << 5,
57af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kHexString_PdfObjectType = 1 << 6,
58af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         _kAnyString_PdfObjectType = kString_PdfObjectType | kHexString_PdfObjectType,
59af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kName_PdfObjectType = 1 << 7,
60af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kKeyword_PdfObjectType = 1 << 8,
61af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         _kStream_PdfObjectType = 1 << 9,  //  attached to a Dictionary, do not use
62af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kArray_PdfObjectType = 1 << 10,
63af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kDictionary_PdfObjectType = 1 << 11,
64af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kNull_PdfObjectType = 1 << 12,
65571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
66af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         kReference_PdfObjectType = 1 << 13,
67571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
68c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com         kUndefined_PdfObjectType = 1 << 14,  // per 1.4 spec, if the same key appear twice in the
69c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                                              // dictionary, the value is undefined.
70af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com
71af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com         _kObject_PdfObjectType = -1,
72571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com     };
73571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
74b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com     enum DataType {
75b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com         kEmpty_Data,
76b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com         kFont_Data,
77b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com         kBitmap_Data,
78b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com     };
79b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com
80571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comprivate:
81c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    // TODO(edisonn): assert reset operations while in rendering! The objects should be reset
82c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    // only when rendering is completed.
83063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com    uint32_t fInRendering : 1;
84063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com    uint32_t fUnused : 31;
85063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com
86571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    struct Reference {
87571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        unsigned int fId;
88571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        unsigned int fGen;
89571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    };
90571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
91571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    ObjectType fObjectType;
92571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
93571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    union {
94571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        bool fBooleanValue;
95571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        int64_t fIntegerValue;
96c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        // TODO(edisonn): double, float, SkScalar?
97571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        double fRealValue;
98571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        NotOwnedString fStr;
99571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1003aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        SkTDArray<SkPdfNativeObject*>* fArray;
101571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        Reference fRef;
102571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    };
1033aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkTDict<SkPdfNativeObject*>* fMap;
104b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com
105b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com    // TODO(edisonn): rename data with cache
106571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    void* fData;
107b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com    DataType fDataType;
108571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1090fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com#ifdef PDF_TRACK_OBJECT_USAGE
1102af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Records if the object was used during rendering/proccessing. It can be used to track
1112af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // what features are only partially implemented, by looking at what objects have not been
1122af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // accessed.
1130fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com    mutable bool fUsed;
1140fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com#endif   // PDF_TRACK_OBJECT_USAGE
1150fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
116bca421b468f53a591333918248f54bbd958389d2edisonn@google.com#ifdef PDF_TRACK_STREAM_OFFSETS
117571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.compublic:
1182af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // TODO(edisonn): replace them with char* start, end - and a mechanism to register streams.
119bca421b468f53a591333918248f54bbd958389d2edisonn@google.com    int fStreamId;
120bca421b468f53a591333918248f54bbd958389d2edisonn@google.com    int fOffsetStart;
121bca421b468f53a591333918248f54bbd958389d2edisonn@google.com    int fOffsetEnd;
122bca421b468f53a591333918248f54bbd958389d2edisonn@google.com#endif  // PDF_TRACK_STREAM_OFFSETS
123bca421b468f53a591333918248f54bbd958389d2edisonn@google.com
124bca421b468f53a591333918248f54bbd958389d2edisonn@google.compublic:
125bca421b468f53a591333918248f54bbd958389d2edisonn@google.com
126bca421b468f53a591333918248f54bbd958389d2edisonn@google.com#ifdef PDF_TRACK_STREAM_OFFSETS
1272af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // TODO(edisonn): remove these ones.
128bca421b468f53a591333918248f54bbd958389d2edisonn@google.com    int streamId() const { return fStreamId; }
129bca421b468f53a591333918248f54bbd958389d2edisonn@google.com    int offsetStart() const { return fOffsetStart; }
130bca421b468f53a591333918248f54bbd958389d2edisonn@google.com    int offsetEnd() const { return fOffsetEnd; }
131bca421b468f53a591333918248f54bbd958389d2edisonn@google.com#endif  // PDF_TRACK_STREAM_OFFSETS
132bca421b468f53a591333918248f54bbd958389d2edisonn@google.com
1330fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com    SkPdfNativeObject() : fInRendering(0)
1340fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com                        , fObjectType(kInvalid_PdfObjectType)
1350fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com                        , fMap(NULL)
1360fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com                        , fData(NULL)
1370fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com                        , fDataType(kEmpty_Data)
1380fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com#ifdef PDF_TRACK_OBJECT_USAGE
1390fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com                        , fUsed(false)
1400fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com#endif   // PDF_TRACK_OBJECT_USAGE
141bca421b468f53a591333918248f54bbd958389d2edisonn@google.com
142bca421b468f53a591333918248f54bbd958389d2edisonn@google.com#ifdef PDF_TRACK_STREAM_OFFSETS
143bca421b468f53a591333918248f54bbd958389d2edisonn@google.com                        , fStreamId(-1)
144bca421b468f53a591333918248f54bbd958389d2edisonn@google.com                        , fOffsetStart(-1)
145bca421b468f53a591333918248f54bbd958389d2edisonn@google.com                        , fOffsetEnd(-1)
146bca421b468f53a591333918248f54bbd958389d2edisonn@google.com#endif  // PDF_TRACK_STREAM_OFFSETS
1470fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com    {}
148b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com
1492af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Used to verify if a form is used in rendering, to check for infinite loops.
150063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com    bool inRendering() const { return fInRendering != 0; }
151063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com    void startRendering() {fInRendering = 1;}
152063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com    void doneRendering() {fInRendering = 0;}
153b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com
1542af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Each object can cache one entry associated with it.
1552af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // for example a SkPdfImage could cache an SkBitmap, of a SkPdfFont, could cache a SkTypeface.
156b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com    inline bool hasData(DataType type) {
157b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com        return type == fDataType;
158b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com    }
159571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1602af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // returns the cached value
161b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com    inline void* data(DataType type) {
162b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com        return type == fDataType ? fData : NULL;
163571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
164571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1652af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Stores something in the cache
166b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com    inline void setData(void* data, DataType type) {
167b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com        releaseData();
168b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com        fDataType = type;
169571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fData = data;
170571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
171571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1722af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // destroys the cache
173b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com    void releaseData();
174b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com
1752af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // TODO(edisonn): add an assert that reset was called
1763aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com//    ~SkPdfNativeObject() {
177c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com//        //reset();  must be called manually! Normally, will be called by allocator destructor.
178222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com//    }
179571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1802af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Resets a pdf object, deleting all resources directly referenced.
1812af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // It will not reset/delete indirect resources.
1822af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // (e.g. it deletes only the array holding pointers to objects, but does not del the objects)
183571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    void reset() {
1840fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUnused();
1850fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
186571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        switch (fObjectType) {
187571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kArray_PdfObjectType:
188571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                delete fArray;
189571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
190571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
191571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kDictionary_PdfObjectType:
192571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                delete fMap;
1932ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com                if (isStreamOwned()) {
1942ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com                    delete[] fStr.fBuffer;
1952ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com                    fStr.fBuffer = NULL;
1962ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com                    fStr.fBytes = 0;
1972ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com                }
198571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
199571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
200571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            default:
201571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
202571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
203571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fObjectType = kInvalid_PdfObjectType;
204b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com        releaseData();
205571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
206571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
2072af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // returns the object type (Null, Integer, String, Dictionary, ... )
2082af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // It does not specify what type of dictionary we have.
2090fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com    ObjectType type() {
2100fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
2110fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
2120fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        return fObjectType;
2130fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com    }
214571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
2152af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Gives quick access to the buffer's address of a string/keyword/name
216571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    const char* c_str() const {
2170fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
2180fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
219571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        switch (fObjectType) {
220571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kString_PdfObjectType:
221571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kHexString_PdfObjectType:
222571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kKeyword_PdfObjectType:
223276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com            case kName_PdfObjectType:
224571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                return (const char*)fStr.fBuffer;
225571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
226571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            default:
227c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                // TODO(edisonn): report/warning/assert?
228571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                return NULL;
229571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
230571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
231571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
2322af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Gives quick access to the length of a string/keyword/name
233e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com    size_t lenstr() const {
2340fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
2350fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
236571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        switch (fObjectType) {
237571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kString_PdfObjectType:
238571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kHexString_PdfObjectType:
239571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kKeyword_PdfObjectType:
240276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com            case kName_PdfObjectType:
241571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                return fStr.fBytes;
242571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
243571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            default:
244c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                // TODO(edisonn): report/warning/assert?
245571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                return 0;
246571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
247571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
248571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
249571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
250571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // TODO(edisonn): NYI
251571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfDate& dateValue() const {
252571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        static SkPdfDate nyi;
253571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return nyi;
254571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
255571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
256571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // TODO(edisonn): NYI
257571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfFunction& functionValue() const {
258571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        static SkPdfFunction nyi;
259571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return nyi;
260571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
261571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
262571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // TODO(edisonn): NYI
263571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfFileSpec& fileSpecValue() const {
264571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        static SkPdfFileSpec nyi;
265571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return nyi;
266571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
267571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
268571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // TODO(edisonn): NYI
269571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfTree& treeValue() const {
270571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        static SkPdfTree nyi;
271571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return nyi;
272571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
273571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
2742af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Boolean object. Assumes and asserts that it was never initialized.
275598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeBoolean(bool value, SkPdfNativeObject* obj) {
276571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
277571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
278571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fObjectType = kBoolean_PdfObjectType;
279571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fBooleanValue = value;
280571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
281571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
282598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static SkPdfNativeObject makeBoolean(bool value) {
2833aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        SkPdfNativeObject obj;
284bca421b468f53a591333918248f54bbd958389d2edisonn@google.com
285571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj.fObjectType = kBoolean_PdfObjectType;
286571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj.fBooleanValue = value;
287571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return obj;
288571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
289571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
2902af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates an Integer object. Assumes and asserts that it was never initialized.
291598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeInteger(int64_t value, SkPdfNativeObject* obj) {
292571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
293571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
294571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fObjectType = kInteger_PdfObjectType;
295571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fIntegerValue = value;
296571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
297571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
2982af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Real object. Assumes and asserts that it was never initialized.
299598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeReal(double value, SkPdfNativeObject* obj) {
300571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
301571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
302571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fObjectType = kReal_PdfObjectType;
303571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fRealValue = value;
304571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
305571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3062af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Null object. Assumes and asserts that it was never initialized.
307598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeNull(SkPdfNativeObject* obj) {
308571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
309571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
310571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fObjectType = kNull_PdfObjectType;
311571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
312571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
313598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static SkPdfNativeObject makeNull() {
3143aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        SkPdfNativeObject obj;
315bca421b468f53a591333918248f54bbd958389d2edisonn@google.com
316571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj.fObjectType = kNull_PdfObjectType;
317571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return obj;
318571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
319571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3202af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // TODO(edisonn): this might not woirk well in Chrome
3213aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    static SkPdfNativeObject kNull;
322571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3232af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Numeric object from a string. Assumes and asserts that it was never initialized.
324c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    static void makeNumeric(const unsigned char* start, const unsigned char* end,
325c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                            SkPdfNativeObject* obj) {
326571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
327571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
328571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        // TODO(edisonn): NYI properly
329571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        // if has dot (impl), or exceeds max int, is real, otherwise is int
330571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        bool isInt = true;
3312ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com        for (const unsigned char* current = start; current < end; current++) {
332571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            if (*current == '.') {
333571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                isInt = false;
334571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
335571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            }
336571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            // TODO(edisonn): report parse issue with numbers like "24asdasd123"
337571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
338571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (isInt) {
339598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com            makeInteger(atol((const char*)start), obj);
340571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        } else {
341598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com            makeReal(atof((const char*)start), obj);
342571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
343571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
344571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3452af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Reference object. Assumes and asserts that it was never initialized.
346598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeReference(unsigned int id, unsigned int gen, SkPdfNativeObject* obj) {
347571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
348571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
349571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fObjectType = kReference_PdfObjectType;
350571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fRef.fId = id;
351571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fRef.fGen = gen;
352571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
353571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3542af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Reference object. Resets the object before use.
355598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void resetAndMakeReference(unsigned int id, unsigned int gen, SkPdfNativeObject* obj) {
356bca421b468f53a591333918248f54bbd958389d2edisonn@google.com        obj->reset();
357598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeReference(id, gen, obj);
358bca421b468f53a591333918248f54bbd958389d2edisonn@google.com    }
359571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3602af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a String object. Assumes and asserts that it was never initialized.
361598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeString(const unsigned char* start, SkPdfNativeObject* obj) {
362598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, strlen((const char*)start), obj, kString_PdfObjectType);
363571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
364571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3652af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a String object. Assumes and asserts that it was never initialized.
366c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    static void makeString(const unsigned char* start, const unsigned char* end,
367c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                           SkPdfNativeObject* obj) {
368598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, end - start, obj, kString_PdfObjectType);
369571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
370571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3712af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a String object. Assumes and asserts that it was never initialized.
372598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
373598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, bytes, obj, kString_PdfObjectType);
374571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
375571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3762af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a HexString object. Assumes and asserts that it was never initialized.
377598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeHexString(const unsigned char* start, SkPdfNativeObject* obj) {
378598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, strlen((const char*)start), obj, kHexString_PdfObjectType);
379571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
380571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3812af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a HexString object. Assumes and asserts that it was never initialized.
382c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    static void makeHexString(const unsigned char* start, const unsigned char* end,
383c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                              SkPdfNativeObject* obj) {
384598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, end - start, obj, kHexString_PdfObjectType);
385571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
386571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3872af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a HexString object. Assumes and asserts that it was never initialized.
388598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeHexString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
389598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, bytes, obj, kHexString_PdfObjectType);
390571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
391571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3922af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Name object. Assumes and asserts that it was never initialized.
393598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeName(const unsigned char* start, SkPdfNativeObject* obj) {
394598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, strlen((const char*)start), obj, kName_PdfObjectType);
395571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
396571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
3972af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Name object. Assumes and asserts that it was never initialized.
398c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    static void makeName(const unsigned char* start, const unsigned char* end,
399c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                         SkPdfNativeObject* obj) {
400598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, end - start, obj, kName_PdfObjectType);
401571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
402571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4032af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Name object. Assumes and asserts that it was never initialized.
404598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeName(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
405598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, bytes, obj, kName_PdfObjectType);
406571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
407571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4082af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Keyword object. Assumes and asserts that it was never initialized.
409598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeKeyword(const unsigned char* start, SkPdfNativeObject* obj) {
410598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, strlen((const char*)start), obj, kKeyword_PdfObjectType);
411571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
412571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4132af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Keyword object. Assumes and asserts that it was never initialized.
414c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    static void makeKeyword(const unsigned char* start, const unsigned char* end,
415c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                            SkPdfNativeObject* obj) {
416598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, end - start, obj, kKeyword_PdfObjectType);
417571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
418571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4192af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates a Keyword object. Assumes and asserts that it was never initialized.
420598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeKeyword(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
421598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, bytes, obj, kKeyword_PdfObjectType);
422571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
423571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4242af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates an empty Array object. Assumes and asserts that it was never initialized.
425598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeEmptyArray(SkPdfNativeObject* obj) {
426571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
427571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
428571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fObjectType = kArray_PdfObjectType;
4293aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        obj->fArray = new SkTDArray<SkPdfNativeObject*>();
430571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
431571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4322af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Appends an object into the array. Assumes <this> is an array.
4333aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    bool appendInArray(SkPdfNativeObject* obj) {
434571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kArray_PdfObjectType);
435571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kArray_PdfObjectType) {
436c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warning/assert?
437571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return false;
438571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
439571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
440571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fArray->push(obj);
441571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return true;
442571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
443571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4442af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the size of an array.
445571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    size_t size() const {
4460fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
4470fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
448571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kArray_PdfObjectType);
449571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
450571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fArray->count();
451571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
452571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4532af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns one object of an array, by index.
4543aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfNativeObject* objAtAIndex(int i) {
4550fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
4560fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
457571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kArray_PdfObjectType);
458571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
459571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return (*fArray)[i];
460571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
461571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4622af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns one object of an array, by index.
4632af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    const SkPdfNativeObject* objAtAIndex(int i) const {
464c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        SkPdfMarkObjectUsed();
4650fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
466571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kArray_PdfObjectType);
467571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4682af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com        return (*fArray)[i];
469571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
470571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4712af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns one object of an array, by index.
4722af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    SkPdfNativeObject* operator[](int i) {
4730fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
4740fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
475571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kArray_PdfObjectType);
476571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
477571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return (*fArray)[i];
478571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
479571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4802af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    const SkPdfNativeObject* operator[](int i) const {
481c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        SkPdfMarkObjectUsed();
482c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com
483571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kArray_PdfObjectType);
484571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
485571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return (*fArray)[i];
486571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
487571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4882af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Removes the last object in the array.
4892af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    SkPdfNativeObject* removeLastInArray() {
4900fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
4910fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
492571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kArray_PdfObjectType);
493571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
4942af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com        SkPdfNativeObject* ret = NULL;
4952af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com        fArray->pop(&ret);
4962af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com
4972af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com        return ret;
498571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
499571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
5002af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Creates an empty Dictionary object. Assumes and asserts that it was never initialized.
501598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com    static void makeEmptyDictionary(SkPdfNativeObject* obj) {
502571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
503571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
504571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fObjectType = kDictionary_PdfObjectType;
5053aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        obj->fMap = new SkTDict<SkPdfNativeObject*>(1);
506571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fStr.fBuffer = NULL;
507571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fStr.fBytes = 0;
508571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
509571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
510c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    // TODO(edisonn): perf: get all the possible names from spec, and compute a hash function
511571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // that would create no overlaps in the same dictionary
512571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // or build a tree of chars that when followed goes to a unique id/index/hash
513571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // TODO(edisonn): generate constants like kDictFoo, kNameDict_name
514571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // which will be used in code
515571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // add function SkPdfFastNameKey key(const char* key);
516c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    // TODO(edisonn): setting the same key twice, will make the value undefined!
5172af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com
5182af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // this[key] = value;
5193aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    bool set(const SkPdfNativeObject* key, SkPdfNativeObject* value) {
520c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        SkPdfMarkObjectUsed();
5210fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
522571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kDictionary_PdfObjectType);
523571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(key->fObjectType == kName_PdfObjectType);
524571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
525571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
526c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert?
527571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return false;
528571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
529571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
530d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com        return set(key->fStr.fBuffer, key->fStr.fBytes, value);
531571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
532571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
5332af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // this[key] = value;
5343aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    bool set(const char* key, SkPdfNativeObject* value) {
535c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        SkPdfMarkObjectUsed();
5360fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
537d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com        return set((const unsigned char*)key, strlen(key), value);
538d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com    }
539d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com
5402af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // this[key] = value;
5413aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    bool set(const unsigned char* key, size_t len, SkPdfNativeObject* value) {
542c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        SkPdfMarkObjectUsed();
5430fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
544571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kDictionary_PdfObjectType);
545571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
546571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kDictionary_PdfObjectType) {
547c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
548571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return false;
549571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
550571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
551d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com        return fMap->set((const char*)key, len, value);
552571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
553571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
5542af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns an object from a Dictionary, identified by it's name.
5553aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfNativeObject* get(const SkPdfNativeObject* key) {
5560fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
5570fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
558571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kDictionary_PdfObjectType);
559571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(key->fObjectType == kName_PdfObjectType);
560571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
561571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
562c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
5633fc482620e8af9442f588e3bf364e198c41ba913edisonn@google.com            return NULL;
564571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
565571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
566d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com        return get(key->fStr.fBuffer, key->fStr.fBytes);
567571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
568571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
5692af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns an object from a Dictionary, identified by it's name.
5703aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfNativeObject* get(const char* key) {
5710fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
5720fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
573d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com        return get((const unsigned char*)key, strlen(key));
574d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com    }
575d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com
5762af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns an object from a Dictionary, identified by it's name.
5773aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfNativeObject* get(const unsigned char* key, size_t len) {
5780fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
5790fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
580571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kDictionary_PdfObjectType);
581571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(key);
582571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kDictionary_PdfObjectType) {
583c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
584571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return NULL;
585571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
5863aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        SkPdfNativeObject* ret = NULL;
587d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com        fMap->find((const char*)key, len, &ret);
5889a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com
5899a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com#ifdef PDF_TRACE
5909a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com        SkString _key;
5919a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com        _key.append((const char*)key, len);
592c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        printf("\nget(/%s) = %s\n", _key.c_str(),
593c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com               ret ? ret->toString(0, len + 9).c_str() : "_NOT_FOUND");
5949a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com#endif
5959a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com
596571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return ret;
597571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
598571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
5992af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns an object from a Dictionary, identified by it's name.
6003aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    const SkPdfNativeObject* get(const SkPdfNativeObject* key) const {
6010fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
6020fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
603571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kDictionary_PdfObjectType);
604571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(key->fObjectType == kName_PdfObjectType);
605571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
606571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
607c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
6083fc482620e8af9442f588e3bf364e198c41ba913edisonn@google.com            return NULL;
609571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
610571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
611d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com        return get(key->fStr.fBuffer, key->fStr.fBytes);
612571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
613571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
6142af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns an object from a Dictionary, identified by it's name.
6153aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    const SkPdfNativeObject* get(const char* key) const {
6160fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
6170fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
618d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com        return get((const unsigned char*)key, strlen(key));
619d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com    }
620d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com
6212af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns an object from a Dictionary, identified by it's name.
6223aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    const SkPdfNativeObject* get(const unsigned char* key, size_t len) const {
6230fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
6240fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
625571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kDictionary_PdfObjectType);
626571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(key);
627571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kDictionary_PdfObjectType) {
628c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
629571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return NULL;
630571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
6313aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        SkPdfNativeObject* ret = NULL;
632d761e3295c10e467d5ae4a5f52ad80c85b656e23edisonn@google.com        fMap->find((const char*)key, len, &ret);
6339a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com
6349a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com#ifdef PDF_TRACE
6359a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com        SkString _key;
6369a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com        _key.append((const char*)key, len);
637c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        printf("\nget(/%s) = %s\n", _key.c_str(),
638c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com               ret ? ret->toString(0, len + 9).c_str() : "_NOT_FOUND");
6399a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com#endif
6409a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com
641571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return ret;
642571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
643571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
6442af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns an object from a Dictionary, identified by it's name.
6453aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    const SkPdfNativeObject* get(const char* key, const char* abr) const {
6460fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
6470fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
6483aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        const SkPdfNativeObject* ret = get(key);
649c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        // TODO(edisonn): remove  || *abr == '\0' and pass NULL in the _autogen files instead.
650571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (ret != NULL || abr == NULL || *abr == '\0') {
651571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return ret;
652571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
653571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return get(abr);
654571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
655571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
6562af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns an object from a Dictionary, identified by it's name.
6573aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfNativeObject* get(const char* key, const char* abr) {
6580fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
6590fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
6603aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        SkPdfNativeObject* ret = get(key);
661c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        // TODO(edisonn): remove  || *abr == '\0' and pass NULL in the _autogen files instead.
662571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (ret != NULL || abr == NULL || *abr == '\0') {
663571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return ret;
664571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
665571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return get(abr);
666571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
667571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
6682af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Casts the object to a Dictionary. Asserts if the object is not a Dictionary.
669571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfDictionary* asDictionary() {
6700fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
6710fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
672571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(isDictionary());
673571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (!isDictionary()) {
674571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return NULL;
675571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
676571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return (SkPdfDictionary*) this;
677571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
678571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
6792af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Casts the object to a Dictionary. Asserts if the object is not a Dictionary.
680571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    const SkPdfDictionary* asDictionary() const {
6810fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
6820fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
683571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(isDictionary());
684571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (!isDictionary()) {
685571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return NULL;
686571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
687571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return (SkPdfDictionary*) this;
688571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
689571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
690571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
6912af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Reference.
692571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isReference() const {
6930fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
6940fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
695571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kReference_PdfObjectType;
696571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
697571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
6982af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Boolean.
699571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isBoolean() const {
7000fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7010fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
702571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kBoolean_PdfObjectType;
703571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
704571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
7052af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is an Integer.
706571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isInteger() const {
7070fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7080fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
709571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kInteger_PdfObjectType;
710571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
7112af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com
712571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comprivate:
7132af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Real number.
714571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isReal() const {
7150fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7160fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
717571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kReal_PdfObjectType;
718571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
7192af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com
720571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.compublic:
7212af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Number (either Integer or Real).
722571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isNumber() const {
7230fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7240fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
725571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kInteger_PdfObjectType || fObjectType == kReal_PdfObjectType;
726571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
727571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
7282af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a R keyword (used to identify references, e.g. "10 3 R".
729571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isKeywordReference() const {
7300fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7310fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
732571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kKeyword_PdfObjectType && fStr.fBytes == 1 && fStr.fBuffer[0] == 'R';
733571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
734571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
7352af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Keyword.
736571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isKeyword() const {
7370fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7380fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
739571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kKeyword_PdfObjectType;
740571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
741571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
7422af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a given Keyword.
7434ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com    bool isKeyword(const char* keyword) const {
7440fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7450fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
7464ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com        if (!isKeyword()) {
7474ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com            return false;
7484ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com        }
7494ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com
7504ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com        if (strlen(keyword) != fStr.fBytes) {
7514ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com            return false;
7524ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com        }
7534ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com
7544ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com        if (strncmp(keyword, (const char*)fStr.fBuffer, fStr.fBytes) != 0) {
7554ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com            return false;
7564ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com        }
7574ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com
7584ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com        return true;
7594ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com    }
7604ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com
7612af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Name.
762571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isName() const {
7630fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7640fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
765571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kName_PdfObjectType;
766571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
767571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
7682af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a given Name.
76978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com    bool isName(const char* name) const {
7700fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7710fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
772c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        return fObjectType == kName_PdfObjectType &&
773c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                fStr.fBytes == strlen(name) &&
774c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                strncmp((const char*)fStr.fBuffer, name, fStr.fBytes) == 0;
77578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com    }
77678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com
7772af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is an Array.
778571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isArray() const {
7790fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7800fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
781571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kArray_PdfObjectType;
782571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
783571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
7842af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Date.
7852af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // TODO(edisonn): NYI
786571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isDate() const {
7870fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7880fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
789571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType;
790571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
791571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
7922af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Dictionary.
793571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isDictionary() const {
7940fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
7950fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
796571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kDictionary_PdfObjectType;
797571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
798571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
7992af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Date.
8002af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // TODO(edisonn): NYI
801571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isFunction() const {
8020fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8030fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
804571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return false;  // NYI
805571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
806571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
8072af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Rectangle.
808571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isRectangle() const {
8090fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8100fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
811c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        // TODO(edisonn): add also that each of these 4 objects are numbers.
812c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        return fObjectType == kArray_PdfObjectType && fArray->count() == 4;
813571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
814571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
8152af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // TODO(edisonn): Design: decide if we should use hasStream or isStream
8162af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object has a stream associated with it.
817571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool hasStream() const {
8180fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8190fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
820571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return isDictionary() && fStr.fBuffer != NULL;
821571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
822571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
8232af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the stream associated with the dictionary. As of now, it casts this to Stream.
824571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    const SkPdfStream* getStream() const {
8250fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8260fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
827571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return hasStream() ? (const SkPdfStream*)this : NULL;
828571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
829571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
8302af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the stream associated with the dictionary. As of now, it casts this to Stream.
831571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkPdfStream* getStream() {
8320fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8330fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
834571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return hasStream() ? (SkPdfStream*)this : NULL;
835571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
836571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
8372af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a String or HexString.
838571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isAnyString() const {
8390fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8400fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
841571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType;
842571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
843571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
8442af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a HexString.
845b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com    bool isHexString() const {
8460fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8470fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
848b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com        return fObjectType == kHexString_PdfObjectType;
849b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com    }
850b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com
8512af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the object is a Matrix.
852571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isMatrix() const {
8530fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8540fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
855c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        // TODO(edisonn): add also that each of these 6 objects are numbers.
856c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        return fObjectType == kArray_PdfObjectType && fArray->count() == 6;
857571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
858571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
8592af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the int value stored in the object. Assert if the object is not an Integer.
860571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    inline int64_t intValue() const {
8610fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8620fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
863571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kInteger_PdfObjectType);
864571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
865571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kInteger_PdfObjectType) {
866c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
867571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return 0;
868571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
869571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fIntegerValue;
870571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
8712af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com
872571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comprivate:
8732af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the real value stored in the object. Assert if the object is not a Real.
874571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    inline double realValue() const {
8750fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8760fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
877571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kReal_PdfObjectType);
878571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
879571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kReal_PdfObjectType) {
880c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
881571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return 0;
882571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
883571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fRealValue;
884571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
8852af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com
886571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.compublic:
8872af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the numeric value stored in the object. Assert if the object is not a Real
8882af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // or an Integer.
889571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    inline double numberValue() const {
8900fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
8910fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
892571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(isNumber());
893571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
894571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (!isNumber()) {
895c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
896571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return 0;
897571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
898571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fObjectType == kReal_PdfObjectType ? fRealValue : fIntegerValue;
899571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
900571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
9012af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the numeric value stored in the object as a scalar. Assert if the object is not
9022af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // a Realor an Integer.
903a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com    inline SkScalar scalarValue() const {
9040fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
9050fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
906a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com        SkASSERT(isNumber());
907a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com
908a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com        if (!isNumber()) {
909c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
910a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com            return SkIntToScalar(0);
911a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com        }
912a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com        return fObjectType == kReal_PdfObjectType ? SkDoubleToScalar(fRealValue) :
913a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com                                                    SkIntToScalar(fIntegerValue);
914a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com    }
915a0cefa18fc25cca4264be04ce30c0c9692487a02edisonn@google.com
9162af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the id of the referenced object. Assert if the object is not a Reference.
917571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    int referenceId() const {
9180fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
9190fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
920571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kReference_PdfObjectType);
921571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fRef.fId;
922571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
923571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
9242af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the generation of the referenced object. Assert if the object is not a Reference.
925571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    int referenceGeneration() const {
9260fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
9270fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
928571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kReference_PdfObjectType);
929571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fRef.fGen;
930571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
931571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
9322af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the buffer of a Name object. Assert if the object is not a Name.
933571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    inline const char* nameValue() const {
9340fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
9350fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
936571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kName_PdfObjectType);
937571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
938571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kName_PdfObjectType) {
939c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
940571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return "";
941571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
942571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return (const char*)fStr.fBuffer;
943571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
944571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
9452af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the buffer of a (Hex)String object. Assert if the object is not a (Hex)String.
946571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    inline const char* stringValue() const {
9470fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
9480fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
949571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType);
950571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
951571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) {
952c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
953571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return "";
954571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
955571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return (const char*)fStr.fBuffer;
956571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
957571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
9582af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the storage of any type that can hold a form of string.
9592ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    inline NotOwnedString strRef() {
9600fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
9610fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
9622ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com        switch (fObjectType) {
9632ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com            case kString_PdfObjectType:
9642ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com            case kHexString_PdfObjectType:
9652ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com            case kKeyword_PdfObjectType:
966276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com            case kName_PdfObjectType:
9672ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com                return fStr;
9682ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com
9692ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com            default:
9702ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com                // TODO(edisonn): report/warning
9712ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com                return NotOwnedString();
9722ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com        }
9732ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    }
9742ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com
975571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // TODO(edisonn): nameValue2 and stringValue2 are used to make code generation easy,
976571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // but it is not a performat way to do it, since it will create an extra copy
977571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    // remove these functions and make code generated faster
978063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com    inline SkString nameValue2() const {
9790fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
9800fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
981571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kName_PdfObjectType);
982571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
983571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kName_PdfObjectType) {
984571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            // TODO(edisonn): log err
985063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com            return SkString();
986571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
987063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com        return SkString((const char*)fStr.fBuffer, fStr.fBytes);
988571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
989571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
9902af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns an SkString with the value of the (Hex)String object.
991063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com    inline SkString stringValue2() const {
9920fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
9930fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
994571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType);
995571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
996571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) {
997c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
998063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com            return SkString();
999571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1000063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com        return SkString((const char*)fStr.fBuffer, fStr.fBytes);
1001571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1002571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
10032af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the boolean of the Bool object. Assert if the object is not a Bool.
1004571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    inline bool boolValue() const {
10050fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
10060fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
1007571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(fObjectType == kBoolean_PdfObjectType);
1008571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1009f111a4b6855277bba8dac84cce7ccfa1b3f25d7cedisonn@google.com        if (fObjectType != kBoolean_PdfObjectType) {
1010c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            // TODO(edisonn): report/warn/assert.
1011571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return false;
1012571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1013571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return fBooleanValue;
1014571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1015571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
10162af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the rectangle of the Rectangle object. Assert if the object is not a Rectangle.
1017571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkRect rectangleValue() const {
10180fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
10190fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
1020571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(isRectangle());
1021571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (!isRectangle()) {
1022571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return SkRect::MakeEmpty();
1023571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1024571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1025571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        double array[4];
1026571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        for (int i = 0; i < 4; i++) {
1027571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            // TODO(edisonn): version where we could resolve references?
10283aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            const SkPdfNativeObject* elem = objAtAIndex(i);
1029571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            if (elem == NULL || !elem->isNumber()) {
1030c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                // TODO(edisonn): report/warn/assert.
1031571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                return SkRect::MakeEmpty();
1032571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            }
1033571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            array[i] = elem->numberValue();
1034571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1035571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1036571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return SkRect::MakeLTRB(SkDoubleToScalar(array[0]),
1037571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                                SkDoubleToScalar(array[1]),
1038571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                                SkDoubleToScalar(array[2]),
1039571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                                SkDoubleToScalar(array[3]));
1040571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1041571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
10422af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the matrix of the Matrix object. Assert if the object is not a Matrix.
1043571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    SkMatrix matrixValue() const {
10440fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
10450fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
1046571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(isMatrix());
1047571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (!isMatrix()) {
1048571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return SkMatrix::I();
1049571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1050571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1051571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        double array[6];
1052571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        for (int i = 0; i < 6; i++) {
1053571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            // TODO(edisonn): version where we could resolve references?
10543aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            const SkPdfNativeObject* elem = objAtAIndex(i);
1055571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            if (elem == NULL || !elem->isNumber()) {
1056c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                // TODO(edisonn): report/warn/assert.
1057571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                return SkMatrix::I();
1058571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            }
1059571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            array[i] = elem->numberValue();
1060571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1061571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1062571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return SkMatrixFromPdfMatrix(array);
1063571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1064571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
10652af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Runs all the filters of this stream, except the last one, if it is a DCT.
10662af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns false on failure.
10672ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    bool filterStream();
1068571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
10692af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Runs all the filters of this stream, except the last one, if it is a DCT, a gives back
10702af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // the buffer and the length. The object continues to own the buffer.
10712af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns false on failure.
10722ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    bool GetFilteredStreamRef(unsigned char const** buffer, size_t* len) {
10730fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
10740fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
1075c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        // TODO(edisonn): add params that could let the last filter in place
1076c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        // if it is jpeg or png to fast load images.
1077571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (!hasStream()) {
1078571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return false;
1079571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1080571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
10812ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com        filterStream();
1082571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1083571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (buffer) {
1084571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            *buffer = fStr.fBuffer;
1085571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1086571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1087571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (len) {
1088c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            *len = fStr.fBytes >> 2;  // last 2 bits - TODO(edisonn): clean up.
1089571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1090571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1091571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return true;
1092571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1093571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
10942af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if the stream is already filtered.
1095571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    bool isStreamFiltered() const {
10960fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
10970fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
1098571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return hasStream() && ((fStr.fBytes & 1) == kFilteredStreamBit);
1099571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1100571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
11012af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns true if this object own the buffer, or false if an Allocator own it.
11022ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    bool isStreamOwned() const {
11030fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
11040fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
11052ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com        return hasStream() && ((fStr.fBytes & 2) == kOwnedStreamBit);
11062ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    }
11072ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com
11082af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Gives back the original buffer and the length. The object continues to own the buffer.
11092af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns false if the stream is already filtered.
11102ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    bool GetUnfilteredStreamRef(unsigned char const** buffer, size_t* len) const {
11110fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com        SkPdfMarkObjectUsed();
11120fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
1113571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (isStreamFiltered()) {
1114571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return false;
1115571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1116571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1117571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (!hasStream()) {
1118571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return false;
1119571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1120571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1121571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (buffer) {
1122571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            *buffer = fStr.fBuffer;
1123571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1124571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1125571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (len) {
1126c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com            *len = fStr.fBytes >> 2;  // remove last 2 bits - TODO(edisonn): clean up.
1127571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1128571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1129571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return true;
1130571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1131571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
11322af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Add a stream to this Dictionarry. Asserts we do not have yet a stream.
11332ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    bool addStream(const unsigned char* buffer, size_t len) {
1134c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com        SkPdfMarkObjectUsed();
11350fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com
1136571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(!hasStream());
1137571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(isDictionary());
1138571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1139571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        if (!isDictionary() || hasStream()) {
1140571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            return false;
1141571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1142571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1143571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fStr.fBuffer = buffer;
1144571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        fStr.fBytes = (len << 2) + kUnfilteredStreamBit;
1145571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1146571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return true;
1147571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1148571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1149276fed9e0ae2e4457efd61eeb14738040feb65f1edisonn@google.com    static void appendSpaces(SkString* str, int level) {
11509a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com        for (int i = 0 ; i < level; i++) {
11519a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com            str->append(" ");
11529a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com        }
11539a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com    }
11549a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com
11553aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    static void append(SkString* str, const char* data, size_t len, const char* prefix = "\\x") {
11563aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        for (unsigned int i = 0 ; i < len; i++) {
11573aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            if (data[i] == kNUL_PdfWhiteSpace) {
11583aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append(prefix);
11593aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append("00");
11603aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            } else if (data[i] == kHT_PdfWhiteSpace) {
11613aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append(prefix);
11623aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append("09");
11633aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            } else if (data[i] == kLF_PdfWhiteSpace) {
11643aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append(prefix);
11653aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append("0A");
11663aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            } else if (data[i] == kFF_PdfWhiteSpace) {
11673aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append(prefix);
11683aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append("0C");
11693aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            } else if (data[i] == kCR_PdfWhiteSpace) {
11703aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append(prefix);
11713aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append("0D");
11723aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            } else {
11733aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                str->append(data + i, 1);
11743aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com            }
11753aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com        }
11763aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    }
11773aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com
11782af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com    // Returns the string representation of the object value.
1179e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com    SkString toString(int firstRowLevel = 0, int level = 0) {
1180571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkString str;
11819a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com        appendSpaces(&str, firstRowLevel);
1182571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        switch (fObjectType) {
1183571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kInvalid_PdfObjectType:
11849a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.append("__Invalid");
1185571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1186571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1187571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kBoolean_PdfObjectType:
11889a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.appendf("%s", fBooleanValue ? "true" : "false");
1189571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1190571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1191571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kInteger_PdfObjectType:
11929a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.appendf("%i", (int)fIntegerValue);
1193571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1194571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1195571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kReal_PdfObjectType:
11969a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.appendf("%f", fRealValue);
1197571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1198571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1199571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kString_PdfObjectType:
12009a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.append("\"");
12013aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                append(&str, (const char*)fStr.fBuffer, fStr.fBytes);
12029a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.append("\"");
1203571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1204571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1205571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kHexString_PdfObjectType:
12069a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.append("<");
1207b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com                for (unsigned int i = 0 ; i < fStr.fBytes; i++) {
1208b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com                    str.appendf("%02x", (unsigned int)fStr.fBuffer[i]);
1209b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com                }
12109a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.append(">");
1211571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1212571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1213571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kName_PdfObjectType:
12149a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.append("/");
12153aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                append(&str, (const char*)fStr.fBuffer, fStr.fBytes, "#");
1216571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1217571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1218571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kKeyword_PdfObjectType:
12193aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                append(&str, (const char*)fStr.fBuffer, fStr.fBytes);
1220571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1221571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1222571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kArray_PdfObjectType:
12239a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.append("[\n");
1224571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                for (unsigned int i = 0; i < size(); i++) {
12259a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    str.append(objAtAIndex(i)->toString(level + 1, level + 1));
12269a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    if (i < size() - 1) {
12279a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                        str.append(",");
12289a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    }
12299a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    str.append("\n");
1230571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                }
12319a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                appendSpaces(&str, level);
1232571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                str.append("]");
1233571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1234571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
12359a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com            case kDictionary_PdfObjectType: {
12363aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                    SkTDict<SkPdfNativeObject*>::Iter iter(*fMap);
12373aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                    SkPdfNativeObject* obj = NULL;
12389a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    const char* key = NULL;
12399a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    str.append("<<\n");
12409a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    while ((key = iter.next(&obj)) != NULL) {
12419a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                        appendSpaces(&str, level + 2);
1242c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                        str.appendf("/%s %s\n", key,
1243c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                                    obj->toString(0, level + strlen(key) + 4).c_str());
12449a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    }
12459a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    appendSpaces(&str, level);
12469a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    str.append(">>");
12479a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    if (hasStream()) {
1248e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com                        const unsigned char* stream = NULL;
1249e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com                        size_t length = 0;
1250e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com                        if (GetFilteredStreamRef(&stream, &length)) {
1251b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com                            str.append("stream\n");
12523aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com                            append(&str, (const char*)stream, length > 256 ? 256 : length);
1253b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com                            str.append("\nendstream");
1254e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com                        } else {
1255e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com                            str.append("stream STREAM_ERROR endstream");
1256e2e01ffb948468d4c3701f7f2a1d0c5ea75657f4edisonn@google.com                        }
12579a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                    }
1258571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                }
1259571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1260571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1261571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kNull_PdfObjectType:
1262571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                str = "NULL";
1263571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1264571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1265571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kReference_PdfObjectType:
12669a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str.appendf("%i %i R", fRef.fId, fRef.fGen);
1267571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1268571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1269571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            case kUndefined_PdfObjectType:
1270571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                str = "Undefined";
1271571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1272571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1273571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com            default:
12749a43c18740d3251b4d52703a0247719a0aef6474edisonn@google.com                str = "Error";
1275571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com                break;
1276571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        }
1277571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1278571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        return str;
1279571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1280571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1281571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comprivate:
1282c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    static void makeStringCore(const unsigned char* start, SkPdfNativeObject* obj,
1283c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                               ObjectType type) {
1284598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, strlen((const char*)start), obj, type);
1285571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1286571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1287c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    static void makeStringCore(const unsigned char* start, const unsigned char* end,
1288c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                               SkPdfNativeObject* obj, ObjectType type) {
1289598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        makeStringCore(start, end - start, obj, type);
1290571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1291571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1292c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com    static void makeStringCore(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj,
1293c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com                               ObjectType type) {
1294571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
1295571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
1296571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fObjectType = type;
1297571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fStr.fBuffer = start;
1298571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com        obj->fStr.fBytes = bytes;
1299571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com    }
1300571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
13012ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    bool applyFilter(const char* name);
13022ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    bool applyFlateDecodeFilter();
13032ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com    bool applyDCTDecodeFilter();
1304571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com};
1305571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
13062af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com// These classes are provided for convenience. You still have to make sure an SkPdfInteger
13072af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com// is indeed an Integer.
13083aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comclass SkPdfStream : public SkPdfNativeObject {};
13093aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comclass SkPdfArray : public SkPdfNativeObject {};
13103aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comclass SkPdfString : public SkPdfNativeObject {};
13113aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comclass SkPdfHexString : public SkPdfNativeObject {};
13123aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comclass SkPdfInteger : public SkPdfNativeObject {};
13133aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comclass SkPdfReal : public SkPdfNativeObject {};
13143aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comclass SkPdfNumber : public SkPdfNativeObject {};
1315571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com
13163aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comclass SkPdfName : public SkPdfNativeObject {
13173aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfName() : SkPdfNativeObject() {
1318598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        SkPdfNativeObject::makeName((const unsigned char*)"", this);
131978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com    }
132078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.compublic:
13213aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com    SkPdfName(char* name) : SkPdfNativeObject() {
1322598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com        this->makeName((const unsigned char*)name, this);
132378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com    }
132478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com};
132578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com
1326cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#endif  // SkPdfNativeObject
1327