"Fossies" - the Fresh Open Source Software Archive

Member "gnash-0.8.10/libbase/AMF.cpp" (19 Jan 2012, 5180 Bytes) of package /linux/www/old/gnash-0.8.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // AMFConverter.h   High-level functions for converting as_values to AMF.
    2 // 
    3 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
    4 //   Free Software Foundation, Inc
    5 // 
    6 // This program is free software; you can redistribute it and/or modify
    7 // it under the terms of the GNU General Public License as published by
    8 // the Free Software Foundation; either version 3 of the License, or
    9 // (at your option) any later version.
   10 // 
   11 // This program is distributed in the hope that it will be useful,
   12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 // GNU General Public License for more details.
   15 // 
   16 // You should have received a copy of the GNU General Public License
   17 // along with this program; if not, write to the Free Software
   18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   19 
   20 // This file provides high-level function objects for converting ActionScript
   21 // values to AMF buffers and vice-versa.
   22 
   23 #include <map>
   24 #include <algorithm>
   25 
   26 #include "log.h"
   27 #include "SimpleBuffer.h"
   28 #include "AMF.h"
   29 
   30 // Define this macro to make AMF parsing verbose
   31 //#define GNASH_DEBUG_AMF_DESERIALIZE 1
   32 
   33 // Define this macto to make AMF writing verbose
   34 // #define GNASH_DEBUG_AMF_SERIALIZE 1
   35 
   36 namespace gnash {
   37 namespace amf {
   38 
   39 namespace {
   40     /// Swap bytes in raw data.
   41     //
   42     /// This only swaps bytes if the host byte order is little endian.
   43     ///
   44     /// @param word The address of the data to byte swap.
   45     /// @param size The number of bytes in the data.
   46     void swapBytes(void* word, size_t size);
   47 }
   48 
   49 bool
   50 readBoolean(const boost::uint8_t*& pos, const boost::uint8_t* _end)
   51 {
   52     if (pos == _end) {
   53         throw AMFException("Read past _end of buffer for boolean type");
   54     }
   55 
   56     const bool val = *pos;
   57     ++pos;
   58 #ifdef GNASH_DEBUG_AMF_DESERIALIZE
   59     log_debug("amf0 read bool: %d", val);
   60 #endif
   61     return val;
   62 }
   63 
   64 double
   65 readNumber(const boost::uint8_t*& pos, const boost::uint8_t* end)
   66 {
   67 
   68     if (end - pos < 8) {
   69         throw AMFException("Read past _end of buffer for number type");
   70     }
   71 
   72     double d;
   73     // TODO: may we avoid a copy and swapBytes call
   74     //       by bitshifting b[0] trough b[7] ?
   75     std::copy(pos, pos + 8, reinterpret_cast<char*>(&d));
   76     pos += 8; 
   77     swapBytes(&d, 8);
   78 
   79 #ifdef GNASH_DEBUG_AMF_DESERIALIZE
   80     log_debug("amf0 read double: %e", dub);
   81 #endif
   82 
   83     return d;
   84 }
   85 
   86 std::string
   87 readString(const boost::uint8_t*& pos, const boost::uint8_t* end)
   88 {
   89     if (end - pos < 2) {
   90         throw AMFException(_("Read past _end of buffer for string length"));
   91     }
   92 
   93     const boost::uint16_t si = readNetworkShort(pos);
   94     pos += 2;
   95 
   96     if (end - pos < si) {
   97         throw AMFException(_("Read past _end of buffer for string type"));
   98     }
   99 
  100     const std::string str(reinterpret_cast<const char*>(pos), si);
  101     pos += si;
  102 #ifdef GNASH_DEBUG_AMF_DESERIALIZE
  103     log_debug("amf0 read string: %s", str);
  104 #endif
  105     return str;
  106 }
  107 
  108 std::string
  109 readLongString(const boost::uint8_t*& pos, const boost::uint8_t* end)
  110 {
  111     if (end - pos < 4) {
  112         throw AMFException("Read past _end of buffer for long string length");
  113     }
  114 
  115     const boost::uint32_t si = readNetworkLong(pos);
  116     pos += 4;
  117     if (static_cast<boost::uint32_t>(end - pos) < si) {
  118         throw AMFException("Read past _end of buffer for long string type");
  119     }
  120 
  121     const std::string str(reinterpret_cast<const char*>(pos), si);
  122     pos += si;
  123 
  124 #ifdef GNASH_DEBUG_AMF_DESERIALIZE
  125     log_debug("amf0 read long string: %s", str);
  126 #endif
  127 
  128     return str;
  129 
  130 }
  131 
  132 void
  133 writePlainString(SimpleBuffer& buf, const std::string& str, Type t)
  134 {
  135     const size_t len = str.size();
  136     switch (t) {
  137         default:
  138             log_error(_("writePlainString called with invalid type!"));
  139             return;
  140        
  141         case LONG_STRING_AMF0:
  142             buf.appendNetworkLong(len);
  143             break;
  144            
  145         case STRING_AMF0:
  146             buf.appendNetworkShort(len);
  147             break;
  148 
  149     }
  150     buf.append(str.c_str(), len);
  151 }
  152 
  153 void
  154 writePlainNumber(SimpleBuffer& buf, double d)
  155 {
  156     swapBytes(&d, 8);
  157     buf.append(&d, 8);
  158 }
  159 
  160 void
  161 write(SimpleBuffer& buf, const std::string& str)
  162 {
  163     Type t = str.size() < 65536 ? STRING_AMF0 : LONG_STRING_AMF0;
  164     buf.appendByte(t);
  165     writePlainString(buf, str, t);
  166 }
  167 
  168 void
  169 write(SimpleBuffer& buf, double d)
  170 {
  171     buf.appendByte(NUMBER_AMF0);
  172     writePlainNumber(buf, d);
  173 }
  174 
  175 void
  176 write(SimpleBuffer& buf, bool b)
  177 {
  178     buf.appendByte(BOOLEAN_AMF0);
  179     buf.appendByte(b ? 1 : 0);
  180 }
  181 
  182 namespace {
  183 
  184 void
  185 swapBytes(void* word, size_t size)
  186 {
  187     union {
  188         boost::uint16_t s;
  189         struct {
  190              boost::uint8_t c0;
  191              boost::uint8_t c1;
  192         } c;
  193     } u;
  194        
  195     u.s = 1;
  196     if (u.c.c0 == 0) {
  197         // Big-endian machine: do nothing
  198         return;
  199     }
  200 
  201     // Little-endian machine: byte-swap the word
  202     // A conveniently-typed pointer to the source data
  203     boost::uint8_t *x = static_cast<boost::uint8_t *>(word);
  204 
  205     // Handles odd as well as even counts of bytes
  206     std::reverse(x, x + size);
  207 }
  208 
  209 } // unnamed namespace
  210 
  211 } // namespace amf
  212 } // namespace gnash