Skip to content

Commit b2f126c

Browse files
committed
Implement write support for some primitives.
This should be enough to enable serialization of very basic seqs for the C++ code generator in the future.
1 parent 8f5b5e3 commit b2f126c

File tree

3 files changed

+299
-0
lines changed

3 files changed

+299
-0
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ set (HEADERS
2020
kaitai/kaitaistruct.h
2121
kaitai/kio.h
2222
kaitai/kistream.h
23+
kaitai/kostream.h
2324
)
2425

2526
set (SOURCES
2627
kaitai/kio.cpp
2728
kaitai/kistream.cpp
29+
kaitai/kostream.cpp
2830
)
2931

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

kaitai/kostream.cpp

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#include <kaitai/kostream.h>
2+
#include <kaitai/endian.h>
3+
4+
#include <iostream>
5+
#include <vector>
6+
#include <stdexcept>
7+
8+
kaitai::kostream::kostream(std::ostream* io): kio(io) {
9+
m_io = io;
10+
}
11+
12+
// ========================================================================
13+
// Integer numbers
14+
// ========================================================================
15+
16+
// ------------------------------------------------------------------------
17+
// Signed
18+
// ------------------------------------------------------------------------
19+
20+
void kaitai::kostream::write_s1(int8_t t) {
21+
m_io->put(t);
22+
}
23+
24+
// ........................................................................
25+
// Big-endian
26+
// ........................................................................
27+
28+
void kaitai::kostream::write_s2be(int16_t t) {
29+
#if __BYTE_ORDER == __LITTLE_ENDIAN
30+
t = bswap_16(t);
31+
#endif
32+
m_io->write(reinterpret_cast<char *>(&t), 2);
33+
}
34+
35+
void kaitai::kostream::write_s4be(int32_t t) {
36+
#if __BYTE_ORDER == __LITTLE_ENDIAN
37+
t = bswap_32(t);
38+
#endif
39+
m_io->write(reinterpret_cast<char *>(&t), 4);
40+
}
41+
42+
void kaitai::kostream::write_s8be(int64_t t) {
43+
#if __BYTE_ORDER == __LITTLE_ENDIAN
44+
t = bswap_64(t);
45+
#endif
46+
m_io->write(reinterpret_cast<char *>(&t), 8);
47+
}
48+
49+
// ........................................................................
50+
// Little-endian
51+
// ........................................................................
52+
53+
void kaitai::kostream::write_s2le(int16_t t) {
54+
#if __BYTE_ORDER == __BIG_ENDIAN
55+
t = bswap_16(t);
56+
#endif
57+
m_io->write(reinterpret_cast<char *>(&t), 2);
58+
}
59+
60+
void kaitai::kostream::write_s4le(int32_t t) {
61+
#if __BYTE_ORDER == __BIG_ENDIAN
62+
t = bswap_32(t);
63+
#endif
64+
m_io->write(reinterpret_cast<char *>(&t), 4);
65+
}
66+
67+
void kaitai::kostream::write_s8le(int64_t t) {
68+
#if __BYTE_ORDER == __BIG_ENDIAN
69+
t = bswap_64(t);
70+
#endif
71+
m_io->write(reinterpret_cast<char *>(&t), 8);
72+
}
73+
74+
// ------------------------------------------------------------------------
75+
// Unsigned
76+
// ------------------------------------------------------------------------
77+
78+
void kaitai::kostream::write_u1(uint8_t t) {
79+
m_io->put(t);
80+
}
81+
82+
// ........................................................................
83+
// Big-endian
84+
// ........................................................................
85+
86+
void kaitai::kostream::write_u2be(uint16_t t) {
87+
#if __BYTE_ORDER == __LITTLE_ENDIAN
88+
t = bswap_16(t);
89+
#endif
90+
m_io->write(reinterpret_cast<char *>(&t), 8);
91+
}
92+
93+
void kaitai::kostream::write_u4be(uint32_t t) {
94+
#if __BYTE_ORDER == __LITTLE_ENDIAN
95+
t = bswap_32(t);
96+
#endif
97+
m_io->write(reinterpret_cast<char *>(&t), 8);
98+
}
99+
100+
void kaitai::kostream::write_u8be(uint64_t t) {
101+
#if __BYTE_ORDER == __LITTLE_ENDIAN
102+
t = bswap_64(t);
103+
#endif
104+
m_io->write(reinterpret_cast<char *>(&t), 8);
105+
}
106+
107+
// ........................................................................
108+
// Little-endian
109+
// ........................................................................
110+
111+
void kaitai::kostream::write_u2le(uint16_t t) {
112+
#if __BYTE_ORDER == __BIG_ENDIAN
113+
t = bswap_16(t);
114+
#endif
115+
m_io->write(reinterpret_cast<char *>(&t), 2);
116+
}
117+
118+
void kaitai::kostream::write_u4le(uint32_t t) {
119+
#if __BYTE_ORDER == __BIG_ENDIAN
120+
t = bswap_32(t);
121+
#endif
122+
m_io->write(reinterpret_cast<char *>(&t), 4);
123+
}
124+
125+
void kaitai::kostream::write_u8le(uint64_t t) {
126+
#if __BYTE_ORDER == __BIG_ENDIAN
127+
t = bswap_64(t);
128+
#endif
129+
m_io->write(reinterpret_cast<char *>(&t), 8);
130+
}
131+
132+
// ========================================================================
133+
// Floating point numbers
134+
// ========================================================================
135+
136+
// ........................................................................
137+
// Big-endian
138+
// ........................................................................
139+
140+
void kaitai::kostream::write_f4be(float t) {
141+
#if __BYTE_ORDER == __LITTLE_ENDIAN
142+
t = bswap_32(t);
143+
#endif
144+
m_io->write(reinterpret_cast<char *>(&t), 4);
145+
}
146+
147+
void kaitai::kostream::write_f8be(double t) {
148+
#if __BYTE_ORDER == __LITTLE_ENDIAN
149+
t = bswap_64(t);
150+
#endif
151+
m_io->write(reinterpret_cast<char *>(&t), 8);
152+
}
153+
154+
// ........................................................................
155+
// Little-endian
156+
// ........................................................................
157+
158+
void kaitai::kostream::write_f4le(float t) {
159+
#if __BYTE_ORDER == __BIG_ENDIAN
160+
t = bswap_32(t);
161+
#endif
162+
m_io->write(reinterpret_cast<char *>(&t), 4);
163+
}
164+
165+
void kaitai::kostream::write_f8le(double t) {
166+
#if __BYTE_ORDER == __BIG_ENDIAN
167+
t = bswap_64(t);
168+
#endif
169+
m_io->write(reinterpret_cast<char *>(&t), 8);
170+
}
171+
172+
// ========================================================================
173+
// Byte arrays
174+
// ========================================================================
175+
176+
void kaitai::kostream::write_bytes(std::string bytes) {
177+
m_io->write(bytes.data(), bytes.length());
178+
}

kaitai/kostream.h

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#ifndef KAITAI_KOSTREAM_H
2+
#define KAITAI_KOSTREAM_H
3+
4+
#include <kaitai/kio.h>
5+
6+
#include <istream>
7+
#include <sstream>
8+
#include <stdint.h>
9+
#include <sys/types.h>
10+
11+
namespace kaitai {
12+
13+
/**
14+
* Kaitai Output Stream class (kaitai::kostream) is an implementation of
15+
* <a href="https://github.com/kaitai-io/kaitai_struct/wiki/Kaitai-Struct-stream-API">Kaitai Struct stream API</a>
16+
* for C++/STL, for serialization. It's implemented as a wrapper over generic
17+
* STL std::ostream.
18+
*
19+
* It provides a wide variety of simple methods to write (serialize) binary
20+
* representations of primitive types, such as integer and floating
21+
* point numbers, byte arrays and strings, with unified cross-language and
22+
* cross-toolkit semantics.
23+
*
24+
* Typically, end users won't access Kaitai Stream classes manually, but would
25+
* describe a binary structure format using .ksy language and then would use
26+
* Kaitai Struct compiler to generate source code in desired target language.
27+
* That code, in turn, would use this class and API to do the actual parsing
28+
* job.
29+
*/
30+
class kostream : public virtual kio {
31+
public:
32+
/**
33+
* Constructs new Kaitai Stream object, wrapping a given std::istream.
34+
* \param io istream object to use for this Kaitai Stream
35+
*/
36+
kostream(std::ostream* io);
37+
38+
/** @name Integer numbers */
39+
//@{
40+
41+
// ------------------------------------------------------------------------
42+
// Signed
43+
// ------------------------------------------------------------------------
44+
45+
void write_s1(int8_t t);
46+
47+
// ........................................................................
48+
// Big-endian
49+
// ........................................................................
50+
51+
void write_s2be(int16_t t);
52+
void write_s4be(int32_t t);
53+
void write_s8be(int64_t t);
54+
55+
// ........................................................................
56+
// Little-endian
57+
// ........................................................................
58+
59+
void write_s2le(int16_t t);
60+
void write_s4le(int32_t t);
61+
void write_s8le(int64_t t);
62+
63+
// ------------------------------------------------------------------------
64+
// Unsigned
65+
// ------------------------------------------------------------------------
66+
67+
void write_u1(uint8_t t);
68+
69+
// ........................................................................
70+
// Big-endian
71+
// ........................................................................
72+
73+
void write_u2be(uint16_t t);
74+
void write_u4be(uint32_t t);
75+
void write_u8be(uint64_t t);
76+
77+
// ........................................................................
78+
// Little-endian
79+
// ........................................................................
80+
81+
void write_u2le(uint16_t t);
82+
void write_u4le(uint32_t t);
83+
void write_u8le(uint64_t t);
84+
85+
//@}
86+
87+
/** @name Floating point numbers */
88+
//@{
89+
90+
// ........................................................................
91+
// Big-endian
92+
// ........................................................................
93+
94+
void write_f4be(float t);
95+
void write_f8be(double t);
96+
97+
// ........................................................................
98+
// Little-endian
99+
// ........................................................................
100+
101+
void write_f4le(float t);
102+
void write_f8le(double t);
103+
104+
//@}
105+
106+
/** @name Byte arrays */
107+
//@{
108+
109+
void write_bytes(std::string bytes);
110+
111+
//@}
112+
113+
private:
114+
std::ostream* m_io;
115+
};
116+
117+
}
118+
119+
#endif

0 commit comments

Comments
 (0)