6#include <BufferStream.h>
10DMX::DMX(
const std::byte* dmxData, std::size_t dmxSize) {
11 if (!dmxData || !dmxSize) {
15 BufferStreamReadOnly stream{dmxData, dmxSize};
17 auto header = stream.read_string();
18 if (header.length() < 37) {
22 char encodingTypeData[64];
23 int32_t encodingVersionData;
24 char formatTypeData[64];
25 int32_t formatVersionData;
27 sscanf_s(header.c_str(),
"<!-- dmx encoding %63s %i format %63s %i -->\n", encodingTypeData, 64, &encodingVersionData, formatTypeData, 64, &formatVersionData);
29 std::sscanf(header.c_str(),
"<!-- dmx encoding %s %i format %s %i -->\n", encodingTypeData, &encodingVersionData, formatTypeData, &formatVersionData);
32 this->encodingType = encodingTypeData;
33 this->encodingVersion = encodingVersionData;
34 this->formatType = formatTypeData;
35 this->formatVersion = formatVersionData;
38 if (this->encodingVersion >= 9) {
47 this->opened = this->
openText(dmxData, dmxSize);
51DMX::DMX(
const unsigned char* dmxData, std::size_t dmxSize)
52 :
DMX(reinterpret_cast<const std::byte*>(dmxData), dmxSize) {}
55 :
DMX(dmxData.data(), dmxData.size()) {}
57DMX::DMX(
const std::vector<unsigned char>& dmxData)
58 :
DMX(dmxData.data(), dmxData.size()) {}
60DMX::operator bool()
const {
65 return this->formatType;
69 return this->formatVersion;
73 return this->encodingType;
77 return this->encodingVersion;
81 return this->elements;
90 const bool stringListLengthIsShort = this->encodingVersion < 4;
91 const bool stringListIndicesAreShort = this->encodingVersion < 5;
92 const bool elementNamesAreStoredInStringList = this->encodingVersion >= 4;
93 const bool stringValuesAreStoredInStringList = this->encodingVersion >= 4;
96 std::vector<std::string> stringList;
98 if (stringListLengthIsShort) {
99 stringCount = stream.read<uint16_t>();
101 stringCount = stream.read<uint32_t>();
103 stringList.reserve(stringCount);
104 for (
int i = 0; i < stringCount; i++) {
105 stringList.push_back(stream.read_string());
109 const auto readStringFromIndex = [stringListIndicesAreShort, &stringList](BufferStream& stream_) {
110 if (stringListIndicesAreShort) {
111 return stringList.at(stream_.read<uint16_t>());
113 return stringList.at(stream_.read<uint32_t>());
117 const int elementCount = stream.read<int32_t>();
118 for (
int i = 0; i < elementCount; i++) {
119 auto& [type, name, guid, attributes] = this->elements.emplace_back();
120 type = readStringFromIndex(stream);
121 if (elementNamesAreStoredInStringList) {
122 name = readStringFromIndex(stream);
124 name = stream.read_string();
126 guid = stream.read_bytes<16>();
131 readValue = [&readValue, &readStringFromIndex](BufferStream& stream_,
Value::ID type,
bool useStringList) ->
Value::Generic {
132 const auto readArrayValue = [&readValue]<
typename T>(BufferStream& reader,
Value::ID type_) {
134 auto size = reader.read<uint32_t>();
136 for (
int i = 0; i < size; i++) {
147 value.
index = stream_.read<uint32_t>();
148 if (value.
index == -2) {
150 value.
stubGUID = stream_.read_string();
155 return stream_.read<int32_t>();
157 return stream_.read<
float>();
159 return stream_.read<
bool>();
161 return useStringList ? readStringFromIndex(stream_) : stream_.read_string();
163 return stream_.read_bytes(stream_.read<uint32_t>());
165 return Value::Time{
static_cast<float>(
static_cast<double>(stream_.read<int32_t>()) / 10000.0)};
181 return readArrayValue.operator()<int32_t>(stream_, type);
183 return readArrayValue.operator()<
float>(stream_, type);
185 return readArrayValue.operator()<
bool>(stream_, type);
187 return readArrayValue.operator()<std::string>(stream_, type);
188 case ARRAY_BYTEARRAY:
189 return readArrayValue.operator()<std::vector<std::byte>>(stream_, type);
191 return readArrayValue.operator()<
Value::Time>(stream_, type);
193 return readArrayValue.operator()<
Value::Color>(stream_, type);
197 case ARRAY_EULER_ANGLE:
200 case ARRAY_QUATERNION:
202 case ARRAY_MATRIX_4X4:
209 for (
auto& [type, name, guid, attributes] : this->elements) {
210 const int attributeCount = stream.read<int32_t>();
211 for (
int i = 0; i < attributeCount; i++) {
212 auto& [attrName, attrType, attrValue] = attributes.emplace_back();
213 attrName = readStringFromIndex(stream);
215 attrValue = readValue(stream, attrType, stringValuesAreStoredInStringList);
int getFormatVersion() const
DMX(const std::byte *dmxData, std::size_t dmxSize)
bool openBinary(BufferStream &stream)
const std::vector< DMXElement > & getElements() const
std::string_view getEncodingType() const
bool openText(const std::byte *dmxData, std::size_t dmxSize)
std::string_view getFormatType() const
int getEncodingVersion() const
constexpr ID arrayIDToInnerID(ID id)
sourcepp::math::Mat4x4f Matrix4x4
std::variant< Invalid, Element, int32_t, float, bool, std::string, std::vector< std::byte >, Time, Color, Vector2, Vector3, Vector4, Matrix4x4, std::vector< Element >, std::vector< int32_t >, std::vector< float >, std::vector< bool >, std::vector< std::string >, std::vector< std::vector< std::byte > >, std::vector< Time >, std::vector< Color >, std::vector< Vector2 >, std::vector< Vector3 >, std::vector< Vector4 >, std::vector< Matrix4x4 > > Generic
sourcepp::math::Vec4f Vector4
sourcepp::math::Vec2f Vector2
sourcepp::math::Vec3f Vector3
constexpr ID byteToID(std::byte id)