blob: ad425d8e02cfdeb96486e5a94596125dbd0bd3aa [file] [log] [blame]
edisonn@google.com3aac1f92013-07-02 22:42:53 +00001#ifndef EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFNATIVETOKENIZER_H_
2#define EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFNATIVETOKENIZER_H_
3
edisonn@google.com571c70b2013-07-10 17:09:50 +00004#include "SkTDArray.h"
5#include "SkTDict.h"
6#include <math.h>
7#include <string.h>
8
9class SkPdfMapper;
10class SkPdfDictionary;
edisonn@google.com78b38b12013-07-15 18:20:58 +000011class SkPdfImageDictionary;
edisonn@google.com571c70b2013-07-10 17:09:50 +000012
13// White Spaces
14#define kNUL_PdfWhiteSpace '\x00'
15#define kHT_PdfWhiteSpace '\x09'
16#define kLF_PdfWhiteSpace '\x0A'
17#define kFF_PdfWhiteSpace '\x0C'
18#define kCR_PdfWhiteSpace '\x0D'
19#define kSP_PdfWhiteSpace '\x20'
20
21// PdfDelimiters
22#define kOpenedRoundBracket_PdfDelimiter '('
23#define kClosedRoundBracket_PdfDelimiter ')'
24#define kOpenedInequityBracket_PdfDelimiter '<'
25#define kClosedInequityBracket_PdfDelimiter '>'
26#define kOpenedSquareBracket_PdfDelimiter '['
27#define kClosedSquareBracket_PdfDelimiter ']'
28#define kOpenedCurlyBracket_PdfDelimiter '{'
29#define kClosedCurlyBracket_PdfDelimiter '}'
30#define kNamed_PdfDelimiter '/'
31#define kComment_PdfDelimiter '%'
32
33#define kEscape_PdfSpecial '\\'
34#define kBackspace_PdfSpecial '\x08'
35
36// TODO(edisonn): what is the faster way for compiler/machine type to evaluate this expressions?
37// we should evaluate all options. might be even different from one machine to another
38// 1) expand expression, let compiler optimize it
39// 2) binary search
40// 3) linear search in array
41// 4) vector (e.f. T type[256] .. return type[ch] ...
42// 5) manually build the expression with least number of operators, e.g. for consecutive
43// chars, we can use an binary equal ignoring last bit
44#define isPdfWhiteSpace(ch) (((ch)==kNUL_PdfWhiteSpace)||((ch)==kHT_PdfWhiteSpace)||((ch)==kLF_PdfWhiteSpace)||((ch)==kFF_PdfWhiteSpace)||((ch)==kCR_PdfWhiteSpace)||((ch)==kSP_PdfWhiteSpace))
45
46#define isPdfEOL(ch) (((ch)==kLF_PdfWhiteSpace)||((ch)==kCR_PdfWhiteSpace))
47
48
49#define isPdfDelimiter(ch) (((ch)==kOpenedRoundBracket_PdfDelimiter)||\
50 ((ch)==kClosedRoundBracket_PdfDelimiter)||\
51 ((ch)==kOpenedInequityBracket_PdfDelimiter)||\
52 ((ch)==kClosedInequityBracket_PdfDelimiter)||\
53 ((ch)==kOpenedSquareBracket_PdfDelimiter)||\
54 ((ch)==kClosedSquareBracket_PdfDelimiter)||\
55 ((ch)==kOpenedCurlyBracket_PdfDelimiter)||\
56 ((ch)==kClosedCurlyBracket_PdfDelimiter)||\
57 ((ch)==kNamed_PdfDelimiter)||\
58 ((ch)==kComment_PdfDelimiter))
59
60#define isPdfWhiteSpaceOrPdfDelimiter(ch) (isPdfWhiteSpace(ch)||isPdfDelimiter(ch))
61
62#define isPdfDigit(ch) ((ch)>='0'&&(ch)<='9')
63#define isPdfNumeric(ch) (isPdfDigit(ch)||(ch)=='+'||(ch)=='-')
64
65unsigned char* skipPdfWhiteSpaces(unsigned char* buffer, size_t len);
66unsigned char* endOfPdfToken(unsigned char* start, size_t len);
67unsigned char* skipPdfComment(unsigned char* start, size_t len);
68
69// TODO(edisonn): typedef read and integer tyepes? make less readable...
70//typedef double SkPdfReal;
71//typedef int64_t SkPdfInteger;
72
73// an allocator only allocates memory, and it deletes it all when the allocator is destroyed
74// this would allow us not to do any garbage collection while we parse or draw a pdf, and defere it
75// while the user is looking at the image
76
77class SkPdfObject;
78
79class SkPdfAllocator {
80#define BUFFER_SIZE 1024
81 SkTDArray<SkPdfObject*> fHistory;
82 SkTDArray<void*> fHandles;
83 SkPdfObject* fCurrent;
84 int fCurrentUsed;
85
86 SkPdfObject* allocBlock();
edisonn@google.coma5aaa792013-07-11 12:27:21 +000087 size_t fSizeInBytes;
edisonn@google.com571c70b2013-07-10 17:09:50 +000088
edisonn@google.com3aac1f92013-07-02 22:42:53 +000089public:
edisonn@google.com571c70b2013-07-10 17:09:50 +000090 SkPdfAllocator() {
edisonn@google.coma5aaa792013-07-11 12:27:21 +000091 fSizeInBytes = sizeof(*this);
edisonn@google.com571c70b2013-07-10 17:09:50 +000092 fCurrent = allocBlock();
93 fCurrentUsed = 0;
94 }
95
96 ~SkPdfAllocator();
97
98 SkPdfObject* allocObject();
99
100 // TODO(edisonn): free this memory in destructor, track the usage?
101 void* alloc(size_t bytes) {
102 void* data = malloc(bytes);
103 fHandles.push(data);
edisonn@google.coma5aaa792013-07-11 12:27:21 +0000104 fSizeInBytes += bytes;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000105 return data;
106 }
edisonn@google.coma5aaa792013-07-11 12:27:21 +0000107
edisonn@google.com7b328fd2013-07-11 12:53:06 +0000108 size_t bytesUsed() const {
edisonn@google.coma5aaa792013-07-11 12:27:21 +0000109 return fSizeInBytes;
110 }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000111};
112
edisonn@google.com951d6532013-07-10 23:17:31 +0000113class SkNativeParsedPDF;
114unsigned char* nextObject(unsigned char* start, unsigned char* end, SkPdfObject* token, SkPdfAllocator* allocator, SkNativeParsedPDF* doc);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000115
116enum SkPdfTokenType {
117 kKeyword_TokenType,
118 kObject_TokenType,
119};
120
121struct PdfToken {
122 const char* fKeyword;
123 size_t fKeywordLength;
124 SkPdfObject* fObject;
125 SkPdfTokenType fType;
126
127 PdfToken() : fKeyword(NULL), fKeywordLength(0), fObject(NULL) {}
128};
129
130class SkPdfNativeTokenizer {
131public:
edisonn@google.com951d6532013-07-10 23:17:31 +0000132 SkPdfNativeTokenizer(SkPdfObject* objWithStream, const SkPdfMapper* mapper, SkPdfAllocator* allocator, SkNativeParsedPDF* doc);
133 SkPdfNativeTokenizer(unsigned char* buffer, int len, const SkPdfMapper* mapper, SkPdfAllocator* allocator, SkNativeParsedPDF* doc);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000134
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000135 virtual ~SkPdfNativeTokenizer();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000136
137 bool readToken(PdfToken* token);
138 bool readTokenCore(PdfToken* token);
139 void PutBack(PdfToken token);
edisonn@google.com78b38b12013-07-15 18:20:58 +0000140 SkPdfImageDictionary* readInlineImage();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000141
142private:
edisonn@google.com951d6532013-07-10 23:17:31 +0000143 SkNativeParsedPDF* fDoc;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000144 const SkPdfMapper* fMapper;
145 SkPdfAllocator* fAllocator;
146
147 unsigned char* fUncompressedStreamStart;
148 unsigned char* fUncompressedStream;
149 unsigned char* fUncompressedStreamEnd;
150
151 bool fEmpty;
152 bool fHasPutBack;
153 PdfToken fPutBack;
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000154};
155
156#endif // EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFNATIVETOKENIZER_H_