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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | experimental/PdfViewer/pdf_auto_gen.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: experimental/PdfViewer/generate_code.py
===================================================================
--- experimental/PdfViewer/generate_code.py (revision 9521)
+++ experimental/PdfViewer/generate_code.py (working copy)
@@ -4,23 +4,45 @@
def __init__(self, name, abr=''):
self.fName = name
self.fAbr = abr
+
+ def toCpp(self):
+ return '\"' + self.fName + '\"'
+class PdfString:
+ def __init__(self, value):
+ self.fValue = value
+
+ def toCpp(self):
+ return '\"' + self.fValue + '\"'
+
class PdfInteger:
def __init__(self, value):
self.fValue = value
+ def toCpp(self):
+ return str(self.fValue)
+
class PdfReal:
def __init__(self, value):
self.fValue = value
+ def toCpp(self):
+ return str(self.fValue)
+
class PdfString:
def __init__(self, value):
self.fValue = value
+ def toCpp(self):
+ return self.fValue
+
class PdfBoolean:
def __init__(self, value):
self.fValue = value
+ def toCpp(self):
+ return self.fValue
+
class PdfField:
def __init__(self, parent, name, abr):
self.fParent = parent
@@ -29,37 +51,59 @@
self.fDefault = ''
self.fType = ''
+ self.fCppName = ''
+ self.fCppType = ''
+ self.fCppReader = ''
+ self.fValidOptions = []
+ self.fHasMust = False
+ self.fMustBe = ''
def must(self, value):
- return self.fParent
+ self.fHasMust = True
+ self.fMustBe = value
+ return self
def default(self, value):
self.fDefault = value
return self
- def number(self):
+ def number(self, name):
self.fType = 'number'
+ self.fCppName = name
+ self.fCppType = 'double'
+ self.fCppReader = 'DoubleFromDictionary'
return self
- def integer(self):
+ def integer(self, name):
self.fType = 'integer'
+ self.fCppName = name
+ self.fCppType = 'long'
+ self.fCppReader = 'LongFromDictionary'
return self
- def real(self):
+ def real(self, name):
self.fType = 'real'
+ self.fCppName = name
+ self.fCppType = 'double'
+ self.fCppReader = 'DoubleFromDictionary'
return self
- def name(self):
+ def name(self, name):
self.fType = 'name'
+ self.fCppName = name
+ self.fCppType = 'std::string'
+ self.fCppReader = 'NameFromDictionary'
return self
- def string(self):
+ def string(self, name):
self.fType = 'string'
+ self.fCppName = name
+ self.fCppType = 'std::string'
+ self.fCppReader = 'StringFromDictionary'
return self
- def multiple(self, options):
- self.fType = 'multiple'
- self.fOptions = options
+ def multiple(self, validOptions):
+ self.fValidOptions = validOptions
return self
def done(self):
@@ -68,14 +112,13 @@
class PdfClassField:
def __init__(self, parent, required):
- self.fFields = []
- self.fIncludes = []
- self.fCC = []
+ #self.fProp = ''
self.fParent = parent
self.fRequired = required
- def hasField(self, name, abr=''):
- return PdfField(self, name, abr)
+ def field(self, name, abr=''):
+ self.fProp = PdfField(self, name, abr)
+ return self.fProp
def done(self):
return self.fParent
@@ -84,7 +127,8 @@
def __init__(self, name, base):
self.fFields = []
self.fIncludes = []
- self.fCC = []
+ self.fCCPublic = []
+ self.fCCPrivate = []
self.fName = name
self.fBase = base
@@ -93,8 +137,9 @@
self.fEnum = '!UNDEFINED'
self.fEnumEnd = '!UNDEFINED'
- def required(self):
+ def required(self, badDefault):
field = PdfClassField(self, True)
+ field.fBadDefault = badDefault
self.fFields.append(field)
return field
@@ -107,17 +152,26 @@
self.fIncludes.append(path)
return self
- def carbonCopy(self, cc):
- self.fCC.append(cc)
+ def carbonCopyPublic(self, cc):
+ self.fCCPublic.append(cc)
return self
+ def carbonCopyPrivate(self, cc):
+ self.fCCPrivate.append(cc)
+ return self
+
class PdfClassManager:
def __init__(self):
self.fClasses = {}
+ self.fClassesNamesInOrder = []
- def addClass(self, name, base=''):
- cls = PdfClass(name, base)
+ def addClass(self, name, base='Object'):
+ if name == 'Object':
+ cls = PdfClass(name, '')
+ else:
+ cls = PdfClass(name, base)
self.fClasses[name] = cls
+ self.fClassesNamesInOrder.append(name)
return cls
def longName(self, name):
@@ -142,6 +196,45 @@
if cnt != 0:
print(' ' + cls.fEnumEnd + ',')
+
+
+ def writeAsNull(self, cls, enumToCls):
+ print(' virtual SkPdf' + cls.fName +'* as' + cls.fName + '() {return NULL;}')
+ print(' virtual const SkPdf' + cls.fName +'* as' + cls.fName + '() const {return NULL;}')
+ print
+
+ cnt = 0
+ for sub in cls.fEnumSubclasses:
+ self.writeAsNull(enumToCls[cls.fEnumSubclasses[cnt]], enumToCls)
+ cnt = cnt + 1
+
+
+ def writeAsFoo(self, cls, enumToCls):
+ # TODO(edisonn): add a container, with sections, public, private, default, ...
+ # the end code will be grouped
+
+ # me
+ print('public:')
+ print(' virtual SkPdf' + cls.fName +'* as' + cls.fName + '() {return this;}')
+ print(' virtual const SkPdf' + cls.fName +'* as' + cls.fName + '() const {return this;}')
+ print
+
+ if cls.fName == 'Object':
+ cnt = 0
+ for sub in cls.fEnumSubclasses:
+ self.writeAsNull(enumToCls[cls.fEnumSubclasses[cnt]], enumToCls)
+ cnt = cnt + 1
+
+ if cls.fName != 'Object':
+ print('private:')
+ base = self.fClasses[cls.fBase]
+ cnt = 0
+ for sub in base.fEnumSubclasses:
+ if enumToCls[base.fEnumSubclasses[cnt]].fName != cls.fName:
+ self.writeAsNull(enumToCls[base.fEnumSubclasses[cnt]], enumToCls)
+ cnt = cnt + 1
+
+
def write(self):
# generate enum
@@ -152,8 +245,8 @@
for name in self.fClasses:
cls = self.fClasses[name]
enum = self.longName(name)
- cls.fEnum = 'k' + enum + '_PdfObjectType'
- cls.fEnumEnd = 'k' + enum + '__End_PdfObjectType'
+ cls.fEnum = 'k' + enum + '_SkPdfObjectType'
+ cls.fEnumEnd = 'k' + enum + '__End_SkPdfObjectType'
if cls.fBase != '':
self.fClasses[cls.fBase].fEnumSubclasses.append(cls.fEnum)
@@ -165,14 +258,138 @@
enumsRoot.sort()
+
+ # TODO(edisonn): move each .h in it's own file
+ # write imports
+
# write enums
- print('enum PdfObjectType {')
+ print('enum SkPdfObjectType {')
for enum in enumsRoot:
self.writeEnum(enum, enumToCls)
print('};')
+ print
+
+ # write forward class declaration
+ for name in self.fClassesNamesInOrder:
+ print('class SkPdf' + name + ';')
+ print
+
+ for name in self.fClassesNamesInOrder:
+ cls = self.fClasses[name]
+ enum = cls.fEnum
- # generate each class
+ if cls.fBase == '':
+ print('class SkPdf' + cls.fName + ' {')
+ else:
+ print('class SkPdf' + cls.fName + ' : public SkPdf' + cls.fBase + ' {')
+
+ print('public:')
+ print(' virtual SkPdfObjectType getType() const { return ' + cls.fEnum + ';}')
+ if len(cls.fEnumSubclasses) == 0:
+ print(' virtual SkPdfObjectType getTypeEnd() const { return (SkPdfObjectType)(' + cls.fEnum + ' + 1);}')
+ else:
+ print(' virtual SkPdfObjectType getTypeEnd() const { return ' + cls.fEnumEnd + ';}')
+
+
+ self.writeAsFoo(cls, enumToCls)
+
+ print('public:')
+ for cc in cls.fCCPublic:
+ print(' ' + cc)
+
+ print('private:')
+ for cc in cls.fCCPrivate:
+ print(' ' + cc)
+
+ if cls.fBase == '':
+ print('protected:')
+ print(' const PdfMemDocument* fPodofoDoc;')
+ print(' const PdfObject* fPodofoObj;')
+ print
+ print('public:')
+ print(' SkPdf' + cls.fName + '(const PdfMemDocument* podofoDoc, const PdfObject* podofoObj) : fPodofoDoc(podofoDoc), fPodofoObj(podofoObj) {}')
+ print(' const PdfObject* podofo() const { return fPodofoObj;}')
+ else:
+ print('public:')
+ print(' SkPdf' + cls.fName + '(const PdfMemDocument* podofoDoc, const PdfObject* podofoObj) : SkPdf' + cls.fBase + '(podofoDoc, podofoObj) {}')
+
+ #check required fieds, also, there should be an internal_valid() manually wrote for complex
+ # situations
+ # right now valid return true
+ print(' virtual bool valid() const {return true;}')
+
+ for field in cls.fFields:
+ prop = field.fProp
+ if prop.fCppName != '':
+ print(' ' + prop.fCppType + ' ' + prop.fCppName + '() const {')
+ print(' ' + prop.fCppType + ' ret;')
+ print(' if (' + prop.fCppReader + '(fPodofoDoc, fPodofoObj->GetDictionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &ret)) return ret;')
+ if field.fRequired == False:
+ print(' return ' + prop.fDefault.toCpp() + ';');
+ if field.fRequired == True:
+ print(' // TODO(edisonn): warn about missing required field, assert for known good pdfs')
+ print(' return ' + field.fBadDefault + ';');
+ print(' }')
+ print
+
+ print('};')
+ print
+ print
+
+
+
+ # generate constructor when knowing the type
+ # later, p2, generate constructor when not knowing the type - very similar with parsing?
+
# generate parser
+
+ # TODO(edisonn): fast recognition based on must attributes.
+ print('class PodofoMapper {')
+ print('public:')
+ for name in self.fClassesNamesInOrder:
+ cls = self.fClasses[name]
+
+ print(' static bool map' + name + '(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj, SkPdfObject** out) {')
+ print(' if (!isA' + name + '(podofoDoc, podofoObj)) return false;')
+ print
+
+ for sub in cls.fEnumSubclasses:
+ print(' if (map' + enumToCls[sub].fName + '(podofoDoc, podofoObj, out)) return true;')
+
+ print
+
+ print(' *out = new SkPdf' + name + '(&podofoDoc, &podofoObj);')
+ print(' return true;')
+ print(' }')
+ print
+
+ for name in self.fClassesNamesInOrder:
+ cls = self.fClasses[name]
+
+ print(' static bool isA' + name + '(const PdfMemDocument& podofoDoc, const PdfObject& podofoObj) {')
+
+ cntMust = 0
+ for field in cls.fFields:
+ prop = field.fProp
+ if prop.fHasMust:
+ cntMust = cntMust + 1
+ print(' ' + prop.fCppType + ' ' + prop.fCppName + ';')
+ print(' if (!' + prop.fCppReader + '(&podofoDoc, podofoObj.GetDictionary(), \"' + prop.fName + '\", \"' + prop.fAbr + '\", &' + prop.fCppName + ')) return false;')
+ print(' if (' + prop.fCppName + ' != ' + prop.fMustBe.toCpp() + ') return false;')
+ print
+
+ # hack, we only care about dictionaries now, so ret tru only if there is a match
+ if cntMust != 0 or name == 'Object' or name == 'Dictionary':
+ print(' return true;')
+ else:
+ print(' return false;')
+
+ print(' }')
+ print
+
+ print('};')
+ print
+
return
def generateCode():
@@ -189,22 +406,28 @@
all.addClass('Array')
all.addClass('Dictionary')
- all.addClass('XObject', 'Dictionary').required().hasField('/Type').must('/XObject')
+ all.addClass('XObject', 'Dictionary').required('""').field('Type').must(PdfName('XObject')).name('t')
- all.addClass('Image', 'XObject').required().hasField('/Type').must('/XObject').done()\
- .required().hasField('/Subtype').must('/Image').done()\
- .required().hasField('/Width', '/W').integer().done().done()\
- .required().hasField('/Height', '/H').integer().done().done()\
- .required().hasField('/ColorSpace').multiple([PdfName('/DeviceRGB', '/RGB'), PdfName('/DeviceGray', '/Gray')])\
+ all.addClass('Image', 'XObject').required('""').field('Type').must(PdfName('XObject')).name('t').done()\
+ .done()\
+ .required('""').field('Subtype').must(PdfName('Image')).name('s').done()\
+ .done()\
+ .required('-1').field('Width', 'W').integer('w').done()\
+ .done()\
+ .required('-1').field('Height', 'H').integer('h').done()\
+ .done()\
+ .required('""').field('ColorSpace').name('cs').multiple([PdfName('/DeviceRGB', '/RGB'), PdfName('/DeviceGray', '/Gray')]).done()\
+ .done()\
+ .optional().field('BitsPerComponent', 'BPC').integer('bpc').multiple([PdfInteger(1), PdfInteger(2), PdfInteger(4), PdfInteger(8)])\
+ .default(PdfInteger(1)).done()\
.done()\
- .done()\
- .optional().hasField('/BitsPerComponent', '/BPC').multiple([PdfInteger(1), PdfInteger(2), PdfInteger(4), PdfInteger(8)])\
- .default(PdfInteger(1))\
- .done().done()\
- .carbonCopy('SkBitmap bitmap;')
+ .carbonCopyPrivate('SkBitmap bitmap;')
- all.addClass('Form', 'XObject').required().hasField('/Type').must('/XObject').done()\
- .required().hasField('/Subtype').must('/Form').done()
+ all.addClass('Form', 'XObject').required('""').field('Type').must(PdfName('XObject')).name('t').done()\
+ .done()\
+ .required('""').field('Subtype').must(PdfName('Form')).name('s').done()\
+ .done()\
+ .carbonCopyPublic('void test() {}')
all.write()
« 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