Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 31 additions & 84 deletions components/core/src/ffi/ir_stream/decoding_methods.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#include "decoding_methods.hpp"

// json
#include "../../../submodules/json/single_include/nlohmann/json.hpp"

// Project headers
#include "byteswap.hpp"
#include "protocol_constants.hpp"
Expand Down Expand Up @@ -76,13 +73,6 @@ namespace ffi::ir_stream {
template <typename encoded_variable_t>
IRErrorCode parse_timestamp (IrBuffer& ir_buf, encoded_tag_t encoded_tag, epoch_time_ms_t& ts);

/**
* Extracts timestamp info from the JSON metadata and stores it into ts_info
* @param metadata_json The JSON metadata
* @param ts_info Returns the timestamp info
*/
static void set_timestamp_info (const nlohmann::json& metadata_json, TimestampInfo& ts_info);

/**
* Decodes the next encoded message from ir_buf
* @tparam encoded_variable_t Type of the encoded variable
Expand All @@ -103,15 +93,18 @@ namespace ffi::ir_stream {
epoch_time_ms_t& timestamp);

/**
* Decodes the JSON metadata from the ir_buf
* Reads metadata information from the ir_buf
* @param ir_buf
* @param json_metadata Returns the JSON metadata
* @param metadata_type Returns the type of the metadata found in the IR
* @param metadata_pos Returns the starting position of the metadata in ir_buf
* @param metadata_size Returns the size of the metadata written in the IR
* @return IRErrorCode_Success on success
* @return IRErrorCode_Corrupted_IR if ir_buf contains invalid IR
* @return IRErrorCode_Incomplete_IR if ir_buf doesn't contain enough data
* to decode
*/
static IRErrorCode read_json_metadata (IrBuffer& ir_buf, string_view& json_metadata);
static IRErrorCode read_metadata_info (IrBuffer& ir_buf, encoded_tag_t& metadata_type,
uint16_t& metadata_size);

/**
* Decodes the message from the given logtype, encoded variables, and
Expand Down Expand Up @@ -308,13 +301,6 @@ namespace ffi::ir_stream {
return IRErrorCode_Success;
}

static void set_timestamp_info (const nlohmann::json& metadata_json, TimestampInfo& ts_info) {
ts_info.time_zone_id = metadata_json.at(cProtocol::Metadata::TimeZoneIdKey);
ts_info.timestamp_pattern = metadata_json.at(cProtocol::Metadata::TimestampPatternKey);
ts_info.timestamp_pattern_syntax =
metadata_json.at(cProtocol::Metadata::TimestampPatternSyntaxKey);
}

template <typename encoded_variable_t>
static IRErrorCode generic_decode_next_message (IrBuffer& ir_buf, string& message,
epoch_time_ms_t& timestamp)
Expand Down Expand Up @@ -383,43 +369,38 @@ namespace ffi::ir_stream {
return IRErrorCode_Success;
}

static IRErrorCode read_json_metadata (IrBuffer& ir_buf, string_view& json_metadata) {
encoded_tag_t encoded_tag;
if (false == ir_buf.try_read(encoded_tag)) {
static IRErrorCode read_metadata_info (IrBuffer& ir_buf, encoded_tag_t& metadata_type,
uint16_t& metadata_size) {
if (false == ir_buf.try_read(metadata_type)) {
return IRErrorCode_Incomplete_IR;
}
if (encoded_tag != cProtocol::Metadata::EncodingJson) {
if (metadata_type != cProtocol::Metadata::EncodingJson) {
return IRErrorCode_Corrupted_IR;
}

// Read metadata length
encoded_tag_t encoded_tag;
if (false == ir_buf.try_read(encoded_tag)) {
return IRErrorCode_Incomplete_IR;
}
unsigned int metadata_length;
switch (encoded_tag) {
case cProtocol::Metadata::LengthUByte:
uint8_t ubyte_res;
if (false == decode_int(ir_buf, ubyte_res)) {
return IRErrorCode_Incomplete_IR;
}
metadata_length = ubyte_res;
metadata_size = ubyte_res;
break;
case cProtocol::Metadata::LengthUShort:
uint16_t ushort_res;
if (false == decode_int(ir_buf, ushort_res)) {
return IRErrorCode_Incomplete_IR;
}
metadata_length = ushort_res;
metadata_size = ushort_res;
break;
default:
return IRErrorCode_Corrupted_IR;
}

// Read the serialized metadata
if (false == ir_buf.try_read(json_metadata, metadata_length)) {
return IRErrorCode_Incomplete_IR;
}
return IRErrorCode_Success;
}

Expand Down Expand Up @@ -532,37 +513,28 @@ namespace ffi::ir_stream {
return IRErrorCode_Success;
}

namespace four_byte_encoding {
IRErrorCode decode_preamble (IrBuffer& ir_buf, TimestampInfo& ts_info,
epoch_time_ms_t& reference_ts)
{
ir_buf.init_internal_pos();

string_view json_metadata;
if (auto error_code = read_json_metadata(ir_buf, json_metadata);
error_code != IRErrorCode_Success)
{
return error_code;
}

try {
auto metadata_json = nlohmann::json::parse(json_metadata);
const auto& version = metadata_json.at(cProtocol::Metadata::VersionKey);
if (version != cProtocol::Metadata::VersionValue) {
return IRErrorCode_Unsupported_Version;
}
IRErrorCode decode_preamble (IrBuffer& ir_buf, encoded_tag_t& metadata_type,
Comment thread
davidlion marked this conversation as resolved.
Resolved
size_t& metadata_pos, uint16_t& metadata_size)
{
ir_buf.init_internal_pos();

set_timestamp_info(metadata_json, ts_info);
reference_ts = std::stoll(metadata_json.at(
cProtocol::Metadata::ReferenceTimestampKey).get<string>());
} catch (const nlohmann::json::parse_error& e) {
return IRErrorCode_Corrupted_Metadata;
}
if (auto error_code = read_metadata_info(ir_buf, metadata_type, metadata_size);
error_code != IRErrorCode_Success) {
return error_code;
}

ir_buf.commit_internal_pos();
return IRErrorCode_Success;
size_t pos{ir_buf.get_cursor_pos()};
ir_buf.commit_internal_pos();
metadata_pos = ir_buf.get_cursor_pos();
if (ir_buf.size() < metadata_pos + metadata_size) {
ir_buf.set_cursor_pos(pos);
return IRErrorCode_Incomplete_IR;
}
ir_buf.set_cursor_pos(metadata_pos + metadata_size);
return IRErrorCode_Success;
}

namespace four_byte_encoding {
IRErrorCode decode_next_message (IrBuffer& ir_buf, string& message,
epoch_time_ms_t& timestamp_delta)
{
Expand All @@ -573,31 +545,6 @@ namespace ffi::ir_stream {
}

namespace eight_byte_encoding {
IRErrorCode decode_preamble (IrBuffer& ir_buf, TimestampInfo& ts_info) {
ir_buf.init_internal_pos();

string_view json_metadata;
if (auto error_code = read_json_metadata(ir_buf, json_metadata);
error_code != IRErrorCode_Success)
{
return error_code;
}
try {
auto metadata_json = nlohmann::json::parse(json_metadata);
const auto& version = metadata_json.at(cProtocol::Metadata::VersionKey);
if (version != cProtocol::Metadata::VersionValue) {
return IRErrorCode_Unsupported_Version;
}

set_timestamp_info(metadata_json, ts_info);
} catch (const nlohmann::json::parse_error& e) {
return IRErrorCode_Corrupted_Metadata;
}

ir_buf.commit_internal_pos();
return IRErrorCode_Success;
}

IRErrorCode decode_next_message (IrBuffer& ir_buf, string& message,
epoch_time_ms_t& timestamp)
{
Expand Down
51 changes: 18 additions & 33 deletions components/core/src/ffi/ir_stream/decoding_methods.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "../encoding_methods.hpp"

namespace ffi::ir_stream {
using encoded_tag_t = uint8_t;
using encoded_tag_t = int8_t;

/**
* Class representing an IR buffer that the decoder sequentially reads from.
Expand All @@ -30,6 +30,7 @@ namespace ffi::ir_stream {
// The following methods should only be used by the decoder
void init_internal_pos () { m_internal_cursor_pos = m_cursor_pos; }
void commit_internal_pos () { m_cursor_pos = m_internal_cursor_pos; }
size_t const size () const { return m_size; }
Comment thread
davidlion marked this conversation as resolved.
Resolved

/**
* Tries reading a string view of size = read_size from the ir_buf.
Expand Down Expand Up @@ -108,22 +109,23 @@ namespace ffi::ir_stream {
*/
IRErrorCode get_encoding_type (IrBuffer& ir_buf, bool& is_four_bytes_encoding);

namespace eight_byte_encoding {
/**
* Decodes the preamble for the eight-byte encoding IR stream.
* @param ir_buf
* @param ts_info Returns the timestamp info on success
* @return IRErrorCode_Success on success
* @return IRErrorCode_Corrupted_IR if ir_buf contains invalid IR
* @return IRErrorCode_Incomplete_IR if ir_buf doesn't contain enough
* data to decode
* @return IRErrorCode_Unsupported_Version if the IR uses an unsupported
* version
* @return IRErrorCode_Corrupted_Metadata if the metadata cannot be
* decoded
*/
IRErrorCode decode_preamble (IrBuffer& ir_buf, TimestampInfo& ts_info);
/**
* Decodes the preamble for the eight-byte encoding IR stream.
Comment thread
davidlion marked this conversation as resolved.
Resolved
* @param ir_buf
* @param metadata_type Returns the type of the metadata found in the IR
* @param metadata_pos Returns the starting position of the metadata in ir_buf
* @param metadata_size Returns the size of the metadata written in the IR
* @return IRErrorCode_Success on success
* @return IRErrorCode_Corrupted_IR if ir_buf contains invalid IR
Comment thread
davidlion marked this conversation as resolved.
Resolved
* @return IRErrorCode_Incomplete_IR if ir_buf doesn't contain enough
* data to decode
* @return IRErrorCode_Unsupported_Version if the IR uses an unsupported
Comment thread
davidlion marked this conversation as resolved.
Resolved
* version
*/
IRErrorCode decode_preamble (IrBuffer& ir_buf, encoded_tag_t& metadata_type,
size_t& metadata_pos, uint16_t& metadata_size);

namespace eight_byte_encoding {
/**
* Decodes the next message for the eight-byte encoding IR stream.
* @param ir_buf
Expand All @@ -142,23 +144,6 @@ namespace ffi::ir_stream {
}

namespace four_byte_encoding {
/**
* Decodes the preamble for the four-byte encoding IR stream.
* @param ir_buf
* @param ts_info Returns the decoded timestamp info
* @param reference_ts Returns the decoded reference timestamp
* @return IRErrorCode_Success on success
* @return IRErrorCode_Corrupted_IR if ir_buf contains invalid IR
* @return IRErrorCode_Incomplete_IR if ir_buf doesn't contain enough
* data to decode
* @return IRErrorCode_Unsupported_Version if the IR has a version that
* is not supported
* @return IRErrorCode_Corrupted_Metadata if the metadata cannot be
* decoded
*/
IRErrorCode decode_preamble (IrBuffer& ir_buf, TimestampInfo& ts_info,
epoch_time_ms_t& reference_ts);

/**
* Decodes the next message for the four-byte encoding IR stream.
* @param ir_buf
Expand Down
Loading