Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,21 @@ endif()
set (HEADERS
kaitai/kaitaistream.h
kaitai/kaitaistruct.h
kaitai/kio.h
kaitai/kistream.h
kaitai/kostream.h
)

set (SOURCES
kaitai/kaitaistream.cpp
kaitai/kio.cpp
kaitai/kistream.cpp
kaitai/kostream.cpp
)

set(STRING_ENCODING_TYPE "ICONV" CACHE STRING "Set the way strings have to be encoded (ICONV|NONE|...)")

add_library (${PROJECT_NAME} SHARED ${HEADERS} ${SOURCES})
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "kaitai/kaitaistream.h;kaitai/kaitaistruct.h")
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "kaitai/kaitaistream.h;kaitai/kaitaistruct.h;kaitai/kio.h;kaitai/kistream.h")

if (ZLIB_FOUND)
target_include_directories(${PROJECT_NAME} PRIVATE ${ZLIB_INCLUDE_DIRS})
Expand Down
26 changes: 26 additions & 0 deletions kaitai/endian.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef KAITAI_ENDIAN_H
#define KAITAI_ENDIAN_H

#if defined(__APPLE__)
#include <machine/endian.h>
#include <libkern/OSByteOrder.h>
#define bswap_16(x) OSSwapInt16(x)
#define bswap_32(x) OSSwapInt32(x)
#define bswap_64(x) OSSwapInt64(x)
#define __BIG_ENDIAN BIG_ENDIAN
#define __LITTLE_ENDIAN LITTLE_ENDIAN
#define __BYTE_ORDER BYTE_ORDER
#elif defined(_MSC_VER) // !__APPLE__
#include <stdlib.h>
#define bswap_16(x) _byteswap_ushort(x)
#define bswap_32(x) _byteswap_ulong(x)
#define bswap_64(x) _byteswap_uint64(x)
#define __BIG_ENDIAN 4321
#define __LITTLE_ENDIAN 1234
#define __BYTE_ORDER __LITTLE_ENDIAN
#else // !__APPLE__ or !_MSC_VER
#include <endian.h>
#include <byteswap.h>
#endif

#endif
6 changes: 3 additions & 3 deletions kaitai/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class undecided_endianness_error: public kstruct_error {
*/
class validation_failed_error: public kstruct_error {
public:
validation_failed_error(const std::string what, const kstream* io, const std::string src_path):
validation_failed_error(const std::string what, const kistream* io, const std::string src_path):
kstruct_error(std::string("at pos ") + /*std::to_string(io->pos())*/ + ": validation failed:" + what, src_path),
m_io(io)
{
Expand All @@ -52,7 +52,7 @@ class validation_failed_error: public kstruct_error {
// "at pos #{io.pos}: validation failed: #{msg}"

protected:
const kstream* m_io;
const kistream* m_io;
};

/**
Expand All @@ -62,7 +62,7 @@ class validation_failed_error: public kstruct_error {
template<typename T>
class validation_not_equal_error: public validation_failed_error {
public:
validation_not_equal_error<T>(const T& expected, const T& actual, const kstream* io, const std::string src_path):
validation_not_equal_error<T>(const T& expected, const T& actual, const kistream* io, const std::string src_path):
validation_failed_error("not equal", io, src_path),
m_expected(expected),
m_actual(actual)
Expand Down
243 changes: 5 additions & 238 deletions kaitai/kaitaistream.h
Original file line number Diff line number Diff line change
@@ -1,249 +1,16 @@
#ifndef KAITAI_STREAM_H
#define KAITAI_STREAM_H

#include "kistream.h"

// Kaitai Struct runtime API version: x.y.z = 'xxxyyyzzz' decimal
#define KAITAI_STRUCT_VERSION 9000L

#include <istream>
#include <sstream>
#include <stdint.h>
#include <sys/types.h>

namespace kaitai {

/**
* Kaitai Stream class (kaitai::kstream) is an implementation of
* <a href="https://github.com/kaitai-io/kaitai_struct/wiki/Kaitai-Struct-stream-API">Kaitai Struct stream API</a>
* for C++/STL. It's implemented as a wrapper over generic STL std::istream.
*
* It provides a wide variety of simple methods to read (parse) binary
* representations of primitive types, such as integer and floating
* point numbers, byte arrays and strings, and also provides stream
* positioning / navigation methods with unified cross-language and
* cross-toolkit semantics.
*
* Typically, end users won't access Kaitai Stream class manually, but would
* describe a binary structure format using .ksy language and then would use
* Kaitai Struct compiler to generate source code in desired target language.
* That code, in turn, would use this class and API to do the actual parsing
* job.
*/
class kstream {
public:
/**
* Constructs new Kaitai Stream object, wrapping a given std::istream.
* \param io istream object to use for this Kaitai Stream
*/
kstream(std::istream* io);

/**
* Constructs new Kaitai Stream object, wrapping a given in-memory data
* buffer.
* \param data data buffer to use for this Kaitai Stream
*/
kstream(std::string& data);

void close();

/** @name Stream positioning */
//@{
/**
* Check if stream pointer is at the end of stream. Note that the semantics
* are different from traditional STL semantics: one does *not* need to do a
* read (which will fail) after the actual end of the stream to trigger EOF
* flag, which can be accessed after that read. It is sufficient to just be
* at the end of the stream for this method to return true.
* \return "true" if we are located at the end of the stream.
*/
bool is_eof() const;

/**
* Set stream pointer to designated position.
* \param pos new position (offset in bytes from the beginning of the stream)
*/
void seek(uint64_t pos);

/**
* Get current position of a stream pointer.
* \return pointer position, number of bytes from the beginning of the stream
*/
uint64_t pos();

/**
* Get total size of the stream in bytes.
* \return size of the stream in bytes
*/
uint64_t size();
//@}

/** @name Integer numbers */
//@{

// ------------------------------------------------------------------------
// Signed
// ------------------------------------------------------------------------

int8_t read_s1();

// ........................................................................
// Big-endian
// ........................................................................

int16_t read_s2be();
int32_t read_s4be();
int64_t read_s8be();

// ........................................................................
// Little-endian
// ........................................................................

int16_t read_s2le();
int32_t read_s4le();
int64_t read_s8le();

// ------------------------------------------------------------------------
// Unsigned
// ------------------------------------------------------------------------

uint8_t read_u1();

// ........................................................................
// Big-endian
// ........................................................................

uint16_t read_u2be();
uint32_t read_u4be();
uint64_t read_u8be();

// ........................................................................
// Little-endian
// ........................................................................

uint16_t read_u2le();
uint32_t read_u4le();
uint64_t read_u8le();

//@}

/** @name Floating point numbers */
//@{

// ........................................................................
// Big-endian
// ........................................................................

float read_f4be();
double read_f8be();

// ........................................................................
// Little-endian
// ........................................................................

float read_f4le();
double read_f8le();

//@}

/** @name Unaligned bit values */
//@{

void align_to_byte();
uint64_t read_bits_int(int n);

//@}

/** @name Byte arrays */
//@{

std::string read_bytes(std::streamsize len);
std::string read_bytes_full();
std::string read_bytes_term(char term, bool include, bool consume, bool eos_error);
std::string ensure_fixed_contents(std::string expected);

static std::string bytes_strip_right(std::string src, char pad_byte);
static std::string bytes_terminate(std::string src, char term, bool include);
static std::string bytes_to_str(std::string src, std::string src_enc);

//@}

/** @name Byte array processing */
//@{

/**
* Performs a XOR processing with given data, XORing every byte of input with a single
* given value.
* @param data data to process
* @param key value to XOR with
* @return processed data
*/
static std::string process_xor_one(std::string data, uint8_t key);

/**
* Performs a XOR processing with given data, XORing every byte of input with a key
* array, repeating key array many times, if necessary (i.e. if data array is longer
* than key array).
* @param data data to process
* @param key array of bytes to XOR with
* @return processed data
*/
static std::string process_xor_many(std::string data, std::string key);

/**
* Performs a circular left rotation shift for a given buffer by a given amount of bits,
* using groups of 1 bytes each time. Right circular rotation should be performed
* using this procedure with corrected amount.
* @param data source data to process
* @param amount number of bits to shift by
* @return copy of source array with requested shift applied
*/
static std::string process_rotate_left(std::string data, int amount);

#ifdef KS_ZLIB
/**
* Performs an unpacking ("inflation") of zlib-compressed data with usual zlib headers.
* @param data data to unpack
* @return unpacked data
* @throws IOException
*/
static std::string process_zlib(std::string data);
#endif

//@}

/**
* Performs modulo operation between two integers: dividend `a`
* and divisor `b`. Divisor `b` is expected to be positive. The
* result is always 0 <= x <= b - 1.
*/
static int mod(int a, int b);

/**
* Converts given integer `val` to a decimal string representation.
* Should be used in place of std::to_string() (which is available only
* since C++11) in older C++ implementations.
*/
static std::string to_string(int val);

/**
* Reverses given string `val`, so that the first character becomes the
* last and the last one becomes the first. This should be used to avoid
* the need of local variables at the caller.
*/
static std::string reverse(std::string val);

private:
std::istream* m_io;
std::istringstream m_io_str;
int m_bits_left;
uint64_t m_bits;

void init();
void exceptions_enable() const;

static uint64_t get_mask_ones(int n);

static const int ZLIB_BUF_SIZE = 128 * 1024;
};
// This typedef exists for API compatibility with previous versions of the
// KaitaiStruct C++ runtime.
typedef kistream kstream;

}

Expand Down
6 changes: 3 additions & 3 deletions kaitai/kaitaistruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ namespace kaitai {

class kstruct {
public:
kstruct(kstream *_io) { m__io = _io; }
kstruct(kistream *_io) { m__io = _io; }
virtual ~kstruct() {}
protected:
kstream *m__io;
kistream *m__io;
public:
kstream *_io() { return m__io; }
kistream *_io() { return m__io; }
};

}
Expand Down
Loading