/// <summary> /// convert <see cref="SwfOp.ByteCode.Actions.ActionPushList">push list</see> to sequence of single <see cref="SwfOp.ByteCode.Actions.ActionPush" >push</see> actions /// </summary> private void ExplodePushLists(ArrayList actionRecord) { for (int i = 0; i < actionRecord.Count; i++) { BaseAction a = (BaseAction)actionRecord[i]; // check if action is multiple push ActionPushList pl = actionRecord[i] as ActionPushList; if (pl != null) { // resolve pushs to single push actions for (int j = 0; j < pl.Length; j++) { ActionPush p = pl[j]; actionRecord.Insert(i + 1 + j, p); } actionRecord.RemoveAt(i); } // process inner actionblocks if (a as ActionDefineFunction != null) { ActionDefineFunction f = (ActionDefineFunction)a; ExplodePushLists(f.ActionRecord); } if (a as ActionDefineFunction2 != null) { ActionDefineFunction2 f = (ActionDefineFunction2)a; ExplodePushLists(f.ActionRecord); } } }
/// <summary> /// Collaps sequence of single push actions into one multiple-push action /// </summary> private void CollapsPushActions(ArrayList actionRecord) { int i = 0; bool isPush; while (i < (actionRecord.Count - 1)) { isPush = actionRecord[i] is ActionPush; if (isPush) { int j = i; int count = 1; do { i++; if (i < actionRecord.Count) { isPush = (actionRecord[i] is ActionPush); if (isPush) { count++; } } } while ((isPush) && (i < actionRecord.Count)); if (count > 1) { ActionPush[] pushList = new ActionPush[count]; actionRecord.CopyTo(j, pushList, 0, count); actionRecord.RemoveRange(j, count); ActionPushList pl = new ActionPushList(pushList); actionRecord.Insert(j, pl); i = j + 1; } } else { // recursively step through functions inner actions ActionDefineFunction f = actionRecord[i] as ActionDefineFunction; if (f != null) { CollapsPushActions(f.ActionRecord); } // and function2 of course ActionDefineFunction2 f2 = actionRecord[i] as ActionDefineFunction2; if (f2 != null) { CollapsPushActions(f2.ActionRecord); } i++; } } }
/// <summary> /// Read multiply push action action as <see cref="SwfOp.ByteCode.Actions.ActionPushList">ActionPushList</see> from swf. /// </summary> private ActionPushList ReadActionPush(BinaryReader br) { // read block length int len = Convert.ToInt32(br.ReadUInt16()); int i = 0; ArrayList pushList = new ArrayList(); while (i < len) { int pushType = Convert.ToInt32(br.ReadByte()); i++; object val = new object(); switch (pushType) { case 0: string str = BinaryStringRW.ReadString(br); i += str.Length + 1; val = str; break; case 1: val = (object)br.ReadSingle(); i += 4; break; case 2: val = null; break; case 3: val = null; break; case 4: val = (object)Convert.ToInt32(br.ReadByte()); i++; break; case 5: val = (object )br.ReadBoolean(); i++; break; case 6: byte[] b0 = br.ReadBytes(4); byte[] b1 = br.ReadBytes(4); byte[] b = new byte[8]; b0.CopyTo(b, 4); b1.CopyTo(b, 0); val = (object)BitConverter.ToDouble(b, 0); i += 8; break; case 7: val = (object)br.ReadInt32(); i += 4; break; case 8: val = (object)Convert.ToInt32(br.ReadByte()); i++; break; case 9: val = (object)Convert.ToInt32(br.ReadUInt16()); i += 2; break; } ActionPush p = new ActionPush(pushType, val); pushList.Add(p); } ActionPush[] pList = new ActionPush[pushList.Count]; pushList.CopyTo(pList, 0); ActionPushList a = new ActionPushList(pList); //a.ByteSize = len+3; return(a); }