CVSROOT: /sources/gnash Module name: gnash Changes by: Chad Musick <cmusick> 07/09/21 13:40:32
Modified files: . : ChangeLog libbase : tu_file.h server : impl.cpp stream.cpp stream.h server/parser : Makefile.am abc_block.cpp abc_block.h server/swf : tag_loaders.cpp tag_loaders.h Log message: Fully parse AS3 blocks of code. (Doesn't yet verify the code or populate symbol tables.) CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4369&r2=1.4370 http://cvs.savannah.gnu.org/viewcvs/gnash/libbase/tu_file.h?cvsroot=gnash&r1=1.16&r2=1.17 http://cvs.savannah.gnu.org/viewcvs/gnash/server/impl.cpp?cvsroot=gnash&r1=1.120&r2=1.121 http://cvs.savannah.gnu.org/viewcvs/gnash/server/stream.cpp?cvsroot=gnash&r1=1.31&r2=1.32 http://cvs.savannah.gnu.org/viewcvs/gnash/server/stream.h?cvsroot=gnash&r1=1.29&r2=1.30 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/Makefile.am?cvsroot=gnash&r1=1.37&r2=1.38 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/abc_block.cpp?cvsroot=gnash&r1=1.1&r2=1.2 http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/abc_block.h?cvsroot=gnash&r1=1.1&r2=1.2 http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.cpp?cvsroot=gnash&r1=1.139&r2=1.140 http://cvs.savannah.gnu.org/viewcvs/gnash/server/swf/tag_loaders.h?cvsroot=gnash&r1=1.21&r2=1.22 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.4369 retrieving revision 1.4370 diff -u -b -r1.4369 -r1.4370 --- ChangeLog 21 Sep 2007 12:12:32 -0000 1.4369 +++ ChangeLog 21 Sep 2007 13:40:31 -0000 1.4370 @@ -1,3 +1,12 @@ +2007-09-21 Chad Musick <[EMAIL PROTECTED]> + + * libbase/tu_file.h: Add support for reading 64-bit doubles. + * server/impl.cpp: Add abc_loader to list of loaders. + * server/stream.cpp,.h: Support necessary read types for AS3. + * server/parser/Makefile.am: Add new files + * server/parser/abc_block.cpp,.h: Changes to parse AS3. + * server/swf/tag_loaders.cpp,.h: Loader for action block (AS3) + 2007-09-21 Sandro Santilli <[EMAIL PROTECTED]> * server/dlist.h (testInvariant): fix a cast discarding const Index: libbase/tu_file.h =================================================================== RCS file: /sources/gnash/gnash/libbase/tu_file.h,v retrieving revision 1.16 retrieving revision 1.17 diff -u -b -r1.16 -r1.17 --- libbase/tu_file.h 14 May 2007 21:39:48 -0000 1.16 +++ libbase/tu_file.h 21 Sep 2007 13:40:31 -0000 1.17 @@ -119,6 +119,19 @@ return(result); } + /// \brief Read a 64-bit word from a little-ending stream, + /// returning it as a native-endian word. + // + /// TODO: define what happens when the stream is in + /// error condition, see get_error(). + /// TODO: define a platform-neutral type for 64 bits. + long double read_le_double64() { + return static_cast<long double> ( + static_cast<int64_t> (read_le32()) | + static_cast<int64_t> (read_le32()) << 32 + ); + } + /// \brief Read a 16-bit word from a little-endian stream. // /// TODO: define what happens when the stream Index: server/impl.cpp =================================================================== RCS file: /sources/gnash/gnash/server/impl.cpp,v retrieving revision 1.120 retrieving revision 1.121 diff -u -b -r1.120 -r1.121 --- server/impl.cpp 19 Sep 2007 14:20:49 -0000 1.120 +++ server/impl.cpp 21 Sep 2007 13:40:31 -0000 1.121 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: impl.cpp,v 1.120 2007/09/19 14:20:49 cmusick Exp $ */ +/* $Id: impl.cpp,v 1.121 2007/09/21 13:40:31 cmusick Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -251,7 +251,7 @@ register_tag_loader(SWF::PLACEOBJECT3, PlaceObject2Tag::loader); // 70 register_tag_loader(SWF::IMPORTASSETS2, import_loader); // 71 - register_tag_loader(SWF::DOABC, fixme_loader); // 72 -- AS3 codeblock. + register_tag_loader(SWF::DOABC, abc_loader); // 72 -- AS3 codeblock. register_tag_loader(SWF::DEFINEALIGNZONES, DefineFontAlignZonesTag::loader); // 73 register_tag_loader(SWF::CSMTEXTSETTINGS, fixme_loader); // 74 @@ -259,7 +259,7 @@ register_tag_loader(SWF::SYMBOLCLASS, fixme_loader); // 76 register_tag_loader(SWF::METADATA, metadata_loader); // 77 register_tag_loader(SWF::DEFINESCALINGGRID, fixme_loader); // 78 - register_tag_loader(SWF::DOABCDEFINE, fixme_loader); // 79 -- AS3 codeblock. + register_tag_loader(SWF::DOABCDEFINE, abc_loader); // 82 -- AS3 codeblock. register_tag_loader(SWF::DEFINESHAPE4, define_shape_loader); // 83 register_tag_loader(SWF::DEFINEMORPHSHAPE2, define_shape_morph_loader); // 84 Index: server/stream.cpp =================================================================== RCS file: /sources/gnash/gnash/server/stream.cpp,v retrieving revision 1.31 retrieving revision 1.32 diff -u -b -r1.31 -r1.32 --- server/stream.cpp 27 Aug 2007 18:52:58 -0000 1.31 +++ server/stream.cpp 21 Sep 2007 13:40:31 -0000 1.32 @@ -254,6 +254,13 @@ return static_cast<float> (m_input->read_le32()); } + // Read a 64-bit double value + long double stream::read_d64() + { + align(); + return m_input->read_le_double64(); + } + uint8_t stream::read_u8() { align(); return m_input->read_byte(); } int8_t stream::read_s8() { align(); return m_input->read_byte(); } uint16_t stream::read_u16() Index: server/stream.h =================================================================== RCS file: /sources/gnash/gnash/server/stream.h,v retrieving revision 1.29 retrieving revision 1.30 diff -u -b -r1.29 -r1.30 --- server/stream.h 28 Aug 2007 13:12:38 -0000 1.29 +++ server/stream.h 21 Sep 2007 13:40:32 -0000 1.30 @@ -72,6 +72,10 @@ float read_float(); /// \brief + /// Read 64-bit double values. + long double read_d64(); + + /// \brief /// Discard any left-over bits from previous bit reads void align() { @@ -109,6 +113,44 @@ int32_t read_s32(); /// \brief + /// Read a variable length unsigned 32-bit value from the stream. + /// These values continue until either the high bit is not set or + /// until 5 bytes have been read. + uint32_t read_V32() + { + uint32_t res = read_u8(); + if (!(res & 0x00000080)) + return res; + res = (res & 0x0000007F) | read_u8() << 7; + if (!(res & 0x00004000)) + return res; + res = (res & 0x00003FFF) | read_u8() << 14; + if (!(res & 0x00200000)) + return res; + res = (res & 0x001FFFFF) | read_u8() << 21; + if (!(res & 0x10000000)) + return res; + res = (res & 0x0FFFFFFF) | read_u8() << 28; + return res; + } + + /// \brief + /// Skip a variable length unsigned 32-bit value in the stream. + /// This is faster than doing the bitwise arithmetic of full reading. + void skip_V32() + { + if (!(read_u8() & 0x80)) + return; + if (!(read_u8() & 0x80)) + return; + if (!(read_u8() & 0x80)) + return; + if (!(read_u8() & 0x80)) + return; + static_cast<void> (read_u8()); + } + + /// \brief /// Read a length in a byte or three. // /// If the byte == 0xff, read the lenght in Index: server/parser/Makefile.am =================================================================== RCS file: /sources/gnash/gnash/server/parser/Makefile.am,v retrieving revision 1.37 retrieving revision 1.38 diff -u -b -r1.37 -r1.38 --- server/parser/Makefile.am 1 Jul 2007 10:54:33 -0000 1.37 +++ server/parser/Makefile.am 21 Sep 2007 13:40:32 -0000 1.38 @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# $Id: Makefile.am,v 1.37 2007/07/01 10:54:33 bjacques Exp $ +# $Id: Makefile.am,v 1.38 2007/09/21 13:40:32 cmusick Exp $ AUTOMAKE_OPTIONS = @@ -45,6 +45,7 @@ $(NULL) libgnashparser_la_SOURCES = \ + abc_block.cpp \ action_buffer.cpp \ bitmap_character_def.cpp \ BitmapMovieDefinition.cpp \ @@ -61,6 +62,7 @@ noinst_HEADERS = \ Timeline.h \ + abc_block.h \ action_buffer.h \ button_character_def.h \ character_def.h \ @@ -71,6 +73,7 @@ morph2_character_def.h \ movie_definition.h \ movie_def_impl.h \ + Namespace.h \ shape_character_def.h \ sound_definition.h \ sprite_definition.h \ Index: server/parser/abc_block.cpp =================================================================== RCS file: /sources/gnash/gnash/server/parser/abc_block.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -u -b -r1.1 -r1.2 --- server/parser/abc_block.cpp 20 Sep 2007 17:07:21 -0000 1.1 +++ server/parser/abc_block.cpp 21 Sep 2007 13:40:32 -0000 1.2 @@ -20,6 +20,10 @@ #include "abc_block.h" #include "stream.h" +#include "VM.h" +#include "log.h" + +#define ERR(x) IF_VERBOSE_MALFORMED_SWF(log_swferror x;); namespace gnash { @@ -41,7 +45,10 @@ mSlotId = in->read_V32(); mTypeIndex = in->read_V32(); mValueIndex = in->read_V32(); + if (mValueIndex) mValueIndexTypeIndex = in->read_u8(); + else + mValueIndexTypeIndex = 0; break; } case KIND_METHOD: @@ -68,6 +75,7 @@ } default: { + ERR((_("Action Block: Unknown trait kind (%d).\n"), mKind)); return false; } } // end of switch @@ -95,24 +103,27 @@ std::vector<abc_Trait> traitVec; - // Minor version. - static_cast<void>(in->read_u16()); - // Major version. - static_cast<void>(in->read_u16()); + // Minor version, major version. + uint32_t version = (in->read_u16()) | (in->read_u16() << 16); + ERR((_("Abc Version: %d.%d\n"), (version & 0xFFFF0000) >> 16, (version & 0x0000FFFF))); // A block of signed integers. Count overshoots by 1, // and the 0 is used to signal a no-op. uint32_t intPoolCount = in->read_V32(); mIntegerPool.resize(intPoolCount); + if (intPoolCount) + mIntegerPool[0] = 0; for (unsigned int i = 1; i < intPoolCount; ++i) { - mIntegerPool[i] = in->read_s32(); + mIntegerPool[i] = static_cast<int32_t> (in->read_V32()); } // A block of unsigned integers. Count overshoots by 1, // and the 0 is used to signal a no-op. uint32_t uIntPoolCount = in->read_V32(); mUIntegerPool.resize(uIntPoolCount); + if (uIntPoolCount) + mUIntegerPool[0] = 0; for (unsigned int i = 1; i < uIntPoolCount; ++i) { mUIntegerPool[i] = in->read_V32(); @@ -122,6 +133,8 @@ // and the 0 is used to signal a no-op. uint32_t doublePoolCount = in->read_V32(); mDoublePool.resize(doublePoolCount); + if (doublePoolCount) + mDoublePool[0] = 0.0; for (unsigned int i = 1; i < doublePoolCount; ++i) { mDoublePool[i] = in->read_d64(); @@ -131,24 +144,28 @@ // entry used to signal a no-op. uint32_t stringPoolCount = in->read_V32(); mStringPool.resize(stringPoolCount); + mStringPoolTableIds.resize(stringPoolCount); + if (stringPoolCount) + { + mStringPool[0] = ""; + mStringPoolTableIds[0] = 0; + } for (unsigned int i = 1; i < stringPoolCount; ++i) { uint32_t length = in->read_V32(); in->read_string_with_length(length, mStringPool[i]); - } - - // Many of the strings will correspond to string table entries -- - // fill this up as we find these. - mStringPoolTableIds.resize(stringPoolCount); - for (unsigned int i = 0; i < stringPoolCount; ++i) mStringPoolTableIds[i] = 0; + } // These are namespaces, individually. The counter overshoots by // 1, with the 0th entry used to signal a wildcard. uint32_t namespacePoolCount = in->read_V32(); mNamespacePool.resize(namespacePoolCount); + if (namespacePoolCount) + { mNamespacePool[0].mUri = mNamespacePool[0].mPrefix = 0; mNamespacePool[0].mKind = Namespace::KIND_NORMAL; + } for (unsigned int i = 1; i < namespacePoolCount; ++i) { uint8_t kind = in->read_u8(); @@ -169,8 +186,12 @@ // And reset the nameIndex for the uri. nameIndex = mStringPoolTableIds[nameIndex]; } - else - nameIndex = 0; + else if (nameIndex >= mStringPool.size()) + { + ERR((_("Action Block: Out of Bound string for namespace.\n"))); + return false; + } + // And set the name in the Namespace itself. mNamespacePool[i].mUri = nameIndex; // The prefix is unknown right now. @@ -180,8 +201,11 @@ // These are sets of namespaces, which use the individual ones above. uint32_t namespaceSetPoolCount = in->read_V32(); mNamespaceSetPool.resize(namespaceSetPoolCount); + if (namespaceSetPoolCount) + { // The base namespace set is empty. mNamespaceSetPool[0].resize(0); + } for (unsigned int i = 1; i < namespaceSetPoolCount; ++i) { // These counts are not inflated the way the others are. @@ -193,6 +217,7 @@ if (!selection || selection >= namespacePoolCount) { // Reached a bad selection. + ERR((_("Action Block: Out of Bound namespace in namespace set.\n"))); return false; } mNamespaceSetPool[i][j] = &mNamespacePool[selection]; @@ -202,8 +227,9 @@ // A list of the multinames. The counter overestimates by 1, and the // 0th is used as a no-op. uint32_t multinamePoolCount = in->read_V32(); + mMultinamePool.resize(multinamePoolCount); - for (unsigned int i = 0; i < multinamePoolCount; ++i) + for (unsigned int i = 1; i < multinamePoolCount; ++i) { uint8_t kind = in->read_u8(); mMultinamePool[i].mKind = static_cast<abc_Multiname::kinds>(kind); @@ -239,7 +265,10 @@ nsset = in->read_V32(); // 0 is not a valid nsset. if (!nsset) + { + ERR((_("Action Block: 0 selection for namespace set is invalid.\n"))); return false; + } break; } case abc_Multiname::KIND_MultinameL: @@ -248,22 +277,35 @@ nsset = in->read_V32(); // 0 is not a valid nsset. if (!nsset) + { + ERR((_("Action Block: 0 selection for namespace set is invalid.\n"))); return false; + } break; } default: { // Unknown type. + ERR((_("Action Block: Unknown multiname type (%d).\n"), kind)); return false; } // End of cases. } // End of switch. if (name >= mStringPool.size()) + { + ERR((_("Action Block: Out of Bound string for Multiname.\n"))); return false; // Bad name. + } if (ns >= mNamespacePool.size()) + { + ERR((_("Action Block: Out of Bound namespace for Multiname.\n"))); return false; // Bad namespace. + } if (nsset >= mNamespaceSetPool.size()) + { + ERR((_("Action Block: Out of Bound namespace set for Multiname.\n"))); return false; // Bad namespace set. + } // The name should be in the string table. if (name && mStringPoolTableIds[name] == 0) @@ -289,7 +331,11 @@ uint32_t return_type = in->read_V32(); if (return_type >= mMultinamePool.size()) + { + ERR((_("Action Block: Out of Bound return type for " + "method info (%d).\n"), return_type)); return false; + } method.mReturnType = &mMultinamePool[return_type]; @@ -299,7 +345,11 @@ // The parameter type. uint32_t ptype = in->read_V32(); if (ptype >= mMultinamePool.size()) + { + ERR((_("Action Block: Out of Bound parameter type " + "for method info (%d).\n"), ptype)); return false; + } method.mParameters[j] = &mMultinamePool[ptype]; } // We ignore the name_index @@ -334,15 +384,19 @@ } // End of method loop. // Following is MetaData, which we will ignore. - in->skip_V32(); // A name index. uint32_t metaCount = in->read_V32(); for (unsigned int i = 0; i < metaCount; ++i) { + in->skip_V32(); // A name index. + uint32_t metaInternalCount = in->read_V32(); + for (unsigned int j = 0; j < metaInternalCount; ++j) + { // key and values are _not_ in this order (they group together), but // we are just skipping anyway. in->skip_V32(); in->skip_V32(); } + } // Classes count. uint32_t classCount = in->read_V32(); @@ -354,15 +408,22 @@ { abc_Instance& instance = mInstances[i]; uint32_t index = in->read_V32(); - if (!index || index >= mMultinamePool.size()) + // 0 is allowed as a name, typically for the last entry. + if (index >= mMultinamePool.size()) + { + ERR((_("Action Block: Out of Bound instance name (%d).\n"), index)); return false; // Name out of bounds. + } instance.mName = &mMultinamePool[index]; uint32_t super_index = in->read_V32(); if (!super_index) instance.mSuperType = NULL; else if (super_index >= mMultinamePool.size()) + { + ERR((_("Action Block: Out of Bound super type (%d).\n"), index)); return false; // Bad index. + } else instance.mSuperType = &mMultinamePool[super_index]; @@ -374,7 +435,11 @@ { uint32_t ns_index = in->read_V32(); if (ns_index >= mNamespacePool.size()) + { + ERR((_("Action Block: Out of Bound namespace for " + "instance protected namespace (%d).\n"), ns_index)); return false; + } if (ns_index) instance.mProtectedNamespace = &mNamespacePool[ns_index]; } @@ -385,15 +450,24 @@ for (unsigned int j = 0; j < interfaceCount; ++j) { uint32_t i_index = in->read_V32(); - if (!i_index || i_index >= mMultinamePool.size()) + // 0 is allowed as an interface, typically for the last one. + if (i_index >= mMultinamePool.size()) + { + ERR((_("Action Block: Out of Bound name for interface. " + "(%d)\n"), i_index)); return false; // Bad read. + } instance.mInterfaces[j] = &mMultinamePool[i_index]; } // Reach into the methods list. uint32_t methodsOffset = in->read_V32(); if (methodsOffset >= mMethods.size()) + { + ERR((_("Action Block: Out of Bound method for interface. (%d)\n"), + methodsOffset)); return false; // Bad method. + } instance.mMethod = &mMethods[methodsOffset]; // Now parse the traits. @@ -402,19 +476,30 @@ instance.mTraits.resize(traitsCount); for (unsigned int j = 0; j < traitsCount; ++j) { - instance.mTraits[j].read(in); + if (!instance.mTraits[j].read(in)) + return false; } } // end of instances list // Now the classes are read. TODO: Discover what these do. for (unsigned int i = 0; i < classCount; ++i) { - uint32_t initial_method_offset = in->read_V32(); + abc_Class& cClass = mClasses[i]; + uint32_t method_offset = in->read_V32(); + if (method_offset >= mMethods.size()) + { + ERR((_("Action Block: Out of Bound method for class (%d).\n"), + method_offset)); + return false; + } + cClass.mMethod = &mMethods[method_offset]; + uint32_t traitsCount = in->read_V32(); - traitVec.resize(traitsCount); + cClass.mTraits.resize(traitsCount); for (unsigned int j = 0; j < traitsCount; ++j) { - traitVec[j].read(in); + if (!cClass.mTraits[j].read(in)) + return false; } } // end of classes list @@ -423,20 +508,41 @@ mScripts.resize(scriptCount); for (unsigned int i = 0; i < scriptCount; ++i) { - uint32_t initial_method_offset = in->read_V32(); + abc_Script& script = mScripts[i]; + uint32_t method_offset = in->read_V32(); + if (method_offset >= mMethods.size()) + { + ERR((_("Action Block: Out of Bound method for script (%d).\n"), + method_offset)); + return false; + } + script.mMethod = &mMethods[method_offset]; + uint32_t traitsCount = in->read_V32(); - traitVec.resize(traitsCount); + script.mTraits.resize(traitsCount); for (unsigned int j = 0; j < traitsCount; ++j) { - traitVec[j].read(in); + if (!script.mTraits[j].read(in)) + return false; } } // The method bodies. TODO: Use these. uint32_t methodBodyCount = in->read_V32(); + mBodies.resize(methodBodyCount); for (unsigned int i = 0; i < methodBodyCount; ++i) { + abc_MethodBody& method = mBodies[i]; + uint32_t method_info = in->read_V32(); + if (method_info >= mMethods.size()) + { + ERR((_("Action Block: Out of Bound method for method body. " + "(%d)\n"), method_info)); + return false; // Too big. + } + method.mMethod = &mMethods[method_info]; + // We don't care about the maximum stack size. Discard it. in->skip_V32(); // We don't care about the maximum register size. Discard it. @@ -448,31 +554,72 @@ // How long is the code? uint32_t code_length = in->read_V32(); // And the code: + method.mCode.resize(code_length); + unsigned int got_length; + if ((got_length = in->read(method.mCode.data(), code_length)) != code_length) + { + ERR((_("Action Block: Not enough body. Wanted %d but got %d.\n"), + code_length, got_length)); + return false; // Not enough bytes. + } + // TODO: Grab code_length bytes for the code. uint32_t exceptions_count = in->read_V32(); + method.mExceptions.resize(exceptions_count); for (unsigned int j = 0; j < exceptions_count; ++j) { - // Where the try block ? begins and ends. - uint32_t start_offset = in->read_V32(); - uint32_t end_offset = in->read_V32(); - // Where the catch block is located. - uint32_t catch_offset = in->read_V32(); + abc_Exception& exceptor = method.mExceptions[j]; + + // Where the try block begins and ends. + exceptor.mStart = in->read_V32(); + exceptor.mEnd = in->read_V32(); + + // Where to go if this exception is activated. + exceptor.mCatch = in->read_V32(); + // What types should be caught. uint32_t catch_type = in->read_V32(); + if (catch_type >= mMultinamePool.size()) + { + ERR((_("Action Block: Out of Bound type for exception " + "(%d).\n"), catch_type)); + return false; // Bad type. + } + exceptor.mType = catch_type ? &mMultinamePool[catch_type] : NULL; + // If caught, what is the variable name. - uint32_t catch_var_name = in->read_V32(); + if (version != (46 << 16) | 15) // In version 46.15, no names. + { + uint32_t cvn = in->read_V32(); + if (cvn >= mMultinamePool.size()) + { + ERR((_("Action Block: Out of Bound name for caught " + "exception. (%d)\n"), cvn)); + return false; // Bad name + } + exceptor.mName = cvn ? &mMultinamePool[cvn] : NULL; } + else + exceptor.mName = NULL; + } // End of exceptions + uint32_t traitsCount = in->read_V32(); - traitVec.resize(traitsCount); + method.mTraits.resize(traitsCount); for (unsigned int j = 0; j < traitsCount; ++j) { - traitVec[j].read(in); - } + if (!method.mTraits[j].read(in)) + return false; } + } // End of method bodies // If flow reaches here, everything went fine. return true; } +abc_block::abc_block() : mStringTable(&VM::get().getStringTable()) +{ + /**/ +} + }; /* namespace gnash */ Index: server/parser/abc_block.h =================================================================== RCS file: /sources/gnash/gnash/server/parser/abc_block.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -b -r1.1 -r1.2 --- server/parser/abc_block.h 20 Sep 2007 17:07:21 -0000 1.1 +++ server/parser/abc_block.h 21 Sep 2007 13:40:32 -0000 1.2 @@ -23,11 +23,11 @@ #include <vector> #include <string> +#include <boost/scoped_array.hpp> #include "gnash.h" #include "stream.h" #include "string_table.h" - #include "Namespace.h" namespace gnash { @@ -89,7 +89,6 @@ std::vector<abc_Multiname*> mParameters; // The types, not the names. uint8_t mFlags; std::vector<optional_parameter> mOptionalParameters; - }; class abc_Instance @@ -141,6 +140,39 @@ bool read(stream* in); }; +class abc_Class +{ +public: + abc_Method *mMethod; + std::vector<abc_Trait> mTraits; +}; + +class abc_Script +{ +public: + abc_Method *mMethod; + std::vector<abc_Trait> mTraits; +}; + +class abc_Exception +{ +public: + uint32_t mStart; + uint32_t mEnd; + uint32_t mCatch; + abc_Multiname* mType; + abc_Multiname* mName; +}; + +class abc_MethodBody +{ +public: + abc_Method *mMethod; + std::vector<abc_Exception> mExceptions; + std::vector<abc_Trait> mTraits; + std::vector<char> mCode; +}; + }; // namespace abc_parsing typedef std::vector<Namespace*> NamespaceSet; @@ -158,17 +190,16 @@ std::vector<abc_parsing::abc_Method> mMethods; std::vector<abc_parsing::abc_Multiname> mMultinamePool; std::vector<abc_parsing::abc_Instance> mInstances; - std::vector<uint32_t> mClasses; // TODO: Fix this. - std::vector<uint32_t> mScripts; // TODO: Fix this. - std::vector<uint32_t> mBodies; // TODO: Fix this. + std::vector<abc_parsing::abc_Class> mClasses; + std::vector<abc_parsing::abc_Script> mScripts; + std::vector<abc_parsing::abc_MethodBody> mBodies; string_table* mStringTable; public: - int32_t poolInteger(uint32_t index) const; - uint32_t poolUInteger(uint32_t index) const; - bool read(stream* in); + + abc_block(); }; }; /* namespace gnash */ Index: server/swf/tag_loaders.cpp =================================================================== RCS file: /sources/gnash/gnash/server/swf/tag_loaders.cpp,v retrieving revision 1.139 retrieving revision 1.140 diff -u -b -r1.139 -r1.140 --- server/swf/tag_loaders.cpp 17 Sep 2007 14:38:34 -0000 1.139 +++ server/swf/tag_loaders.cpp 21 Sep 2007 13:40:32 -0000 1.140 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: tag_loaders.cpp,v 1.139 2007/09/17 14:38:34 strk Exp $ */ +/* $Id: tag_loaders.cpp,v 1.140 2007/09/21 13:40:32 cmusick Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -54,6 +54,7 @@ #include "GnashException.h" #include "video_stream_def.h" #include "sound_definition.h" +#include "abc_block.h" #ifdef HAVE_ZLIB_H #include <zlib.h> @@ -1953,6 +1954,30 @@ } +void +abc_loader(stream* in, tag_type tag, movie_definition* /*m*/) +{ + assert(tag == SWF::DOABC + || tag == SWF::DOABCDEFINE); // 72 or 82 + + abc_block a; + + if (tag == SWF::DOABCDEFINE) + { + // Skip the 'flags' until they are actually used. + static_cast<void> (in->read_u32()); + std::string name = in->read_string(); + name.c_str(); + } + + bool success = a.read(in); + if (success) + { + /* TODO: Run the script if needed. */ + } + + log_unimpl(_("Action Block tags are parsed but not yet used")); +} } // namespace gnash::SWF::tag_loaders } // namespace gnash::SWF Index: server/swf/tag_loaders.h =================================================================== RCS file: /sources/gnash/gnash/server/swf/tag_loaders.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -b -r1.21 -r1.22 --- server/swf/tag_loaders.h 22 Aug 2007 13:09:10 -0000 1.21 +++ server/swf/tag_loaders.h 21 Sep 2007 13:40:32 -0000 1.22 @@ -19,7 +19,7 @@ // // -/* $Id: tag_loaders.h,v 1.21 2007/08/22 13:09:10 cmusick Exp $ */ +/* $Id: tag_loaders.h,v 1.22 2007/09/21 13:40:32 cmusick Exp $ */ #ifndef GNASH_SWF_TAG_LOADERS_H #define GNASH_SWF_TAG_LOADERS_H @@ -142,6 +142,8 @@ /// Load a SWF::SOUNDSTREAMBLOCK tag. void sound_stream_block_loader(stream*, tag_type, movie_definition*); +void abc_loader(stream*, tag_type, movie_definition*); + void define_video_loader(stream* in, tag_type tag, movie_definition* m); _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit