swfmill 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.swfmill +0 -134
  2. data/README.rdoc +28 -8
  3. data/Rakefile +6 -5
  4. data/VERSION +1 -1
  5. data/ext/.gitignore +1 -0
  6. data/ext/buffer.h +95 -0
  7. data/ext/deflate.h +125 -0
  8. data/ext/extconf.rb +77 -43
  9. data/ext/inflate.h +82 -0
  10. data/ext/swfmill/.gitignore +3 -16
  11. data/ext/swfmill/AUTHORS +2 -1
  12. data/ext/swfmill/Makefile.in +2 -1
  13. data/ext/swfmill/NEWS +5 -0
  14. data/ext/swfmill/autogen.sh +7 -1
  15. data/ext/swfmill/configure +361 -275
  16. data/ext/swfmill/configure.ac +28 -20
  17. data/ext/swfmill/src/Makefile.am +93 -20
  18. data/ext/swfmill/src/Makefile.in +454 -170
  19. data/ext/swfmill/src/SWF.h +3 -0
  20. data/ext/swfmill/src/SWFFile.cpp +1 -1
  21. data/ext/swfmill/src/SWFShapeMaker.cpp +4 -3
  22. data/ext/swfmill/src/codegen/basics.xsl +2 -1
  23. data/ext/swfmill/src/codegen/header.xsl +3 -0
  24. data/ext/swfmill/src/codegen/parsexml.xsl +53 -2
  25. data/ext/swfmill/src/codegen/writexml.xsl +54 -1
  26. data/ext/swfmill/src/swfmill.cpp +52 -35
  27. data/ext/swfmill/src/swft/swft_import_jpeg.cpp +62 -16
  28. data/ext/swfmill/src/xslt/simple-elements.xslt +1 -0
  29. data/ext/swfmill/test/Makefile.in +2 -1
  30. data/ext/swfmill/test/xml/Makefile.in +2 -1
  31. data/ext/swfmill_ext.cc +12 -366
  32. data/ext/swfmill_ext_to_swf.cc +260 -0
  33. data/ext/swfmill_ext_to_swf.h +6 -0
  34. data/ext/swfmill_ext_to_xml.cc +262 -0
  35. data/ext/swfmill_ext_to_xml.h +6 -0
  36. data/ext/test/Makefile +16 -0
  37. data/ext/test/buffer_test.cc +84 -0
  38. data/ext/test/deflate_test.cc +61 -0
  39. data/ext/test/inflate_test.cc +84 -0
  40. data/ext/test/test.dat +0 -0
  41. data/lib/swfmill.rb +14 -23
  42. data/spec/swfmill_spec.rb +0 -123
  43. metadata +28 -17
  44. data/ext/swfmill/src/codegen/Makefile.am +0 -15
  45. data/ext/swfmill/src/codegen/Makefile.in +0 -346
  46. data/ext/swfmill/src/swft/Makefile.am +0 -55
  47. data/ext/swfmill/src/swft/Makefile.in +0 -717
  48. data/ext/swfmill/src/xslt/Makefile.am +0 -51
  49. data/ext/swfmill/src/xslt/Makefile.in +0 -536
  50. data/ext/swfmill/src/xslt/README +0 -19
  51. data/ext/swfmill/src/xslt/simple.cpp +0 -1686
@@ -39,6 +39,7 @@
39
39
  <xsl:variable name="frames">
40
40
  <xsl:choose>
41
41
  <xsl:when test="@frames"><xsl:value-of select="@frames"/></xsl:when>
42
+ <xsl:when test="frame"><xsl:value-of select="count(frame)"/></xsl:when>
42
43
  <xsl:otherwise>1</xsl:otherwise>
43
44
  </xsl:choose>
44
45
  </xsl:variable>
@@ -80,12 +80,13 @@ ECHO_N = @ECHO_N@
80
80
  ECHO_T = @ECHO_T@
81
81
  EGREP = @EGREP@
82
82
  EXEEXT = @EXEEXT@
83
+ EXSLT_CFLAGS = @EXSLT_CFLAGS@
84
+ EXSLT_LIBS = @EXSLT_LIBS@
83
85
  F77 = @F77@
84
86
  FFLAGS = @FFLAGS@
85
87
  FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
86
88
  FREETYPE_LIBS = @FREETYPE_LIBS@
87
89
  GREP = @GREP@
88
- HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
89
90
  INSTALL = @INSTALL@
90
91
  INSTALL_DATA = @INSTALL_DATA@
91
92
  INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -68,12 +68,13 @@ ECHO_N = @ECHO_N@
68
68
  ECHO_T = @ECHO_T@
69
69
  EGREP = @EGREP@
70
70
  EXEEXT = @EXEEXT@
71
+ EXSLT_CFLAGS = @EXSLT_CFLAGS@
72
+ EXSLT_LIBS = @EXSLT_LIBS@
71
73
  F77 = @F77@
72
74
  FFLAGS = @FFLAGS@
73
75
  FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
74
76
  FREETYPE_LIBS = @FREETYPE_LIBS@
75
77
  GREP = @GREP@
76
- HAVE_PKGCONFIG = @HAVE_PKGCONFIG@
77
78
  INSTALL = @INSTALL@
78
79
  INSTALL_DATA = @INSTALL_DATA@
79
80
  INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -1,375 +1,21 @@
1
- #include <zlib.h>
2
1
  #include "ruby.h"
3
- #include "SWF.h"
4
- #include "SWFReader.h"
5
- #include "SWFWriter.h"
2
+ #include "swfmill_ext_to_xml.h"
3
+ #include "swfmill_ext_to_swf.h"
6
4
 
7
- static VALUE rb_mSwfmill;
8
- static VALUE rb_eSwfmill_Error;
9
- static VALUE rb_eSwfmill_EOFError;
5
+ VALUE rb_mSwfmill;
6
+ VALUE rb_eSwfmill_Error;
7
+ VALUE rb_eSwfmill_EOFError;
10
8
 
11
- /*
12
- call-seq:
13
- Swfmill.to_xmlstr(str [, params]) -> String
14
-
15
- +params+
16
- {
17
- :version => Fixnum,
18
- :compressed => Boolean,
19
- }
20
- */
21
- VALUE swfmill_ext_to_xmlstr(int argc, VALUE *argv, VALUE self)
22
- {
23
- VALUE arg_str, arg_param;
24
- int arg_num = rb_scan_args(argc, argv, "11", &arg_str, &arg_param);
25
-
26
- unsigned char version = 7;
27
- bool compressed = false;
28
-
29
- Check_Type(arg_str, T_STRING);
30
- if(arg_num == 2)
31
- {
32
- Check_Type(arg_param, T_HASH);
33
-
34
- VALUE ver = rb_hash_aref(arg_param, ID2SYM(rb_intern("version")));
35
- if(!NIL_P(ver))
36
- {
37
- version = (unsigned char)NUM2INT(ver);
38
- }
39
-
40
- VALUE cmp = rb_hash_aref(arg_param, ID2SYM(rb_intern("compressed")));
41
- if(!NIL_P(cmp))
42
- {
43
- compressed = cmp == Qtrue;
44
- }
45
- }
46
-
47
- unsigned char* data = (unsigned char*)StringValuePtr(arg_str);
48
- size_t size = RSTRING_LEN(arg_str);
49
-
50
- SWF::Header header;
51
- {
52
- SWF::Context context;
53
- SWF::Reader reader(data, size);
54
- header.parse(&reader, size, &context);
55
- switch(reader.getError())
56
- {
57
- case SWFR_ERROR:
58
- rb_raise(rb_eSwfmill_Error, "unknown error while reading SWF");
59
- break;
60
- case SWFR_EOF:
61
- rb_raise(rb_eSwfmill_EOFError, "reached EOF while reading SWF");
62
- break;
63
- }
64
- }
65
-
66
- VALUE xml = Qnil;
67
- {
68
- SWF::Context context;
69
- xmlDocPtr doc = xmlNewDoc((const xmlChar*)"1.0");
70
- xmlNodePtr root = doc->xmlRootNode = xmlNewDocNode(doc, NULL, (const xmlChar *)"swf", NULL);
71
- char tmp[4];
72
-
73
- snprintf(tmp, sizeof(tmp), "%i", version);
74
- xmlSetProp(root, (const xmlChar*)"version", (const xmlChar*)tmp);
75
-
76
- snprintf(tmp, sizeof(tmp), "%i", compressed?1:0);
77
- xmlSetProp(root, (const xmlChar*)"compressed", (const xmlChar*)tmp);
78
-
79
- context.swfVersion = version;
80
- header.writeXML(root, &context);
81
-
82
- char* xml_data = NULL;
83
- int xml_size;
84
- xmlDocDumpFormatMemory(doc, (xmlChar **)&xml_data, &xml_size, 1);
85
-
86
- if(xml_size > 0)
87
- {
88
- xml = rb_str_new(xml_data, xml_size);
89
- }
90
-
91
- if(xml_data != NULL)
92
- {
93
- xmlFree(xml_data);
94
- }
95
-
96
- xmlFreeDoc(doc);
97
- }
98
-
99
- return xml;
100
- }
101
-
102
- /*
103
- call-seq:
104
- Swfmill.to_swf(str [, params]) -> Array
105
-
106
- +params+
107
- {
108
- :compress => Boolean,
109
- :level => Symbol,
110
- }
111
-
112
- :compress
113
- true
114
- false
115
- nil
9
+ extern "C" {
116
10
 
117
- :level
118
- :best
119
- :speed
120
- :none
121
- */
122
- VALUE swfmill_ext_to_swf(int argc, VALUE *argv, VALUE self)
11
+ void Init_swfmill_ext(void)
123
12
  {
124
- VALUE arg_str, arg_param;
125
- int arg_num = rb_scan_args(argc, argv, "11", &arg_str, &arg_param);
126
-
127
- unsigned char version = 7;
128
- bool compressed = false;
129
- int compress = 0;
130
- int compress_level = Z_BEST_COMPRESSION;
131
-
132
- Check_Type(arg_str, T_STRING);
133
- if(arg_num == 2)
134
- {
135
- Check_Type(arg_param, T_HASH);
136
-
137
- VALUE lvl = rb_hash_aref(arg_param, ID2SYM(rb_intern("level")));
138
- if(!NIL_P(lvl))
139
- {
140
- if(lvl == ID2SYM(rb_intern("speed")))
141
- {
142
- compress_level = Z_BEST_SPEED;
143
- }
144
- if(lvl == ID2SYM(rb_intern("none")))
145
- {
146
- compress_level = Z_NO_COMPRESSION;
147
- }
148
- }
149
-
150
- VALUE cmp = rb_hash_aref(arg_param, ID2SYM(rb_intern("compressed")));
151
- if(!NIL_P(cmp))
152
- {
153
- compress = cmp == Qtrue ? 1 : 2;
154
- }
155
- }
13
+ rb_mSwfmill = rb_define_module("Swfmill");
14
+ rb_eSwfmill_Error = rb_define_class_under(rb_mSwfmill, "Error", rb_eStandardError);
15
+ rb_eSwfmill_EOFError = rb_define_class_under(rb_mSwfmill, "EOFError", rb_eStandardError);
156
16
 
157
- char* data = StringValuePtr(arg_str);
158
- int size = RSTRING_LEN(arg_str);
159
- xmlDocPtr doc = xmlParseMemory(data, size);
160
-
161
- if(doc == NULL)
162
- {
163
- rb_raise(rb_eSwfmill_Error, "XML parser error");
164
- }
165
-
166
- xmlNodePtr root = doc->xmlRootNode;
167
- if(strcmp((const char*)root->name, "swf") != 0)
168
- {
169
- xmlFreeDoc(doc);
170
- rb_raise(rb_eSwfmill_Error, "doesn't seem to be a swfml file");
171
- }
172
-
173
- xmlNodePtr headerNode = root->children;
174
- while((headerNode != NULL) &&
175
- (headerNode->name == NULL || strcmp((const char*)headerNode->name, "Header") != 0))
176
- {
177
- headerNode = headerNode->next;
178
- }
179
- if(headerNode == NULL)
180
- {
181
- xmlFreeDoc(doc);
182
- rb_raise(rb_eSwfmill_Error, "swfml file is empty");
183
- }
184
-
185
- {
186
- xmlChar *tmp;
187
- tmp = xmlGetProp(root, (const xmlChar*)"version");
188
- if(tmp != NULL)
189
- {
190
- int i;
191
- sscanf((char*)tmp, "%i", &i);
192
- version = i;
193
- xmlFree(tmp);
194
- }
195
-
196
- tmp = xmlGetProp(root, (const xmlChar*)"compressed");
197
- if(tmp != NULL)
198
- {
199
- int i;
200
- sscanf((char*)tmp, "%i", &i);
201
- compressed = i > 0;
202
- xmlFree(tmp);
203
- }
204
- }
205
- if(compress > 0)
206
- {
207
- compressed = compress == 1;
208
- }
209
-
210
- SWF::Header header;
211
- size_t swf_size;
212
- {
213
- SWF::Context context;
214
- context.swfVersion = version;
215
- header.parseXML(headerNode, &context);
216
- swf_size = header.getSize(&context, 0) / 8;
217
- }
218
-
219
- char swf_head[8+1];
220
- {
221
- swf_size += 8;
222
- snprintf(swf_head, 8, "%s%c%c%c%c%c",
223
- compressed ? "CWS" : "FWS",
224
- version,
225
- ((swf_size>> 0) & 0xFF),
226
- ((swf_size>> 8) & 0xFF),
227
- ((swf_size>>16) & 0xFF),
228
- ((swf_size>>24) & 0xFF));
229
- swf_size -= 8;
230
- }
231
-
232
- unsigned char* swf_buff = (unsigned char*)ruby_xmalloc(swf_size);
233
- {
234
- SWF::Context context;
235
- SWF::Writer writer(swf_buff, swf_size);
236
- context.swfVersion = version;
237
- header.write(&writer, &context);
238
- switch(writer.getError())
239
- {
240
- case SWFW_ERROR:
241
- ruby_xfree(swf_buff);
242
- xmlFreeDoc(doc);
243
- rb_raise(rb_eSwfmill_Error, "unknown write error");
244
- break;
245
- case SWFW_FULL:
246
- ruby_xfree(swf_buff);
247
- xmlFreeDoc(doc);
248
- rb_raise(rb_eSwfmill_Error, "write buffer full");
249
- break;
250
- }
251
- }
252
-
253
- if(compressed)
254
- {
255
- unsigned char temp[BUFSIZ];
256
- z_stream stream={Z_NULL};
257
- int status, count;
258
-
259
- unsigned char* out_buff = (unsigned char*)ruby_xmalloc(swf_size);
260
- int out_offset = 0, out_size = swf_size;
261
-
262
- stream.next_in = swf_buff;
263
- stream.avail_in = swf_size;
264
- stream.next_out = temp;
265
- stream.avail_out = BUFSIZ;
266
-
267
- status = deflateInit(&stream, compress_level);
268
- if(status != Z_OK)
269
- {
270
- ruby_xfree(swf_buff);
271
- xmlFreeDoc(doc);
272
- rb_raise(rb_eSwfmill_Error, "Error compressing SWF: %s", stream.msg);
273
- }
274
-
275
- for(;;)
276
- {
277
- if(stream.avail_in == 0)
278
- {
279
- break;
280
- }
281
-
282
- status = deflate(&stream, Z_NO_FLUSH);
283
- if(status != Z_OK)
284
- {
285
- ruby_xfree(swf_buff);
286
- xmlFreeDoc(doc);
287
- rb_raise(rb_eSwfmill_Error, "Error compressing SWF: %s", stream.msg);
288
- }
289
-
290
- count = BUFSIZ - stream.avail_out;
291
- if(count > 0)
292
- {
293
- if(out_offset + count >= out_size)
294
- {
295
- int tmp_size = out_size + out_size / 2;
296
- unsigned char* tmp_buff = (unsigned char*)ruby_xmalloc(tmp_size);
297
- memcpy(tmp_buff, out_buff, out_size);
298
- ruby_xfree(out_buff);
299
- out_buff = tmp_buff;
300
- out_size = tmp_size;
301
- }
302
- memcpy(out_buff + out_offset, temp, count);
303
- out_offset += count;
304
- }
305
-
306
- stream.next_out = temp;
307
- stream.avail_out = BUFSIZ;
308
- }
309
-
310
- do
311
- {
312
- status = deflate(&stream, Z_FINISH);
313
-
314
- count = BUFSIZ - stream.avail_out;
315
- if(count > 0)
316
- {
317
- if(out_offset + count >= out_size)
318
- {
319
- int tmp_size = out_size + out_size / 2;
320
- unsigned char* tmp_buff = (unsigned char*)ruby_xmalloc(tmp_size);
321
- memcpy(tmp_buff, out_buff, out_size);
322
- ruby_xfree(out_buff);
323
- out_buff = tmp_buff;
324
- out_size = tmp_size;
325
- }
326
- memcpy(out_buff + out_offset, temp, count);
327
- out_offset += count;
328
- }
329
-
330
- stream.next_out = temp;
331
- stream.avail_out = BUFSIZ;
332
- } while(status == Z_OK);
333
-
334
- if(status != Z_STREAM_END)
335
- {
336
- ruby_xfree(swf_buff);
337
- xmlFreeDoc(doc);
338
- rb_raise(rb_eSwfmill_Error, "Error compressing SWF: %s", stream.msg);
339
- }
340
-
341
- status = deflateEnd(&stream);
342
- if(status != Z_OK)
343
- {
344
- ruby_xfree(swf_buff);
345
- xmlFreeDoc(doc);
346
- rb_raise(rb_eSwfmill_Error, "Error compressing SWF: %s", stream.msg);
347
- }
348
-
349
- ruby_xfree(swf_buff);
350
- swf_size = out_offset;
351
- swf_buff = (unsigned char*)ruby_xmalloc(swf_size);
352
- memcpy(swf_buff, out_buff, swf_size);
353
- ruby_xfree(out_buff);
354
- }
355
-
356
- VALUE swf;
357
- swf = rb_str_new(swf_head, 8);
358
- rb_str_cat(swf, (const char*)swf_buff, swf_size);
359
-
360
- ruby_xfree(swf_buff);
361
- xmlFreeDoc(doc);
362
- return swf;
17
+ rb_define_singleton_method(rb_mSwfmill, "to_xml", (VALUE (*)(...))swfmill_ext_to_xml, 2);
18
+ rb_define_singleton_method(rb_mSwfmill, "to_swf", (VALUE (*)(...))swfmill_ext_to_swf, 2);
363
19
  }
364
20
 
365
- extern "C" {
366
- void Init_swfmill_ext(void)
367
- {
368
- rb_mSwfmill = rb_define_module("Swfmill");
369
- rb_define_singleton_method(rb_mSwfmill, "to_xmlstr", (VALUE(*)(...))swfmill_ext_to_xmlstr, -1);
370
- rb_define_singleton_method(rb_mSwfmill, "to_swf", (VALUE(*)(...))swfmill_ext_to_swf, -1);
371
-
372
- rb_eSwfmill_Error = rb_define_class_under(rb_mSwfmill, "Error", rb_eStandardError);
373
- rb_eSwfmill_EOFError = rb_define_class_under(rb_mSwfmill, "EOFError", rb_eStandardError);
374
- }
375
21
  }
@@ -0,0 +1,260 @@
1
+ #include <zlib.h>
2
+ #include "ruby.h"
3
+ #include "SWF.h"
4
+ #include "SWFWriter.h"
5
+ #include "deflate.h"
6
+
7
+ extern VALUE rb_eSwfmill_Error;
8
+ extern VALUE rb_eSwfmill_EOFError;
9
+
10
+ #define SIGNATURE_SIZE 8
11
+ typedef struct {
12
+ VALUE string;
13
+ VALUE encoding;
14
+ bool compressed;
15
+ SWF::Header *header;
16
+ SWF::Context *context;
17
+ size_t datasize;
18
+ unsigned char *databuff;
19
+ int compress_level;
20
+ xmlDocPtr document;
21
+ xmlNodePtr root_node;
22
+ xmlNodePtr header_node;
23
+ } swfmill_to_swf;
24
+
25
+ static void
26
+ sts_mark(swfmill_to_swf * const sts)
27
+ {
28
+ if(sts != NULL)
29
+ {
30
+ rb_gc_mark(sts->string);
31
+ rb_gc_mark(sts->encoding);
32
+ }
33
+ }
34
+
35
+ static void
36
+ sts_free(swfmill_to_swf * const sts)
37
+ {
38
+ if(sts != NULL)
39
+ {
40
+ if(sts->document != NULL)
41
+ {
42
+ xmlFreeDoc(sts->document);
43
+ sts->document = NULL;
44
+ }
45
+
46
+ ruby_xfree(sts->databuff);
47
+ sts->databuff = NULL;
48
+
49
+ delete sts->header;
50
+ sts->header = NULL;
51
+
52
+ delete sts->context;
53
+ sts->context = NULL;
54
+ }
55
+ }
56
+
57
+ static bool
58
+ sts_parse_document(swfmill_to_swf * const sts)
59
+ {
60
+ sts->document = xmlParseMemory(RSTRING_PTR(sts->string), RSTRING_LEN(sts->string));
61
+ if(sts->document == NULL)
62
+ {
63
+ rb_raise(rb_eSwfmill_Error, "XML parser error");
64
+ return false;
65
+ }
66
+
67
+ sts->root_node = sts->document->xmlRootNode;
68
+ if(strcmp((const char*)sts->root_node->name, "swf") != 0)
69
+ {
70
+ rb_raise(rb_eSwfmill_Error, "doesn't seem to be a swfml file");
71
+ return false;
72
+ }
73
+
74
+ return true;
75
+ }
76
+
77
+ static bool
78
+ sts_search_header_node(swfmill_to_swf * const sts)
79
+ {
80
+ xmlNodePtr headerNode = sts->root_node->children;
81
+
82
+ while((headerNode != NULL) &&
83
+ (headerNode->name == NULL || strcmp((const char*)headerNode->name, "Header") != 0))
84
+ {
85
+ headerNode = headerNode->next;
86
+ }
87
+
88
+ if(headerNode == NULL)
89
+ {
90
+ rb_raise(rb_eSwfmill_Error, "swfml file is empty");
91
+ return false;
92
+ }
93
+
94
+ sts->header_node = headerNode;
95
+
96
+ return true;
97
+ }
98
+
99
+ static void
100
+ sts_get_version(swfmill_to_swf * const sts)
101
+ {
102
+ xmlChar *tmp = xmlGetProp(sts->root_node, (const xmlChar*)"version");
103
+
104
+ sts->context = new SWF::Context;
105
+ sts->context->debugTrace = false;
106
+ sts->context->quiet = true;
107
+
108
+ if(tmp != NULL)
109
+ {
110
+ sscanf((char*)tmp, "%i", &sts->context->swfVersion);
111
+ xmlFree(tmp);
112
+ }
113
+ }
114
+
115
+ static void
116
+ sts_get_compressed(swfmill_to_swf * const sts)
117
+ {
118
+ xmlChar *tmp = xmlGetProp(sts->root_node, (const xmlChar*)"compressed");
119
+ int compress;
120
+
121
+ sts->compressed = false;
122
+ if(tmp != NULL)
123
+ {
124
+ sscanf((char*)tmp, "%i", &compress);
125
+ sts->compressed = compress > 0;
126
+ xmlFree(tmp);
127
+ }
128
+ }
129
+
130
+ static void
131
+ sts_parse_xml(swfmill_to_swf * const sts)
132
+ {
133
+ sts->context->convertEncoding = true;
134
+ sts->context->swf_encoding = StringValueCStr(sts->encoding);
135
+
136
+ sts->header = new SWF::Header;
137
+ sts->header->parseXML(sts->header_node, sts->context);
138
+
139
+ sts->datasize = sts->header->getSize(sts->context, 0) / 8;
140
+ sts->databuff = (unsigned char*)ruby_xmalloc(sts->datasize + SIGNATURE_SIZE);
141
+ }
142
+
143
+ static bool
144
+ sts_compress(swfmill_to_swf * const sts)
145
+ {
146
+ if(!sts->compressed)
147
+ {
148
+ return true;
149
+ }
150
+
151
+ Deflate deflate(sts->databuff + SIGNATURE_SIZE, sts->datasize, sts->compress_level);
152
+
153
+ if(!deflate.compress())
154
+ {
155
+ rb_raise(rb_eSwfmill_Error, "compressing SWF: %s", deflate.error());
156
+ return false;
157
+ }
158
+
159
+ ruby_xfree(sts->databuff);
160
+ sts->databuff = NULL;
161
+
162
+ sts->datasize = deflate.size();
163
+ sts->databuff = (unsigned char*)ruby_xmalloc(sts->datasize + SIGNATURE_SIZE);
164
+ memcpy(sts->databuff + SIGNATURE_SIZE, deflate.data(), sts->datasize);
165
+
166
+ return true;
167
+ }
168
+
169
+ static bool
170
+ sts_write(swfmill_to_swf * const sts)
171
+ {
172
+ SWF::Writer writer(sts->databuff + SIGNATURE_SIZE, sts->datasize);
173
+ size_t datasize;
174
+
175
+ sts->header->write(&writer, sts->context);
176
+ switch(writer.getError())
177
+ {
178
+ case SWFW_ERROR:
179
+ rb_raise(rb_eSwfmill_Error, "unknown write error");
180
+ return false;
181
+ case SWFW_FULL:
182
+ rb_raise(rb_eSwfmill_Error, "write buffer full");
183
+ return false;
184
+ }
185
+
186
+ if(!sts_compress(sts))
187
+ {
188
+ return false;
189
+ }
190
+
191
+ sts->databuff[0] = (unsigned char)(sts->compressed ? 'C' : 'F');
192
+ sts->databuff[1] = (unsigned char)'W';
193
+ sts->databuff[2] = (unsigned char)'S';
194
+ sts->databuff[3] = (unsigned char)sts->context->swfVersion;
195
+
196
+ datasize = sts->datasize;
197
+ sts->databuff[4] = (unsigned char)((datasize >> 0) & 0xFF);
198
+ sts->databuff[5] = (unsigned char)((datasize >> 8) & 0xFF);
199
+ sts->databuff[6] = (unsigned char)((datasize >> 16) & 0xFF);
200
+ sts->databuff[7] = (unsigned char)((datasize >> 24) & 0xFF);
201
+
202
+ return true;
203
+ }
204
+
205
+ static bool
206
+ sts_parse(swfmill_to_swf * const sts)
207
+ {
208
+ if(!sts_parse_document(sts))
209
+ {
210
+ return false;
211
+ }
212
+ if(!sts_search_header_node(sts))
213
+ {
214
+ return false;
215
+ }
216
+ sts_get_version(sts);
217
+ sts_get_compressed(sts);
218
+ sts_parse_xml(sts);
219
+ if(!sts_write(sts))
220
+ {
221
+ return false;
222
+ }
223
+ return true;
224
+ }
225
+
226
+ static VALUE
227
+ sts_to_string(swfmill_to_swf * const sts)
228
+ {
229
+ VALUE str = rb_str_new((const char*)sts->databuff, sts->datasize + SIGNATURE_SIZE);
230
+
231
+ ruby_xfree(sts->databuff);
232
+ sts->databuff = NULL;
233
+
234
+ return str;
235
+ }
236
+
237
+ /*
238
+ call-seq:
239
+ Swfmill.to_swf(str, encoding) -> String
240
+ */
241
+ VALUE swfmill_ext_to_swf(VALUE self, VALUE string, VALUE encoding)
242
+ {
243
+ swfmill_to_swf *sts;
244
+
245
+ Check_Type(string, T_STRING);
246
+ Check_Type(encoding, T_STRING);
247
+
248
+ Data_Make_Struct(rb_cData, swfmill_to_swf, sts_mark, sts_free, sts);
249
+
250
+ sts->string = string;
251
+ sts->encoding = encoding;
252
+ sts->compress_level = Z_BEST_COMPRESSION;
253
+
254
+ if(sts_parse(sts))
255
+ {
256
+ return sts_to_string(sts);
257
+ }
258
+
259
+ return Qnil;
260
+ }