swfmill 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. data/.document +5 -0
  2. data/.gitignore +23 -0
  3. data/.swfmill +240 -0
  4. data/LICENSE +340 -0
  5. data/README.rdoc +37 -0
  6. data/Rakefile +59 -0
  7. data/VERSION +1 -0
  8. data/ext/.gitignore +5 -0
  9. data/ext/extconf.rb +86 -0
  10. data/ext/swfmill/.gitignore +27 -0
  11. data/ext/swfmill/AUTHORS +9 -0
  12. data/ext/swfmill/COPYING +340 -0
  13. data/ext/swfmill/Makefile.am +14 -0
  14. data/ext/swfmill/Makefile.in +635 -0
  15. data/ext/swfmill/NEWS +189 -0
  16. data/ext/swfmill/README +170 -0
  17. data/ext/swfmill/TODO +33 -0
  18. data/ext/swfmill/aclocal.m4 +7712 -0
  19. data/ext/swfmill/autogen.sh +7 -0
  20. data/ext/swfmill/compile +142 -0
  21. data/ext/swfmill/config.guess +1516 -0
  22. data/ext/swfmill/config.sub +1626 -0
  23. data/ext/swfmill/configure +21868 -0
  24. data/ext/swfmill/configure.ac +55 -0
  25. data/ext/swfmill/depcomp +589 -0
  26. data/ext/swfmill/install-sh +519 -0
  27. data/ext/swfmill/ltmain.sh +6964 -0
  28. data/ext/swfmill/missing +367 -0
  29. data/ext/swfmill/src/Geom.cpp +107 -0
  30. data/ext/swfmill/src/Geom.h +100 -0
  31. data/ext/swfmill/src/Makefile.am +86 -0
  32. data/ext/swfmill/src/Makefile.in +1025 -0
  33. data/ext/swfmill/src/SWF.h +11941 -0
  34. data/ext/swfmill/src/SWFAction.cpp +41 -0
  35. data/ext/swfmill/src/SWFAction.h +19 -0
  36. data/ext/swfmill/src/SWFBasic.h +7 -0
  37. data/ext/swfmill/src/SWFFile.cpp +406 -0
  38. data/ext/swfmill/src/SWFFile.h +34 -0
  39. data/ext/swfmill/src/SWFFilter.cpp +25 -0
  40. data/ext/swfmill/src/SWFFilter.h +15 -0
  41. data/ext/swfmill/src/SWFGlyphList.cpp +262 -0
  42. data/ext/swfmill/src/SWFGlyphList.h +34 -0
  43. data/ext/swfmill/src/SWFIdItem.h +85 -0
  44. data/ext/swfmill/src/SWFIdItems.h +16 -0
  45. data/ext/swfmill/src/SWFItem.cpp +235 -0
  46. data/ext/swfmill/src/SWFItem.h +60 -0
  47. data/ext/swfmill/src/SWFList.h +179 -0
  48. data/ext/swfmill/src/SWFReader.cpp +352 -0
  49. data/ext/swfmill/src/SWFReader.h +73 -0
  50. data/ext/swfmill/src/SWFShapeItem.cpp +220 -0
  51. data/ext/swfmill/src/SWFShapeItem.h +45 -0
  52. data/ext/swfmill/src/SWFShapeMaker.cpp +401 -0
  53. data/ext/swfmill/src/SWFShapeMaker.h +128 -0
  54. data/ext/swfmill/src/SWFTag.cpp +49 -0
  55. data/ext/swfmill/src/SWFTag.h +20 -0
  56. data/ext/swfmill/src/SWFTrait.cpp +35 -0
  57. data/ext/swfmill/src/SWFTrait.h +22 -0
  58. data/ext/swfmill/src/SWFWriter.cpp +312 -0
  59. data/ext/swfmill/src/SWFWriter.h +84 -0
  60. data/ext/swfmill/src/base64.c +110 -0
  61. data/ext/swfmill/src/base64.h +15 -0
  62. data/ext/swfmill/src/codegen/Makefile.am +15 -0
  63. data/ext/swfmill/src/codegen/Makefile.in +346 -0
  64. data/ext/swfmill/src/codegen/basic.xsl +45 -0
  65. data/ext/swfmill/src/codegen/basics.xsl +235 -0
  66. data/ext/swfmill/src/codegen/dumper.xsl +109 -0
  67. data/ext/swfmill/src/codegen/header.xsl +131 -0
  68. data/ext/swfmill/src/codegen/mk.xsl +26 -0
  69. data/ext/swfmill/src/codegen/parser.xsl +196 -0
  70. data/ext/swfmill/src/codegen/parsexml.xsl +312 -0
  71. data/ext/swfmill/src/codegen/size.xsl +189 -0
  72. data/ext/swfmill/src/codegen/source.xml +2197 -0
  73. data/ext/swfmill/src/codegen/writer.xsl +190 -0
  74. data/ext/swfmill/src/codegen/writexml.xsl +138 -0
  75. data/ext/swfmill/src/swfmill.cpp +482 -0
  76. data/ext/swfmill/src/swft/Makefile.am +55 -0
  77. data/ext/swfmill/src/swft/Makefile.in +717 -0
  78. data/ext/swfmill/src/swft/Parser.cpp +76 -0
  79. data/ext/swfmill/src/swft/Parser.h +37 -0
  80. data/ext/swfmill/src/swft/SVGAttributeParser.cpp +78 -0
  81. data/ext/swfmill/src/swft/SVGAttributeParser.h +35 -0
  82. data/ext/swfmill/src/swft/SVGColor.cpp +116 -0
  83. data/ext/swfmill/src/swft/SVGColor.h +37 -0
  84. data/ext/swfmill/src/swft/SVGColors.h +167 -0
  85. data/ext/swfmill/src/swft/SVGGradient.cpp +258 -0
  86. data/ext/swfmill/src/swft/SVGGradient.h +81 -0
  87. data/ext/swfmill/src/swft/SVGPathParser.cpp +155 -0
  88. data/ext/swfmill/src/swft/SVGPathParser.h +126 -0
  89. data/ext/swfmill/src/swft/SVGPointsParser.cpp +51 -0
  90. data/ext/swfmill/src/swft/SVGPointsParser.h +25 -0
  91. data/ext/swfmill/src/swft/SVGStyle.cpp +181 -0
  92. data/ext/swfmill/src/swft/SVGStyle.h +80 -0
  93. data/ext/swfmill/src/swft/SVGTransformParser.cpp +72 -0
  94. data/ext/swfmill/src/swft/SVGTransformParser.h +32 -0
  95. data/ext/swfmill/src/swft/readpng.c +305 -0
  96. data/ext/swfmill/src/swft/readpng.h +92 -0
  97. data/ext/swfmill/src/swft/swft.cpp +251 -0
  98. data/ext/swfmill/src/swft/swft.h +64 -0
  99. data/ext/swfmill/src/swft/swft_document.cpp +57 -0
  100. data/ext/swfmill/src/swft/swft_import.cpp +38 -0
  101. data/ext/swfmill/src/swft/swft_import_binary.cpp +82 -0
  102. data/ext/swfmill/src/swft/swft_import_jpeg.cpp +255 -0
  103. data/ext/swfmill/src/swft/swft_import_mp3.cpp +268 -0
  104. data/ext/swfmill/src/swft/swft_import_png.cpp +231 -0
  105. data/ext/swfmill/src/swft/swft_import_ttf.cpp +519 -0
  106. data/ext/swfmill/src/swft/swft_import_wav.cpp +255 -0
  107. data/ext/swfmill/src/swft/swft_path.cpp +178 -0
  108. data/ext/swfmill/src/xslt/Makefile.am +51 -0
  109. data/ext/swfmill/src/xslt/Makefile.in +536 -0
  110. data/ext/swfmill/src/xslt/README +19 -0
  111. data/ext/swfmill/src/xslt/assemble.xsl +38 -0
  112. data/ext/swfmill/src/xslt/simple-deprecated.xslt +62 -0
  113. data/ext/swfmill/src/xslt/simple-elements.xslt +627 -0
  114. data/ext/swfmill/src/xslt/simple-import.xslt +565 -0
  115. data/ext/swfmill/src/xslt/simple-svg.xslt +383 -0
  116. data/ext/swfmill/src/xslt/simple-tools.xslt +255 -0
  117. data/ext/swfmill/src/xslt/simple.cpp +1686 -0
  118. data/ext/swfmill/src/xslt/simple.xml +7 -0
  119. data/ext/swfmill/src/xslt/xslt.h +7 -0
  120. data/ext/swfmill/test/Makefile.am +1 -0
  121. data/ext/swfmill/test/Makefile.in +490 -0
  122. data/ext/swfmill/test/xml/Makefile.am +20 -0
  123. data/ext/swfmill/test/xml/Makefile.in +353 -0
  124. data/ext/swfmill/test/xml/test-xml +21 -0
  125. data/ext/swfmill_ext.cc +375 -0
  126. data/lib/swfmill.rb +30 -0
  127. data/spec/data/swfmill-banner1.swf +0 -0
  128. data/spec/spec.opts +1 -0
  129. data/spec/spec_helper.rb +14 -0
  130. data/spec/swfmill_spec.rb +125 -0
  131. metadata +206 -0
@@ -0,0 +1,34 @@
1
+ #ifndef SWF_FILE_H
2
+ #define SWF_FILE_H
3
+
4
+ #include "SWF.h"
5
+
6
+ namespace SWF {
7
+
8
+ class File {
9
+ public:
10
+ File();
11
+ ~File();
12
+ int load( FILE *fp, Context *ctx = NULL, unsigned int filesize=0 );
13
+ int save( FILE *fp, Context *ctx = NULL );
14
+ void dump();
15
+ int saveXML( FILE *fp, Context *ctx = NULL );
16
+ int loadXML( const char *filename, Context *ctx = NULL );
17
+
18
+ xmlDocPtr getXML( Context *ctx = NULL );
19
+ int setXML( xmlNodePtr root, Context *ctx = NULL );
20
+
21
+ protected:
22
+ void compress( unsigned char *data, size_t len, FILE *fp );
23
+ void decompress( unsigned char *data, size_t len, FILE *fp );
24
+
25
+ Header *header;
26
+
27
+ bool compressed;
28
+ unsigned char version;
29
+ uint32_t length;
30
+ };
31
+
32
+
33
+ }
34
+ #endif
@@ -0,0 +1,25 @@
1
+ #include <SWFFilter.h>
2
+ #include "SWF.h"
3
+
4
+ namespace SWF {
5
+
6
+ Filter *Filter::get( Reader *r, int end, Context *ctx ) {
7
+ int type = r->getByte();
8
+ int len = end - r->getPosition();
9
+
10
+ Filter* ret = getByType( type );
11
+
12
+ if( !ret ) {
13
+ Filter* ret = new UnknownFilter();
14
+ }
15
+
16
+ if( ret ) {
17
+ ret->setType( type );
18
+ ret->setLength( len );
19
+ ret->parse( r, end, ctx );
20
+ }
21
+
22
+ return ret;
23
+ }
24
+
25
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef SWF_FILTER_H
2
+ #define SWF_FILTER_H
3
+
4
+ #include <SWFIdItem.h>
5
+
6
+ namespace SWF {
7
+
8
+ class Filter : public IdItem<Filter> {
9
+ // static stuff
10
+ public:
11
+ static Filter* get( Reader *r, int end, Context *ctx );
12
+ };
13
+
14
+ }
15
+ #endif
@@ -0,0 +1,262 @@
1
+ #include "SWFGlyphList.h"
2
+ #include <SWFShapeItem.h>
3
+ #include "SWF.h"
4
+ #include <cstring>
5
+
6
+ namespace SWF {
7
+
8
+ GlyphList::GlyphList() {
9
+ nGlyphs = 0;
10
+ glyphs = NULL;
11
+ map = 0;
12
+ }
13
+
14
+ GlyphList::~GlyphList() {
15
+ delete[] glyphs;
16
+ delete[] map;
17
+ }
18
+
19
+ bool GlyphList::parse( Reader *r, int end, Context *ctx ) {
20
+ file_offset = r->getPosition();
21
+
22
+ int nOffsets;
23
+ int s=0;
24
+
25
+ if( ctx->tagVersion>1 ) {
26
+ nGlyphs = ctx->glyphCount;
27
+ nOffsets = nGlyphs+1;
28
+ } else {
29
+ nGlyphs = (r->getWord()/2);
30
+ nOffsets = nGlyphs;
31
+ s=1;
32
+ }
33
+
34
+ if( ctx->debugTrace ) fprintf(stderr, "GL nGlyphs: %i, glyphs %s, map %s\n", (int)nGlyphs, ctx->wideGlyphOffsets?"wide":"narrow", ctx->wideMap?"wide":"narrow" );
35
+
36
+ int offset[ nGlyphs+1 ];
37
+ memset( offset, 0, sizeof(int)*nGlyphs+1 );
38
+ if( ctx->wideGlyphOffsets ) {
39
+ for( int i=s; i<nOffsets; i++ ) {
40
+ offset[i] = r->getInt();
41
+ }
42
+ } else {
43
+ for( int i=s; i<nOffsets; i++ ) {
44
+ offset[i] = r->getWord();
45
+ }
46
+ }
47
+
48
+ if( ctx->tagVersion<=1 ) {
49
+ offset[0] = r->getPosition() - file_offset;
50
+ offset[nOffsets] = end-file_offset;
51
+ }
52
+ /*
53
+ int fillBits = r->getNBitInt(4);
54
+ int lineBits = r->getNBitInt(4);
55
+ if( fillBits != 1 || lineBits != 0 ) {
56
+ fprintf(stderr,"WARNING: GlyphList fillBits: %i, lineBits: %i, expected 1/0\n", fillBits, lineBits );
57
+ }
58
+ */
59
+ if( ctx->debugTrace ) fprintf(stderr, "Glyphs @%i offset[0]: %i\n", r->getPosition(), offset[0] );
60
+ glyphs = new GlyphShape[nGlyphs];
61
+ for( int i=0; i<nGlyphs; i++ ) {
62
+ if( ctx->debugTrace ) fprintf(stderr, "PARSE glyph #%i @%i should be %i-%i\n", i, r->getPosition(), file_offset + offset[i], file_offset + offset[i+1] );
63
+ if( r->getPosition() != file_offset + offset[i] ) {
64
+ fprintf(stderr,"WARNING: wrong offset at glyph %i, ofs %i but pos %i\n", i, offset[i], r->getPosition()-file_offset );
65
+ }
66
+ glyphs[i].parse( r, file_offset + offset[i+1], ctx );
67
+ r->byteAlign();
68
+ }
69
+ /* if( ctx->debugTrace ) fprintf(stderr, "PARSE last gylph %i\n", r->getPosition() );
70
+ glyphs[nGlyphs-1].parse( r, end, ctx );
71
+ r->byteAlign();
72
+ */
73
+ if( ctx->tagVersion>1 ) {
74
+ if( ctx->debugTrace ) fprintf(stderr,"- parse GlyphMap" );
75
+ map = new int[ nGlyphs ];
76
+ if( ctx->wideMap ) {
77
+ for( int i=0; i<nGlyphs; i++ ) {
78
+ map[i] = r->getWord();
79
+ }
80
+ } else {
81
+ for( int i=0; i<nGlyphs; i++ ) {
82
+ map[i] = r->getByte();
83
+ }
84
+ }
85
+ }
86
+
87
+ return r->getError() == SWFR_OK;
88
+ }
89
+
90
+ void GlyphList::dump( int n, Context *ctx ) {
91
+ for( int i=0; i<n; i++ ) printf(" ");
92
+ printf("GlyphList\n");
93
+
94
+ for( int i=0; i<nGlyphs; i++ ) {
95
+ glyphs[i].dump( n+1, ctx );
96
+ }
97
+ printf("\n");
98
+ }
99
+
100
+ size_t GlyphList::calcSize( Context *ctx, int start_at ) {
101
+ int r=start_at;
102
+
103
+ if( ctx->tagVersion>1 ) {
104
+ r += ( ctx->wideGlyphOffsets ? 4 : 2 ) * (nGlyphs+1) * 8;
105
+ } else {
106
+ r += (nGlyphs+1) * 16;
107
+ }
108
+ /*
109
+ // fillBits/lineBits
110
+ ctx->fillBits = 1;
111
+ ctx->lineBits = 0;
112
+ r+=8
113
+ */
114
+ for( int i=0; i<nGlyphs; i++ ) {
115
+ r += glyphs[i].getSize( ctx, r );
116
+ if( r%8 != 0 ) r += 8-(r%8);
117
+ }
118
+
119
+ if( ctx->tagVersion>1 ) r += ( ctx->wideMap ? 2 : 1 ) * nGlyphs * 8;
120
+
121
+ /* fprintf(stderr,"SIZE DefineFont-%i, %s map\n",
122
+ ctx->tagVersion, ctx->wideMap ? "wide" : "narrow" );
123
+ fprintf(stderr,"GL size: %i %i %i\n", nGlyphs, r, r/8 );
124
+ */
125
+ r += Item::getHeaderSize(r-start_at);
126
+ return r-start_at;
127
+ }
128
+
129
+ void GlyphList::write( Writer *w, Context *ctx ) {
130
+ Item::writeHeader( w, ctx, 0 );
131
+ int ofs = 0;
132
+
133
+ if( ctx->tagVersion>1 ) {
134
+ ofs = (( ctx->wideGlyphOffsets ? 4 : 2 ) * (nGlyphs+1));
135
+ } else {
136
+ ofs = (nGlyphs+1)*2;
137
+ }
138
+ /*
139
+ // fillBits/lineBits
140
+ ofs++;
141
+ */
142
+ ctx->fillBits = 1;
143
+ ctx->lineBits = 1;
144
+
145
+ ctx->wideGlyphOffsets ? w->putInt( ofs ) : w->putWord( ofs );
146
+ for( int i=0; i<nGlyphs; i++ ) {
147
+ int p = glyphs[i].getSize(ctx,ofs);
148
+ if( p%8 != 0 ) p += 8-(p%8);
149
+ ofs += (p)/8;
150
+ ctx->wideGlyphOffsets ? w->putInt( ofs ) : w->putWord( ofs );
151
+ }
152
+ /*
153
+ // fillBits/lineBits
154
+ w->putNBitInt( 1, 4 );
155
+ w->putNBitInt( 0, 4 );
156
+ */
157
+ ofs = w->getPosition();
158
+ for( int i=0; i<nGlyphs; i++ ) {
159
+ glyphs[i].write( w, ctx );
160
+ w->byteAlign();
161
+ }
162
+
163
+ if( ctx->tagVersion>1 ) {
164
+ for( int i=0; i<nGlyphs; i++ ) {
165
+ ctx->wideMap ? w->putWord( map[i] ) : w->putByte( map[i] );
166
+ }
167
+ }
168
+ }
169
+
170
+ void GlyphList::writeXML( xmlNodePtr xml, Context *ctx ) {
171
+ char tmp[32];
172
+ /*
173
+ xmlNodePtr node = xmlNewChild( xml, NULL, (const xmlChar *)"GlyphList", NULL );
174
+
175
+ for( int i=0; i<nGlyphs; i++ ) {
176
+ glyphs[i].writeXML( node, ctx );
177
+ }
178
+ */
179
+ xmlNodePtr node = xml; //xmlNewChild( xml, NULL, (const xmlChar *)"glyphs", NULL );
180
+ for( int i=0; i<nGlyphs; i++ ) {
181
+ xmlNodePtr child = xmlNewChild( node, NULL, (const xmlChar *)"Glyph", NULL );
182
+ glyphs[i].writeXML( child, ctx );
183
+ if( ctx->tagVersion>1 && map ) {
184
+ snprintf( tmp, 32, "%i", map[i] );
185
+ xmlSetProp( child, (const xmlChar *)"map", (const xmlChar *)tmp );
186
+ }
187
+ }
188
+ }
189
+
190
+ void GlyphList::parseXML( xmlNodePtr node, Context *ctx ) {
191
+ {
192
+ nGlyphs = 0;
193
+ xmlNodePtr child = node;
194
+ while( child ) {
195
+ if( !strcmp( (const char *)child->name, "Glyph" ) ) {
196
+ nGlyphs++;
197
+ }
198
+ child = child->next;
199
+ }
200
+ ctx->glyphCount = nGlyphs;
201
+
202
+ if( ctx->tagVersion>1 ) {
203
+ map = new int[ nGlyphs ];
204
+ memset( map, 0, sizeof(int)*nGlyphs );
205
+ }
206
+
207
+ glyphs = new GlyphShape[ nGlyphs ];
208
+ child = node;
209
+ int i=0;
210
+ while( child ) {
211
+ if( !strcmp( (const char *)child->name, "Glyph" ) ) {
212
+ xmlNodePtr shape = child->children;
213
+ while( shape ) {
214
+ if( !strcmp( (const char *)shape->name, "GlyphShape" ) ) {
215
+ glyphs[i].parseXML( shape, ctx );
216
+
217
+ if( ctx->tagVersion>1 ) {
218
+ xmlChar *tmp;
219
+ tmp = xmlGetProp( child, (const xmlChar *)"map" );
220
+ if( tmp ) {
221
+ sscanf( (char*)tmp, "%i", &map[i]);
222
+ xmlFree( tmp );
223
+ if( map[i] > 0xFF ) ctx->wideMap = true;
224
+ } else {
225
+ map[i] = 0;
226
+ }
227
+ }
228
+
229
+ i++;
230
+ shape = NULL;
231
+ } else {
232
+ shape = shape->next;
233
+ }
234
+ }
235
+ }
236
+ child = child->next;
237
+ }
238
+
239
+ if( ctx->swfVersion >= 6 ) ctx->wideMap = true;
240
+
241
+ }
242
+ }
243
+
244
+ void GlyphList::allocate( int n ) {
245
+ delete[] map;
246
+ delete[] glyphs;
247
+
248
+ nGlyphs = n;
249
+ glyphs = new GlyphShape[ nGlyphs ];
250
+ map = new int[ nGlyphs ];
251
+ memset( map, 0, sizeof(int)*nGlyphs );
252
+ }
253
+
254
+ GlyphShape *GlyphList::getShapeN( int n ) {
255
+ return &glyphs[n];
256
+ }
257
+
258
+ void GlyphList::setMapN( int n, int m ) {
259
+ map[n] = m;
260
+ }
261
+
262
+ }
@@ -0,0 +1,34 @@
1
+ #ifndef SWF_GLYPHLIST_H
2
+ #define SWF_GLYPHLIST_H
3
+
4
+ #include <SWFItem.h>
5
+
6
+ namespace SWF {
7
+
8
+ class GlyphShape;
9
+
10
+ class GlyphList : public Item {
11
+ /* glyph lists have strange offsetting stuff, so we do them manually */
12
+ public:
13
+ GlyphList();
14
+ virtual ~GlyphList();
15
+ virtual bool parse( Reader *r, int end, Context *ctx );
16
+ virtual void dump( int indent, Context *ctx );
17
+ virtual size_t calcSize( Context *ctx, int start_at );
18
+ virtual void write( Writer *w, Context *ctx );
19
+ virtual void writeXML( xmlNodePtr node, Context *ctx );
20
+ virtual void parseXML( xmlNodePtr node, Context *ctx );
21
+
22
+ void allocate( int n );
23
+ GlyphShape *getShapeN( int n );
24
+ void setMapN( int n, int m );
25
+
26
+ protected:
27
+ int nGlyphs;
28
+ GlyphShape *glyphs;
29
+ int *map;
30
+ };
31
+
32
+ }
33
+
34
+ #endif
@@ -0,0 +1,85 @@
1
+ #ifndef SWF_IDITEM_H
2
+ #define SWF_IDITEM_H
3
+
4
+ #include <SWFItem.h>
5
+ #include <cstring>
6
+
7
+ namespace SWF {
8
+
9
+ template <class T>
10
+ class IdItem : public Item {
11
+ protected:
12
+ IdItem() { type = 0; len = 0; }
13
+
14
+ int getHeaderSize( int size ) { return 8; }
15
+ void writeHeader( Writer *w, Context *ctx, size_t len ) { w->putByte( type ); }
16
+
17
+ void setType( int t ) { type = t; }
18
+ int getType() { return type; }
19
+
20
+ void setLength( int l ) { len = l; }
21
+ int getLength() { return len; }
22
+
23
+ int type;
24
+ int len;
25
+
26
+ // static stuff
27
+ public:
28
+ static T* get( Reader *r, int end, Context *ctx ) {
29
+ int type = r->getByte();
30
+ int len = end - r->getPosition();
31
+
32
+ T* ret = getByType( type );
33
+
34
+ if( ret ) {
35
+ ret->setType( type );
36
+ ret->setLength( len );
37
+ ret->parse( r, end, ctx );
38
+ } else {
39
+ fprintf(stderr,"WARNING: unknown %s type 0x%02X\n", itemName, type );
40
+ }
41
+
42
+ return ret;
43
+ }
44
+
45
+ static T* getByName( const char *name ) {
46
+ T *ret = NULL;
47
+
48
+ for( int i=0; i<nRegistered; i++ ) {
49
+ if( !strcmp( Registry[i].name, name ) ) {
50
+ ret = Registry[i].factory();
51
+ ret->setType( Registry[i].type );
52
+ return ret;
53
+ }
54
+ }
55
+ return NULL;
56
+ }
57
+
58
+ protected:
59
+ static T* getByType( int type ) {
60
+ T *ret = NULL;
61
+
62
+ for( int i=0; i<nRegistered; i++ ) {
63
+ if( Registry[i].type == type ) {
64
+ ret = Registry[i].factory();
65
+ }
66
+ }
67
+
68
+ return ret;
69
+ }
70
+
71
+ struct Description {
72
+ typedef T * FactoryFunction();
73
+ int type;
74
+ const char *name;
75
+ FactoryFunction *factory;
76
+ };
77
+ static Description Registry[];
78
+ static int nRegistered;
79
+
80
+ static const char* itemName;
81
+ };
82
+
83
+ }
84
+ #endif
85
+