amf.h

Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
00003 // 
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017 
00018 #ifndef _AMF_H_
00019 #define _AMF_H_
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "gnashconfig.h"
00023 #endif
00024 
00025 #include <vector>
00026 #include <string>
00027 #include <cstring>
00028 #include <map>
00029 
00030 #include "element.h"
00031 #include "amfutf8.h"
00032 #include <boost/cstdint.hpp>
00033 
00034 namespace amf 
00035 {
00036 
00037 const char AMF_NUMBER_SIZE = 0x08;
00038 
00039 typedef enum {
00040     CLIENT,                     // Flash player
00041     SERVER                      // Flash com server
00042 } amfsource_e;
00043 
00044 const char AMF_VERSION = 0;
00045 const int  AMF_HEADSIZE_MASK = 0xc0;
00046 const char AMF_HEADER_SIZE = 0x03;
00047 const char AMF_INDEX_MASK = 0x3f;
00048 const int  AMF_VIDEO_PACKET_SIZE = 128;
00049 const int  AMF_AUDIO_PACKET_SIZE = 64;
00050 // This is the sized used when reading from the network to
00051 // be the most efficient
00052 const int  AMF_PACKET_SIZE = 7096;
00053 
00054 // For terminating sequences, a byte with value 0x09 is used.
00055 const char TERMINATOR = 0x09;
00056 
00057 // Each packet consists of the following:
00058 //
00059 // The first byte of the AMF file/stream is believed to be a version
00060 // indicator. So far the only valid value for this field that has been
00061 // found is 0x00. If it is anything other than 0x00 (zero), your
00062 // system should consider the AMF file/stream to be
00063 // 'malformed'd. This can happen in the IDE if AMF calls are put
00064 // on the stack but never executed and the user exits the movie from the
00065 // IDE; the two top bytes will be random and the number of headers will
00066 // be unreliable.
00067 
00068 // The second byte of the AMF file/stream is appears to be 0x00 if the
00069 // client is the Flash Player and 0x01 if the client is the FlashCom
00070 // server. 
00071 
00072 // The third and fourth bytes form an integer value that specifies the
00073 // number of headers. 
00074 typedef struct {
00075     boost::uint8_t version;
00076     boost::uint8_t source;
00077     boost::uint32_t  count;
00078 } amfpacket_t;
00079 
00080 typedef enum {
00081     onStatus,
00082     onResult,
00083     onDebugEvents
00084 } amfresponse_e;
00085 
00086 class AMF {
00087 public:
00088     typedef enum {
00089         HEADER_12 = 0x0,
00090         HEADER_8  = 0x40,
00091         HEADER_4  = 0x80,
00092         HEADER_1  = 0xc0
00093     } amf_headersize_e;    
00094     
00095 //     typedef enum {
00096 //         Byte,
00097 //         Int,
00098 //         MediumInt,
00099 //         Long,
00100 //         Double,
00101 //         UTF8,
00102 //         LongUTF8
00103 //     } amftype_e;
00104     typedef enum {
00105         NONE = 0x0,
00106         CHUNK_SIZE = 0x1,
00107         UNKNOWN = 0x2,
00108         BYTES_READ = 0x3,
00109         PING = 0x4,
00110         SERVER = 0x5,
00111         CLIENT = 0x6,
00112         UNKNOWN2 = 0x7,
00113         AUDIO_DATA = 0x8,
00114         VIDEO_DATA = 0x9,
00115         UNKNOWN3 = 0xa,
00116         NOTIFY = 0x12,
00117         SHARED_OBJ = 0x13,
00118         INVOKE = 0x14
00119     } content_types_e;
00120     typedef enum {
00121         CONNECT = 0x01,
00122         DISCONNECT = 0x02,
00123         SET_ATTRIBUTE = 0x03,
00124         UPDATE_DATA = 0x04,
00125         UPDATE_ATTRIBUTE = 0x05,
00126         SEND_MESSAGE = 0x06,
00127         STATUS = 0x07,
00128         CLEAR_DATA = 0x08,
00129         DELETE_DATA = 0x09,
00130         DELETE_ATTRIBYTE = 0x0a,
00131         INITIAL_DATA = 0x0b
00132     } shared_obj_types_e;
00133 
00134     AMF();
00135     AMF(int size);
00136     ~AMF();
00137 //    size_t size() { return _total_size; };
00138 
00139     //
00140     // Methods for encoding data into big endian formatted raw AMF data.
00141     //
00142     
00147     static boost::uint8_t *encodeElement(const char *str);
00148 
00153     static boost::uint8_t *encodeBoolean(bool flag);
00154 
00159     static boost::uint8_t *encodeUndefined();
00160 
00165     static boost::uint8_t *encodeNull();
00166 
00171     static  boost::uint8_t *encodeUnsupported();
00172 
00177     static boost::uint8_t *encodeXMLObject(boost::uint8_t *data, int size);
00178 
00183     static boost::uint8_t *encodeTypedObject(boost::uint8_t *data, int size);
00184 
00189     static boost::uint8_t *encodeReference(boost::uint8_t *data, int size);
00190 
00195     static boost::uint8_t *encodeMovieClip(boost::uint8_t *data, int size);
00196 
00201     static boost::uint8_t *encodeECMAArray(boost::uint8_t *data, int size);
00202 
00207     static boost::uint8_t *encodeLongString(boost::uint8_t *data, int size);
00208 
00213     static boost::uint8_t *encodeRecordSet(boost::uint8_t *data, int size);
00214 
00219     static boost::uint8_t *encodeDate(boost::uint8_t *data);
00220 
00225     static boost::uint8_t *encodeStrictArray(boost::uint8_t *data, int size);
00226     
00231     static boost::uint8_t *encodeObject(const boost::uint8_t *data, int size);
00232 
00237     static boost::uint8_t *encodeNumber(double num);
00238     
00242 
00246     static boost::uint8_t *encodeElement(amf::Element *el);
00247 
00251 
00255     static std::vector<boost::uint8_t> *encodeElement(std::vector<amf::Element *> &els);
00256 
00258     //
00267     boost::uint8_t *encodeVariable(amf::Element *el, size_t& outsize);
00268 
00269 #if 0
00271     //
00283     static boost::uint8_t* encodeElement(Element::astype_e type, const void *in, int nbytes);
00284 
00288     static boost::uint8_t* encodeVariable(const char *name);
00289 
00291     //
00295     static boost::uint8_t* encodeVariable(const char *name, bool flag);
00296 
00298     //
00302     static boost::uint8_t* encodeVariable(const char *name, double num);
00303 
00305     //
00309     static boost::uint8_t* encodeVariable(std::string &name, std::string &val);
00310 
00312     //
00316     static boost::uint8_t* encodeVariable(const char *name, const char *val);
00317 
00318     void *encodeRTMPHeader(int amf_index, amf_headersize_e head_size, int total_size,
00319                            content_types_e type, amfsource_e routing);
00320 //    amfhead_t *encodeHeader(amfutf8_t *name, bool required, int nbytes, void *data);
00321 //     amfbody_t *encodeBody(amfutf8_t *target, amfutf8_t *response, int nbytes, void *data);
00322 //    amfpacket_t *encodePacket(std::vector<amfhead_t *> messages);
00323 
00324 //    std::vector<amf_element_t> *readElements(boost::uint8_t *in);
00325     
00327     //
00333 #endif
00334     
00335     //
00336     // Methods for extracting data from big endian formatted raw AMF data.
00337     //
00338     amf::Element::astype_e extractElementHeader(boost::uint8_t *in)
00339         { return *(reinterpret_cast<amf::Element::astype_e *>(in)); };
00340     
00341     boost::uint8_t *extractElement(amf::Element *el, boost::uint8_t *in);
00342     boost::uint8_t *extractVariable(amf::Element *el, boost::uint8_t *in);
00343     
00344 #if 0
00345     // FIXME: these should return an Element, and then use to_*() to convert.
00346     char *extractString(const boost::uint8_t* in);
00347 
00348     double extractNumber(const boost::uint8_t *in);
00349     Element &extractObject(const boost::uint8_t *in);
00350     
00351 
00352     // FIXME: these are all for RTMP, and should be moved
00353     bool parseAMF(boost::uint8_t *in);
00354     static int headerSize(int8_t header);
00355     int packetReadAMF(int bytes);
00356 
00357     int parseHeader(boost::uint8_t *in);
00358     int parseBody();
00359     int getHeaderSize()         { return _header_size; }; 
00360     int getTotalSize()          { return _total_size; }; 
00361     int getPacketSize()         { return _packet_size; };
00362     int getMysteryWord()        { return _mystery_word; };
00363     amfsource_e getRouting()    { return _src_dest; };
00364     int getAMFIndex()           { return _amf_index; };
00365     boost::uint8_t *addPacketData(boost::uint8_t *data, int bytes);
00366 #endif    
00367 
00368     content_types_e getType()   { return _type; };
00369 //    std::map<std::string, Element> *getElements() { return &_elements; };
00370     boost::uint8_t *appendPtr(boost::uint8_t *data, boost::uint8_t *var,
00371                               int bytes) {
00372         memcpy(data, var, bytes);
00373         return data += bytes;
00374     }
00375         
00376  private:
00377 #if 0
00378     Element::astype_e extractElementHeader(void *in);
00379     int extractElementLength(void *in);
00380 //    std::map<std::string, Element &> _elements;
00381     int                 _amf_index;
00382     int                 _header_size;
00383     int                 _total_size;
00384     int                 _packet_size;
00385     boost::uint8_t      *_amf_data;
00386     boost::uint8_t      *_seekptr;
00387     amfsource_e         _src_dest;
00388 #endif
00389     content_types_e     _type;
00390     int                 _mystery_word;
00391 };
00392  
00393 void *swapBytes(void *word, int size);
00394 
00395 
00396 } // end of amf namespace
00397 
00398 // end of _AMF_H_
00399 #endif
00400 
00401 // local Variables:
00402 // mode: C++
00403 // indent-tabs-mode: t
00404 // End:

Generated on Thu Mar 6 18:25:06 2008 for Gnash by  doxygen 1.5.4