Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for serialization #30

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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