正在显示
6 个修改的文件
包含
324 行增加
和
59 行删除
@@ -24,6 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -24,6 +24,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
24 | #include <srs_core_amf0.hpp> | 24 | #include <srs_core_amf0.hpp> |
25 | 25 | ||
26 | #include <srs_core_log.hpp> | 26 | #include <srs_core_log.hpp> |
27 | +#include <srs_core_error.hpp> | ||
27 | #include <srs_core_stream.hpp> | 28 | #include <srs_core_stream.hpp> |
28 | 29 | ||
29 | // AMF0 marker | 30 | // AMF0 marker |
@@ -49,30 +50,34 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -49,30 +50,34 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
49 | // origin array whos data takes the same form as LengthValueBytes | 50 | // origin array whos data takes the same form as LengthValueBytes |
50 | #define RTMP_AMF0_OriginStrictArray 0x20 | 51 | #define RTMP_AMF0_OriginStrictArray 0x20 |
51 | 52 | ||
52 | -std::string srs_amf0_read_utf8(SrsStream* stream) | 53 | +int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*&); |
54 | + | ||
55 | +int srs_amf0_read_utf8(SrsStream* stream, std::string& value) | ||
53 | { | 56 | { |
54 | - std::string str; | 57 | + int ret = ERROR_SUCCESS; |
55 | 58 | ||
56 | // len | 59 | // len |
57 | if (!stream->require(2)) { | 60 | if (!stream->require(2)) { |
58 | - srs_warn("amf0 read string length failed"); | ||
59 | - return str; | 61 | + ret = ERROR_RTMP_AMF0_DECODE; |
62 | + srs_error("amf0 read string length failed. ret=%d", ret); | ||
63 | + return ret; | ||
60 | } | 64 | } |
61 | int16_t len = stream->read_2bytes(); | 65 | int16_t len = stream->read_2bytes(); |
62 | srs_verbose("amf0 read string length success. len=%d", len); | 66 | srs_verbose("amf0 read string length success. len=%d", len); |
63 | 67 | ||
64 | // empty string | 68 | // empty string |
65 | if (len <= 0) { | 69 | if (len <= 0) { |
66 | - srs_verbose("amf0 read empty string."); | ||
67 | - return str; | 70 | + srs_verbose("amf0 read empty string. ret=%d", ret); |
71 | + return ret; | ||
68 | } | 72 | } |
69 | 73 | ||
70 | // data | 74 | // data |
71 | if (!stream->require(len)) { | 75 | if (!stream->require(len)) { |
72 | - srs_warn("amf0 read string data failed"); | ||
73 | - return str; | 76 | + ret = ERROR_RTMP_AMF0_DECODE; |
77 | + srs_error("amf0 read string data failed. ret=%d", ret); | ||
78 | + return ret; | ||
74 | } | 79 | } |
75 | - str = stream->read_string(len); | 80 | + std::string str = stream->read_string(len); |
76 | 81 | ||
77 | // support utf8-1 only | 82 | // support utf8-1 only |
78 | // 1.3.1 Strings and UTF-8 | 83 | // 1.3.1 Strings and UTF-8 |
@@ -80,54 +85,104 @@ std::string srs_amf0_read_utf8(SrsStream* stream) | @@ -80,54 +85,104 @@ std::string srs_amf0_read_utf8(SrsStream* stream) | ||
80 | for (int i = 0; i < len; i++) { | 85 | for (int i = 0; i < len; i++) { |
81 | char ch = *(str.data() + i); | 86 | char ch = *(str.data() + i); |
82 | if ((ch & 0x80) != 0) { | 87 | if ((ch & 0x80) != 0) { |
83 | - srs_warn("only support utf8-1, 0x00-0x7F, actual is %#x", (int)ch); | ||
84 | - return ""; | 88 | + ret = ERROR_RTMP_AMF0_DECODE; |
89 | + srs_error("only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d", (int)ch, ret); | ||
90 | + return ret; | ||
85 | } | 91 | } |
86 | } | 92 | } |
93 | + | ||
94 | + value = str; | ||
87 | srs_verbose("amf0 read string data success. str=%s", str.c_str()); | 95 | srs_verbose("amf0 read string data success. str=%s", str.c_str()); |
88 | 96 | ||
89 | - return str; | 97 | + return ret; |
90 | } | 98 | } |
91 | 99 | ||
92 | -std::string srs_amf0_read_string(SrsStream* stream) | 100 | +int srs_amf0_read_string(SrsStream* stream, std::string& value) |
93 | { | 101 | { |
102 | + int ret = ERROR_SUCCESS; | ||
103 | + | ||
94 | // marker | 104 | // marker |
95 | if (!stream->require(1)) { | 105 | if (!stream->require(1)) { |
96 | - srs_warn("amf0 read string marker failed"); | ||
97 | - return ""; | 106 | + ret = ERROR_RTMP_AMF0_DECODE; |
107 | + srs_error("amf0 read string marker failed. ret=%d", ret); | ||
108 | + return ret; | ||
98 | } | 109 | } |
99 | 110 | ||
100 | char marker = stream->read_char(); | 111 | char marker = stream->read_char(); |
101 | if (marker != RTMP_AMF0_String) { | 112 | if (marker != RTMP_AMF0_String) { |
102 | - srs_warn("amf0 check string marker failed. marker=%#x, required=%#x", marker, RTMP_AMF0_String); | ||
103 | - return ""; | 113 | + ret = ERROR_RTMP_AMF0_DECODE; |
114 | + srs_error("amf0 check string marker failed. " | ||
115 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_String, ret); | ||
116 | + return ret; | ||
104 | } | 117 | } |
105 | srs_verbose("amf0 read string marker success"); | 118 | srs_verbose("amf0 read string marker success"); |
106 | 119 | ||
107 | - return srs_amf0_read_utf8(stream); | 120 | + return srs_amf0_read_utf8(stream, value); |
121 | +} | ||
122 | + | ||
123 | +int srs_amf0_read_boolean(SrsStream* stream, bool& value) | ||
124 | +{ | ||
125 | + int ret = ERROR_SUCCESS; | ||
126 | + | ||
127 | + // marker | ||
128 | + if (!stream->require(1)) { | ||
129 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
130 | + srs_error("amf0 read bool marker failed. ret=%d", ret); | ||
131 | + return ret; | ||
132 | + } | ||
133 | + | ||
134 | + char marker = stream->read_char(); | ||
135 | + if (marker != RTMP_AMF0_Boolean) { | ||
136 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
137 | + srs_error("amf0 check bool marker failed. " | ||
138 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Boolean, ret); | ||
139 | + return ret; | ||
140 | + } | ||
141 | + srs_verbose("amf0 read bool marker success"); | ||
142 | + | ||
143 | + // value | ||
144 | + if (!stream->require(1)) { | ||
145 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
146 | + srs_error("amf0 read bool value failed. ret=%d", ret); | ||
147 | + return ret; | ||
148 | + } | ||
149 | + | ||
150 | + if (stream->read_char() == 0) { | ||
151 | + value = false; | ||
152 | + } else { | ||
153 | + value = true; | ||
154 | + } | ||
155 | + | ||
156 | + srs_verbose("amf0 read bool value success. value=%d", value); | ||
157 | + | ||
158 | + return ret; | ||
108 | } | 159 | } |
109 | 160 | ||
110 | -double srs_amf0_read_number(SrsStream* stream) | 161 | +int srs_amf0_read_number(SrsStream* stream, double& value) |
111 | { | 162 | { |
112 | - double value = 0; | 163 | + int ret = ERROR_SUCCESS; |
113 | 164 | ||
114 | // marker | 165 | // marker |
115 | if (!stream->require(1)) { | 166 | if (!stream->require(1)) { |
116 | - srs_warn("amf0 read number marker failed"); | ||
117 | - return value; | 167 | + ret = ERROR_RTMP_AMF0_DECODE; |
168 | + srs_error("amf0 read number marker failed. ret=%d", ret); | ||
169 | + return ret; | ||
118 | } | 170 | } |
119 | 171 | ||
120 | char marker = stream->read_char(); | 172 | char marker = stream->read_char(); |
121 | if (marker != RTMP_AMF0_Number) { | 173 | if (marker != RTMP_AMF0_Number) { |
122 | - srs_warn("amf0 check number marker failed. marker=%#x, required=%#x", marker, RTMP_AMF0_Number); | ||
123 | - return value; | 174 | + ret = ERROR_RTMP_AMF0_DECODE; |
175 | + srs_error("amf0 check number marker failed. " | ||
176 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Number, ret); | ||
177 | + return ret; | ||
124 | } | 178 | } |
125 | srs_verbose("amf0 read number marker success"); | 179 | srs_verbose("amf0 read number marker success"); |
126 | 180 | ||
127 | // value | 181 | // value |
128 | if (!stream->require(8)) { | 182 | if (!stream->require(8)) { |
129 | - srs_warn("amf0 read number value failed"); | ||
130 | - return value; | 183 | + ret = ERROR_RTMP_AMF0_DECODE; |
184 | + srs_error("amf0 read number value failed. ret=%d", ret); | ||
185 | + return ret; | ||
131 | } | 186 | } |
132 | 187 | ||
133 | int64_t temp = stream->read_8bytes(); | 188 | int64_t temp = stream->read_8bytes(); |
@@ -135,13 +190,158 @@ double srs_amf0_read_number(SrsStream* stream) | @@ -135,13 +190,158 @@ double srs_amf0_read_number(SrsStream* stream) | ||
135 | 190 | ||
136 | srs_verbose("amf0 read number value success. value=%.2f", value); | 191 | srs_verbose("amf0 read number value success. value=%.2f", value); |
137 | 192 | ||
138 | - return value; | 193 | + return ret; |
194 | +} | ||
195 | + | ||
196 | +int srs_amf0_read_any(SrsStream* stream, SrsAmf0Any*& value) | ||
197 | +{ | ||
198 | + int ret = ERROR_SUCCESS; | ||
199 | + | ||
200 | + // marker | ||
201 | + if (!stream->require(1)) { | ||
202 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
203 | + srs_error("amf0 read any marker failed. ret=%d", ret); | ||
204 | + return ret; | ||
205 | + } | ||
206 | + | ||
207 | + char marker = stream->read_char(); | ||
208 | + srs_verbose("amf0 any marker success"); | ||
209 | + | ||
210 | + // backward the 1byte marker. | ||
211 | + stream->skip(-1); | ||
212 | + | ||
213 | + switch (marker) { | ||
214 | + case RTMP_AMF0_String: { | ||
215 | + std::string data; | ||
216 | + if ((ret = srs_amf0_read_string(stream, data)) != ERROR_SUCCESS) { | ||
217 | + return ret; | ||
218 | + } | ||
219 | + value = new SrsAmf0String(); | ||
220 | + srs_amf0_convert<SrsAmf0String>(value)->value = data; | ||
221 | + return ret; | ||
222 | + } | ||
223 | + case RTMP_AMF0_Boolean: { | ||
224 | + bool data; | ||
225 | + if ((ret = srs_amf0_read_boolean(stream, data)) != ERROR_SUCCESS) { | ||
226 | + return ret; | ||
227 | + } | ||
228 | + value = new SrsAmf0Boolean(); | ||
229 | + srs_amf0_convert<SrsAmf0Boolean>(value)->value = data; | ||
230 | + return ret; | ||
231 | + } | ||
232 | + case RTMP_AMF0_Number: { | ||
233 | + double data; | ||
234 | + if ((ret = srs_amf0_read_number(stream, data)) != ERROR_SUCCESS) { | ||
235 | + return ret; | ||
236 | + } | ||
237 | + value = new SrsAmf0Number(); | ||
238 | + srs_amf0_convert<SrsAmf0Number>(value)->value = data; | ||
239 | + return ret; | ||
240 | + } | ||
241 | + case RTMP_AMF0_ObjectEnd: { | ||
242 | + SrsAmf0ObjectEOF* p = NULL; | ||
243 | + if ((ret = srs_amf0_read_object_eof(stream, p)) != ERROR_SUCCESS) { | ||
244 | + return ret; | ||
245 | + } | ||
246 | + value = p; | ||
247 | + return ret; | ||
248 | + } | ||
249 | + case RTMP_AMF0_Object: { | ||
250 | + SrsAmf0Object* p = NULL; | ||
251 | + if ((ret = srs_amf0_read_object(stream, p)) != ERROR_SUCCESS) { | ||
252 | + return ret; | ||
253 | + } | ||
254 | + value = p; | ||
255 | + return ret; | ||
256 | + } | ||
257 | + default: | ||
258 | + value = new SrsAmf0Any(); | ||
259 | + value->marker = stream->read_char(); | ||
260 | + return ret; | ||
261 | + } | ||
262 | + | ||
263 | + return ret; | ||
139 | } | 264 | } |
140 | 265 | ||
141 | -SrsAmf0Object* srs_amf0_read_object(SrsStream* stream) | 266 | +int srs_amf0_read_object_eof(SrsStream* stream, SrsAmf0ObjectEOF*& value) |
142 | { | 267 | { |
143 | - SrsAmf0Object* value = NULL; | ||
144 | - return value; | 268 | + int ret = ERROR_SUCCESS; |
269 | + | ||
270 | + // marker | ||
271 | + if (!stream->require(1)) { | ||
272 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
273 | + srs_error("amf0 read object eof marker failed. ret=%d", ret); | ||
274 | + return ret; | ||
275 | + } | ||
276 | + | ||
277 | + char marker = stream->read_char(); | ||
278 | + if (marker != RTMP_AMF0_ObjectEnd) { | ||
279 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
280 | + srs_error("amf0 check object eof marker failed. " | ||
281 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_ObjectEnd, ret); | ||
282 | + return ret; | ||
283 | + } | ||
284 | + srs_verbose("amf0 read object eof marker success"); | ||
285 | + | ||
286 | + // value | ||
287 | + value = new SrsAmf0ObjectEOF(); | ||
288 | + srs_verbose("amf0 read object eof marker success"); | ||
289 | + | ||
290 | + return ret; | ||
291 | +} | ||
292 | + | ||
293 | +int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value) | ||
294 | +{ | ||
295 | + int ret = ERROR_SUCCESS; | ||
296 | + | ||
297 | + // marker | ||
298 | + if (!stream->require(1)) { | ||
299 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
300 | + srs_error("amf0 read object marker failed. ret=%d", ret); | ||
301 | + return ret; | ||
302 | + } | ||
303 | + | ||
304 | + char marker = stream->read_char(); | ||
305 | + if (marker != RTMP_AMF0_Object) { | ||
306 | + ret = ERROR_RTMP_AMF0_DECODE; | ||
307 | + srs_error("amf0 check object marker failed. " | ||
308 | + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret); | ||
309 | + return ret; | ||
310 | + } | ||
311 | + srs_verbose("amf0 read object marker success"); | ||
312 | + | ||
313 | + // value | ||
314 | + value = new SrsAmf0Object(); | ||
315 | + | ||
316 | + while (!stream->empty()) { | ||
317 | + // property-name: utf8 string | ||
318 | + std::string property_name; | ||
319 | + if ((ret =srs_amf0_read_utf8(stream, property_name)) != ERROR_SUCCESS) { | ||
320 | + srs_error("amf0 object read property name failed. ret=%d", ret); | ||
321 | + return ret; | ||
322 | + } | ||
323 | + // property-value: any | ||
324 | + SrsAmf0Any* property_value = NULL; | ||
325 | + if ((ret = srs_amf0_read_any(stream, property_value)) != ERROR_SUCCESS) { | ||
326 | + srs_error("amf0 object read property_value failed. " | ||
327 | + "name=%s, ret=%d", property_name.c_str(), ret); | ||
328 | + return ret; | ||
329 | + } | ||
330 | + | ||
331 | + // AMF0 Object EOF. | ||
332 | + if (property_name.empty() || !property_value || property_value->is_object_eof()) { | ||
333 | + if (property_value) { | ||
334 | + delete property_value; | ||
335 | + } | ||
336 | + srs_info("amf0 read object EOF."); | ||
337 | + break; | ||
338 | + } | ||
339 | + | ||
340 | + // add property | ||
341 | + value->properties[property_name] = property_value; | ||
342 | + } | ||
343 | + | ||
344 | + return ret; | ||
145 | } | 345 | } |
146 | 346 | ||
147 | SrsAmf0Any::SrsAmf0Any() | 347 | SrsAmf0Any::SrsAmf0Any() |
@@ -158,6 +358,11 @@ bool SrsAmf0Any::is_string() | @@ -158,6 +358,11 @@ bool SrsAmf0Any::is_string() | ||
158 | return marker == RTMP_AMF0_String; | 358 | return marker == RTMP_AMF0_String; |
159 | } | 359 | } |
160 | 360 | ||
361 | +bool SrsAmf0Any::is_boolean() | ||
362 | +{ | ||
363 | + return marker == RTMP_AMF0_Boolean; | ||
364 | +} | ||
365 | + | ||
161 | bool SrsAmf0Any::is_number() | 366 | bool SrsAmf0Any::is_number() |
162 | { | 367 | { |
163 | return marker == RTMP_AMF0_Number; | 368 | return marker == RTMP_AMF0_Number; |
@@ -168,6 +373,11 @@ bool SrsAmf0Any::is_object() | @@ -168,6 +373,11 @@ bool SrsAmf0Any::is_object() | ||
168 | return marker == RTMP_AMF0_Object; | 373 | return marker == RTMP_AMF0_Object; |
169 | } | 374 | } |
170 | 375 | ||
376 | +bool SrsAmf0Any::is_object_eof() | ||
377 | +{ | ||
378 | + return marker == RTMP_AMF0_ObjectEnd; | ||
379 | +} | ||
380 | + | ||
171 | SrsAmf0String::SrsAmf0String() | 381 | SrsAmf0String::SrsAmf0String() |
172 | { | 382 | { |
173 | marker = RTMP_AMF0_String; | 383 | marker = RTMP_AMF0_String; |
@@ -177,6 +387,16 @@ SrsAmf0String::~SrsAmf0String() | @@ -177,6 +387,16 @@ SrsAmf0String::~SrsAmf0String() | ||
177 | { | 387 | { |
178 | } | 388 | } |
179 | 389 | ||
390 | +SrsAmf0Boolean::SrsAmf0Boolean() | ||
391 | +{ | ||
392 | + marker = RTMP_AMF0_Boolean; | ||
393 | + value = false; | ||
394 | +} | ||
395 | + | ||
396 | +SrsAmf0Boolean::~SrsAmf0Boolean() | ||
397 | +{ | ||
398 | +} | ||
399 | + | ||
180 | SrsAmf0Number::SrsAmf0Number() | 400 | SrsAmf0Number::SrsAmf0Number() |
181 | { | 401 | { |
182 | marker = RTMP_AMF0_Number; | 402 | marker = RTMP_AMF0_Number; |
@@ -185,12 +405,12 @@ SrsAmf0Number::SrsAmf0Number() | @@ -185,12 +405,12 @@ SrsAmf0Number::SrsAmf0Number() | ||
185 | 405 | ||
186 | SrsAmf0Number::~SrsAmf0Number() | 406 | SrsAmf0Number::~SrsAmf0Number() |
187 | { | 407 | { |
408 | + marker = RTMP_AMF0_ObjectEnd; | ||
188 | } | 409 | } |
189 | 410 | ||
190 | SrsAmf0ObjectEOF::SrsAmf0ObjectEOF() | 411 | SrsAmf0ObjectEOF::SrsAmf0ObjectEOF() |
191 | { | 412 | { |
192 | utf8_empty = 0x00; | 413 | utf8_empty = 0x00; |
193 | - object_end_marker = RTMP_AMF0_ObjectEnd; | ||
194 | } | 414 | } |
195 | 415 | ||
196 | SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF() | 416 | SrsAmf0ObjectEOF::~SrsAmf0ObjectEOF() |
@@ -43,25 +43,30 @@ class SrsAmf0Object; | @@ -43,25 +43,30 @@ class SrsAmf0Object; | ||
43 | * UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4 | 43 | * UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4 |
44 | * UTF8-1 = %x00-7F | 44 | * UTF8-1 = %x00-7F |
45 | * @remark only support UTF8-1 char. | 45 | * @remark only support UTF8-1 char. |
46 | -* @return default value is empty string. | ||
47 | */ | 46 | */ |
48 | -extern std::string srs_amf0_read_utf8(SrsStream* stream); | 47 | +extern int srs_amf0_read_utf8(SrsStream* stream, std::string& value); |
49 | 48 | ||
50 | /** | 49 | /** |
51 | * read amf0 string from stream. | 50 | * read amf0 string from stream. |
52 | * 2.4 String Type | 51 | * 2.4 String Type |
53 | * string-type = string-marker UTF-8 | 52 | * string-type = string-marker UTF-8 |
54 | -* @return default value is empty string. | ||
55 | */ | 53 | */ |
56 | -extern std::string srs_amf0_read_string(SrsStream* stream); | 54 | +extern int srs_amf0_read_string(SrsStream* stream, std::string& value); |
55 | + | ||
56 | +/** | ||
57 | +* read amf0 boolean from stream. | ||
58 | +* 2.4 String Type | ||
59 | +* boolean-type = boolean-marker U8 | ||
60 | +* 0 is false, <> 0 is true | ||
61 | +*/ | ||
62 | +extern int srs_amf0_read_boolean(SrsStream* stream, bool& value); | ||
57 | 63 | ||
58 | /** | 64 | /** |
59 | * read amf0 number from stream. | 65 | * read amf0 number from stream. |
60 | * 2.2 Number Type | 66 | * 2.2 Number Type |
61 | * number-type = number-marker DOUBLE | 67 | * number-type = number-marker DOUBLE |
62 | -* @return default value is 0. | ||
63 | */ | 68 | */ |
64 | -extern double srs_amf0_read_number(SrsStream* stream); | 69 | +extern int srs_amf0_read_number(SrsStream* stream, double& value); |
65 | 70 | ||
66 | /** | 71 | /** |
67 | * read amf0 object from stream. | 72 | * read amf0 object from stream. |
@@ -69,7 +74,7 @@ extern double srs_amf0_read_number(SrsStream* stream); | @@ -69,7 +74,7 @@ extern double srs_amf0_read_number(SrsStream* stream); | ||
69 | * anonymous-object-type = object-marker *(object-property) | 74 | * anonymous-object-type = object-marker *(object-property) |
70 | * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) | 75 | * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) |
71 | */ | 76 | */ |
72 | -extern SrsAmf0Object* srs_amf0_read_object(SrsStream* stream); | 77 | +extern int srs_amf0_read_object(SrsStream* stream, SrsAmf0Object*& value); |
73 | 78 | ||
74 | /** | 79 | /** |
75 | * any amf0 value. | 80 | * any amf0 value. |
@@ -87,22 +92,10 @@ struct SrsAmf0Any | @@ -87,22 +92,10 @@ struct SrsAmf0Any | ||
87 | virtual ~SrsAmf0Any(); | 92 | virtual ~SrsAmf0Any(); |
88 | 93 | ||
89 | virtual bool is_string(); | 94 | virtual bool is_string(); |
95 | + virtual bool is_boolean(); | ||
90 | virtual bool is_number(); | 96 | virtual bool is_number(); |
91 | virtual bool is_object(); | 97 | virtual bool is_object(); |
92 | - | ||
93 | - /** | ||
94 | - * convert the any to specified object. | ||
95 | - * @return T*, the converted object. never NULL. | ||
96 | - * @remark, user must ensure the current object type, | ||
97 | - * or the covert will cause assert failed. | ||
98 | - */ | ||
99 | - template<class T> | ||
100 | - T* convert() | ||
101 | - { | ||
102 | - T* p = dynamic_cast<T>(this); | ||
103 | - srs_assert(p != NULL); | ||
104 | - return p; | ||
105 | - } | 98 | + virtual bool is_object_eof(); |
106 | }; | 99 | }; |
107 | 100 | ||
108 | /** | 101 | /** |
@@ -120,6 +113,21 @@ struct SrsAmf0String : public SrsAmf0Any | @@ -120,6 +113,21 @@ struct SrsAmf0String : public SrsAmf0Any | ||
120 | }; | 113 | }; |
121 | 114 | ||
122 | /** | 115 | /** |
116 | +* read amf0 boolean from stream. | ||
117 | +* 2.4 String Type | ||
118 | +* boolean-type = boolean-marker U8 | ||
119 | +* 0 is false, <> 0 is true | ||
120 | +* @return default value is false. | ||
121 | +*/ | ||
122 | +struct SrsAmf0Boolean : public SrsAmf0Any | ||
123 | +{ | ||
124 | + bool value; | ||
125 | + | ||
126 | + SrsAmf0Boolean(); | ||
127 | + virtual ~SrsAmf0Boolean(); | ||
128 | +}; | ||
129 | + | ||
130 | +/** | ||
123 | * read amf0 number from stream. | 131 | * read amf0 number from stream. |
124 | * 2.2 Number Type | 132 | * 2.2 Number Type |
125 | * number-type = number-marker DOUBLE | 133 | * number-type = number-marker DOUBLE |
@@ -138,10 +146,9 @@ struct SrsAmf0Number : public SrsAmf0Any | @@ -138,10 +146,9 @@ struct SrsAmf0Number : public SrsAmf0Any | ||
138 | * object-end-type = UTF-8-empty object-end-marker | 146 | * object-end-type = UTF-8-empty object-end-marker |
139 | * 0x00 0x00 0x09 | 147 | * 0x00 0x00 0x09 |
140 | */ | 148 | */ |
141 | -struct SrsAmf0ObjectEOF | 149 | +struct SrsAmf0ObjectEOF : public SrsAmf0Any |
142 | { | 150 | { |
143 | int16_t utf8_empty; | 151 | int16_t utf8_empty; |
144 | - char object_end_marker; | ||
145 | 152 | ||
146 | SrsAmf0ObjectEOF(); | 153 | SrsAmf0ObjectEOF(); |
147 | virtual ~SrsAmf0ObjectEOF(); | 154 | virtual ~SrsAmf0ObjectEOF(); |
@@ -161,4 +168,18 @@ struct SrsAmf0Object : public SrsAmf0Any | @@ -161,4 +168,18 @@ struct SrsAmf0Object : public SrsAmf0Any | ||
161 | virtual ~SrsAmf0Object(); | 168 | virtual ~SrsAmf0Object(); |
162 | }; | 169 | }; |
163 | 170 | ||
171 | +/** | ||
172 | +* convert the any to specified object. | ||
173 | +* @return T*, the converted object. never NULL. | ||
174 | +* @remark, user must ensure the current object type, | ||
175 | +* or the covert will cause assert failed. | ||
176 | +*/ | ||
177 | +template<class T> | ||
178 | +T* srs_amf0_convert(SrsAmf0Any* any) | ||
179 | +{ | ||
180 | + T* p = dynamic_cast<T*>(any); | ||
181 | + srs_assert(p != NULL); | ||
182 | + return p; | ||
183 | +} | ||
184 | + | ||
164 | #endif | 185 | #endif |
@@ -281,7 +281,11 @@ int SrsMessage::decode_packet() | @@ -281,7 +281,11 @@ int SrsMessage::decode_packet() | ||
281 | } | 281 | } |
282 | srs_verbose("decode stream initialized success"); | 282 | srs_verbose("decode stream initialized success"); |
283 | 283 | ||
284 | - std::string command = srs_amf0_read_string(stream); | 284 | + std::string command; |
285 | + if ((ret = srs_amf0_read_string(stream, command)) != ERROR_SUCCESS) { | ||
286 | + srs_error("decode AMF0 command name failed. ret=%d", ret); | ||
287 | + return ret; | ||
288 | + } | ||
285 | srs_verbose("AMF0 command message, command_name=%s", command.c_str()); | 289 | srs_verbose("AMF0 command message, command_name=%s", command.c_str()); |
286 | 290 | ||
287 | stream->reset(); | 291 | stream->reset(); |
@@ -337,7 +341,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | @@ -337,7 +341,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | ||
337 | return ret; | 341 | return ret; |
338 | } | 342 | } |
339 | 343 | ||
340 | - command_name = srs_amf0_read_string(stream); | 344 | + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { |
345 | + srs_error("amf0 decode connect command_name failed. ret=%d", ret); | ||
346 | + return ret; | ||
347 | + } | ||
341 | if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_CONNECT) { | 348 | if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_CONNECT) { |
342 | ret = ERROR_RTMP_AMF0_DECODE; | 349 | ret = ERROR_RTMP_AMF0_DECODE; |
343 | srs_error("amf0 decode connect command_name failed. " | 350 | srs_error("amf0 decode connect command_name failed. " |
@@ -345,7 +352,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | @@ -345,7 +352,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | ||
345 | return ret; | 352 | return ret; |
346 | } | 353 | } |
347 | 354 | ||
348 | - transaction_id = srs_amf0_read_number(stream); | 355 | + if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) { |
356 | + srs_error("amf0 decode connect transaction_id failed. ret=%d", ret); | ||
357 | + return ret; | ||
358 | + } | ||
349 | if (transaction_id != 1.0) { | 359 | if (transaction_id != 1.0) { |
350 | ret = ERROR_RTMP_AMF0_DECODE; | 360 | ret = ERROR_RTMP_AMF0_DECODE; |
351 | srs_error("amf0 decode connect transaction_id failed. " | 361 | srs_error("amf0 decode connect transaction_id failed. " |
@@ -353,7 +363,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | @@ -353,7 +363,10 @@ int SrsConnectAppPacket::decode(SrsStream* stream) | ||
353 | return ret; | 363 | return ret; |
354 | } | 364 | } |
355 | 365 | ||
356 | - command_object = srs_amf0_read_object(stream); | 366 | + if ((ret = srs_amf0_read_object(stream, command_object)) != ERROR_SUCCESS) { |
367 | + srs_error("amf0 decode connect command_object failed. ret=%d", ret); | ||
368 | + return ret; | ||
369 | + } | ||
357 | if (command_object == NULL) { | 370 | if (command_object == NULL) { |
358 | ret = ERROR_RTMP_AMF0_DECODE; | 371 | ret = ERROR_RTMP_AMF0_DECODE; |
359 | srs_error("amf0 decode connect command_object failed. ret=%d", ret); | 372 | srs_error("amf0 decode connect command_object failed. ret=%d", ret); |
@@ -70,7 +70,12 @@ bool SrsStream::empty() | @@ -70,7 +70,12 @@ bool SrsStream::empty() | ||
70 | 70 | ||
71 | bool SrsStream::require(int required_size) | 71 | bool SrsStream::require(int required_size) |
72 | { | 72 | { |
73 | - return !empty() && (required_size < bytes + size - p); | 73 | + return !empty() && (required_size <= bytes + size - p); |
74 | +} | ||
75 | + | ||
76 | +void SrsStream::skip(int size) | ||
77 | +{ | ||
78 | + p += size; | ||
74 | } | 79 | } |
75 | 80 | ||
76 | char SrsStream::read_char() | 81 | char SrsStream::read_char() |
@@ -65,6 +65,11 @@ public: | @@ -65,6 +65,11 @@ public: | ||
65 | * @return true if stream can read/write specified required_size bytes. | 65 | * @return true if stream can read/write specified required_size bytes. |
66 | */ | 66 | */ |
67 | virtual bool require(int required_size); | 67 | virtual bool require(int required_size); |
68 | + /** | ||
69 | + * to skip some size. | ||
70 | + * @size can be any value. positive to forward; nagetive to backward. | ||
71 | + */ | ||
72 | + virtual void skip(int size); | ||
68 | public: | 73 | public: |
69 | /** | 74 | /** |
70 | * get 1bytes char from stream. | 75 | * get 1bytes char from stream. |
-
请 注册 或 登录 后发表评论