OLD | NEW |
1 #include "SkNativeParsedPDF.h" | 1 #include "SkNativeParsedPDF.h" |
2 #include "SkPdfNativeTokenizer.h" | 2 #include "SkPdfNativeTokenizer.h" |
3 #include "SkPdfBasics.h" | 3 #include "SkPdfBasics.h" |
4 #include "SkPdfObject.h" | 4 #include "SkPdfObject.h" |
5 | 5 |
6 #include <stdio.h> | 6 #include <stdio.h> |
7 #include <string.h> | 7 #include <string.h> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 | 10 |
11 #include "SkPdfFileTrailerDictionary_autogen.h" | 11 #include "SkPdfFileTrailerDictionary_autogen.h" |
12 #include "SkPdfCatalogDictionary_autogen.h" | 12 #include "SkPdfCatalogDictionary_autogen.h" |
13 #include "SkPdfPageObjectDictionary_autogen.h" | 13 #include "SkPdfPageObjectDictionary_autogen.h" |
14 #include "SkPdfPageTreeNodeDictionary_autogen.h" | 14 #include "SkPdfPageTreeNodeDictionary_autogen.h" |
15 #include "SkPdfMapper_autogen.h" | 15 #include "SkPdfMapper_autogen.h" |
16 | 16 |
| 17 #include "SkStream.h" |
17 | 18 |
18 | 19 |
19 static long getFileSize(const char* filename) | 20 static long getFileSize(const char* filename) |
20 { | 21 { |
21 struct stat stat_buf; | 22 struct stat stat_buf; |
22 int rc = stat(filename, &stat_buf); | 23 int rc = stat(filename, &stat_buf); |
23 return rc == 0 ? (long)stat_buf.st_size : -1; | 24 return rc == 0 ? (long)stat_buf.st_size : -1; |
24 } | 25 } |
25 | 26 |
26 static const unsigned char* lineHome(const unsigned char* start, const unsigned
char* current) { | 27 static const unsigned char* lineHome(const unsigned char* start, const unsigned
char* current) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 | 61 |
61 SkNativeParsedPDF* gDoc = NULL; | 62 SkNativeParsedPDF* gDoc = NULL; |
62 | 63 |
63 // TODO(edisonn): NYI | 64 // TODO(edisonn): NYI |
64 // TODO(edisonn): 3 constructuctors from URL, from stream, from file ... | 65 // TODO(edisonn): 3 constructuctors from URL, from stream, from file ... |
65 // TODO(edisonn): write one that accepts errors in the file and ignores/fixis th
em | 66 // TODO(edisonn): write one that accepts errors in the file and ignores/fixis th
em |
66 // TODO(edisonn): testing: | 67 // TODO(edisonn): testing: |
67 // 1) run on a lot of file | 68 // 1) run on a lot of file |
68 // 2) recoverable corupt file: remove endobj, endsteam, remove other keywords, u
se other white spaces, insert comments randomly, ... | 69 // 2) recoverable corupt file: remove endobj, endsteam, remove other keywords, u
se other white spaces, insert comments randomly, ... |
69 // 3) irrecoverable corrupt file | 70 // 3) irrecoverable corrupt file |
| 71 |
| 72 SkNativeParsedPDF::SkNativeParsedPDF(SkStream* stream) |
| 73 : fAllocator(new SkPdfAllocator()) |
| 74 , fFileContent(NULL) |
| 75 , fContentLength(0) |
| 76 , fRootCatalogRef(NULL) |
| 77 , fRootCatalog(NULL) { |
| 78 size_t size = stream->getLength(); |
| 79 void* ptr = sk_malloc_throw(size); |
| 80 stream->read(ptr, size); |
| 81 |
| 82 init(ptr, size); |
| 83 } |
| 84 |
70 SkNativeParsedPDF::SkNativeParsedPDF(const char* path) | 85 SkNativeParsedPDF::SkNativeParsedPDF(const char* path) |
71 : fAllocator(new SkPdfAllocator()) | 86 : fAllocator(new SkPdfAllocator()) |
| 87 , fFileContent(NULL) |
| 88 , fContentLength(0) |
72 , fRootCatalogRef(NULL) | 89 , fRootCatalogRef(NULL) |
73 , fRootCatalog(NULL) { | 90 , fRootCatalog(NULL) { |
74 gDoc = this; | 91 gDoc = this; |
75 FILE* file = fopen(path, "r"); | 92 FILE* file = fopen(path, "r"); |
76 fContentLength = getFileSize(path); | 93 size_t size = getFileSize(path); |
77 unsigned char* content = new unsigned char[fContentLength + 1]; | 94 void* content = sk_malloc_throw(size); |
78 bool ok = (0 != fread(content, fContentLength, 1, file)); | 95 bool ok = (0 != fread(content, size, 1, file)); |
79 content[fContentLength] = '\0'; | |
80 fFileContent = content; | |
81 fclose(file); | 96 fclose(file); |
82 file = NULL; | 97 file = NULL; |
83 | 98 |
84 if (!ok) { | 99 if (!ok) { |
| 100 sk_free(content); |
85 // TODO(edisonn): report read error | 101 // TODO(edisonn): report read error |
| 102 // TODO(edisonn): not nice to return like this from constructor, create
a static |
| 103 // function that can report NULL for failures. |
86 return; // Doc will have 0 pages | 104 return; // Doc will have 0 pages |
87 } | 105 } |
88 | 106 |
| 107 init(content, size); |
| 108 } |
| 109 |
| 110 void SkNativeParsedPDF::init(const void* bytes, size_t length) { |
| 111 fFileContent = (const unsigned char*)bytes; |
| 112 fContentLength = length; |
89 const unsigned char* eofLine = lineHome(fFileContent, fFileContent + fConten
tLength - 1); | 113 const unsigned char* eofLine = lineHome(fFileContent, fFileContent + fConten
tLength - 1); |
90 const unsigned char* xrefByteOffsetLine = previousLineHome(fFileContent, eof
Line); | 114 const unsigned char* xrefByteOffsetLine = previousLineHome(fFileContent, eof
Line); |
91 const unsigned char* xrefstartKeywordLine = previousLineHome(fFileContent, x
refByteOffsetLine); | 115 const unsigned char* xrefstartKeywordLine = previousLineHome(fFileContent, x
refByteOffsetLine); |
92 | 116 |
93 if (strcmp((char*)xrefstartKeywordLine, "startxref") != 0) { | 117 if (strcmp((char*)xrefstartKeywordLine, "startxref") != 0) { |
94 // TODO(edisonn): report/issue | 118 // TODO(edisonn): report/issue |
95 } | 119 } |
96 | 120 |
97 long xrefByteOffset = atol((const char*)xrefByteOffsetLine); | 121 long xrefByteOffset = atol((const char*)xrefByteOffsetLine); |
98 | 122 |
(...skipping 20 matching lines...) Expand all Loading... |
119 | 143 |
120 // TODO(edisonn): corrupted pdf, read it from beginning and rebuild (xref, t
railer, or just reall all objects) | 144 // TODO(edisonn): corrupted pdf, read it from beginning and rebuild (xref, t
railer, or just reall all objects) |
121 // 0 pages | 145 // 0 pages |
122 | 146 |
123 // now actually read all objects if we want, or do it lazyly | 147 // now actually read all objects if we want, or do it lazyly |
124 // and resolve references?... or not ... | 148 // and resolve references?... or not ... |
125 } | 149 } |
126 | 150 |
127 // TODO(edisonn): NYI | 151 // TODO(edisonn): NYI |
128 SkNativeParsedPDF::~SkNativeParsedPDF() { | 152 SkNativeParsedPDF::~SkNativeParsedPDF() { |
129 delete[] fFileContent; | 153 sk_free((void*)fFileContent); |
130 delete fAllocator; | 154 delete fAllocator; |
131 } | 155 } |
132 | 156 |
133 const unsigned char* SkNativeParsedPDF::readCrossReferenceSection(const unsigned
char* xrefStart, const unsigned char* trailerEnd) { | 157 const unsigned char* SkNativeParsedPDF::readCrossReferenceSection(const unsigned
char* xrefStart, const unsigned char* trailerEnd) { |
134 const unsigned char* current = ignoreLine(xrefStart, trailerEnd); // TODO(e
disonn): verify next keyord is "xref", use nextObject here | 158 const unsigned char* current = ignoreLine(xrefStart, trailerEnd); // TODO(e
disonn): verify next keyord is "xref", use nextObject here |
135 | 159 |
136 SkPdfObject token; | 160 SkPdfObject token; |
137 while (current < trailerEnd) { | 161 while (current < trailerEnd) { |
138 token.reset(); | 162 token.reset(); |
139 const unsigned char* previous = current; | 163 const unsigned char* previous = current; |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 return (SkPdfObject*)ref; | 460 return (SkPdfObject*)ref; |
437 } | 461 } |
438 | 462 |
439 size_t SkNativeParsedPDF::bytesUsed() const { | 463 size_t SkNativeParsedPDF::bytesUsed() const { |
440 return fAllocator->bytesUsed() + | 464 return fAllocator->bytesUsed() + |
441 fContentLength + | 465 fContentLength + |
442 fObjects.count() * sizeof(PublicObjectEntry) + | 466 fObjects.count() * sizeof(PublicObjectEntry) + |
443 fPages.count() * sizeof(SkPdfPageObjectDictionary*) + | 467 fPages.count() * sizeof(SkPdfPageObjectDictionary*) + |
444 sizeof(*this); | 468 sizeof(*this); |
445 } | 469 } |
OLD | NEW |