OSDN Git Service

DoAction, DoInitAction を parse/build する時の内部仕様変更。
authoryoya <yoya@7c90b180-03d5-4157-b861-58a559ae9d1e>
Wed, 8 Jun 2011 07:52:20 +0000 (07:52 +0000)
committeryoya <yoya@7c90b180-03d5-4157-b861-58a559ae9d1e>
Wed, 8 Jun 2011 07:52:20 +0000 (07:52 +0000)
Actionレコードのバイナリ全体でなく、Actionの配列として保持するようにした。

- swf_tag_action 構造体から action_data, action_length、has_length を削除してaction_list を追加
- detail input, output に action_list 処理を追加
- setvariable を action_list に対する処理に変更
- getTagDetail で Action タグの時に埋めるキーを action_record_data,len から action_list_count に変更
- getActionData で参照でなく malloc したデータが返るので、その対応
- swf_tag_action_create_setvaribles, swf_tag_action_put_setvaribles の処理が重複してたので swf_tag_action_top_append_varibles にまとめた。
- action_has_length で判断する場所を action_id >= 0x80 で判断するよう変更

git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/swfed/trunk@575 7c90b180-03d5-4157-b861-58a559ae9d1e

src/php_swfed.c
src/swf_action.c
src/swf_action.h
src/swf_object.c
src/swf_tag.c
src/swf_tag_action.c
src/swf_tag_action.h

index 56a748e..2492aae 100644 (file)
@@ -474,6 +474,8 @@ PHP_METHOD(swfed, getTagDetail) {
         swf_tag_sprite_detail_t   *tag_sprite;
         swf_tag_shape_detail_t    *tag_shape;
         swf_tag_place_detail_t    *tag_place;
+        swf_action_t   *action;
+        int action_list_count;
        zval *data = NULL;
       case 6:  // DefineBitsJPEG
       case 21: // DefineBitsJPEG2
@@ -517,8 +519,12 @@ PHP_METHOD(swfed, getTagDetail) {
         if (tag->code == 59) { // DoInitAction
             add_assoc_long(return_value, "action_sprite", tag_action->action_sprite);
         }
-        if (tag_action->action_record && tag_action->action_record_len) {
-            add_assoc_long(return_value, "action_record_len", tag_action->action_record_len);
+        action = tag_action->action_list->head;
+        if (action) {
+            for (action_list_count = 0 ; action ; action_list_count++) {
+                action = action->next;
+            }
+            add_assoc_long(return_value, "action_list_count", action_list_count);
         }
         break;
       case 37: // DefineEditText;
@@ -1208,7 +1214,7 @@ PHP_METHOD(swfed, replaceEditString) {
 PHP_METHOD(swfed, getActionData) {
     long tag_seqno = 0;
     swf_object_t *swf = NULL;
-    unsigned char *data_ref = NULL;
+    unsigned char *data = NULL;
     char *new_buff = NULL;
     unsigned long data_len = 0;
     
@@ -1216,17 +1222,19 @@ PHP_METHOD(swfed, getActionData) {
         RETURN_FALSE;
     }
     swf = get_swf_object(getThis() TSRMLS_CC);
-    data_ref = swf_object_get_actiondata(swf, &data_len, tag_seqno);
-    if (data_ref == NULL) {
+    data = swf_object_get_actiondata(swf, &data_len, tag_seqno);
+    if (data == NULL) {
         fprintf(stderr, "getActionData: Can't get_actiondata\n");
         RETURN_FALSE;
     }
     new_buff = emalloc(data_len);
     if (new_buff == NULL) {
         fprintf(stderr, "getActionData: Can't emalloc new_buff\n");
+        free(data);
         RETURN_FALSE;
     }
-    memcpy(new_buff, data_ref, data_len);
+    memcpy(new_buff, data, data_len);
+    free(data);
     RETURN_STRINGL(new_buff, data_len, 0);
 }
 
@@ -1242,7 +1250,8 @@ PHP_METHOD(swfed, disasmActionData) {
     array_init(return_value);
     bs = bitstream_open();
     bitstream_input(bs, (unsigned char*) data, data_len);
-    action_list = swf_action_list_create(bs);
+    action_list = swf_action_list_create();
+    swf_action_list_parse(bs, action_list);
     bitstream_close(bs);
     if (action_list) {
         swf_action_t *action = action_list->head;
index 2df7207..5e74ab0 100644 (file)
@@ -139,11 +139,6 @@ swf_action_parse(bitstream_t *bs, swf_action_t *act) {
     bitstream_align(bs);
     act->action_id = bitstream_getbyte(bs);
     if (act->action_id & 0x80) {
-        act->action_has_length = 1;
-    } else {
-        act->action_has_length = 0;
-    }
-    if (act->action_has_length) {
         act->action_length = bitstream_getbytesLE(bs, 2);
         offset = bitstream_getbytepos(bs);
         act->action_data = malloc(act->action_length);
@@ -159,9 +154,8 @@ swf_action_parse(bitstream_t *bs, swf_action_t *act) {
 int
 swf_action_build(bitstream_t *bs, swf_action_t *act) {
     bitstream_align(bs);
-    /* bitstream_putbits(bs, act->action_has_length, 1);  no need */
     bitstream_putbyte(bs, act->action_id);
-    if (act->action_has_length) {
+    if (act->action_id & 0x80) {
         if (act->action_data == NULL) {
             return 1; // error
         }
@@ -181,7 +175,7 @@ swf_action_print(swf_action_t *act, int indent_depth) {
         print_indent(indent_depth);
         printf("0x%02x", act->action_id);
     }
-    if (act->action_has_length) {
+    if (act->action_id & 0x80) {
         int i, n;
         unsigned char *d;
         switch(act->action_id) {
@@ -214,21 +208,31 @@ swf_action_print(swf_action_t *act, int indent_depth) {
 }
 
 swf_action_list_t *
-swf_action_list_create(bitstream_t *bs) {
+swf_action_list_create(void) {
     swf_action_list_t *action_list;
-    swf_action_t *action;
     action_list = calloc(sizeof(*action_list), 1);
     if (action_list == NULL) {
         fprintf(stderr, "Can't alloc memory for action_list\n");
         return NULL;
     }
-    do {
+    action_list->head = NULL;
+    action_list->tail = NULL;
+    return action_list;
+}
+
+int
+swf_action_list_parse(bitstream_t *bs, swf_action_list_t *action_list) {
+    swf_action_t *action;
+    while (1) {
         action = calloc(sizeof(*action), 1);
         if (action == NULL) {
             fprintf(stderr, "Can't alloc memory for action\n");
             break;
         }
-        swf_action_parse(bs, action);
+        if (swf_action_parse(bs, action)) {
+            fprintf(stderr, "swf_action_list_parse: swf_action_parse failed");
+            return 1; // NG
+        }
         if (action_list->head == NULL) {
             action_list->head = action_list->tail = action;
         } else {
@@ -236,23 +240,26 @@ swf_action_list_create(bitstream_t *bs) {
             action_list->tail = action;
         }
         action->next = NULL;
-    } while(action->action_id != 0); // End Action;
-    return action_list;
+        if (action->action_id == 0) { // End Action;
+            break;
+        }
+    }
+    return 0;
 }
-unsigned char *
-swf_action_list_output(swf_action_list_t *list, unsigned long *length) {
+
+int
+swf_action_list_build(bitstream_t *bs, swf_action_list_t *list) {
     swf_action_t *action;
-    bitstream_t *bs;
-    unsigned char *data;
-    *length = 0;
-    bs = bitstream_open();
     for (action=list->head ; action ; action=action->next) {
-        swf_action_build(bs, action);
+        if (swf_action_build(bs, action) != 0) {
+            fprintf(stderr, "swf_action_list_build: swf_action_build failed\n");
+            bitstream_putbyte(bs, 0);
+            return 1;
+        }
     }
-    data = bitstream_steal(bs, length);
-    bitstream_close(bs);
-    return data;
+    return 0;
 }
+
 void
 swf_action_list_destroy(swf_action_list_t *action_list) {
 
@@ -332,3 +339,25 @@ swf_action_data_print(unsigned char *action_data, unsigned short action_data_len
     }
     return result;
 }
+
+int
+swf_action_list_append_top(swf_action_list_t *list, int action_id,
+                           unsigned char *action_data, int action_data_length) {
+    swf_action_t *action;
+    action = calloc(sizeof(*action), 1);
+    action->action_id = action_id;
+    if (action_id >= 0x80) {
+        action->action_data = malloc(action_data_length);
+        memcpy(action->action_data, action_data, action_data_length);
+        action->action_length = action_data_length;
+    } else {
+        action->action_data = NULL;
+        action->action_length = action_data_length;
+    }
+    action->next = list->head;
+    list->head = action;
+    if (list->tail == NULL) {
+        list->tail = action;
+    }
+    return 0;
+}
index 6c16275..e6f1b2e 100644 (file)
@@ -8,7 +8,6 @@
 #define __SWF_ACTION_H__
 
 typedef struct swf_action_ {
-    unsigned char  action_has_length;
     unsigned char  action_id;
     unsigned short action_length;
     unsigned char *action_data;
@@ -30,9 +29,9 @@ extern int swf_action_parse(bitstream_t *bs, swf_action_t *act);
 extern int swf_action_build(bitstream_t *bs, swf_action_t *act);
 extern int swf_action_print(swf_action_t *act, int indent_depth);
 
-extern swf_action_list_t *swf_action_list_create(bitstream_t *bs);
-extern unsigned char *swf_action_list_output(swf_action_list_t *list,
-                                             unsigned long *length);
+extern swf_action_list_t *swf_action_list_create(void);
+extern int swf_action_list_parse(bitstream_t *bs, swf_action_list_t *list);
+extern int swf_action_list_build(bitstream_t *bs, swf_action_list_t *list);
 extern void swf_action_list_destroy(swf_action_list_t *act_list);
 extern void swf_action_list_print(swf_action_list_t *act_list,
                                   int indent_depth);
@@ -40,4 +39,9 @@ extern void swf_action_list_print(swf_action_list_t *act_list,
 extern int swf_action_data_print(unsigned char *action_data,
                                  unsigned short action_data_len);
 
+extern int swf_action_list_append_top(swf_action_list_t *list,
+                                      int action_id,
+                                      unsigned char *action_data,
+                                      int action_data_length);
+
 #endif /* __SWF_ACTION_H__ */
index 16b454b..3848a64 100644 (file)
@@ -1080,6 +1080,8 @@ unsigned char *
 swf_object_get_actiondata(swf_object_t *swf, unsigned long *length, int tag_seqno) {
     swf_tag_t *tag;
     swf_tag_action_detail_t *swf_tag_action;
+    bitstream_t *bs;
+    unsigned char *data;
     int i = 0;
     if (swf == NULL) {
         fprintf(stderr, "swf_object_get_actiondata: swf == NULL\n");
@@ -1102,8 +1104,11 @@ swf_object_get_actiondata(swf_object_t *swf, unsigned long *length, int tag_seqn
         fprintf(stderr, "swf_object_get_actiondata: swf_tag_create_input_detail failed");
         return NULL;
     }
-    *length = swf_tag_action->action_record_len;
-    return swf_tag_action->action_record;
+    bs = bitstream_open();
+    swf_action_list_build(bs,swf_tag_action->action_list);
+    data = bitstream_steal(bs, length);
+    bitstream_close(bs);
+    return data;
 }
 
 int
index b9c92e8..1fb006b 100644 (file)
@@ -938,6 +938,7 @@ swf_tag_t *
 swf_tag_create_action_setvariables(y_keyvalue_t *kv) {
     int ret;
     swf_tag_t *tag = NULL;
+    swf_tag_action_detail_t *swf_tag_action;
     if (kv == NULL) {
         fprintf(stderr, "swf_tag_create_action_setvariables: kv == NULL\n");
         return NULL;
@@ -947,7 +948,15 @@ swf_tag_create_action_setvariables(y_keyvalue_t *kv) {
     swf_tag_info_t *tag_info = get_swf_tag_info(tag->code);
     swf_tag_detail_handler_t *detail_handler = tag_info->detail_handler();
     tag->detail = detail_handler->create();
-    ret = swf_tag_action_create_setvaribles(tag, kv);
+    swf_tag_action = (swf_tag_action_detail_t*) tag->detail;
+    swf_tag_action->action_list = swf_action_list_create();
+    if (swf_tag_action->action_list == NULL) {
+        fprintf(stderr, "swf_tag_create_action_setvariables: swf_action_list_create failed\n");
+        swf_tag_destroy(tag);
+        return NULL;
+    }
+    swf_action_list_append_top(swf_tag_action->action_list, 0, NULL, 0); // End Action
+    ret = swf_tag_action_top_append_varibles(tag, kv);
     if (ret) {
         swf_tag_destroy(tag);
         return NULL;
@@ -971,7 +980,7 @@ swf_tag_put_action_setvariables(swf_tag_t *tag, y_keyvalue_t *kv,
         fprintf(stderr, "swf_tag_put_action_setvariables: swf_tag_create_input_detail failed\n");
         return 1;
     }
-    ret = swf_tag_action_put_setvaribles(tag, kv);
+    ret = swf_tag_action_top_append_varibles(tag, kv);
     if (ret) {
         swf_tag_destroy(tag);
         return 1; // NG
index 6ba2d4f..04eefcb 100644 (file)
@@ -33,8 +33,7 @@ swf_tag_action_create_detail(void) {
         return NULL;
     }
     swf_tag_action->action_sprite = 0;
-    swf_tag_action->action_record = NULL;
-    swf_tag_action->action_record_len = 0;
+    swf_tag_action->action_list = NULL;
     return swf_tag_action;
 }
 
@@ -44,10 +43,16 @@ swf_tag_action_input_detail(swf_tag_t *tag, struct swf_object_ *swf) {
     unsigned char *data  = tag->data;
     unsigned long length = tag->length;
     bitstream_t *bs;
-    unsigned long pos, len;
     (void) swf;
+    if (tag == NULL) {
+        fprintf(stderr, "ERROR: swf_tag_action_input_detail: tag == NULL\n");
+        return 1;
+    }
+    swf_tag_action = tag->detail;
+    data  = tag->data;
+    length = tag->length;
     if (swf_tag_action == NULL) {
-        fprintf(stderr, "ERROR: swf_tag_action_create_detail: swf_tag_action == NULL\n");
+        fprintf(stderr, "ERROR: swf_tag_action_input_detail: swf_tag_action == NULL\n");
         return 1;
     }
 
@@ -59,10 +64,17 @@ swf_tag_action_input_detail(swf_tag_t *tag, struct swf_object_ *swf) {
     } else {              // DoAction
         swf_tag_action->action_sprite = 0; // fail safe
     }
-    pos = bitstream_getbytepos(bs);
-    len = bitstream_length(bs) - pos;
-    swf_tag_action->action_record = bitstream_output_sub(bs, pos, len);
-    swf_tag_action->action_record_len = len;
+    swf_tag_action->action_list = swf_action_list_create();
+    if (swf_tag_action->action_list == NULL) {
+        fprintf(stderr, "swf_tag_action_input_detail: swf_action_list_create failed\n");
+        bitstream_close(bs);
+        return 1;
+    }
+    if (swf_action_list_parse(bs, swf_tag_action->action_list)) {
+        fprintf(stderr, "swf_tag_action_input_detail: swf_action_list_parse failed\n");
+        bitstream_close(bs);
+        return 1;
+    }
     bitstream_close(bs);
     return 0;
 }
@@ -82,18 +94,14 @@ swf_tag_action_output_detail(swf_tag_t *tag, unsigned long *length,
     } else {              // DoAction
         ; // nothing
     }
-    bitstream_putstring(bs, swf_tag_action->action_record,
-                        swf_tag_action->action_record_len);
+    swf_action_list_build(bs,swf_tag_action->action_list);
     data = bitstream_steal(bs, length);
-    bitstream_close(bs);
     return data;
 }
 
 void
 swf_tag_action_print_detail(swf_tag_t *tag,
                             struct swf_object_ *swf, int indent_depth) {
-    bitstream_t *bs;
-    swf_action_list_t *action_list;
     swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail;
     (void) swf;
     print_indent(indent_depth);
@@ -101,13 +109,7 @@ swf_tag_action_print_detail(swf_tag_t *tag,
         printf("action_sprite=%d  ", swf_tag_action->action_sprite);
     }
     printf("action_record =\n");
-    bs = bitstream_open();
-    bitstream_input(bs, swf_tag_action->action_record,
-                    swf_tag_action->action_record_len);
-    action_list = swf_action_list_create(bs);
-    bitstream_close(bs);
-    swf_action_list_print(action_list, indent_depth + 1);
-    swf_action_list_destroy(action_list);
+    swf_action_list_print(swf_tag_action->action_list, indent_depth + 1);
     return ;
 }
 
@@ -115,8 +117,8 @@ void
 swf_tag_action_destroy_detail(swf_tag_t *tag) {
     swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail;
     if (swf_tag_action) {
-        free(swf_tag_action->action_record);
-        swf_tag_action->action_record = NULL;
+        swf_action_list_destroy(swf_tag_action->action_list);
+        swf_tag_action->action_list = NULL;
         free(swf_tag_action);
         tag->detail = NULL;
     }
@@ -124,72 +126,55 @@ swf_tag_action_destroy_detail(swf_tag_t *tag) {
 }
 
 int
-swf_tag_action_create_setvaribles(swf_tag_t *tag, y_keyvalue_t *kv) {
-    bitstream_t *bs;
+swf_tag_action_top_append_varibles(swf_tag_t *tag, y_keyvalue_t *kv) {
     char *key, *value;
     int key_len, value_len;
-    unsigned long data_len;
+    int key_maxlen, value_maxlen, maxlen;
     swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail;
-    swf_tag_action->action_sprite = 0;
-    bs = bitstream_open();
-
-    y_keyvalue_rewind(kv);
-    while (y_keyvalue_next(kv)) {
-        key   = y_keyvalue_get_currentkey(kv, &key_len);
-        value = y_keyvalue_get_currentvalue(kv, &value_len);
-        bitstream_putbyte(bs, 0x96); // Push Data
-        bitstream_putbytesLE(bs, key_len + 2 , 2);
-        bitstream_putbyte(bs, 0);
-        bitstream_putstring(bs, (unsigned char*) key, key_len);
-        bitstream_putbyte(bs, 0);
-        bitstream_putbyte(bs, 0x96); // Push Data
-        bitstream_putbytesLE(bs, value_len + 2 , 2);
-        bitstream_putbyte(bs, 0);
-        bitstream_putstring(bs, (unsigned char*) value, value_len);
-        bitstream_putbyte(bs, 0);
-        bitstream_putbyte(bs, 0x1d); // Set Variable
+    unsigned char *action_data = NULL;
+    if (tag == NULL) {
+        fprintf(stderr, "swf_tag_action_top_append_varibles: tag == NULL\n");
+        return 1; // NG
     }
-    bitstream_putbyte(bs, 0); // End
-    if (swf_tag_action->action_record) {
-        free(swf_tag_action->action_record);
+    if (! isActionTag(tag->code)) {
+        fprintf(stderr, "swf_tag_action_top_append_varibles: isnot ActionTag code=%d\n", tag->code);
+        return 1; // NG
     }
-    swf_tag_action->action_record = bitstream_steal(bs, &data_len);
-    swf_tag_action->action_record_len = data_len;
-    bitstream_close(bs);
-    return 0;
-}
-
-int
-swf_tag_action_put_setvaribles(swf_tag_t *tag, y_keyvalue_t *kv) {
-    bitstream_t *bs;
-    char *key, *value;
-    int key_len, value_len;
-    unsigned long data_len;
-    swf_tag_action_detail_t *swf_tag_action = (swf_tag_action_detail_t *) tag->detail;
+    key_maxlen = y_keyvalue_get_maxkeylength(kv);
+    value_maxlen = y_keyvalue_get_maxvaluelength(kv);
+    maxlen = (key_maxlen>value_maxlen)?key_maxlen:value_maxlen;
+    action_data = malloc(1 + maxlen + 1);
     swf_tag_action->action_sprite = 0;
-    bs = bitstream_open();
-    y_keyvalue_rewind(kv);
-    while (y_keyvalue_next(kv)) {
-        key   = y_keyvalue_get_currentkey(kv, &key_len);
+    // Reversible itelator for append top method.
+    y_keyvalue_seeklast(kv);
+    while (1) {
+        key = y_keyvalue_get_currentkey(kv, &key_len);
+        if (key == NULL) {
+            break;
+        }
         value = y_keyvalue_get_currentvalue(kv, &value_len);
-        bitstream_putbyte(bs, 0x96); // Push Data
-        bitstream_putbytesLE(bs, key_len + 2 , 2);
-        bitstream_putbyte(bs, 0);
-        bitstream_putstring(bs, (unsigned char *)key, key_len);
-        bitstream_putbyte(bs, 0);
-        bitstream_putbyte(bs, 0x96); // Push Data
-        bitstream_putbytesLE(bs, value_len + 2 , 2);
-        bitstream_putbyte(bs, 0);
-        bitstream_putstring(bs, (unsigned char *)value, value_len);
-        bitstream_putbyte(bs, 0);
-        bitstream_putbyte(bs, 0x1d); // Set Variable
-    }
-    if (swf_tag_action->action_record) {
-        bitstream_putstring(bs, swf_tag_action->action_record, swf_tag_action->action_record_len);
-        free(swf_tag_action->action_record);
+
+        // Push Data(key), Push Data(value), Set Variable.
+        // But reversible order for append top method.
+        //
+        // Set Variable
+        swf_action_list_append_top(swf_tag_action->action_list, 0x1d, NULL, 0);
+        // Push Data (value);
+        action_data[0] = 0; // type string;
+        memcpy(action_data + 1, value, value_len);
+        action_data[value_len + 1] = '\0';
+        swf_action_list_append_top(swf_tag_action->action_list, 0x96,
+                                   action_data, 1 + value_len + 1);
+        // Push Data (key);
+        action_data[0] = 0; // type string;
+        memcpy(action_data + 1, key, key_len);
+        action_data[key_len + 1] = '\0';
+        swf_action_list_append_top(swf_tag_action->action_list, 0x96,
+                                   action_data, 1 + key_len + 1);
+        if (y_keyvalue_prev(kv) == 0) {
+            break;
+        }
     }
-    swf_tag_action->action_record = bitstream_steal(bs, &data_len);
-    swf_tag_action->action_record_len = data_len;
-    bitstream_close(bs);
+    free(action_data);
     return 0;
 }
index 5752157..5e95649 100644 (file)
@@ -12,8 +12,7 @@
 
 typedef struct swf_tag_action_detail_ {
     unsigned short  action_sprite;
-    unsigned char  *action_record;
-    unsigned long   action_record_len;
+    swf_action_list_t *action_list;
 } swf_tag_action_detail_t;
 
 extern swf_tag_detail_handler_t *swf_tag_action_detail_handler(void);
@@ -31,7 +30,6 @@ extern void swf_tag_action_print_detail(swf_tag_t *tag,
                                         int indent_depth);
 extern void swf_tag_action_destroy_detail(swf_tag_t *tag);
 
-extern int swf_tag_action_create_setvaribles(swf_tag_t *tag, y_keyvalue_t *kv);
-extern int swf_tag_action_put_setvaribles(swf_tag_t *tag, y_keyvalue_t *kv);
+extern int swf_tag_action_top_append_varibles(swf_tag_t *tag, y_keyvalue_t *kv);
 
 #endif /* __SWF_TAG_ACTION__H__ */