Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: experimental/PdfViewer/generate_code.py

Issue 16838002: Code generator for dinamic generation of podofo wrappers (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | experimental/PdfViewer/pdf_auto_gen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 import sys 1 import sys
2 2
3 class PdfName: 3 class PdfName:
4 def __init__(self, name, abr=''): 4 def __init__(self, name, abr=''):
5 self.fName = name 5 self.fName = name
6 self.fAbr = abr 6 self.fAbr = abr
7
8 def toCpp(self):
9 return '\"' + self.fName + '\"'
10
11 class PdfString:
12 def __init__(self, value):
13 self.fValue = value
14
15 def toCpp(self):
16 return '\"' + self.fValue + '\"'
7 17
8 class PdfInteger: 18 class PdfInteger:
9 def __init__(self, value): 19 def __init__(self, value):
10 self.fValue = value 20 self.fValue = value
11 21
22 def toCpp(self):
23 return str(self.fValue)
24
12 class PdfReal: 25 class PdfReal:
13 def __init__(self, value): 26 def __init__(self, value):
14 self.fValue = value 27 self.fValue = value
15 28
29 def toCpp(self):
30 return str(self.fValue)
31
16 class PdfString: 32 class PdfString:
17 def __init__(self, value): 33 def __init__(self, value):
18 self.fValue = value 34 self.fValue = value
19 35
36 def toCpp(self):
37 return self.fValue
38
20 class PdfBoolean: 39 class PdfBoolean:
21 def __init__(self, value): 40 def __init__(self, value):
22 self.fValue = value 41 self.fValue = value
23 42
43 def toCpp(self):
44 return self.fValue
45
24 class PdfField: 46 class PdfField:
25 def __init__(self, parent, name, abr): 47 def __init__(self, parent, name, abr):
26 self.fParent = parent 48 self.fParent = parent
27 self.fName = name 49 self.fName = name
28 self.fAbr = abr 50 self.fAbr = abr
29 51
30 self.fDefault = '' 52 self.fDefault = ''
31 self.fType = '' 53 self.fType = ''
54 self.fCppName = ''
55 self.fCppType = ''
56 self.fCppReader = ''
57 self.fValidOptions = []
58 self.fHasMust = False
59 self.fMustBe = ''
32 60
33 def must(self, value): 61 def must(self, value):
34 return self.fParent 62 self.fHasMust = True
63 self.fMustBe = value
64 return self
35 65
36 def default(self, value): 66 def default(self, value):
37 self.fDefault = value 67 self.fDefault = value
38 return self 68 return self
39 69
40 def number(self): 70 def number(self, name):
41 self.fType = 'number' 71 self.fType = 'number'
72 self.fCppName = name
73 self.fCppType = 'double'
74 self.fCppReader = 'DoubleFromDictionary'
42 return self 75 return self
43 76
44 def integer(self): 77 def integer(self, name):
45 self.fType = 'integer' 78 self.fType = 'integer'
79 self.fCppName = name
80 self.fCppType = 'long'
81 self.fCppReader = 'LongFromDictionary'
46 return self 82 return self
47 83
48 def real(self): 84 def real(self, name):
49 self.fType = 'real' 85 self.fType = 'real'
86 self.fCppName = name
87 self.fCppType = 'double'
88 self.fCppReader = 'DoubleFromDictionary'
50 return self 89 return self
51 90
52 def name(self): 91 def name(self, name):
53 self.fType = 'name' 92 self.fType = 'name'
93 self.fCppName = name
94 self.fCppType = 'std::string'
95 self.fCppReader = 'NameFromDictionary'
54 return self 96 return self
55 97
56 def string(self): 98 def string(self, name):
57 self.fType = 'string' 99 self.fType = 'string'
100 self.fCppName = name
101 self.fCppType = 'std::string'
102 self.fCppReader = 'StringFromDictionary'
58 return self 103 return self
59 104
60 def multiple(self, options): 105 def multiple(self, validOptions):
61 self.fType = 'multiple' 106 self.fValidOptions = validOptions
62 self.fOptions = options
63 return self 107 return self
64 108
65 def done(self): 109 def done(self):
66 return self.fParent 110 return self.fParent
67 111
68 112
69 class PdfClassField: 113 class PdfClassField:
70 def __init__(self, parent, required): 114 def __init__(self, parent, required):
71 self.fFields = [] 115 #self.fProp = ''
72 self.fIncludes = []
73 self.fCC = []
74 self.fParent = parent 116 self.fParent = parent
75 self.fRequired = required 117 self.fRequired = required
76 118
77 def hasField(self, name, abr=''): 119 def field(self, name, abr=''):
78 return PdfField(self, name, abr) 120 self.fProp = PdfField(self, name, abr)
121 return self.fProp
79 122
80 def done(self): 123 def done(self):
81 return self.fParent 124 return self.fParent
82 125
83 class PdfClass: 126 class PdfClass:
84 def __init__(self, name, base): 127 def __init__(self, name, base):
85 self.fFields = [] 128 self.fFields = []
86 self.fIncludes = [] 129 self.fIncludes = []
87 self.fCC = [] 130 self.fCCPublic = []
131 self.fCCPrivate = []
88 self.fName = name 132 self.fName = name
89 self.fBase = base 133 self.fBase = base
90 134
91 self.fEnumSubclasses = [] 135 self.fEnumSubclasses = []
92 136
93 self.fEnum = '!UNDEFINED' 137 self.fEnum = '!UNDEFINED'
94 self.fEnumEnd = '!UNDEFINED' 138 self.fEnumEnd = '!UNDEFINED'
95 139
96 def required(self): 140 def required(self, badDefault):
97 field = PdfClassField(self, True) 141 field = PdfClassField(self, True)
142 field.fBadDefault = badDefault
98 self.fFields.append(field) 143 self.fFields.append(field)
99 return field 144 return field
100 145
101 def optional(self): 146 def optional(self):
102 field = PdfClassField(self, False) 147 field = PdfClassField(self, False)
103 self.fFields.append(field) 148 self.fFields.append(field)
104 return field 149 return field
105 150
106 def include(self, path): 151 def include(self, path):
107 self.fIncludes.append(path) 152 self.fIncludes.append(path)
108 return self 153 return self
109 154
110 def carbonCopy(self, cc): 155 def carbonCopyPublic(self, cc):
111 self.fCC.append(cc) 156 self.fCCPublic.append(cc)
157 return self
158
159 def carbonCopyPrivate(self, cc):
160 self.fCCPrivate.append(cc)
112 return self 161 return self
113 162
114 class PdfClassManager: 163 class PdfClassManager:
115 def __init__(self): 164 def __init__(self):
116 self.fClasses = {} 165 self.fClasses = {}
166 self.fClassesNamesInOrder = []
117 167
118 def addClass(self, name, base=''): 168 def addClass(self, name, base='Object'):
119 cls = PdfClass(name, base) 169 if name == 'Object':
170 cls = PdfClass(name, '')
171 else:
172 cls = PdfClass(name, base)
120 self.fClasses[name] = cls 173 self.fClasses[name] = cls
174 self.fClassesNamesInOrder.append(name)
121 return cls 175 return cls
122 176
123 def longName(self, name): 177 def longName(self, name):
124 ret = '' 178 ret = ''
125 while name != '': 179 while name != '':
126 cls = self.fClasses[name] 180 cls = self.fClasses[name]
127 ret = name + ret 181 ret = name + ret
128 name = cls.fBase 182 name = cls.fBase
129 183
130 return ret 184 return ret
131 185
132 186
133 def writeEnum(self, enum, enumToCls): 187 def writeEnum(self, enum, enumToCls):
134 print(' ' + enum + ',') 188 print(' ' + enum + ',')
135 cls = enumToCls[enum] 189 cls = enumToCls[enum]
136 cls.fEnumSubclasses.sort() 190 cls.fEnumSubclasses.sort()
137 191
138 cnt = 0 192 cnt = 0
139 for sub in cls.fEnumSubclasses: 193 for sub in cls.fEnumSubclasses:
140 self.writeEnum(cls.fEnumSubclasses[cnt], enumToCls) 194 self.writeEnum(cls.fEnumSubclasses[cnt], enumToCls)
141 cnt = cnt + 1 195 cnt = cnt + 1
142 196
143 if cnt != 0: 197 if cnt != 0:
144 print(' ' + cls.fEnumEnd + ',') 198 print(' ' + cls.fEnumEnd + ',')
199
200
201 def writeAsNull(self, cls, enumToCls):
202 print(' virtual SkPdf' + cls.fName +'* as' + cls.fName + '() {return NULL;} ')
203 print(' virtual const SkPdf' + cls.fName +'* as' + cls.fName + '() const {r eturn NULL;}')
204 print
205
206 cnt = 0
207 for sub in cls.fEnumSubclasses:
208 self.writeAsNull(enumToCls[cls.fEnumSubclasses[cnt]], enumToCls)
209 cnt = cnt + 1
210
211
212 def writeAsFoo(self, cls, enumToCls):
213 # TODO(edisonn): add a container, with sections, public, private, default, . ..
214 # the end code will be grouped
215
216 # me
217 print('public:')
218 print(' virtual SkPdf' + cls.fName +'* as' + cls.fName + '() {return this;} ')
219 print(' virtual const SkPdf' + cls.fName +'* as' + cls.fName + '() const {r eturn this;}')
220 print
221
222 if cls.fName == 'Object':
223 cnt = 0
224 for sub in cls.fEnumSubclasses:
225 self.writeAsNull(enumToCls[cls.fEnumSubclasses[cnt]], enumToCls)
226 cnt = cnt + 1
227
228 if cls.fName != 'Object':
229 print('private:')
230 base = self.fClasses[cls.fBase]
231 cnt = 0
232 for sub in base.fEnumSubclasses:
233 if enumToCls[base.fEnumSubclasses[cnt]].fName != cls.fName:
234 self.writeAsNull(enumToCls[base.fEnumSubclasses[cnt]], enumToCls)
235 cnt = cnt + 1
236
237
145 238
146 def write(self): 239 def write(self):
147 # generate enum 240 # generate enum
148 enumsRoot = [] 241 enumsRoot = []
149 242
150 enumToCls = {} 243 enumToCls = {}
151 244
152 for name in self.fClasses: 245 for name in self.fClasses:
153 cls = self.fClasses[name] 246 cls = self.fClasses[name]
154 enum = self.longName(name) 247 enum = self.longName(name)
155 cls.fEnum = 'k' + enum + '_PdfObjectType' 248 cls.fEnum = 'k' + enum + '_SkPdfObjectType'
156 cls.fEnumEnd = 'k' + enum + '__End_PdfObjectType' 249 cls.fEnumEnd = 'k' + enum + '__End_SkPdfObjectType'
157 250
158 if cls.fBase != '': 251 if cls.fBase != '':
159 self.fClasses[cls.fBase].fEnumSubclasses.append(cls.fEnum) 252 self.fClasses[cls.fBase].fEnumSubclasses.append(cls.fEnum)
160 253
161 if cls.fBase == '': 254 if cls.fBase == '':
162 enumsRoot.append(cls.fEnum) 255 enumsRoot.append(cls.fEnum)
163 256
164 enumToCls[cls.fEnum] = cls 257 enumToCls[cls.fEnum] = cls
165 258
166 enumsRoot.sort() 259 enumsRoot.sort()
167 260
261
262 # TODO(edisonn): move each .h in it's own file
263 # write imports
264
168 # write enums 265 # write enums
169 print('enum PdfObjectType {') 266 print('enum SkPdfObjectType {')
170 for enum in enumsRoot: 267 for enum in enumsRoot:
171 self.writeEnum(enum, enumToCls) 268 self.writeEnum(enum, enumToCls)
172 print('};') 269 print('};')
270 print
271
272 # write forward class declaration
273 for name in self.fClassesNamesInOrder:
274 print('class SkPdf' + name + ';')
275 print
276
277 for name in self.fClassesNamesInOrder:
278 cls = self.fClasses[name]
279 enum = cls.fEnum
173 280
174 # generate each class 281 if cls.fBase == '':
282 print('class SkPdf' + cls.fName + ' {')
283 else:
284 print('class SkPdf' + cls.fName + ' : public SkPdf' + cls.fBase + ' {')
285
286 print('public:')
287 print(' virtual SkPdfObjectType getType() const { return ' + cls.fEnum + ';}')
288 if len(cls.fEnumSubclasses) == 0:
289 print(' virtual SkPdfObjectType getTypeEnd() const { return (SkPdfObjec tType)(' + cls.fEnum + ' + 1);}')
290 else:
291 print(' virtual SkPdfObjectType getTypeEnd() const { return ' + cls.fEn umEnd + ';}')
292
293
294 self.writeAsFoo(cls, enumToCls)
295
296 print('public:')
297 for cc in cls.fCCPublic:
298 print(' ' + cc)
299
300 print('private:')
301 for cc in cls.fCCPrivate:
302 print(' ' + cc)
303
304 if cls.fBase == '':
305 print('protected:')
306 print(' const PdfMemDocument* fPodofoDoc;')
307 print(' const PdfObject* fPodofoObj;')
308 print
309 print('public:')
310 print(' SkPdf' + cls.fName + '(const PdfMemDocument* podofoDoc, const P dfObject* podofoObj) : fPodofoDoc(podofoDoc), fPodofoObj(podofoObj) {}')
311 print(' const PdfObject* podofo() const { return fPodofoObj;}')
312 else:
313 print('public:')
314 print(' SkPdf' + cls.fName + '(const PdfMemDocument* podofoDoc, const Pd fObject* podofoObj) : SkPdf' + cls.fBase + '(podofoDoc, podofoObj) {}')
315
316 #check required fieds, also, there should be an internal_valid() manually wrote for complex
317 # situations
318 # right now valid return true
319 print(' virtual bool valid() const {return true;}')
320
321 for field in cls.fFields:
322 prop = field.fProp
323 if prop.fCppName != '':
324 print(' ' + prop.fCppType + ' ' + prop.fCppName + '() const {')
325 print(' ' + prop.fCppType + ' ret;')
326 print(' if (' + prop.fCppReader + '(fPodofoDoc, fPodofoObj->GetDi ctionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &ret)) return ret;')
327 if field.fRequired == False:
328 print(' return ' + prop.fDefault.toCpp() + ';');
329 if field.fRequired == True:
330 print(' // TODO(edisonn): warn about missing required field, as sert for known good pdfs')
331 print(' return ' + field.fBadDefault + ';');
332 print(' }')
333 print
334
335 print('};')
336 print
337 print
338
339
340
341 # generate constructor when knowing the type
342 # later, p2, generate constructor when not knowing the type - very similar with parsing?
343
175 # generate parser 344 # generate parser
345
346 # TODO(edisonn): fast recognition based on must attributes.
347 print('class PodofoMapper {')
348 print('public:')
349 for name in self.fClassesNamesInOrder:
350 cls = self.fClasses[name]
351
352 print(' static bool map' + name + '(const PdfMemDocument& podofoDoc, cons t PdfObject& podofoObj, SkPdfObject** out) {')
353 print(' if (!isA' + name + '(podofoDoc, podofoObj)) return false;')
354 print
355
356 for sub in cls.fEnumSubclasses:
357 print(' if (map' + enumToCls[sub].fName + '(podofoDoc, podofoObj, out )) return true;')
358
359 print
360
361 print(' *out = new SkPdf' + name + '(&podofoDoc, &podofoObj);')
362 print(' return true;')
363 print(' }')
364 print
365
366 for name in self.fClassesNamesInOrder:
367 cls = self.fClasses[name]
368
369 print(' static bool isA' + name + '(const PdfMemDocument& podofoDoc, cons t PdfObject& podofoObj) {')
370
371 cntMust = 0
372 for field in cls.fFields:
373 prop = field.fProp
374 if prop.fHasMust:
375 cntMust = cntMust + 1
376 print(' ' + prop.fCppType + ' ' + prop.fCppName + ';')
377 print(' if (!' + prop.fCppReader + '(&podofoDoc, podofoObj.GetDicti onary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &' + prop.fCppName + ')) return false;')
378 print(' if (' + prop.fCppName + ' != ' + prop.fMustBe.toCpp() + ') return false;')
379 print
380
381 # hack, we only care about dictionaries now, so ret tru only if there is a match
382 if cntMust != 0 or name == 'Object' or name == 'Dictionary':
383 print(' return true;')
384 else:
385 print(' return false;')
386
387 print(' }')
388 print
389
390 print('};')
391 print
392
176 return 393 return
177 394
178 def generateCode(): 395 def generateCode():
179 all = PdfClassManager() 396 all = PdfClassManager()
180 397
181 all.addClass('Object') 398 all.addClass('Object')
182 all.addClass('Null') 399 all.addClass('Null')
183 all.addClass('Boolean') 400 all.addClass('Boolean')
184 all.addClass('Integer') 401 all.addClass('Integer')
185 all.addClass('Real') 402 all.addClass('Real')
186 all.addClass('Name') 403 all.addClass('Name')
187 all.addClass('Stream') 404 all.addClass('Stream')
188 all.addClass('Reference') 405 all.addClass('Reference')
189 all.addClass('Array') 406 all.addClass('Array')
190 all.addClass('Dictionary') 407 all.addClass('Dictionary')
191 408
192 all.addClass('XObject', 'Dictionary').required().hasField('/Type').must('/XObj ect') 409 all.addClass('XObject', 'Dictionary').required('""').field('Type').must(PdfNam e('XObject')).name('t')
193 410
194 all.addClass('Image', 'XObject').required().hasField('/Type').must('/XObject') .done()\ 411 all.addClass('Image', 'XObject').required('""').field('Type').must(PdfName('XO bject')).name('t').done()\
195 .required().hasField('/Subtype').must('/Image' ).done()\ 412 .done()\
196 .required().hasField('/Width', '/W').integer() .done().done()\ 413 .required('""').field('Subtype').must(PdfName( 'Image')).name('s').done()\
197 .required().hasField('/Height', '/H').integer( ).done().done()\ 414 .done()\
198 .required().hasField('/ColorSpace').multiple([ PdfName('/DeviceRGB', '/RGB'), PdfName('/DeviceGray', '/Gray')])\ 415 .required('-1').field('Width', 'W').integer('w ').done()\
416 .done()\
417 .required('-1').field('Height', 'H').integer(' h').done()\
418 .done()\
419 .required('""').field('ColorSpace').name('cs') .multiple([PdfName('/DeviceRGB', '/RGB'), PdfName('/DeviceGray', '/Gray')]).done ()\
420 .done()\
421 .optional().field('BitsPerComponent', 'BPC').i nteger('bpc').multiple([PdfInteger(1), PdfInteger(2), PdfInteger(4), PdfInteger( 8)])\
422 .default(PdfInteger(1)).done()\
199 .done()\ 423 .done()\
200 .done()\ 424 .carbonCopyPrivate('SkBitmap bitmap;')
201 .optional().hasField('/BitsPerComponent', '/BP C').multiple([PdfInteger(1), PdfInteger(2), PdfInteger(4), PdfInteger(8)])\
202 .default(PdfInteger(1))\
203 .done().done()\
204 .carbonCopy('SkBitmap bitmap;')
205 425
206 all.addClass('Form', 'XObject').required().hasField('/Type').must('/XObject'). done()\ 426 all.addClass('Form', 'XObject').required('""').field('Type').must(PdfName('XOb ject')).name('t').done()\
207 .required().hasField('/Subtype').must('/Form'). done() 427 .done()\
428 .required('""').field('Subtype').must(PdfName(' Form')).name('s').done()\
429 .done()\
430 .carbonCopyPublic('void test() {}')
208 431
209 432
210 all.write() 433 all.write()
211 434
212 return 1 435 return 1
213 436
214 if '__main__' == __name__: 437 if '__main__' == __name__:
215 sys.exit(generateCode()) 438 sys.exit(generateCode())
OLDNEW
« no previous file with comments | « no previous file | experimental/PdfViewer/pdf_auto_gen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698