Skip to content

Commit 55674d7

Browse files
authored
Merge pull request #13 from brwarner/platform
InkBin Header (#8)
2 parents d2a73b2 + b1d6085 commit 55674d7

9 files changed

Lines changed: 109 additions & 8 deletions

File tree

inkcpp/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ list(APPEND SOURCES
1717
system.cpp
1818
value.h value.cpp
1919
string_table.h string_table.cpp avl_array.h
20+
header.cpp
2021
)
2122
source_group(Collections REGULAR_EXPRESSION collections/.*)
2223
add_library(inkcpp ${SOURCES})
@@ -36,4 +37,4 @@ install(TARGETS inkcpp DESTINATION lib)
3637

3738
# Unreal installation
3839
install(DIRECTORY "include/" DESTINATION "inkcpp/Source/inkcpp/Public/ink/" COMPONENT unreal)
39-
install(FILES ${SOURCES} DESTINATION "inkcpp/Source/inkcpp/Private/ink/" COMPONENT unreal)
40+
install(FILES ${SOURCES} DESTINATION "inkcpp/Source/inkcpp/Private/ink/" COMPONENT unreal)

inkcpp/header.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "header.h"
2+
#include "version.h"
3+
4+
namespace ink::internal {
5+
6+
header header::parse_header(const char *data)
7+
{
8+
header res;
9+
const char* ptr = data;
10+
res.endien = *reinterpret_cast<const header::endian_types*>(ptr);
11+
ptr += sizeof(header::endian_types);
12+
13+
using v_t = decltype(header::ink_version_number);
14+
using vcpp_t = decltype(header::ink_bin_version_number);
15+
16+
if (res.endien == header::endian_types::same) {
17+
res.ink_version_number =
18+
*reinterpret_cast<const v_t*>(ptr);
19+
ptr += sizeof(v_t);
20+
res.ink_bin_version_number =
21+
*reinterpret_cast<const vcpp_t*>(ptr);
22+
23+
} else if (res.endien == header::endian_types::differ) {
24+
res.ink_version_number =
25+
swap_bytes(*reinterpret_cast<const v_t*>(ptr));
26+
ptr += sizeof(v_t);
27+
res.ink_bin_version_number =
28+
swap_bytes(*reinterpret_cast<const vcpp_t*>(ptr));
29+
} else {
30+
throw ink_exception("Failed to parse endian encoding!");
31+
}
32+
33+
if (res.ink_bin_version_number != InkBinVersion) {
34+
throw ink_exception("InkCpp-version mismatch: file was compiled with different InkCpp-version!");
35+
}
36+
return res;
37+
}
38+
}

inkcpp/runner_impl.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "command.h"
44
#include "choice.h"
55
#include "globals_impl.h"
6+
#include "header.h"
67

78
namespace ink::runtime
89
{
@@ -23,11 +24,15 @@ namespace ink::runtime::internal
2324
template<typename T>
2425
inline T runner_impl::read()
2526
{
27+
using header = ink::internal::header;
2628
// Sanity
2729
inkAssert(_ptr + sizeof(T) <= _story->end(), "Unexpected EOF in Ink execution");
2830

2931
// Read memory
3032
T val = *(const T*)_ptr;
33+
if (_story->get_header().endien == header::endian_types::differ) {
34+
val = header::swap_bytes(val);
35+
}
3136

3237
// Advance ip
3338
_ptr += sizeof(T);
@@ -1067,4 +1072,4 @@ namespace ink::runtime::internal
10671072
return out;
10681073
}
10691074
#endif
1070-
}
1075+
}

inkcpp/story_impl.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "platform.h"
33
#include "runner_impl.h"
44
#include "globals_impl.h"
5+
#include "version.h"
56

67
#ifdef INK_ENABLE_STL
78
#include <iostream>
@@ -24,6 +25,7 @@ namespace ink::runtime
2425

2526
namespace ink::runtime::internal
2627
{
28+
2729
#ifdef INK_ENABLE_STL
2830
unsigned char* read_file_into_memory(const char* filename, size_t* read)
2931
{
@@ -177,8 +179,11 @@ namespace ink::runtime::internal
177179

178180
void story_impl::setup_pointers()
179181
{
180-
// String table is after the version information
181-
_string_table = (char*)_file + sizeof(int);
182+
using header = ink::internal::header;
183+
_header = header::parse_header(reinterpret_cast<char*>(_file));
184+
185+
// String table is after the header
186+
_string_table = (char*)_file + header::Size;
182187

183188
// Pass over strings
184189
const char* ptr = _string_table;
@@ -252,4 +257,4 @@ namespace ink::runtime::internal
252257
}
253258
}*/
254259
}
255-
}
260+
}

inkcpp/story_impl.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
#include <config.h>
55
#include "types.h"
66
#include "story.h"
7+
#include "header.h"
78

89
namespace ink::runtime::internal
910
{
1011
// Ink story. Constant once constructed. Can be shared safely between multiple runner instances
1112
class story_impl : public story
1213
{
1314
public:
15+
1416
#ifdef INK_ENABLE_STL
1517
story_impl(const char* filename);
1618
#endif
@@ -34,6 +36,8 @@ namespace ink::runtime::internal
3436
virtual globals new_globals() override;
3537
virtual runner new_runner(globals store = nullptr) override;
3638

39+
40+
const ink::internal::header& get_header() const { return _header; }
3741
private:
3842
void setup_pointers();
3943

@@ -42,6 +46,8 @@ namespace ink::runtime::internal
4246
unsigned char* _file;
4347
size_t _length;
4448

49+
ink::internal::header _header;
50+
4551
// string table
4652
const char* _string_table;
4753

@@ -63,4 +69,4 @@ namespace ink::runtime::internal
6369
// whether we need to delete our binary data after we destruct
6470
bool _managed;
6571
};
66-
}
72+
}

inkcpp_compiler/binary_emitter.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "binary_emitter.h"
22

3+
#include "header.h"
4+
#include "version.h"
5+
36
#include <vector>
47
#include <map>
58
#include <fstream>
@@ -173,7 +176,12 @@ namespace ink::compiler::internal
173176
void binary_emitter::output(std::ostream& out)
174177
{
175178
// Write the ink version
176-
out.write((const char*)&_ink_version, sizeof(int));
179+
// TODO: define this order in header?
180+
using header = ink::internal::header;
181+
header::endian_types same = header::endian_types::same;
182+
out.write((const char*)&same, sizeof(decltype(same)));
183+
out.write((const char*)&_ink_version, sizeof(decltype(_ink_version)));
184+
out.write((const char*)&ink::InkBinVersion, sizeof(decltype(ink::InkBinVersion)));
177185

178186
// Write the string table
179187
_strings.write_to(out);

inkcpp_compiler/emitter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,4 @@ namespace ink::compiler::internal
7878
// ink version
7979
int _ink_version;
8080
};
81-
}
81+
}

shared/private/header.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include "system.h"
4+
5+
namespace ink::internal {
6+
7+
struct header {
8+
static header parse_header(const char* data);
9+
10+
template<typename T>
11+
static T swap_bytes(const T& value) {
12+
char data[sizeof(T)];
13+
for (int i = 0; i < sizeof(T); ++i) {
14+
data[i] = reinterpret_cast<const char*>(&value)[sizeof(T)-1-i];
15+
}
16+
return *reinterpret_cast<const T*>(data);
17+
}
18+
19+
enum class endian_types: uint16_t {
20+
none = 0,
21+
same = 0x0001,
22+
differ = 0x0100
23+
} endien = endian_types::none;
24+
uint32_t ink_version_number = 0;
25+
uint32_t ink_bin_version_number = 0;
26+
static constexpr size_t Size = ///< actual data size of Header,
27+
/// because padding of struct may
28+
/// differ between platforms
29+
sizeof(uint16_t) + 2 * sizeof(uint32_t);
30+
};
31+
}

shared/public/version.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include "system.h"
4+
5+
namespace ink {
6+
constexpr uint32_t InkBinVersion = 0;
7+
};

0 commit comments

Comments
 (0)