OLD | NEW |
1 | 1 |
2 | 2 |
3 import sys | 3 import sys |
4 | 4 |
5 import datatypes | 5 import datatypes |
6 import pdfspec_autogen | 6 import pdfspec_autogen |
7 | 7 |
8 | 8 knowTypes = { |
| 9 '(any)': ['SkPdfObject*', 'ObjectFromDictionary', datatypes.CppNull(), 'true'], |
| 10 '(undefined)': ['SkPdfObject*', 'ObjectFromDictionary', datatypes.CppNull(), 'tr
ue'], |
| 11 '(various)': ['SkPdfObject*', 'ObjectFromDictionary', datatypes.CppNull(), 'true
'], |
| 12 'array': ['SkPdfArray', 'ArrayFromDictionary', datatypes.PdfArrayNone(), 'ret->p
odofo()->GetDataType() == ePdfDataType_Array'], |
| 13 'boolean': ['bool', 'BoolFromDictionary', datatypes.PdfBoolean('false'), 'ret->p
odofo()->GetDataType() == ePdfDataType_Bool'], |
| 14 'date': ['SkPdfDate', 'DateFromDictionary', datatypes.PdfDateNever(), 'ret->podo
fo()->GetDataType() == ePdfDataType_Array'], |
| 15 'dictionary': ['SkPdfDictionary*', 'DictionaryFromDictionary', datatypes.CppNull
(), 'ret->podofo()->GetDataType() == ePdfDataType_Dictionary'], |
| 16 'function': ['SkPdfFunction', 'FunctionFromDictionary', datatypes.PdfFunctionNon
e(), 'ret->podofo()->GetDataType() == ePdfDataType_Reference'], |
| 17 'integer': ['long', 'LongFromDictionary', datatypes.PdfInteger(0), 'ret->podofo(
)->GetDataType() == ePdfDataType_Number'], |
| 18 'file_specification': ['SkPdfFileSpec', 'FileSpecFromDictionary', datatypes.File
SpecNone(), 'ret->podofo()->GetDataType() == ePdfDataType_Reference'], |
| 19 'name': ['std::string', 'NameFromDictionary', datatypes.PdfString('""'), 'ret->p
odofo()->GetDataType() == ePdfDataType_Name'], |
| 20 'tree': ['SkPdfTree*', 'TreeFromDictionary', datatypes.CppNull(), 'ret->podofo()
->GetDataType() == ePdfDataType_Reference'], |
| 21 'number': ['double', 'DoubleFromDictionary', datatypes.PdfNumber(0), 'ret->podof
o()->GetDataType() == ePdfDataType_Real'], |
| 22 'rectangle': ['SkRect', 'SkRectFromDictionary', datatypes.PdfEmptyRect(), 'ret->
podofo()->GetDataType() == ePdfDataType_Array'], |
| 23 'stream': ['SkPdfStream', 'StreamFromDictionary', datatypes.PdfEmptyStream(), '
ret->podofo()->HasStream()'], |
| 24 'string': ['std::string', 'StringFromDictionary', datatypes.PdfString('""'), 're
t->podofo()->GetDataType() == ePdfDataType_String || ret->podofo()->GetDataType(
) == ePdfDataType_HexString'], |
| 25 'text': ['std::string', 'StringFromDictionary', datatypes.PdfString('""'), 'ret-
>podofo()->GetDataType() == ePdfDataType_String || ret->podofo()->GetDataType()
== ePdfDataType_HexString'], |
| 26 'text string': ['std::string', 'StringFromDictionary', datatypes.PdfString('""')
, 'ret->podofo()->GetDataType() == ePdfDataType_String || ret->podofo()->GetData
Type() == ePdfDataType_HexString'], |
| 27 } |
9 | 28 |
10 | 29 |
11 class PdfField: | 30 class PdfField: |
12 def __init__(self, parent, name, abr): | 31 def __init__(self, parent, name, abr): |
13 self.fParent = parent | 32 self.fParent = parent |
14 self.fName = name | 33 self.fName = name |
15 self.fAbr = abr | 34 self.fAbr = abr |
16 | 35 |
17 self.fDefault = '' | 36 self.fDefault = '' |
18 self.fType = '' | 37 self.fTypes = '' |
19 self.fCppName = '' | 38 self.fCppName = '' |
20 self.fCppType = '' | 39 self.fEnumValues = [] |
21 self.fCppReader = '' | 40 self.fHasMust = False |
22 self.fValidOptions = [] | |
23 self.fHasMust = False | |
24 self.fMustBe = '' | 41 self.fMustBe = '' |
25 | 42 |
26 def must(self, value): | 43 def must(self, value): |
27 self.fHasMust = True | 44 self.fHasMust = True |
28 self.fMustBe = value | 45 self.fMustBe = value |
29 return self | 46 return self |
30 | 47 |
31 def default(self, value): | 48 def default(self, value): |
32 self.fDefault = value | 49 self.fDefault = value |
33 return self | 50 return self |
34 | 51 |
35 def number(self, name): | 52 def multiple(self, enumValues): |
36 self.fType = 'number' | 53 self.fEnumValues = enumValues |
37 self.fCppName = name | |
38 self.fCppType = 'double' | |
39 self.fCppReader = 'DoubleFromDictionary' | |
40 return self | |
41 | |
42 def integer(self, name): | |
43 self.fType = 'integer' | |
44 self.fCppName = name | |
45 self.fCppType = 'long' | |
46 self.fCppReader = 'LongFromDictionary' | |
47 return self | 54 return self |
48 | 55 |
49 def name(self, name): | 56 def name(self, name): |
50 self.fType = 'name' | |
51 self.fCppName = name | 57 self.fCppName = name |
52 self.fCppType = 'std::string' | |
53 self.fCppReader = 'NameFromDictionary' | |
54 return self | 58 return self |
55 | 59 |
56 def string(self, name): | 60 def type(self, types): |
57 self.fType = 'string' | 61 # TODO (edisonn): if simple type, use it, otherwise set it to Dictionary, an
d set a mask for valid types, like array or name |
58 self.fCppName = name | 62 types = types.strip() |
59 self.fCppType = 'std::string' | 63 types = types.replace('or', ' ') |
60 self.fCppReader = 'StringFromDictionary' | 64 types = types.replace(',', ' ') |
61 return self | 65 types = types.replace('text', ' ') # TODO(edisonn): what is the difference b
etween 'text string' and 'string'? |
| 66 types = types.replace('file specification', 'file_specification') |
62 | 67 |
63 def multiple(self, validOptions): | |
64 self.fValidOptions = validOptions | |
65 return self | |
66 | 68 |
67 def dictionary(self, name): | 69 self.fTypes = types |
68 self.fType = 'dictionary' | |
69 self.fCppName = name | |
70 self.fDictionaryType = 'Dictionary' | |
71 self.fCppType = 'SkPdfDictionary*' | |
72 self.fCppReader = 'DictionaryFromDictionary' | |
73 self.fDefault = datatypes.CppNull() | |
74 return self | |
75 | |
76 def type(self, type): | |
77 # TODO (edisonn): if simple type, use it, otherwise set it to Dictionary, an
d set a mask for valid types, like array or name | |
78 type = type.replace('or', ' ') | |
79 type = type.replace(',', ' ') | |
80 type = type.replace('text', ' ') # TODO(edisonn): what is the difference bet
ween 'text string' and 'string'? | |
81 | |
82 type = type.strip() | |
83 types = type.split() | |
84 | |
85 if len(types) == 1: | |
86 if type == 'integer': | |
87 self.integer(self.fCppName) | |
88 self.default(datatypes.PdfInteger(0)) | |
89 return self | |
90 | |
91 if type == 'number': | |
92 self.number(self.fCppName) | |
93 self.default(datatypes.PdfNumber(0)) | |
94 return self | |
95 | |
96 if type == 'string': | |
97 self.string(self.fCppName) | |
98 self.default(datatypes.PdfString('""')) | |
99 return self | |
100 | |
101 if type == 'name': | |
102 self.name(self.fCppName) | |
103 self.default(datatypes.PdfName('""')) | |
104 return self | |
105 | |
106 if type == 'dictionary': | |
107 self.dictionary(self.fCppName) | |
108 self.default(datatypes.CppNull()) | |
109 return self | |
110 | |
111 self.fType = 'object' | |
112 self.fDictionaryType = 'Object' | |
113 self.fCppType = 'SkPdfObject*' | |
114 self.fCppReader = 'ObjectFromDictionary' | |
115 self.fDefault = datatypes.CppNull() | |
116 return self | 70 return self |
117 | 71 |
118 def comment(self, comment): | 72 def comment(self, comment): |
119 return self | 73 return self |
120 | 74 |
121 def done(self): | 75 def done(self): |
122 return self.fParent | 76 return self.fParent |
123 | 77 |
124 | 78 |
125 class PdfClassField: | 79 class PdfClassField: |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 base = self.fClasses[cls.fBase] | 218 base = self.fClasses[cls.fBase] |
265 cnt = 0 | 219 cnt = 0 |
266 for sub in base.fEnumSubclasses: | 220 for sub in base.fEnumSubclasses: |
267 if enumToCls[base.fEnumSubclasses[cnt]].fName != cls.fName: | 221 if enumToCls[base.fEnumSubclasses[cnt]].fName != cls.fName: |
268 self.writeAsNull(enumToCls[base.fEnumSubclasses[cnt]], enumToCls) | 222 self.writeAsNull(enumToCls[base.fEnumSubclasses[cnt]], enumToCls) |
269 cnt = cnt + 1 | 223 cnt = cnt + 1 |
270 | 224 |
271 | 225 |
272 | 226 |
273 def write(self): | 227 def write(self): |
| 228 |
| 229 global knowTypes |
| 230 |
274 # generate enum | 231 # generate enum |
275 enumsRoot = [] | 232 enumsRoot = [] |
276 | 233 |
277 enumToCls = {} | 234 enumToCls = {} |
278 | 235 |
279 for name in self.fClasses: | 236 for name in self.fClasses: |
280 cls = self.fClasses[name] | 237 cls = self.fClasses[name] |
281 enum = self.longName(name) | 238 enum = self.longName(name) |
282 cls.fEnum = 'k' + enum + '_SkPdfObjectType' | 239 cls.fEnum = 'k' + enum + '_SkPdfObjectType' |
283 cls.fEnumEnd = 'k' + enum + '__End_SkPdfObjectType' | 240 cls.fEnumEnd = 'k' + enum + '__End_SkPdfObjectType' |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 print | 313 print |
357 | 314 |
358 print(' SkPdf' + cls.fName + '& operator=(const SkPdf' + cls.fName + '& f
rom) {this->fPodofoDoc = from.fPodofoDoc; this->fPodofoObj = from.fPodofoObj; re
turn *this;}') | 315 print(' SkPdf' + cls.fName + '& operator=(const SkPdf' + cls.fName + '& f
rom) {this->fPodofoDoc = from.fPodofoDoc; this->fPodofoObj = from.fPodofoObj; re
turn *this;}') |
359 print | 316 print |
360 | 317 |
361 for field in cls.fFields: | 318 for field in cls.fFields: |
362 prop = field.fProp | 319 prop = field.fProp |
363 if prop.fCppName != '': | 320 if prop.fCppName != '': |
364 if prop.fCppName[0] == '[': | 321 if prop.fCppName[0] == '[': |
365 print('/*') # comment code of the atributes that can have any name | 322 print('/*') # comment code of the atributes that can have any name |
366 | 323 |
367 print(' ' + prop.fCppType + ' ' + prop.fCppName + '() const {') | 324 # TODO(edisonn): has_foo(); |
368 print(' ' + prop.fCppType + ' ret;') | 325 print(' bool has_' + prop.fCppName + '() const {') |
369 print(' if (' + prop.fCppReader + '(fPodofoDoc, fPodofoObj->GetDict
ionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &ret)) return ret;') | 326 print(' return (ObjectFromDictionary(fPodofoDoc, fPodofoObj->GetD
ictionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", NULL));') |
370 if field.fRequired == False: | 327 print(' }') |
371 print(' return ' + prop.fDefault.toCpp() + ';'); | 328 |
372 if field.fRequired == True: | 329 if len(prop.fTypes.split()) == 1: |
373 print(' // TODO(edisonn): warn about missing required field, asse
rt for known good pdfs') | 330 t = prop.fTypes.strip() |
374 print(' return ' + field.fBadDefault + ';'); | 331 print(' ' + knowTypes[t][0] + ' ' + prop.fCppName + '() const {') |
375 print(' }') | 332 print(' ' + knowTypes[t][0] + ' ret;') |
376 print | 333 print(' if (' + knowTypes[t][1] + '(fPodofoDoc, fPodofoObj->GetDi
ctionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &ret)) return ret;') |
| 334 if field.fRequired == False and prop.fDefault != '': |
| 335 print(' return ' + prop.fDefault.toCpp() + ';'); |
| 336 else: |
| 337 print(' // TODO(edisonn): warn about missing required field, as
sert for known good pdfs') |
| 338 print(' return ' + knowTypes[t][2].toCpp() + ';'); |
| 339 print(' }') |
| 340 print |
| 341 else: |
| 342 for type in prop.fTypes.split(): |
| 343 t = type.strip() |
| 344 print(' bool is' + prop.fCppName + 'A' + t.title() + '() const {'
) |
| 345 print(' SkPdfObject* ret = NULL;') |
| 346 print(' if (!ObjectFromDictionary(fPodofoDoc, fPodofoObj->GetDi
ctionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &ret)) return false;'
) |
| 347 print(' return ' + knowTypes[t][3] + ';') |
| 348 print(' }') |
| 349 print |
| 350 |
| 351 print(' ' + knowTypes[t][0] + ' get' + prop.fCppName + 'As' + t.t
itle() + '() const {') |
| 352 print(' ' + knowTypes[t][0] + ' ret = ' + knowTypes[t][2].toCpp
() + ';') |
| 353 print(' if (' + knowTypes[t][1] + '(fPodofoDoc, fPodofoObj->Get
Dictionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &ret)) return ret;'
) |
| 354 print(' // TODO(edisonn): warn about missing required field, as
sert for known good pdfs') |
| 355 print(' return ' + knowTypes[t][2].toCpp() + ';') |
| 356 print(' }') |
| 357 print |
| 358 |
377 | 359 |
378 if prop.fCppName[0] == '[': | 360 if prop.fCppName[0] == '[': |
379 print('*/') # comment code of the atributes that can have any name | 361 print('*/') # comment code of the atributes that can have any name |
380 | 362 |
381 | 363 |
382 print('};') | 364 print('};') |
383 print | 365 print |
384 print | 366 print |
385 | 367 |
386 | 368 |
387 | 369 |
388 # generate constructor when knowing the type | 370 # generate constructor when knowing the type |
389 # later, p2, generate constructor when not knowing the type - very similar
with parsing? | 371 # later, p2, generate constructor when not knowing the type - very similar
with parsing? |
390 | 372 |
391 # generate parser | 373 # generate parser |
392 | 374 |
393 # TODO(edisonn): fast recognition based on must attributes. | 375 # TODO(edisonn): fast recognition based on must attributes. |
394 print('class PodofoMapper {') | 376 print('class PodofoMapper {') |
395 print('public:') | 377 print('public:') |
396 for name in self.fClassesNamesInOrder: | 378 for name in self.fClassesNamesInOrder: |
397 cls = self.fClasses[name] | 379 cls = self.fClasses[name] |
398 | 380 |
399 | 381 |
400 print(' static bool map(const SkPdfObject& in, SkPdf' + name + '** out) {
') | 382 print(' static bool map(const SkPdfObject& in, SkPdf' + name + '** out) {
') |
401 print(' return map(*in.doc(), *in.podofo(), out);') | 383 print(' return map(*in.doc(), *in.podofo(), out);') |
402 print(' }') | 384 print(' }') |
403 print | 385 print |
404 | 386 |
405 print(' static bool map(const PdfMemDocument& podofoDoc, const PdfObject&
podofoObj, SkPdf' + name + '** out) {') | 387 print(' static bool map(const PdfMemDocument& podofoDoc, const PdfObject&
podofoObj, SkPdf' + name + '** out) {') |
406 print(' if (!isA' + name + '(podofoDoc, podofoObj)) return false;') | 388 print(' if (!is' + name + '(podofoDoc, podofoObj)) return false;') |
407 print | 389 print |
408 | 390 |
409 for sub in cls.fEnumSubclasses: | 391 for sub in cls.fEnumSubclasses: |
410 print(' if (map(podofoDoc, podofoObj, (SkPdf' + enumToCls[sub].fName
+ '**)out)) return true;') | 392 print(' if (map(podofoDoc, podofoObj, (SkPdf' + enumToCls[sub].fName
+ '**)out)) return true;') |
411 | 393 |
412 print | 394 print |
413 | 395 |
414 print(' *out = new SkPdf' + name + '(&podofoDoc, &podofoObj);') | 396 print(' *out = new SkPdf' + name + '(&podofoDoc, &podofoObj);') |
415 print(' return true;') | 397 print(' return true;') |
416 print(' }') | 398 print(' }') |
417 print | 399 print |
418 | 400 |
419 for name in self.fClassesNamesInOrder: | 401 for name in self.fClassesNamesInOrder: |
420 cls = self.fClasses[name] | 402 cls = self.fClasses[name] |
421 | 403 |
422 print(' static bool isA' + name + '(const PdfMemDocument& podofoDoc, cons
t PdfObject& podofoObj) {') | 404 print(' static bool is' + name + '(const PdfMemDocument& podofoDoc, const
PdfObject& podofoObj) {') |
423 | 405 |
424 if cls.fCheck != '': | 406 if cls.fCheck != '': |
425 print(' return ' + cls.fCheck + ';') | 407 print(' return ' + cls.fCheck + ';') |
426 else: | 408 else: |
427 cntMust = 0 | 409 cntMust = 0 |
428 for field in cls.fFields: | 410 for field in cls.fFields: |
429 prop = field.fProp | 411 prop = field.fProp |
430 if prop.fHasMust: | 412 if prop.fHasMust: |
431 cntMust = cntMust + 1 | 413 cntMust = cntMust + 1 |
432 print(' ' + prop.fCppType + ' ' + prop.fCppName + ';') | 414 print(' ' + knowTypes[prop.fTypes.strip()][0] + ' ' + prop.fCppNa
me + ';') |
433 print(' if (!' + prop.fCppReader + '(&podofoDoc, podofoObj.GetDic
tionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &' + prop.fCppName + '
)) return false;') | 415 print(' if (!' + knowTypes[prop.fTypes.strip()][1] + '(&podofoDoc
, podofoObj.GetDictionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &' +
prop.fCppName + ')) return false;') |
434 print(' if (' + prop.fCppName + ' != ' + prop.fMustBe.toCpp() + '
) return false;') | 416 print(' if (' + prop.fCppName + ' != ' + prop.fMustBe.toCpp() + '
) return false;') |
435 print | 417 print |
436 | 418 |
437 print(' return true;') | 419 print(' return true;') |
438 | 420 |
439 print(' }') | 421 print(' }') |
440 print | 422 print |
441 | 423 |
442 print('};') | 424 print('};') |
443 print | 425 print |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 | 464 |
483 | 465 |
484 manager.write() | 466 manager.write() |
485 | 467 |
486 return 1 | 468 return 1 |
487 | 469 |
488 if '__main__' == __name__: | 470 if '__main__' == __name__: |
489 sys.exit(generateCode()) | 471 sys.exit(generateCode()) |
490 | 472 |
491 | 473 |
OLD | NEW |