SkPdfNativeTokenizer.h revision 598cf5d3cfc428108cf21ab45d73a995d7e5c2a8
1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#ifndef SkPdfNativeTokenizer_DEFINED 9#define SkPdfNativeTokenizer_DEFINED 10 11#include "SkPdfConfig.h" 12 13#include "SkTDArray.h" 14#include "SkTDict.h" 15#include <math.h> 16#include <string.h> 17 18class SkPdfDictionary; 19class SkPdfImageDictionary; 20 21// White Spaces 22#define kNUL_PdfWhiteSpace '\x00' 23#define kHT_PdfWhiteSpace '\x09' 24#define kLF_PdfWhiteSpace '\x0A' 25#define kFF_PdfWhiteSpace '\x0C' 26#define kCR_PdfWhiteSpace '\x0D' 27#define kSP_PdfWhiteSpace '\x20' 28 29// PdfDelimiters 30#define kOpenedRoundBracket_PdfDelimiter '(' 31#define kClosedRoundBracket_PdfDelimiter ')' 32#define kOpenedInequityBracket_PdfDelimiter '<' 33#define kClosedInequityBracket_PdfDelimiter '>' 34#define kOpenedSquareBracket_PdfDelimiter '[' 35#define kClosedSquareBracket_PdfDelimiter ']' 36#define kOpenedCurlyBracket_PdfDelimiter '{' 37#define kClosedCurlyBracket_PdfDelimiter '}' 38#define kNamed_PdfDelimiter '/' 39#define kComment_PdfDelimiter '%' 40 41#define kEscape_PdfSpecial '\\' 42#define kBackspace_PdfSpecial '\x08' 43 44// TODO(edisonn): what is the faster way for compiler/machine type to evaluate this expressions? 45// we should evaluate all options. might be even different from one machine to another 46// 1) expand expression, let compiler optimize it 47// 2) binary search 48// 3) linear search in array 49// 4) vector (e.f. T type[256] .. return type[ch] ... 50// 5) manually build the expression with least number of operators, e.g. for consecutive 51// chars, we can use an binary equal ignoring last bit 52#define isPdfWhiteSpace(ch) (((ch)==kNUL_PdfWhiteSpace)||((ch)==kHT_PdfWhiteSpace)||((ch)==kLF_PdfWhiteSpace)||((ch)==kFF_PdfWhiteSpace)||((ch)==kCR_PdfWhiteSpace)||((ch)==kSP_PdfWhiteSpace)) 53 54#define isPdfEOL(ch) (((ch)==kLF_PdfWhiteSpace)||((ch)==kCR_PdfWhiteSpace)) 55 56 57#define isPdfDelimiter(ch) (((ch)==kOpenedRoundBracket_PdfDelimiter)||\ 58 ((ch)==kClosedRoundBracket_PdfDelimiter)||\ 59 ((ch)==kOpenedInequityBracket_PdfDelimiter)||\ 60 ((ch)==kClosedInequityBracket_PdfDelimiter)||\ 61 ((ch)==kOpenedSquareBracket_PdfDelimiter)||\ 62 ((ch)==kClosedSquareBracket_PdfDelimiter)||\ 63 ((ch)==kOpenedCurlyBracket_PdfDelimiter)||\ 64 ((ch)==kClosedCurlyBracket_PdfDelimiter)||\ 65 ((ch)==kNamed_PdfDelimiter)||\ 66 ((ch)==kComment_PdfDelimiter)) 67 68#define isPdfWhiteSpaceOrPdfDelimiter(ch) (isPdfWhiteSpace(ch)||isPdfDelimiter(ch)) 69 70#define isPdfDigit(ch) ((ch)>='0'&&(ch)<='9') 71#define isPdfNumeric(ch) (isPdfDigit(ch)||(ch)=='+'||(ch)=='-'||(ch)=='.') 72 73const unsigned char* skipPdfWhiteSpaces(const unsigned char* buffer, const unsigned char* end); 74const unsigned char* endOfPdfToken(const unsigned char* start, const unsigned char* end); 75 76// TODO(edisonn): typedef read and integer tyepes? make less readable... 77//typedef double SkPdfReal; 78//typedef int64_t SkPdfInteger; 79 80// an allocator only allocates memory, and it deletes it all when the allocator is destroyed 81// this would allow us not to do any garbage collection while we parse or draw a pdf, and defere it 82// while the user is looking at the image 83 84class SkPdfNativeObject; 85 86class SkPdfAllocator { 87#define BUFFER_SIZE 1024 88 SkTDArray<SkPdfNativeObject*> fHistory; 89 SkTDArray<void*> fHandles; 90 SkPdfNativeObject* fCurrent; 91 int fCurrentUsed; 92 93 SkPdfNativeObject* allocBlock(); 94 size_t fSizeInBytes; 95 96public: 97 SkPdfAllocator() { 98 fSizeInBytes = sizeof(*this); 99 fCurrent = allocBlock(); 100 fCurrentUsed = 0; 101 } 102 103 ~SkPdfAllocator(); 104 105 SkPdfNativeObject* allocObject(); 106 107 // TODO(edisonn): free this memory in destructor, track the usage? 108 void* alloc(size_t bytes) { 109 void* data = malloc(bytes); 110 fHandles.push(data); 111 fSizeInBytes += bytes; 112 return data; 113 } 114 115 size_t bytesUsed() const { 116 return fSizeInBytes; 117 } 118}; 119 120class SkPdfNativeDoc; 121const unsigned char* nextObject(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* token, SkPdfAllocator* allocator, SkPdfNativeDoc* doc); 122 123enum SkPdfTokenType { 124 kKeyword_TokenType, 125 kObject_TokenType, 126}; 127 128struct PdfToken { 129 const char* fKeyword; 130 size_t fKeywordLength; 131 SkPdfNativeObject* fObject; 132 SkPdfTokenType fType; 133 134 PdfToken() : fKeyword(NULL), fKeywordLength(0), fObject(NULL) {} 135}; 136 137class SkPdfNativeTokenizer { 138public: 139 SkPdfNativeTokenizer(SkPdfNativeObject* objWithStream, SkPdfAllocator* allocator, SkPdfNativeDoc* doc); 140 SkPdfNativeTokenizer(const unsigned char* buffer, int len, SkPdfAllocator* allocator, SkPdfNativeDoc* doc); 141 142 virtual ~SkPdfNativeTokenizer(); 143 144 bool readToken(PdfToken* token); 145 bool readTokenCore(PdfToken* token); 146 void PutBack(PdfToken token); 147 SkPdfImageDictionary* readInlineImage(); 148 149private: 150 SkPdfNativeDoc* fDoc; 151 SkPdfAllocator* fAllocator; 152 153 const unsigned char* fUncompressedStreamStart; 154 const unsigned char* fUncompressedStream; 155 const unsigned char* fUncompressedStreamEnd; 156 157 bool fEmpty; 158 bool fHasPutBack; 159 PdfToken fPutBack; 160}; 161 162#endif // SkPdfNativeTokenizer_DEFINED 163