swfmill 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+