"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