1 /*
2    mkvmerge -- utility for splicing together matroska files
3    from component media subtypes
4 
5    Distributed under the GPL v2
6    see the file COPYING for details
7    or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
8 
9    helper functions for AMF (Action Message Format) data
10 
11    Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13 
14 #pragma once
15 
16 #include "common/common_pch.h"
17 
18 #include <unordered_map>
19 #include <variant>
20 
21 #include "common/mm_mem_io.h"
22 
23 namespace mtx::amf {
24 
25 using value_type_t = std::variant<double, bool, std::string>;
26 using meta_data_t  = std::unordered_map<std::string, value_type_t>;
27 
28 class script_parser_c {
29 public:
30   enum data_type_e {
31     TYPE_NUMBER      = 0x00,
32     TYPE_BOOL        = 0x01,
33     TYPE_STRING      = 0x02,
34     TYPE_OBJECT      = 0x03,
35     TYPE_MOVIECLIP   = 0x04,
36     TYPE_NULL        = 0x05,
37     TYPE_UNDEFINED   = 0x06,
38     TYPE_REFERENCE   = 0x07,
39     TYPE_ECMAARRAY   = 0x08,
40     TYPE_OBJECT_END  = 0x09,
41     TYPE_ARRAY       = 0x0a,
42     TYPE_DATE        = 0x0b,
43     TYPE_LONG_STRING = 0x0c,
44   };
45 
46 private:
47   memory_cptr m_data_mem;
48   mm_mem_io_c m_data;
49   meta_data_t m_meta_data;
50   bool m_in_meta_data;
51   unsigned int m_level;
52 
53   debugging_option_c m_debug;
54 
55 public:
56   script_parser_c(memory_cptr const &mem);
57 
58   bool parse();
59   meta_data_t const &get_meta_data() const;
60 
61   template<typename T>
62   std::optional<T>
get_meta_data_value(std::string const & key)63   get_meta_data_value(std::string const &key) {
64     auto itr = m_meta_data.find(key);
65     if (m_meta_data.end() == itr)
66       return {};
67 
68     return std::get<T>(itr->second);
69   }
70 
71 protected:
72   std::string read_string(data_type_e type);
73   std::pair<value_type_t, bool> read_value();
74   void read_properties(std::unordered_map<std::string, value_type_t> &properties);
75   std::string level_spacer() const;
76 };
77 
78 }
79 
80 namespace std {
81 template <>
82 struct hash<mtx::amf::script_parser_c::data_type_e> {
83   size_t operator()(mtx::amf::script_parser_c::data_type_e value) const {
84     return hash<unsigned int>()(static_cast<unsigned int>(value));
85   }
86 };
87 }
88