summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjhurst <jhurst@cinecert.com>2006-04-05 23:03:55 +0000
committerjhurst <>2006-04-05 23:03:55 +0000
commitbfedf725dac9d13f3a02fe69f45c302ab29d2b1e (patch)
tree4a746f759dcb62ebeb6309373e7579d6048f4af6
parentfdf31e0105bf8272a6b7fa9c4039941dff37a271 (diff)
ginormo merge-back with Kumu, SMPTE MIC key and MPEG parser fix
-rwxr-xr-xAS_DCP_UUID.cpp125
-rwxr-xr-xAS_DCP_system.h191
-rwxr-xr-xDirScanner.cpp189
-rwxr-xr-xDirScanner.h91
-rwxr-xr-xFortunaRNG.cpp207
-rwxr-xr-xFortunaRNG.h72
-rwxr-xr-xIdentifier.h190
-rwxr-xr-xREADME70
-rwxr-xr-xhex_utils.h83
-rwxr-xr-xsrc/AS_DCP.cpp387
-rwxr-xr-xsrc/AS_DCP.h245
-rwxr-xr-xsrc/AS_DCP_AES.cpp87
-rwxr-xr-xsrc/AS_DCP_JP2K.cpp24
-rwxr-xr-xsrc/AS_DCP_MPEG2.cpp2
-rwxr-xr-xsrc/AS_DCP_MXF.cpp42
-rwxr-xr-xsrc/AS_DCP_PCM.cpp2
-rwxr-xr-xsrc/AS_DCP_internal.h19
-rwxr-xr-xsrc/Dict.cpp7
-rwxr-xr-xsrc/Index.cpp82
-rwxr-xr-xsrc/JP2K.cpp9
-rwxr-xr-xsrc/JP2K.h31
-rwxr-xr-xsrc/JP2K_Codestream_Parser.cpp10
-rwxr-xr-xsrc/JP2K_Sequence_Parser.cpp9
-rwxr-xr-xsrc/KLV.cpp34
-rwxr-xr-xsrc/KLV.h81
-rwxr-xr-xsrc/KM_error.h117
-rw-r--r--[-rwxr-xr-x]src/KM_fileio.cpp (renamed from FileIO.cpp)453
-rwxr-xr-xsrc/KM_fileio.h (renamed from FileIO.h)107
-rwxr-xr-xsrc/KM_log.cpp155
-rwxr-xr-xsrc/KM_log.h133
-rwxr-xr-xsrc/KM_memio.h (renamed from MemIO.h)168
-rwxr-xr-xsrc/KM_mutex.h (renamed from Mutex.h)39
-rw-r--r--src/KM_platform.h189
-rwxr-xr-xsrc/KM_prng.cpp214
-rwxr-xr-xsrc/KM_prng.h (renamed from AS_DCP_UUID.h)36
-rwxr-xr-xsrc/KM_util.cpp921
-rwxr-xr-xsrc/KM_util.h392
-rwxr-xr-xsrc/MPEG.cpp118
-rwxr-xr-xsrc/MPEG.h31
-rwxr-xr-xsrc/MPEG2_Parser.cpp93
-rwxr-xr-xsrc/MXF.cpp171
-rwxr-xr-xsrc/MXF.h91
-rwxr-xr-xsrc/MXFTypes.cpp238
-rwxr-xr-xsrc/MXFTypes.h200
-rwxr-xr-xsrc/Metadata.cpp85
-rwxr-xr-xsrc/PCM_Parser.cpp6
-rwxr-xr-xsrc/Wav.cpp61
-rwxr-xr-xsrc/Wav.h9
-rwxr-xr-xsrc/WavFileWriter.h10
-rwxr-xr-xsrc/asdcp-test.cpp124
-rw-r--r--src/blackwave.cpp245
-rwxr-xr-xsrc/h__Reader.cpp26
-rwxr-xr-xsrc/h__Writer.cpp21
-rwxr-xr-xsrc/klvwalk.cpp24
-rwxr-xr-xsrc/wavesplit.cpp369
55 files changed, 4397 insertions, 2738 deletions
diff --git a/AS_DCP_UUID.cpp b/AS_DCP_UUID.cpp
deleted file mode 100755
index 39daeb0..0000000
--- a/AS_DCP_UUID.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-Copyright (c) 2005, John Hurst
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/*! \file AS_DCP_UUID.cpp
- \version $Id$
- \brief Miscellaneous timecode functions
-*/
-
-#include <AS_DCP_UUID.h>
-#include <assert.h>
-
-
-static FortunaRNG s_RNG;
-
-using namespace ASDCP;
-
-
-// given a 16 byte buffer, this subroutine uses the given RNG to generate a
-// random value, and sets the necessary bits to turn the value into a proper UUID per
-// sec. 4.4 of http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-03.txt
-// Parts of that document are reprinted here for your convenience:
-//
-// 0 1 2 3
-// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | time_low |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | time_mid | time_hi_and_version |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// |clk_seq_hi_res | clk_seq_low | node (0-1) |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-// | node (2-5) |
-// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-//
-// Msb0 Msb1 Msb2 Msb3 Version Description
-//
-// 0 1 0 0 4 The randomly or pseudo-
-// randomly generated version
-// specified in this document.
-//
-// o Set the two most significant bits (bits six and seven) of the
-// clock_seq_hi_and_reserved to zero and one, respectively.
-// o Set the four most significant bits (bits 12 through 15) of the
-// time_hi_and_version field to the four-bit version number from
-// Section 4.1.3.
-// o Set all the other bits to randomly (or pseudo-randomly) chosen
-// values.
-//
-
-// fill buffer with random bits and set appropriate UUID flags
-void
-ASDCP::GenRandomUUID(FortunaRNG& RNG, byte_t* buf)
-{
- assert(buf);
- RNG.FillRandom(buf, UUIDlen);
- buf[6] &= 0x0f; // clear bits 4-7
- buf[6] |= 0x40; // set UUID version
- buf[8] &= 0x3f; // clear bits 6&7
- buf[8] |= 0x80; // set bit 7
-}
-
-// add UUID hyphens to 32 character hexadecimal string
-char*
-ASDCP::hyphenate_UUID(char* str_buf, ui32_t buf_len)
-{
- ui32_t i, j, k;
-
- assert(str_buf);
- assert (buf_len > 36);
-
- // shift the node id
- for ( k = 19, i = 12; i > 0; i-- )
- str_buf[k+i+4] = str_buf[k+i];
-
- // shift the time (mid+hi+clk)
- for ( k = 15, j = 3; k > 6; k -= 4, j-- )
- {
- for ( i = 4; i > 0; i-- )
- str_buf[k+i+j] = str_buf[k+i];
- }
-
- // add in the hyphens and trainling null
- for ( i = 8; i < 24; i += 5 )
- str_buf[i] = '-';
-
- str_buf[36] = 0;
- return str_buf;
-}
-
-
-//
-void
-ASDCP::MakeUUID(byte_t* buf)
-{
- GenRandomUUID(s_RNG, buf);
-}
-
-
-
-//
-// end AS_DCP_UUID.cpp
-//
diff --git a/AS_DCP_system.h b/AS_DCP_system.h
deleted file mode 100755
index 3b02836..0000000
--- a/AS_DCP_system.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
-Copyright (c) 2004-2005, John Hurst
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/*! \file AS_DCP_system.h
- \version $Id$
- \brief AS-DCP portable types and byte swapping
-*/
-
-
-#ifndef _AS_DCP_SYSTEM_H_
-#define _AS_DCP_SYSTEM_H_
-
-#ifdef __APPLE__
-#define ASDCP_BIG_ENDIAN
-#endif
-
-// 64 bit types are not used in the public interface
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#define VC_EXTRALEAN
-#include <windows.h>
-#pragma warning(disable:4786) // Ignore "identifer > 255 characters" warning
-#define snprintf _snprintf
-
-#ifndef ASDCP_NO_BASE_TYPES
-typedef unsigned __int64 ui64_t;
-typedef __int64 i64_t;
-#define i64_C(c) (i64_t)(c)
-#define ui64_C(c) (ui64_t)(c)
-#endif
-
-#else // WIN32
-
-#ifndef ASDCP_NO_BASE_TYPES
-typedef unsigned long long ui64_t;
-typedef long long i64_t;
-#define i64_C(c) c##LL
-#define ui64_C(c) c##ULL
-#endif
-
-#endif // WIN32
-
-#include <AS_DCP.h>
-#include <assert.h>
-
-namespace ASDCP {
-
- inline ui16_t Swap2(ui16_t i)
- {
- return ( (i << 8) | (( i & 0xff00) >> 8) );
- }
-
- inline ui32_t Swap4(ui32_t i)
- {
- return
- ( (i & 0x000000ffUL) << 24 ) |
- ( (i & 0xff000000UL) >> 24 ) |
- ( (i & 0x0000ff00UL) << 8 ) |
- ( (i & 0x00ff0000UL) >> 8 );
- }
-
- inline ui64_t Swap8(ui64_t i)
- {
- return
- ( (i & ui64_C(0x00000000000000FF)) << 56 ) |
- ( (i & ui64_C(0xFF00000000000000)) >> 56 ) |
- ( (i & ui64_C(0x000000000000FF00)) << 40 ) |
- ( (i & ui64_C(0x00FF000000000000)) >> 40 ) |
- ( (i & ui64_C(0x0000000000FF0000)) << 24 ) |
- ( (i & ui64_C(0x0000FF0000000000)) >> 24 ) |
- ( (i & ui64_C(0x00000000FF000000)) << 8 ) |
- ( (i & ui64_C(0x000000FF00000000)) >> 8 );
- }
-
- //
- template<class T>
- inline T xmin(T lhs, T rhs)
- {
- return (lhs < rhs) ? lhs : rhs;
- }
-
- //
- template<class T>
- inline T xmax(T lhs, T rhs)
- {
- return (lhs > rhs) ? lhs : rhs;
- }
-
- // read an integer from byte-structured storage
- template<class T>
- inline T cp2i(const byte_t* p) { return *(T*)p; }
-
- // write an integer to byte-structured storage
- template<class T>
- inline void i2p(T i, byte_t* p) { *(T*)p = i; }
-
-#ifdef ASDCP_BIG_ENDIAN
-#define ASDCP_i16_LE(i) ASDCP::Swap2(i)
-#define ASDCP_i32_LE(i) ASDCP::Swap4(i)
-#define ASDCP_i64_LE(i) ASDCP::Swap8(i)
-#define ASDCP_i16_BE(i) (i)
-#define ASDCP_i32_BE(i) (i)
-#define ASDCP_i64_BE(i) (i)
-#else
-#define ASDCP_i16_LE(i) (i)
-#define ASDCP_i32_LE(i) (i)
-#define ASDCP_i64_LE(i) (i)
-#define ASDCP_i16_BE(i) ASDCP::Swap2(i)
-#define ASDCP_i32_BE(i) ASDCP::Swap4(i)
-#define ASDCP_i64_BE(i) ASDCP::Swap8(i)
-#endif // ASDCP_BIG_ENDIAN
-
-
-// 64 bit integer/text conversion
-//
- const ui32_t IntBufferLen = 32;
-
- inline i64_t atoi64(const char *str) {
-#ifdef WIN32
- return _atoi64(str);
-#else
- return strtoll(str, NULL, 10);
-#endif
- }
-
- inline const char* i64sz(i64_t i, char* buf)
- {
- assert(buf);
-#ifdef WIN32
- snprintf(buf, IntBufferLen, "%I64d", i);
-#else
- snprintf(buf, IntBufferLen, "%lld", i);
-#endif
- return buf;
- }
-
- inline const char* ui64sz(ui64_t i, char* buf)
- {
- assert(buf);
-#ifdef WIN32
- snprintf(buf, IntBufferLen, "%I64u", i);
-#else
- snprintf(buf, IntBufferLen, "%llu", i);
-#endif
- return buf;
- }
-
- inline const char* i64szx(i64_t i, ui32_t digits, char* buf)
- {
- assert(buf);
- if ( digits > 30 ) digits = 30;
-#ifdef WIN32
- snprintf(buf, IntBufferLen, "%0*I64x", digits, i);
-#else
- snprintf(buf, IntBufferLen, "%0*llx", digits, i);
-#endif
- return buf;
- }
-
-} // namespace ASDCP
-
-
-
-#endif // _AS_DCP_SYSTEM_H_
-
-//
-// AS_DCP_system.h
-//
diff --git a/DirScanner.cpp b/DirScanner.cpp
deleted file mode 100755
index 6c3c40a..0000000
--- a/DirScanner.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
-Copyright (c) 2004-2005, John Hurst
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/*! \file DirScanner.cpp
- \version $Id$
- \brief Cross-platform, simple non-recursive directory scanner
-*/
-
-#include <DirScanner.h>
-#include <errno.h>
-#include <assert.h>
-
-// Win32 directory scanner
-//
-#ifdef WIN32
-
-//
-//
-ASDCP::Result_t
-DirScanner::Open(const char* filename)
-{
- ASDCP_TEST_NULL_STR(filename);
-
- // we need to append a '*' to read the entire directory
- ui32_t fn_len = strlen(filename);
- char* tmp_file = (char*)malloc(fn_len + 8);
-
- if ( tmp_file == 0 )
- return ASDCP::RESULT_ALLOC;
-
- strcpy(tmp_file, filename);
- char* p = &tmp_file[fn_len] - 1;
-
- if ( *p != '/' && *p != '\\' )
- {
- p++;
- *p++ = '/';
- }
-
- *p++ = '*';
- *p = 0;
- // whew...
-
- m_Handle = _findfirsti64(tmp_file, &m_FileInfo);
- ASDCP::Result_t result = ASDCP::RESULT_OK;
-
- if ( m_Handle == -1 )
- result = ASDCP::RESULT_NOT_FOUND;
-
- return result;
-}
-
-
-//
-//
-ASDCP::Result_t
-DirScanner::Close()
-{
- if ( m_Handle == -1 )
- return ASDCP::RESULT_FILEOPEN;
-
- if ( _findclose((long)m_Handle) == -1 )
- return ASDCP::RESULT_FAIL;
-
- m_Handle = -1;
- return ASDCP::RESULT_OK;
-}
-
-
-// This sets filename param to the same per-instance buffer every time, so
-// the value will change on the next call
-ASDCP::Result_t
-DirScanner::GetNext(char* filename)
-{
- ASDCP_TEST_NULL(filename);
-
- if ( m_Handle == -1 )
- return ASDCP::RESULT_FILEOPEN;
-
- if ( m_FileInfo.name[0] == '\0' )
- return ASDCP::RESULT_ENDOFFILE;
-
- strncpy(filename, m_FileInfo.name, ASDCP_MAX_PATH);
- ASDCP::Result_t result = ASDCP::RESULT_OK;
-
- if ( _findnexti64((long)m_Handle, &m_FileInfo) == -1 )
- {
- m_FileInfo.name[0] = '\0';
-
- if ( errno != ENOENT )
- result = ASDCP::RESULT_FAIL;
- }
-
- return result;
-}
-
-
-#else // WIN32
-
-// POSIX directory scanner
-
-//
-ASDCP::Result_t
-DirScanner::Open(const char* filename)
-{
- ASDCP_TEST_NULL_STR(filename);
-
- ASDCP::Result_t result = ASDCP::RESULT_OK;
-
- if ( ( m_Handle = opendir(filename) ) == NULL )
- {
- if ( errno == ENOENT )
- result = ASDCP::RESULT_ENDOFFILE;
-
- else
- result = ASDCP::RESULT_FAIL;
- }
-
- return result;
-}
-
-
-//
-ASDCP::Result_t
-DirScanner::Close()
-{
- if ( m_Handle == NULL )
- return ASDCP::RESULT_FILEOPEN;
-
- if ( closedir(m_Handle) == -1 )
- return ASDCP::RESULT_FAIL;
-
- m_Handle = NULL;
- return ASDCP::RESULT_OK;
-}
-
-
-//
-ASDCP::Result_t
-DirScanner::GetNext(char* filename)
-{
- ASDCP_TEST_NULL(filename);
-
- if ( m_Handle == NULL )
- return ASDCP::RESULT_FILEOPEN;
-
- struct dirent* entry;
-
- for (;;)
- {
- if ( ( entry = readdir(m_Handle)) == NULL )
- return ASDCP::RESULT_ENDOFFILE;
-
- break;
- }
-
- strncpy(filename, entry->d_name, ASDCP_MAX_PATH);
- return ASDCP::RESULT_OK;
-}
-
-
-#endif // WIN32
-
-//
-// end DirScanner.cpp
-//
diff --git a/DirScanner.h b/DirScanner.h
deleted file mode 100755
index fba681b..0000000
--- a/DirScanner.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-Copyright (c) 2004-2005, John Hurst
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/*! \file DirScanner.h
- \version $Id$
- \brief Cross-platform, simple non-recursive directory scanner
-*/
-
-#ifndef _DIRSCANNER_H_
-#define _DIRSCANNER_H_
-
-#include <AS_DCP_system.h>
-#define ASDCP_MAX_PATH 256
-
-// Win32 directory scanner
-//
-#ifdef WIN32
-#include <io.h>
-
-//
-//
-class DirScanner
-{
- public:
- __int64 m_Handle;
- struct _finddatai64_t m_FileInfo;
-
- DirScanner() {};
- ~DirScanner() { Close(); }
- ASDCP::Result_t Open(const char*);
- ASDCP::Result_t Close();
- ASDCP::Result_t GetNext(char*);
-};
-
-
-#else // WIN32
-
-#include <dirent.h>
-
-// POSIX directory scanner
-
-//
-//
-class DirScanner
-{
- public:
- DIR* m_Handle;
-
- DirScanner() : m_Handle(NULL)
- {
- }
-
- ~DirScanner() { Close(); }
-
- ASDCP::Result_t Open(const char*);
- ASDCP::Result_t Close();
- ASDCP::Result_t GetNext(char*);
-};
-
-
-#endif // WIN32
-
-#endif // _DIRSCANNER_H_
-
-
-//
-// end DirScanner.h
-//
diff --git a/FortunaRNG.cpp b/FortunaRNG.cpp
deleted file mode 100755
index 9c444c8..0000000
--- a/FortunaRNG.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
-Copyright (c) 2004, John Hurst
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/*! \file FortunaRNG.cpp
- \version $Id$
- \brief Fortuna PRNG implementation
-*/
-
-
-/*
- This module partially implements the Fortuna PRNG described in Chapter
- 10 of "Practical Cryptography", Ferguson & Schneier, 2003.
-
- The generator does not use a hash to stir the key, nor does it limit
- the block size of generated blocks. It does NOT implement a cross-
- platform entropy collector.
-
- In fact, the seed methods in use here should be regarded with great
- suspicion. This module is provided as a development aid, and is not
- endorsed for any use outside that narrow purpose.
- */
-
-
-#include <FortunaRNG.h>
-#include <string.h>
-#include <assert.h>
-#include <openssl/aes.h>
-
-
-const ui32_t RNG_KEY_SIZE = 16;
-const ui32_t RNG_KEY_SIZE_BITS = 128;
-const ui32_t RNG_BLOCK_SIZE = 16;
-
-// internal implementation class
-class FortunaRNG::h__RNG
-{
-public:
- AES_KEY m_Context;
- byte_t m_rng_buf[RNG_BLOCK_SIZE];
-
- //
- void
- fill_rand(byte_t* buf, ui32_t len)
- {
- ui32_t gen_count = 0;
-
- while ( gen_count + RNG_BLOCK_SIZE <= len )
- {
- AES_encrypt(m_rng_buf, buf + gen_count, &m_Context);
- *(ui32_t*)(m_rng_buf + 12) += 3;
- gen_count += RNG_BLOCK_SIZE;
- }
-
- if ( len == gen_count ) // partial count needed?
- return;
-
- byte_t tmp[RNG_BLOCK_SIZE];
- AES_encrypt(m_rng_buf, tmp, &m_Context);
- *(ui32_t*)(m_rng_buf + 12) += 3;
- memcpy(buf + gen_count, tmp, len - gen_count);
- }
-
- void
- re_seed()
- {
- // re-seed the generator
- byte_t rng_key[RNG_KEY_SIZE];
- fill_rand(rng_key, RNG_KEY_SIZE);
- AES_set_encrypt_key(rng_key, RNG_KEY_SIZE_BITS, &m_Context);
- }
-};
-
-
-// we have separate constructor implementations depending upon platform:
-//
-
-#ifdef WIN32
-// on win32 systems, we grab one bit at a time from the performance
-// counter and assemble seed bytes from the collected bits
-
-#define WIN32_LEAN_AND_MEAN
-#define VC_EXTRALEAN
-#include <windows.h>
-
-//
-static byte_t get_perf_byte()
-{
- LARGE_INTEGER ticks;
- byte_t retval;
-
- for ( int i = 0; i < 8; i++ )
- {
- QueryPerformanceCounter(&ticks);
- retval |= (ticks.LowPart & 0x00000001) << i;
- }
-
- return retval;
-}
-
-//
-FortunaRNG::FortunaRNG()
-{
- m_RNG = new h__RNG;
- byte_t rng_key[RNG_KEY_SIZE];
- int i;
-
- for ( i = 0; i < RNG_KEY_SIZE; i++ )
- rng_key[i] = get_perf_byte();
-
- for ( i = 0; i < RNG_BLOCK_SIZE; i++ )
- m_RNG->m_rng_buf[i] = get_perf_byte();
-
- AES_set_encrypt_key(rng_key, RNG_KEY_SIZE_BITS, &m_RNG->m_Context);
-}
-
-#else // WIN32
-// on POSIX systems, we simply read some seed from /dev/urandom
-
-#include <stdio.h>
-
-const char* DEV_URANDOM = "/dev/urandom";
-
-FortunaRNG::FortunaRNG()
-{
- m_RNG = new h__RNG;
-
- byte_t rng_key[RNG_KEY_SIZE];
- FILE* dev_random = fopen(DEV_URANDOM, "r");
-
- if ( dev_random == 0 )
- {
- ASDCP::DefaultLogSink().Error("Unable to open DEV_URANDOM\n");
- perror(DEV_URANDOM);
- m_RNG = 0;
- return;
- }
-
- if ( fread(rng_key, 1, RNG_KEY_SIZE, dev_random) != RNG_KEY_SIZE )
- {
- fclose(dev_random);
- ASDCP::DefaultLogSink().Error("Unable to read DEV_URANDOM\n");
- perror(DEV_URANDOM);
- m_RNG = 0;
- return;
- }
-
- if ( fread(m_RNG->m_rng_buf, 1, RNG_BLOCK_SIZE, dev_random) != RNG_BLOCK_SIZE )
- {
- fclose(dev_random);
- ASDCP::DefaultLogSink().Error("Unable to read DEV_URANDOM\n");
- perror(DEV_URANDOM);
- m_RNG = 0;
- return;
- }
-
- fclose(dev_random);
- AES_set_encrypt_key(rng_key, RNG_KEY_SIZE_BITS, &m_RNG->m_Context);
-}
-
-#endif // WIN32
-
-FortunaRNG::~FortunaRNG()
-{
-}
-
-//
-byte_t*
-FortunaRNG::FillRandom(byte_t* buf, ui32_t len)
-{
- assert(buf);
-
- if ( ! m_RNG )
- return 0;
-
- m_RNG->fill_rand(buf, len);
- m_RNG->re_seed();
-
- return buf;
-}
-
-
-//
-// end FortunaRNG.cpp
-//
diff --git a/FortunaRNG.h b/FortunaRNG.h
deleted file mode 100755
index 356af8b..0000000
--- a/FortunaRNG.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-Copyright (c) 2004, John Hurst
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/*! \file FortunaRNG.h
- \version $Id$
- \brief Fortuna PRNG interface
-*/
-
-
-/*
- This module partially implements the Fortuna PRNG described in Chapter
- 10 of "Practical Cryptography", Ferguson & Schneier, 2003.
-
- The generator does not use a hash to stir the key, nor does it limit
- the block size of generated blocks. It does NOT implement a cross-
- platform entropy collector.
-
- In fact, the seed methods in use here should be regarded with great
- suspicion. This module is provided as a development aid, and is not
- endorsed for any use outside that narrow purpose.
- */
-
-
-
-#ifndef __FORTUNARNG_H__
-#define __FORTUNARNG_H__
-
-#include <AS_DCP.h> // re-using handy typedefs
-
-
-class FortunaRNG
-{
- class h__RNG;
- ASDCP::mem_ptr<h__RNG> m_RNG;
- ASDCP_NO_COPY_CONSTRUCT(FortunaRNG);
-
- public:
- FortunaRNG();
- ~FortunaRNG();
- byte_t* FillRandom(byte_t* buf, ui32_t len);
-};
-
-
-
-#endif // __FORTUNARNG_H__
-
-//
-// end FortunaRNG.h
-//
diff --git a/Identifier.h b/Identifier.h
deleted file mode 100755
index 4fbd716..0000000
--- a/Identifier.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
-Copyright (c) 2005-2006, John Hurst
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/*! \file Identifier.h
- \version $Id$
- \brief strings of bytes that identify things
-*/
-
-#ifndef _IDENTIFIER_H_
-#define _IDENTIFIER_H_
-
-namespace ASDCP
-{
- // the base of all identifier classes
- template <ui32_t SIZE>
- class Identifier : public IArchive
- {
- protected:
- byte_t m_Value[SIZE];
- bool m_HasValue;
-
- public:
- Identifier() : m_HasValue(false) {
- memset(m_Value, 0, SIZE);
- }
-
- //
- inline Result_t Set(const byte_t* value) {
- ASDCP_TEST_NULL(value);
- memcpy(m_Value, value, SIZE);
- m_HasValue = true;
- return RESULT_OK;
- }
-
- //
- inline Identifier& operator=(const Identifier& rhs)
- {
- Set(rhs.m_Value);
- return *this;
- }
-
- //
- inline Result_t Unarchive(ASDCP::MemIOReader& Reader) {
- Result_t result = Reader.ReadRaw(m_Value, SIZE);
- if ( ASDCP_SUCCESS(result) ) m_HasValue = true;
- return result;
- }
-
- inline bool HasValue() const { return m_HasValue; }
-
- //
- inline Result_t Archive(ASDCP::MemIOWriter& Writer) const {
- return Writer.WriteRaw(m_Value, SIZE);
- }
-
- inline const byte_t* Value() const { return m_Value; }
-
- inline ui32_t Size() const { return SIZE; }
-
- //
- inline bool operator<(const Identifier& rhs) const
- {
- for ( ui32_t i = 0; i < SIZE; i++ )
- {
- if ( m_Value[i] != rhs.m_Value[i] )
- return m_Value[i] < rhs.m_Value[i];
- }
-
- return false;
- }
-
- //
- inline bool operator==(const Identifier& rhs) const
- {
- if ( rhs.Size() != SIZE )
- return false;
-
- return ( memcmp(m_Value, rhs.m_Value, SIZE) == 0 );
- }
-
- //
- // todo: refactor characrer insertion back to bin2hex()
- const char* ToString(char* str_buf) const
- {
- char* p = str_buf;
-
- for ( ui32_t i = 0; i < SIZE; i++ )
- {
- *p = (m_Value[i] >> 4) & 0x0f;
- *p += *p < 10 ? 0x30 : 0x61 - 10;
- p++;
-
- *p = m_Value[i] & 0x0f;
- *p += *p < 10 ? 0x30 : 0x61 - 10;
- p++;
-
- *p = ' ';
- p++;
- }
-
- *p = 0;
- return str_buf;
- }
- };
-
-
- class UL;
- class UUID;
- class UMID;
-
- // Universal Label
- class UL : public Identifier<SMPTE_UL_LENGTH>
- {
- public:
- UL() {}
- UL(const byte_t* rhs) {
- assert(rhs);
- Set(rhs);
- }
-
- UL(const UL& rhs) {
- Set(rhs.m_Value);
- }
-
- bool operator==(const UL& rhs) const {
- return ( memcmp(m_Value, rhs.m_Value, SMPTE_UL_LENGTH) == 0 ) ? true : false;
- }
- };
-
- // UUID
- class UUID : public Identifier<UUIDlen>
- {
- public:
- UUID() {}
- UUID(const byte_t* rhs) {
- assert(rhs);
- Set(rhs);
- }
-
- UUID(const UUID& rhs) {
- Set(rhs.m_Value);
- }
-
- void GenRandomValue();
- };
-
- // UMID
- class UMID : public Identifier<SMPTE_UMID_LENGTH>
- {
- public:
- UMID() {}
- UMID(const UMID &rhs) {
- Set(rhs.m_Value);
- };
-
- void MakeUMID(int Type);
- void MakeUMID(int Type, const UUID& ID);
- const char* ToString(char* str_buf) const;
- };
-
-} // namespace mxflib
-
-#endif // _IDENTIFIER_H_
-
-//
-// end Identifier.h
-//
diff --git a/README b/README
index dbd73fd..3d91c88 100755
--- a/README
+++ b/README
@@ -7,17 +7,15 @@ picture track file formats proposed by the SMPTE working
group DC-28.20.
This work was originally funded by Digital Cinema
-Initiatives, LLC. Subsequent efforts have been funded by
-Deluxe Laboratories, Doremi Labs, CineCert, LLC. and others.
+Initiatives, LLC (DCI). Subsequent efforts have been funded
+by Deluxe Laboratories, Doremi Labs, CineCert, LLC, Avica
+Technology and others.
-**The asdcplib project is housed on SourceForge. The project
-home page is at http://sourceforge.net/projects/asdcplib.
-There is not much there other than CVS because I don't
-really have the time to master SourceForge administration.
-Feel free to email with questions or to request a tar file.
+**The asdcplib project was housed on SourceForge. The project
+will be moving to a new home, to be announced here soon.
-The project used to depend upon the mxflib project. Because
-of the focus on covering the whole of the MXF spscifications,
+The project formerly depended upon the mxflib project. Because
+of its focus on covering the whole of the MXF specifications,
mxflib is considerably larger and more complex that what I
require for this application. For this reason I have created
a dedicated MXF implementation that is now part of this
@@ -55,7 +53,9 @@ objects which provide those services.
AS_DCP.h contains the entire API. You do not need to read
any of the other files, except maybe asdcp-test.cpp which
contains detailed usage examples of each of the API's
-services.
+services. The KM_* files may be of interest for general
+development support, but may be ignored if all you want
+is simple AS-DCP support.
Build Instructions
@@ -83,6 +83,21 @@ I have tested this build on win32, Linux and Darwin platforms.
Others may work as well.
+Utilities
+
+asdcp-test - Writes, reads and verifies AS-DCP (MXF) track files.
+
+asdcp-lf-test - Writes and verifies large files using a platform-
+independent format. Use it to test issues related to large files.
+
+wavesplit - Splits a WAVE file into two or more output files. Used
+ to untangle incorrectly-paired DCDM sound files.
+
+blackwave - Write a WAVE file full of zeros, Used to make filler
+ tracks (though you would be better off modifying asdcp-test if
+ this is a common use case).
+
+
Documentation
Currently, the documentation is mostly in AS_DCP.h. Read
@@ -92,6 +107,41 @@ examples. More detailed documentation will be written RSN.
Change History
+2006.04.05 - Bug fixes and new stuff
+ o Fixed a bug in the MPEG parser that caused it to fail when
+ handling start codes spanning buffer boundaries
+ o Added wavesplit and blackwave utility programs
+ o Added support for revised SMPTE HMAC key derivation when
+ using LS_MXF_SMPTE
+ o Refactored platform compatibility and general utilities
+ into a new sub-library "Kumu". There are no new build
+ steps or dependencies, but some important things have
+ changed:
+ + Result_t is no longer an enum, it is now a class.
+ Library result codes are now declared as const objects
+ like this:
+
+ const Kumu::Result_t RESULT_FORMAT (-101, "The file...");
+
+ The macros ASDCP_SUCCESS and ASDCP_FAILURE still work
+ the same thanks to an operator overload for long. See
+ KM_error.h for more information.
+ + The logging interface has been moved out of AS_DCP.h
+ and into KM_log.h
+ o Some of the command line utilities that were using headers
+ other than AS_DCP.h have been changed to us the Kumu
+ equivalents. If you have code based on those utilities, you
+ will have to update by hand.
+ o Added new types to the EssenceType_t enum.
+ o The guard macro for Win32 code has changed from WIN32 to
+ KM_WIN32.
+
+
+2006.03.2x - new stuff
+ o Proper handling of stream-id byte of essence UL values
+ o writes 3-partition files, reads 2-part or 3-part
+
+
2006.03.16 - bug fixes plus
o Removed SMPTE_LABELS compile-time option. The reader will now
silently accept either SMPTE or MXF Interop labels, the writer
diff --git a/hex_utils.h b/hex_utils.h
deleted file mode 100755
index 5f51876..0000000
--- a/hex_utils.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-Copyright (c) 2004-2005, John Hurst
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-/*! \file hex_utils.h
- \version $Id$
- \brief AS-DCP library, printable hex utilities
-*/
-
-#ifndef _AS_DCP_HEX_UTILS_H__
-#define _AS_DCP_HEX_UTILS_H__
-
-namespace ASDCP
-{
- // Convert NULL-terminated UTF-8 hexadecimal string to binary, returns 0 if
- // the binary buffer was large enough to hold the result. The output parameter
- // 'char_count' will contain the length of the converted string. If the output
- // buffer is too small or any of the pointer arguments are NULL, the subroutine
- // will return -1 and set 'char_count' to the required buffer size. No data will
- // be written to 'buf' if the subroutine fails.
- i32_t hex2bin(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* char_count);
-
- // Convert a binary string to NULL-terminated UTF-8 hexadecimal, returns the buffer
- // if the binary buffer was large enough to hold the result. If the output buffer
- // is too small or any of the pointer arguments are NULL, the subroutine will
- // return 0.
- //
- const char* bin2hex(const byte_t* bin_buf, ui32_t bin_len, char* str_buf, ui32_t str_len);
-
-
- // print to a stream the contents of the buffer as hexadecimal numbers in numbered
- // rows of 16-bytes each.
- //
- void hexdump(const byte_t* buf, ui32_t dump_len, FILE* stream = 0);
-
- // Return the length in bytes of a BER encoded value
- inline ui32_t BER_length(const byte_t* buf)
- {
- if ( buf == 0 || (*buf & 0xf0) != 0x80 )
- return 0;
-
- return (*buf & 0x0f) + 1;
- }
-
- // read a BER value
- bool read_BER(const byte_t* buf, ui64_t* val);
-
- // decode a ber value and compare it to a test value
- bool read_test_BER(byte_t **buf, ui64_t test_value);
-
- // create BER encoding of integer value
- bool write_BER(byte_t* buf, ui64_t val, ui32_t ber_len = 0);
-
-} // namespace ASDCP
-
-#endif // _AS_DCP_HEX_UTILS_H__
-
-//
-// end hex_utils.cpp
-//
-
diff --git a/src/AS_DCP.cpp b/src/AS_DCP.cpp
index a5187d6..12765c6 100755
--- a/src/AS_DCP.cpp
+++ b/src/AS_DCP.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004-2005, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -29,146 +29,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\brief AS-DCP library, misc classes and subroutines
*/
-#include <AS_DCP_system.h>
-#include "hex_utils.h"
+#include "AS_DCP_internal.h"
#include <assert.h>
-
-static const ui32_t s_MessageCount = 27;
-static const char* s_ErrorMessages[] =
-{
- "An undefined error was detected.",
- "An unexpected NULL pointer was given.",
- "An unexpected empty string was given.",
- "The given frame buffer is too small.",
- "The object is not yet initialized.",
-
- "The requested file does not exist on the system.",
- "Insufficient privilege exists to perform the operation.",
- "File open error.",
- "The file contains errors or is not OP-Atom/AS-DCP.",
- "An invalid file location was requested.",
-
- "File read error.",
- "File write error.",
- "Unknown raw essence file type.",
- "Raw essence format invalid.",
- "Object state error.",
-
- "Attempt to read past end of file.",
- "Invalid configuration option detected.",
- "Frame number out of range.",
- "AESEncContext required when writing to encrypted file",
- "Plaintext offset exceeds frame buffer size",
-
- "Error allocating memory",
- "Cannot resize externally allocated memory",
- "The check value did not decrypt correctly",
- "HMAC authentication failure",
- "HMAC context required",
-
- "Error initializing block cipher context",
- "Attempted to write an empty frame buffer"
-};
-
-
-//------------------------------------------------------------------------------------------
-
-//
-class StderrLogSink : public ASDCP::ILogSink
-{
-public:
- bool show_info;
- bool show_debug;
-
- StderrLogSink() : show_info(false), show_debug(false) {}
- ~StderrLogSink() {}
-
- void Error(const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vLogf(LOG_ERROR, fmt, &args);
- va_end(args);
- }
-
- void Warn(const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vLogf(LOG_WARN, fmt, &args);
- va_end(args);
- }
-
- void Info(const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vLogf(LOG_INFO, fmt, &args);
- va_end(args);
- }
-
- void Debug(const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vLogf(LOG_DEBUG, fmt, &args);
- va_end(args);
- }
-
- void Logf(ASDCP::ILogSink::LogType_t type, const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vLogf(type, fmt, &args);
- va_end(args);
- }
-
- void vLogf(ASDCP::ILogSink::LogType_t type, const char* fmt, va_list* list) {
- FILE* stream = stderr;
-
- switch ( type )
- {
- case LOG_ERROR: fputs("Error: ", stream); break;
- case LOG_WARN: fputs("Warning: ", stream); break;
- case LOG_INFO:
- if ( ! show_info ) return;
- fputs("Info: ", stream);
- break;
- case LOG_DEBUG:
- if ( ! show_debug ) return;
- fputs("Debug: ", stream);
- break;
- }
-
- vfprintf(stream, fmt, *list);
- }
-
-} s_StderrLogSink;
-
-//
-static ASDCP::ILogSink* s_DefaultLogSink = 0;
-
-//
-void
-ASDCP::SetDefaultLogSink(ILogSink* Sink)
-{
- s_DefaultLogSink = Sink;
-}
-
-// bootleg entry for debug enthusiasts
-void
-set_debug_mode(bool info_mode, bool debug_mode)
-{
- s_StderrLogSink.show_info = info_mode;
- s_StderrLogSink.show_debug = debug_mode;
-}
-
-// Returns the internal default sink.
-ASDCP::ILogSink&
-ASDCP::DefaultLogSink()
-{
- if ( s_DefaultLogSink == 0 )
- s_DefaultLogSink = &s_StderrLogSink;
-
- return *s_DefaultLogSink;
-}
-
const char*
ASDCP::Version()
{
@@ -178,252 +41,6 @@ ASDCP::Version()
}
-// Returns a pointer to an English language string describing the given result code.
-// If the result code is not a valid member of the Result_t enum, the string
-// "**UNKNOWN**" will be returned.
-const char*
-ASDCP::GetResultString(Result_t result)
-{
- if ( result >= 0 )
- return "No error.";
-
- ui32_t idx = (- result);
-
- if ( idx > s_MessageCount )
- return "**UNKNOWN**";
-
- return s_ErrorMessages[--idx];
-}
-
-
-// convert utf-8 hext string to bin
-i32_t
-ASDCP::hex2bin(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* conv_size)
-{
- ASDCP_TEST_NULL(str);
- ASDCP_TEST_NULL(buf);
- ASDCP_TEST_NULL(conv_size);
-
- *conv_size = 0;
-
- if ( str[0] == 0 ) // nothing to convert
- return 0;
-
- for ( int j = 0; str[j]; j++ )
- {
- if ( isxdigit(str[j]) )
- (*conv_size)++;
- }
-
- if ( *conv_size & 0x01 ) (*conv_size)++;
- *conv_size /= 2;
-
- if ( *conv_size > buf_len )// maximum possible data size
- return -1;
-
- *conv_size = 0;
-
- int phase = 0; // track high/low nybble
-
- // for each character, fill in the high nybble then the low
- for ( int i = 0; str[i]; i++ )
- {
- if ( ! isxdigit(str[i]) )
- continue;
-
- byte_t val = str[i] - ( isdigit(str[i]) ? 0x30 : ( isupper(str[i]) ? 0x37 : 0x57 ) );
-
- if ( phase == 0 )
- {
- buf[*conv_size] = val << 4;
- phase++;
- }
- else
- {
- buf[*conv_size] |= val;
- phase = 0;
- (*conv_size)++;
- }
- }
-
- return 0;
-}
-
-
-// convert a memory region to a NULL-terminated hexadecimal string
-//
-const char*
-ASDCP::bin2hex(const byte_t* bin_buf, ui32_t bin_len, char* str_buf, ui32_t str_len)
-{
- if ( bin_buf == 0
- || str_buf == 0
- || ((bin_len * 2) + 1) > str_len )
- return 0;
-
- char* p = str_buf;
-
- for ( ui32_t i = 0; i < bin_len; i++ )
- {
- *p = (bin_buf[i] >> 4) & 0x0f;
- *p += *p < 10 ? 0x30 : 0x61 - 10;
- p++;
-
- *p = bin_buf[i] & 0x0f;
- *p += *p < 10 ? 0x30 : 0x61 - 10;
- p++;
- }
-
- *p = '\0';
- return str_buf;
-}
-
-
-// spew a range of bin data as hex
-void
-ASDCP::hexdump(const byte_t* buf, ui32_t dump_len, FILE* stream)
-{
- if ( buf == 0 )
- return;
-
- if ( stream == 0 )
- stream = stderr;
-
- static ui32_t row_len = 16;
- const byte_t* p = buf;
- const byte_t* end_p = p + dump_len;
-
- for ( ui32_t line = 0; p < end_p; line++ )
- {
- fprintf(stream, " %06x: ", line);
- ui32_t i;
- const byte_t* pp;
-
- for ( pp = p, i = 0; i < row_len && pp < end_p; i++, pp++ )
- fprintf(stream, "%02x ", *pp);
-
- while ( i++ < row_len )
- fputs(" ", stream);
-
- for ( pp = p, i = 0; i < row_len && pp < end_p; i++, pp++ )
- fputc((isprint(*pp) ? *pp : '.'), stream);
-
- fputc('\n', stream);
- p += row_len;
- }
-}
-
-//------------------------------------------------------------------------------------------
-
-// read a ber value from the buffer and compare with test value.
-// Advances buffer to first character after BER value.
-//
-bool
-ASDCP::read_test_BER(byte_t **buf, ui64_t test_value)
-{
- if ( buf == 0 )
- return false;
-
- if ( ( **buf & 0x80 ) == 0 )
- return false;
-
- ui64_t val = 0;
- ui8_t ber_size = ( **buf & 0x0f ) + 1;
-
- if ( ber_size > 9 )
- return false;
-
- for ( ui8_t i = 1; i < ber_size; i++ )
- {
- if ( (*buf)[i] > 0 )
- val |= (ui64_t)((*buf)[i]) << ( ( ( ber_size - 1 ) - i ) * 8 );
- }
-
- *buf += ber_size;
- return ( val == test_value );
-}
-
-
-//
-bool
-ASDCP::read_BER(const byte_t* buf, ui64_t* val)
-{
- ui8_t ber_size, i;
-
- if ( buf == 0 || val == 0 )
- return false;
-
- if ( ( *buf & 0x80 ) == 0 )
- return false;
-
- *val = 0;
- ber_size = ( *buf & 0x0f ) + 1;
-
- if ( ber_size > 9 )
- return false;
-
- for ( i = 1; i < ber_size; i++ )
- {
- if ( buf[i] > 0 )
- *val |= (ui64_t)buf[i] << ( ( ( ber_size - 1 ) - i ) * 8 );
- }
-
- return true;
-}
-
-
-static const ui64_t ber_masks[9] =
- { ui64_C(0xffffffffffffffff), ui64_C(0xffffffffffffff00),
- ui64_C(0xffffffffffff0000), ui64_C(0xffffffffff000000),
- ui64_C(0xffffffff00000000), ui64_C(0xffffff0000000000),
- ui64_C(0xffff000000000000), ui64_C(0xff00000000000000),
- 0
- };
-
-
-//
-bool
-ASDCP::write_BER(byte_t* buf, ui64_t val, ui32_t ber_len)
-{
- if ( buf == 0 )
- return false;
-
- if ( ber_len == 0 )
- { // calculate default length
- if ( val < 0x01000000L )
- ber_len = 4;
- else if ( val < ui64_C(0x0100000000000000) )
- ber_len = 8;
- else
- ber_len = 9;
- }
- else
- { // sanity check BER length
- if ( ber_len > 9 )
- {
- DefaultLogSink().Error("BER size %lu exceeds maximum size of 9\n", ber_len);
- return false;
- }
-
- if ( val & ber_masks[ber_len - 1] )
- {
- char intbuf[IntBufferLen];
- DefaultLogSink().Error("BER size %lu too small for value %s\n",
- ber_len, ui64sz(val, intbuf));
- return false;
- }
- }
-
- buf[0] = 0x80 + ( ber_len - 1 );
-
- for ( ui32_t i = ber_len - 1; i > 0; i-- )
- {
- buf[i] = (ui8_t)(val & 0xff);
- val >>= 8;
- }
-
- return true;
-}
-
//------------------------------------------------------------------------------------------
//
// frame buffer base class implementation
diff --git a/src/AS_DCP.h b/src/AS_DCP.h
index e65b029..f6574ac 100755
--- a/src/AS_DCP.h
+++ b/src/AS_DCP.h
@@ -72,9 +72,10 @@ This project depends upon the following library:
*/
-#ifndef _AS_DCP_H__
-#define _AS_DCP_H__
+#ifndef _AS_DCP_H_
+#define _AS_DCP_H_
+#include <KM_error.h>
#include <stdio.h>
#include <stdarg.h>
#include <iostream>
@@ -128,7 +129,6 @@ typedef unsigned int ui32_t;
T(const T&); \
T& operator=(const T&)
-
//--------------------------------------------------------------------------------
// All library components are defined in the namespace ASDCP
//
@@ -142,8 +142,8 @@ namespace ASDCP {
// in file format, and if no changes were made to AS_DCP.h, the new version would be
// 1.0.1. If changes were also required in AS_DCP.h, the new version would be 1.1.1.
const ui32_t VERSION_MAJOR = 1;
- const ui32_t VERSION_APIMINOR = 0;
- const ui32_t VERSION_IMPMINOR = 5;
+ const ui32_t VERSION_APIMINOR = 1;
+ const ui32_t VERSION_IMPMINOR = 7;
const char* Version();
// UUIDs are passed around as strings of UUIDlen bytes
@@ -153,75 +153,42 @@ namespace ASDCP {
const ui32_t KeyLen = 16;
//---------------------------------------------------------------------------------
- // message logging
-
- // Error and debug messages will be delivered to an object having this interface.
- // The default implementation sends only LOG_ERROR and LOG_WARN messages to stderr.
- // To receive LOG_INFO or LOG_DEBUG messages, or to send messages somewhere other
- // than stderr, implement this interface and register an instance of your new class
- // by calling SetDefaultLogSink().
- class ILogSink
- {
- public:
- enum LogType_t { LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG };
-
- virtual ~ILogSink() {}
- virtual void Error(const char*, ...) = 0; // receives error messges
- virtual void Warn(const char*, ...) = 0; // receives warning messges
- virtual void Info(const char*, ...) = 0; // receives info messages
- virtual void Debug(const char*, ...) = 0; // receives debug messages
- virtual void Logf(LogType_t, const char*, ...) = 0; // log a formatted string with positional parameters
- virtual void vLogf(LogType_t, const char*, va_list*) = 0; // log a formatted string with a va_list struct
- };
-
- // Sets the internal default sink to the given receiver. If the given value
- // is zero, sets the default sink to the internally allocated stderr sink.
- void SetDefaultLogSink(ILogSink* = 0);
-
- // Returns the internal default sink.
- ILogSink& DefaultLogSink();
-
- //---------------------------------------------------------------------------------
// return values
- // Each method or subroutine in this library that is not void or does not directly
- // return a value will instead return a result code from this enumeration.
- enum Result_t {
- RESULT_FALSE = 1, // successful but negative
- RESULT_OK = 0, // No errors detected
- RESULT_FAIL = -1, // An undefined error was detected
- RESULT_PTR = -2, // An unexpected NULL pointer was given
- RESULT_NULL_STR = -3, // An unexpected empty string was given
- RESULT_SMALLBUF = -4, // The given frame buffer is too small
- RESULT_INIT = -5, // The object is not yet initialized
- RESULT_NOT_FOUND = -6, // The requested file does not exist on the system
- RESULT_NO_PERM = -7, // Insufficient privilege exists to perform the operation
- RESULT_FILEOPEN = -8, // Failure opening file
- RESULT_FORMAT = -9, // The file format is not proper OP-Atom/AS-DCP
- RESULT_BADSEEK = -10, // An invalid file location was requested
- RESULT_READFAIL = -11, // File read error
- RESULT_WRITEFAIL = -12, // File write error
- RESULT_RAW_ESS = -13, // Unknown raw essence file type
- RESULT_RAW_FORMAT = -14, // Raw essence format invalid
- RESULT_STATE = -15, // Object state error
- RESULT_ENDOFFILE = -16, // Attempt to read past end of file
- RESULT_CONFIG = -17, // Invalid configuration option detected
- RESULT_RANGE = -18, // Frame number out of range
- RESULT_CRYPT_CTX = -19, // AESEncContext required when writing to encrypted file
- RESULT_LARGE_PTO = -20, // Plaintext offset exceeds frame buffer size
- RESULT_ALLOC = -21, // Error allocating memory
- RESULT_CAPEXTMEM = -22, // Cannot resize externally allocated memory
- RESULT_CHECKFAIL = -23, // The check value did not decrypt correctly
- RESULT_HMACFAIL = -24, // HMAC authentication failure
- RESULT_HMAC_CTX = -25, // HMAC context required
- RESULT_CRYPT_INIT = -26, // Error initializing block cipher context
- RESULT_EMPTY_FB = -27, // Attempted to write an empty frame buffer
- };
-
- // Returns a pointer to an English language string describing the given result code.
- // If the result code is not a valid member of the Result_t enum, the string
- // "**UNKNOWN**" will be returned.
- const char* GetResultString(Result_t);
+ using Kumu::Result_t;
+
+ using Kumu::RESULT_FALSE;
+ using Kumu::RESULT_OK;
+ using Kumu::RESULT_FAIL;
+ using Kumu::RESULT_PTR;
+ using Kumu::RESULT_NULL_STR;
+ using Kumu::RESULT_ALLOC;
+ using Kumu::RESULT_PARAM;
+ using Kumu::RESULT_SMALLBUF;
+ using Kumu::RESULT_INIT;
+ using Kumu::RESULT_NOT_FOUND;
+ using Kumu::RESULT_NO_PERM;
+ using Kumu::RESULT_FILEOPEN;
+ using Kumu::RESULT_BADSEEK;
+ using Kumu::RESULT_READFAIL;
+ using Kumu::RESULT_WRITEFAIL;
+ using Kumu::RESULT_STATE;
+ using Kumu::RESULT_ENDOFFILE;
+ using Kumu::RESULT_CONFIG;
+
+ const Kumu::Result_t RESULT_FORMAT (-101, "The file format is not proper OP-Atom/AS-DCP.");
+ const Kumu::Result_t RESULT_RAW_ESS (-102, "Unknown raw essence file type.");
+ const Kumu::Result_t RESULT_RAW_FORMAT (-103, "Raw essence format invalid.");
+ const Kumu::Result_t RESULT_RANGE (-104, "Frame number out of range.");
+ const Kumu::Result_t RESULT_CRYPT_CTX (-105, "AESEncContext required when writing to encrypted file.");
+ const Kumu::Result_t RESULT_LARGE_PTO (-106, "Plaintext offset exceeds frame buffer size.");
+ const Kumu::Result_t RESULT_CAPEXTMEM (-107, "Cannot resize externally allocated memory.");
+ const Kumu::Result_t RESULT_CHECKFAIL (-108, "The check value did not decrypt correctly.");
+ const Kumu::Result_t RESULT_HMACFAIL (-109, "HMAC authentication failure.");
+ const Kumu::Result_t RESULT_HMAC_CTX (-110, "HMAC context required.");
+ const Kumu::Result_t RESULT_CRYPT_INIT (-111, "Error initializing block cipher context.");
+ const Kumu::Result_t RESULT_EMPTY_FB (-112, "Empty frame buffer.");
+ const Kumu::Result_t RESULT_KLV_CODING (-113, "KLV coding error.");
//---------------------------------------------------------------------------------
// file identification
@@ -232,7 +199,10 @@ namespace ASDCP {
ESS_UNKNOWN, // the file is not a supported AS-DCP essence container
ESS_MPEG2_VES, // the file contains an MPEG video elementary stream
ESS_JPEG_2000, // the file contains one or more JPEG 2000 codestreams
- ESS_PCM_24b_48k // the file contains one or more PCM audio pairs
+ ESS_PCM_24b_48k, // the file contains one or more PCM audio pairs
+ ESS_PCM_24b_96k, // the file contains one or more PCM audio pairs
+ ESS_UTF8_XML, // the file contains UTF-8 encoded XML data
+ ESS_PNG // the file contains a Portable Network Graphics image
};
// Determine the type of essence contained in the given MXF file. RESULT_OK
@@ -301,6 +271,69 @@ namespace ASDCP {
inline bool empty() const { return m_p == 0; }
};
+
+ //---------------------------------------------------------------------------------
+ // WriterInfo class - encapsulates writer identification details used for
+ // OpenWrite() calls. Replace these values at runtime to identify your product.
+ //
+ // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
+ // in a file is determined by the MXF Operational Pattern and any constraining
+ // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
+ // and SMPTE. The two differ only in the values of two labels:
+ //
+ // OP Atom / Interop : 06 0e 2b 34 04 01 01 01 0d 01 02 01 10 00 00 00
+ // OP Atom / SMPTE : 06 0e 2b 34 04 01 01 02 0d 01 02 01 10 00 00 00
+ // and
+ // EKLV Packet / Interop : 06 0e 2b 34 02 04 01 07 0d 01 03 01 02 7e 01 00
+ // EKLV Packet / SMPTE : 06 0e 2b 34 02 04 01 01 0d 01 03 01 02 7e 01 00
+ //
+ // asdcplib will read any (otherwise valid) file which has any combination of the
+ // above values. When writing files, MXF Interop labels are used by default. To
+ // write a file containing SMPTE labels, replace the default label set value in
+ // the WriterInfo before calling OpenWrite()
+ //
+ enum LabelSet_t
+ {
+ LS_MXF_UNKNOWN,
+ LS_MXF_INTEROP,
+ LS_MXF_SMPTE
+ };
+
+ //
+ struct WriterInfo
+ {
+ byte_t ProductUUID[UUIDlen];
+ byte_t AssetUUID[UUIDlen];
+ byte_t ContextID[UUIDlen];
+ byte_t CryptographicKeyID[UUIDlen];
+ bool EncryptedEssence; // true if essence data is (or is going to be) encrypted
+ bool UsesHMAC; // true if HMAC exists or is to be calculated
+ std::string ProductVersion;
+ std::string CompanyName;
+ std::string ProductName;
+ LabelSet_t LabelSetType;
+
+ WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
+ {
+ static byte_t default_ProductUUID_Data[UUIDlen] = {
+ 0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
+ 0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
+
+ memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
+ memset(AssetUUID, 0, UUIDlen);
+ memset(ContextID, 0, UUIDlen);
+ memset(CryptographicKeyID, 0, UUIDlen);
+
+ ProductVersion = "Unreleased ";
+ ProductVersion += Version();
+ CompanyName = "DCI";
+ ProductName = "asdcplib";
+ }
+ };
+
+ // Print WriterInfo to stream, stderr by default.
+ void WriterInfoDump(const WriterInfo&, FILE* = 0);
+
//---------------------------------------------------------------------------------
// cryptographic support
@@ -376,7 +409,7 @@ namespace ASDCP {
// Initializes HMAC context. The key argument must point to a binary
// key that is CBC_KEY_SIZE bytes in length. Returns error if the key
// argument is NULL.
- Result_t InitKey(const byte_t* key);
+ Result_t InitKey(const byte_t* key, LabelSet_t = LS_MXF_INTEROP);
// Reset internal state, allows repeated cycles of Update -> Finalize
void Reset();
@@ -400,68 +433,6 @@ namespace ASDCP {
};
//---------------------------------------------------------------------------------
- // WriterInfo class - encapsulates writer identification details used for
- // OpenWrite() calls. Replace these values at runtime to identify your product.
- //
- // MXF files use SMPTE Universal Labels to identify data items. The set of Labels
- // in a file is determined by the MXF Operational Pattern and any constraining
- // documentation. There are currently two flavors of AS-DCP file in use: MXF Interop
- // and SMPTE. The two differ only in the values of two labels:
- //
- // OP Atom / Interop : 06 0e 2b 34 04 01 01 01 0d 01 02 01 10 00 00 00
- // OP Atom / SMPTE : 06 0e 2b 34 04 01 01 02 0d 01 02 01 10 00 00 00
- // and
- // EKLV Packet / Interop : 06 0e 2b 34 02 04 01 07 0d 01 03 01 02 7e 01 00
- // EKLV Packet / SMPTE : 06 0e 2b 34 02 04 01 01 0d 01 03 01 02 7e 01 00
- //
- // asdcplib will read any (otherwise valid) file which has any combination of the
- // above values. When writing files, MXF Interop labels are used by default. To
- // write a file containing SMPTE labels, replace the default label set value in
- // the WriterInfo before calling OpenWrite()
- //
- enum LabelSet_t
- {
- LS_MXF_UNKNOWN,
- LS_MXF_INTEROP,
- LS_MXF_SMPTE
- };
-
- //
- struct WriterInfo
- {
- byte_t ProductUUID[UUIDlen];
- byte_t AssetUUID[UUIDlen];
- byte_t ContextID[UUIDlen];
- byte_t CryptographicKeyID[UUIDlen];
- bool EncryptedEssence; // true if essence data is (or is going to be) encrypted
- bool UsesHMAC; // true if HMAC exists or is to be calculated
- std::string ProductVersion;
- std::string CompanyName;
- std::string ProductName;
- LabelSet_t LabelSetType;
-
- WriterInfo() : EncryptedEssence(false), UsesHMAC(false), LabelSetType(LS_MXF_INTEROP)
- {
- static byte_t default_ProductUUID_Data[UUIDlen] = {
- 0x43, 0x05, 0x9a, 0x1d, 0x04, 0x32, 0x41, 0x01,
- 0xb8, 0x3f, 0x73, 0x68, 0x15, 0xac, 0xf3, 0x1d };
-
- memcpy(ProductUUID, default_ProductUUID_Data, UUIDlen);
- memset(AssetUUID, 0, UUIDlen);
- memset(ContextID, 0, UUIDlen);
- memset(CryptographicKeyID, 0, UUIDlen);
-
- ProductVersion = "Unreleased ";
- ProductVersion += Version();
- CompanyName = "DCI";
- ProductName = "asdcplib";
- }
- };
-
- // Print WriterInfo to stream, stderr by default.
- void WriterInfoDump(const WriterInfo&, FILE* = 0);
-
- //---------------------------------------------------------------------------------
// frame buffer base class
//
// The supported essence types are stored using per-frame KLV packetization. The
@@ -1103,7 +1074,7 @@ namespace ASDCP {
} // namespace ASDCP
-#endif // _AS_DCP_H__
+#endif // _AS_DCP_H_
//
// end AS_DCP.h
diff --git a/src/AS_DCP_AES.cpp b/src/AS_DCP_AES.cpp
index e21dba1..fc10425 100755
--- a/src/AS_DCP_AES.cpp
+++ b/src/AS_DCP_AES.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assert.h>
#include <AS_DCP.h>
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
using namespace ASDCP;
const int KEY_SIZE_BITS = 128;
@@ -39,6 +41,7 @@ const int KEY_SIZE_BITS = 128;
#include <openssl/aes.h>
#include <openssl/sha.h>
+#include <openssl/bn.h>
#include <openssl/err.h>
void
@@ -255,9 +258,76 @@ public:
h__HMACContext() : m_Final(false) {}
~h__HMACContext() {}
- //
+ // SMPTE 429.6 MIC key generation
void SetKey(const byte_t* key)
{
+ // FIPS 186-2 Sec. 3.1 as modified by Change 1, section entitled "General Purpose Random Number Generation"
+ //
+
+ static byte_t t[SHA_DIGEST_LENGTH] = {
+ 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89,
+ 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76,
+ 0xc3, 0xd2, 0xe1, 0xf0
+ };
+
+ byte_t sha_buf0[SHA_DIGEST_LENGTH];
+ byte_t sha_buf1[SHA_DIGEST_LENGTH];
+ SHA_CTX SHA;
+ BN_CTX* ctx1 = BN_CTX_new(); // used by BN_* functions
+ assert(ctx1);
+
+ // create the 2^160 constant
+ BIGNUM c_2powb, c_2, c_160;
+ BN_init(&c_2powb); BN_init(&c_2); BN_init(&c_160);
+ BN_set_word(&c_2, 2);
+ BN_set_word(&c_160, 160);
+ BN_exp(&c_2powb, &c_2, &c_160, ctx1);
+
+ // ROUND 1
+ // step a -- SMPTE 429.6 sets XSEED = 0, so no need to do anything for this step
+ // step b -- (key mod 2^160) is moot because the input value is only 128 bits in length
+
+ // step c -- x = G(t,xkey)
+ SHA1_Init(&SHA);
+ SHA1_Update(&SHA, t, SHA_DIGEST_LENGTH);
+ SHA1_Update(&SHA, key, KeyLen);
+ SHA1_Final(sha_buf0, &SHA);
+
+ // step d ...
+ BIGNUM xkey1, xkey2, x0;
+ BN_init(&xkey1); BN_init(&xkey2); BN_init(&x0);
+
+ BN_bin2bn(key, KeyLen, &xkey1);
+ BN_bin2bn(sha_buf0, SHA_DIGEST_LENGTH, &x0);
+ BN_add_word(&xkey1, 1); // xkey += 1
+ BN_add(&xkey2, &xkey1, &x0); // xkey += x
+ BN_mod(&xkey1, &xkey2, &c_2powb, ctx1); // xkey = xkey mod (2^160)
+
+ // ROUND 2
+ // step a -- SMPTE 429.6 sets XSEED = 0, so no need to do anything for this step
+ // step b -- (key mod 2^160) is moot because xkey1 is the result of the same operation
+
+ byte_t bin_buf[SHA_DIGEST_LENGTH+1]; // we need xkey1 in bin form for use by SHA1_Update
+ ui32_t bin_buf_len = BN_num_bytes(&xkey1);
+ assert(bin_buf_len < SHA_DIGEST_LENGTH+1);
+ BN_bn2bin(&xkey1, bin_buf);
+
+ // step c -- x = G(t,xkey)
+ SHA1_Init(&SHA);
+ SHA1_Update(&SHA, t, SHA_DIGEST_LENGTH);
+ SHA1_Update(&SHA, bin_buf, bin_buf_len);
+ SHA1_Final(sha_buf1, &SHA);
+
+ assert(memcmp(sha_buf1, sha_buf0, SHA_DIGEST_LENGTH) != 0); // are x0 and x1 different?
+
+ BN_CTX_free(ctx1);
+ memcpy(m_key, sha_buf1, KeyLen);
+ Reset();
+ }
+
+ // MXF Interop MIC key generation
+ void SetInteropKey(const byte_t* key)
+ {
static byte_t key_nonce[KeyLen] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
byte_t sha_buf[SHA_DIGEST_LENGTH];
@@ -334,12 +404,21 @@ HMACContext::~HMACContext()
//
Result_t
-HMACContext::InitKey(const byte_t* key)
+HMACContext::InitKey(const byte_t* key, LabelSet_t SetType)
{
ASDCP_TEST_NULL(key);
m_Context = new h__HMACContext;
- m_Context->SetKey(key);
+
+ switch ( SetType )
+ {
+ case LS_MXF_INTEROP: m_Context->SetInteropKey(key); break;
+ case LS_MXF_SMPTE: m_Context->SetKey(key); break;
+ default:
+ m_Context = 0;
+ return RESULT_INIT;
+ }
+
return RESULT_OK;
}
diff --git a/src/AS_DCP_JP2K.cpp b/src/AS_DCP_JP2K.cpp
index f08203a..02d1d91 100755
--- a/src/AS_DCP_JP2K.cpp
+++ b/src/AS_DCP_JP2K.cpp
@@ -92,15 +92,13 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream)
if ( PDesc.CodingStyleLength )
fprintf(stream, "Default Coding (%lu): %s\n",
PDesc.CodingStyleLength,
- bin2hex(PDesc.CodingStyle, PDesc.CodingStyleLength,
- tmp_buf, tmp_buf_len)
+ Kumu::bin2hex(PDesc.CodingStyle, PDesc.CodingStyleLength, tmp_buf, tmp_buf_len)
);
if ( PDesc.QuantDefaultLength )
fprintf(stream, "Quantization Default (%lu): %s\n",
PDesc.QuantDefaultLength,
- bin2hex(PDesc.QuantDefault, PDesc.QuantDefaultLength,
- tmp_buf, tmp_buf_len)
+ Kumu::bin2hex(PDesc.QuantDefault, PDesc.QuantDefaultLength, tmp_buf, tmp_buf_len)
);
}
@@ -152,7 +150,7 @@ ASDCP::JP2K::MXFReader::h__Reader::MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDe
PDesc.Csize = m_EssenceSubDescriptor->Csize;
// PictureComponentSizing
- ui32_t tmp_size = m_EssenceSubDescriptor->PictureComponentSizing.Size();
+ ui32_t tmp_size = m_EssenceSubDescriptor->PictureComponentSizing.Length();
if ( tmp_size == 17 ) // ( 2 * sizeof(ui32_t) ) + 3 components * 3 byte each
memcpy(&PDesc.ImageComponents, m_EssenceSubDescriptor->PictureComponentSizing.RoData() + 8, tmp_size - 8);
@@ -161,11 +159,11 @@ ASDCP::JP2K::MXFReader::h__Reader::MD_to_JP2K_PDesc(JP2K::PictureDescriptor& PDe
DefaultLogSink().Error("Unexpected PictureComponentSizing size: %lu, should be 17\n", tmp_size);
// CodingStyleDefault
- if ( ( PDesc.CodingStyleLength = m_EssenceSubDescriptor->CodingStyleDefault.Size() ) != 0 )
+ if ( ( PDesc.CodingStyleLength = m_EssenceSubDescriptor->CodingStyleDefault.Length() ) != 0 )
memcpy(PDesc.CodingStyle, m_EssenceSubDescriptor->CodingStyleDefault.RoData(), PDesc.CodingStyleLength);
// QuantizationDefault
- if ( ( PDesc.QuantDefaultLength = m_EssenceSubDescriptor->QuantizationDefault.Size() ) != 0 )
+ if ( ( PDesc.QuantDefaultLength = m_EssenceSubDescriptor->QuantizationDefault.Length() ) != 0 )
memcpy(PDesc.QuantDefault, m_EssenceSubDescriptor->QuantizationDefault.RoData(), PDesc.QuantDefaultLength);
}
@@ -226,7 +224,7 @@ ASDCP::JP2K::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const
fputc('\n', stream);
if ( dump_len > 0 )
- hexdump(m_Data, dump_len, stream);
+ Kumu::hexdump(m_Data, dump_len, stream);
}
@@ -368,18 +366,18 @@ ASDCP::JP2K::MXFWriter::h__Writer::JP2K_PDesc_to_MD(JP2K::PictureDescriptor& PDe
const ui32_t tmp_buffer_len = 64;
byte_t tmp_buffer[tmp_buffer_len];
- *(ui32_t*)tmp_buffer = ASDCP_i32_BE(3L); // three components
- *(ui32_t*)(tmp_buffer+4) = ASDCP_i32_BE(3L);
+ *(ui32_t*)tmp_buffer = KM_i32_BE(3L); // three components
+ *(ui32_t*)(tmp_buffer+4) = KM_i32_BE(3L);
memcpy(tmp_buffer + 8, &PDesc.ImageComponents, sizeof(ASDCP::JP2K::ImageComponent) * 3L);
memcpy(m_EssenceSubDescriptor->PictureComponentSizing.Data(), tmp_buffer, 17);
- m_EssenceSubDescriptor->PictureComponentSizing.Size(17);
+ m_EssenceSubDescriptor->PictureComponentSizing.Length(17);
memcpy(m_EssenceSubDescriptor->CodingStyleDefault.Data(), PDesc.CodingStyle, PDesc.CodingStyleLength);
- m_EssenceSubDescriptor->CodingStyleDefault.Size(PDesc.CodingStyleLength);
+ m_EssenceSubDescriptor->CodingStyleDefault.Length(PDesc.CodingStyleLength);
memcpy(m_EssenceSubDescriptor->QuantizationDefault.Data(), PDesc.QuantDefault, PDesc.QuantDefaultLength);
- m_EssenceSubDescriptor->QuantizationDefault.Size(PDesc.QuantDefaultLength);
+ m_EssenceSubDescriptor->QuantizationDefault.Length(PDesc.QuantDefaultLength);
return RESULT_OK;
}
diff --git a/src/AS_DCP_MPEG2.cpp b/src/AS_DCP_MPEG2.cpp
index e265848..83f7bbe 100755
--- a/src/AS_DCP_MPEG2.cpp
+++ b/src/AS_DCP_MPEG2.cpp
@@ -273,7 +273,7 @@ ASDCP::MPEG2::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const
fputc('\n', stream);
if ( dump_len > 0 )
- hexdump(m_Data, dump_len, stream);
+ Kumu::hexdump(m_Data, dump_len, stream);
}
diff --git a/src/AS_DCP_MXF.cpp b/src/AS_DCP_MXF.cpp
index 92f76bb..1c8b6e9 100755
--- a/src/AS_DCP_MXF.cpp
+++ b/src/AS_DCP_MXF.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004-2005, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -29,9 +29,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\brief AS-DCP library, misc classes and subroutines
*/
+#include <KM_fileio.h>
#include "AS_DCP_internal.h"
-#include "FileIO.h"
-#include "DirScanner.h"
#include "JP2K.h"
#include "Wav.h"
@@ -49,7 +48,7 @@ ASDCP::WriterInfoDump(const WriterInfo& Info, FILE* stream)
char str_buf[40];
- fprintf(stream," ProductUUID: %s\n", bin2hex(Info.ProductUUID, 16, str_buf, 40));
+ fprintf(stream," ProductUUID: %s\n", UUID(Info.ProductUUID).EncodeHex(str_buf, 40));
fprintf(stream,"\
ProductVersion: %s\n\
CompanyName: %s\n\
@@ -64,11 +63,11 @@ ASDCP::WriterInfoDump(const WriterInfo& Info, FILE* stream)
if ( Info.EncryptedEssence )
{
fprintf(stream, " HMAC: %s\n", ( Info.UsesHMAC ? "Yes" : "No"));
- fprintf(stream, " ContextID: %s\n", bin2hex(Info.ContextID, 16, str_buf, 40));
- fprintf(stream, "CryptographicKeyID: %s\n", bin2hex(Info.CryptographicKeyID, 16, str_buf, 40));
+ fprintf(stream, " ContextID: %s\n", UUID(Info.ContextID).EncodeHex(str_buf, 40));
+ fprintf(stream, "CryptographicKeyID: %s\n", UUID(Info.CryptographicKeyID).EncodeHex(str_buf, 40));
}
- fprintf(stream," AssetUUID: %s\n", bin2hex(Info.AssetUUID, 16, str_buf, 40));
+ fprintf(stream," AssetUUID: %s\n", UUID(Info.AssetUUID).EncodeHex(str_buf, 40));
fprintf(stream," Label Set Type: %s\n", ( Info.LabelSetType == LS_MXF_SMPTE ? "SMPTE" :
( Info.LabelSetType == LS_MXF_INTEROP ? "MXF Interop" :
"Unknown" ) ));
@@ -86,13 +85,13 @@ ASDCP::MD_to_WriterInfo(Identification* InfoObj, WriterInfo& Info)
Info.CompanyName = "Unknown Company";
memset(Info.ProductUUID, 0, UUIDlen);
- InfoObj->ProductName.ToString(tmp_str);
+ InfoObj->ProductName.EncodeString(tmp_str, IdentBufferLen);
if ( *tmp_str ) Info.ProductName = tmp_str;
- InfoObj->VersionString.ToString(tmp_str);
+ InfoObj->VersionString.EncodeString(tmp_str, IdentBufferLen);
if ( *tmp_str ) Info.ProductVersion = tmp_str;
- InfoObj->CompanyName.ToString(tmp_str);
+ InfoObj->CompanyName.EncodeString(tmp_str, IdentBufferLen);
if ( *tmp_str ) Info.CompanyName = tmp_str;
memcpy(Info.ProductUUID, InfoObj->ProductUID.Value(), UUIDlen);
@@ -135,7 +134,7 @@ ASDCP::Result_t
ASDCP::EssenceType(const char* filename, EssenceType_t& type)
{
ASDCP_TEST_NULL_STR(filename);
- FileReader Reader;
+ Kumu::FileReader Reader;
OPAtomHeader TestHeader;
Result_t result = Reader.OpenRead(filename);
@@ -163,7 +162,6 @@ ASDCP::EssenceType(const char* filename, EssenceType_t& type)
return result;
}
-
//
ASDCP::Result_t
ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
@@ -171,11 +169,11 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
ASDCP_TEST_NULL_STR(filename);
type = ESS_UNKNOWN;
ASDCP::FrameBuffer FB;
- FileReader Reader;
+ Kumu::FileReader Reader;
ui32_t read_count;
Result_t result = FB.Capacity(Wav::MaxWavHeader); // using Wav max because everything else is much smaller
- if ( ASDCP::PathIsFile(filename) )
+ if ( Kumu::PathIsFile(filename) )
{
result = Reader.OpenRead(filename);
@@ -202,10 +200,10 @@ ASDCP::RawEssenceType(const char* filename, EssenceType_t& type)
type = ESS_PCM_24b_48k;
}
}
- else if ( ASDCP::PathIsDirectory(filename) )
+ else if ( Kumu::PathIsDirectory(filename) )
{
- char next_file[ASDCP_MAX_PATH];
- DirScanner Scanner;
+ char next_file[Kumu::MaxFilePath];
+ Kumu::DirScanner Scanner;
Result_t result = Scanner.Open(filename);
if ( ASDCP_SUCCESS(result) )
@@ -397,7 +395,7 @@ ASDCP::IntegrityPack::CalcValues(const ASDCP::FrameBuffer& FB, byte_t* AssetID,
p += MXF_BER_LENGTH;
// sequence number
- i2p<ui64_t>(ASDCP_i64_BE(sequence), p);
+ Kumu::i2p<ui64_t>(KM_i64_BE(sequence), p);
p += sizeof(ui64_t);
// HMAC length
@@ -429,7 +427,7 @@ ASDCP::IntegrityPack::TestValues(const ASDCP::FrameBuffer& FB, byte_t* AssetID,
byte_t* p = (byte_t*)FB.RoData() + ( FB.Size() - klv_intpack_size );
// test the AssetID length
- if ( ! read_test_BER(&p, UUIDlen) )
+ if ( ! Kumu::read_test_BER(&p, UUIDlen) )
return RESULT_HMACFAIL;
// test the AssetID
@@ -441,10 +439,10 @@ ASDCP::IntegrityPack::TestValues(const ASDCP::FrameBuffer& FB, byte_t* AssetID,
p += UUIDlen;
// test the sequence length
- if ( ! read_test_BER(&p, sizeof(ui64_t)) )
+ if ( ! Kumu::read_test_BER(&p, sizeof(ui64_t)) )
return RESULT_HMACFAIL;
- ui32_t test_sequence = (ui32_t)ASDCP_i64_BE(cp2i<ui64_t>(p));
+ ui32_t test_sequence = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(p));
// test the sequence value
if ( test_sequence != sequence )
@@ -456,7 +454,7 @@ ASDCP::IntegrityPack::TestValues(const ASDCP::FrameBuffer& FB, byte_t* AssetID,
p += sizeof(ui64_t);
// test the HMAC length
- if ( ! read_test_BER(&p, HMAC_SIZE) )
+ if ( ! Kumu::read_test_BER(&p, HMAC_SIZE) )
return RESULT_HMACFAIL;
// test the HMAC
diff --git a/src/AS_DCP_PCM.cpp b/src/AS_DCP_PCM.cpp
index 8036745..a4f9b5f 100755
--- a/src/AS_DCP_PCM.cpp
+++ b/src/AS_DCP_PCM.cpp
@@ -219,7 +219,7 @@ ASDCP::PCM::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const
m_FrameNumber, m_Size);
if ( dump_len )
- hexdump(m_Data, dump_len, stream);
+ Kumu::hexdump(m_Data, dump_len, stream);
}
//------------------------------------------------------------------------------------------
diff --git a/src/AS_DCP_internal.h b/src/AS_DCP_internal.h
index 173540d..4a00ba0 100755
--- a/src/AS_DCP_internal.h
+++ b/src/AS_DCP_internal.h
@@ -29,14 +29,16 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\brief AS-DCP library, non-public common elements
*/
-#ifndef _AS_DCP_INTERNAL_H__
-#define _AS_DCP_INTERNAL_H__
+#ifndef _AS_DCP_INTERNAL_H_
+#define _AS_DCP_INTERNAL_H_
-#include "AS_DCP_system.h"
+#include <KM_platform.h>
+#include <KM_util.h>
+#include <KM_log.h>
#include "Metadata.h"
-#include "hex_utils.h"
-using namespace std;
+using Kumu::DefaultLogSink;
+// using namespace std;
using namespace ASDCP;
using namespace ASDCP::MXF;
@@ -45,7 +47,6 @@ using namespace ASDCP::MXF;
namespace ASDCP
{
// constant values used to calculate KLV and EKLV packet sizes
-
static const ui32_t klv_cryptinfo_size =
MXF_BER_LENGTH
+ UUIDlen /* ContextID */
@@ -95,7 +96,7 @@ namespace ASDCP
ASDCP_NO_COPY_CONSTRUCT(h__Reader);
public:
- FileReader m_File;
+ Kumu::FileReader m_File;
OPAtomHeader m_HeaderPart;
Partition m_BodyPart;
OPAtomIndexFooter m_FooterPart;
@@ -157,7 +158,7 @@ namespace ASDCP
ASDCP_NO_COPY_CONSTRUCT(h__Writer);
public:
- FileWriter m_File;
+ Kumu::FileWriter m_File;
ui32_t m_HeaderSize;
OPAtomHeader m_HeaderPart;
Partition m_BodyPart;
@@ -220,7 +221,7 @@ namespace ASDCP
} // namespace ASDCP
-#endif // _AS_DCP_INTERNAL_H__
+#endif // _AS_DCP_INTERNAL_H_
//
diff --git a/src/Dict.cpp b/src/Dict.cpp
index fa51fbd..e2aadcb 100755
--- a/src/Dict.cpp
+++ b/src/Dict.cpp
@@ -30,12 +30,12 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "Mutex.h"
+#include "KM_mutex.h"
#include "KLV.h"
#include "MDD.cpp"
#include <map>
-static ASDCP::Mutex s_Lock;
+static Kumu::Mutex s_Lock;
static bool s_md_init = false;
static std::map<ASDCP::UL, ui32_t> s_md_lookup;
@@ -56,7 +56,8 @@ ASDCP::Dict::FindUL(const byte_t* ul_buf)
{
if ( ! s_md_init )
{
- AutoMutex AL(s_Lock);
+ Kumu::AutoMutex AL(s_Lock);
+
if ( ! s_md_init )
{
for ( ui32_t x = 0; x < s_MDD_Table_size; x++ )
diff --git a/src/Index.cpp b/src/Index.cpp
index 0f243f8..a7bedb1 100755
--- a/src/Index.cpp
+++ b/src/Index.cpp
@@ -60,22 +60,6 @@ ASDCP::MXF::IndexTableSegment::InitFromTLVSet(TLVReader& TLVSet)
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, PosTableCount));
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(IndexTableSegment, DeltaEntryArray));
if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(IndexTableSegment, IndexEntryArray));
-
-#if 0
- if ( ASDCP_SUCCESS(result) )
- {
- Batch<IndexEntry>::iterator i;
- ui32_t offset = 0;
- for ( i = IndexEntryArray.begin(); i != IndexEntryArray.end(); i++ )
- {
- if ( (*i).Flags == 0x40 )
- offset = 0;
-
- (*i).KeyFrameOffset = offset++;
- }
- }
-#endif
-
return result;
}
@@ -123,7 +107,7 @@ ASDCP::MXF::IndexTableSegment::Dump(FILE* stream)
stream = stderr;
InterchangeObject::Dump(stream);
- fprintf(stream, " IndexEditRate = %s\n", IndexEditRate.ToString(identbuf));
+ fprintf(stream, " IndexEditRate = %s\n", IndexEditRate.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " IndexStartPosition = %s\n", i64sz(IndexStartPosition, identbuf));
fprintf(stream, " IndexDuration = %s\n", i64sz(IndexDuration, identbuf));
fprintf(stream, " EditUnitByteCount = %lu\n", EditUnitByteCount);
@@ -150,30 +134,30 @@ ASDCP::MXF::IndexTableSegment::Dump(FILE* stream)
//
const char*
-ASDCP::MXF::IndexTableSegment::DeltaEntry::ToString(char* str_buf) const
+ASDCP::MXF::IndexTableSegment::DeltaEntry::EncodeString(char* str_buf, ui32_t buf_len) const
{
- snprintf(str_buf, IdentBufferLen, "%3i %-3hu %-3lu", PosTableIndex, Slice, ElementData);
+ snprintf(str_buf, buf_len, "%3i %-3hu %-3lu", PosTableIndex, Slice, ElementData);
return str_buf;
}
//
-ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::DeltaEntry::Unarchive(ASDCP::MemIOReader& Reader)
+bool
+ASDCP::MXF::IndexTableSegment::DeltaEntry::Unarchive(Kumu::MemIOReader* Reader)
{
- Result_t result = Reader.ReadUi8((ui8_t*)&PosTableIndex);
- if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8(&Slice);
- if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi32BE(&ElementData);
- return result;
+ if ( ! Reader->ReadUi8((ui8_t*)&PosTableIndex) ) return false;
+ if ( ! Reader->ReadUi8(&Slice) ) return false;
+ if ( ! Reader->ReadUi32BE(&ElementData) ) return false;
+ return true;
}
//
-ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::DeltaEntry::Archive(ASDCP::MemIOWriter& Writer) const
+bool
+ASDCP::MXF::IndexTableSegment::DeltaEntry::Archive(Kumu::MemIOWriter* Writer) const
{
- Result_t result = Writer.WriteUi8((ui8_t)PosTableIndex);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8(Slice);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi32BE(ElementData);
- return result;
+ if ( ! Writer->WriteUi8((ui8_t)PosTableIndex) ) return false;
+ if ( ! Writer->WriteUi8(Slice) ) return false;
+ if ( ! Writer->WriteUi32BE(ElementData) ) return false;
+ return true;
}
//------------------------------------------------------------------------------------------
@@ -193,7 +177,7 @@ ASDCP::MXF::IndexTableSegment::DeltaEntry::Archive(ASDCP::MemIOWriter& Writer) c
//
const char*
-ASDCP::MXF::IndexTableSegment::IndexEntry::ToString(char* str_buf) const
+ASDCP::MXF::IndexTableSegment::IndexEntry::EncodeString(char* str_buf, ui32_t buf_len) const
{
char intbuf[IntBufferLen];
char txt_flags[6];
@@ -205,33 +189,33 @@ ASDCP::MXF::IndexTableSegment::IndexEntry::ToString(char* str_buf) const
txt_flags[4] = ( (Flags & 0x0f) == 3 ) ? 'B' : ( (Flags & 0x0f) == 2 ) ? 'P' : 'I';
txt_flags[5] = 0;
- snprintf(str_buf, IdentBufferLen, "%3i %-3hu %s %s",
- TemporalOffset, KeyFrameOffset, txt_flags,
- i64sz(StreamOffset, intbuf));
+ snprintf(str_buf, buf_len, "%3i %-3hu %s %s",
+ TemporalOffset, KeyFrameOffset, txt_flags,
+ i64sz(StreamOffset, intbuf));
return str_buf;
}
//
-ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::IndexEntry::Unarchive(ASDCP::MemIOReader& Reader)
+bool
+ASDCP::MXF::IndexTableSegment::IndexEntry::Unarchive(Kumu::MemIOReader* Reader)
{
- Result_t result = Reader.ReadUi8((ui8_t*)&TemporalOffset);
- if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8((ui8_t*)&KeyFrameOffset);
- if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8(&Flags);
- if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi64BE(&StreamOffset);
- return result;
+ if ( ! Reader->ReadUi8((ui8_t*)&TemporalOffset) ) return false;
+ if ( ! Reader->ReadUi8((ui8_t*)&KeyFrameOffset) ) return false;
+ if ( ! Reader->ReadUi8(&Flags) ) return false;
+ if ( ! Reader->ReadUi64BE(&StreamOffset) ) return false;
+ return true;
}
//
-ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::IndexEntry::Archive(ASDCP::MemIOWriter& Writer) const
+bool
+ASDCP::MXF::IndexTableSegment::IndexEntry::Archive(Kumu::MemIOWriter* Writer) const
{
- Result_t result = Writer.WriteUi8((ui8_t)TemporalOffset);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8((ui8_t)KeyFrameOffset);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8(Flags);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi64BE(StreamOffset);
- return result;
+ if ( ! Writer->WriteUi8((ui8_t)TemporalOffset) ) return false;
+ if ( ! Writer->WriteUi8((ui8_t)KeyFrameOffset) ) return false;
+ if ( ! Writer->WriteUi8(Flags) ) return false;
+ if ( ! Writer->WriteUi64BE(StreamOffset) ) return false;
+ return true;
}
diff --git a/src/JP2K.cpp b/src/JP2K.cpp
index 20ec891..ee979ba 100755
--- a/src/JP2K.cpp
+++ b/src/JP2K.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2005, John Hurst
+Copyright (c) 2005-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -33,7 +33,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <JP2K.h>
-#include <hex_utils.h>
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
// when indexed with the second byte of a marker code, this table will procuce one of
@@ -161,7 +162,7 @@ ASDCP::JP2K::Accessor::COM::Dump(FILE* stream)
}
else
{
- hexdump(CommentData(), CommentSize(), stream);
+ Kumu::hexdump(CommentData(), CommentSize(), stream);
}
}
@@ -218,5 +219,5 @@ ASDCP::JP2K::GetMarkerString(Marker_t m)
}
//
-// end
+// end JP2K.cpp
//
diff --git a/src/JP2K.h b/src/JP2K.h
index cff77b2..7e63fd2 100755
--- a/src/JP2K.h
+++ b/src/JP2K.h
@@ -36,8 +36,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define _JP2K_H_
// AS_DCP.h is included only for it's base type definitions.
-#include <AS_DCP_system.h>
-#include <hex_utils.h>
+#include <KM_platform.h>
+#include <KM_util.h>
+#include <AS_DCP.h>
#include <assert.h>
namespace ASDCP
@@ -76,7 +77,7 @@ namespace JP2K
//
class Marker
{
- ASDCP_NO_COPY_CONSTRUCT(Marker);
+ KM_NO_COPY_CONSTRUCT(Marker);
public:
Marker_t m_Type;
@@ -100,7 +101,7 @@ namespace JP2K
class SIZ
{
const byte_t* m_MarkerData;
- ASDCP_NO_COPY_CONSTRUCT(SIZ);
+ KM_NO_COPY_CONSTRUCT(SIZ);
SIZ();
public:
@@ -112,16 +113,16 @@ namespace JP2K
~SIZ() {}
- inline ui16_t Rsize() { return ASDCP_i16_BE(*(ui16_t*)m_MarkerData); }
- inline ui32_t Xsize() { return ASDCP_i32_BE(*(ui32_t*)(m_MarkerData + 2)); }
- inline ui32_t Ysize() { return ASDCP_i32_BE(*(ui32_t*)(m_MarkerData + 6)); }
- inline ui32_t XOsize() { return ASDCP_i32_BE(*(ui32_t*)(m_MarkerData + 10)); }
- inline ui32_t YOsize() { return ASDCP_i32_BE(*(ui32_t*)(m_MarkerData + 14)); }
- inline ui32_t XTsize() { return ASDCP_i32_BE(*(ui32_t*)(m_MarkerData + 18)); }
- inline ui32_t YTsize() { return ASDCP_i32_BE(*(ui32_t*)(m_MarkerData + 22)); }
- inline ui32_t XTOsize() { return ASDCP_i32_BE(*(ui32_t*)(m_MarkerData + 26)); }
- inline ui32_t YTOsize() { return ASDCP_i32_BE(*(ui32_t*)(m_MarkerData + 30)); }
- inline ui16_t Csize() { return ASDCP_i16_BE(*(ui16_t*)(m_MarkerData + 34)); }
+ inline ui16_t Rsize() { return KM_i16_BE(*(ui16_t*)m_MarkerData); }
+ inline ui32_t Xsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 2)); }
+ inline ui32_t Ysize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 6)); }
+ inline ui32_t XOsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 10)); }
+ inline ui32_t YOsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 14)); }
+ inline ui32_t XTsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 18)); }
+ inline ui32_t YTsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 22)); }
+ inline ui32_t XTOsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 26)); }
+ inline ui32_t YTOsize() { return KM_i32_BE(*(ui32_t*)(m_MarkerData + 30)); }
+ inline ui16_t Csize() { return KM_i16_BE(*(ui16_t*)(m_MarkerData + 34)); }
void ReadComponent(ui32_t index, ImageComponent& IC);
void Dump(FILE* stream = 0);
};
@@ -133,7 +134,7 @@ namespace JP2K
const byte_t* m_MarkerData;
ui32_t m_DataSize;
- ASDCP_NO_COPY_CONSTRUCT(COM);
+ KM_NO_COPY_CONSTRUCT(COM);
COM();
public:
diff --git a/src/JP2K_Codestream_Parser.cpp b/src/JP2K_Codestream_Parser.cpp
index 216827b..700233f 100755
--- a/src/JP2K_Codestream_Parser.cpp
+++ b/src/JP2K_Codestream_Parser.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -29,10 +29,12 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\brief AS-DCP library, JPEG 2000 codestream essence reader implementation
*/
+#include <KM_fileio.h>
#include <AS_DCP.h>
-#include <FileIO.h>
#include <JP2K.h>
#include <assert.h>
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
//------------------------------------------------------------------------------------------
@@ -42,7 +44,7 @@ class ASDCP::JP2K::CodestreamParser::h__CodestreamParser
public:
PictureDescriptor m_PDesc;
- FileReader m_File;
+ Kumu::FileReader m_File;
h__CodestreamParser()
{
@@ -61,7 +63,7 @@ public:
if ( ASDCP_SUCCESS(result) )
{
- fsize_t file_size = m_File.Size();
+ Kumu::fsize_t file_size = m_File.Size();
if ( FB.Capacity() < file_size )
{
diff --git a/src/JP2K_Sequence_Parser.cpp b/src/JP2K_Sequence_Parser.cpp
index 8d1b63c..cd93583 100755
--- a/src/JP2K_Sequence_Parser.cpp
+++ b/src/JP2K_Sequence_Parser.cpp
@@ -30,8 +30,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <AS_DCP.h>
-#include <FileIO.h>
-#include <DirScanner.h>
+#include <KM_fileio.h>
#include <list>
#include <string>
#include <algorithm>
@@ -54,8 +53,8 @@ public:
//
Result_t InitFromDirectory(const char* path)
{
- char next_file[ASDCP_MAX_PATH];
- DirScanner Scanner;
+ char next_file[Kumu::MaxFilePath];
+ Kumu::DirScanner Scanner;
Result_t result = Scanner.Open(path);
@@ -139,7 +138,7 @@ ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const char* filename)
CodestreamParser Parser;
FrameBuffer TmpBuffer;
- fsize_t file_size = FileSize((*m_CurrentFile).c_str());
+ Kumu::fsize_t file_size = Kumu::FileSize((*m_CurrentFile).c_str());
if ( file_size == 0 )
result = RESULT_NOT_FOUND;
diff --git a/src/KLV.cpp b/src/KLV.cpp
index 63c1e54..f4a1580 100755
--- a/src/KLV.cpp
+++ b/src/KLV.cpp
@@ -30,7 +30,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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
@@ -69,7 +70,7 @@ ASDCP::KLVPacket::InitFromBuffer(const byte_t* buf, ui32_t buf_len)
return RESULT_FAIL;
}
- ui32_t ber_len = BER_length(buf + SMPTE_UL_LENGTH);
+ ui32_t ber_len = Kumu::BER_length(buf + SMPTE_UL_LENGTH);
if ( ber_len > ( buf_len - SMPTE_UL_LENGTH ) )
{
@@ -79,16 +80,16 @@ ASDCP::KLVPacket::InitFromBuffer(const byte_t* buf, ui32_t buf_len)
if ( ber_len == 0 )
{
- ASDCP::DefaultLogSink().Error("KLV format error, zero BER length not allowed\n");
+ 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) )
+ if ( ! Kumu::read_BER(buf + SMPTE_UL_LENGTH, &tmp_size) )
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;
@@ -116,7 +117,7 @@ ASDCP::KLVPacket::WriteKLToBuffer(ASDCP::FrameBuffer& Buffer, const byte_t* labe
memcpy(Buffer.Data() + Buffer.Size(), label, SMPTE_UL_LENGTH);
- 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);
@@ -141,7 +142,7 @@ ASDCP::KLVPacket::Dump(FILE* stream, bool show_hex)
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);
+ Kumu::hexdump(m_ValueStart, Kumu::xmin(m_ValueLength, (ui32_t)64), stream);
}
else
{
@@ -151,7 +152,7 @@ ASDCP::KLVPacket::Dump(FILE* stream, bool show_hex)
//
ASDCP::Result_t
-ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader, const byte_t* label)
+ASDCP::KLVFilePacket::InitFromFile(const Kumu::FileReader& Reader, const byte_t* label)
{
Result_t result = KLVFilePacket::InitFromFile(Reader);
@@ -164,7 +165,7 @@ ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader, const byte_t* label
// 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];
@@ -191,7 +192,7 @@ ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader)
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;
@@ -199,14 +200,13 @@ ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader)
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;
ui32_t packet_length = m_ValueLength + m_KLLength;
@@ -229,7 +229,7 @@ ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader)
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);
}
@@ -264,12 +264,12 @@ ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader)
//
ASDCP::Result_t
-ASDCP::KLVFilePacket::WriteKLToFile(FileWriter& Writer, const byte_t* label, ui32_t length)
+ASDCP::KLVFilePacket::WriteKLToFile(Kumu::FileWriter& Writer, const byte_t* label, ui32_t length)
{
byte_t buffer[kl_length];
memcpy(buffer, label, SMPTE_UL_LENGTH);
- 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;
diff --git a/src/KLV.h b/src/KLV.h
index 9eb230b..9c274bf 100755
--- a/src/KLV.h
+++ b/src/KLV.h
@@ -32,8 +32,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _KLV_H_
#define _KLV_H_
-#include "FileIO.h"
-#include "MemIO.h"
+#include <KM_fileio.h>
+#include <KM_memio.h>
+#include "AS_DCP.h"
#include "MDD.h"
@@ -48,6 +49,30 @@ namespace ASDCP
const ui32_t IdentBufferLen = 128;
+const ui32_t IntBufferLen = 64;
+
+inline const char* i64sz(i64_t i, char* buf)
+{
+ assert(buf);
+#ifdef WIN32
+ snprintf(buf, IntBufferLen, "%I64d", i);
+#else
+ snprintf(buf, IntBufferLen, "%lld", i);
+#endif
+ return buf;
+}
+
+inline const char* ui64sz(ui64_t i, char* buf)
+{
+ assert(buf);
+#ifdef WIN32
+ snprintf(buf, IntBufferLen, "%I64u", i);
+#else
+ snprintf(buf, IntBufferLen, "%llu", i);
+#endif
+ return buf;
+}
+
struct TagValue
{
byte_t a;
@@ -66,21 +91,47 @@ namespace ASDCP
}
};
- //
- class IArchive
+ using Kumu::UUID;
+
+ // Universal Label
+ class UL : public Kumu::Identifier<SMPTE_UL_LENGTH>
{
public:
- virtual ~IArchive() {}
- virtual Result_t Unarchive(ASDCP::MemIOReader& Reader) = 0;
- virtual bool HasValue() const = 0;
- virtual Result_t Archive(ASDCP::MemIOWriter& Writer) const = 0;
+ UL() {}
+ UL(const byte_t* rhs) {
+ assert(rhs);
+ Set(rhs);
+ }
+
+ UL(const UL& rhs) {
+ Set(rhs.m_Value);
+ }
+
+ virtual ~UL() {}
+
+ bool operator==(const UL& rhs) const {
+ return ( memcmp(m_Value, rhs.m_Value, SMPTE_UL_LENGTH) == 0 ) ? true : false;
+ }
+
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
+ };
+
+ // UMID
+ class UMID : public Kumu::Identifier<SMPTE_UMID_LENGTH>
+ {
+ public:
+ UMID() {}
+ UMID(const UMID &rhs) {
+ Set(rhs.m_Value);
+ };
+ virtual ~UMID() {}
+
+ void MakeUMID(int Type);
+ void MakeUMID(int Type, const UUID& ID);
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
};
-} // namespace ASDCP
-#include "Identifier.h"
-namespace ASDCP
-{
//
struct MDDEntry
{
@@ -164,9 +215,9 @@ namespace ASDCP
KLVFilePacket() {}
virtual ~KLVFilePacket() {}
- virtual Result_t InitFromFile(const FileReader&);
- virtual Result_t InitFromFile(const FileReader&, const byte_t* label);
- virtual Result_t WriteKLToFile(FileWriter& Writer, const byte_t* label, ui32_t length);
+ virtual Result_t InitFromFile(const Kumu::FileReader&);
+ virtual Result_t InitFromFile(const Kumu::FileReader&, const byte_t* label);
+ virtual Result_t WriteKLToFile(Kumu::FileWriter& Writer, const byte_t* label, ui32_t length);
};
} // namespace ASDCP
diff --git a/src/KM_error.h b/src/KM_error.h
new file mode 100755
index 0000000..612a92c
--- /dev/null
+++ b/src/KM_error.h
@@ -0,0 +1,117 @@
+/*
+Copyright (c) 2004-2006, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+ /*! \file KM_error.h
+ \version $Id$
+ \brief error reporting support
+ */
+
+
+
+#ifndef _KM_ERROR_H_
+#define _KM_ERROR_H_
+
+namespace Kumu
+{
+ // Result code container. Both a signed integer and a text string are stored in the object.
+ // When defining your own codes your choice of integer values is mostly unconstrained, but pay
+ // attention to the numbering in the other libraries that use Kumu. Values between -99 and 99
+ // are reserved for Kumu.
+
+ class Result_t
+ {
+ long value;
+ const char* label;
+ Result_t();
+
+ public:
+ Result_t(long v, const char* l) : value(v), label(l) {}
+ inline bool operator==(const Result_t& rhs) const { return value == rhs.value; }
+ inline bool operator!=(const Result_t& rhs) const { return value != rhs.value; }
+ inline bool Success() { return ( value >= 0 ); }
+ inline bool Failure() { return ( value < 0 ); }
+
+ inline long Value() { return value; }
+ inline operator long() const { return value; }
+
+ inline const char* Label() { return label; }
+ inline operator const char*() const { return label; }
+ };
+
+ const Result_t RESULT_FALSE ( 1, "Successful but not true.");
+ const Result_t RESULT_OK ( 0, "Success.");
+ const Result_t RESULT_FAIL (-1, "An undefined error was detected.");
+ const Result_t RESULT_PTR (-2, "An unexpected NULL pointer was given.");
+ const Result_t RESULT_NULL_STR (-3, "An unexpected empty string was given.");
+ const Result_t RESULT_ALLOC (-4, "Error allocating memory.");
+ const Result_t RESULT_PARAM (-5, "Invalid parameter.");
+ const Result_t RESULT_NOTIMPL (-6, "Unimplemented Feature.");
+ const Result_t RESULT_SMALLBUF (-7, "The given buffer is too small.");
+ const Result_t RESULT_INIT (-8, "The object is not yet initialized.");
+ const Result_t RESULT_NOT_FOUND (-9, "The requested file does not exist on the system.");
+ const Result_t RESULT_NO_PERM (-10, "Insufficient privilege exists to perform the operation.");
+ const Result_t RESULT_STATE (-11, "Object state error.");
+ const Result_t RESULT_CONFIG (-12, "Invalid configuration option detected.");
+ const Result_t RESULT_FILEOPEN (-13, "File open failure.");
+ const Result_t RESULT_BADSEEK (-14, "An invalid file location was requested.");
+ const Result_t RESULT_READFAIL (-15, "File read error.");
+ const Result_t RESULT_WRITEFAIL (-16, "File write error.");
+ const Result_t RESULT_ENDOFFILE (-17, "Attempt to read past end of file.");
+ const Result_t RESULT_FILEEXISTS (-18, "Filename already exists.");
+ const Result_t RESULT_NOTAFILE (-19, "Filename not found.");
+} // namespace Kumu
+
+//--------------------------------------------------------------------------------
+// convenience macros
+
+// Convenience macros for managing return values in predicates
+# define KM_SUCCESS(v) (((v) < 0) ? 0 : 1)
+# define KM_FAILURE(v) (((v) < 0) ? 1 : 0)
+
+
+// Returns RESULT_PTR if the given argument is NULL.
+// See Result_t above for an explanation of RESULT_* symbols.
+# define KM_TEST_NULL(p) \
+ if ( (p) == 0 ) { \
+ return Kumu::RESULT_PTR; \
+ }
+
+// Returns RESULT_PTR if the given argument is NULL. See Result_t
+// in WaimeaCore for an explanation of RESULT_* symbols. It then assumes
+// that the argument is a pointer to a string and returns
+// RESULT_NULL_STR if the first character is '\0'.
+//
+# define KM_TEST_NULL_STR(p) \
+ KM_TEST_NULL(p); \
+ if ( (p)[0] == '\0' ) { \
+ return Kumu::RESULT_NULL_STR; \
+ }
+
+#endif // _KM_ERROR_H_
+
+//
+// end KM_error.h
+//
diff --git a/FileIO.cpp b/src/KM_fileio.cpp
index 3665c45..1ed32fb 100755..100644
--- a/FileIO.cpp
+++ b/src/KM_fileio.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2005, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -24,17 +24,19 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*! \file FileIO.cpp
+ /*! \file KM_fileio.cpp
\version $Id$
- \brief Cross-platform, simple file accessors
-*/
-
+ \brief portable file i/o
+ */
-#include <FileIO.h>
+#include <KM_fileio.h>
+#include <KM_log.h>
#include <fcntl.h>
#include <assert.h>
-#ifdef WIN32
+using namespace Kumu;
+
+#ifdef KM_WIN32
typedef struct _stati64 fstat_t;
// AFAIK, there is no iovec equivalent in the win32 API
@@ -48,43 +50,62 @@ typedef struct stat fstat_t;
#endif
//
-//
-static ASDCP::Result_t
+static Kumu::Result_t
do_stat(const char* path, fstat_t* stat_info)
{
- ASDCP_TEST_NULL_STR(path);
- ASDCP_TEST_NULL(stat_info);
+ KM_TEST_NULL_STR(path);
+ KM_TEST_NULL(stat_info);
- ASDCP::Result_t result = ASDCP::RESULT_OK;
+ Kumu::Result_t result = Kumu::RESULT_OK;
-#ifdef WIN32
+#ifdef KM_WIN32
UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
if ( _stati64(path, stat_info) == (__int64)-1 )
- result = ASDCP::RESULT_FILEOPEN;
+ result = Kumu::RESULT_FILEOPEN;
::SetErrorMode( prev );
#else
if ( stat(path, stat_info) == -1L )
- result = ASDCP::RESULT_FILEOPEN;
+ result = Kumu::RESULT_FILEOPEN;
if ( stat_info->st_mode & (S_IFREG|S_IFLNK|S_IFDIR) == 0 )
- result = ASDCP::RESULT_FILEOPEN;
+ result = Kumu::RESULT_FILEOPEN;
#endif
return result;
}
+#ifndef KM_WIN32
+
+//
+static Kumu::Result_t
+do_fstat(HANDLE handle, fstat_t* stat_info)
+{
+ KM_TEST_NULL(stat_info);
+
+ Kumu::Result_t result = Kumu::RESULT_OK;
+
+ if ( fstat(handle, stat_info) == -1L )
+ result = Kumu::RESULT_FILEOPEN;
+
+ if ( stat_info->st_mode & (S_IFREG|S_IFLNK|S_IFDIR) == 0 )
+ result = Kumu::RESULT_FILEOPEN;
+
+ return result;
+}
+
+#endif
//
bool
-ASDCP::PathIsFile(const char* pathname)
+Kumu::PathIsFile(const char* pathname)
{
assert(pathname);
fstat_t info;
- if ( ASDCP_SUCCESS(do_stat(pathname, &info)) )
+ if ( KM_SUCCESS(do_stat(pathname, &info)) )
{
if ( info.st_mode & S_IFREG )
return true;
@@ -96,12 +117,12 @@ ASDCP::PathIsFile(const char* pathname)
//
bool
-ASDCP::PathIsDirectory(const char* pathname)
+Kumu::PathIsDirectory(const char* pathname)
{
assert(pathname);
fstat_t info;
- if ( ASDCP_SUCCESS(do_stat(pathname, &info)) )
+ if ( KM_SUCCESS(do_stat(pathname, &info)) )
{
if ( info.st_mode & S_IFDIR )
return true;
@@ -112,13 +133,13 @@ ASDCP::PathIsDirectory(const char* pathname)
//
-ASDCP::fsize_t
-ASDCP::FileSize(const char* pathname)
+Kumu::fsize_t
+Kumu::FileSize(const char* pathname)
{
assert(pathname);
fstat_t info;
- if ( ASDCP_SUCCESS(do_stat(pathname, &info)) )
+ if ( KM_SUCCESS(do_stat(pathname, &info)) )
{
if ( info.st_mode & S_IFREG )
return(info.st_size);
@@ -133,7 +154,7 @@ ASDCP::FileSize(const char* pathname)
const int IOVecMaxEntries = 32; // we never use more that 3, but that number seems somehow small...
//
-class ASDCP::FileWriter::h__iovec
+class Kumu::FileWriter::h__iovec
{
public:
int m_Count;
@@ -144,24 +165,36 @@ public:
//
-ASDCP::fsize_t
-ASDCP::FileReader::Size() const
+Kumu::fsize_t
+Kumu::FileReader::Size() const
{
- return ASDCP::FileSize(m_Filename.c_str());
+#ifdef KM_WIN32
+ return FileSize(m_Filename.c_str());
+#else
+ fstat_t info;
+
+ if ( KM_SUCCESS(do_fstat(m_Handle, &info)) )
+ {
+ if ( info.st_mode & S_IFREG )
+ return(info.st_size);
+ }
+#endif
+
+ return 0;
}
// these are declared here instead of in the header file
// because we have a mem_ptr that is managing a hidden class
-ASDCP::FileWriter::FileWriter() {}
-ASDCP::FileWriter::~FileWriter() {}
+Kumu::FileWriter::FileWriter() {}
+Kumu::FileWriter::~FileWriter() {}
//
-ASDCP::Result_t
-ASDCP::FileWriter::Writev(const byte_t* buf, ui32_t buf_len)
+Kumu::Result_t
+Kumu::FileWriter::Writev(const byte_t* buf, ui32_t buf_len)
{
assert( ! m_IOVec.empty() );
register h__iovec* iov = m_IOVec;
- ASDCP_TEST_NULL(buf);
+ KM_TEST_NULL(buf);
if ( iov->m_Count >= IOVecMaxEntries )
{
@@ -178,14 +211,14 @@ ASDCP::FileWriter::Writev(const byte_t* buf, ui32_t buf_len)
}
-#ifdef WIN32
+#ifdef KM_WIN32
//------------------------------------------------------------------------------------------
//
-ASDCP::Result_t
-ASDCP::FileReader::OpenRead(const char* filename) const
+Kumu::Result_t
+Kumu::FileReader::OpenRead(const char* filename) const
{
- ASDCP_TEST_NULL_STR(filename);
+ KM_TEST_NULL_STR(filename);
const_cast<FileReader*>(this)->m_Filename = filename;
// suppress popup window on error
@@ -203,15 +236,15 @@ ASDCP::FileReader::OpenRead(const char* filename) const
::SetErrorMode(prev);
return ( m_Handle == INVALID_HANDLE_VALUE ) ?
- ASDCP::RESULT_FILEOPEN : ASDCP::RESULT_OK;
+ Kumu::RESULT_FILEOPEN : Kumu::RESULT_OK;
}
//
-ASDCP::Result_t
-ASDCP::FileReader::Close() const
+Kumu::Result_t
+Kumu::FileReader::Close() const
{
if ( m_Handle == INVALID_HANDLE_VALUE )
- return ASDCP::RESULT_FILEOPEN;
+ return Kumu::RESULT_FILEOPEN;
// suppress popup window on error
UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
@@ -219,15 +252,15 @@ ASDCP::FileReader::Close() const
::SetErrorMode(prev);
const_cast<FileReader*>(this)->m_Handle = INVALID_HANDLE_VALUE;
- return ( result == 0 ) ? ASDCP::RESULT_FAIL : ASDCP::RESULT_OK;
+ return ( result == 0 ) ? Kumu::RESULT_FAIL : Kumu::RESULT_OK;
}
//
-ASDCP::Result_t
-ASDCP::FileReader::Seek(ASDCP::fpos_t position, SeekPos_t whence) const
+Kumu::Result_t
+Kumu::FileReader::Seek(Kumu::fpos_t position, SeekPos_t whence) const
{
if ( m_Handle == INVALID_HANDLE_VALUE )
- return ASDCP::RESULT_STATE;
+ return Kumu::RESULT_STATE;
LARGE_INTEGER in;
UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
@@ -239,19 +272,19 @@ ASDCP::FileReader::Seek(ASDCP::fpos_t position, SeekPos_t whence) const
if ( (LastError != NO_ERROR
&& (in.LowPart == INVALID_SET_FILE_POINTER
|| in.LowPart == ERROR_NEGATIVE_SEEK )) )
- return ASDCP::RESULT_READFAIL;
+ return Kumu::RESULT_READFAIL;
- return ASDCP::RESULT_OK;
+ return Kumu::RESULT_OK;
}
//
-ASDCP::Result_t
-ASDCP::FileReader::Tell(ASDCP::fpos_t* pos) const
+Kumu::Result_t
+Kumu::FileReader::Tell(Kumu::fpos_t* pos) const
{
- ASDCP_TEST_NULL(pos);
+ KM_TEST_NULL(pos);
if ( m_Handle == (HANDLE)-1L )
- return ASDCP::RESULT_FILEOPEN;
+ return Kumu::RESULT_FILEOPEN;
LARGE_INTEGER in;
UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
@@ -263,18 +296,18 @@ ASDCP::FileReader::Tell(ASDCP::fpos_t* pos) const
if ( (LastError != NO_ERROR
&& (in.LowPart == INVALID_SET_FILE_POINTER
|| in.LowPart == ERROR_NEGATIVE_SEEK )) )
- return ASDCP::RESULT_READFAIL;
+ return Kumu::RESULT_READFAIL;
- *pos = (ASDCP::fpos_t)in.QuadPart;
- return ASDCP::RESULT_OK;
+ *pos = (Kumu::fpos_t)in.QuadPart;
+ return Kumu::RESULT_OK;
}
//
-ASDCP::Result_t
-ASDCP::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
+Kumu::Result_t
+Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
{
- ASDCP_TEST_NULL(buf);
- Result_t result = ASDCP::RESULT_OK;
+ KM_TEST_NULL(buf);
+ Result_t result = Kumu::RESULT_OK;
DWORD tmp_count;
ui32_t tmp_int;
@@ -284,18 +317,18 @@ ASDCP::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
*read_count = 0;
if ( m_Handle == INVALID_HANDLE_VALUE )
- return ASDCP::RESULT_FILEOPEN;
+ return Kumu::RESULT_FILEOPEN;
UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
if ( ::ReadFile(m_Handle, buf, buf_len, &tmp_count, NULL) == 0 )
- result = ASDCP::RESULT_READFAIL;
+ result = Kumu::RESULT_READFAIL;
::SetErrorMode(prev);
if ( tmp_count == 0 ) /* EOF */
- result = ASDCP::RESULT_ENDOFFILE;
+ result = Kumu::RESULT_ENDOFFILE;
- if ( ASDCP_SUCCESS(result) )
+ if ( KM_SUCCESS(result) )
*read_count = tmp_count;
return result;
@@ -307,10 +340,10 @@ ASDCP::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
//
//
-ASDCP::Result_t
-ASDCP::FileWriter::OpenWrite(const char* filename)
+Kumu::Result_t
+Kumu::FileWriter::OpenWrite(const char* filename)
{
- ASDCP_TEST_NULL_STR(filename);
+ KM_TEST_NULL_STR(filename);
m_Filename = filename;
// suppress popup window on error
@@ -328,15 +361,15 @@ ASDCP::FileWriter::OpenWrite(const char* filename)
::SetErrorMode(prev);
if ( m_Handle == INVALID_HANDLE_VALUE )
- return ASDCP::RESULT_FILEOPEN;
+ return Kumu::RESULT_FILEOPEN;
m_IOVec = new h__iovec;
- return ASDCP::RESULT_OK;
+ return Kumu::RESULT_OK;
}
//
-ASDCP::Result_t
-ASDCP::FileWriter::Writev(ui32_t* bytes_written)
+Kumu::Result_t
+Kumu::FileWriter::Writev(ui32_t* bytes_written)
{
assert( ! m_IOVec.empty() );
register h__iovec* iov = m_IOVec;
@@ -346,11 +379,11 @@ ASDCP::FileWriter::Writev(ui32_t* bytes_written)
bytes_written = &tmp_int;
if ( m_Handle == INVALID_HANDLE_VALUE )
- return ASDCP::RESULT_STATE;
+ return Kumu::RESULT_STATE;
*bytes_written = 0;
UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
- Result_t result = ASDCP::RESULT_OK;
+ Result_t result = Kumu::RESULT_OK;
// AFAIK, there is no writev() equivalent in the win32 API
for ( register int i = 0; i < iov->m_Count; i++ )
@@ -362,12 +395,13 @@ ASDCP::FileWriter::Writev(ui32_t* bytes_written)
(DWORD*)&tmp_count,
NULL);
- if ( wr_result == 0 || iov->m_iovec[i].iov_len != tmp_count)
+ if ( wr_result == 0 )
{
- result = ASDCP::RESULT_WRITEFAIL;
+ result = Kumu::RESULT_WRITEFAIL;
break;
}
+ assert(iov->m_iovec[i].iov_len == tmp_count);
*bytes_written += tmp_count;
}
@@ -378,43 +412,43 @@ ASDCP::FileWriter::Writev(ui32_t* bytes_written)
}
//
-ASDCP::Result_t
-ASDCP::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written)
+Kumu::Result_t
+Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written)
{
- ASDCP_TEST_NULL(buf);
+ KM_TEST_NULL(buf);
ui32_t tmp_int;
if ( bytes_written == 0 )
bytes_written = &tmp_int;
if ( m_Handle == INVALID_HANDLE_VALUE )
- return ASDCP::RESULT_STATE;
+ return Kumu::RESULT_STATE;
// suppress popup window on error
UINT prev = ::SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
BOOL result = ::WriteFile(m_Handle, buf, buf_len, (DWORD*)bytes_written, NULL);
::SetErrorMode(prev);
- return ( result == 0 ) ? ASDCP::RESULT_WRITEFAIL : ASDCP::RESULT_OK;
+ return ( result == 0 ) ? Kumu::RESULT_WRITEFAIL : Kumu::RESULT_OK;
}
-#else // WIN32
+#else // KM_WIN32
//------------------------------------------------------------------------------------------
// POSIX
//
-ASDCP::Result_t
-ASDCP::FileReader::OpenRead(const char* filename) const
+Kumu::Result_t
+Kumu::FileReader::OpenRead(const char* filename) const
{
- ASDCP_TEST_NULL_STR(filename);
+ KM_TEST_NULL_STR(filename);
const_cast<FileReader*>(this)->m_Filename = filename;
const_cast<FileReader*>(this)->m_Handle = open(filename, O_RDONLY, 0);
return ( m_Handle == -1L ) ? RESULT_FILEOPEN : RESULT_OK;
}
//
-ASDCP::Result_t
-ASDCP::FileReader::Close() const
+Kumu::Result_t
+Kumu::FileReader::Close() const
{
if ( m_Handle == -1L )
return RESULT_FILEOPEN;
@@ -425,8 +459,8 @@ ASDCP::FileReader::Close() const
}
//
-ASDCP::Result_t
-ASDCP::FileReader::Seek(ASDCP::fpos_t position, SeekPos_t whence) const
+Kumu::Result_t
+Kumu::FileReader::Seek(Kumu::fpos_t position, SeekPos_t whence) const
{
if ( m_Handle == -1L )
return RESULT_FILEOPEN;
@@ -438,15 +472,15 @@ ASDCP::FileReader::Seek(ASDCP::fpos_t position, SeekPos_t whence) const
}
//
-ASDCP::Result_t
-ASDCP::FileReader::Tell(ASDCP::fpos_t* pos) const
+Kumu::Result_t
+Kumu::FileReader::Tell(Kumu::fpos_t* pos) const
{
- ASDCP_TEST_NULL(pos);
+ KM_TEST_NULL(pos);
if ( m_Handle == -1L )
return RESULT_FILEOPEN;
- ASDCP::fpos_t tmp_pos;
+ Kumu::fpos_t tmp_pos;
if ( (tmp_pos = lseek(m_Handle, 0, SEEK_CUR)) == -1 )
return RESULT_READFAIL;
@@ -456,10 +490,10 @@ ASDCP::FileReader::Tell(ASDCP::fpos_t* pos) const
}
//
-ASDCP::Result_t
-ASDCP::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
+Kumu::Result_t
+Kumu::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
{
- ASDCP_TEST_NULL(buf);
+ KM_TEST_NULL(buf);
i32_t tmp_count = 0;
ui32_t tmp_int = 0;
@@ -483,16 +517,16 @@ ASDCP::FileReader::Read(byte_t* buf, ui32_t buf_len, ui32_t* read_count) const
//
//
-ASDCP::Result_t
-ASDCP::FileWriter::OpenWrite(const char* filename)
+Kumu::Result_t
+Kumu::FileWriter::OpenWrite(const char* filename)
{
- ASDCP_TEST_NULL_STR(filename);
+ KM_TEST_NULL_STR(filename);
m_Filename = filename;
m_Handle = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644);
if ( m_Handle == -1L )
{
- perror(filename);
+ DefaultLogSink().Error("Error opening file %s: %s\n", filename, strerror(errno));
return RESULT_FILEOPEN;
}
@@ -501,8 +535,26 @@ ASDCP::FileWriter::OpenWrite(const char* filename)
}
//
-ASDCP::Result_t
-ASDCP::FileWriter::Writev(ui32_t* bytes_written)
+Kumu::Result_t
+Kumu::FileWriter::OpenModify(const char* filename)
+{
+ KM_TEST_NULL_STR(filename);
+ m_Filename = filename;
+ m_Handle = open(filename, O_RDWR|O_CREAT, 0644);
+
+ if ( m_Handle == -1L )
+ {
+ DefaultLogSink().Error("Error opening file %s: %s\n", filename, strerror(errno));
+ return RESULT_FILEOPEN;
+ }
+
+ m_IOVec = new h__iovec;
+ return RESULT_OK;
+}
+
+//
+Kumu::Result_t
+Kumu::FileWriter::Writev(ui32_t* bytes_written)
{
assert( ! m_IOVec.empty() );
register h__iovec* iov = m_IOVec;
@@ -525,15 +577,18 @@ ASDCP::FileWriter::Writev(ui32_t* bytes_written)
}
//
-ASDCP::Result_t
-ASDCP::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written)
+Kumu::Result_t
+Kumu::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_written)
{
- ASDCP_TEST_NULL(buf);
+ KM_TEST_NULL(buf);
ui32_t tmp_int;
if ( bytes_written == 0 )
bytes_written = &tmp_int;
+ // TODO: flush iovec
+
+
if ( m_Handle == -1L )
return RESULT_STATE;
@@ -547,8 +602,200 @@ ASDCP::FileWriter::Write(const byte_t* buf, ui32_t buf_len, ui32_t* bytes_writte
}
-#endif // WIN32
+#endif // KM_WIN32
+
+//------------------------------------------------------------------------------------------
+
+
+//
+Kumu::Result_t
+Kumu::ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size)
+{
+ fsize_t fsize = 0;
+ ui32_t read_size;
+ FileReader File;
+ ByteString ReadBuf;
+
+ KM_TEST_NULL_STR(filename);
+
+ Result_t result = File.OpenRead(filename);
+
+ if ( KM_SUCCESS(result) )
+ {
+ fsize = File.Size();
+
+ if ( fsize > max_size )
+ return RESULT_ALLOC;
+
+ result = ReadBuf.Capacity((ui32_t)fsize);
+ }
+
+ if ( KM_SUCCESS(result) )
+ result = File.Read(ReadBuf.Data(), ReadBuf.Capacity(), &read_size);
+
+ if ( KM_SUCCESS(result) )
+ outString.assign((const char*)ReadBuf.RoData(), read_size);
+
+ return result;
+}
+
+
+//------------------------------------------------------------------------------------------
+//
+
+// Win32 directory scanner
+//
+#ifdef KM_WIN32
+
+//
+//
+Result_t
+Kumu::DirScanner::Open(const char* filename)
+{
+ KM_TEST_NULL_STR(filename);
+
+ // we need to append a '*' to read the entire directory
+ ui32_t fn_len = strlen(filename);
+ char* tmp_file = (char*)malloc(fn_len + 8);
+
+ if ( tmp_file == 0 )
+ return RESULT_ALLOC;
+
+ strcpy(tmp_file, filename);
+ char* p = &tmp_file[fn_len] - 1;
+
+ if ( *p != '/' && *p != '\\' )
+ {
+ p++;
+ *p++ = '/';
+ }
+
+ *p++ = '*';
+ *p = 0;
+ // whew...
+
+ m_Handle = _findfirsti64(tmp_file, &m_FileInfo);
+ Result_t result = RESULT_OK;
+
+ if ( m_Handle == -1 )
+ result = RESULT_NOT_FOUND;
+
+ return result;
+}
+
+
+//
+//
+Result_t
+Kumu::DirScanner::Close()
+{
+ if ( m_Handle == -1 )
+ return RESULT_FILEOPEN;
+
+ if ( _findclose((long)m_Handle) == -1 )
+ return RESULT_FAIL;
+
+ m_Handle = -1;
+ return RESULT_OK;
+}
+
+
+// This sets filename param to the same per-instance buffer every time, so
+// the value will change on the next call
+Result_t
+Kumu::DirScanner::GetNext(char* filename)
+{
+ KM_TEST_NULL(filename);
+
+ if ( m_Handle == -1 )
+ return RESULT_FILEOPEN;
+
+ if ( m_FileInfo.name[0] == '\0' )
+ return RESULT_ENDOFFILE;
+
+ strncpy(filename, m_FileInfo.name, MaxFilePath);
+ Result_t result = RESULT_OK;
+
+ if ( _findnexti64((long)m_Handle, &m_FileInfo) == -1 )
+ {
+ m_FileInfo.name[0] = '\0';
+
+ if ( errno != ENOENT )
+ result = RESULT_FAIL;
+ }
+
+ return result;
+}
+
+
+#else // KM_WIN32
+
+// POSIX directory scanner
+
+//
+Result_t
+Kumu::DirScanner::Open(const char* filename)
+{
+ KM_TEST_NULL_STR(filename);
+
+ Result_t result = RESULT_OK;
+
+ if ( ( m_Handle = opendir(filename) ) == NULL )
+ {
+ if ( errno == ENOENT )
+ result = RESULT_ENDOFFILE;
+
+ else
+ result = RESULT_FAIL;
+ }
+
+ return result;
+}
+
+
+//
+Result_t
+Kumu::DirScanner::Close()
+{
+ if ( m_Handle == NULL )
+ return RESULT_FILEOPEN;
+
+ if ( closedir(m_Handle) == -1 )
+ return RESULT_FAIL;
+
+ m_Handle = NULL;
+ return RESULT_OK;
+}
+
+
+//
+Result_t
+Kumu::DirScanner::GetNext(char* filename)
+{
+ KM_TEST_NULL(filename);
+
+ if ( m_Handle == NULL )
+ return RESULT_FILEOPEN;
+
+ struct dirent* entry;
+
+ for (;;)
+ {
+ if ( ( entry = readdir(m_Handle)) == NULL )
+ return RESULT_ENDOFFILE;
+
+ break;
+ }
+
+ strncpy(filename, entry->d_name, MaxFilePath);
+ return RESULT_OK;
+}
+
+
+#endif // KM_WIN32
+
+
//
-// end FileIO.cpp
+// end KM_fileio.cpp
//
diff --git a/FileIO.h b/src/KM_fileio.h
index 159d0a3..9c79d49 100755
--- a/FileIO.h
+++ b/src/KM_fileio.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2003-2005, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -24,27 +24,64 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*! \file FileIO.h
+ /*! \file KM_fileio.h
\version $Id$
- \brief Cross-platform, simple file accessors
-*/
-
+ \brief portable file i/o
+ */
-#ifndef _FILEIO_H_
-#define _FILEIO_H_
+#ifndef _KM_FILEIO_H_
+#define _KM_FILEIO_H_
-#include <AS_DCP_system.h>
-#include <sys/stat.h>
+#include <KM_util.h>
+#include <string>
-#ifdef WIN32
-#include <io.h>
+#ifdef KM_WIN32
+# include <io.h>
#else
-#include <unistd.h>
-#include <sys/types.h>
+# include <dirent.h>
+# include <unistd.h>
+# include <time.h>
+# include <sys/types.h>
#endif
-namespace ASDCP {
-#ifdef WIN32
+#include <sys/stat.h>
+
+
+
+namespace Kumu
+{
+#ifdef KM_WIN32
+ //
+ class DirScanner
+ {
+ public:
+ __int64 m_Handle;
+ struct _finddatai64_t m_FileInfo;
+
+ DirScanner() {};
+ ~DirScanner() { Close(); }
+ Result_t Open(const char*);
+ Result_t Close();
+ Result_t GetNext(char*);
+ };
+#else // KM_WIN32
+ // POSIX directory scanner
+ //
+ class DirScanner
+ {
+ public:
+ DIR* m_Handle;
+
+ DirScanner() : m_Handle(NULL) {}
+ ~DirScanner() { Close(); }
+
+ Result_t Open(const char*);
+ Result_t Close();
+ Result_t GetNext(char*);
+ };
+#endif // KM_WIN32
+
+#ifdef KM_WIN32
typedef __int64 fsize_t;
typedef __int64 fpos_t;
@@ -66,14 +103,23 @@ namespace ASDCP {
};
#endif
- bool PathIsFile(const char* pathname);
- bool PathIsDirectory(const char* pathname);
- fsize_t FileSize(const char* pathname);
+ const ui32_t Kilobyte = 1024;
+ const ui32_t Megabyte = Kilobyte * Kilobyte;
+ const ui32_t Gigabyte = Megabyte * Kilobyte;
+
+ const ui32_t MaxFilePath = Kilobyte;
+
+ bool PathIsFile(const char* pathname);
+ bool PathIsDirectory(const char* pathname);
+ fsize_t FileSize(const char* pathname);
+
+ // reads an entire file into a string
+ Result_t ReadFileIntoString(const char* filename, std::string& outString, ui32_t max_size = 256 * Kilobyte);
//
class FileReader
{
- ASDCP_NO_COPY_CONSTRUCT(FileReader);
+ KM_NO_COPY_CONSTRUCT(FileReader);
protected:
std::string m_Filename;
@@ -86,13 +132,13 @@ namespace ASDCP {
Result_t OpenRead(const char*) const; // open the file for reading
Result_t Close() const; // close the file
fsize_t Size() const; // returns the file's current size
- Result_t Seek(ASDCP::fpos_t = 0, SeekPos_t = SP_BEGIN) const; // move the file pointer
- Result_t Tell(ASDCP::fpos_t* pos) const; // report the file pointer's location
+ Result_t Seek(Kumu::fpos_t = 0, SeekPos_t = SP_BEGIN) const; // move the file pointer
+ Result_t Tell(Kumu::fpos_t* pos) const; // report the file pointer's location
Result_t Read(byte_t*, ui32_t, ui32_t* = 0) const; // read a buffer of data
- inline ASDCP::fpos_t Tell() const // report the file pointer's location
+ inline Kumu::fpos_t Tell() const // report the file pointer's location
{
- ASDCP::fpos_t tmp_pos;
+ Kumu::fpos_t tmp_pos;
Tell(&tmp_pos);
return tmp_pos;
}
@@ -102,13 +148,12 @@ namespace ASDCP {
}
};
-
//
class FileWriter : public FileReader
{
class h__iovec;
mem_ptr<h__iovec> m_IOVec;
- ASDCP_NO_COPY_CONSTRUCT(FileWriter);
+ KM_NO_COPY_CONSTRUCT(FileWriter);
public:
FileWriter();
@@ -121,23 +166,21 @@ namespace ASDCP {
// platforms that support it. For each call to Writev(const byte_t*, ui32_t, ui32_t*),
// the given buffer is added to an internal iovec struct. All items on the list
// are written to disk by a call to Writev();
- Result_t Writev(const byte_t*, ui32_t); // queue buffer for write
+ Result_t Writev(const byte_t*, ui32_t); // queue buffer for "gather" write
Result_t Writev(ui32_t* = 0); // write all queued buffers
// if you call this while there are unwritten items on the iovec list,
- // the iovec list will be written to disk before the givn buffer,as though
+ // the iovec list will be written to disk before the given buffer,as though
// you had called Writev() first.
Result_t Write(const byte_t*, ui32_t, ui32_t* = 0); // write buffer to disk
-
-
};
-} // namespace ASDCP
+} // namespace Kumu
-#endif // _FILEREADER_H_
+#endif // _KM_FILEIO_H_
//
-// end FileReader.h
+// end KM_fileio.h
//
diff --git a/src/KM_log.cpp b/src/KM_log.cpp
new file mode 100755
index 0000000..a76df09
--- /dev/null
+++ b/src/KM_log.cpp
@@ -0,0 +1,155 @@
+/*
+Copyright (c) 2004-2006, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+ /*! \file KM_log.cpp
+ \version $Id$
+ \brief message logging API
+ */
+
+#include <KM_util.h>
+#include <KM_log.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef KM_WIN32
+#define getpid GetCurrentProcessId
+#else
+#include <unistd.h>
+#endif
+
+
+void
+Kumu::StdioLogSink::vLogf(ILogSink::LogType_t type, const char* fmt, va_list* list)
+{
+ AutoMutex L(m_Lock);
+
+ switch ( type )
+ {
+ case LOG_CRIT: fprintf(m_stream, "[%d CRT]: ", getpid()); break;
+ case LOG_ALERT: fprintf(m_stream, "[%d ALR]: ", getpid()); break;
+ case LOG_NOTICE: fprintf(m_stream, "[%d NTC]: ", getpid()); break;
+ case LOG_ERROR: fprintf(m_stream, "[%d ERR]: ", getpid()); break;
+ case LOG_WARN: fprintf(m_stream, "[%d WRN]: ", getpid()); break;
+ case LOG_INFO: fprintf(m_stream, "[%d INF]: ", getpid()); break;
+ case LOG_DEBUG: fprintf(m_stream, "[%d DBG]: ", getpid()); break;
+ default: fprintf(m_stream, "[%d DFL]: ", getpid());
+ }
+
+ vfprintf(m_stream, fmt, *list);
+}
+
+static Kumu::ILogSink* s_DefaultLogSink;
+static Kumu::StdioLogSink s_StderrLogSink;
+
+//
+void
+Kumu::SetDefaultLogSink(ILogSink* Sink)
+{
+ s_DefaultLogSink = Sink;
+}
+
+// Returns the internal default sink.
+Kumu::ILogSink&
+Kumu::DefaultLogSink()
+{
+ if ( s_DefaultLogSink == 0 )
+ s_DefaultLogSink = &s_StderrLogSink;
+
+ return *s_DefaultLogSink;
+}
+
+//---------------------------------------------------------------------------------
+#ifdef KM_WIN32
+
+//
+void
+Kumu::WinDbgLogSink::vLogf(ILogSink::LogType_t type, const char* fmt, va_list* list)
+{
+ AutoMutex L(m_Lock);
+ char msg_buf[MaxLogLength];
+
+ DWORD pid = GetCurrentProcessId();
+
+ switch ( type )
+ {
+ case LOG_CRIT: snprintf(msg_buf, MaxLogLength, "[%d CRT]: ", pid); break;
+ case LOG_ALERT: snprintf(msg_buf, MaxLogLength, "[%d ALR]: ", pid); break;
+ case LOG_NOTICE: snprintf(msg_buf, MaxLogLength, "[%d NTC]: ", pid); break;
+ case LOG_ERROR: snprintf(msg_buf, MaxLogLength, "[%d ERR]: ", pid); break;
+ case LOG_WARN: snprintf(msg_buf, MaxLogLength, "[%d WRN]: ", pid); break;
+ case LOG_INFO: snprintf(msg_buf, MaxLogLength, "[%d INF]: ", pid); break;
+ case LOG_DEBUG: snprintf(msg_buf, MaxLogLength, "[%d DBG]: ", pid); break;
+ default: snprintf(msg_buf, MaxLogLength, "[%d DFL]: ", pid);
+ }
+
+ ui32_t len = strlen(msg_buf);
+ vsnprintf(msg_buf + len, MaxLogLength - len, fmt, *list);
+ msg_buf[MaxLogLength-1] = 0;
+ ::OutputDebugString(msg_buf);
+}
+
+#else
+
+void
+Kumu::StreamLogSink::vLogf(ILogSink::LogType_t type, const char* fmt, va_list* list)
+{
+ AutoMutex L(m_Lock);
+ char msg_buf[MaxLogLength];
+ char ts_buf[MaxLogLength];
+ Timestamp Now;
+
+ switch ( type )
+ {
+ case LOG_CRIT: snprintf(msg_buf, MaxLogLength, "[%s %d CRT]: ",
+ Now.EncodeString(ts_buf, MaxLogLength), getpid()); break;
+ case LOG_ALERT: snprintf(msg_buf, MaxLogLength, "[%s %d ALR]: ",
+ Now.EncodeString(ts_buf, MaxLogLength), getpid()); break;
+ case LOG_NOTICE: snprintf(msg_buf, MaxLogLength, "[%s %d NTC]: ",
+ Now.EncodeString(ts_buf, MaxLogLength), getpid()); break;
+ case LOG_ERROR: snprintf(msg_buf, MaxLogLength, "[%s %d ERR]: ",
+ Now.EncodeString(ts_buf, MaxLogLength), getpid()); break;
+ case LOG_WARN: snprintf(msg_buf, MaxLogLength, "[%s %d WRN]: ",
+ Now.EncodeString(ts_buf, MaxLogLength), getpid()); break;
+ case LOG_INFO: snprintf(msg_buf, MaxLogLength, "[%s %d INF]: ",
+ Now.EncodeString(ts_buf, MaxLogLength), getpid()); break;
+ case LOG_DEBUG: snprintf(msg_buf, MaxLogLength, "[%s %d DBG]: ",
+ Now.EncodeString(ts_buf, MaxLogLength), getpid()); break;
+ default: snprintf(msg_buf, MaxLogLength, "[%s %d DFL]: ",
+ Now.EncodeString(ts_buf, MaxLogLength), getpid());
+ }
+
+ ui32_t len = strlen(msg_buf);
+ vsnprintf(msg_buf + len, MaxLogLength - len, fmt, *list);
+ msg_buf[MaxLogLength-1] = 0;
+ write(m_fd, msg_buf, strlen(msg_buf));
+}
+#endif
+
+
+//
+// end
+//
diff --git a/src/KM_log.h b/src/KM_log.h
new file mode 100755
index 0000000..2bbc330
--- /dev/null
+++ b/src/KM_log.h
@@ -0,0 +1,133 @@
+/*
+Copyright (c) 2004-2006, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+ /*! \file KM_log.h
+ \version $Id$
+ \brief message logging API
+ */
+
+
+#ifndef _KM_LOG_H_
+#define _KM_LOG_H_
+
+#include <KM_platform.h>
+#include <KM_mutex.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#define LOG_MSG_IMPL(t) va_list args; va_start(args, fmt); vLogf((t), fmt, &args); va_end(args)
+
+
+namespace Kumu
+{
+ // no log message will exceed this length
+ const ui32_t MaxLogLength = 512;
+
+ //---------------------------------------------------------------------------------
+ // message logging
+
+ // Error and debug messages will be delivered to an object having this interface.
+ // The default implementation sends only LOG_ERROR and LOG_WARN messages to stderr.
+ // To receive LOG_INFO or LOG_DEBUG messages, or to send messages somewhere other
+ // than stderr, implement this interface and register an instance of your new class
+ // by calling SetDefaultLogSink().
+ class ILogSink
+ {
+ public:
+ enum LogType_t { LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR,
+ LOG_NOTICE, LOG_ALERT, LOG_CRIT };
+
+ virtual ~ILogSink() {}
+
+ void Critical(const char* fmt, ...) { LOG_MSG_IMPL(LOG_CRIT); }
+ void Alert(const char* fmt, ...) { LOG_MSG_IMPL(LOG_ALERT); }
+ void Notice(const char* fmt, ...) { LOG_MSG_IMPL(LOG_NOTICE); }
+ void Error(const char* fmt, ...) { LOG_MSG_IMPL(LOG_ERROR); }
+ void Warn(const char* fmt, ...) { LOG_MSG_IMPL(LOG_WARN); }
+ void Info(const char* fmt, ...) { LOG_MSG_IMPL(LOG_INFO); }
+ void Debug(const char* fmt, ...) { LOG_MSG_IMPL(LOG_DEBUG); }
+ void Logf(ILogSink::LogType_t type, const char* fmt, ...) { LOG_MSG_IMPL(type); }
+ virtual void vLogf(LogType_t, const char*, va_list*) = 0; // log a formatted string with a va_list struct
+ };
+
+ // Sets the internal default sink to the given receiver. If the given value
+ // is zero, sets the default sink to the internally allocated stderr sink.
+ void SetDefaultLogSink(ILogSink* = 0);
+
+ // Returns the internal default sink.
+ ILogSink& DefaultLogSink();
+
+ //
+ class StdioLogSink : public ILogSink
+ {
+ Mutex m_Lock;
+ FILE* m_stream;
+ KM_NO_COPY_CONSTRUCT(StdioLogSink);
+
+ public:
+ StdioLogSink() : m_stream(stderr) {};
+ StdioLogSink(FILE* stream) : m_stream(stream) {}
+ virtual ~StdioLogSink() {}
+ virtual void vLogf(LogType_t, const char*, va_list*);
+ };
+
+#ifdef KM_WIN32
+ //
+ class WinDbgLogSink : public ILogSink
+ {
+ Mutex m_Lock;
+ KM_NO_COPY_CONSTRUCT(WinDbgLogSink);
+
+ public:
+ WinDbgLogSink() {}
+ virtual ~WinDbgLogSink() {}
+ virtual void vLogf(LogType_t, const char*, va_list*);
+ };
+
+#else
+
+ //
+ class StreamLogSink : public ILogSink
+ {
+ Mutex m_Lock;
+ int m_fd;
+ KM_NO_COPY_CONSTRUCT(StreamLogSink);
+ StreamLogSink();
+
+ public:
+ StreamLogSink(int fd) : m_fd(fd) {}
+ virtual ~StreamLogSink() {}
+ virtual void vLogf(LogType_t, const char*, va_list*);
+ };
+#endif
+
+} // namespace Kumu
+
+#endif // _KM_LOG_H_
+
+//
+// end KM_log.h
+//
diff --git a/MemIO.h b/src/KM_memio.h
index c8e8493..8416b57 100755
--- a/MemIO.h
+++ b/src/KM_memio.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2005, John Hurst
+Copyright (c) 2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -24,23 +24,25 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*! \file MemIO.h
+ /*! \file KM_memio.h
\version $Id$
- \brief Interface for reading and writing typed objects to a byte-oriented buffer
-*/
+ \brief abstraction for byte-oriented conversion of integers and objects
+ */
-#ifndef _MEMIO_H_
-#define _MEMIO_H_
+#ifndef _KM_MEMIO_H_
+#define _KM_MEMIO_H_
-#include <AS_DCP_system.h>
-#include <hex_utils.h>
+#include <KM_platform.h>
+#include <string.h>
-namespace ASDCP
+namespace Kumu
{
+ class ByteString;
+
//
class MemIOWriter
{
- ASDCP_NO_COPY_CONSTRUCT(MemIOWriter);
+ KM_NO_COPY_CONSTRUCT(MemIOWriter);
MemIOWriter();
protected:
@@ -49,88 +51,80 @@ namespace ASDCP
ui32_t m_size;
public:
- MemIOWriter(byte_t* p, ui32_t c) :
- m_p(p), m_capacity(c), m_size(0) {
- assert(m_p);
+ MemIOWriter(byte_t* p, ui32_t c) : m_p(p), m_capacity(c), m_size(0) {
+ assert(m_p); assert(m_capacity);
}
+ MemIOWriter(ByteString* Buf);
~MemIOWriter() {}
+ inline void Reset() { m_size = 0; }
inline byte_t* Data() { return m_p; }
inline byte_t* CurrentData() { return m_p + m_size; }
- inline ui32_t Size() { return m_size; }
+ inline ui32_t Length() { return m_size; }
inline ui32_t Remainder() { return m_capacity - m_size; }
- inline Result_t AddOffset(ui32_t offset) {
+ inline bool AddOffset(ui32_t offset) {
if ( ( m_size + offset ) > m_capacity )
- return RESULT_FAIL;
+ return false;
m_size += offset;
- return RESULT_OK;
+ return true;
}
- inline Result_t WriteRaw(const byte_t* p, ui32_t buf_len) {
+ inline bool WriteRaw(const byte_t* p, ui32_t buf_len) {
if ( ( m_size + buf_len ) > m_capacity )
- return RESULT_FAIL;
+ return false;
memcpy(m_p + m_size, p, buf_len);
m_size += buf_len;
- return RESULT_OK;
+ return true;
}
- inline Result_t WriteBER(ui64_t i, ui32_t ber_len) {
- if ( ( m_size + ber_len ) > m_capacity )
- return RESULT_FAIL;
-
- if ( ! write_BER(m_p + m_size, i, ber_len) )
- return RESULT_FAIL;
+ bool WriteBER(ui64_t i, ui32_t ber_len);
- m_size += ber_len;
- return RESULT_OK;
- }
-
- inline Result_t WriteUi8(ui8_t i) {
+ inline bool WriteUi8(ui8_t i) {
if ( ( m_size + 1 ) > m_capacity )
- return RESULT_FAIL;
+ return false;
*(m_p + m_size) = i;
m_size++;
- return RESULT_OK;
+ return true;
}
- inline Result_t WriteUi16BE(ui16_t i) {
+ inline bool WriteUi16BE(ui16_t i) {
if ( ( m_size + sizeof(ui16_t) ) > m_capacity )
- return RESULT_FAIL;
+ return false;
- i2p<ui16_t>(ASDCP_i16_BE(i), m_p + m_size);
+ i2p<ui16_t>(KM_i16_BE(i), m_p + m_size);
m_size += sizeof(ui16_t);
- return RESULT_OK;
+ return true;
}
- inline Result_t WriteUi32BE(ui32_t i) {
+ inline bool WriteUi32BE(ui32_t i) {
if ( ( m_size + sizeof(ui32_t) ) > m_capacity )
- return RESULT_FAIL;
+ return false;
- i2p<ui32_t>(ASDCP_i32_BE(i), m_p + m_size);
+ i2p<ui32_t>(KM_i32_BE(i), m_p + m_size);
m_size += sizeof(ui32_t);
- return RESULT_OK;
+ return true;
}
- inline Result_t WriteUi64BE(ui64_t i) {
+ inline bool WriteUi64BE(ui64_t i) {
if ( ( m_size + sizeof(ui64_t) ) > m_capacity )
- return RESULT_FAIL;
+ return false;
- i2p<ui64_t>(ASDCP_i64_BE(i), m_p + m_size);
+ i2p<ui64_t>(KM_i64_BE(i), m_p + m_size);
m_size += sizeof(ui64_t);
- return RESULT_OK;
+ return true;
}
};
//
class MemIOReader
{
- ASDCP_NO_COPY_CONSTRUCT(MemIOReader);
+ KM_NO_COPY_CONSTRUCT(MemIOReader);
MemIOReader();
protected:
@@ -141,96 +135,82 @@ namespace ASDCP
public:
MemIOReader(const byte_t* p, ui32_t c) :
m_p(p), m_capacity(c), m_size(0) {
- assert(m_p);
+ assert(m_p); assert(m_capacity);
}
+ MemIOReader(const ByteString* Buf);
~MemIOReader() {}
+ inline void Reset() { m_size = 0; }
inline const byte_t* Data() { return m_p; }
inline const byte_t* CurrentData() { return m_p + m_size; }
- inline ui32_t Offset() { return m_size; }
- inline ui32_t Remainder() { return m_capacity - m_size; }
+ inline ui32_t Offset() { return m_size; }
+ inline ui32_t Remainder() { return m_capacity - m_size; }
- inline Result_t SkipOffset(ui32_t offset) {
+ inline bool SkipOffset(ui32_t offset) {
if ( ( m_size + offset ) > m_capacity )
- return RESULT_FAIL;
+ return false;
m_size += offset;
- return RESULT_OK;
+ return true;
}
- inline Result_t ReadRaw(byte_t* p, ui32_t buf_len) {
+ inline bool ReadRaw(byte_t* p, ui32_t buf_len) {
if ( ( m_size + buf_len ) > m_capacity )
- return RESULT_FAIL;
+ return false;
memcpy(p, m_p + m_size, buf_len);
m_size += buf_len;
- return RESULT_OK;
+ return true;
}
- Result_t ReadBER(ui64_t* i, ui32_t* ber_len) {
- ASDCP_TEST_NULL(i);
- ASDCP_TEST_NULL(ber_len);
+ bool ReadBER(ui64_t* i, ui32_t* ber_len);
- if ( ( *ber_len = BER_length(m_p + m_size) ) == 0 )
- return RESULT_FAIL;
-
- if ( ( m_size + *ber_len ) > m_capacity )
- return RESULT_FAIL;
-
- if ( ! read_BER(m_p + m_size, i) )
- return RESULT_FAIL;
-
- m_size += *ber_len;
- return RESULT_OK;
- }
-
- inline Result_t ReadUi8(ui8_t* i) {
- ASDCP_TEST_NULL(i);
+ inline bool ReadUi8(ui8_t* i) {
+ assert(i);
if ( ( m_size + 1 ) > m_capacity )
- return RESULT_FAIL;
+ return false;
*i = *(m_p + m_size);
m_size++;
- return RESULT_OK;
+ return true;
}
- inline Result_t ReadUi16BE(ui16_t* i) {
- ASDCP_TEST_NULL(i);
+ inline bool ReadUi16BE(ui16_t* i) {
+ assert(i);
if ( ( m_size + sizeof(ui16_t) ) > m_capacity )
- return RESULT_FAIL;
+ return false;
- *i = ASDCP_i16_BE(cp2i<ui16_t>(m_p + m_size));
+ *i = KM_i16_BE(cp2i<ui16_t>(m_p + m_size));
m_size += sizeof(ui16_t);
- return RESULT_OK;
+ return true;
}
- inline Result_t ReadUi32BE(ui32_t* i) {
- ASDCP_TEST_NULL(i);
+ inline bool ReadUi32BE(ui32_t* i) {
+ assert(i);
if ( ( m_size + sizeof(ui32_t) ) > m_capacity )
- return RESULT_FAIL;
+ return false;
- *i = ASDCP_i32_BE(cp2i<ui32_t>(m_p + m_size));
+ *i = KM_i32_BE(cp2i<ui32_t>(m_p + m_size));
m_size += sizeof(ui32_t);
- return RESULT_OK;
+ return true;
}
- inline Result_t ReadUi64BE(ui64_t* i) {
- ASDCP_TEST_NULL(i);
+ inline bool ReadUi64BE(ui64_t* i) {
+ assert(i);
if ( ( m_size + sizeof(ui64_t) ) > m_capacity )
- return RESULT_FAIL;
+ return false;
- *i = ASDCP_i64_BE(cp2i<ui64_t>(m_p + m_size));
+ *i = KM_i64_BE(cp2i<ui64_t>(m_p + m_size));
m_size += sizeof(ui64_t);
- return RESULT_OK;
+ return true;
}
};
+} // namespace Kumu
-} // namespace ASDCP
-
-#endif // _MEMIO_H_
+#endif // _KM_MEMIO_H_
//
-// end MemIO.h
+// end KM_memio.h
//
diff --git a/Mutex.h b/src/KM_mutex.h
index fdd1e81..513b504 100755
--- a/Mutex.h
+++ b/src/KM_mutex.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2005-2006, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -24,23 +24,27 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*! \file Mutex.h
+ /*! \file KM_mutex.h
\version $Id$
- \brief Portable mutex wrapper
-*/
+ \brief platform portability
+ */
+
+#ifndef _KM_MUTEX_H_
+#define _KM_MUTEX_H_
-#ifndef _MUTEX_H_
-#define _MUTEX_H_
+#include <KM_platform.h>
-#include "AS_DCP_system.h"
+#ifndef KM_WIN32
+# include <pthread.h>
+#endif
-namespace ASDCP
+namespace Kumu
{
-#ifdef WIN32
+#ifdef KM_WIN32
class Mutex
{
CRITICAL_SECTION m_Mutex;
- ASDCP_NO_COPY_CONSTRUCT(Mutex);
+ KM_NO_COPY_CONSTRUCT(Mutex);
public:
inline Mutex() { ::InitializeCriticalSection(&m_Mutex); }
@@ -48,12 +52,11 @@ namespace ASDCP
inline void Lock() { ::EnterCriticalSection(&m_Mutex); }
inline void Unlock() { ::LeaveCriticalSection(&m_Mutex); }
};
-#else // WIN32
-#include <pthread.h>
+#else // KM_WIN32
class Mutex
{
pthread_mutex_t m_Mutex;
- ASDCP_NO_COPY_CONSTRUCT(Mutex);
+ KM_NO_COPY_CONSTRUCT(Mutex);
public:
inline Mutex() { pthread_mutex_init(&m_Mutex, 0); }
@@ -61,7 +64,7 @@ namespace ASDCP
inline void Lock() { pthread_mutex_lock(&m_Mutex); }
inline void Unlock() { pthread_mutex_unlock(&m_Mutex); }
};
-#endif // WIN32
+#endif // KM_WIN32
// automatic Mutex management within a block -
// the mutex is created by the constructor and
@@ -70,17 +73,17 @@ namespace ASDCP
{
Mutex& m_Mutex;
AutoMutex();
- ASDCP_NO_COPY_CONSTRUCT(AutoMutex);
+ KM_NO_COPY_CONSTRUCT(AutoMutex);
public:
AutoMutex(Mutex& Mtx) : m_Mutex(Mtx) { m_Mutex.Lock(); }
~AutoMutex() { m_Mutex.Unlock(); }
};
-} // namespace ASDCP
+} // namespace Kumu
-#endif // _MUTEX_H_
+#endif // _KM_MUTEX_H_
//
-// end Mutex.h
+// end KM_mutex.h
//
diff --git a/src/KM_platform.h b/src/KM_platform.h
new file mode 100644
index 0000000..0c577a1
--- /dev/null
+++ b/src/KM_platform.h
@@ -0,0 +1,189 @@
+/*
+Copyright (c) 2004-2006, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+ /*! \file KM_platform.h
+ \version $Id$
+ \brief platform portability
+ */
+
+#ifndef _KM_PLATFORM_H_
+# define _KM_PLATFORM_H_
+
+# ifdef __APPLE__
+# ifdef __BIG_ENDIAN__
+# define KM_BIG_ENDIAN
+# endif
+# endif
+
+# ifdef KM_WIN32
+# define WIN32_LEAN_AND_MEAN
+# define VC_EXTRALEAN
+# include <windows.h>
+# include <stdlib.h>
+# pragma warning(disable:4786) // Ignore "identifer > 255 characters" warning
+
+typedef unsigned __int64 ui64_t;
+typedef __int64 i64_t;
+# define i64_C(c) (i64_t)(c)
+# define ui64_C(c) (ui64_t)(c)
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
+
+# else // KM_WIN32
+typedef unsigned long long ui64_t;
+typedef long long i64_t;
+# define i64_C(c) c##LL
+# define ui64_C(c) c##ULL
+
+# endif // KM_WIN32
+
+# include <stdio.h>
+# include <assert.h>
+# include <stdlib.h>
+# include <limits.h>
+
+typedef unsigned char byte_t;
+typedef char i8_t;
+typedef unsigned char ui8_t;
+typedef short i16_t;
+typedef unsigned short ui16_t;
+typedef int i32_t;
+typedef unsigned int ui32_t;
+
+
+namespace Kumu
+{
+ inline ui16_t Swap2(ui16_t i)
+ {
+ return ( (i << 8) | (( i & 0xff00) >> 8) );
+ }
+
+ inline ui32_t Swap4(ui32_t i)
+ {
+ return
+ ( (i & 0x000000ffUL) << 24 ) |
+ ( (i & 0xff000000UL) >> 24 ) |
+ ( (i & 0x0000ff00UL) << 8 ) |
+ ( (i & 0x00ff0000UL) >> 8 );
+ }
+
+ inline ui64_t Swap8(ui64_t i)
+ {
+ return
+ ( (i & ui64_C(0x00000000000000FF)) << 56 ) |
+ ( (i & ui64_C(0xFF00000000000000)) >> 56 ) |
+ ( (i & ui64_C(0x000000000000FF00)) << 40 ) |
+ ( (i & ui64_C(0x00FF000000000000)) >> 40 ) |
+ ( (i & ui64_C(0x0000000000FF0000)) << 24 ) |
+ ( (i & ui64_C(0x0000FF0000000000)) >> 24 ) |
+ ( (i & ui64_C(0x00000000FF000000)) << 8 ) |
+ ( (i & ui64_C(0x000000FF00000000)) >> 8 );
+ }
+
+ //
+ template<class T>
+ inline T xmin(T lhs, T rhs) {
+ return (lhs < rhs) ? lhs : rhs;
+ }
+
+ //
+ template<class T>
+ inline T xmax(T lhs, T rhs) {
+ return (lhs > rhs) ? lhs : rhs;
+ }
+
+ //
+ template<class T>
+ inline T xclamp(T v, T l, T h) {
+ if ( v < l ) return l;
+ if ( v > h ) return h;
+ return v;
+ }
+
+
+ // read an integer from byte-structured storage
+ template<class T>
+ inline T cp2i(const byte_t* p) { return *(T*)p; }
+
+ // write an integer to byte-structured storage
+ template<class T>
+ inline void i2p(T i, byte_t* p) { *(T*)p = i; }
+
+# ifdef KM_BIG_ENDIAN
+# define KM_i16_LE(i) Kumu::Swap2(i)
+# define KM_i32_LE(i) Kumu::Swap4(i)
+# define KM_i64_LE(i) Kumu::Swap8(i)
+# define KM_i16_BE(i) (i)
+# define KM_i32_BE(i) (i)
+# define KM_i64_BE(i) (i)
+# else
+# define KM_i16_LE(i) (i)
+# define KM_i32_LE(i) (i)
+# define KM_i64_LE(i) (i)
+# define KM_i16_BE(i) Kumu::Swap2(i)
+# define KM_i32_BE(i) Kumu::Swap4(i)
+# define KM_i64_BE(i) Kumu::Swap8(i)
+# endif // KM_BIG_ENDIAN
+
+ // A non-reference counting, auto-delete container for internal
+ // member object pointers.
+ template <class T>
+ class mem_ptr
+ {
+ mem_ptr(T&);
+
+ protected:
+ T* m_p; // the thing we point to
+
+ public:
+ mem_ptr() : m_p(0) {}
+ mem_ptr(T* p) : m_p(p) {}
+ ~mem_ptr() { delete m_p; }
+
+ inline T& operator*() const { return *m_p; }
+ inline T* operator->() const { return m_p; }
+ inline operator T*()const { return m_p; }
+ inline const mem_ptr<T>& operator=(T* p) { set(p); return *this; }
+ inline T* set(T* p) { delete m_p; m_p = p; return m_p; }
+ inline T* get() const { return m_p; }
+ inline void release() { m_p = 0; }
+ inline bool empty() const { return m_p == 0; }
+ };
+
+} // namespace Kumu
+
+// Produces copy constructor boilerplate. Allows convenient private
+// declatarion of copy constructors to prevent the compiler from
+// silently manufacturing default methods.
+# define KM_NO_COPY_CONSTRUCT(T) \
+ T(const T&); \
+ T& operator=(const T&)
+
+#endif // _KM_PLATFORM_H_
+
+//
+// KM_platform.h
+//
diff --git a/src/KM_prng.cpp b/src/KM_prng.cpp
new file mode 100755
index 0000000..5e3dd48
--- /dev/null
+++ b/src/KM_prng.cpp
@@ -0,0 +1,214 @@
+/*
+Copyright (c) 2006, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+ /*! \file KM_prng.cpp
+ \version $Id$
+ \brief Fortuna pseudo-random number generator
+ */
+
+#include <KM_prng.h>
+#include <KM_log.h>
+#include <KM_mutex.h>
+#include <string.h>
+#include <assert.h>
+#include <openssl/aes.h>
+#include <openssl/sha.h>
+
+using namespace Kumu;
+
+
+#ifdef KM_WIN32
+
+// make up a byte by sampling the perf counter LSB
+static byte_t get_perf_byte()
+{
+ LARGE_INTEGER ticks;
+ byte_t retval;
+
+ for ( int i = 0; i < 8; i++ )
+ {
+ QueryPerformanceCounter(&ticks);
+ retval |= (ticks.LowPart & 0x00000001) << i;
+ }
+
+ return retval;
+}
+
+#else // KM_WIN32
+
+#include <KM_fileio.h>
+const char* DEV_URANDOM = "/dev/urandom";
+
+#endif // KM_WIN32
+
+
+const ui32_t RNG_KEY_SIZE = 512UL;
+const ui32_t RNG_KEY_SIZE_BITS = 256UL;
+const ui32_t RNG_BLOCK_SIZE = 16UL;
+const ui32_t MAX_SEQUENCE_LEN = 0x00040000UL;
+
+
+// internal implementation class
+class h__RNG
+{
+ KM_NO_COPY_CONSTRUCT(h__RNG);
+
+public:
+ AES_KEY m_Context;
+ byte_t m_ctr_buf[RNG_BLOCK_SIZE];
+ Mutex m_Lock;
+
+ h__RNG()
+ {
+ memset(m_ctr_buf, 0, RNG_BLOCK_SIZE);
+ byte_t rng_key[RNG_KEY_SIZE];
+
+ { // this block scopes the following AutoMutex so that it will be
+ // released before the call to set_key() below.
+ AutoMutex Lock(m_Lock);
+
+#ifdef KM_WIN32
+ for ( ui32_t i = 0; i < RNG_KEY_SIZE; i++ )
+ rng_key[i] = get_perf_byte();
+
+#else // KM_WIN32
+ // on POSIX systems we simply read some seed from /dev/urandom
+ FileReader URandom;
+
+ Result_t result = URandom.OpenRead(DEV_URANDOM);
+
+ if ( KM_SUCCESS(result) )
+ {
+ ui32_t read_count;
+ result = URandom.Read(rng_key, RNG_KEY_SIZE, &read_count);
+ }
+
+ if ( KM_FAILURE(result) )
+ DefaultLogSink().Error("Error opening random device: %s\n", DEV_URANDOM);
+
+#endif // KM_WIN32
+ } // end AutoMutex context
+
+ set_key(rng_key);
+ }
+
+ //
+ void
+ set_key(const byte_t* key_fodder)
+ {
+ assert(key_fodder);
+ byte_t sha_buf[20];
+ SHA_CTX SHA;
+ SHA1_Init(&SHA);
+
+ SHA1_Update(&SHA, (byte_t*)&m_Context, sizeof(m_Context));
+ SHA1_Update(&SHA, key_fodder, RNG_KEY_SIZE);
+ SHA1_Final(sha_buf, &SHA);
+
+ AutoMutex Lock(m_Lock);
+ AES_set_encrypt_key(sha_buf, RNG_KEY_SIZE_BITS, &m_Context);
+ *(ui32_t*)(m_ctr_buf + 12) = 1;
+ }
+
+ //
+ void
+ fill_rand(byte_t* buf, ui32_t len)
+ {
+ assert(len <= MAX_SEQUENCE_LEN);
+ ui32_t gen_count = 0;
+ AutoMutex Lock(m_Lock);
+
+ while ( gen_count + RNG_BLOCK_SIZE <= len )
+ {
+ AES_encrypt(m_ctr_buf, buf + gen_count, &m_Context);
+ *(ui32_t*)(m_ctr_buf + 12) += 1;
+ gen_count += RNG_BLOCK_SIZE;
+ }
+
+ if ( len != gen_count ) // partial count needed?
+ {
+ byte_t tmp[RNG_BLOCK_SIZE];
+ AES_encrypt(m_ctr_buf, tmp, &m_Context);
+ *(ui32_t*)(m_ctr_buf + 12) += 1;
+ memcpy(buf, tmp, len - gen_count);
+ }
+ }
+};
+
+
+static h__RNG* s_RNG = 0;
+
+
+//------------------------------------------------------------------------------------------
+//
+// public interface
+
+Kumu::FortunaRNG::FortunaRNG()
+{
+ if ( s_RNG == 0 )
+ s_RNG = new h__RNG;
+}
+
+Kumu::FortunaRNG::~FortunaRNG() {}
+
+//
+const byte_t*
+Kumu::FortunaRNG::FillRandom(byte_t* buf, ui32_t len)
+{
+ assert(buf);
+ assert(s_RNG);
+
+ while ( len )
+ {
+ // 2^20 bytes max per seeding, use 2^19 to save
+ // room for generating reseed values
+ ui32_t gen_size = xmin(len, MAX_SEQUENCE_LEN);
+ s_RNG->fill_rand(buf, gen_size);
+ buf += gen_size;
+ len -= gen_size;
+
+ // re-seed the generator
+ byte_t rng_key[RNG_KEY_SIZE];
+ s_RNG->fill_rand(rng_key, RNG_KEY_SIZE);
+ s_RNG->set_key(rng_key);
+ }
+
+ return buf;
+}
+
+//
+const byte_t*
+Kumu::FortunaRNG::FillRandom(Kumu::ByteString& Buffer)
+{
+ FillRandom(Buffer.Data(), Buffer.Capacity());
+ Buffer.Length(Buffer.Capacity());
+ return Buffer.Data();
+}
+
+
+//
+// end KM_prng.cpp
+//
diff --git a/AS_DCP_UUID.h b/src/KM_prng.h
index 342224e..f7dfa2b 100755
--- a/AS_DCP_UUID.h
+++ b/src/KM_prng.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2005, John Hurst
+Copyright (c) 2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -24,30 +24,34 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*! \file AS_DCP_UUID.h
+ /*! \file KM_prng.h
\version $Id$
- \brief UUID generation
-*/
+ \brief Fortuna pseudo-random number generator
+ */
-#ifndef _AS_DCP_UUID_H_
-#define _AS_DCP_UUID_H_
+#ifndef _KM_PRNG_H_
+#define _KM_PRNG_H_
-#include <AS_DCP_system.h>
-#include <FortunaRNG.h>
+#include <KM_util.h>
-namespace ASDCP
+namespace Kumu
{
- void MakeUUID(byte_t* buf);
+ class FortunaRNG
+ {
+ KM_NO_COPY_CONSTRUCT(FortunaRNG);
- void GenRandomUUID(FortunaRNG& RNG, byte_t* buf);
+ public:
+ FortunaRNG();
+ ~FortunaRNG();
+ const byte_t* FillRandom(byte_t* buf, ui32_t len);
+ const byte_t* FillRandom(ByteString&);
+ };
+} // namespace Kumu
- // add UUID hyphens to 32 character hexadecimal string
- char* hyphenate_UUID(char* str_buf, ui32_t buf_len);
-} // namespace ASDCP
-#endif //_AS_DCP_UUID_H_
+#endif // _KM_PRNG_H_
//
-// end Timecode.h
+// end KM_prng.h
//
diff --git a/src/KM_util.cpp b/src/KM_util.cpp
new file mode 100755
index 0000000..c8cbb1c
--- /dev/null
+++ b/src/KM_util.cpp
@@ -0,0 +1,921 @@
+/*
+Copyright (c) 2005-2006, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+ /*! \file KM_util.cpp
+ \version $Id$
+ \brief Utility functions
+ */
+
+#include <KM_util.h>
+#include <KM_prng.h>
+#include <KM_memio.h>
+#include <KM_fileio.h>
+#include <KM_log.h>
+#include <ctype.h>
+#include <list>
+#include <string>
+
+//------------------------------------------------------------------------------------------
+
+
+const char fill = '=';
+const char* base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+const byte_t decode_map[] =
+{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 62, 0xff, 0xff, 0xff, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff,
+ 0xff, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+
+// Convert a binary string to NULL-terminated UTF-8 hexadecimal, returns the buffer
+// if the binary buffer was large enough to hold the result. If the output buffer
+// is too small or any of the pointer arguments are NULL, the subroutine will
+// return 0.
+//
+const char*
+Kumu::base64encode(const byte_t* buf, ui32_t buf_len, char* strbuf, ui32_t strbuf_len)
+{
+ ui32_t out_char = 0;
+ ui32_t i, block_len, diff;
+
+ if ( buf == 0 || strbuf == 0 )
+ return 0;
+
+ if ( strbuf_len < base64_encode_length(buf_len) + 1 )
+ return 0;
+
+ block_len = buf_len;
+
+ while ( block_len % 3 )
+ block_len--;
+
+ for ( i = 0; i < block_len; i += 3 )
+ {
+ strbuf[out_char++] = base64_chars[( buf[0] >> 2 )];
+ strbuf[out_char++] = base64_chars[( ( ( buf[0] & 0x03 ) << 4 ) | ( buf[1] >> 4 ) )];
+ strbuf[out_char++] = base64_chars[( ( ( buf[1] & 0x0f ) << 2 ) | ( buf[2] >> 6 ) )];
+ strbuf[out_char++] = base64_chars[( buf[2] & 0x3f )];
+ buf += 3;
+ }
+
+ if ( i < buf_len )
+ {
+ diff = buf_len - i;
+ assert(diff > 0);
+ assert(diff < 3);
+
+ strbuf[out_char++] = base64_chars[( buf[0] >> 2 )];
+
+ if ( diff == 1 )
+ {
+ strbuf[out_char++] = base64_chars[( ( ( buf[0] & 0x03 ) << 4 ) )];
+ strbuf[out_char++] = fill;
+ }
+ else if ( diff == 2 )
+ {
+ strbuf[out_char++] = base64_chars[( ( ( buf[0] & 0x03 ) << 4 ) | ( buf[1] >> 4 ) )];
+ strbuf[out_char++] = base64_chars[( ( ( buf[1] & 0x0f ) << 2 ) )];
+ }
+
+ strbuf[out_char++] = fill;
+ }
+
+ strbuf[out_char] = 0;
+ return strbuf;;
+}
+
+
+
+
+// Convert NULL-terminated UTF-8 Base64 string to binary, returns 0 if
+// the binary buffer was large enough to hold the result. The output parameter
+// 'char_count' will contain the length of the converted string. If the output
+// buffer is too small or any of the pointer arguments are NULL, the subroutine
+// will return -1 and set 'char_count' to the required buffer size. No data will
+// be written to 'buf' if the subroutine fails.
+//
+i32_t
+Kumu::base64decode(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* char_count)
+{
+ register byte_t c = 0, d = 0;
+ register ui32_t phase = 0, i = 0;
+
+ if ( str == 0 || buf == 0 || char_count == 0 )
+ return -1;
+
+ while ( *str != 0 && i < buf_len )
+ {
+ c = decode_map[(int)*str++];
+ if ( c == 0xff ) continue;
+ if ( c == 0xfe ) break;
+
+ switch ( phase++ )
+ {
+ case 0:
+ buf[i++] = c << 2;
+ break;
+
+ case 1:
+ buf[i - 1] |= c >> 4;
+ d = c;
+ break;
+
+ case 2:
+ buf[i++] = ( d << 4 ) | ( c >> 2 );
+ d = c;
+ break;
+
+ case 3:
+ buf[i++] = ( d << 6 ) | c;
+ phase = 0;
+ break;
+ }
+ }
+
+ *char_count = i;
+ return 0;
+}
+
+//------------------------------------------------------------------------------------------
+
+// convert utf-8 hext string to bin
+i32_t
+Kumu::hex2bin(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* conv_size)
+{
+ KM_TEST_NULL(str);
+ KM_TEST_NULL(buf);
+ KM_TEST_NULL(conv_size);
+
+ *conv_size = 0;
+
+ if ( str[0] == 0 ) // nothing to convert
+ return 0;
+
+ for ( int j = 0; str[j]; j++ )
+ {
+ if ( isxdigit(str[j]) )
+ (*conv_size)++;
+ }
+
+ if ( *conv_size & 0x01 ) (*conv_size)++;
+ *conv_size /= 2;
+
+ if ( *conv_size > buf_len )// maximum possible data size
+ return -1;
+
+ *conv_size = 0;
+
+ int phase = 0; // track high/low nybble
+
+ // for each character, fill in the high nybble then the low
+ for ( int i = 0; str[i]; i++ )
+ {
+ if ( ! isxdigit(str[i]) )
+ continue;
+
+ byte_t val = str[i] - ( isdigit(str[i]) ? 0x30 : ( isupper(str[i]) ? 0x37 : 0x57 ) );
+
+ if ( phase == 0 )
+ {
+ buf[*conv_size] = val << 4;
+ phase++;
+ }
+ else
+ {
+ buf[*conv_size] |= val;
+ phase = 0;
+ (*conv_size)++;
+ }
+ }
+
+ return 0;
+}
+
+
+// convert a memory region to a NULL-terminated hexadecimal string
+//
+const char*
+Kumu::bin2hex(const byte_t* bin_buf, ui32_t bin_len, char* str_buf, ui32_t str_len)
+{
+ if ( bin_buf == 0
+ || str_buf == 0
+ || ((bin_len * 2) + 1) > str_len )
+ return 0;
+
+ char* p = str_buf;
+
+ for ( ui32_t i = 0; i < bin_len; i++ )
+ {
+ *p = (bin_buf[i] >> 4) & 0x0f;
+ *p += *p < 10 ? 0x30 : 0x61 - 10;
+ p++;
+
+ *p = bin_buf[i] & 0x0f;
+ *p += *p < 10 ? 0x30 : 0x61 - 10;
+ p++;
+ }
+
+ *p = '\0';
+ return str_buf;
+}
+
+
+// spew a range of bin data as hex
+void
+Kumu::hexdump(const byte_t* buf, ui32_t dump_len, FILE* stream)
+{
+ if ( buf == 0 )
+ return;
+
+ if ( stream == 0 )
+ stream = stderr;
+
+ static ui32_t row_len = 16;
+ const byte_t* p = buf;
+ const byte_t* end_p = p + dump_len;
+
+ for ( ui32_t line = 0; p < end_p; line++ )
+ {
+ fprintf(stream, " %06x: ", line);
+ ui32_t i;
+ const byte_t* pp;
+
+ for ( pp = p, i = 0; i < row_len && pp < end_p; i++, pp++ )
+ fprintf(stream, "%02x ", *pp);
+
+ while ( i++ < row_len )
+ fputs(" ", stream);
+
+ for ( pp = p, i = 0; i < row_len && pp < end_p; i++, pp++ )
+ fputc((isprint(*pp) ? *pp : '.'), stream);
+
+ fputc('\n', stream);
+ p += row_len;
+ }
+}
+
+//
+const char*
+Kumu::bin2UUIDhex(const byte_t* bin_buf, ui32_t bin_len, char* str_buf, ui32_t str_len)
+{
+ ui32_t i, j, k;
+
+ if ( str_len < 34 || bin_len != UUID_Length )
+ return 0;
+
+ if ( bin2hex(bin_buf, bin_len, str_buf, str_len) == 0 )
+ return 0;
+
+ // shift the node id
+ for ( k = 19, i = 12; i > 0; i-- )
+ str_buf[k+i+4] = str_buf[k+i];
+
+ // shift the time (mid+hi+clk)
+ for ( k = 15, j = 3; k > 6; k -= 4, j-- )
+ {
+ for ( i = 4; i > 0; i-- )
+ str_buf[k+i+j] = str_buf[k+i];
+ }
+
+ // add in the hyphens and trainling null
+ for ( i = 8; i < 24; i += 5 )
+ str_buf[i] = '-';
+
+ str_buf[36] = 0;
+ return str_buf;
+}
+
+//
+void
+Kumu::GenRandomValue(UUID& ID)
+{
+ byte_t tmp_buf[UUID_Length];
+ GenRandomUUID(tmp_buf);
+ ID.Set(tmp_buf);
+}
+
+//
+void
+Kumu::GenRandomUUID(byte_t* buf)
+{
+ FortunaRNG RNG;
+ RNG.FillRandom(buf, UUID_Length);
+ buf[6] &= 0x0f; // clear bits 4-7
+ buf[6] |= 0x40; // set UUID version
+ buf[8] &= 0x3f; // clear bits 6&7
+ buf[8] |= 0x80; // set bit 7
+}
+
+//
+void
+Kumu::GenRandomValue(SymmetricKey& ID)
+{
+ byte_t tmp_buf[SymmetricKey_Length];
+ FortunaRNG RNG;
+ RNG.FillRandom(tmp_buf, SymmetricKey_Length);
+ ID.Set(tmp_buf);
+}
+
+
+//------------------------------------------------------------------------------------------
+// read a ber value from the buffer and compare with test value.
+// Advances buffer to first character after BER value.
+
+// read a ber value from the buffer and compare with test value.
+// Advances buffer to first character after BER value.
+//
+bool
+Kumu::read_test_BER(byte_t **buf, ui64_t test_value)
+{
+ if ( buf == 0 )
+ return false;
+
+ if ( ( **buf & 0x80 ) == 0 )
+ return false;
+
+ ui64_t val = 0;
+ ui8_t ber_size = ( **buf & 0x0f ) + 1;
+
+ if ( ber_size > 9 )
+ return false;
+
+ for ( ui8_t i = 1; i < ber_size; i++ )
+ {
+ if ( (*buf)[i] > 0 )
+ val |= (ui64_t)((*buf)[i]) << ( ( ( ber_size - 1 ) - i ) * 8 );
+ }
+
+ *buf += ber_size;
+ return ( val == test_value );
+}
+
+
+//
+bool
+Kumu::read_BER(const byte_t* buf, ui64_t* val)
+{
+ ui8_t ber_size, i;
+
+ if ( buf == 0 || val == 0 )
+ return false;
+
+ if ( ( *buf & 0x80 ) == 0 )
+ return false;
+
+ *val = 0;
+ ber_size = ( *buf & 0x0f ) + 1;
+
+ if ( ber_size > 9 )
+ return false;
+
+ for ( i = 1; i < ber_size; i++ )
+ {
+ if ( buf[i] > 0 )
+ *val |= (ui64_t)buf[i] << ( ( ( ber_size - 1 ) - i ) * 8 );
+ }
+
+ return true;
+}
+
+
+static const ui64_t ber_masks[9] =
+ { ui64_C(0xffffffffffffffff), ui64_C(0xffffffffffffff00),
+ ui64_C(0xffffffffffff0000), ui64_C(0xffffffffff000000),
+ ui64_C(0xffffffff00000000), ui64_C(0xffffff0000000000),
+ ui64_C(0xffff000000000000), ui64_C(0xff00000000000000),
+ 0
+ };
+
+
+//
+bool
+Kumu::write_BER(byte_t* buf, ui64_t val, ui32_t ber_len)
+{
+ if ( buf == 0 )
+ return false;
+
+ if ( ber_len == 0 )
+ { // calculate default length
+ if ( val < 0x01000000L )
+ ber_len = 4;
+ else if ( val < ui64_C(0x0100000000000000) )
+ ber_len = 8;
+ else
+ ber_len = 9;
+ }
+ else
+ { // sanity check BER length
+ if ( ber_len > 9 )
+ {
+ DefaultLogSink().Error("BER size %lu exceeds maximum size of 9\n", ber_len);
+ return false;
+ }
+
+ if ( val & ber_masks[ber_len - 1] )
+ {
+ ui64Printer tmp_i(val);
+ DefaultLogSink().Error("BER size %lu too small for value %s\n", tmp_i.c_str());
+ return false;
+ }
+ }
+
+ buf[0] = 0x80 + ( ber_len - 1 );
+
+ for ( ui32_t i = ber_len - 1; i > 0; i-- )
+ {
+ buf[i] = (ui8_t)(val & 0xff);
+ val >>= 8;
+ }
+
+ return true;
+}
+
+
+//------------------------------------------------------------------------------------------
+#ifdef KM_WIN32
+
+#define TIMESTAMP_TO_SYSTIME(ts, t) \
+ (t)->wYear = (ts).Year; /* year */ \
+ (t)->wMonth = (ts).Month; /* month of year (1 - 12) */ \
+ (t)->wDay = (ts).Day; /* day of month (1 - 31) */ \
+ (t)->wHour = (ts).Hour; /* hours (0 - 23) */ \
+ (t)->wMinute = (ts).Minute; /* minutes (0 - 59) */ \
+ (t)->wSecond = (ts).Second; /* seconds (0 - 60) */ \
+ (t)->wDayOfWeek = 0; \
+ (t)->wMilliseconds = 0
+
+#define SYSTIME_TO_TIMESTAMP(t, ts) \
+ (ts).Year = (t)->wYear; /* year */ \
+ (ts).Month = (t)->wMonth; /* month of year (1 - 12) */ \
+ (ts).Day = (t)->wDay; /* day of month (1 - 31) */ \
+ (ts).Hour = (t)->wHour; /* hours (0 - 23) */ \
+ (ts).Minute = (t)->wMinute; /* minutes (0 - 59) */ \
+ (ts).Second = (t)->wSecond; /* seconds (0 - 60) */
+
+//
+Kumu::Timestamp::Timestamp() :
+ Year(0), Month(0), Day(0), Hour(0), Minute(0), Second(0)
+{
+ SYSTEMTIME sys_time;
+ GetSystemTime(&sys_time);
+ SYSTIME_TO_TIMESTAMP(&sys_time, *this);
+}
+
+//
+bool
+Kumu::Timestamp::operator<(const Timestamp& rhs) const
+{
+ SYSTEMTIME lhst, rhst;
+ FILETIME lft, rft;
+
+ TIMESTAMP_TO_SYSTIME(*this, &lhst);
+ TIMESTAMP_TO_SYSTIME(rhs, &rhst);
+ SystemTimeToFileTime(&lhst, &lft);
+ SystemTimeToFileTime(&rhst, &rft);
+ return ( CompareFileTime(&lft, &rft) == -1 );
+}
+
+inline ui64_t
+seconds_to_ns100(ui32_t seconds)
+{
+ return ((ui64_t)seconds * 10000000);
+}
+
+//
+void
+Kumu::Timestamp::AddDays(i32_t days)
+{
+ SYSTEMTIME current_st;
+ FILETIME current_ft;
+ ULARGE_INTEGER current_ul;
+
+ if ( days != 0 )
+ {
+ TIMESTAMP_TO_SYSTIME(*this, &current_st);
+ SystemTimeToFileTime(&current_st, &current_ft);
+ memcpy(&current_ul, &current_ft, sizeof(current_ul));
+ current_ul.QuadPart += ( seconds_to_ns100(86400) * (ui64_t)days );
+ memcpy(&current_ft, &current_ul, sizeof(current_ft));
+ FileTimeToSystemTime(&current_ft, &current_st);
+ SYSTIME_TO_TIMESTAMP(&current_st, *this);
+ }
+}
+
+//
+void
+Kumu::Timestamp::AddHours(i32_t hours)
+{
+ SYSTEMTIME current_st;
+ FILETIME current_ft;
+ ULARGE_INTEGER current_ul;
+
+ if ( hours != 0 )
+ {
+ TIMESTAMP_TO_SYSTIME(*this, &current_st);
+ SystemTimeToFileTime(&current_st, &current_ft);
+ memcpy(&current_ul, &current_ft, sizeof(current_ul));
+ current_ul.QuadPart += ( seconds_to_ns100(3600) * (ui64_t)hours );
+ memcpy(&current_ft, &current_ul, sizeof(current_ft));
+ FileTimeToSystemTime(&current_ft, &current_st);
+ SYSTIME_TO_TIMESTAMP(&current_st, *this);
+ }
+}
+
+#else // KM_WIN32
+
+#include <time.h>
+
+#define TIMESTAMP_TO_TM(ts, t) \
+ (t)->tm_year = (ts).Year - 1900; /* year - 1900 */ \
+ (t)->tm_mon = (ts).Month - 1; /* month of year (0 - 11) */ \
+ (t)->tm_mday = (ts).Day; /* day of month (1 - 31) */ \
+ (t)->tm_hour = (ts).Hour; /* hours (0 - 23) */ \
+ (t)->tm_min = (ts).Minute; /* minutes (0 - 59) */ \
+ (t)->tm_sec = (ts).Second; /* seconds (0 - 60) */
+
+#define TM_TO_TIMESTAMP(t, ts) \
+ (ts).Year = (t)->tm_year + 1900; /* year - 1900 */ \
+ (ts).Month = (t)->tm_mon + 1; /* month of year (0 - 11) */ \
+ (ts).Day = (t)->tm_mday; /* day of month (1 - 31) */ \
+ (ts).Hour = (t)->tm_hour; /* hours (0 - 23) */ \
+ (ts).Minute = (t)->tm_min; /* minutes (0 - 59) */ \
+ (ts).Second = (t)->tm_sec; /* seconds (0 - 60) */
+
+//
+Kumu::Timestamp::Timestamp() :
+ Year(0), Month(0), Day(0), Hour(0), Minute(0), Second(0)
+{
+ time_t t_now = time(0);
+ struct tm* now = gmtime(&t_now);
+ TM_TO_TIMESTAMP(now, *this);
+}
+
+//
+bool
+Kumu::Timestamp::operator<(const Timestamp& rhs) const
+{
+ struct tm lhtm, rhtm;
+ TIMESTAMP_TO_TM(*this, &lhtm);
+ TIMESTAMP_TO_TM(rhs, &rhtm);
+ return ( timegm(&lhtm) < timegm(&rhtm) );
+}
+
+//
+void
+Kumu::Timestamp::AddDays(i32_t days)
+{
+ struct tm current;
+
+ if ( days != 0 )
+ {
+ TIMESTAMP_TO_TM(*this, &current);
+ time_t adj_time = timegm(&current);
+ adj_time += 86400 * days;
+ struct tm* now = gmtime(&adj_time);
+ TM_TO_TIMESTAMP(now, *this);
+ }
+}
+
+//
+void
+Kumu::Timestamp::AddHours(i32_t hours)
+{
+ struct tm current;
+
+ if ( hours != 0 )
+ {
+ TIMESTAMP_TO_TM(*this, &current);
+ time_t adj_time = timegm(&current);
+ adj_time += 3600 * hours;
+ struct tm* now = gmtime(&adj_time);
+ TM_TO_TIMESTAMP(now, *this);
+ }
+}
+
+#endif // KM_WIN32
+
+
+Kumu::Timestamp::Timestamp(const Timestamp& rhs)
+{
+ Year = rhs.Year;
+ Month = rhs.Month;
+ Day = rhs.Day;
+ Hour = rhs.Hour;
+ Minute = rhs.Minute;
+ Second = rhs.Second;
+}
+
+Kumu::Timestamp::~Timestamp()
+{
+}
+
+//
+const Kumu::Timestamp&
+Kumu::Timestamp::operator=(const Timestamp& rhs)
+{
+ Year = rhs.Year;
+ Month = rhs.Month;
+ Day = rhs.Day;
+ Hour = rhs.Hour;
+ Minute = rhs.Minute;
+ Second = rhs.Second;
+ return *this;
+}
+
+//
+bool
+Kumu::Timestamp::operator==(const Timestamp& rhs) const
+{
+ if ( Year == rhs.Year
+ && Month == rhs.Month
+ && Day == rhs.Day
+ && Hour == rhs.Hour
+ && Minute == rhs.Minute
+ && Second == rhs.Second )
+ return true;
+
+ return false;
+}
+
+//
+bool
+Kumu::Timestamp::operator!=(const Timestamp& rhs) const
+{
+ if ( Year != rhs.Year
+ || Month != rhs.Month
+ || Day != rhs.Day
+ || Hour != rhs.Hour
+ || Minute != rhs.Minute
+ || Second != rhs.Second )
+ return true;
+
+ return false;
+}
+
+//
+const char*
+Kumu::Timestamp::EncodeString(char* str_buf, ui32_t buf_len) const
+{
+ if ( buf_len < ( DateTimeLen + 1 ) )
+ return 0;
+
+ // 2004-05-01T13:20:00-00:00
+ snprintf(str_buf, buf_len,
+ "%04hu-%02hu-%02huT%02hu:%02hu:%02hu-00:00",
+ Year, Month, Day, Hour, Minute, Second);
+
+ return str_buf;
+}
+
+//
+bool
+Kumu::Timestamp::HasValue() const
+{
+ if ( Year || Month || Day || Hour || Minute || Second )
+ return true;
+
+ return false;
+}
+
+//
+bool
+Kumu::Timestamp::Unarchive(MemIOReader* Reader)
+{
+ assert(Reader);
+ if ( ! Reader->ReadUi16BE(&Year) ) return false;
+ if ( ! Reader->ReadRaw(&Month, 6) ) return false;
+ return true;
+}
+
+//
+bool
+Kumu::Timestamp::Archive(MemIOWriter* Writer) const
+{
+ assert(Writer);
+ if ( ! Writer->WriteUi16BE(Year) ) return false;
+ if ( ! Writer->WriteRaw(&Month, 6) ) return false;
+ return true;
+}
+
+#if 0
+//
+bool
+Kumu::UnarchiveString(MemIOReader* Reader, std::string&)
+{
+ assert(Reader);
+ ui32_t str_length;
+ if ( ! Reader->ReadUi32BE(&str_length) ) return false;
+ assign((const char*)Reader->CurrentData(), str_length);
+ if ( ! Reader->SkipOffset(str_length) ) return false;
+ return true;
+}
+
+//
+bool
+Kumu::String::Archive(MemIOWriter* Writer) const
+{
+ assert(Writer);
+ if ( ! Writer->WriteUi32BE(length()) ) return false;
+ if ( ! Writer->WriteRaw((const byte_t*)c_str(), length()) ) return false;
+
+ return true;
+}
+#endif
+
+//------------------------------------------------------------------------------------------
+
+Kumu::MemIOWriter::MemIOWriter(ByteString* Buf)
+ : m_p(0), m_capacity(0), m_size(0)
+{
+ m_p = Buf->Data();
+ m_capacity = Buf->Capacity();
+ assert(m_p); assert(m_capacity);
+}
+
+bool
+Kumu::MemIOWriter:: WriteBER(ui64_t i, ui32_t ber_len)
+{
+ if ( ( m_size + ber_len ) > m_capacity )
+ return false;
+
+ if ( ! write_BER(m_p + m_size, i, ber_len) )
+ return false;
+
+ m_size += ber_len;
+ return true;
+}
+
+
+Kumu::MemIOReader::MemIOReader(const ByteString* Buf)
+ : m_p(0), m_capacity(0), m_size(0)
+{
+ m_p = Buf->RoData();
+ m_capacity = Buf->Capacity();
+ assert(m_p); assert(m_capacity);
+}
+
+bool
+Kumu::MemIOReader::ReadBER(ui64_t* i, ui32_t* ber_len)
+{
+ if ( i == 0 || ber_len == 0 ) return false;
+
+ if ( ( *ber_len = BER_length(m_p + m_size) ) == 0 )
+ return false;
+
+ if ( ( m_size + *ber_len ) > m_capacity )
+ return false;
+
+ if ( ! read_BER(m_p + m_size, i) )
+ return false;
+
+ m_size += *ber_len;
+ return true;
+}
+
+//------------------------------------------------------------------------------------------
+
+Kumu::ByteString::ByteString() : m_Data(0), m_Capacity(0), m_Length(0) {}
+
+Kumu::ByteString::ByteString(ui32_t cap) : m_Data(0), m_Capacity(0), m_Length(0)
+{
+ Capacity(cap);
+}
+
+Kumu::ByteString::~ByteString()
+{
+ if ( m_Data != 0 )
+ free(m_Data);
+}
+
+
+// copy the given data into the ByteString, set Length value.
+// Returns error if the ByteString is too small.
+Kumu::Result_t
+Kumu::ByteString::Set(const byte_t* buf, ui32_t buf_len)
+{
+ if ( m_Capacity < buf_len )
+ return RESULT_ALLOC;
+
+ memcpy(m_Data, buf, buf_len);
+ m_Length = buf_len;
+ return RESULT_OK;
+}
+
+
+// Sets the size of the internally allocate buffer.
+// Resets content length to zero.
+Kumu::Result_t
+Kumu::ByteString::Capacity(ui32_t cap_size)
+{
+ if ( m_Capacity < cap_size )
+ {
+ if ( m_Data != 0 )
+ free(m_Data);
+
+ m_Data = (byte_t*)malloc(cap_size);
+
+ if ( m_Data == 0 )
+ return RESULT_ALLOC;
+
+ m_Capacity = cap_size;
+ m_Length = 0;
+ }
+
+ return RESULT_OK;
+}
+
+//
+Kumu::Result_t
+Kumu::ByteString::Append(const ByteString& Buf)
+{
+ Result_t result = RESULT_OK;
+ ui32_t diff = m_Capacity - m_Length;
+
+ if ( diff < Buf.Length() )
+ result = Capacity(m_Capacity + Buf.Length());
+
+ if ( KM_SUCCESS(result) )
+ {
+ memcpy(m_Data + m_Length, Buf.RoData(), Buf.Length());
+ m_Length += Buf.Length();
+ }
+
+ return result;
+}
+
+//
+Kumu::Result_t
+Kumu::ByteString::Append(const byte_t* buf, ui32_t buf_len)
+{
+ Result_t result = RESULT_OK;
+ ui32_t diff = m_Capacity - m_Length;
+
+ if ( diff < buf_len )
+ result = Capacity(m_Capacity + buf_len);
+
+ if ( KM_SUCCESS(result) )
+ {
+ memcpy(m_Data + m_Length, buf, buf_len);
+ m_Length += buf_len;
+ }
+
+ return result;
+}
+
+
+//
+// end KM_util.cpp
+//
diff --git a/src/KM_util.h b/src/KM_util.h
new file mode 100755
index 0000000..a27296b
--- /dev/null
+++ b/src/KM_util.h
@@ -0,0 +1,392 @@
+/*
+Copyright (c) 2005-2006, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+ /*! \file KM_util.h
+ \version $Id$
+ \brief Utility functions
+ */
+
+#ifndef _KM_UTIL_H_
+#define _KM_UTIL_H_
+
+#include <KM_memio.h>
+#include <KM_error.h>
+#include <string.h>
+#include <string>
+
+namespace Kumu
+{
+
+ template <class T, int SIZE = 16>
+ class IntPrinter : public std::string
+ {
+ protected:
+ IntPrinter();
+ char m_strbuf[SIZE];
+
+ public:
+ inline const char* c_str() { return m_strbuf; }
+
+ IntPrinter(const char* format, T value) {
+ snprintf(m_strbuf, SIZE, format, value);
+ }
+ };
+
+ struct i8Printer : public IntPrinter<i8_t> {
+ i8Printer(i8_t value) : IntPrinter<i8_t>("%hd", value) {}
+ };
+
+ struct ui8Printer : public IntPrinter<ui8_t> {
+ ui8Printer(ui8_t value) : IntPrinter<ui8_t>("%hu", value) {}
+ };
+
+ struct i16Printer : public IntPrinter<i16_t> {
+ i16Printer(i16_t value) : IntPrinter<i16_t>("%hd", value) {}
+ };
+
+ struct ui16Printer : public IntPrinter<ui16_t> {
+ ui16Printer(ui16_t value) : IntPrinter<ui16_t>("%hu", value) {}
+ };
+
+ struct i32Printer : public IntPrinter<i32_t> {
+ i32Printer(i32_t value) : IntPrinter<i32_t>("%d", value) {}
+ };
+
+ struct ui32Printer : public IntPrinter<ui32_t> {
+ ui32Printer(ui32_t value) : IntPrinter<ui32_t>("%u", value) {}
+ };
+
+#ifdef KM_WIN32
+ struct i64Printer : public IntPrinter<i64_t, 32> {
+ i64Printer(i64_t value) : IntPrinter<i64_t, 32>("%I64d", value) {}
+ };
+
+ struct ui64Printer : public IntPrinter<ui64_t, 32> {
+ ui64Printer(ui64_t value) : IntPrinter<ui64_t, 32>("%I64u", value) {}
+ };
+#else
+ struct i64Printer : public IntPrinter<i64_t, 32> {
+ i64Printer(i64_t value) : IntPrinter<i64_t, 32>("%qd", value) {}
+ };
+
+ struct ui64Printer : public IntPrinter<ui64_t, 32> {
+ ui64Printer(ui64_t value) : IntPrinter<ui64_t, 32>("%qu", value) {}
+ };
+#endif
+
+ // Convert NULL-terminated UTF-8 hexadecimal string to binary, returns 0 if
+ // the binary buffer was large enough to hold the result. The output parameter
+ // 'char_count' will contain the length of the converted string. If the output
+ // buffer is too small or any of the pointer arguments are NULL, the subroutine
+ // will return -1 and set 'char_count' to the required buffer size. No data will
+ // be written to 'buf' if the subroutine fails.
+ i32_t hex2bin(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* char_count);
+
+ // Convert a binary string to NULL-terminated UTF-8 hexadecimal, returns the buffer
+ // if the binary buffer was large enough to hold the result. If the output buffer
+ // is too small or any of the pointer arguments are NULL, the subroutine will
+ // return 0.
+ //
+ const char* bin2hex(const byte_t* bin_buf, ui32_t bin_len, char* str_buf, ui32_t str_len);
+
+ const char* bin2UUIDhex(const byte_t* bin_buf, ui32_t bin_len, char* str_buf, ui32_t str_len);
+
+ // same as above for base64 text
+ i32_t base64decode(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* char_count);
+ const char* base64encode(const byte_t* bin_buf, ui32_t bin_len, char* str_buf, ui32_t str_len);
+
+ // returns the length of a Base64 encoding of a buffer of the given length
+ inline ui32_t base64_encode_length(ui32_t length) {
+ while ( ( length % 3 ) != 0 )
+ length++;
+
+ return ( length / 3 ) * 4;
+ }
+
+ // print buffer contents to a stream as hexadecimal values in numbered
+ // rows of 16-bytes each.
+ //
+ void hexdump(const byte_t* buf, ui32_t dump_len, FILE* stream = 0);
+
+ // Return the length in bytes of a BER encoded value
+ inline ui32_t BER_length(const byte_t* buf)
+ {
+ if ( buf == 0 || (*buf & 0xf0) != 0x80 )
+ return 0;
+
+ return (*buf & 0x0f) + 1;
+ }
+
+ // read a BER value
+ bool read_BER(const byte_t* buf, ui64_t* val);
+
+ // decode a ber value and compare it to a test value
+ bool read_test_BER(byte_t **buf, ui64_t test_value);
+
+ // create BER encoding of integer value
+ bool write_BER(byte_t* buf, ui64_t val, ui32_t ber_len = 0);
+
+ //----------------------------------------------------------------
+ //
+
+ class IArchive
+ {
+ public:
+ virtual ~IArchive(){}
+ virtual bool HasValue() const = 0;
+ virtual bool Archive(MemIOWriter* Writer) const = 0;
+ virtual bool Unarchive(MemIOReader* Reader) = 0;
+ };
+
+
+ //
+ // the base of all identifier classes
+ template <ui32_t SIZE>
+ class Identifier : public IArchive
+ {
+ protected:
+ bool m_HasValue;
+ byte_t m_Value[SIZE];
+
+ public:
+ Identifier() : m_HasValue(false) { memset(m_Value, 0, SIZE); }
+ Identifier(const byte_t* value) : m_HasValue(true) { memcpy(m_Value, value, SIZE); }
+ Identifier(const Identifier& rhs) : m_HasValue(true) { memcpy(m_Value, rhs.m_Value, SIZE); }
+ virtual ~Identifier() {}
+
+ const Identifier& operator=(const Identifier& rhs) {
+ m_HasValue = true;
+ memcpy(m_Value, rhs.m_Value, SIZE);
+ return *this;
+ }
+
+ inline void Set(const byte_t* value) { m_HasValue = true; memcpy(m_Value, value, SIZE); }
+ inline const byte_t* Value() const { return m_Value; }
+ inline ui32_t Size() const { return SIZE; }
+
+ inline bool operator<(const Identifier& rhs) const
+ {
+ ui32_t test_size = xmin(rhs.Size(), SIZE);
+ for ( ui32_t i = 0; i < test_size; i++ )
+ {
+ if ( m_Value[i] != rhs.m_Value[i] )
+ return m_Value[i] < rhs.m_Value[i];
+ }
+
+ return false;
+ }
+
+ inline bool operator==(const Identifier& rhs) const
+ {
+ if ( rhs.Size() != SIZE ) return false;
+ return ( memcmp(m_Value, rhs.m_Value, SIZE) == 0 );
+ }
+
+ inline bool operator!=(const Identifier& rhs) const
+ {
+ if ( rhs.Size() != SIZE ) return true;
+ return ( memcmp(m_Value, rhs.m_Value, SIZE) != 0 );
+ }
+
+ inline bool DecodeHex(const char* str)
+ {
+ ui32_t char_count;
+ if ( hex2bin(str, m_Value, SIZE, &char_count) != 0 )
+ return false;
+
+ m_HasValue = true;
+ return true;
+ }
+
+ inline const char* EncodeHex(char* buf, ui32_t buf_len) const
+ {
+ return bin2hex(m_Value, SIZE, buf, buf_len);
+ }
+
+ inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+ return EncodeHex(str_buf, buf_len);
+ }
+
+ inline bool DecodeBase64(const char* str)
+ {
+ ui32_t char_count;
+ if ( base64decode(str, m_Value, SIZE, &char_count) != 0 )
+ return false;
+
+ m_HasValue = true;
+ return true;
+ }
+
+ inline const char* EncodeBase64(char* buf, ui32_t buf_len) const
+ {
+ return base64encode(m_Value, SIZE, buf, buf_len);
+ }
+
+ inline virtual bool HasValue() const { return m_HasValue; }
+
+ inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+ if ( ! Reader->ReadRaw(m_Value, SIZE) ) return false;
+ m_HasValue = true;
+ return true;
+ }
+
+ inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+ return Writer->WriteRaw(m_Value, SIZE);
+ }
+ };
+
+
+ // UUID
+ //
+ const ui32_t UUID_Length = 16;
+ class UUID : public Identifier<UUID_Length>
+ {
+ public:
+ UUID() {}
+ UUID(const byte_t* value) : Identifier<UUID_Length>(value) {}
+ UUID(const UUID& rhs) : Identifier<UUID_Length>(rhs) {}
+ virtual ~UUID() {}
+
+ inline const char* EncodeHex(char* buf, ui32_t buf_len) const {
+ return bin2UUIDhex(m_Value, Size(), buf, buf_len);
+ }
+ };
+
+ void GenRandomUUID(byte_t* buf);
+ void GenRandomValue(UUID&);
+
+ // a self-wiping key container
+ //
+ const ui32_t SymmetricKey_Length = 16;
+ const byte_t NilKey[SymmetricKey_Length] = {
+ 0xfa, 0xce, 0xfa, 0xce, 0xfa, 0xce, 0xfa, 0xce,
+ 0xfa, 0xce, 0xfa, 0xce, 0xfa, 0xce, 0xfa, 0xce
+ };
+
+ class SymmetricKey : public Identifier<SymmetricKey_Length>
+ {
+ public:
+ SymmetricKey() {}
+ SymmetricKey(const byte_t* value) : Identifier<SymmetricKey_Length>(value) {}
+ SymmetricKey(const UUID& rhs) : Identifier<SymmetricKey_Length>(rhs) {}
+ virtual ~SymmetricKey() { memcpy(m_Value, NilKey, 16); m_HasValue = false; }
+ };
+
+ void GenRandomValue(SymmetricKey&);
+
+ //
+ // 2004-05-01T13:20:00-00:00
+ const ui32_t DateTimeLen = 25; // the number of chars in the xs:dateTime format (sans milliseconds)
+
+ // UTC time+date representation
+ class Timestamp : public IArchive
+ {
+ public:
+ ui16_t Year;
+ ui8_t Month;
+ ui8_t Day;
+ ui8_t Hour;
+ ui8_t Minute;
+ ui8_t Second;
+
+ Timestamp();
+ Timestamp(const Timestamp& rhs);
+ Timestamp(const char* datestr);
+ virtual ~Timestamp();
+
+ const Timestamp& operator=(const Timestamp& rhs);
+ bool operator<(const Timestamp& rhs) const;
+ bool operator==(const Timestamp& rhs) const;
+ bool operator!=(const Timestamp& rhs) const;
+
+ // Write the timestamp value to the given buffer in the form 2004-05-01T13:20:00-00:00
+ // returns 0 if the buffer is smaller than DateTimeLen
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
+
+ // decode and set value from string formatted by EncodeString
+ Result_t SetFromString(const char* datestr);
+
+ // add the given number of days or hours to the timestamp value. Values less than zero
+ // will cause the value to decrease
+ void AddDays(i32_t);
+ void AddHours(i32_t);
+
+ // Read and write the timestamp value as a byte string
+ virtual bool HasValue() const;
+ virtual bool Archive(MemIOWriter* Writer) const;
+ virtual bool Unarchive(MemIOReader* Reader);
+ };
+
+ //
+ class ByteString
+ {
+ KM_NO_COPY_CONSTRUCT(ByteString);
+
+ protected:
+ byte_t* m_Data; // pointer to memory area containing frame data
+ ui32_t m_Capacity; // size of memory area pointed to by m_Data
+ ui32_t m_Length; // length of byte string in memory area pointed to by m_Data
+
+ public:
+ ByteString();
+ ByteString(ui32_t cap);
+ virtual ~ByteString();
+
+ // Sets the size of the internally allocated buffer.
+ // Resets content Size to zero.
+ Result_t Capacity(ui32_t cap);
+
+ Result_t Append(const ByteString&);
+ Result_t Append(const byte_t* buf, ui32_t buf_len);
+
+ // returns the size of the buffer
+ inline ui32_t Capacity() const { return m_Capacity; }
+
+ // returns a const pointer to the essence data
+ inline const byte_t* RoData() const { return m_Data; }
+
+ // returns a non-const pointer to the essence data
+ inline byte_t* Data() { return m_Data; }
+
+ // set the length of the buffer's contents
+ inline ui32_t Length(ui32_t l) { return m_Length = l; }
+
+ // returns the length of the buffer's contents
+ inline ui32_t Length() const { return m_Length; }
+
+ // copy the given data into the ByteString, set Length value.
+ // Returns error if the ByteString is too small.
+ Result_t Set(const byte_t* buf, ui32_t buf_len);
+ };
+
+} // namespace Kumu
+
+
+#endif // _KM_UTIL_H_
+
+//
+// end KM_util.h
+//
diff --git a/src/MPEG.cpp b/src/MPEG.cpp
index 0f60a8f..0c4e49c 100755
--- a/src/MPEG.cpp
+++ b/src/MPEG.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2005, John Hurst
+Copyright (c) 2005-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <MPEG.h>
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
// walk a buffer stopping at the end of the buffer or the end of a VES
// start code '00 00 01'. If successful, returns address of first byte
@@ -103,9 +105,9 @@ public:
h__StreamState() : m_State(ST_IDLE) {}
~h__StreamState() {}
- void Goto_START_HEADER() { m_State = ST_START_HEADER; }
- void Goto_IN_HEADER() { m_State = ST_IN_HEADER; }
- void Goto_IDLE() { m_State = ST_IDLE; }
+ void Goto_START_HEADER() { m_State = ST_START_HEADER; }
+ void Goto_IN_HEADER() { m_State = ST_IN_HEADER; }
+ void Goto_IDLE() { m_State = ST_IDLE; }
bool Test_IDLE() { return m_State == ST_IDLE; }
bool Test_START_HEADER() { return m_State == ST_START_HEADER; }
bool Test_IN_HEADER() { return m_State == ST_IN_HEADER; }
@@ -115,7 +117,7 @@ public:
ASDCP::MPEG2::VESParser::VESParser() :
- m_Delegate(0), m_HBufLen(0), m_ZeroCount(0), m_Partial(false)
+ m_Delegate(0), m_HBufLen(0), m_ZeroCount(0)
{
m_State = new h__StreamState;
}
@@ -139,7 +141,6 @@ ASDCP::MPEG2::VESParser::Reset()
m_State->Goto_IDLE();
m_HBufLen = 0;
m_ZeroCount = 0;
- m_Partial = false;
}
//
@@ -149,17 +150,18 @@ ASDCP::MPEG2::VESParser::Parse(const byte_t* buf, ui32_t buf_len)
ASDCP_TEST_NULL(buf);
ASDCP_TEST_NULL(m_Delegate);
- Result_t result;
- const byte_t* end_p = buf + buf_len;
- const byte_t* run_pos = buf; // track runs of uninteresting data as a position and count
- ui32_t run_len = 0;
+ Result_t result = RESULT_OK;
+ register const byte_t* end_p = buf + buf_len;
+ register const byte_t* run_pos = buf; // track runs of uninteresting data using a position and count
+ register ui32_t run_len = 0;
// search for MPEG2 headers
// copy interesting data to a buffer and pass to delegate for processing
- for ( const byte_t* p = buf; p < end_p; p++ )
+ for ( register const byte_t* p = buf; p < end_p; p++ )
{
if ( m_State->Test_IN_HEADER() )
{
+ assert(run_len==0);
m_HBuf[m_HBufLen++] = *p;
assert(m_HBufLen < VESHeaderBufSize);
}
@@ -170,8 +172,44 @@ ASDCP::MPEG2::VESParser::Parse(const byte_t* buf, ui32_t buf_len)
if ( m_State->Test_START_HEADER() ) // *p is a start code
{
- // Do we already have a header? We need to flush it...
- if ( m_HBufLen > 0)
+ if ( m_HBufLen == 0) // not already collecting a header
+ {
+ m_HBuf[0] = m_HBuf[1] = 0; m_HBuf[2] = 1; m_HBuf[3] = *p;
+
+ // is this one we want?
+ if ( *p == PIC_START || *p == SEQ_START || *p == EXT_START || *p == GOP_START )
+ {
+ m_HBufLen = 4;
+ m_State->Goto_IN_HEADER();
+
+ switch ( run_len )
+ {
+ case 1: // we suppressed writing 001 when exiting from the last call
+ case 4: // we have exactly 001x
+ break;
+ case 2: // we have 1x
+ case 3: // we have 01x
+ m_Delegate->Data(this, run_pos, (run_len == 2 ? -2 : -1));
+ break;
+
+ default:
+ m_Delegate->Data(this, run_pos, run_len - 4);
+ }
+
+ run_len = 0;
+ }
+ else
+ {
+ m_State->Goto_IDLE();
+
+ if ( run_len == 1 ) // did we suppress writing 001 when exiting from the last call?
+ {
+ m_Delegate->Data(this, m_HBuf, 4);
+ run_len = 0;
+ }
+ }
+ }
+ else // currently collecting a header, requires a flush before handling
{
m_HBufLen -= 3; // remove the current partial start code
@@ -189,48 +227,38 @@ ASDCP::MPEG2::VESParser::Parse(const byte_t* buf, ui32_t buf_len)
result = RESULT_RAW_FORMAT;
}
- // the next run starts with the start code that got us here
- run_len = 4;
- run_pos = p-3;
- m_HBufLen = 0;
-
// Parser handlers return RESULT_FALSE to teriminate without error
if ( result != RESULT_OK )
{
m_State->Goto_IDLE();
return result;
}
- }
-
- // all headers start with this same start code: 00 00 01 xx
- m_HBuf[0] = m_HBuf[1] = 0; m_HBuf[2] = 1; m_HBuf[3] = *p;
+
+ m_HBuf[0] = m_HBuf[1] = 0; m_HBuf[2] = 1; m_HBuf[3] = *p; // 001x
+ run_len = 0;
- // is this a header we want?
- if ( *p == PIC_START || *p == SEQ_START || *p == EXT_START || *p == GOP_START )
- {
- // we're starting a new header, flush the current run
- if ( run_len > 4 )
+ // is this a header we want?
+ if ( *p == PIC_START || *p == SEQ_START || *p == EXT_START || *p == GOP_START )
{
- m_Delegate->Data(this, run_pos, run_len - 4);
- run_len = 0;
+ m_HBufLen = 4;
+ m_State->Goto_IN_HEADER();
}
+ else
+ {
+ m_HBufLen = 0;
+ m_State->Goto_IDLE();
- m_Partial = false;
- m_HBufLen = 4;
- m_State->Goto_IN_HEADER();
- }
- else
- {
- if ( *p == FIRST_SLICE )
- result = m_Delegate->Slice(this);
+ if ( *p >= FIRST_SLICE && *p <= LAST_SLICE )
+ {
+ result = m_Delegate->Slice(this, *p);
- if ( m_Partial )
- {
- m_Partial = false;
- m_Delegate->Data(this, m_HBuf, 3);
+ if ( result != RESULT_OK )
+ return result;
+ }
+
+ m_Delegate->Data(this, m_HBuf, 4);
+ run_pos = p+1;
}
-
- m_State->Goto_IDLE();
}
}
else if ( *p == 0 )
@@ -248,9 +276,9 @@ ASDCP::MPEG2::VESParser::Parse(const byte_t* buf, ui32_t buf_len)
if ( run_len > 0 )
{
- if ( m_State->Test_START_HEADER() )
+ if ( m_State->Test_START_HEADER() && run_len != 0 )
{
- m_Partial = true; // 'partial' means we have a partial header in progress
+ assert(run_len > 2);
run_len -= 3;
}
diff --git a/src/MPEG.h b/src/MPEG.h
index c4de827..61cb1c3 100755
--- a/src/MPEG.h
+++ b/src/MPEG.h
@@ -29,10 +29,11 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\brief MPEG2 VES parser interface
*/
-#ifndef _ASDCP_MPEG_H_
-#define _ASDCP_MPEG_H_
+#ifndef _MPEG_H_
+#define _MPEG_H_
-#include <AS_DCP_system.h>
+#include <KM_platform.h>
+#include "AS_DCP.h"
#include <stdio.h>
#include <assert.h>
@@ -48,6 +49,7 @@ namespace ASDCP
EXT_START = 0xb5,
GOP_START = 0xb8,
FIRST_SLICE = 0x01,
+ LAST_SLICE = 0xaf,
INVALID = 0xff
};
@@ -90,7 +92,7 @@ namespace ASDCP
class VESParser
{
class h__StreamState;
- mem_ptr<h__StreamState> m_State;
+ Kumu::mem_ptr<h__StreamState> m_State;
VESParserDelegate* m_Delegate;
ui32_t m_HBufLen; // temp space for partial header contents
@@ -106,7 +108,7 @@ namespace ASDCP
void SetDelegate(VESParserDelegate*); // you must call this before Parse()
Result_t Parse(const byte_t*, ui32_t); // call repeatedly
- void Reset(); // resets the internal state machine and counters
+ void Reset(); // resets the internal state machine and counters, return to the top of the file
};
// Parser Event Delegate Interface
@@ -114,7 +116,7 @@ namespace ASDCP
// Create a concrete subclass and give it to the parser by calling SetDelegate().
// The respective method will be called when a header of the named type is found.
// Handler methods should return RESULT_OK to continue processing or RESULT_FALSE
- // to stop without error.
+ // to terminate parsing without signaling an error.
//
class VESParserDelegate
{
@@ -122,17 +124,20 @@ namespace ASDCP
virtual ~VESParserDelegate() {}
// header handlers
- virtual Result_t Picture(VESParser*, const byte_t*, ui32_t) = 0;
+ virtual Result_t Picture(VESParser* Caller, const byte_t* header_buf, ui32_t header_len) = 0;
virtual Result_t Extension(VESParser*, const byte_t*, ui32_t) = 0;
virtual Result_t Sequence(VESParser*, const byte_t*, ui32_t) = 0;
virtual Result_t GOP(VESParser*, const byte_t*, ui32_t) = 0;
// this is not a header handler, it is a signal that actual picture data
// has started. All Slice data is reported via the Data() method.
- virtual Result_t Slice(VESParser*) = 0;
+ virtual Result_t Slice(VESParser*, byte_t slice_id) = 0;
// Any data not given to the header handlers above is reported here
- virtual Result_t Data(VESParser*, const byte_t*, ui32_t) = 0;
+ // This method may be called with a value of -1 or -2. This will happen
+ // when processing a start code that has one or two leading zeros
+ // in the preceding buffer
+ virtual Result_t Data(VESParser*, const byte_t*, i32_t) = 0;
};
@@ -141,7 +146,9 @@ namespace ASDCP
//
// For use within parser delegate methods. The constructor expects a pointer to a buffer
// containing two zero bytes, a one byte, a start code and some number of header bytes.
- // They are not documented further as they should be self-explanatory.
+ // They are not documented further as it is hoped that they are self-explanatory.
+
+ //
namespace Accessor
{
// decoding tables
@@ -169,7 +176,7 @@ namespace ASDCP
};
//
- class SequenceEx
+ class SequenceEx // tension
{
const byte_t* m_p;
ASDCP_NO_COPY_CONSTRUCT(SequenceEx);
@@ -230,7 +237,7 @@ namespace ASDCP
} // namespace ASDCP
-#endif // ASDCP_MPEG_H_
+#endif // _MPEG_H_
//
// end MPEG.h
diff --git a/src/MPEG2_Parser.cpp b/src/MPEG2_Parser.cpp
index f6e0089..af7396f 100755
--- a/src/MPEG2_Parser.cpp
+++ b/src/MPEG2_Parser.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -29,14 +29,17 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\brief AS-DCP library, MPEG2 raw essence reader implementation
*/
-#include <FileIO.h>
+#include <KM_fileio.h>
#include <MPEG.h>
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
+
using namespace ASDCP;
using namespace ASDCP::MPEG2;
// data will be read from a VES file in chunks of this size
-const ui32_t VESReadSize = 4096;
+const ui32_t VESReadSize = 4 * Kumu::Kilobyte;
//------------------------------------------------------------------------------------------
@@ -59,11 +62,11 @@ class h__ParserState
ASDCP_NO_COPY_CONSTRUCT(h__ParserState);
public:
- h__ParserState() : m_State(::ST_INIT) {}
+ h__ParserState() : m_State(ST_INIT) {}
~h__ParserState() {}
- bool Test_SLICE() { return m_State == ST_SLICE; }
- void Reset() { m_State = ST_INIT; }
+ inline bool Test_SLICE() { return m_State == ST_SLICE; }
+ inline void Reset() { m_State = ST_INIT; }
//
inline Result_t Goto_SEQ()
@@ -75,6 +78,7 @@ class h__ParserState
return RESULT_OK;
}
+ DefaultLogSink().Error("SEQ follows 0x%02x\n", m_State);
return RESULT_STATE;
}
@@ -90,6 +94,7 @@ class h__ParserState
return RESULT_OK;
}
+ DefaultLogSink().Error("Slice follows 0x%02x\n", m_State);
return RESULT_STATE;
}
@@ -107,23 +112,25 @@ class h__ParserState
return RESULT_OK;
}
+ DefaultLogSink().Error("PIC follows 0x%02x\n", m_State);
return RESULT_STATE;
}
//
inline Result_t Goto_GOP()
- {
- switch ( m_State )
- {
- case ST_EXT:
- case ST_SEQ:
- m_State = ST_GOP;
- return RESULT_OK;
- }
-
- return RESULT_STATE;
- }
+ {
+ switch ( m_State )
+ {
+ case ST_EXT:
+ case ST_SEQ:
+ m_State = ST_GOP;
+ return RESULT_OK;
+ }
+
+ DefaultLogSink().Error("GOP follows 0x%02x\n", m_State);
+ return RESULT_STATE;
+ }
//
inline Result_t Goto_EXT()
@@ -138,6 +145,7 @@ class h__ParserState
return RESULT_OK;
}
+ DefaultLogSink().Error("EXT follows 0x%02x\n", m_State);
return RESULT_STATE;
}
};
@@ -216,8 +224,8 @@ public:
Result_t GOP(VESParser*, const byte_t*, ui32_t) { return RESULT_FALSE; }
Result_t Picture(VESParser*, const byte_t*, ui32_t) { return RESULT_FALSE; }
- Result_t Slice(VESParser*) { return RESULT_FALSE; }
- Result_t Data(VESParser*, const byte_t*, ui32_t) { return RESULT_OK; }
+ Result_t Slice(VESParser*, byte_t) { return RESULT_FALSE; }
+ Result_t Data(VESParser*, const byte_t*, i32_t) { return RESULT_OK; }
};
@@ -258,7 +266,7 @@ public:
m_PlaintextOffset = 0;
m_FrameType = FRAME_U;
m_State.Reset();
- }
+ }
Result_t Sequence(VESParser*, const byte_t* b, ui32_t s)
{
@@ -287,10 +295,15 @@ public:
return m_State.Goto_PIC();
}
- Result_t Slice(VESParser*)
+ Result_t Slice(VESParser*, byte_t slice_id)
{
- m_PlaintextOffset = m_FrameSize;
- return m_State.Goto_SLICE();
+ if ( slice_id == FIRST_SLICE )
+ {
+ m_PlaintextOffset = m_FrameSize;
+ return m_State.Goto_SLICE();
+ }
+
+ return m_State.Test_SLICE() ? RESULT_OK : RESULT_FAIL;
}
Result_t Extension(VESParser*, const byte_t* b, ui32_t s)
@@ -308,7 +321,7 @@ public:
return m_State.Goto_GOP();
}
- Result_t Data(VESParser*, const byte_t* b, ui32_t s)
+ Result_t Data(VESParser*, const byte_t* b, i32_t s)
{
m_FrameSize += s;
return RESULT_OK;
@@ -324,13 +337,12 @@ public:
// - any frame that begins with a picture header is either an I, B or P frame
// and is assumed to contain a complete picture header and picture data
-
class ASDCP::MPEG2::Parser::h__Parser
{
StreamParams m_ParamsDelegate;
FrameParser m_ParserDelegate;
VESParser m_Parser;
- FileReader m_FileReader;
+ Kumu::FileReader m_FileReader;
ui32_t m_FrameNumber;
bool m_EOF;
ASDCP::MPEG2::FrameBuffer m_TmpBuffer;
@@ -387,9 +399,9 @@ ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
// Since no one complained and that's the easiest thing to implement,
// I have left it that way. Let me know if you want to be able to
// locate the first GOP in the stream.
- if ( p[0] != 0 || p[1] != 0 || p[2] != 1 )
+ if ( p[0] != 0 || p[1] != 0 || p[2] != 1 || ! ( p[3] == SEQ_START || p[3] == PIC_START ) )
{
- DefaultLogSink().Error("Frame buffer does not begin with a start code.\n");
+ DefaultLogSink().Error("Frame buffer does not begin with a PIC or SEQ start code.\n");
return RESULT_RAW_FORMAT;
}
@@ -412,8 +424,8 @@ ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
m_FileReader.Close();
}
- return result;
-}
+ return result;}
+
//
//
@@ -434,6 +446,7 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
// the input file is exhausted. The partial next frame is cached for the
// next call.
m_ParserDelegate.Reset();
+ m_Parser.Reset();
if ( m_TmpBuffer.Size() > 0 )
{
@@ -443,7 +456,7 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
m_TmpBuffer.Size(0);
}
- while ( ! m_ParserDelegate.m_CompletePicture && ASDCP_SUCCESS(result) )
+ while ( ! m_ParserDelegate.m_CompletePicture && result == RESULT_OK )
{
if ( FB.Capacity() < ( write_offset + VESReadSize ) )
{
@@ -454,7 +467,7 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
result = m_FileReader.Read(FB.Data() + write_offset, VESReadSize, &read_count);
- if ( result == RESULT_ENDOFFILE )
+ if ( result == RESULT_ENDOFFILE || read_count == 0 )
{
m_EOF = true;
@@ -471,6 +484,7 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
if ( m_EOF )
break;
}
+ assert(m_ParserDelegate.m_FrameSize <= write_offset);
if ( ASDCP_SUCCESS(result)
&& m_ParserDelegate.m_FrameSize < write_offset )
@@ -478,21 +492,20 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
assert(m_TmpBuffer.Size() == 0);
ui32_t diff = write_offset - m_ParserDelegate.m_FrameSize;
assert(diff <= m_TmpBuffer.Capacity());
+
memcpy(m_TmpBuffer.Data(), FB.RoData() + m_ParserDelegate.m_FrameSize, diff);
m_TmpBuffer.Size(diff);
}
-#ifndef NDEBUG
if ( ASDCP_SUCCESS(result) )
{
const byte_t* p = FB.RoData();
- if ( p[0] != 0 || p[1] != 0 || p[2] != 1 )
- {
- DefaultLogSink().Error("Parsed frame buffer does not begin with a start code.\n");
- return RESULT_RAW_FORMAT;
- }
+ if ( p[0] != 0 || p[1] != 0 || p[2] != 1 || ! ( p[3] == SEQ_START || p[3] == PIC_START ) )
+ {
+ DefaultLogSink().Error("Frame buffer does not begin with a PIC or SEQ start code.\n");
+ return RESULT_RAW_FORMAT;
+ }
}
-#endif
if ( ASDCP_SUCCESS(result) )
{
@@ -573,5 +586,5 @@ ASDCP::MPEG2::Parser::FillVideoDescriptor(VideoDescriptor& VDesc) const
}
//
-// end AS_DCP_MPEG2_Parser.cpp
+// end MPEG2_Parser.cpp
//
diff --git a/src/MXF.cpp b/src/MXF.cpp
index ed16cab..ab30389 100755
--- a/src/MXF.cpp
+++ b/src/MXF.cpp
@@ -30,8 +30,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "MXF.h"
-#include "hex_utils.h"
-
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
//------------------------------------------------------------------------------------------
//
@@ -40,12 +40,12 @@ const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH;
//
ASDCP::Result_t
-ASDCP::MXF::SeekToRIP(const ASDCP::FileReader& Reader)
+ASDCP::MXF::SeekToRIP(const Kumu::FileReader& Reader)
{
- ASDCP::fpos_t end_pos;
+ Kumu::fpos_t end_pos;
// go to the end - 4 bytes
- Result_t result = Reader.Seek(0, ASDCP::SP_END);
+ Result_t result = Reader.Seek(0, Kumu::SP_END);
if ( ASDCP_SUCCESS(result) )
result = Reader.Tell(&end_pos);
@@ -72,7 +72,7 @@ ASDCP::MXF::SeekToRIP(const ASDCP::FileReader& Reader)
if ( ASDCP_SUCCESS(result) )
{
- rip_size = ASDCP_i32_BE(cp2i<ui32_t>(intbuf));
+ rip_size = KM_i32_BE(Kumu::cp2i<ui32_t>(intbuf));
if ( rip_size > end_pos ) // RIP can't be bigger than the file
return RESULT_FAIL;
@@ -87,14 +87,14 @@ ASDCP::MXF::SeekToRIP(const ASDCP::FileReader& Reader)
//
ASDCP::Result_t
-ASDCP::MXF::RIP::InitFromFile(const ASDCP::FileReader& Reader)
+ASDCP::MXF::RIP::InitFromFile(const Kumu::FileReader& Reader)
{
Result_t result = KLVFilePacket::InitFromFile(Reader, Dict::ul(MDD_RandomIndexMetadata));
if ( ASDCP_SUCCESS(result) )
{
- MemIOReader MemRDR(m_ValueStart, m_ValueLength - 4);
- result = PairArray.Unarchive(MemRDR);
+ Kumu::MemIOReader MemRDR(m_ValueStart, m_ValueLength - 4);
+ result = PairArray.Unarchive(&MemRDR) ? RESULT_OK : RESULT_KLV_CODING;
}
if ( ASDCP_FAILURE(result) )
@@ -105,7 +105,7 @@ ASDCP::MXF::RIP::InitFromFile(const ASDCP::FileReader& Reader)
//
ASDCP::Result_t
-ASDCP::MXF::RIP::WriteToFile(ASDCP::FileWriter& Writer)
+ASDCP::MXF::RIP::WriteToFile(Kumu::FileWriter& Writer)
{
ASDCP::FrameBuffer Buffer;
ui32_t RIPSize = ( PairArray.size() * (sizeof(ui32_t) + sizeof(ui64_t)) ) + 4;
@@ -116,14 +116,15 @@ ASDCP::MXF::RIP::WriteToFile(ASDCP::FileWriter& Writer)
if ( ASDCP_SUCCESS(result) )
{
- MemIOWriter MemWRT(Buffer.Data(), Buffer.Capacity());
- result = PairArray.Archive(MemWRT);
-
- if ( ASDCP_SUCCESS(result) )
- MemWRT.WriteUi32BE(RIPSize + 20);
+ result = RESULT_KLV_CODING;
- if ( ASDCP_SUCCESS(result) )
- Buffer.Size(MemWRT.Size());
+ Kumu::MemIOWriter MemWRT(Buffer.Data(), Buffer.Capacity());
+ if ( PairArray.Archive(&MemWRT) )
+ if ( MemWRT.WriteUi32BE(RIPSize + 20) )
+ {
+ Buffer.Size(MemWRT.Length());
+ result = RESULT_OK;
+ }
}
if ( ASDCP_SUCCESS(result) )
@@ -215,14 +216,14 @@ ASDCP::MXF::Partition::AddChildObject(InterchangeObject* Object)
{
assert(Object);
UUID TmpID;
- TmpID.GenRandomValue();
+ Kumu::GenRandomValue(TmpID);
Object->InstanceUID = TmpID;
m_PacketList->AddPacket(Object);
}
//
ASDCP::Result_t
-ASDCP::MXF::Partition::InitFromFile(const ASDCP::FileReader& Reader)
+ASDCP::MXF::Partition::InitFromFile(const Kumu::FileReader& Reader)
{
Result_t result = KLVFilePacket::InitFromFile(Reader);
// test the UL
@@ -230,20 +231,23 @@ ASDCP::MXF::Partition::InitFromFile(const ASDCP::FileReader& Reader)
if ( ASDCP_SUCCESS(result) )
{
- MemIOReader MemRDR(m_ValueStart, m_ValueLength);
- result = MemRDR.ReadUi16BE(&MajorVersion);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi16BE(&MinorVersion);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32BE(&KAGSize);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64BE(&ThisPartition);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64BE(&PreviousPartition);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64BE(&FooterPartition);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64BE(&HeaderByteCount);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64BE(&IndexByteCount);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32BE(&IndexSID);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64BE(&BodyOffset);
- if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32BE(&BodySID);
- if ( ASDCP_SUCCESS(result) ) result = OperationalPattern.Unarchive(MemRDR);
- if ( ASDCP_SUCCESS(result) ) result = EssenceContainers.Unarchive(MemRDR);
+ Kumu::MemIOReader MemRDR(m_ValueStart, m_ValueLength);
+ result = RESULT_KLV_CODING;
+
+ if ( MemRDR.ReadUi16BE(&MajorVersion) )
+ if ( MemRDR.ReadUi16BE(&MinorVersion) )
+ if ( MemRDR.ReadUi32BE(&KAGSize) )
+ if ( MemRDR.ReadUi64BE(&ThisPartition) )
+ if ( MemRDR.ReadUi64BE(&PreviousPartition) )
+ if ( MemRDR.ReadUi64BE(&FooterPartition) )
+ if ( MemRDR.ReadUi64BE(&HeaderByteCount) )
+ if ( MemRDR.ReadUi64BE(&IndexByteCount) )
+ if ( MemRDR.ReadUi32BE(&IndexSID) )
+ if ( MemRDR.ReadUi64BE(&BodyOffset) )
+ if ( MemRDR.ReadUi32BE(&BodySID) )
+ if ( OperationalPattern.Unarchive(&MemRDR) )
+ if ( EssenceContainers.Unarchive(&MemRDR) )
+ result = RESULT_OK;
}
if ( ASDCP_FAILURE(result) )
@@ -254,28 +258,32 @@ ASDCP::MXF::Partition::InitFromFile(const ASDCP::FileReader& Reader)
//
ASDCP::Result_t
-ASDCP::MXF::Partition::WriteToFile(ASDCP::FileWriter& Writer, UL& PartitionLabel)
+ASDCP::MXF::Partition::WriteToFile(Kumu::FileWriter& Writer, UL& PartitionLabel)
{
ASDCP::FrameBuffer Buffer;
Result_t result = Buffer.Capacity(1024);
if ( ASDCP_SUCCESS(result) )
{
- MemIOWriter MemWRT(Buffer.Data(), Buffer.Capacity());
- result = MemWRT.WriteUi16BE(MajorVersion);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi16BE(MinorVersion);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi32BE(KAGSize);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi64BE(ThisPartition);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi64BE(PreviousPartition);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi64BE(FooterPartition);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi64BE(HeaderByteCount);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi64BE(IndexByteCount);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi32BE(IndexSID);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi64BE(BodyOffset);
- if ( ASDCP_SUCCESS(result) ) result = MemWRT.WriteUi32BE(BodySID);
- if ( ASDCP_SUCCESS(result) ) result = OperationalPattern.Archive(MemWRT);
- if ( ASDCP_SUCCESS(result) ) result = EssenceContainers.Archive(MemWRT);
- if ( ASDCP_SUCCESS(result) ) Buffer.Size(MemWRT.Size());
+ Kumu::MemIOWriter MemWRT(Buffer.Data(), Buffer.Capacity());
+ result = RESULT_KLV_CODING;
+ if ( MemWRT.WriteUi16BE(MajorVersion) )
+ if ( MemWRT.WriteUi16BE(MinorVersion) )
+ if ( MemWRT.WriteUi32BE(KAGSize) )
+ if ( MemWRT.WriteUi64BE(ThisPartition) )
+ if ( MemWRT.WriteUi64BE(PreviousPartition) )
+ if ( MemWRT.WriteUi64BE(FooterPartition) )
+ if ( MemWRT.WriteUi64BE(HeaderByteCount) )
+ if ( MemWRT.WriteUi64BE(IndexByteCount) )
+ if ( MemWRT.WriteUi32BE(IndexSID) )
+ if ( MemWRT.WriteUi64BE(BodyOffset) )
+ if ( MemWRT.WriteUi32BE(BodySID) )
+ if ( OperationalPattern.Archive(&MemWRT) )
+ if ( EssenceContainers.Archive(&MemWRT) )
+ {
+ Buffer.Size(MemWRT.Length());
+ result = RESULT_OK;
+ }
}
if ( ASDCP_SUCCESS(result) )
@@ -310,7 +318,6 @@ void
ASDCP::MXF::Partition::Dump(FILE* stream)
{
char identbuf[IdentBufferLen];
- char intbuf[IntBufferLen];
if ( stream == 0 )
stream = stderr;
@@ -319,15 +326,15 @@ ASDCP::MXF::Partition::Dump(FILE* stream)
fprintf(stream, " MajorVersion = %hu\n", MajorVersion);
fprintf(stream, " MinorVersion = %hu\n", MinorVersion);
fprintf(stream, " KAGSize = %lu\n", KAGSize);
- fprintf(stream, " ThisPartition = %s\n", ui64sz(ThisPartition, intbuf));
- fprintf(stream, " PreviousPartition = %s\n", ui64sz(PreviousPartition, intbuf));
- fprintf(stream, " FooterPartition = %s\n", ui64sz(FooterPartition, intbuf));
- fprintf(stream, " HeaderByteCount = %s\n", ui64sz(HeaderByteCount, intbuf));
- fprintf(stream, " IndexByteCount = %s\n", ui64sz(IndexByteCount, intbuf));
+ fprintf(stream, " ThisPartition = %s\n", ui64sz(ThisPartition, identbuf));
+ fprintf(stream, " PreviousPartition = %s\n", ui64sz(PreviousPartition, identbuf));
+ fprintf(stream, " FooterPartition = %s\n", ui64sz(FooterPartition, identbuf));
+ fprintf(stream, " HeaderByteCount = %s\n", ui64sz(HeaderByteCount, identbuf));
+ fprintf(stream, " IndexByteCount = %s\n", ui64sz(IndexByteCount, identbuf));
fprintf(stream, " IndexSID = %lu\n", IndexSID);
- fprintf(stream, " BodyOffset = %s\n", ui64sz(BodyOffset, intbuf));
+ fprintf(stream, " BodyOffset = %s\n", ui64sz(BodyOffset, identbuf));
fprintf(stream, " BodySID = %lu\n", BodySID);
- fprintf(stream, " OperationalPattern = %s\n", OperationalPattern.ToString(identbuf));
+ fprintf(stream, " OperationalPattern = %s\n", OperationalPattern.EncodeString(identbuf, IdentBufferLen));
fputs("Essence Containers:\n", stream); EssenceContainers.Dump(stream, false);
fputs("==========================================================================\n", stream);
@@ -372,8 +379,8 @@ ASDCP::MXF::Primer::InitFromBuffer(const byte_t* p, ui32_t l)
if ( ASDCP_SUCCESS(result) )
{
- MemIOReader MemRDR(m_ValueStart, m_ValueLength);
- result = LocalTagEntryBatch.Unarchive(MemRDR);
+ Kumu::MemIOReader MemRDR(m_ValueStart, m_ValueLength);
+ result = LocalTagEntryBatch.Unarchive(&MemRDR) ? RESULT_OK : RESULT_KLV_CODING;
}
if ( ASDCP_SUCCESS(result) )
@@ -390,7 +397,7 @@ ASDCP::MXF::Primer::InitFromBuffer(const byte_t* p, ui32_t l)
//
ASDCP::Result_t
-ASDCP::MXF::Primer::WriteToFile(ASDCP::FileWriter& Writer)
+ASDCP::MXF::Primer::WriteToFile(Kumu::FileWriter& Writer)
{
ASDCP::FrameBuffer Buffer;
Result_t result = Buffer.Capacity(128*1024);
@@ -409,12 +416,12 @@ ASDCP::Result_t
ASDCP::MXF::Primer::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
{
ASDCP::FrameBuffer LocalTagBuffer;
- MemIOWriter MemWRT(Buffer.Data() + kl_length, Buffer.Capacity() - kl_length);
- Result_t result = LocalTagEntryBatch.Archive(MemWRT);
+ Kumu::MemIOWriter MemWRT(Buffer.Data() + kl_length, Buffer.Capacity() - kl_length);
+ Result_t result = LocalTagEntryBatch.Archive(&MemWRT) ? RESULT_OK : RESULT_KLV_CODING;
if ( ASDCP_SUCCESS(result) )
{
- ui32_t packet_length = MemWRT.Size();
+ ui32_t packet_length = MemWRT.Length();
result = WriteKLToBuffer(Buffer, Dict::ul(MDD_Primer), packet_length);
if ( ASDCP_SUCCESS(result) )
@@ -498,7 +505,7 @@ ASDCP::MXF::Primer::Dump(FILE* stream)
for ( ; i != LocalTagEntryBatch.end(); i++ )
{
const MDDEntry* Entry = Dict::FindUL((*i).UL.Value());
- fprintf(stream, " %s %s\n", (*i).ToString(identbuf), (Entry ? Entry->name : "Unknown"));
+ fprintf(stream, " %s %s\n", (*i).EncodeString(identbuf, IdentBufferLen), (Entry ? Entry->name : "Unknown"));
}
fputs("==========================================================================\n", stream);
@@ -568,13 +575,13 @@ ASDCP::MXF::Preface::Dump(FILE* stream)
stream = stderr;
InterchangeObject::Dump(stream);
- fprintf(stream, " %22s = %s\n", "LastModifiedDate", LastModifiedDate.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "LastModifiedDate", LastModifiedDate.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s = %hu\n", "Version", Version);
fprintf(stream, " %22s = %lu\n", "ObjectModelVersion", ObjectModelVersion);
- fprintf(stream, " %22s = %s\n", "PrimaryPackage", PrimaryPackage.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "PrimaryPackage", PrimaryPackage.EncodeHex(identbuf, IdentBufferLen));
fprintf(stream, " %22s:\n", "Identifications"); Identifications.Dump(stream);
- fprintf(stream, " %22s = %s\n", "ContentStorage", ContentStorage.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "OperationalPattern", OperationalPattern.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "ContentStorage", ContentStorage.EncodeHex(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "OperationalPattern", OperationalPattern.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s:\n", "EssenceContainers"); EssenceContainers.Dump(stream);
fprintf(stream, " %22s:\n", "DMSchemes"); DMSchemes.Dump(stream);
}
@@ -587,7 +594,7 @@ ASDCP::MXF::OPAtomHeader::~OPAtomHeader() {}
//
ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::InitFromFile(const ASDCP::FileReader& Reader)
+ASDCP::MXF::OPAtomHeader::InitFromFile(const Kumu::FileReader& Reader)
{
m_HasRIP = false;
Result_t result = SeekToRIP(Reader);
@@ -637,18 +644,16 @@ ASDCP::MXF::OPAtomHeader::InitFromFile(const ASDCP::FileReader& Reader)
if ( ASDCP_SUCCESS(result) )
result = Partition::InitFromFile(Reader); // test UL and OP
- Partition::Dump();
-
// is it really OP-Atom?
UL OPAtomUL(Dict::ul(MDD_OPAtom));
UL InteropOPAtomUL(Dict::ul(MDD_MXFInterop_OPAtom));
if ( ! ( OperationalPattern == OPAtomUL || OperationalPattern == InteropOPAtomUL ) )
{
- char strbuf[IntBufferLen];
+ char strbuf[IdentBufferLen];
const MDDEntry* Entry = Dict::FindUL(OperationalPattern.Value());
if ( Entry == 0 )
- DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", OperationalPattern.ToString(strbuf));
+ DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", OperationalPattern.EncodeString(strbuf, IdentBufferLen));
else
DefaultLogSink().Warn("Operational pattern is not OP-Atom: %s\n", Entry->name);
}
@@ -760,7 +765,7 @@ ASDCP::MXF::OPAtomHeader::GetSourcePackage()
//
ASDCP::Result_t
-ASDCP::MXF::OPAtomHeader::WriteToFile(ASDCP::FileWriter& Writer, ui32_t HeaderSize)
+ASDCP::MXF::OPAtomHeader::WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderSize)
{
if ( m_Preface == 0 )
return RESULT_STATE;
@@ -808,9 +813,9 @@ ASDCP::MXF::OPAtomHeader::WriteToFile(ASDCP::FileWriter& Writer, ui32_t HeaderSi
// KLV Fill
if ( ASDCP_SUCCESS(result) )
{
- ASDCP::fpos_t pos = Writer.Tell();
+ Kumu::fpos_t pos = Writer.Tell();
- if ( pos > (ASDCP::fpos_t)HeaderByteCount )
+ if ( pos > (Kumu::fpos_t)HeaderByteCount )
{
char intbuf[IntBufferLen];
DefaultLogSink().Error("Header size %s exceeds specified value %lu\n",
@@ -884,7 +889,7 @@ ASDCP::MXF::OPAtomIndexFooter::~OPAtomIndexFooter() {}
ASDCP::Result_t
-ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const ASDCP::FileReader& Reader)
+ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const Kumu::FileReader& Reader)
{
Result_t result = Partition::InitFromFile(Reader); // test UL and OP
@@ -936,7 +941,7 @@ ASDCP::MXF::OPAtomIndexFooter::InitFromFile(const ASDCP::FileReader& Reader)
//
ASDCP::Result_t
-ASDCP::MXF::OPAtomIndexFooter::WriteToFile(ASDCP::FileWriter& Writer, ui64_t duration)
+ASDCP::MXF::OPAtomIndexFooter::WriteToFile(Kumu::FileWriter& Writer, ui64_t duration)
{
ASDCP::FrameBuffer FooterBuffer;
ui32_t footer_size = m_PacketList->m_List.size() * MaxIndexSegmentSize; // segment-count * max-segment-size
@@ -1059,7 +1064,7 @@ ASDCP::MXF::OPAtomIndexFooter::SetIndexParamsCBR(IPrimerLookup* lookup, ui32_t s
//
void
-ASDCP::MXF::OPAtomIndexFooter::SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, fpos_t offset)
+ASDCP::MXF::OPAtomIndexFooter::SetIndexParamsVBR(IPrimerLookup* lookup, const Rational& Rate, Kumu::fpos_t offset)
{
assert(lookup);
m_Lookup = lookup;
@@ -1132,7 +1137,7 @@ ASDCP::Result_t
ASDCP::MXF::InterchangeObject::InitFromBuffer(const byte_t* p, ui32_t l)
{
ASDCP_TEST_NULL(p);
- Result_t result;
+ Result_t result = RESULT_FALSE;
if ( m_Typeinfo == 0 )
{
@@ -1164,7 +1169,7 @@ ASDCP::MXF::InterchangeObject::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
if ( ASDCP_SUCCESS(result) )
{
- ui32_t packet_length = MemWRT.Size();
+ ui32_t packet_length = MemWRT.Length();
result = WriteKLToBuffer(Buffer, m_Typeinfo->ul, packet_length);
if ( ASDCP_SUCCESS(result) )
@@ -1182,8 +1187,8 @@ ASDCP::MXF::InterchangeObject::Dump(FILE* stream)
fputc('\n', stream);
KLVPacket::Dump(stream, false);
- fprintf(stream, " InstanceUID = %s\n", InstanceUID.ToString(identbuf));
- fprintf(stream, " GenerationUID = %s\n", GenerationUID.ToString(identbuf));
+ fprintf(stream, " InstanceUID = %s\n", InstanceUID.EncodeHex(identbuf, IdentBufferLen));
+ fprintf(stream, " GenerationUID = %s\n", GenerationUID.EncodeHex(identbuf, IdentBufferLen));
}
//
diff --git a/src/MXF.h b/src/MXF.h
index 27f3b3e..da7b92f 100755
--- a/src/MXF.h
+++ b/src/MXF.h
@@ -41,7 +41,7 @@ namespace ASDCP
class InterchangeObject;
// seek an open file handle to the start of the RIP KLV packet
- Result_t SeekToRIP(const FileReader&);
+ Result_t SeekToRIP(const Kumu::FileReader&);
//
class RIP : public ASDCP::KLVFilePacket
@@ -50,7 +50,7 @@ namespace ASDCP
public:
//
- class Pair : public IArchive
+ class Pair : public Kumu::IArchive
{
public:
ui32_t BodySID;
@@ -58,33 +58,28 @@ namespace ASDCP
Pair() : BodySID(0), ByteOffset(0) {}
Pair(ui32_t sid, ui64_t offset) : BodySID(sid), ByteOffset(offset) {}
+ virtual ~Pair() {}
ui32_t Size() { return sizeof(ui32_t) + sizeof(ui64_t); }
- inline const char* ToString(char* str_buf) const {
- char intbuf[IntBufferLen];
- snprintf(str_buf, IdentBufferLen, "%-6lu: %s", BodySID, ui64sz(ByteOffset, intbuf));
+ inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+ Kumu::ui64Printer offset_str(ByteOffset);
+ snprintf(str_buf, buf_len, "%-6lu: %s", BodySID, offset_str.c_str());
return str_buf;
}
- inline Result_t Unarchive(ASDCP::MemIOReader& Reader) {
- Result_t result = Reader.ReadUi32BE(&BodySID);
-
- if ( ASDCP_SUCCESS(result) )
- result = Reader.ReadUi64BE(&ByteOffset);
-
- return result;
+ inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+ if ( ! Reader->ReadUi32BE(&BodySID) ) return false;
+ if ( ! Reader->ReadUi64BE(&ByteOffset) ) return false;
+ return true;
}
- inline bool HasValue() const { return true; }
+ inline virtual bool HasValue() const { return true; }
- inline Result_t Archive(ASDCP::MemIOWriter& Writer) const {
- Result_t result = Writer.WriteUi32BE(BodySID);
-
- if ( ASDCP_SUCCESS(result) )
- result = Writer.WriteUi64BE(ByteOffset);
-
- return result;
+ inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+ if ( ! Writer->WriteUi32BE(BodySID) ) return false;
+ if ( ! Writer->WriteUi64BE(ByteOffset) ) return false;
+ return true;
}
};
@@ -92,15 +87,15 @@ namespace ASDCP
RIP() {}
virtual ~RIP() {}
- virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
- virtual Result_t WriteToFile(ASDCP::FileWriter& Writer);
+ virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer);
virtual void Dump(FILE* = 0);
};
//
class Partition : public ASDCP::KLVFilePacket
- {
+ {
ASDCP_NO_COPY_CONSTRUCT(Partition);
protected:
@@ -125,8 +120,8 @@ namespace ASDCP
Partition();
virtual ~Partition();
virtual void AddChildObject(InterchangeObject*);
- virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
- virtual Result_t WriteToFile(ASDCP::FileWriter& Writer, UL& PartitionLabel);
+ virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer, UL& PartitionLabel);
virtual ui32_t ArchiveSize(); // returns the size of the archived structure
virtual void Dump(FILE* = 0);
};
@@ -148,24 +143,22 @@ namespace ASDCP
TagValue Tag;
ASDCP::UL UL;
- inline const char* ToString(char* str_buf) const {
- snprintf(str_buf, IdentBufferLen, "%02x %02x: ", Tag.a, Tag.b);
- UL.ToString(str_buf + strlen(str_buf));
+ inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+ snprintf(str_buf, buf_len, "%02x %02x: ", Tag.a, Tag.b);
+ UL.EncodeString(str_buf + strlen(str_buf), buf_len - strlen(str_buf));
return str_buf;
}
- inline Result_t Unarchive(ASDCP::MemIOReader& Reader) {
- Result_t result = Reader.ReadUi8(&Tag.a);
- if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8(&Tag.b);
- if ( ASDCP_SUCCESS(result) ) result = UL.Unarchive(Reader);
- return result;
+ inline bool Unarchive(Kumu::MemIOReader* Reader) {
+ if ( ! Reader->ReadUi8(&Tag.a) ) return false;
+ if ( ! Reader->ReadUi8(&Tag.b) ) return false;
+ return UL.Unarchive(Reader);
}
- inline Result_t Archive(ASDCP::MemIOWriter& Writer) const {
- Result_t result = Writer.WriteUi8(Tag.a);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8(Tag.b);
- if ( ASDCP_SUCCESS(result) ) result = UL.Archive(Writer);
- return result;
+ inline bool Archive(Kumu::MemIOWriter* Writer) const {
+ if ( ! Writer->WriteUi8(Tag.a) ) return false;
+ if ( ! Writer->WriteUi8(Tag.b) ) return false;
+ return UL.Archive(Writer);
}
};
@@ -180,7 +173,7 @@ namespace ASDCP
virtual Result_t InitFromBuffer(const byte_t* p, ui32_t l);
virtual Result_t WriteToBuffer(ASDCP::FrameBuffer&);
- virtual Result_t WriteToFile(ASDCP::FileWriter& Writer);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer);
virtual void Dump(FILE* = 0);
};
@@ -253,9 +246,9 @@ namespace ASDCP
ui32_t ElementData;
DeltaEntry() : PosTableIndex(-1), Slice(0), ElementData(0) {}
- Result_t Unarchive(ASDCP::MemIOReader& Reader);
- Result_t Archive(ASDCP::MemIOWriter& Writer) const;
- const char* ToString(char* str_buf) const;
+ bool Unarchive(Kumu::MemIOReader* Reader);
+ bool Archive(Kumu::MemIOWriter* Writer) const;
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
};
//
@@ -270,9 +263,9 @@ namespace ASDCP
// Array<Rational> PosTable;
IndexEntry() : TemporalOffset(0), KeyFrameOffset(0), Flags(0), StreamOffset() {}
- Result_t Unarchive(ASDCP::MemIOReader& Reader);
- Result_t Archive(ASDCP::MemIOWriter& Writer) const;
- const char* ToString(char* str_buf) const;
+ bool Unarchive(Kumu::MemIOReader* Reader);
+ bool Archive(Kumu::MemIOWriter* Writer) const;
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
};
Rational IndexEditRate;
@@ -315,8 +308,8 @@ namespace ASDCP
OPAtomHeader();
virtual ~OPAtomHeader();
- virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
- virtual Result_t WriteToFile(ASDCP::FileWriter& Writer, ui32_t HeaderLength = 16384);
+ virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui32_t HeaderLength = 16384);
virtual void Dump(FILE* = 0);
virtual Result_t GetMDObjectByType(const byte_t*, InterchangeObject** = 0);
Identification* GetIdentification();
@@ -339,8 +332,8 @@ namespace ASDCP
OPAtomIndexFooter();
virtual ~OPAtomIndexFooter();
- virtual Result_t InitFromFile(const ASDCP::FileReader& Reader);
- virtual Result_t WriteToFile(ASDCP::FileWriter& Writer, ui64_t duration);
+ virtual Result_t InitFromFile(const Kumu::FileReader& Reader);
+ virtual Result_t WriteToFile(Kumu::FileWriter& Writer, ui64_t duration);
virtual void Dump(FILE* = 0);
virtual Result_t Lookup(ui32_t frame_num, IndexTableSegment::IndexEntry&);
diff --git a/src/MXFTypes.cpp b/src/MXFTypes.cpp
index 111d493..c2352fd 100755
--- a/src/MXFTypes.cpp
+++ b/src/MXFTypes.cpp
@@ -29,19 +29,51 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\brief MXF objects
*/
+#include <KM_prng.h>
#include "MXFTypes.h"
-#include "FortunaRNG.h"
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
//------------------------------------------------------------------------------------------
//
+const char*
+ASDCP::UL::EncodeString(char* str_buf, ui32_t buf_len) const
+{
+ if ( buf_len > 38 ) // room for dotted notation?
+ {
+ snprintf(str_buf, buf_len,
+ "%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x",
+ m_Value[0], m_Value[1], m_Value[2], m_Value[3],
+ m_Value[4], m_Value[5], m_Value[6], m_Value[7],
+ m_Value[8], m_Value[9], m_Value[10], m_Value[11],
+ m_Value[12], m_Value[13], m_Value[14], m_Value[15]
+ );
+
+ return str_buf;
+ }
+ else if ( buf_len > 32 ) // room for compact?
+ {
+ snprintf(str_buf, buf_len,
+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ m_Value[0], m_Value[1], m_Value[2], m_Value[3],
+ m_Value[4], m_Value[5], m_Value[6], m_Value[7],
+ m_Value[8], m_Value[9], m_Value[10], m_Value[11],
+ m_Value[12], m_Value[13], m_Value[14], m_Value[15]
+ );
+
+ return str_buf;
+ }
+
+ return 0;
+}
//
void
ASDCP::UMID::MakeUMID(int Type)
{
UUID AssetID;
- AssetID.GenRandomValue();
+ Kumu::GenRandomValue(AssetID);
MakeUMID(Type, AssetID);
}
@@ -69,11 +101,11 @@ ASDCP::UMID::MakeUMID(int Type, const UUID& AssetID)
// Write the timestamp value to the given buffer in the form 2004-05-01 13:20:00.000
// returns 0 if the buffer is smaller than DateTimeLen
const char*
-ASDCP::UMID::ToString(char* str_buf) const
+ASDCP::UMID::EncodeString(char* str_buf, ui32_t buf_len) const
{
assert(str_buf);
- snprintf(str_buf, IdentBufferLen, "[%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x],%02x,%02x,%02x,%02x,",
+ snprintf(str_buf, buf_len, "[%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x],%02x,%02x,%02x,%02x,",
m_Value[0], m_Value[1], m_Value[2], m_Value[3],
m_Value[4], m_Value[5], m_Value[6], m_Value[7],
m_Value[8], m_Value[9], m_Value[10], m_Value[11],
@@ -85,7 +117,7 @@ ASDCP::UMID::ToString(char* str_buf) const
if ( ( m_Value[8] & 0x80 ) == 0 )
{
// half-swapped UL, use [bbaa9988.ddcc.ffee.00010203.04050607]
- snprintf(str_buf + offset, IdentBufferLen - offset,
+ snprintf(str_buf + offset, buf_len - offset,
"[%02x%02x%02x%02x.%02x%02x.%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x]",
m_Value[24], m_Value[25], m_Value[26], m_Value[27],
m_Value[28], m_Value[29], m_Value[30], m_Value[31],
@@ -96,7 +128,7 @@ ASDCP::UMID::ToString(char* str_buf) const
else
{
// UUID, use {00112233-4455-6677-8899-aabbccddeeff}
- snprintf(str_buf + offset, IdentBufferLen - offset,
+ snprintf(str_buf + offset, buf_len - offset,
"{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
m_Value[16], m_Value[17], m_Value[18], m_Value[19],
m_Value[20], m_Value[21], m_Value[22], m_Value[23],
@@ -108,20 +140,6 @@ ASDCP::UMID::ToString(char* str_buf) const
return str_buf;
}
-//
-void
-ASDCP::UUID::GenRandomValue()
-{
- FortunaRNG RNG;
- RNG.FillRandom(m_Value, UUIDlen);
- m_Value[6] &= 0x0f; // clear bits 4-7
- m_Value[6] |= 0x40; // set UUID version
- m_Value[8] &= 0x3f; // clear bits 6&7
- m_Value[8] |= 0x80; // set bit 7
- m_HasValue = true;
-}
-
-
//------------------------------------------------------------------------------------------
//
@@ -135,7 +153,7 @@ ASDCP::MXF::UTF16String::operator=(const char* sz)
}
else
{
- ui32_t len = xmin((ui32_t)strlen(sz), (IdentBufferLen - 1));
+ ui32_t len = Kumu::xmin((ui32_t)strlen(sz), (IdentBufferLen - 1));
m_length = len;
memcpy(m_buffer, sz, m_length);
m_buffer[m_length] = 0;
@@ -146,11 +164,11 @@ ASDCP::MXF::UTF16String::operator=(const char* sz)
//
-ASDCP::Result_t
-ASDCP::MXF::UTF16String::Unarchive(ASDCP::MemIOReader& Reader)
+bool
+ASDCP::MXF::UTF16String::Unarchive(Kumu::MemIOReader* Reader)
{
- const byte_t* p = Reader.CurrentData();
- m_length = Reader.Remainder();
+ const byte_t* p = Reader->CurrentData();
+ m_length = Reader->Remainder();
assert(m_length % 2 == 0);
m_length /= 2;
assert(IdentBufferLen >= m_length);
@@ -161,23 +179,23 @@ ASDCP::MXF::UTF16String::Unarchive(ASDCP::MemIOReader& Reader)
m_buffer[i] = 0;
- Reader.SkipOffset(m_length*2);
- return RESULT_OK;
+ Reader->SkipOffset(m_length*2);
+ return true;
}
//
-ASDCP::Result_t
-ASDCP::MXF::UTF16String::Archive(ASDCP::MemIOWriter& Writer) const
+bool
+ASDCP::MXF::UTF16String::Archive(Kumu::MemIOWriter* Writer) const
{
- byte_t* p = Writer.Data() + Writer.Size();
+ byte_t* p = Writer->Data() + Writer->Length();
ui32_t i = 0;
memset(p, 0, (m_length*2)+2);
for ( i = 0; i < m_length; i++ )
p[(i*2)+1] = m_buffer[i];
- Writer.AddOffset(m_length * 2);
- return RESULT_OK;
+ Writer->AddOffset(m_length * 2);
+ return true;
}
@@ -274,7 +292,7 @@ ASDCP::MXF::Timestamp::AddHours(i32_t hours)
}
}
-#else // WM_WIN32
+#else // KM_WIN32
#include <time.h>
@@ -345,7 +363,7 @@ ASDCP::MXF::Timestamp::AddHours(i32_t hours)
}
}
-#endif // WM_WIN32
+#endif // KM_WIN32
ASDCP::MXF::Timestamp::Timestamp(const Timestamp& rhs)
@@ -407,11 +425,11 @@ ASDCP::MXF::Timestamp::operator!=(const Timestamp& rhs) const
//
const char*
-ASDCP::MXF::Timestamp::ToString(char* str_buf) const
+ASDCP::MXF::Timestamp::EncodeString(char* str_buf, ui32_t buf_len) const
{
// 2004-05-01 13:20:00.000
- snprintf(str_buf, IntBufferLen,
- "%04hu-%02hu-%02hu %02hu:%02hu:%02hu.000",
+ snprintf(str_buf, buf_len,
+ "%04hu-%02hu-%02hu %02hu:%02hu:%02hu.000",
Year, Month, Day, Hour, Minute, Second, Tick);
return str_buf;
@@ -430,26 +448,18 @@ ASDCP::MXF::TLVReader::TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* Prime
TagValue Tag;
ui16_t pkt_len = 0;
- result = MemIOReader::ReadUi8(&Tag.a);
-
- if ( ASDCP_SUCCESS(result) )
- result = MemIOReader::ReadUi8(&Tag.b);
-
- if ( ASDCP_SUCCESS(result) )
- result = MemIOReader::ReadUi16BE(&pkt_len);
-
- if ( ASDCP_SUCCESS(result) )
- {
- m_ElementMap.insert(TagMap::value_type(Tag, ItemInfo(m_size, pkt_len)));
- result = SkipOffset(pkt_len);
- }
-
- if ( ASDCP_FAILURE(result) )
- {
- DefaultLogSink().Error("Malformed Set\n");
- m_ElementMap.clear();
- break;
- }
+ if ( MemIOReader::ReadUi8(&Tag.a) )
+ if ( MemIOReader::ReadUi8(&Tag.b) )
+ if ( MemIOReader::ReadUi16BE(&pkt_len) )
+ {
+ m_ElementMap.insert(TagMap::value_type(Tag, ItemInfo(m_size, pkt_len)));
+ if ( SkipOffset(pkt_len) )
+ continue;;
+ }
+
+ DefaultLogSink().Error("Malformed Set\n");
+ m_ElementMap.clear();
+ result = RESULT_KLV_CODING;
}
}
@@ -469,8 +479,8 @@ ASDCP::MXF::TLVReader::FindTL(const MDDEntry& Entry)
{
if ( Entry.tag.a == 0 )
{
- DefaultLogSink().Info("No such UL in this TL list: %s (%02x %02x)\n",
- Entry.name, Entry.tag.a, Entry.tag.b);
+ // DefaultLogSink().Debug("No such UL in this TL list: %s (%02x %02x)\n",
+ // Entry.name, Entry.tag.a, Entry.tag.b);
return false;
}
@@ -486,20 +496,20 @@ ASDCP::MXF::TLVReader::FindTL(const MDDEntry& Entry)
return true;
}
- DefaultLogSink().Info("Not Found (%02x %02x): %s\n", TmpTag.a, TmpTag.b, Entry.name);
+ // DefaultLogSink().Debug("Not Found (%02x %02x): %s\n", TmpTag.a, TmpTag.b, Entry.name);
return false;
}
//
ASDCP::Result_t
-ASDCP::MXF::TLVReader::ReadObject(const MDDEntry& Entry, IArchive* Object)
+ASDCP::MXF::TLVReader::ReadObject(const MDDEntry& Entry, Kumu::IArchive* Object)
{
ASDCP_TEST_NULL(Object);
if ( FindTL(Entry) )
{
if ( m_size < m_capacity ) // don't try to unarchive an empty item
- return Object->Unarchive(*this);
+ return Object->Unarchive(this) ? RESULT_OK : RESULT_KLV_CODING;
}
return RESULT_FALSE;
@@ -512,7 +522,7 @@ ASDCP::MXF::TLVReader::ReadUi8(const MDDEntry& Entry, ui8_t* value)
ASDCP_TEST_NULL(value);
if ( FindTL(Entry) )
- return MemIOReader::ReadUi8(value);
+ return MemIOReader::ReadUi8(value) ? RESULT_OK : RESULT_KLV_CODING;
return RESULT_FALSE;
}
@@ -524,7 +534,7 @@ ASDCP::MXF::TLVReader::ReadUi16(const MDDEntry& Entry, ui16_t* value)
ASDCP_TEST_NULL(value);
if ( FindTL(Entry) )
- return MemIOReader::ReadUi16BE(value);
+ return MemIOReader::ReadUi16BE(value) ? RESULT_OK : RESULT_KLV_CODING;
return RESULT_FALSE;
}
@@ -536,7 +546,7 @@ ASDCP::MXF::TLVReader::ReadUi32(const MDDEntry& Entry, ui32_t* value)
ASDCP_TEST_NULL(value);
if ( FindTL(Entry) )
- return MemIOReader::ReadUi32BE(value);
+ return MemIOReader::ReadUi32BE(value) ? RESULT_OK : RESULT_KLV_CODING;
return RESULT_FALSE;
}
@@ -548,7 +558,7 @@ ASDCP::MXF::TLVReader::ReadUi64(const MDDEntry& Entry, ui64_t* value)
ASDCP_TEST_NULL(value);
if ( FindTL(Entry) )
- return MemIOReader::ReadUi64BE(value);
+ return MemIOReader::ReadUi64BE(value) ? RESULT_OK : RESULT_KLV_CODING;
return RESULT_FALSE;
}
@@ -580,15 +590,14 @@ ASDCP::MXF::TLVWriter::WriteTag(const MDDEntry& Entry)
return RESULT_FAIL;
}
- Result_t result = MemIOWriter::WriteUi8(TmpTag.a);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(TmpTag.b);
-
- return result;
+ if ( ! MemIOWriter::WriteUi8(TmpTag.a) ) return RESULT_KLV_CODING;
+ if ( ! MemIOWriter::WriteUi8(TmpTag.b) ) return RESULT_KLV_CODING;
+ return RESULT_OK;
}
//
ASDCP::Result_t
-ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, IArchive* Object)
+ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, Kumu::IArchive* Object)
{
ASDCP_TEST_NULL(Object);
@@ -600,19 +609,12 @@ ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, IArchive* Object)
// write a temp length
byte_t* l_p = CurrentData();
- if ( ASDCP_SUCCESS(result) )
- MemIOWriter::WriteUi16BE(0);
+ if ( ! MemIOWriter::WriteUi16BE(0) ) return RESULT_KLV_CODING;
- if ( ASDCP_SUCCESS(result) )
- {
- ui32_t before = Size();
- result = Object->Archive(*this);
-
- if ( ASDCP_SUCCESS(result) )
- i2p<ui16_t>(ASDCP_i16_BE( Size() - before), l_p);
- }
-
- return result;
+ ui32_t before = Length();
+ if ( ! Object->Archive(this) ) return RESULT_KLV_CODING;
+ Kumu::i2p<ui16_t>(KM_i16_BE( Length() - before), l_p);
+ return RESULT_OK;
}
//
@@ -621,8 +623,13 @@ ASDCP::MXF::TLVWriter::WriteUi8(const MDDEntry& Entry, ui8_t* value)
{
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui8_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ if ( ! MemIOWriter::WriteUi16BE(sizeof(ui8_t)) ) return RESULT_KLV_CODING;
+ if ( ! MemIOWriter::WriteUi8(*value) ) return RESULT_KLV_CODING;
+ }
+
return result;
}
@@ -632,8 +639,13 @@ ASDCP::MXF::TLVWriter::WriteUi16(const MDDEntry& Entry, ui16_t* value)
{
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui16_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(*value);
+
+ if ( KM_SUCCESS(result) )
+ {
+ if ( ! MemIOWriter::WriteUi16BE(sizeof(ui16_t)) ) return RESULT_KLV_CODING;
+ if ( ! MemIOWriter::WriteUi16BE(*value) ) return RESULT_KLV_CODING;
+ }
+
return result;
}
@@ -643,8 +655,13 @@ ASDCP::MXF::TLVWriter::WriteUi32(const MDDEntry& Entry, ui32_t* value)
{
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui32_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi32BE(*value);
+
+ if ( KM_SUCCESS(result) )
+ {
+ if ( ! MemIOWriter::WriteUi16BE(sizeof(ui32_t)) ) return RESULT_KLV_CODING;
+ if ( ! MemIOWriter::WriteUi32BE(*value) ) return RESULT_KLV_CODING;
+ }
+
return result;
}
@@ -654,8 +671,13 @@ ASDCP::MXF::TLVWriter::WriteUi64(const MDDEntry& Entry, ui64_t* value)
{
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui64_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi64BE(*value);
+
+ if ( KM_SUCCESS(result) )
+ {
+ if ( ! MemIOWriter::WriteUi16BE(sizeof(ui64_t)) ) return RESULT_KLV_CODING;
+ if ( ! MemIOWriter::WriteUi64BE(*value) ) return RESULT_KLV_CODING;
+ }
+
return result;
}
@@ -673,39 +695,31 @@ ASDCP::MXF::Raw::~Raw()
}
//
-ASDCP::Result_t
-ASDCP::MXF::Raw::Unarchive(ASDCP::MemIOReader& Reader)
+bool
+ASDCP::MXF::Raw::Unarchive(Kumu::MemIOReader* Reader)
{
- ui32_t payload_size = Reader.Remainder();
-
- if ( payload_size == 0 )
- return RESULT_OK;
+ ui32_t payload_size = Reader->Remainder();
+ if ( payload_size == 0 ) return false;
+ if ( KM_FAILURE(Capacity(payload_size)) ) return false;
- Result_t result = Capacity(payload_size);
-
- if ( ASDCP_SUCCESS(result) )
- {
- memcpy(Data(), Reader.CurrentData(), payload_size);
- Size(payload_size);
- }
-
- return result;
+ memcpy(Data(), Reader->CurrentData(), payload_size);
+ Length(payload_size);
+ return true;
}
//
-ASDCP::Result_t
-ASDCP::MXF::Raw::Archive(ASDCP::MemIOWriter& Writer) const
+bool
+ASDCP::MXF::Raw::Archive(Kumu::MemIOWriter* Writer) const
{
- return Writer.WriteRaw(RoData(), Size());
+ return Writer->WriteRaw(RoData(), Length());
}
//
const char*
-ASDCP::MXF::Raw::ToString(char* str_buf) const
+ASDCP::MXF::Raw::EncodeString(char* str_buf, ui32_t buf_len) const
{
*str_buf = 0;
- bin2hex(RoData(), Size(), str_buf, IdentBufferLen);
- snprintf(str_buf, IdentBufferLen, "%s\n", str_buf);
+ Kumu::bin2hex(RoData(), Length(), str_buf, buf_len);
return str_buf;
}
diff --git a/src/MXFTypes.h b/src/MXFTypes.h
index e78b55c..5bb8ca4 100755
--- a/src/MXFTypes.h
+++ b/src/MXFTypes.h
@@ -54,7 +54,7 @@ namespace ASDCP
typedef std::map<TagValue, ItemInfo> TagMap;
//
- class TLVReader : public ASDCP::MemIOReader
+ class TLVReader : public Kumu::MemIOReader
{
TagMap m_ElementMap;
@@ -66,7 +66,7 @@ namespace ASDCP
public:
TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* = 0);
- Result_t ReadObject(const MDDEntry&, IArchive*);
+ Result_t ReadObject(const MDDEntry&, Kumu::IArchive*);
Result_t ReadUi8(const MDDEntry&, ui8_t*);
Result_t ReadUi16(const MDDEntry&, ui16_t*);
Result_t ReadUi32(const MDDEntry&, ui32_t*);
@@ -74,7 +74,7 @@ namespace ASDCP
};
//
- class TLVWriter : public ASDCP::MemIOWriter
+ class TLVWriter : public Kumu::MemIOWriter
{
TagMap m_ElementMap;
@@ -86,7 +86,7 @@ namespace ASDCP
public:
TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* = 0);
- Result_t WriteObject(const MDDEntry&, IArchive*);
+ Result_t WriteObject(const MDDEntry&, Kumu::IArchive*);
Result_t WriteUi8(const MDDEntry&, ui8_t*);
Result_t WriteUi16(const MDDEntry&, ui16_t*);
Result_t WriteUi32(const MDDEntry&, ui32_t*);
@@ -95,58 +95,55 @@ namespace ASDCP
//
template <class T>
- class Batch : public std::vector<T>, public IArchive
+ class Batch : public std::vector<T>, public Kumu::IArchive
{
public:
Batch() {}
~Batch() {}
//
- Result_t Unarchive(ASDCP::MemIOReader& Reader) {
+ virtual bool Unarchive(Kumu::MemIOReader* Reader) {
ui32_t ItemCount, ItemSize;
- Result_t result = Reader.ReadUi32BE(&ItemCount);
-
- if ( ASDCP_SUCCESS(result) )
- result = Reader.ReadUi32BE(&ItemSize);
+ if ( ! Reader->ReadUi32BE(&ItemCount) ) return false;
+ if ( ! Reader->ReadUi32BE(&ItemSize) ) return false;
if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) )
- return RESULT_FAIL;
+ return false;
- for ( ui32_t i = 0; i < ItemCount && ASDCP_SUCCESS(result); i++ )
+ bool result = true;
+ for ( ui32_t i = 0; i < ItemCount && result; i++ )
{
T Tmp;
result = Tmp.Unarchive(Reader);
- if ( ASDCP_SUCCESS(result) )
+ if ( result )
push_back(Tmp);
}
return result;
}
- inline bool HasValue() const { return ! this->empty(); }
+ inline virtual bool HasValue() const { return ! this->empty(); }
//
- Result_t Archive(ASDCP::MemIOWriter& Writer) const {
- Result_t result = Writer.WriteUi32BE(size());
- byte_t* p = Writer.CurrentData();
-
- if ( ASDCP_SUCCESS(result) )
- result = Writer.WriteUi32BE(0);
+ virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+ if ( ! Writer->WriteUi32BE(this->size()) ) return false;
+ byte_t* p = Writer->CurrentData();
- if ( ASDCP_FAILURE(result) || this->empty() )
- return result;
+ if ( ! Writer->WriteUi32BE(0) ) return false;
+ if ( this->empty() ) return true;
typename std::vector<T>::const_iterator l_i = this->begin();
assert(l_i != this->end());
- ui32_t ItemSize = Writer.Remainder();
- result = (*l_i).Archive(Writer);
- ItemSize -= Writer.Remainder();
- i2p<ui32_t>(ASDCP_i32_BE(ItemSize), p);
+ ui32_t ItemSize = Writer->Remainder();
+ if ( ! (*l_i).Archive(Writer) ) return false;
+ ItemSize -= Writer->Remainder();
+ Kumu::i2p<ui32_t>(KM_i32_BE(ItemSize), p);
l_i++;
- for ( ; l_i != this->end() && ASDCP_SUCCESS(result); l_i++ )
+ bool result = true;
+ for ( ; l_i != this->end() && result; l_i++ )
result = (*l_i).Archive(Writer);
return result;
@@ -162,39 +159,41 @@ namespace ASDCP
typename std::vector<T>::iterator i = this->begin();
for ( ; i != this->end(); i++ )
- fprintf(stream, " %s\n", (*i).ToString(identbuf));
+ fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
}
};
//
template <class T>
- class Array : public std::list<T>, public IArchive
+ class Array : public std::list<T>, public Kumu::IArchive
{
public:
Array() {}
~Array() {}
//
- Result_t Unarchive(ASDCP::MemIOReader& Reader)
+ virtual bool Unarchive(Kumu::MemIOReader* Reader)
{
- while ( Reader.Remainder() > 0 )
+ bool result = true;
+
+ while ( Reader->Remainder() > 0 && result )
{
T Tmp;
- Tmp.Unarchive(Reader);
+ result = Tmp.Unarchive(Reader);
push_back(Tmp);
}
- return RESULT_OK;
+ return result;
}
- inline bool HasValue() const { return ! this->empty(); }
+ inline virtual bool HasValue() const { return ! this->empty(); }
//
- Result_t Archive(ASDCP::MemIOWriter& Writer) const {
- Result_t result = RESULT_OK;
+ virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+ bool result = true;
typename std::list<T>::const_iterator l_i = this->begin();
- for ( ; l_i != this->end() && ASDCP_SUCCESS(result); l_i++ )
+ for ( ; l_i != this->end() && result; l_i++ )
result = (*l_i).Archive(Writer);
return result;
@@ -210,12 +209,12 @@ namespace ASDCP
typename std::list<T>::iterator i = this->begin();
for ( ; i != this->end(); i++ )
- fprintf(stream, " %s\n", (*i).ToString(identbuf));
+ fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
}
};
//
- class Timestamp : public IArchive
+ class Timestamp : public Kumu::IArchive
{
public:
ui16_t Year;
@@ -246,33 +245,27 @@ namespace ASDCP
// Write the timestamp value to the given buffer in the form 2004-05-01 13:20:00.000
// returns 0 if the buffer is smaller than DateTimeLen
- const char* ToString(char* str_buf) const;
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
//
- inline Result_t Unarchive(ASDCP::MemIOReader& Reader) {
- Result_t result = Reader.ReadUi16BE(&Year);
-
- if ( ASDCP_SUCCESS(result) )
- result = Reader.ReadRaw(&Month, 6);
-
- return result;
+ inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+ if ( ! Reader->ReadUi16BE(&Year) ) return false;
+ if ( ! Reader->ReadRaw(&Month, 6) ) return false;
+ return true;
}
- inline bool HasValue() const { return true; }
+ inline virtual bool HasValue() const { return true; }
//
- inline Result_t Archive(ASDCP::MemIOWriter& Writer) const {
- Result_t result = Writer.WriteUi16BE(Year);
-
- if ( ASDCP_SUCCESS(result) )
- result = Writer.WriteRaw(&Month, 6);
-
- return result;
+ inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+ if ( ! Writer->WriteUi16BE(Year) ) return false;
+ if ( ! Writer->WriteRaw(&Month, 6) ) return false;
+ return true;
}
};
//
- class UTF16String : public IArchive
+ class UTF16String : public Kumu::IArchive
{
ui16_t m_length;
char m_buffer[IdentBufferLen];
@@ -285,18 +278,19 @@ namespace ASDCP
const UTF16String& operator=(const char*);
//
- const char* ToString(char* str_buf) const {
- strncpy(str_buf, m_buffer, m_length+1);
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+ strncpy(str_buf, m_buffer, Kumu::xmin(buf_len, ((ui32_t)m_length+1)));
+ str_buf[buf_len-1] = 0;
return str_buf;
}
- Result_t Unarchive(ASDCP::MemIOReader& Reader);
- inline bool HasValue() const { return m_length > 0; }
- Result_t Archive(ASDCP::MemIOWriter& Writer) const;
+ virtual bool Unarchive(Kumu::MemIOReader* Reader);
+ inline virtual bool HasValue() const { return m_length > 0; }
+ virtual bool Archive(Kumu::MemIOWriter* Writer) const;
};
//
- class Rational : public ASDCP::Rational, public IArchive
+ class Rational : public ASDCP::Rational, public Kumu::IArchive
{
public:
Rational() {}
@@ -325,34 +319,28 @@ namespace ASDCP
}
//
- const char* ToString(char* str_buf) const {
- snprintf(str_buf, IdentBufferLen, "%lu/%lu", Numerator, Denominator);
+ inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+ snprintf(str_buf, buf_len, "%lu/%lu", Numerator, Denominator);
return str_buf;
}
- Result_t Unarchive(ASDCP::MemIOReader& Reader) {
- Result_t result = Reader.ReadUi32BE((ui32_t*)&Numerator);
-
- if ( ASDCP_SUCCESS(result) )
- result = Reader.ReadUi32BE((ui32_t*)&Denominator);
-
- return result;
+ inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+ if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
+ if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
+ return true;
}
- inline bool HasValue() const { return true; }
+ inline virtual bool HasValue() const { return true; }
- Result_t Archive(ASDCP::MemIOWriter& Writer) const {
- Result_t result = Writer.WriteUi32BE((ui32_t)Numerator);
-
- if ( ASDCP_SUCCESS(result) )
- result = Writer.WriteUi32BE((ui32_t)Denominator);
-
- return result;
+ inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+ if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
+ if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
+ return true;
}
};
//
- class VersionType : public IArchive
+ class VersionType : public Kumu::IArchive
{
ASDCP_NO_COPY_CONSTRUCT(VersionType);
@@ -368,40 +356,36 @@ namespace ASDCP
~VersionType() {}
void Dump(FILE* = 0);
- const char* ToString(char* str_buf) const {
- snprintf(str_buf, IdentBufferLen, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, Release);
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+ snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, Release);
return str_buf;
}
- Result_t Unarchive(ASDCP::MemIOReader& Reader) {
- Result_t result = Reader.ReadUi16BE(&Major);
- if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi16BE(&Minor);
- if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi16BE(&Patch);
- if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi16BE(&Build);
- if ( ASDCP_SUCCESS(result) )
- {
- ui16_t tmp_release;
- result = Reader.ReadUi16BE(&tmp_release);
- Release = (Release_t)tmp_release;
- }
-
- return result;
+ virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+ if ( ! Reader->ReadUi16BE(&Major) ) return false;
+ if ( ! Reader->ReadUi16BE(&Minor) ) return false;
+ if ( ! Reader->ReadUi16BE(&Patch) ) return false;
+ if ( ! Reader->ReadUi16BE(&Build) ) return false;
+ ui16_t tmp_release;
+ if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
+ Release = (Release_t)tmp_release;
+ return true;
}
- inline bool HasValue() const { return true; }
+ inline virtual bool HasValue() const { return true; }
- Result_t Archive(ASDCP::MemIOWriter& Writer) const {
- Result_t result = Writer.WriteUi16BE(Major);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi16BE(Minor);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi16BE(Patch);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi16BE(Build);
- if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi16BE((ui16_t)(Release & 0x0000ffffL));
- return result;
+ virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+ if ( ! Writer->WriteUi16BE(Major) ) return false;
+ if ( ! Writer->WriteUi16BE(Minor) ) return false;
+ if ( ! Writer->WriteUi16BE(Patch) ) return false;
+ if ( ! Writer->WriteUi16BE(Build) ) return false;
+ if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
+ return true;
}
};
//
- class Raw : public ASDCP::FrameBuffer, public IArchive
+ class Raw : public Kumu::ByteString, public Kumu::IArchive
{
ASDCP_NO_COPY_CONSTRUCT(Raw);
@@ -410,10 +394,10 @@ namespace ASDCP
~Raw();
//
- Result_t Unarchive(ASDCP::MemIOReader& Reader);
- inline bool HasValue() const { return Size() > 0; }
- Result_t Archive(ASDCP::MemIOWriter& Writer) const;
- const char* ToString(char* str_buf) const;
+ virtual bool Unarchive(Kumu::MemIOReader* Reader);
+ inline virtual bool HasValue() const { return Length() > 0; }
+ virtual bool Archive(Kumu::MemIOWriter* Writer) const;
+ const char* EncodeString(char* str_buf, ui32_t buf_len) const;
};
} // namespace MXF
diff --git a/src/Metadata.cpp b/src/Metadata.cpp
index d4cc819..3290b1b 100755
--- a/src/Metadata.cpp
+++ b/src/Metadata.cpp
@@ -30,9 +30,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <KM_mutex.h>
#include "Metadata.h"
-#include "Mutex.h"
-#include "hex_utils.h"
const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH;
@@ -71,24 +70,24 @@ typedef std::map<ASDCP::UL, FLT_t>::iterator FLi_t;
class FactoryList : public std::map<ASDCP::UL, FLT_t>
{
- ASDCP::Mutex m_Lock;
+ Kumu::Mutex m_Lock;
public:
FactoryList() {}
~FactoryList() {}
bool Empty() {
- ASDCP::AutoMutex BlockLock(m_Lock);
+ Kumu::AutoMutex BlockLock(m_Lock);
return empty();
}
FLi_t Find(const byte_t* label) {
- ASDCP::AutoMutex BlockLock(m_Lock);
+ Kumu::AutoMutex BlockLock(m_Lock);
return find(label);
}
FLi_t End() {
- ASDCP::AutoMutex BlockLock(m_Lock);
+ Kumu::AutoMutex BlockLock(m_Lock);
return end();
}
@@ -220,15 +219,15 @@ ASDCP::MXF::Identification::Dump(FILE* stream)
stream = stderr;
InterchangeObject::Dump(stream);
- fprintf(stream, " %22s = %s\n", "ThisGenerationUID", ThisGenerationUID.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "CompanyName", CompanyName.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "ProductName", ProductName.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "ProductVersion", ProductVersion.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "VersionString", VersionString.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "ProductUID", ProductUID.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "ModificationDate", ModificationDate.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "ToolkitVersion", ToolkitVersion.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "Platform", Platform.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "ThisGenerationUID", ThisGenerationUID.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "CompanyName", CompanyName.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "ProductName", ProductName.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "ProductVersion", ProductVersion.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "VersionString", VersionString.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "ProductUID", ProductUID.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "ModificationDate", ModificationDate.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "ToolkitVersion", ToolkitVersion.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "Platform", Platform.EncodeString(identbuf, IdentBufferLen));
}
//
@@ -339,7 +338,7 @@ ASDCP::MXF::EssenceContainerData::Dump(FILE* stream)
stream = stderr;
InterchangeObject::Dump(stream);
- fprintf(stream, " %22s = %s\n", "LinkedPackageUID", LinkedPackageUID.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "LinkedPackageUID", LinkedPackageUID.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s = %d\n", "IndexSID", IndexSID);
fprintf(stream, " %22s = %d\n", "BodySID", BodySID);
}
@@ -400,10 +399,10 @@ ASDCP::MXF::GenericPackage::Dump(FILE* stream)
stream = stderr;
InterchangeObject::Dump(stream);
- fprintf(stream, " %22s = %s\n", "PackageUID", PackageUID.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "Name", Name.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "PackageCreationDate", PackageCreationDate.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "PackageModifiedDate", PackageModifiedDate.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "PackageUID", PackageUID.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "Name", Name.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "PackageCreationDate", PackageCreationDate.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "PackageModifiedDate", PackageModifiedDate.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s:\n", "Tracks");
Tracks.Dump(stream);
}
@@ -489,7 +488,7 @@ ASDCP::MXF::SourcePackage::Dump(FILE* stream)
stream = stderr;
GenericPackage::Dump(stream);
- fprintf(stream, " %22s = %s\n", "Descriptor", Descriptor.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "Descriptor", Descriptor.EncodeString(identbuf, IdentBufferLen));
}
//
@@ -548,8 +547,8 @@ ASDCP::MXF::GenericTrack::Dump(FILE* stream)
InterchangeObject::Dump(stream);
fprintf(stream, " %22s = %d\n", "TrackID", TrackID);
fprintf(stream, " %22s = %d\n", "TrackNumber", TrackNumber);
- fprintf(stream, " %22s = %s\n", "TrackName", TrackName.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "Sequence", Sequence.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "TrackName", TrackName.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "Sequence", Sequence.EncodeString(identbuf, IdentBufferLen));
}
@@ -635,7 +634,7 @@ ASDCP::MXF::Track::Dump(FILE* stream)
stream = stderr;
GenericTrack::Dump(stream);
- fprintf(stream, " %22s = %s\n", "EditRate", EditRate.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "EditRate", EditRate.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s = %s\n", "Origin", i64sz(Origin, identbuf));
}
@@ -689,7 +688,7 @@ ASDCP::MXF::StructuralComponent::Dump(FILE* stream)
stream = stderr;
InterchangeObject::Dump(stream);
- fprintf(stream, " %22s = %s\n", "DataDefinition", DataDefinition.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "DataDefinition", DataDefinition.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s = %s\n", "Duration", i64sz(Duration, identbuf));
}
@@ -783,7 +782,7 @@ ASDCP::MXF::SourceClip::Dump(FILE* stream)
StructuralComponent::Dump(stream);
fprintf(stream, " %22s = %s\n", "StartPosition", i64sz(StartPosition, identbuf));
- fprintf(stream, " %22s = %s\n", "SourcePackageID", SourcePackageID.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "SourcePackageID", SourcePackageID.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s = %d\n", "SourceTrackID", SourceTrackID);
}
@@ -942,10 +941,10 @@ ASDCP::MXF::FileDescriptor::Dump(FILE* stream)
GenericDescriptor::Dump(stream);
fprintf(stream, " %22s = %d\n", "LinkedTrackID", LinkedTrackID);
- fprintf(stream, " %22s = %s\n", "SampleRate", SampleRate.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "SampleRate", SampleRate.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s = %s\n", "ContainerDuration", i64sz(ContainerDuration, identbuf));
- fprintf(stream, " %22s = %s\n", "EssenceContainer", EssenceContainer.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "Codec", Codec.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "EssenceContainer", EssenceContainer.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "Codec", Codec.EncodeString(identbuf, IdentBufferLen));
}
//
@@ -1006,7 +1005,7 @@ ASDCP::MXF::GenericSoundEssenceDescriptor::Dump(FILE* stream)
stream = stderr;
FileDescriptor::Dump(stream);
- fprintf(stream, " %22s = %s\n", "AudioSamplingRate", AudioSamplingRate.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "AudioSamplingRate", AudioSamplingRate.EncodeString(identbuf, IdentBufferLen));
fprintf(stream, " %22s = %d\n", "Locked", Locked);
fprintf(stream, " %22s = %d\n", "AudioRefLevel", AudioRefLevel);
fprintf(stream, " %22s = %d\n", "ChannelCount", ChannelCount);
@@ -1128,7 +1127,7 @@ ASDCP::MXF::GenericPictureEssenceDescriptor::Dump(FILE* stream)
fprintf(stream, " %22s = %d\n", "FrameLayout", FrameLayout);
fprintf(stream, " %22s = %d\n", "StoredWidth", StoredWidth);
fprintf(stream, " %22s = %d\n", "StoredHeight", StoredHeight);
- fprintf(stream, " %22s = %s\n", "AspectRatio", AspectRatio.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "AspectRatio", AspectRatio.EncodeString(identbuf, IdentBufferLen));
}
//
@@ -1267,9 +1266,9 @@ ASDCP::MXF::JPEG2000PictureSubDescriptor::Dump(FILE* stream)
fprintf(stream, " %22s = %d\n", "XTOsize", XTOsize);
fprintf(stream, " %22s = %d\n", "YTOsize", YTOsize);
fprintf(stream, " %22s = %d\n", "Csize", Csize);
- fprintf(stream, " %22s = %s\n", "PictureComponentSizing", PictureComponentSizing.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "CodingStyleDefault", CodingStyleDefault.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "QuantizationDefault", QuantizationDefault.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "PictureComponentSizing", PictureComponentSizing.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "CodingStyleDefault", CodingStyleDefault.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "QuantizationDefault", QuantizationDefault.EncodeString(identbuf, IdentBufferLen));
}
//
@@ -1445,8 +1444,8 @@ ASDCP::MXF::DMSegment::Dump(FILE* stream)
InterchangeObject::Dump(stream);
fprintf(stream, " %22s = %s\n", "EventStartPosition", i64sz(EventStartPosition, identbuf));
- fprintf(stream, " %22s = %s\n", "EventComment", EventComment.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "DMFramework", DMFramework.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "EventComment", EventComment.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "DMFramework", DMFramework.EncodeString(identbuf, IdentBufferLen));
}
//
@@ -1497,7 +1496,7 @@ ASDCP::MXF::CryptographicFramework::Dump(FILE* stream)
stream = stderr;
InterchangeObject::Dump(stream);
- fprintf(stream, " %22s = %s\n", "ContextSR", ContextSR.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "ContextSR", ContextSR.EncodeString(identbuf, IdentBufferLen));
}
//
@@ -1556,11 +1555,11 @@ ASDCP::MXF::CryptographicContext::Dump(FILE* stream)
stream = stderr;
InterchangeObject::Dump(stream);
- fprintf(stream, " %22s = %s\n", "ContextID", ContextID.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "SourceEssenceContainer", SourceEssenceContainer.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "CipherAlgorithm", CipherAlgorithm.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "MICAlgorithm", MICAlgorithm.ToString(identbuf));
- fprintf(stream, " %22s = %s\n", "CryptographicKeyID", CryptographicKeyID.ToString(identbuf));
+ fprintf(stream, " %22s = %s\n", "ContextID", ContextID.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "SourceEssenceContainer", SourceEssenceContainer.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "CipherAlgorithm", CipherAlgorithm.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "MICAlgorithm", MICAlgorithm.EncodeString(identbuf, IdentBufferLen));
+ fprintf(stream, " %22s = %s\n", "CryptographicKeyID", CryptographicKeyID.EncodeString(identbuf, IdentBufferLen));
}
//
@@ -1580,5 +1579,5 @@ ASDCP::MXF::CryptographicContext::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
}
//
-// end MXF.cpp
+// end Metadata.cpp
//
diff --git a/src/PCM_Parser.cpp b/src/PCM_Parser.cpp
index 331bebf..f3e32db 100755
--- a/src/PCM_Parser.cpp
+++ b/src/PCM_Parser.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <Wav.h>
#include <assert.h>
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
using namespace ASDCP;
using namespace ASDCP::PCM;
@@ -42,7 +44,7 @@ using namespace ASDCP::Wav;
//
class ASDCP::PCM::WAVParser::h__WAVParser
{
- FileReader m_FileReader;
+ Kumu::FileReader m_FileReader;
bool m_EOF;
ui32_t m_DataStart;
ui32_t m_DataLength;
diff --git a/src/Wav.cpp b/src/Wav.cpp
index ce64a78..92bd5e7 100755
--- a/src/Wav.cpp
+++ b/src/Wav.cpp
@@ -30,8 +30,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Wav.h"
-#include "hex_utils.h"
#include <assert.h>
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
const ui32_t SimpleWavHeaderLength = 46;
@@ -69,7 +70,7 @@ ASDCP::Wav::SimpleWaveHeader::FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, ASDC
//
ASDCP::Result_t
-ASDCP::Wav::SimpleWaveHeader::WriteToFile(ASDCP::FileWriter& OutFile) const
+ASDCP::Wav::SimpleWaveHeader::WriteToFile(Kumu::FileWriter& OutFile) const
{
ui32_t write_count;
byte_t tmp_header[SimpleWavHeaderLength];
@@ -87,26 +88,26 @@ ASDCP::Wav::SimpleWaveHeader::WriteToFile(ASDCP::FileWriter& OutFile) const
ui32_t RIFF_len = data_len + SimpleWavHeaderLength - 8;
memcpy(p, &FCC_RIFF, sizeof(fourcc)); p += 4;
- *((ui32_t*)p) = ASDCP_i32_LE(RIFF_len); p += 4;
+ *((ui32_t*)p) = KM_i32_LE(RIFF_len); p += 4;
memcpy(p, &FCC_WAVE, sizeof(fourcc)); p += 4;
memcpy(p, &FCC_fmt_, sizeof(fourcc)); p += 4;
- *((ui32_t*)p) = ASDCP_i32_LE(fmt_len); p += 4;
- *((ui16_t*)p) = ASDCP_i16_LE(format); p += 2;
- *((ui16_t*)p) = ASDCP_i16_LE(nchannels); p += 2;
- *((ui32_t*)p) = ASDCP_i32_LE(samplespersec); p += 4;
- *((ui32_t*)p) = ASDCP_i32_LE(avgbps); p += 4;
- *((ui16_t*)p) = ASDCP_i16_LE(blockalign); p += 2;
- *((ui16_t*)p) = ASDCP_i16_LE(bitspersample); p += 2;
- *((ui16_t*)p) = ASDCP_i16_LE(cbsize); p += 2;
+ *((ui32_t*)p) = KM_i32_LE(fmt_len); p += 4;
+ *((ui16_t*)p) = KM_i16_LE(format); p += 2;
+ *((ui16_t*)p) = KM_i16_LE(nchannels); p += 2;
+ *((ui32_t*)p) = KM_i32_LE(samplespersec); p += 4;
+ *((ui32_t*)p) = KM_i32_LE(avgbps); p += 4;
+ *((ui16_t*)p) = KM_i16_LE(blockalign); p += 2;
+ *((ui16_t*)p) = KM_i16_LE(bitspersample); p += 2;
+ *((ui16_t*)p) = KM_i16_LE(cbsize); p += 2;
memcpy(p, &FCC_data, sizeof(fourcc)); p += 4;
- *((ui32_t*)p) = ASDCP_i32_LE(data_len); p += 4;
+ *((ui32_t*)p) = KM_i32_LE(data_len); p += 4;
return OutFile.Write(tmp_header, SimpleWavHeaderLength, &write_count);
}
//
ASDCP::Result_t
-ASDCP::Wav::SimpleWaveHeader::ReadFromFile(const ASDCP::FileReader& InFile, ui32_t* data_start)
+ASDCP::Wav::SimpleWaveHeader::ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start)
{
ui32_t read_count = 0;
ui32_t local_data_start = 0;
@@ -140,7 +141,7 @@ ASDCP::Wav::SimpleWaveHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len,
return RESULT_RAW_FORMAT;
}
- ui32_t RIFF_len = ASDCP_i32_LE(*(ui32_t*)p); p += 4;
+ ui32_t RIFF_len = KM_i32_LE(*(ui32_t*)p); p += 4;
fourcc test_WAVE(p); p += 4;
if ( test_WAVE != FCC_WAVE )
@@ -154,7 +155,7 @@ ASDCP::Wav::SimpleWaveHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len,
while ( p < end_p )
{
test_fcc = fourcc(p); p += 4;
- ui32_t chunk_size = ASDCP_i32_LE(*(ui32_t*)p); p += 4;
+ ui32_t chunk_size = KM_i32_LE(*(ui32_t*)p); p += 4;
if ( test_fcc == FCC_data )
{
@@ -171,7 +172,7 @@ ASDCP::Wav::SimpleWaveHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len,
if ( test_fcc == FCC_fmt_ )
{
- ui16_t format = ASDCP_i16_LE(*(ui16_t*)p); p += 2;
+ ui16_t format = KM_i16_LE(*(ui16_t*)p); p += 2;
if ( format != 1 )
{
@@ -179,11 +180,11 @@ ASDCP::Wav::SimpleWaveHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len,
return RESULT_RAW_FORMAT;
}
- nchannels = ASDCP_i16_LE(*(ui16_t*)p); p += 2;
- samplespersec = ASDCP_i32_LE(*(ui32_t*)p); p += 4;
- avgbps = ASDCP_i32_LE(*(ui32_t*)p); p += 4;
- blockalign = ASDCP_i16_LE(*(ui16_t*)p); p += 2;
- bitspersample = ASDCP_i16_LE(*(ui16_t*)p); p += 2;
+ nchannels = KM_i16_LE(*(ui16_t*)p); p += 2;
+ samplespersec = KM_i32_LE(*(ui32_t*)p); p += 4;
+ avgbps = KM_i32_LE(*(ui32_t*)p); p += 4;
+ blockalign = KM_i16_LE(*(ui16_t*)p); p += 2;
+ bitspersample = KM_i16_LE(*(ui16_t*)p); p += 2;
p += chunk_size - 16;
}
else
@@ -230,7 +231,7 @@ Rat_to_extended(ASDCP::Rational rate, byte_t* buf)
value <<= 1;
}
- *(ui32_t*)(buf+2) = ASDCP_i32_BE(value);
+ *(ui32_t*)(buf+2) = KM_i32_BE(value);
}
//
@@ -238,7 +239,7 @@ ASDCP::Rational
extended_to_Rat(const byte_t* buf)
{
ui32_t last = 0;
- ui32_t mantissa = ASDCP_i32_BE(*(ui32_t*)(buf+2));
+ ui32_t mantissa = KM_i32_BE(*(ui32_t*)(buf+2));
byte_t exp = 30 - *(buf+1);
@@ -271,7 +272,7 @@ ASDCP::AIFF::SimpleAIFFHeader::FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, ASD
//
ASDCP::Result_t
-ASDCP::AIFF::SimpleAIFFHeader::ReadFromFile(const ASDCP::FileReader& InFile, ui32_t* data_start)
+ASDCP::AIFF::SimpleAIFFHeader::ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start)
{
ui32_t read_count = 0;
ui32_t local_data_start = 0;
@@ -306,7 +307,7 @@ ASDCP::AIFF::SimpleAIFFHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len,
return RESULT_RAW_FORMAT;
}
- ui32_t RIFF_len = ASDCP_i32_BE(*(ui32_t*)p); p += 4;
+ ui32_t RIFF_len = KM_i32_BE(*(ui32_t*)p); p += 4;
fourcc test_AIFF(p); p += 4;
if ( test_AIFF != FCC_AIFF )
@@ -320,13 +321,13 @@ ASDCP::AIFF::SimpleAIFFHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len,
while ( p < end_p )
{
test_fcc = fourcc(p); p += 4;
- ui32_t chunk_size = ASDCP_i32_BE(*(ui32_t*)p); p += 4;
+ ui32_t chunk_size = KM_i32_BE(*(ui32_t*)p); p += 4;
if ( test_fcc == FCC_COMM )
{
- numChannels = ASDCP_i16_BE(*(ui16_t*)p); p += 2;
- numSampleFrames = ASDCP_i32_BE(*(ui32_t*)p); p += 4;
- sampleSize = ASDCP_i16_BE(*(ui16_t*)p); p += 2;
+ numChannels = KM_i16_BE(*(ui16_t*)p); p += 2;
+ numSampleFrames = KM_i32_BE(*(ui32_t*)p); p += 4;
+ sampleSize = KM_i16_BE(*(ui16_t*)p); p += 2;
memcpy(sampleRate, p, 10);
p += 10;
}
@@ -338,7 +339,7 @@ ASDCP::AIFF::SimpleAIFFHeader::ReadFromBuffer(const byte_t* buf, ui32_t buf_len,
return RESULT_RAW_FORMAT;
}
- ui32_t offset = ASDCP_i32_BE(*(ui32_t*)p); p += 4;
+ ui32_t offset = KM_i32_BE(*(ui32_t*)p); p += 4;
p += 4; // blockSize;
data_len = chunk_size - 8;
diff --git a/src/Wav.h b/src/Wav.h
index efd99c0..bd890ce 100755
--- a/src/Wav.h
+++ b/src/Wav.h
@@ -32,7 +32,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _WAV_H_
#define _WAV_H_
-#include <FileIO.h>
+#include <KM_fileio.h>
+#include <AS_DCP.h>
namespace ASDCP
{
@@ -73,7 +74,7 @@ namespace ASDCP
}
Result_t ReadFromBuffer(const byte_t* buf, ui32_t buf_len, ui32_t* data_start);
- Result_t ReadFromFile(const ASDCP::FileReader& InFile, ui32_t* data_start);
+ Result_t ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start);
void FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, Rational PictureRate) const;
};
@@ -108,8 +109,8 @@ namespace ASDCP
SimpleWaveHeader(ASDCP::PCM::AudioDescriptor& ADesc);
Result_t ReadFromBuffer(const byte_t* buf, ui32_t buf_len, ui32_t* data_start);
- Result_t ReadFromFile(const ASDCP::FileReader& InFile, ui32_t* data_start);
- Result_t WriteToFile(ASDCP::FileWriter& OutFile) const;
+ Result_t ReadFromFile(const Kumu::FileReader& InFile, ui32_t* data_start);
+ Result_t WriteToFile(Kumu::FileWriter& OutFile) const;
void FillADesc(ASDCP::PCM::AudioDescriptor& ADesc, Rational PictureRate) const;
};
diff --git a/src/WavFileWriter.h b/src/WavFileWriter.h
index 40d23ba..b246f3c 100755
--- a/src/WavFileWriter.h
+++ b/src/WavFileWriter.h
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2005, John Hurst
+Copyright (c) 2005-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -29,7 +29,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\brief demux and write PCM data to WAV file(s)
*/
-#include <FileIO.h>
+#include <KM_fileio.h>
#include <Wav.h>
#include <list>
@@ -40,7 +40,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class WavFileWriter
{
ASDCP::PCM::AudioDescriptor m_ADesc;
- std::list<ASDCP::FileWriter*> m_OutFile;
+ std::list<Kumu::FileWriter*> m_OutFile;
ASDCP_NO_COPY_CONSTRUCT(WavFileWriter);
public:
@@ -73,7 +73,7 @@ class WavFileWriter
for ( ui32_t i = 0; i < file_count && ASDCP_SUCCESS(result); i++ )
{
snprintf(filename, 256, "%s_%lu.wav", file_root, (i + 1));
- m_OutFile.push_back(new ASDCP::FileWriter);
+ m_OutFile.push_back(new Kumu::FileWriter);
result = m_OutFile.back()->OpenWrite(filename);
if ( ASDCP_SUCCESS(result) )
@@ -91,7 +91,7 @@ class WavFileWriter
{
ui32_t write_count;
ASDCP::Result_t result = ASDCP::RESULT_OK;
- std::list<ASDCP::FileWriter*>::iterator fi;
+ std::list<Kumu::FileWriter*>::iterator fi;
assert(! m_OutFile.empty());
ui32_t sample_size = ASDCP::PCM::CalcSampleSize(m_ADesc);
diff --git a/src/asdcp-test.cpp b/src/asdcp-test.cpp
index c048a30..50a02ef 100755
--- a/src/asdcp-test.cpp
+++ b/src/asdcp-test.cpp
@@ -50,11 +50,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include <assert.h>
-#include <FileIO.h>
+#include <KM_fileio.h>
+#include <KM_prng.h>
#include <PCMParserList.h>
#include <WavFileWriter.h>
-#include <hex_utils.h>
-#include <AS_DCP_UUID.h>
#include <MXF.h>
#include <Metadata.h>
@@ -138,46 +137,46 @@ USAGE: %s [-i [-H, -n]|-c <filename> [-p <rate>, -e, -M, -R]|-x <root-name> [-m]
fprintf(stream, "\
Major modes:\n\
- -i - show file info\n\
- -c <filename> - create AS-DCP file from input(s)\n\
- -x <root-name> - extract essence from AS-DCP file to named file(s)\n\
- -g - generate a random 16 byte value to stdout\n\
- -u - generate a random UUID value to stdout\n\
+ -i - Show file info\n\
+ -c <filename> - Create AS-DCP file from input(s)\n\
+ -x <root-name> - Extract essence from AS-DCP file to named file(s)\n\
+ -g - Generate a random 16 byte value to stdout\n\
+ -u - Generate a random UUID value to stdout\n\
-G - Perform GOP start lookup test on MPEG file\n\
- -V - show version\n\
- -h - show help\n\
+ -V - Show version\n\
+ -h - Show help\n\
\n");
fprintf(stream, "\
Security Options:\n\
- -j <key-id-str> - write key ID instead of creating a random value\n\
- -k <key-string> - use key for ciphertext operations\n\
- -e - encrypt MPEG or JP2K headers (default)\n\
- -E - do not encrypt MPEG or JP2K headers\n\
- -M - do not create HMAC values when writing\n\
+ -j <key-id-str> - Write key ID instead of creating a random value\n\
+ -k <key-string> - Use key for ciphertext operations\n\
+ -e - Encrypt MPEG or JP2K headers (default)\n\
+ -E - Do not encrypt MPEG or JP2K headers\n\
+ -M - Do not create HMAC values when writing\n\
-m - verify HMAC values when reading\n\
\n");
fprintf(stream, "\
Read/Write Options:\n\
-b <buf-size> - Size (in bytes) of the picture frame buffer, default: 2097152 (2MB)\n\
- -f <frame-num> - starting frame number, default 0\n\
- -d <duration> - number of frames to process, default all\n\
+ -f <frame-num> - Starting frame number, default 0\n\
+ -d <duration> - Number of frames to process, default all\n\
-p <rate> - fps of picture when wrapping PCM or JP2K:, use one of [23|24|48], 24 is default\n\
-L - Write SMPTE UL values instead of MXF Interop\n\
-R - Repeat the first frame over the entire file (picture essence only, requires -c, -d)\n\
-S - Split Wave essence to stereo WAV files during extract (default = multichannel WAV)\n\
- -W - read input file only, do not write source file\n\
+ -W - Read input file only, do not write source file\n\
\n");
fprintf(stream, "\
Info Options:\n\
- -H - show MXF header metadata, used with option -i\n\
- -n - show index, used with option -i\n\
+ -H - Show MXF header metadata, used with option -i\n\
+ -n - Show index, used with option -i\n\
\n\
Other Options:\n\
- -s <number> - number of bytes of frame buffer to be dumped as hex to stderr (use with -v)\n\
- -v - verbose, show extra detail during run\n\
+ -s <number> - Number of bytes of frame buffer to be dumped as hex to stderr (use with -v)\n\
+ -v - Verbose, show extra detail during run\n\
\n\
NOTES: o There is no option grouping, all options must be distinct arguments.\n\
o All option arguments must be separated from the option by whitespace.\n\
@@ -296,7 +295,7 @@ public:
TEST_EXTRA_ARG(i, 'k');
{
ui32_t length;
- hex2bin(argv[i], key_value, KeyLen, &length);
+ Kumu::hex2bin(argv[i], key_value, KeyLen, &length);
if ( length != KeyLen )
{
@@ -310,7 +309,7 @@ public:
TEST_EXTRA_ARG(i, 'j');
{
ui32_t length;
- hex2bin(argv[i], key_id_value, UUIDlen, &length);
+ Kumu::hex2bin(argv[i], key_id_value, UUIDlen, &length);
if ( length != UUIDlen )
{
@@ -402,7 +401,7 @@ write_MPEG2_file(CommandOptions& Options)
MPEG2::MXFWriter Writer;
MPEG2::VideoDescriptor VDesc;
byte_t IV_buf[CBC_BLOCK_SIZE];
- FortunaRNG RNG;
+ Kumu::FortunaRNG RNG;
// set up essence parser
Result_t result = Parser.OpenRead(Options.filenames[0]);
@@ -424,18 +423,18 @@ write_MPEG2_file(CommandOptions& Options)
if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
{
WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here
- GenRandomUUID(RNG, Info.AssetUUID);
+ Kumu::GenRandomUUID(Info.AssetUUID);
if ( Options.use_smpte_labels )
{
- Info.LabelSetType = LS_MXF_INTEROP;
+ Info.LabelSetType = LS_MXF_SMPTE;
fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n");
}
// configure encryption
if( Options.key_flag )
{
- GenRandomUUID(RNG, Info.ContextID);
+ Kumu::GenRandomUUID(Info.ContextID);
Info.EncryptedEssence = true;
if ( Options.key_id_flag )
@@ -453,7 +452,7 @@ write_MPEG2_file(CommandOptions& Options)
{
Info.UsesHMAC = true;
HMAC = new HMACContext;
- result = HMAC->InitKey(Options.key_value);
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
}
}
@@ -517,7 +516,7 @@ read_MPEG2_file(CommandOptions& Options)
HMACContext* HMAC = 0;
MPEG2::MXFReader Reader;
MPEG2::FrameBuffer FrameBuffer(Options.fb_size);
- FileWriter OutFile;
+ Kumu::FileWriter OutFile;
ui32_t frame_count = 0;
Result_t result = Reader.OpenRead(Options.filenames[0]);
@@ -555,7 +554,7 @@ read_MPEG2_file(CommandOptions& Options)
if ( Info.UsesHMAC )
{
HMAC = new HMACContext;
- result = HMAC->InitKey(Options.key_value);
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
}
else
{
@@ -649,8 +648,8 @@ write_JP2K_file(CommandOptions& Options)
JP2K::FrameBuffer FrameBuffer(Options.fb_size);
JP2K::PictureDescriptor PDesc;
JP2K::SequenceParser Parser;
- byte_t IV_buf[CBC_BLOCK_SIZE];
- FortunaRNG RNG;
+ byte_t IV_buf[CBC_BLOCK_SIZE];
+ Kumu::FortunaRNG RNG;
// set up essence parser
Result_t result = Parser.OpenRead(Options.filenames[0]);
@@ -673,18 +672,18 @@ write_JP2K_file(CommandOptions& Options)
if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
{
WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here
- GenRandomUUID(RNG, Info.AssetUUID);
+ Kumu::GenRandomUUID(Info.AssetUUID);
if ( Options.use_smpte_labels )
{
- Info.LabelSetType = LS_MXF_INTEROP;
+ Info.LabelSetType = LS_MXF_SMPTE;
fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n");
}
// configure encryption
if( Options.key_flag )
{
- GenRandomUUID(RNG, Info.ContextID);
+ Kumu::GenRandomUUID(Info.ContextID);
Info.EncryptedEssence = true;
if ( Options.key_id_flag )
@@ -702,7 +701,7 @@ write_JP2K_file(CommandOptions& Options)
{
Info.UsesHMAC = true;
HMAC = new HMACContext;
- result = HMAC->InitKey(Options.key_value);
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
}
}
@@ -796,7 +795,7 @@ read_JP2K_file(CommandOptions& Options)
if ( Info.UsesHMAC )
{
HMAC = new HMACContext;
- result = HMAC->InitKey(Options.key_value);
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
}
else
{
@@ -815,7 +814,7 @@ read_JP2K_file(CommandOptions& Options)
if ( ASDCP_SUCCESS(result) )
{
- FileWriter OutFile;
+ Kumu::FileWriter OutFile;
char filename[256];
ui32_t write_count;
snprintf(filename, 256, "%s%06lu.j2c", Options.file_root, i);
@@ -842,15 +841,15 @@ read_JP2K_file(CommandOptions& Options)
Result_t
write_PCM_file(CommandOptions& Options)
{
- AESEncContext* Context = 0;
- HMACContext* HMAC = 0;
- PCMParserList Parser;
- PCM::MXFWriter Writer;
- PCM::FrameBuffer FrameBuffer;
+ AESEncContext* Context = 0;
+ HMACContext* HMAC = 0;
+ PCMParserList Parser;
+ PCM::MXFWriter Writer;
+ PCM::FrameBuffer FrameBuffer;
PCM::AudioDescriptor ADesc;
- Rational PictureRate = Options.PictureRate();
- byte_t IV_buf[CBC_BLOCK_SIZE];
- FortunaRNG RNG;
+ Rational PictureRate = Options.PictureRate();
+ byte_t IV_buf[CBC_BLOCK_SIZE];
+ Kumu::FortunaRNG RNG;
// set up essence parser
Result_t result = Parser.OpenRead(Options.file_count, Options.filenames, PictureRate);
@@ -876,18 +875,18 @@ write_PCM_file(CommandOptions& Options)
if ( ASDCP_SUCCESS(result) && ! Options.no_write_flag )
{
WriterInfo Info = s_MyInfo; // fill in your favorite identifiers here
- GenRandomUUID(RNG, Info.AssetUUID);
+ Kumu::GenRandomUUID(Info.AssetUUID);
if ( Options.use_smpte_labels )
{
- Info.LabelSetType = LS_MXF_INTEROP;
+ Info.LabelSetType = LS_MXF_SMPTE;
fprintf(stderr, "ATTENTION! Writing SMPTE Universal Labels\n");
}
// configure encryption
if( Options.key_flag )
{
- GenRandomUUID(RNG, Info.ContextID);
+ Kumu::GenRandomUUID(Info.ContextID);
Info.EncryptedEssence = true;
if ( Options.key_id_flag )
@@ -905,7 +904,7 @@ write_PCM_file(CommandOptions& Options)
{
Info.UsesHMAC = true;
HMAC = new HMACContext;
- result = HMAC->InitKey(Options.key_value);
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
}
}
@@ -1006,7 +1005,7 @@ read_PCM_file(CommandOptions& Options)
return RESULT_FAIL;
}
- last_frame = xmin(Options.start_frame + last_frame, ADesc.ContainerDuration);
+ last_frame = Kumu::xmin(Options.start_frame + last_frame, ADesc.ContainerDuration);
}
ADesc.ContainerDuration = last_frame - Options.start_frame;
@@ -1026,7 +1025,7 @@ read_PCM_file(CommandOptions& Options)
if ( Info.UsesHMAC )
{
HMAC = new HMACContext;
- result = HMAC->InitKey(Options.key_value);
+ result = HMAC->InitKey(Options.key_value, Info.LabelSetType);
}
else
{
@@ -1165,7 +1164,7 @@ show_file_info(CommandOptions& Options)
else
{
fprintf(stderr, "File is not AS-DCP: %s\n", Options.filenames[0]);
- FileReader Reader;
+ Kumu::FileReader Reader;
MXF::OPAtomHeader TestHeader;
result = Reader.OpenRead(Options.filenames[0]);
@@ -1226,22 +1225,19 @@ main(int argc, const char** argv)
}
else if ( Options.genkey_flag )
{
- FortunaRNG RNG;
+ Kumu::FortunaRNG RNG;
byte_t bin_buf[KeyLen];
char str_buf[40];
RNG.FillRandom(bin_buf, KeyLen);
- printf("%s\n", bin2hex(bin_buf, KeyLen, str_buf, 40));
+ printf("%s\n", Kumu::bin2hex(bin_buf, KeyLen, str_buf, 40));
}
else if ( Options.genid_flag )
{
- FortunaRNG RNG;
- byte_t bin_buf[KeyLen];
+ UUID TmpID;
+ Kumu::GenRandomValue(TmpID);
char str_buf[40];
-
- GenRandomUUID(RNG, bin_buf);
- bin2hex(bin_buf, KeyLen, str_buf, 40);
- printf("%s\n", hyphenate_UUID(str_buf, 40));
+ printf("%s\n", TmpID.EncodeHex(str_buf, 40));
}
else if ( Options.extract_flag )
{
@@ -1305,13 +1301,13 @@ main(int argc, const char** argv)
}
}
- if ( result != RESULT_OK )
+ if ( ASDCP_FAILURE(result) )
{
fputs("Program stopped on error.\n", stderr);
if ( result != RESULT_FAIL )
{
- fputs(GetResultString(result), stderr);
+ fputs(result, stderr);
fputc('\n', stderr);
}
diff --git a/src/blackwave.cpp b/src/blackwave.cpp
new file mode 100644
index 0000000..c84774f
--- /dev/null
+++ b/src/blackwave.cpp
@@ -0,0 +1,245 @@
+/*
+Copyright (c) 2005, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*! \file wavsplit.cpp
+ \version $Id$
+ \brief Black WAV file generator
+*/
+
+#include "Wav.h"
+#include <assert.h>
+
+using namespace ASDCP;
+
+//------------------------------------------------------------------------------------------
+//
+// command line option parser class
+
+static const char* PACKAGE = "wavsplit"; // program name for messages
+
+// Macros used to test command option data state.
+
+// Increment the iterator, test for an additional non-option command line argument.
+// Causes the caller to return if there are no remaining arguments or if the next
+// argument begins with '-'.
+#define TEST_EXTRA_ARG(i,c) if ( ++i >= argc || argv[(i)][0] == '-' ) \
+ { \
+ fprintf(stderr, "Argument not found for option %c.\n", (c)); \
+ return; \
+ }
+//
+void
+banner(FILE* stream = stderr)
+{
+ fprintf(stream, "\n\
+%s (asdcplib %s)\n\n\
+Copyright (c) 2005-2006 John Hurst\n\n\
+wavesplit is part of asdcplib.\n\
+asdcplib may be copied only under the terms of the license found at\n\
+the top of every file in the asdcplib distribution kit.\n\n\
+Specify the -h (help) option for further information about %s\n\n",
+ PACKAGE, ASDCP::Version(), PACKAGE);
+}
+
+//
+void
+usage(FILE* stream = stderr)
+{
+ fprintf(stream, "\
+USAGE: %s [-v|-h[-d]] <filename>\n\
+\n\
+ -V - Show version\n\
+ -h - Show help\n\
+ -d <duration> - Number of 2k-sample frames to process, default 1440\n\
+\n\
+Other Options:\n\
+ -v - Verbose, show extra detail during run\n\
+\n\
+ NOTES: o There is no option grouping, all options must be distinct arguments.\n\
+ o All option arguments must be separated from the option by whitespace.\n\
+\n", PACKAGE);
+}
+
+//
+//
+class CommandOptions
+{
+ CommandOptions();
+
+public:
+ bool error_flag; // true if the given options are in error or not complete
+ bool verbose_flag; // true if the verbose option was selected
+ bool version_flag; // true if the version display option was selected
+ bool help_flag; // true if the help display option was selected
+ ui32_t duration; // number of frames to be processed
+ const char* filename; // filename prefix for files written by the extract mode
+
+ CommandOptions(int argc, const char** argv) :
+ error_flag(true), verbose_flag(false), version_flag(false), help_flag(false),
+ duration(1440), filename(0)
+ {
+ for ( int i = 1; i < argc; i++ )
+ {
+ if ( argv[i][0] == '-' && isalpha(argv[i][1]) && argv[i][2] == 0 )
+ {
+ switch ( argv[i][1] )
+ {
+ case 'V': version_flag = true; break;
+ case 'h': help_flag = true; break;
+ case 'v': verbose_flag = true; break;
+
+ case 'd':
+ TEST_EXTRA_ARG(i, 'd');
+ duration = atoi(argv[i]); // TODO: test for negative value, should use strtol()
+ break;
+
+ default:
+ fprintf(stderr, "Unrecognized option: %c\n", argv[i][1]);
+ return;
+ }
+ }
+ else
+ {
+ if ( filename )
+ {
+ fprintf(stderr, "Unexpected extra filename.\n");
+ return;
+ }
+
+ filename = argv[i];
+ }
+ }
+
+ if ( filename == 0 )
+ {
+ fputs("Output filename required.\n", stderr);
+ return;
+ }
+
+ error_flag = false;
+ }
+};
+
+
+//
+//
+Result_t
+make_black_wav_file(CommandOptions& Options)
+{
+ PCM::FrameBuffer FrameBuffer;
+ PCM::AudioDescriptor ADesc;
+
+ ADesc.SampleRate = Rational(24,1);
+ ADesc.AudioSamplingRate = ASDCP::SampleRate_48k;
+ ADesc.Locked = 0;
+ ADesc.ChannelCount = 1;
+ ADesc.QuantizationBits = 24;
+ ADesc.BlockAlign = 18;
+ ADesc.AvgBps = 86400;
+ ADesc.LinkedTrackID = 1;
+ ADesc.ContainerDuration = Options.duration;
+
+ // fill the frame buffer with a frame (2000 samples) of black
+ FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc));
+ memset(FrameBuffer.Data(), 0, FrameBuffer.Capacity());
+ FrameBuffer.Size(FrameBuffer.Capacity());
+
+ if ( 1 ) // Options.verbose_flag )
+ {
+ fprintf(stderr, "48Khz PCM Audio, %s fps (%lu spf)\n", "24",
+ PCM::CalcSamplesPerFrame(ADesc));
+ fputs("AudioDescriptor:\n", stderr);
+ PCM::AudioDescriptorDump(ADesc);
+ }
+
+ // set up output file
+ Kumu::FileWriter OutFile;
+ Result_t result = OutFile.OpenWrite(Options.filename);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ Wav::SimpleWaveHeader WavHeader(ADesc);
+ result = WavHeader.WriteToFile(OutFile);
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ ui32_t write_count = 0;
+ ui32_t duration = 0;
+
+ while ( ASDCP_SUCCESS(result) && (duration++ < Options.duration) )
+ {
+ result = OutFile.Write(FrameBuffer.Data(), FrameBuffer.Size(), &write_count);
+ }
+
+ if ( result == RESULT_ENDOFFILE )
+ result = RESULT_OK;
+ }
+
+ return RESULT_OK;
+}
+
+
+//
+int
+main(int argc, const char** argv)
+{
+ Result_t result = RESULT_OK;
+ CommandOptions Options(argc, argv);
+
+ if ( Options.help_flag )
+ {
+ usage();
+ return 0;
+ }
+
+ if ( Options.error_flag )
+ return 3;
+
+ if ( Options.version_flag )
+ banner();
+
+ else
+ result = make_black_wav_file(Options);
+
+ if ( result != RESULT_OK )
+ {
+ fputs("Program stopped on error.\n", stderr);
+
+ if ( result != RESULT_FAIL )
+ {
+ fputs(result, stderr);
+ fputc('\n', stderr);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+//
diff --git a/src/h__Reader.cpp b/src/h__Reader.cpp
index 7851953..268f308 100755
--- a/src/h__Reader.cpp
+++ b/src/h__Reader.cpp
@@ -112,15 +112,11 @@ ASDCP::h__Reader::OpenMXFRead(const char* filename)
// partition and read off the partition pack
if ( m_HeaderPart.m_RIP.PairArray.size() == 3 )
{
- fprintf(stderr, "Three part!\n");
Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
r_i++;
m_File.Seek((*r_i).ByteOffset);
result = m_BodyPart.InitFromFile(m_File);
- m_BodyPart.Dump();
- // TODO: check the partition pack to make sure it is
- // really a body with a single essence container
}
m_EssenceStart = m_File.Tell();
@@ -163,7 +159,7 @@ public:
inline const ui64_t Length() { return m_ValueLength; }
inline const ui64_t KLLength() { return m_KLLength; }
- Result_t ReadKLFromFile(ASDCP::FileReader& Reader)
+ Result_t ReadKLFromFile(Kumu::FileReader& Reader)
{
ui32_t read_count;
ui32_t header_length = SMPTE_UL_LENGTH + MXF_BER_LENGTH;
@@ -197,7 +193,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
// get frame position and go read the frame's key and length
Result_t result = RESULT_OK;
KLReader Reader;
- ASDCP::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset;
+ Kumu::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset;
if ( FilePosition != m_LastPosition )
{
@@ -244,7 +240,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
byte_t* ess_p = m_CtFrameBuf.Data();
// read context ID length
- if ( ! read_test_BER(&ess_p, UUIDlen) )
+ if ( ! Kumu::read_test_BER(&ess_p, UUIDlen) )
return RESULT_FORMAT;
// test the context ID
@@ -256,14 +252,14 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
ess_p += UUIDlen;
// read PlaintextOffset length
- if ( ! read_test_BER(&ess_p, sizeof(ui64_t)) )
+ if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
return RESULT_FORMAT;
- ui32_t PlaintextOffset = (ui32_t)ASDCP_i64_BE(cp2i<ui64_t>(ess_p));
+ ui32_t PlaintextOffset = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
ess_p += sizeof(ui64_t);
// read essence UL length
- if ( ! read_test_BER(&ess_p, SMPTE_UL_LENGTH) )
+ if ( ! Kumu::read_test_BER(&ess_p, SMPTE_UL_LENGTH) )
return RESULT_FORMAT;
// test essence UL
@@ -272,7 +268,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
char strbuf[IntBufferLen];
const MDDEntry* Entry = Dict::FindUL(Key.Value());
if ( Entry == 0 )
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.ToString(strbuf));
+ DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
else
DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
return RESULT_FORMAT;
@@ -280,10 +276,10 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
ess_p += SMPTE_UL_LENGTH;
// read SourceLength length
- if ( ! read_test_BER(&ess_p, sizeof(ui64_t)) )
+ if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
return RESULT_FORMAT;
- ui32_t SourceLength = (ui32_t)ASDCP_i64_BE(cp2i<ui64_t>(ess_p));
+ ui32_t SourceLength = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
ess_p += sizeof(ui64_t);
assert(SourceLength);
@@ -296,7 +292,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
ui32_t esv_length = calc_esv_length(SourceLength, PlaintextOffset);
// read ESV length
- if ( ! read_test_BER(&ess_p, esv_length) )
+ if ( ! Kumu::read_test_BER(&ess_p, esv_length) )
{
DefaultLogSink().Error("read_test_BER did not return %lu\n", esv_length);
return RESULT_FORMAT;
@@ -377,7 +373,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
char strbuf[IntBufferLen];
const MDDEntry* Entry = Dict::FindUL(Key.Value());
if ( Entry == 0 )
- DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.ToString(strbuf));
+ DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
else
DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
return RESULT_FORMAT;
diff --git a/src/h__Writer.cpp b/src/h__Writer.cpp
index 1449748..7d874c0 100755
--- a/src/h__Writer.cpp
+++ b/src/h__Writer.cpp
@@ -30,7 +30,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "AS_DCP_internal.h"
-#include "MemIO.h"
#include "KLV.h"
using namespace ASDCP;
@@ -120,7 +119,7 @@ ASDCP::h__Writer::WriteMXFHeader(const std::string& PackageLabel, const UL& Wrap
m_HeaderPart.AddChildObject(Ident);
m_HeaderPart.m_Preface->Identifications.push_back(Ident->InstanceUID);
- Ident->ThisGenerationUID.GenRandomValue();
+ Kumu::GenRandomValue(Ident->ThisGenerationUID);
Ident->CompanyName = m_Info.CompanyName.c_str();
Ident->ProductName = m_Info.ProductName.c_str();
Ident->VersionString = m_Info.ProductVersion.c_str();
@@ -315,11 +314,11 @@ Result_t
ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte_t* EssenceUL,
AESEncContext* Ctx, HMACContext* HMAC)
{
- Result_t result;
+ Result_t result = RESULT_OK;
IntegrityPack IntPack;
byte_t overhead[128];
- MemIOWriter Overhead(overhead, 128);
+ Kumu::MemIOWriter Overhead(overhead, 128);
if ( FrameBuf.Size() == 0 )
{
@@ -371,12 +370,12 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte
Overhead.WriteUi64BE(FrameBuf.Size()); // write SourceLength
Overhead.WriteBER(m_CtFrameBuf.Size(), MXF_BER_LENGTH); // write ESV length
- result = m_File.Writev(Overhead.Data(), Overhead.Size());
+ result = m_File.Writev(Overhead.Data(), Overhead.Length());
}
if ( ASDCP_SUCCESS(result) )
{
- m_StreamOffset += Overhead.Size();
+ m_StreamOffset += Overhead.Length();
// write encrypted source value
result = m_File.Writev((byte_t*)m_CtFrameBuf.RoData(), m_CtFrameBuf.Size());
}
@@ -386,7 +385,7 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte
m_StreamOffset += m_CtFrameBuf.Size();
byte_t hmoverhead[512];
- MemIOWriter HMACOverhead(hmoverhead, 512);
+ Kumu::MemIOWriter HMACOverhead(hmoverhead, 512);
// write the HMAC
if ( m_Info.UsesHMAC )
@@ -400,21 +399,21 @@ ASDCP::h__Writer::WriteEKLVPacket(const ASDCP::FrameBuffer& FrameBuf, const byte
}
// write HMAC
- result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Size());
- m_StreamOffset += HMACOverhead.Size();
+ result = m_File.Writev(HMACOverhead.Data(), HMACOverhead.Length());
+ m_StreamOffset += HMACOverhead.Length();
}
}
else
{
Overhead.WriteRaw((byte_t*)EssenceUL, SMPTE_UL_LENGTH);
Overhead.WriteBER(FrameBuf.Size(), MXF_BER_LENGTH);
- result = m_File.Writev(Overhead.Data(), Overhead.Size());
+ result = m_File.Writev(Overhead.Data(), Overhead.Length());
if ( ASDCP_SUCCESS(result) )
result = m_File.Writev((byte_t*)FrameBuf.RoData(), FrameBuf.Size());
if ( ASDCP_SUCCESS(result) )
- m_StreamOffset += Overhead.Size() + FrameBuf.Size();
+ m_StreamOffset += Overhead.Length() + FrameBuf.Size();
}
if ( ASDCP_SUCCESS(result) )
diff --git a/src/klvwalk.cpp b/src/klvwalk.cpp
index b5b3cea..395aa54 100755
--- a/src/klvwalk.cpp
+++ b/src/klvwalk.cpp
@@ -31,7 +31,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AS_DCP.h"
#include "MXF.h"
-#include "hex_utils.h"
+#include <KM_log.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
@@ -40,15 +40,14 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/stat.h>
using namespace ASDCP;
+using Kumu::DefaultLogSink;
+
+const char* PACKAGE = "klvwalk";
//------------------------------------------------------------------------------------------
//
-// There is no header file thet defines this function.
-// You just have to know it's there...
-void set_debug_mode(bool info_mode, bool debug_mode);
-
int
main(int argc, char** argv)
@@ -56,19 +55,24 @@ main(int argc, char** argv)
Result_t result = RESULT_OK;
bool read_mxf = false;
int arg_i = 1;
- set_debug_mode(true, true);
- if ( strcmp(argv[1], "-r") == 0 )
+ if ( argc > arg_i && strcmp(argv[1], "-r") == 0 )
{
read_mxf = true;
arg_i++;
}
+ if ( argc - arg_i != 1 )
+ {
+ fprintf(stderr, "usage: %s [-r] <infile>\n", PACKAGE);
+ return 1;
+ }
+
fprintf(stderr, "Opening file %s\n", argv[arg_i]);
if ( read_mxf )
{
- ASDCP::FileReader Reader;
+ Kumu::FileReader Reader;
ASDCP::MXF::OPAtomHeader Header;
result = Reader.OpenRead(argv[arg_i]);
@@ -95,7 +99,7 @@ main(int argc, char** argv)
}
else // dump klv
{
- ASDCP::FileReader Reader;
+ Kumu::FileReader Reader;
KLVFilePacket KP;
result = Reader.OpenRead(argv[arg_i]);
@@ -119,7 +123,7 @@ main(int argc, char** argv)
if ( result != RESULT_FAIL )
{
- fputs(GetResultString(result), stderr);
+ fputs(result, stderr);
fputc('\n', stderr);
}
diff --git a/src/wavesplit.cpp b/src/wavesplit.cpp
new file mode 100755
index 0000000..2a40e1e
--- /dev/null
+++ b/src/wavesplit.cpp
@@ -0,0 +1,369 @@
+/*
+Copyright (c) 2005-2006, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*! \file wavesplit.cpp
+ \version $Id$
+ \brief WAV file splitter
+*/
+
+#include <AS_DCP.h>
+#include <WavFileWriter.h>
+#include <assert.h>
+
+using namespace ASDCP;
+
+//------------------------------------------------------------------------------------------
+//
+// command line option parser class
+
+static const char* PACKAGE = "wavesplit"; // program name for messages
+
+// Macros used to test command option data state.
+
+// True if a major mode has already been selected.
+#define TEST_MAJOR_MODE() ( create_flag )
+
+// Causes the caller to return if a major mode has already been selected,
+// otherwise sets the given flag.
+#define TEST_SET_MAJOR_MODE(f) if ( TEST_MAJOR_MODE() ) \
+ { \
+ fputs("Conflicting major mode, choose one of -(ic)).\n", stderr); \
+ return; \
+ } \
+ (f) = true;
+
+// Increment the iterator, test for an additional non-option command line argument.
+// Causes the caller to return if there are no remaining arguments or if the next
+// argument begins with '-'.
+#define TEST_EXTRA_ARG(i,c) if ( ++i >= argc || argv[(i)][0] == '-' ) \
+ { \
+ fprintf(stderr, "Argument not found for option %c.\n", (c)); \
+ return; \
+ }
+//
+void
+banner(FILE* stream = stderr)
+{
+ fprintf(stream, "\n\
+%s (asdcplib %s)\n\n\
+Copyright (c) 2005-2006 John Hurst\n\n\
+wavesplit is part of asdcplib.\n\
+asdcplib may be copied only under the terms of the license found at\n\
+the top of every file in the asdcplib distribution kit.\n\n\
+Specify the -h (help) option for further information about %s\n\n",
+ PACKAGE, ASDCP::Version(), PACKAGE, PACKAGE);
+}
+
+//
+void
+usage(FILE* stream = stderr)
+{
+ fprintf(stream, "\
+USAGE: %s [-i|-c <root-name> [-v]] <filename>\n\
+\n\
+Major modes:\n\
+ -c <root-name> - Create a WAV file for each channel in the input file (default is two channel files)\n\
+ -V - Show version\n\
+ -h - Show help\n\
+\n\
+Read/Write Options:\n\
+ -f <frame-num> - Starting frame number, default 0\n\
+ -d <duration> - Number of frames to process, default all\n\
+ -v - Print extra info while processing\n\
+\n\
+ NOTES: o There is no option grouping, all options must be distinct arguments.\n\
+ o All option arguments must be separated from the option by whitespace.\n\
+\n", PACKAGE);
+}
+
+//
+//
+class CommandOptions
+{
+ CommandOptions();
+
+public:
+ bool error_flag; // true if the given options are in error or not complete
+ bool create_flag; // true if the file create mode was selected
+ bool version_flag; // true if the version display option was selected
+ bool help_flag; // true if the help display option was selected
+ bool verbose_flag; // true for extra info during procesing
+ ui32_t start_frame; // frame number to begin processing
+ ui32_t duration; // number of frames to be processed
+ const char* file_root; // filename prefix for files written by the extract mode
+ const char* filename; // filename to be processed
+
+ CommandOptions(int argc, const char** argv) :
+ error_flag(true), create_flag(false),
+ version_flag(false), help_flag(false), start_frame(0),
+ duration(0xffffffff), file_root(0), filename(0)
+ {
+ for ( int i = 1; i < argc; i++ )
+ {
+ if ( argv[i][0] == '-' && isalpha(argv[i][1]) && argv[i][2] == 0 )
+ {
+ switch ( argv[i][1] )
+ {
+ case 'V': version_flag = true; break;
+ case 'h': help_flag = true; break;
+ case 'c':
+ TEST_SET_MAJOR_MODE(create_flag);
+ TEST_EXTRA_ARG(i, 'c');
+ file_root = argv[i];
+ break;
+
+ case 'f':
+ TEST_EXTRA_ARG(i, 'f');
+ start_frame = atoi(argv[i]); // TODO: test for negative value, should use strtol()
+ break;
+
+ case 'd':
+ TEST_EXTRA_ARG(i, 'd');
+ duration = atoi(argv[i]); // TODO: test for negative value, should use strtol()
+ break;
+
+ default:
+ fprintf(stderr, "Unrecognized option: %c\n", argv[i][1]);
+ return;
+ }
+ }
+ else
+ {
+ if ( filename )
+ {
+ fprintf(stderr, "Unexpected extra filename.\n");
+ return;
+ }
+
+ filename = argv[i];
+ }
+ }
+
+ if ( TEST_MAJOR_MODE() )
+ {
+ if ( filename == 0 )
+ {
+ fputs("Input filename required.\n", stderr);
+ return;
+ }
+ }
+
+ if ( ! TEST_MAJOR_MODE() && ! help_flag && ! version_flag )
+ {
+ fputs("No operation selected (use one of -(ic) or -h for help).\n", stderr);
+ return;
+ }
+
+ error_flag = false;
+ }
+};
+
+
+//
+//
+void
+split_buffer(ui32_t sample_size, PCM::FrameBuffer& FrameBuffer,
+ PCM::FrameBuffer& L_FrameBuffer, PCM::FrameBuffer& R_FrameBuffer)
+{
+ assert((FrameBuffer.Size() % 2) == 0);
+ byte_t* p = FrameBuffer.Data();
+ byte_t* end_p = p + FrameBuffer.Size();
+ byte_t* lp = L_FrameBuffer.Data();
+ byte_t* rp = R_FrameBuffer.Data();
+
+ for ( ; p < end_p; )
+ {
+ memcpy(lp, p, sample_size);
+ lp += sample_size;
+ p += sample_size;
+ memcpy(rp, p, sample_size);
+ rp += sample_size;
+ p += sample_size;
+ }
+
+ L_FrameBuffer.Size(L_FrameBuffer.Capacity());
+ R_FrameBuffer.Size(R_FrameBuffer.Capacity());
+}
+
+
+//
+//
+Result_t
+split_wav_file(CommandOptions& Options)
+{
+ PCM::FrameBuffer FrameBuffer;
+ PCM::FrameBuffer L_FrameBuffer;
+ PCM::FrameBuffer R_FrameBuffer;
+ PCM::AudioDescriptor ADesc;
+ Rational PictureRate = EditRate_24;
+ PCM::WAVParser Parser;
+
+ // set up essence parser
+ Result_t result = Parser.OpenRead(Options.filename, PictureRate);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ Parser.FillAudioDescriptor(ADesc);
+
+ ADesc.SampleRate = PictureRate;
+ ui32_t fb_size = PCM::CalcFrameBufferSize(ADesc);
+ assert((fb_size % 2) == 0);
+ FrameBuffer.Capacity(fb_size);
+ L_FrameBuffer.Capacity(fb_size/2);
+ R_FrameBuffer.Capacity(fb_size/2);
+
+ if ( Options.verbose_flag )
+ {
+ fprintf(stderr, "48Khz PCM Audio, %s fps (%lu spf)\n", "24",
+ PCM::CalcSamplesPerFrame(ADesc));
+ fputs("AudioDescriptor:\n", stderr);
+ PCM::AudioDescriptorDump(ADesc);
+ }
+
+ ADesc.ChannelCount = 1;
+ }
+
+ // set up output files
+ Kumu::FileWriter L_OutFile;
+ Kumu::FileWriter R_OutFile;
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ char filename[256];
+ sprintf(filename, "%s_l.wav", Options.file_root);
+ result = L_OutFile.OpenWrite(filename);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ sprintf(filename, "%s_r.wav", Options.file_root);
+ result = R_OutFile.OpenWrite(filename);
+ }
+ }
+
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ Wav::SimpleWaveHeader WavHeader(ADesc);
+ result = WavHeader.WriteToFile(L_OutFile);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = WavHeader.WriteToFile(R_OutFile);
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ ui32_t write_count = 0;
+ ui32_t duration = 0;
+
+ while ( ASDCP_SUCCESS(result) && (duration++ < Options.duration) )
+ {
+ result = Parser.ReadFrame(FrameBuffer);
+
+ if ( FrameBuffer.Size() != FrameBuffer.Capacity() )
+ {
+ fprintf(stderr, "WARNING: Last frame read was short, PCM input is possibly not frame aligned.\n");
+ fprintf(stderr, "Expecting %lu bytes, got %lu.\n", FrameBuffer.Capacity(), FrameBuffer.Size());
+ result = RESULT_ENDOFFILE;
+ continue;
+ }
+
+ if ( Options.verbose_flag )
+ FrameBuffer.Dump(stderr);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ split_buffer(PCM::CalcSampleSize(ADesc), FrameBuffer, L_FrameBuffer, R_FrameBuffer);
+ result = L_OutFile.Write(L_FrameBuffer.Data(), L_FrameBuffer.Size(), &write_count);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = R_OutFile.Write(R_FrameBuffer.Data(), R_FrameBuffer.Size(), &write_count);
+ }
+ }
+
+ if ( result == RESULT_ENDOFFILE )
+ result = RESULT_OK;
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ ADesc.ContainerDuration = duration;
+ Wav::SimpleWaveHeader WavHeader(ADesc);
+ L_OutFile.Seek();
+
+ if ( ASDCP_SUCCESS(result) )
+ result = R_OutFile.Seek();
+
+ if ( ASDCP_SUCCESS(result) )
+ result = WavHeader.WriteToFile(L_OutFile);
+
+ if ( ASDCP_SUCCESS(result) )
+ result = WavHeader.WriteToFile(R_OutFile);
+ }
+ }
+
+ return RESULT_OK;
+}
+
+
+//
+int
+main(int argc, const char** argv)
+{
+ Result_t result = RESULT_OK;
+ CommandOptions Options(argc, argv);
+
+ if ( Options.help_flag )
+ {
+ usage();
+ return 0;
+ }
+
+ if ( Options.error_flag )
+ return 3;
+
+ if ( Options.version_flag )
+ banner();
+
+ if ( Options.create_flag )
+ result = split_wav_file(Options);
+
+ if ( result != RESULT_OK )
+ {
+ fputs("Program stopped on error.\n", stderr);
+
+ if ( result != RESULT_FAIL )
+ {
+ fputs(result, stderr);
+ fputc('\n', stderr);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+//