/*
-Copyright (c) 2005-2006, John Hurst
+Copyright (c) 2005-2009, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
*/
#include "KLV.h"
-#include <hex_utils.h>
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
// This is how much we read when we're reading from a file and we don't know
//
ASDCP::Result_t
-ASDCP::KLVPacket::InitFromBuffer(const byte_t* buf, ui32_t buf_len, const byte_t* label)
+ASDCP::KLVPacket::InitFromBuffer(const byte_t* buf, ui32_t buf_len, const UL& label)
{
Result_t result = KLVPacket::InitFromBuffer(buf, buf_len);
if ( ASDCP_SUCCESS(result) )
- result = ( memcmp(m_KeyStart, label, SMPTE_UL_LENGTH) == 0 ) ?
- RESULT_OK : RESULT_FAIL;
+ result = ( UL(m_KeyStart) == label ) ? RESULT_OK : RESULT_FAIL;
return result;
}
+//
+ASDCP::UL
+ASDCP::KLVPacket::GetUL()
+{
+ if ( m_KeyStart != 0 )
+ return UL(m_KeyStart);
+
+ return m_UL;
+}
+
+//
+bool
+ASDCP::KLVPacket::SetUL(const UL& new_ul)
+{
+ if ( m_KeyStart != 0 )
+ return false;
+
+ m_UL = new_ul;
+ return true;
+}
+
//
ASDCP::Result_t
ASDCP::KLVPacket::InitFromBuffer(const byte_t* buf, ui32_t buf_len)
return RESULT_FAIL;
}
+ ui32_t ber_len = Kumu::BER_length(buf + SMPTE_UL_LENGTH);
+
+ if ( ber_len > ( buf_len - SMPTE_UL_LENGTH ) )
+ {
+ DefaultLogSink().Error("BER encoding length exceeds buffer size.\n");
+ return RESULT_FAIL;
+ }
+
+ if ( ber_len == 0 )
+ {
+ DefaultLogSink().Error("KLV format error, zero BER length not allowed.\n");
+ return RESULT_FAIL;
+ }
+
ui64_t tmp_size;
- if ( ! read_BER(buf + SMPTE_UL_LENGTH, &tmp_size) )
- return RESULT_FAIL;
+ if ( ! Kumu::read_BER(buf + SMPTE_UL_LENGTH, &tmp_size) )
+ {
+ DefaultLogSink().Error("KLV format error, BER decode failure.\n");
+ return RESULT_FAIL;
+ }
m_ValueLength = tmp_size;
- m_KLLength = SMPTE_UL_LENGTH + BER_length(buf + SMPTE_UL_LENGTH);
+ m_KLLength = SMPTE_UL_LENGTH + Kumu::BER_length(buf + SMPTE_UL_LENGTH);
m_KeyStart = buf;
m_ValueStart = buf + m_KLLength;
return RESULT_OK;
bool
ASDCP::KLVPacket::HasUL(const byte_t* ul)
{
- if ( m_KeyStart == 0 )
- return false;
+ if ( m_KeyStart != 0 )
+ {
+ return UL(ul) == UL(m_KeyStart);
+ }
- return ( memcmp(ul, m_KeyStart, SMPTE_UL_LENGTH) == 0 ) ? true : false;
+ if ( m_UL.HasValue() )
+ {
+ return UL(ul) == m_UL;
+ }
+
+ return false;
}
//
ASDCP::Result_t
-ASDCP::KLVPacket::WriteKLToBuffer(ASDCP::FrameBuffer& Buffer, const byte_t* label, ui32_t length)
+ASDCP::KLVPacket::WriteKLToBuffer(ASDCP::FrameBuffer& Buffer, const UL& label, ui32_t length)
{
+ assert(label.HasValue());
+
if ( Buffer.Size() + kl_length > Buffer.Capacity() )
{
DefaultLogSink().Error("Small write buffer\n");
return RESULT_FAIL;
}
- memcpy(Buffer.Data() + Buffer.Size(), label, SMPTE_UL_LENGTH);
+ memcpy(Buffer.Data() + Buffer.Size(), label.Value(), label.Size());
- if ( ! write_BER(Buffer.Data() + Buffer.Size() + SMPTE_UL_LENGTH, length, MXF_BER_LENGTH) )
+ if ( ! Kumu::write_BER(Buffer.Data() + Buffer.Size() + SMPTE_UL_LENGTH, length, MXF_BER_LENGTH) )
return RESULT_FAIL;
Buffer.Size(Buffer.Size() + kl_length);
//
void
-ASDCP::KLVPacket::Dump(FILE* stream, bool show_hex)
+ASDCP::KLVPacket::Dump(FILE* stream, const Dictionary& Dict, bool show_value)
{
+ char buf[64];
+
if ( stream == 0 )
stream = stderr;
if ( m_KeyStart != 0 )
{
assert(m_ValueStart);
+ UL TmpUL(m_KeyStart);
+ fprintf(stream, "%s", TmpUL.EncodeString(buf, 64));
- for ( ui32_t i = 0; i < SMPTE_UL_LENGTH; i++ )
- fprintf(stream, "%02x.", m_KeyStart[i]);
+ const MDDEntry* Entry = Dict.FindULAnyVersion(m_KeyStart);
+ fprintf(stream, " len: %7llu (%s)\n", m_ValueLength, (Entry ? Entry->name : "Unknown"));
- const MDDEntry* Entry = Dict::FindUL(m_KeyStart);
- fprintf(stream, "\b len: %7lu (%s)\n", m_ValueLength, (Entry ? Entry->name : "Unknown"));
-
- if ( show_hex && m_ValueLength < 1000 )
- hexdump(m_ValueStart, ASDCP::xmin(m_ValueLength, (ui32_t)64), stream);
+ if ( show_value && m_ValueLength < 1000 )
+ Kumu::hexdump(m_ValueStart, Kumu::xmin(m_ValueLength, (ui64_t)128), stream);
+ }
+ else if ( m_UL.HasValue() )
+ {
+ fprintf(stream, "%s\n", m_UL.EncodeString(buf, 64));
}
else
{
- fprintf(stream, "*** Malformed packet ***\n");
+ fprintf(stream, "*** Malformed KLV packet ***\n");
}
}
//
ASDCP::Result_t
-ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader, const byte_t* label)
+ASDCP::KLVFilePacket::InitFromFile(const Kumu::FileReader& Reader, const UL& label)
{
Result_t result = KLVFilePacket::InitFromFile(Reader);
if ( ASDCP_SUCCESS(result) )
- result = ( memcmp(m_KeyStart, label, SMPTE_UL_LENGTH) == 0 ) ?
- RESULT_OK : RESULT_FAIL;
+ result = ( UL(m_KeyStart) == label ) ? RESULT_OK : RESULT_FAIL;
return result;
}
-//
+// TODO: refactor to use InitFromBuffer
ASDCP::Result_t
-ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader)
+ASDCP::KLVFilePacket::InitFromFile(const Kumu::FileReader& Reader)
{
ui32_t read_count;
byte_t tmp_data[tmp_read_size];
if ( read_count < (SMPTE_UL_LENGTH + 1) )
{
- DefaultLogSink().Error("Short read of Key and Length got %lu\n", read_count);
+ DefaultLogSink().Error("Short read of Key and Length got %u\n", read_count);
return RESULT_READFAIL;
}
return RESULT_FAIL;
}
- if ( ! read_BER(tmp_data + SMPTE_UL_LENGTH, &tmp_size) )
+ if ( ! Kumu::read_BER(tmp_data + SMPTE_UL_LENGTH, &tmp_size) )
{
DefaultLogSink().Error("BER Length decoding error\n");
return RESULT_FAIL;
if ( tmp_size > MAX_KLV_PACKET_LENGTH )
{
- char intbuf[IntBufferLen];
- DefaultLogSink().Error("Packet length %s exceeds internal limit\n",
- ui64sz(tmp_size, intbuf));
+ Kumu::ui64Printer tmp_size_str(tmp_size);
+ DefaultLogSink().Error("Packet length %s exceeds internal limit\n", tmp_size_str.c_str());
return RESULT_FAIL;
}
ui32_t remainder = 0;
- ui32_t ber_len = BER_length(tmp_data + SMPTE_UL_LENGTH);
+ ui32_t ber_len = Kumu::BER_length(tmp_data + SMPTE_UL_LENGTH);
m_KLLength = SMPTE_UL_LENGTH + ber_len;
- m_ValueLength = tmp_size;
+ assert(tmp_size <= 0xFFFFFFFFL);
+ m_ValueLength = (ui32_t) tmp_size;
ui32_t packet_length = m_ValueLength + m_KLLength;
result = m_Buffer.Capacity(packet_length);
if ( (remainder = read_count - packet_length) != 0 )
{
DefaultLogSink().Warn("Repositioning pointer for short packet\n");
- ASDCP::fpos_t pos = Reader.Tell();
+ Kumu::fpos_t pos = Reader.Tell();
assert(pos > remainder);
result = Reader.Seek(pos - remainder);
}
{
if ( read_count < tmp_read_size )
{
- DefaultLogSink().Error("Short read of packet body, expecting %lu, got %lu\n",
+ DefaultLogSink().Error("Short read of packet body, expecting %u, got %u\n",
m_Buffer.Size(), read_count);
return RESULT_READFAIL;
}
if ( read_count != remainder )
{
- DefaultLogSink().Error("Short read of packet body, expecting %lu, got %lu\n",
+ DefaultLogSink().Error("Short read of packet body, expecting %u, got %u\n",
remainder+tmp_read_size, read_count+tmp_read_size);
result = RESULT_READFAIL;
}
//
ASDCP::Result_t
-ASDCP::KLVFilePacket::WriteKLToFile(FileWriter& Writer, const byte_t* label, ui32_t length)
+ASDCP::KLVFilePacket::WriteKLToFile(Kumu::FileWriter& Writer, const UL& label, ui32_t length)
{
byte_t buffer[kl_length];
- memcpy(buffer, label, SMPTE_UL_LENGTH);
+ memcpy(buffer, label.Value(), label.Size());
- if ( ! write_BER(buffer+SMPTE_UL_LENGTH, length, MXF_BER_LENGTH) )
+ if ( ! Kumu::write_BER(buffer+SMPTE_UL_LENGTH, length, MXF_BER_LENGTH) )
return RESULT_FAIL;
ui32_t write_count;