Skip to content

Commit

Permalink
Implement write support for some primitives.
Browse files Browse the repository at this point in the history
This should be enough to enable serialization of very basic seqs for the
C++ code generator in the future.
  • Loading branch information
jchv committed Sep 7, 2019
1 parent 8b83281 commit d853591
Show file tree
Hide file tree
Showing 3 changed files with 299 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ set (HEADERS
kaitai/kaitaistruct.h
kaitai/kio.h
kaitai/kistream.h
kaitai/kostream.h
)

set (SOURCES
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|...)")
Expand Down
178 changes: 178 additions & 0 deletions kaitai/kostream.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#include <kaitai/kostream.h>
#include <kaitai/endian.h>

#include <iostream>
#include <vector>
#include <stdexcept>

kaitai::kostream::kostream(std::ostream* io): kio(io) {
m_io = io;
}

// ========================================================================
// Integer numbers
// ========================================================================

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

void kaitai::kostream::write_s1(int8_t t) {
m_io->put(t);
}

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

void kaitai::kostream::write_s2be(int16_t t) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
t = bswap_16(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 2);
}

void kaitai::kostream::write_s4be(int32_t t) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
t = bswap_32(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 4);
}

void kaitai::kostream::write_s8be(int64_t t) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
t = bswap_64(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 8);
}

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

void kaitai::kostream::write_s2le(int16_t t) {
#if __BYTE_ORDER == __BIG_ENDIAN
t = bswap_16(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 2);
}

void kaitai::kostream::write_s4le(int32_t t) {
#if __BYTE_ORDER == __BIG_ENDIAN
t = bswap_32(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 4);
}

void kaitai::kostream::write_s8le(int64_t t) {
#if __BYTE_ORDER == __BIG_ENDIAN
t = bswap_64(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 8);
}

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

void kaitai::kostream::write_u1(uint8_t t) {
m_io->put(t);
}

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

void kaitai::kostream::write_u2be(uint16_t t) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
t = bswap_16(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 8);
}

void kaitai::kostream::write_u4be(uint32_t t) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
t = bswap_32(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 8);
}

void kaitai::kostream::write_u8be(uint64_t t) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
t = bswap_64(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 8);
}

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

void kaitai::kostream::write_u2le(uint16_t t) {
#if __BYTE_ORDER == __BIG_ENDIAN
t = bswap_16(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 2);
}

void kaitai::kostream::write_u4le(uint32_t t) {
#if __BYTE_ORDER == __BIG_ENDIAN
t = bswap_32(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 4);
}

void kaitai::kostream::write_u8le(uint64_t t) {
#if __BYTE_ORDER == __BIG_ENDIAN
t = bswap_64(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 8);
}

// ========================================================================
// Floating point numbers
// ========================================================================

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

void kaitai::kostream::write_f4be(float t) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
t = bswap_32(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 4);
}

void kaitai::kostream::write_f8be(double t) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
t = bswap_64(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 8);
}

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

void kaitai::kostream::write_f4le(float t) {
#if __BYTE_ORDER == __BIG_ENDIAN
t = bswap_32(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 4);
}

void kaitai::kostream::write_f8le(double t) {
#if __BYTE_ORDER == __BIG_ENDIAN
t = bswap_64(t);
#endif
m_io->write(reinterpret_cast<char *>(&t), 8);
}

// ========================================================================
// Byte arrays
// ========================================================================

void kaitai::kostream::write_bytes(std::string bytes) {
m_io->write(bytes.data(), bytes.length());
}
119 changes: 119 additions & 0 deletions kaitai/kostream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#ifndef KAITAI_KOSTREAM_H
#define KAITAI_KOSTREAM_H

#include <kaitai/kio.h>

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

namespace kaitai {

/**
* Kaitai Output Stream class (kaitai::kostream) 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, for serialization. It's implemented as a wrapper over generic
* STL std::ostream.
*
* It provides a wide variety of simple methods to write (serialize) binary
* representations of primitive types, such as integer and floating
* point numbers, byte arrays and strings, with unified cross-language and
* cross-toolkit semantics.
*
* Typically, end users won't access Kaitai Stream classes 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 kostream : public virtual kio {
public:
/**
* Constructs new Kaitai Stream object, wrapping a given std::istream.
* \param io istream object to use for this Kaitai Stream
*/
kostream(std::ostream* io);

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

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

void write_s1(int8_t t);

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

void write_s2be(int16_t t);
void write_s4be(int32_t t);
void write_s8be(int64_t t);

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

void write_s2le(int16_t t);
void write_s4le(int32_t t);
void write_s8le(int64_t t);

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

void write_u1(uint8_t t);

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

void write_u2be(uint16_t t);
void write_u4be(uint32_t t);
void write_u8be(uint64_t t);

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

void write_u2le(uint16_t t);
void write_u4le(uint32_t t);
void write_u8le(uint64_t t);

//@}

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

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

void write_f4be(float t);
void write_f8be(double t);

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

void write_f4le(float t);
void write_f8le(double t);

//@}

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

void write_bytes(std::string bytes);

//@}

private:
std::ostream* m_io;
};

}

#endif

0 comments on commit d853591

Please sign in to comment.