OSDN Git Service

add bitmap_id parameter into apply factor method.
[swfed/swfed.git] / src / swf_action.c
index 7f40b6f..c227456 100644 (file)
@@ -293,88 +293,198 @@ swf_action_list_print(swf_action_list_t *action_list, int indent_depth) {
 
 int
 swf_action_data_print(unsigned char *action_data, unsigned short action_data_len) {
-    unsigned char type = action_data[0] & 0xff;
+  unsigned char type;
     unsigned char *data = action_data+1;
     unsigned short data_len = action_data_len - 1;
-    int result = 1; // type field
-    switch (type) {
-    case 0x00: // String
-        printf("(String)%*s", data_len, data);
-        result += strlen((char*) data) + 1; // text + \0
-        break;
-    case 0x01: // Float
-        printf("(Float)XXX");
-        break;
-    case 0x02: // NULL
-        printf("(NULL)");
-        break;
-    case 0x03: // Undefined
-        printf("(Undefined)");
-        break;
-    case 0x04: // Register
-        printf("(Register)%d", (data[0]&0xff));
-        break;
-    case 0x05: // Boolean
-        printf("(Boolean)%s", (data[0]&0xff)?"true":"false");
-        result += 1;
-        break;
-    case 0x06: // Double
-        printf("(Double)%f", GetDoubleIEEE(data));
-        break;
-    case 0x07: // Integer
-        printf("(Integer)%ld", GetULongLE(data));
-        result += 4;
-        break;
-    case 0x08: // Dictionary Lookup
-        printf("(Dictionary Lookup)%d", data[0] & 0xff);
-        result += 1;
-        break;
-    case 0x09: // Large Dictionary Lookup
-        printf("(Large Dictionary Lookup)%d", GetUShortLE(data) & 0xffff);
-        result += 2;
-        break;
-    default:
-        printf("type=0x%02x len=%d", type, data_len);
-        break;
+    data = action_data;
+    while (data < action_data + action_data_len) {
+        type = data[0];
+       data += 1;
+       switch (type) {
+          case 0x00: // String
+           printf("(String)%s", data);
+           data += strlen((char*) data) + 1; // text + \0
+           break;
+          case 0x01: // Float
+           printf("(Float)%f", GetFloatIEEE(data));
+           data += 4;
+           break;
+          case 0x02: // NULL
+           printf("(NULL)");
+           break;
+          case 0x03: // Undefined
+           printf("(Undefined)");
+           break;
+          case 0x04: // Register
+           printf("(Register)%d", (data[0]&0xff));
+           data += 1;
+           break;
+          case 0x05: // Boolean
+           printf("(Boolean)%s", (data[0]&0xff)?"true":"false");
+           data += 1;
+           break;
+          case 0x06: // Double
+           printf("(Double)%f", GetDoubleIEEE(data));
+           data += 8;
+           break;
+          case 0x07: // Integer
+           printf("(Integer)%ld", GetULongLE(data));
+           data += 4;
+           break;
+          case 0x08: // Dictionary Lookup
+           printf("(Dictionary Lookup)%d", data[0] & 0xff);
+           data += 1;
+           break;
+          case 0x09: // Large Dictionary Lookup
+           printf("(Large Dictionary Lookup)%d", GetUShortLE(data) & 0xffff);
+           data += 2;
+           break;
+          default:
+           printf("type=0x%02x len=%d", type, data_len);
+           break;
+        }
     }
-    return result;
+    return 0;
 }
 
 int
-swf_action_list_replace_string(swf_action_list_t *action_list, y_keyvalue_t *kv) {
+swf_action_list_replace_strings(swf_action_list_t *action_list,
+                                int *modified, y_keyvalue_t *kv) {
     swf_action_t *action;
+    if (modified) {
+        *modified = 0;
+    }
     for (action=action_list->head ; action ; action=action->next) {
         if (action->action_id < 0x80) {
            continue; // skip (no string)
        }
        switch(action->action_id) {
-         unsigned char *action_data;
-         unsigned char type;
+         int type;
+          unsigned char *token;
+          int token_len;
+          bitstream_t *bs;
+          char *value;
+          int value_len;
+          int count;
+          int m = 0;
+          int i;
        case 0x83: // Get URL
-         // todo
+            m = 0;
+            bs = bitstream_open();
+            token = action->action_data;
+            token_len = strlen((char *) token);
+            value = y_keyvalue_get(kv, (char *)token, token_len, &value_len);
+            if (value) {
+                bitstream_putstring(bs, (unsigned char *) value, value_len);
+                bitstream_putbyte(bs, '\0');
+                m = 1;
+            } else {
+                bitstream_putstring(bs, (unsigned char *) token, token_len);
+                bitstream_putbyte(bs, '\0');
+            }
+            token +=  token_len + 1;
+            token_len = strlen((char *) token);
+            value = y_keyvalue_get(kv, (char *)token, token_len, &value_len);
+            if (value) {
+                bitstream_putstring(bs, (unsigned char *)value, value_len);
+                bitstream_putbyte(bs, '\0');
+                m = 1;
+            } else {
+                bitstream_putstring(bs, (unsigned char *)token, token_len);
+                bitstream_putbyte(bs, '\0');
+            }
+            if (m) {
+                unsigned long length;
+                free(action->action_data);
+                action->action_data = bitstream_steal(bs, &length);
+                action->action_length = length;
+                if (modified) {
+                    *modified = 1;
+                }
+            }
+            bitstream_close(bs);
            break;
        case 0x88: // ActionConstantPool
-         // todo
+            m = 0;
+            count = action->action_data[0] + 0x100 * action->action_data[1];
+            token = action->action_data + 2;
+            bs = bitstream_open();
+            bitstream_putbytesLE(bs, count, 2);
+            for (i = 0 ; i < count ; i++) {
+                token_len = strlen((char *) token);
+                value = y_keyvalue_get(kv, (char *)token, token_len, &value_len);
+                if (value) {
+                    bitstream_putstring(bs, (unsigned char *)value, value_len);
+                    bitstream_putbyte(bs, '\0');
+                    m = 1;
+                } else {
+                    bitstream_putstring(bs, (unsigned char *)token , token_len);
+                    bitstream_putbyte(bs, '\0');
+                }
+                token +=  token_len + 1;
+            }
+            if (m) {
+                unsigned long length;
+                free(action->action_data);
+                action->action_data = bitstream_steal(bs, &length);
+                action->action_length = length;
+                if (modified) {
+                    *modified = 1;
+                }
+            }
+            bitstream_close(bs);
            break;
        case 0x96: // Push Data
-           action_data = action->action_data;
-           type = action_data[0] & 0xff;
-           if (type == 0x00) { // Type: String 
-               unsigned char *data = action_data + 1;
-               int data_len = action->action_length - 2;
-               char *value;
-               int value_len;
-               value = y_keyvalue_get(kv, (char *)data, data_len, &value_len);
-               if (value) {
-                   action_data = malloc(1 + value_len + 1);
-                   action_data[0] = 0x00; // Type: String
-                   memcpy(action_data + 1, value, value_len);
-                   action_data[1 + value_len] = '\0';
-                   free(action->action_data);
-                   action->action_data = action_data;
-                   action->action_length = 1 + value_len + 1;
-               }
+            m = 0;
+            token = action->action_data;
+            bs = bitstream_open();
+           while (token < action->action_data + action->action_length) {
+             static const int action_value_type_size[] = {
+               -1, // 0: String
+               4,  // 1: Float
+               0,  // 2: NULL
+               0,  // 3: Undefined
+               1,  // 4: Register
+               1,  // 5: Boolean
+               8,  // 6: Double
+               4,  // 7: Integer
+               1,  // 8: Dictionary Lookup
+               2,  // 9: Large Dictionary Lookup
+             };
+             type = token[0];
+             bitstream_putbyte(bs, type);
+             token += 1;
+             if (type == 0) { // String
+                token_len = strlen((char *) token);
+                value = y_keyvalue_get(kv, (char *)token, token_len, &value_len);
+                if (value) {
+                    bitstream_putstring(bs, (unsigned char *)value, value_len);
+                    bitstream_putbyte(bs, '\0');
+                    m = 1;
+                } else {
+                    bitstream_putstring(bs, (unsigned char *)token , token_len);
+                    bitstream_putbyte(bs, '\0');
+                }
+                token +=  token_len + 1;
+             } else if (type < 10) { // else String
+               bitstream_putstring(bs, token, action_value_type_size[type]);
+               token += action_value_type_size[type];
+             } else {
+               fprintf(stderr, "swf_action_list_replace_strings: illegal type=%d\n", type);
+               bitstream_close(bs);
+               return 1; // FAILURE
+             }
            }
+            if (m) {
+                unsigned long length;
+                free(action->action_data);
+                action->action_data = bitstream_steal(bs, &length);
+                action->action_length = length;
+                if (modified) {
+                    *modified = 1;
+                }
+            }
+            bitstream_close(bs);
            break;
        }
     }