libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
amf0.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
13#include <cstdint>
14#include <initializer_list>
15#include <utility>
16#include <promeki/namespace.h>
17#include <promeki/pair.h>
18#include <promeki/string.h>
19#include <promeki/list.h>
20#include <promeki/sharedptr.h>
21#include <promeki/error.h>
22#include <promeki/result.h>
23
24PROMEKI_NAMESPACE_BEGIN
25
26class Buffer;
27class BufferView;
28
72class Amf0Value {
73 public:
76 using List = promeki::List<Amf0Value>;
77
79 using Field = promeki::Pair<promeki::String, Amf0Value>;
80
82 using FieldList = promeki::List<Field>;
83
85 enum Type {
86 Null,
87 Undefined,
88 Boolean,
89 Number,
90 String,
91 Object,
92 EcmaArray,
93 StrictArray,
94 Date,
95 XmlDocument,
96 TypedObject,
97 Reference,
98 Unsupported
99 };
100
109 enum Marker : uint8_t {
110 MarkerNumber = 0x00,
111 MarkerBoolean = 0x01,
112 MarkerString = 0x02,
113 MarkerObject = 0x03,
114 MarkerMovieClip = 0x04,
115 MarkerNull = 0x05,
116 MarkerUndefined = 0x06,
117 MarkerReference = 0x07,
118 MarkerEcmaArray = 0x08,
119 MarkerObjectEnd = 0x09,
120 MarkerStrictArray = 0x0A,
121 MarkerDate = 0x0B,
122 MarkerLongString = 0x0C,
123 MarkerUnsupported = 0x0D,
124 MarkerRecordSet = 0x0E,
125 MarkerXmlDocument = 0x0F,
126 MarkerTypedObject = 0x10,
127 MarkerAvmPlusObject = 0x11
128 };
129
131 Amf0Value();
133 Amf0Value(bool b);
135 Amf0Value(double d);
137 Amf0Value(int i);
139 Amf0Value(int64_t i);
141 Amf0Value(const promeki::String &s);
143 Amf0Value(const char *s);
144
146 Amf0Value(const Amf0Value &);
148 Amf0Value(Amf0Value &&) noexcept;
150 Amf0Value &operator=(const Amf0Value &);
152 Amf0Value &operator=(Amf0Value &&) noexcept;
162 ~Amf0Value();
163
165 static Amf0Value undefined();
166
168 static Amf0Value unsupported();
169
171 static Amf0Value reference(uint16_t index);
172
174 static Amf0Value object(std::initializer_list<Field> kv = {});
175
183 static Amf0Value ecmaArray(std::initializer_list<Field> kv = {}, uint32_t countHint = 0);
184
186 static Amf0Value strictArray(std::initializer_list<Amf0Value> items = {});
187
194 static Amf0Value date(double msSinceEpoch, int16_t timezone = 0);
195
197 static Amf0Value xmlDocument(const promeki::String &xml);
198
200 static Amf0Value typedObject(const promeki::String &className,
201 std::initializer_list<Field> kv = {});
202
204 Type type() const;
205
207 bool isNull() const { return type() == Null; }
209 bool isUndefined() const { return type() == Undefined; }
211 bool isBoolean() const { return type() == Boolean; }
213 bool isNumber() const { return type() == Number; }
215 bool isString() const { return type() == String; }
217 bool isObject() const { return type() == Object; }
219 bool isEcmaArray() const { return type() == EcmaArray; }
221 bool isStrictArray() const { return type() == StrictArray; }
223 bool isDate() const { return type() == Date; }
225 bool isXmlDocument() const { return type() == XmlDocument; }
227 bool isTypedObject() const { return type() == TypedObject; }
229 bool isReference() const { return type() == Reference; }
231 bool isUnsupportedMarker() const { return type() == Unsupported; }
232
234 bool asBool(bool def = false) const;
236 double asNumber(double def = 0.0) const;
238 promeki::String asString(const promeki::String &def = promeki::String()) const;
239
241 double dateMs() const;
243 int16_t dateTimezone() const;
244
246 uint16_t referenceIndex() const;
247
249 const promeki::String &className() const;
250
257 const FieldList &fields() const;
258
267 FieldList &fields();
268
274 const Amf0Value *find(const promeki::String &key) const;
275
280 Amf0Value *find(const promeki::String &key);
281
283 bool contains(const promeki::String &key) const;
284
292 void setField(const promeki::String &key, Amf0Value value);
293
295 uint32_t ecmaCountHint() const;
296
298 void setEcmaCountHint(uint32_t count);
299
301 const List &items() const;
302
304 List &items();
305
319 Error serialize(Buffer &out) const;
320
322 promeki::String toDebugString(unsigned int indent = 0) const;
323
325 bool operator==(const Amf0Value &other) const;
327 bool operator!=(const Amf0Value &other) const { return !(*this == other); }
328
329 private:
330 struct Amf0Data;
331 SharedPtr<Amf0Data> _d;
332
333 // Out-of-line so the SharedPtr<Amf0Data> temporary destructor
334 // only instantiates inside amf0.cpp (where Amf0Data is fully
335 // defined) rather than at every include site.
336 explicit Amf0Value(SharedPtr<Amf0Data> d);
337};
338
357class Amf0Reader {
358 public:
360 static Result<Amf0Value::List> read(const BufferView &view);
361
372 static Result<Amf0Value::List> read(const uint8_t *data, size_t len);
373
382 static Error readOne(const uint8_t *data, size_t len, size_t &offset, Amf0Value &out);
383};
384
400class Amf0Writer {
401 public:
409 explicit Amf0Writer(Buffer &out);
410
412 Error writeNumber(double v);
414 Error writeBoolean(bool v);
418 Error writeString(const promeki::String &s);
420 Error writeNull();
422 Error writeUndefined();
424 Error writeDate(double msSinceEpoch, int16_t timezone = 0);
426 Error writeStrictArray(const Amf0Value::List &items);
428 Error writeObject(const Amf0Value::FieldList &fields);
430 Error writeEcmaArray(const Amf0Value::FieldList &fields, uint32_t countHint = 0);
432 Error writeTypedObject(const promeki::String &className,
433 const Amf0Value::FieldList &fields);
435 Error writeXmlDocument(const promeki::String &xml);
437 Error writeValue(const Amf0Value &v);
438
440 size_t bytesWritten() const { return _bytesWritten; }
441
442 private:
443 Buffer &_out;
444 size_t _bytesWritten = 0;
445
446 Error appendBytes(const void *bytes, size_t len);
447 Error appendByte(uint8_t b);
448 Error appendU16BE(uint16_t v);
449 Error appendU32BE(uint32_t v);
450 Error appendDoubleBE(double v);
451 Error appendShortString(const promeki::String &s); // 16-bit length prefix
452 Error appendLongString(const promeki::String &s); // 32-bit length prefix
453};
454
455PROMEKI_NAMESPACE_END
456
457#endif // PROMEKI_ENABLE_PROAV