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
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;
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;
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);
}
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;
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);
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
}
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) {
}
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 {
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) {
}
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;
+}
#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;
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);
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__ */
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");
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
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;
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;
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
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;
}
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;
}
} 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;
}
} 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);
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 ;
}
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;
}
}
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;
}
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);
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__ */