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