deukpack 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/binding.gyp ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "thrift_fast_engine",
5
+ "sources": [
6
+ "native/cpp/src/thrift_engine.cpp",
7
+ "native/cpp/src/binary_writer.cpp",
8
+ "native/cpp/src/binary_reader.cpp",
9
+ "native/cpp/src/compact_writer.cpp",
10
+ "native/cpp/src/compact_reader.cpp"
11
+ ],
12
+ "include_dirs": [
13
+ "<!@(node -p \"require('node-addon-api').include\")",
14
+ "native/cpp/include"
15
+ ],
16
+ "defines": [
17
+ "NAPI_DISABLE_CPP_EXCEPTIONS"
18
+ ],
19
+ "cflags!": ["-fno-exceptions"],
20
+ "cflags_cc!": ["-fno-exceptions"],
21
+ "xcode_settings": {
22
+ "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
23
+ "CLANG_CXX_LIBRARY": "libc++",
24
+ "MACOSX_DEPLOYMENT_TARGET": "10.7"
25
+ },
26
+ "msvs_settings": {
27
+ "VCCLCompilerTool": {
28
+ "ExceptionHandling": 1
29
+ }
30
+ },
31
+ "conditions": [
32
+ ["OS=='win'", {
33
+ "defines": [
34
+ "WIN32_LEAN_AND_MEAN",
35
+ "NOMINMAX"
36
+ ]
37
+ }]
38
+ ]
39
+ }
40
+ ]
41
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * DeukPack Binary Reader Header
3
+ * High-performance binary deserialization
4
+ */
5
+
6
+ #ifndef BINARY_READER_H
7
+ #define BINARY_READER_H
8
+
9
+ #include <vector>
10
+ #include <cstdint>
11
+ #include <string>
12
+ #include "thrift_engine.h"
13
+
14
+ namespace deukpack
15
+ {
16
+
17
+ class BinaryReader
18
+ {
19
+ public:
20
+ explicit BinaryReader(const uint8_t *data, size_t size, Endianness endianness = Endianness::LITTLE_ENDIAN);
21
+ ~BinaryReader() = default;
22
+
23
+ // Basic types
24
+ uint8_t ReadByte();
25
+ int16_t ReadI16();
26
+ int32_t ReadI32();
27
+ int64_t ReadI64();
28
+ double ReadDouble();
29
+
30
+ // String and binary
31
+ std::string ReadString();
32
+ std::vector<uint8_t> ReadBinary();
33
+
34
+ // Buffer management
35
+ bool IsAtEnd() const;
36
+ size_t GetPosition() const;
37
+ void SetPosition(size_t position);
38
+
39
+ private:
40
+ const uint8_t *data_;
41
+ size_t size_;
42
+ size_t position_;
43
+ Endianness endianness_;
44
+ };
45
+
46
+ } // namespace deukpack
47
+
48
+ #endif // BINARY_READER_H
@@ -0,0 +1,53 @@
1
+ /**
2
+ * DeukPack Binary Writer Header
3
+ * High-performance binary serialization
4
+ */
5
+
6
+ #ifndef BINARY_WRITER_H
7
+ #define BINARY_WRITER_H
8
+
9
+ #include <vector>
10
+ #include <cstdint>
11
+ #include <string>
12
+ #include "thrift_engine.h"
13
+
14
+ namespace deukpack
15
+ {
16
+
17
+ class BinaryWriter
18
+ {
19
+ public:
20
+ explicit BinaryWriter(Endianness endianness = Endianness::LITTLE_ENDIAN, size_t initialSize = 1024);
21
+ ~BinaryWriter() = default;
22
+
23
+ // Basic types
24
+ void WriteByte(uint8_t value);
25
+ void WriteI16(int16_t value);
26
+ void WriteI32(int32_t value);
27
+ void WriteI64(int64_t value);
28
+ void WriteDouble(double value);
29
+
30
+ // String and binary
31
+ void WriteString(const std::string &value);
32
+ void WriteBytes(const uint8_t *data, size_t length);
33
+ void WriteBinary(const std::vector<uint8_t> &data);
34
+
35
+ // Buffer management
36
+ std::vector<uint8_t> GetBuffer();
37
+ size_t GetPosition() const;
38
+ void Reset();
39
+
40
+ private:
41
+ void EnsureCapacity(size_t needed);
42
+ void FlushCurrentBuffer();
43
+ void AllocateNewBuffer(size_t size);
44
+
45
+ Endianness endianness_;
46
+ std::vector<uint8_t> currentBuffer_;
47
+ std::vector<std::vector<uint8_t>> buffers_;
48
+ size_t position_;
49
+ };
50
+
51
+ } // namespace deukpack
52
+
53
+ #endif // BINARY_WRITER_H
@@ -0,0 +1,35 @@
1
+ /**
2
+ * DeukPack Compact Reader Header
3
+ * High-performance compact protocol deserialization
4
+ */
5
+
6
+ #ifndef COMPACT_READER_H
7
+ #define COMPACT_READER_H
8
+
9
+ #include <cstdint>
10
+ #include <string>
11
+
12
+ namespace deukpack
13
+ {
14
+
15
+ class CompactReader
16
+ {
17
+ public:
18
+ explicit CompactReader(const uint8_t *data, size_t size);
19
+ ~CompactReader() = default;
20
+
21
+ uint8_t ReadByte();
22
+ int32_t ReadVarInt();
23
+ std::string ReadString();
24
+
25
+ bool IsAtEnd() const;
26
+
27
+ private:
28
+ const uint8_t *data_;
29
+ size_t size_;
30
+ size_t position_;
31
+ };
32
+
33
+ } // namespace deukpack
34
+
35
+ #endif // COMPACT_READER_H
@@ -0,0 +1,43 @@
1
+ /**
2
+ * DeukPack Compact Writer Header
3
+ * High-performance compact protocol serialization
4
+ */
5
+
6
+ #ifndef COMPACT_WRITER_H
7
+ #define COMPACT_WRITER_H
8
+
9
+ #include <vector>
10
+ #include <cstdint>
11
+ #include <string>
12
+ #include <cstring>
13
+
14
+ namespace deukpack
15
+ {
16
+
17
+ class CompactWriter
18
+ {
19
+ public:
20
+ explicit CompactWriter(size_t initialSize = 1024);
21
+ ~CompactWriter() = default;
22
+
23
+ void WriteByte(uint8_t value);
24
+ void WriteVarInt(int32_t value);
25
+ void WriteString(const std::string &value);
26
+ void WriteBytes(const uint8_t *data, size_t length);
27
+
28
+ std::vector<uint8_t> GetBuffer();
29
+ void Reset();
30
+
31
+ private:
32
+ void EnsureCapacity(size_t needed);
33
+ void FlushCurrentBuffer();
34
+ void AllocateNewBuffer(size_t size);
35
+
36
+ std::vector<uint8_t> currentBuffer_;
37
+ std::vector<std::vector<uint8_t>> buffers_;
38
+ size_t position_;
39
+ };
40
+
41
+ } // namespace deukpack
42
+
43
+ #endif // COMPACT_WRITER_H
@@ -0,0 +1,187 @@
1
+ /**
2
+ * DeukPack Native C++ Header
3
+ * High-performance Thrift engine implementation
4
+ */
5
+
6
+ #ifndef THRIFT_ENGINE_H
7
+ #define THRIFT_ENGINE_H
8
+
9
+ #include <string>
10
+ #include <vector>
11
+ #include <unordered_map>
12
+ #include <memory>
13
+ #include <chrono>
14
+
15
+ namespace deukpack
16
+ {
17
+
18
+ // Forward declarations
19
+ struct ThriftAST;
20
+ struct ThriftStruct;
21
+ struct ThriftEnum;
22
+ struct ThriftService;
23
+ struct ThriftField;
24
+ struct ThriftNamespace;
25
+ struct SerializationOptions;
26
+
27
+ // Thrift types
28
+ enum class ThriftType
29
+ {
30
+ BOOL,
31
+ BYTE,
32
+ I16,
33
+ I32,
34
+ I64,
35
+ DOUBLE,
36
+ STRING,
37
+ BINARY,
38
+ LIST,
39
+ SET,
40
+ MAP,
41
+ STRUCT,
42
+ ENUM
43
+ };
44
+
45
+ enum class Endianness
46
+ {
47
+ LITTLE_ENDIAN,
48
+ BIG_ENDIAN
49
+ };
50
+
51
+ enum class ThriftProtocol
52
+ {
53
+ BINARY,
54
+ COMPACT,
55
+ JSON
56
+ };
57
+
58
+ // Thrift field definition
59
+ struct ThriftField
60
+ {
61
+ int32_t id;
62
+ std::string name;
63
+ ThriftType type;
64
+ bool required;
65
+ std::string defaultValue;
66
+ ThriftType elementType;
67
+ ThriftType keyType;
68
+ ThriftType valueType;
69
+ std::string structType;
70
+ std::unordered_map<std::string, int32_t> enumValues;
71
+ };
72
+
73
+ // Thrift struct definition
74
+ struct ThriftStruct
75
+ {
76
+ std::string name;
77
+ std::vector<ThriftField> fields;
78
+ std::unordered_map<std::string, std::string> annotations;
79
+ };
80
+
81
+ // Thrift enum definition
82
+ struct ThriftEnum
83
+ {
84
+ std::string name;
85
+ std::unordered_map<std::string, int32_t> values;
86
+ std::unordered_map<std::string, std::string> annotations;
87
+ };
88
+
89
+ // Thrift method definition
90
+ struct ThriftMethod
91
+ {
92
+ std::string name;
93
+ ThriftType returnType;
94
+ std::vector<ThriftField> parameters;
95
+ bool oneway;
96
+ std::unordered_map<std::string, std::string> annotations;
97
+ };
98
+
99
+ // Thrift service definition
100
+ struct ThriftService
101
+ {
102
+ std::string name;
103
+ std::vector<ThriftMethod> methods;
104
+ std::unordered_map<std::string, std::string> annotations;
105
+ };
106
+
107
+ // Thrift namespace definition
108
+ struct ThriftNamespace
109
+ {
110
+ std::string language;
111
+ std::string name;
112
+ };
113
+
114
+ // Thrift AST
115
+ struct ThriftAST
116
+ {
117
+ std::vector<ThriftNamespace> namespaces;
118
+ std::vector<ThriftStruct> structs;
119
+ std::vector<ThriftEnum> enums;
120
+ std::vector<ThriftService> services;
121
+ std::vector<std::string> includes;
122
+ std::unordered_map<std::string, std::string> annotations;
123
+ };
124
+
125
+ // Serialization options
126
+ struct SerializationOptions
127
+ {
128
+ ThriftProtocol protocol;
129
+ Endianness endianness;
130
+ bool optimizeForSize;
131
+ bool includeDefaultValues;
132
+ bool validateTypes;
133
+ };
134
+
135
+ // Performance metrics
136
+ struct PerformanceMetrics
137
+ {
138
+ double parseTime;
139
+ double generateTime;
140
+ double serializeTime;
141
+ double deserializeTime;
142
+ size_t memoryUsage;
143
+ int32_t fileCount;
144
+ int32_t lineCount;
145
+ };
146
+
147
+ // Main Thrift Engine class
148
+ class ThriftEngine
149
+ {
150
+ public:
151
+ ThriftEngine();
152
+ ~ThriftEngine();
153
+
154
+ // Parse Thrift files
155
+ ThriftAST ParseFiles(const std::vector<std::string> &filePaths);
156
+
157
+ // Serialize object
158
+ std::vector<uint8_t> Serialize(const std::unordered_map<std::string, std::string> &data, const SerializationOptions &options);
159
+
160
+ // Deserialize data
161
+ std::unordered_map<std::string, std::string> Deserialize(const std::vector<uint8_t> &data, const SerializationOptions &options);
162
+
163
+ // Get memory usage
164
+ size_t GetMemoryUsage() const;
165
+
166
+ // Get performance metrics
167
+ PerformanceMetrics GetPerformanceMetrics() const;
168
+
169
+ // Reset metrics
170
+ void ResetMetrics();
171
+
172
+ private:
173
+ class Impl;
174
+ std::unique_ptr<Impl> impl_;
175
+ };
176
+
177
+ // Utility functions
178
+ std::string ThriftTypeToString(ThriftType type);
179
+ ThriftType StringToThriftType(const std::string &str);
180
+ std::string EndiannessToString(Endianness endianness);
181
+ Endianness StringToEndianness(const std::string &str);
182
+ std::string ProtocolToString(ThriftProtocol protocol);
183
+ ThriftProtocol StringToProtocol(const std::string &str);
184
+
185
+ } // namespace deukpack
186
+
187
+ #endif // THRIFT_ENGINE_H
@@ -0,0 +1,177 @@
1
+ /**
2
+ * DeukPack Binary Reader
3
+ * High-performance binary deserialization
4
+ */
5
+
6
+ #include "binary_reader.h"
7
+ #include <cstring>
8
+ #include <algorithm>
9
+
10
+ namespace deukpack
11
+ {
12
+
13
+ BinaryReader::BinaryReader(const uint8_t *data, size_t size, Endianness endianness)
14
+ : data_(data), size_(size), position_(0), endianness_(endianness)
15
+ {
16
+ }
17
+
18
+ uint8_t BinaryReader::ReadByte()
19
+ {
20
+ if (position_ >= size_)
21
+ {
22
+ throw std::runtime_error("Buffer overflow");
23
+ }
24
+ return data_[position_++];
25
+ }
26
+
27
+ int16_t BinaryReader::ReadI16()
28
+ {
29
+ if (position_ + 2 > size_)
30
+ {
31
+ throw std::runtime_error("Buffer overflow");
32
+ }
33
+
34
+ int16_t value;
35
+ if (endianness_ == Endianness::LITTLE_ENDIAN)
36
+ {
37
+ value = data_[position_] | (data_[position_ + 1] << 8);
38
+ }
39
+ else
40
+ {
41
+ value = (data_[position_] << 8) | data_[position_ + 1];
42
+ }
43
+
44
+ position_ += 2;
45
+ return value;
46
+ }
47
+
48
+ int32_t BinaryReader::ReadI32()
49
+ {
50
+ if (position_ + 4 > size_)
51
+ {
52
+ throw std::runtime_error("Buffer overflow");
53
+ }
54
+
55
+ int32_t value;
56
+ if (endianness_ == Endianness::LITTLE_ENDIAN)
57
+ {
58
+ value = data_[position_] |
59
+ (data_[position_ + 1] << 8) |
60
+ (data_[position_ + 2] << 16) |
61
+ (data_[position_ + 3] << 24);
62
+ }
63
+ else
64
+ {
65
+ value = (data_[position_] << 24) |
66
+ (data_[position_ + 1] << 16) |
67
+ (data_[position_ + 2] << 8) |
68
+ data_[position_ + 3];
69
+ }
70
+
71
+ position_ += 4;
72
+ return value;
73
+ }
74
+
75
+ int64_t BinaryReader::ReadI64()
76
+ {
77
+ if (position_ + 8 > size_)
78
+ {
79
+ throw std::runtime_error("Buffer overflow");
80
+ }
81
+
82
+ int64_t value = 0;
83
+ if (endianness_ == Endianness::LITTLE_ENDIAN)
84
+ {
85
+ for (int i = 0; i < 8; i++)
86
+ {
87
+ value |= static_cast<int64_t>(data_[position_ + i]) << (i * 8);
88
+ }
89
+ }
90
+ else
91
+ {
92
+ for (int i = 0; i < 8; i++)
93
+ {
94
+ value |= static_cast<int64_t>(data_[position_ + i]) << ((7 - i) * 8);
95
+ }
96
+ }
97
+
98
+ position_ += 8;
99
+ return value;
100
+ }
101
+
102
+ double BinaryReader::ReadDouble()
103
+ {
104
+ if (position_ + 8 > size_)
105
+ {
106
+ throw std::runtime_error("Buffer overflow");
107
+ }
108
+
109
+ union
110
+ {
111
+ double d;
112
+ uint8_t bytes[8];
113
+ } converter;
114
+
115
+ if (endianness_ == Endianness::LITTLE_ENDIAN)
116
+ {
117
+ std::memcpy(converter.bytes, &data_[position_], 8);
118
+ }
119
+ else
120
+ {
121
+ // Reverse byte order for big endian
122
+ for (int i = 0; i < 8; i++)
123
+ {
124
+ converter.bytes[i] = data_[position_ + 7 - i];
125
+ }
126
+ }
127
+
128
+ position_ += 8;
129
+ return converter.d;
130
+ }
131
+
132
+ std::string BinaryReader::ReadString()
133
+ {
134
+ int32_t length = ReadI32();
135
+ if (position_ + length > size_)
136
+ {
137
+ throw std::runtime_error("Buffer overflow");
138
+ }
139
+
140
+ std::string result(reinterpret_cast<const char *>(&data_[position_]), length);
141
+ position_ += length;
142
+ return result;
143
+ }
144
+
145
+ std::vector<uint8_t> BinaryReader::ReadBinary()
146
+ {
147
+ int32_t length = ReadI32();
148
+ if (position_ + length > size_)
149
+ {
150
+ throw std::runtime_error("Buffer overflow");
151
+ }
152
+
153
+ std::vector<uint8_t> result(data_ + position_, data_ + position_ + length);
154
+ position_ += length;
155
+ return result;
156
+ }
157
+
158
+ bool BinaryReader::IsAtEnd() const
159
+ {
160
+ return position_ >= size_;
161
+ }
162
+
163
+ size_t BinaryReader::GetPosition() const
164
+ {
165
+ return position_;
166
+ }
167
+
168
+ void BinaryReader::SetPosition(size_t position)
169
+ {
170
+ if (position > size_)
171
+ {
172
+ throw std::runtime_error("Position out of bounds");
173
+ }
174
+ position_ = position;
175
+ }
176
+
177
+ } // namespace deukpack
@@ -0,0 +1,211 @@
1
+ /**
2
+ * DeukPack Binary Writer
3
+ * High-performance binary serialization
4
+ */
5
+
6
+ #include "binary_writer.h"
7
+ #include <cstring>
8
+ #include <algorithm>
9
+
10
+ namespace deukpack
11
+ {
12
+
13
+ BinaryWriter::BinaryWriter(Endianness endianness, size_t initialSize)
14
+ : endianness_(endianness), position_(0)
15
+ {
16
+ currentBuffer_.resize(initialSize);
17
+ }
18
+
19
+ void BinaryWriter::WriteByte(uint8_t value)
20
+ {
21
+ EnsureCapacity(1);
22
+ currentBuffer_[position_++] = value;
23
+ }
24
+
25
+ void BinaryWriter::WriteI16(int16_t value)
26
+ {
27
+ EnsureCapacity(2);
28
+
29
+ if (endianness_ == Endianness::LITTLE_ENDIAN)
30
+ {
31
+ currentBuffer_[position_] = value & 0xFF;
32
+ currentBuffer_[position_ + 1] = (value >> 8) & 0xFF;
33
+ }
34
+ else
35
+ {
36
+ currentBuffer_[position_] = (value >> 8) & 0xFF;
37
+ currentBuffer_[position_ + 1] = value & 0xFF;
38
+ }
39
+
40
+ position_ += 2;
41
+ }
42
+
43
+ void BinaryWriter::WriteI32(int32_t value)
44
+ {
45
+ EnsureCapacity(4);
46
+
47
+ if (endianness_ == Endianness::LITTLE_ENDIAN)
48
+ {
49
+ currentBuffer_[position_] = value & 0xFF;
50
+ currentBuffer_[position_ + 1] = (value >> 8) & 0xFF;
51
+ currentBuffer_[position_ + 2] = (value >> 16) & 0xFF;
52
+ currentBuffer_[position_ + 3] = (value >> 24) & 0xFF;
53
+ }
54
+ else
55
+ {
56
+ currentBuffer_[position_] = (value >> 24) & 0xFF;
57
+ currentBuffer_[position_ + 1] = (value >> 16) & 0xFF;
58
+ currentBuffer_[position_ + 2] = (value >> 8) & 0xFF;
59
+ currentBuffer_[position_ + 3] = value & 0xFF;
60
+ }
61
+
62
+ position_ += 4;
63
+ }
64
+
65
+ void BinaryWriter::WriteI64(int64_t value)
66
+ {
67
+ EnsureCapacity(8);
68
+
69
+ if (endianness_ == Endianness::LITTLE_ENDIAN)
70
+ {
71
+ for (int i = 0; i < 8; i++)
72
+ {
73
+ currentBuffer_[position_ + i] = (value >> (i * 8)) & 0xFF;
74
+ }
75
+ }
76
+ else
77
+ {
78
+ for (int i = 0; i < 8; i++)
79
+ {
80
+ currentBuffer_[position_ + i] = (value >> ((7 - i) * 8)) & 0xFF;
81
+ }
82
+ }
83
+
84
+ position_ += 8;
85
+ }
86
+
87
+ void BinaryWriter::WriteDouble(double value)
88
+ {
89
+ EnsureCapacity(8);
90
+
91
+ // Convert to IEEE 754 representation
92
+ union
93
+ {
94
+ double d;
95
+ uint8_t bytes[8];
96
+ } converter;
97
+
98
+ converter.d = value;
99
+
100
+ if (endianness_ == Endianness::LITTLE_ENDIAN)
101
+ {
102
+ std::memcpy(&currentBuffer_[position_], converter.bytes, 8);
103
+ }
104
+ else
105
+ {
106
+ // Reverse byte order for big endian
107
+ for (int i = 0; i < 8; i++)
108
+ {
109
+ currentBuffer_[position_ + i] = converter.bytes[7 - i];
110
+ }
111
+ }
112
+
113
+ position_ += 8;
114
+ }
115
+
116
+ void BinaryWriter::WriteString(const std::string &value)
117
+ {
118
+ WriteI32(static_cast<int32_t>(value.length()));
119
+ WriteBytes(reinterpret_cast<const uint8_t *>(value.c_str()), value.length());
120
+ }
121
+
122
+ void BinaryWriter::WriteBytes(const uint8_t *data, size_t length)
123
+ {
124
+ EnsureCapacity(length);
125
+ std::memcpy(&currentBuffer_[position_], data, length);
126
+ position_ += length;
127
+ }
128
+
129
+ void BinaryWriter::WriteBinary(const std::vector<uint8_t> &data)
130
+ {
131
+ WriteI32(static_cast<int32_t>(data.size()));
132
+ WriteBytes(data.data(), data.size());
133
+ }
134
+
135
+ std::vector<uint8_t> BinaryWriter::GetBuffer()
136
+ {
137
+ FlushCurrentBuffer();
138
+
139
+ if (buffers_.empty())
140
+ {
141
+ return std::vector<uint8_t>();
142
+ }
143
+
144
+ if (buffers_.size() == 1)
145
+ {
146
+ return std::move(buffers_[0]);
147
+ }
148
+
149
+ // Calculate total size
150
+ size_t totalSize = 0;
151
+ for (const auto &buffer : buffers_)
152
+ {
153
+ totalSize += buffer.size();
154
+ }
155
+
156
+ // Concatenate all buffers
157
+ std::vector<uint8_t> result;
158
+ result.reserve(totalSize);
159
+
160
+ for (const auto &buffer : buffers_)
161
+ {
162
+ result.insert(result.end(), buffer.begin(), buffer.end());
163
+ }
164
+
165
+ return result;
166
+ }
167
+
168
+ size_t BinaryWriter::GetPosition() const
169
+ {
170
+ size_t totalPosition = 0;
171
+ for (const auto &buffer : buffers_)
172
+ {
173
+ totalPosition += buffer.size();
174
+ }
175
+ return totalPosition + position_;
176
+ }
177
+
178
+ void BinaryWriter::Reset()
179
+ {
180
+ buffers_.clear();
181
+ position_ = 0;
182
+ currentBuffer_.resize(1024);
183
+ }
184
+
185
+ void BinaryWriter::EnsureCapacity(size_t needed)
186
+ {
187
+ if (position_ + needed > currentBuffer_.size())
188
+ {
189
+ FlushCurrentBuffer();
190
+ AllocateNewBuffer(std::max(needed * 2, static_cast<size_t>(1024)));
191
+ }
192
+ }
193
+
194
+ void BinaryWriter::FlushCurrentBuffer()
195
+ {
196
+ if (position_ > 0)
197
+ {
198
+ std::vector<uint8_t> buffer(position_);
199
+ std::memcpy(buffer.data(), currentBuffer_.data(), position_);
200
+ buffers_.push_back(std::move(buffer));
201
+ position_ = 0;
202
+ }
203
+ }
204
+
205
+ void BinaryWriter::AllocateNewBuffer(size_t size)
206
+ {
207
+ currentBuffer_.resize(size);
208
+ position_ = 0;
209
+ }
210
+
211
+ } // namespace deukpack
@@ -0,0 +1,69 @@
1
+ /**
2
+ * DeukPack Compact Reader
3
+ * High-performance compact protocol deserialization
4
+ */
5
+
6
+ #include "compact_reader.h"
7
+ #include <stdexcept>
8
+
9
+ namespace deukpack
10
+ {
11
+
12
+ CompactReader::CompactReader(const uint8_t *data, size_t size)
13
+ : data_(data), size_(size), position_(0)
14
+ {
15
+ }
16
+
17
+ uint8_t CompactReader::ReadByte()
18
+ {
19
+ if (position_ >= size_)
20
+ {
21
+ throw std::runtime_error("Buffer overflow");
22
+ }
23
+ return data_[position_++];
24
+ }
25
+
26
+ int32_t CompactReader::ReadVarInt()
27
+ {
28
+ int32_t result = 0;
29
+ int shift = 0;
30
+
31
+ while (position_ < size_)
32
+ {
33
+ uint8_t byte = data_[position_++];
34
+ result |= (byte & 0x7F) << shift;
35
+
36
+ if ((byte & 0x80) == 0)
37
+ {
38
+ break;
39
+ }
40
+
41
+ shift += 7;
42
+ if (shift >= 32)
43
+ {
44
+ throw std::runtime_error("VarInt too large");
45
+ }
46
+ }
47
+
48
+ return result;
49
+ }
50
+
51
+ std::string CompactReader::ReadString()
52
+ {
53
+ int32_t length = ReadVarInt();
54
+ if (position_ + length > size_)
55
+ {
56
+ throw std::runtime_error("Buffer overflow");
57
+ }
58
+
59
+ std::string result(reinterpret_cast<const char *>(&data_[position_]), length);
60
+ position_ += length;
61
+ return result;
62
+ }
63
+
64
+ bool CompactReader::IsAtEnd() const
65
+ {
66
+ return position_ >= size_;
67
+ }
68
+
69
+ } // namespace deukpack
@@ -0,0 +1,113 @@
1
+ /**
2
+ * DeukPack Compact Writer
3
+ * High-performance compact protocol serialization
4
+ */
5
+
6
+ #include "compact_writer.h"
7
+ #include <cstring>
8
+
9
+ namespace deukpack
10
+ {
11
+
12
+ CompactWriter::CompactWriter(size_t initialSize)
13
+ : position_(0)
14
+ {
15
+ currentBuffer_.resize(initialSize);
16
+ }
17
+
18
+ void CompactWriter::WriteByte(uint8_t value)
19
+ {
20
+ EnsureCapacity(1);
21
+ currentBuffer_[position_++] = value;
22
+ }
23
+
24
+ void CompactWriter::WriteVarInt(int32_t value)
25
+ {
26
+ while (value >= 0x80)
27
+ {
28
+ WriteByte((value & 0x7F) | 0x80);
29
+ value >>= 7;
30
+ }
31
+ WriteByte(value & 0x7F);
32
+ }
33
+
34
+ void CompactWriter::WriteString(const std::string &value)
35
+ {
36
+ WriteVarInt(static_cast<int32_t>(value.length()));
37
+ WriteBytes(reinterpret_cast<const uint8_t *>(value.c_str()), value.length());
38
+ }
39
+
40
+ void CompactWriter::WriteBytes(const uint8_t *data, size_t length)
41
+ {
42
+ EnsureCapacity(length);
43
+ std::memcpy(&currentBuffer_[position_], data, length);
44
+ position_ += length;
45
+ }
46
+
47
+ std::vector<uint8_t> CompactWriter::GetBuffer()
48
+ {
49
+ FlushCurrentBuffer();
50
+
51
+ if (buffers_.empty())
52
+ {
53
+ return std::vector<uint8_t>();
54
+ }
55
+
56
+ if (buffers_.size() == 1)
57
+ {
58
+ return std::move(buffers_[0]);
59
+ }
60
+
61
+ // Calculate total size
62
+ size_t totalSize = 0;
63
+ for (const auto &buffer : buffers_)
64
+ {
65
+ totalSize += buffer.size();
66
+ }
67
+
68
+ // Concatenate all buffers
69
+ std::vector<uint8_t> result;
70
+ result.reserve(totalSize);
71
+
72
+ for (const auto &buffer : buffers_)
73
+ {
74
+ result.insert(result.end(), buffer.begin(), buffer.end());
75
+ }
76
+
77
+ return result;
78
+ }
79
+
80
+ void CompactWriter::Reset()
81
+ {
82
+ buffers_.clear();
83
+ position_ = 0;
84
+ currentBuffer_.resize(1024);
85
+ }
86
+
87
+ void CompactWriter::EnsureCapacity(size_t needed)
88
+ {
89
+ if (position_ + needed > currentBuffer_.size())
90
+ {
91
+ FlushCurrentBuffer();
92
+ AllocateNewBuffer(std::max(needed * 2, static_cast<size_t>(1024)));
93
+ }
94
+ }
95
+
96
+ void CompactWriter::FlushCurrentBuffer()
97
+ {
98
+ if (position_ > 0)
99
+ {
100
+ std::vector<uint8_t> buffer(position_);
101
+ std::memcpy(buffer.data(), currentBuffer_.data(), position_);
102
+ buffers_.push_back(std::move(buffer));
103
+ position_ = 0;
104
+ }
105
+ }
106
+
107
+ void CompactWriter::AllocateNewBuffer(size_t size)
108
+ {
109
+ currentBuffer_.resize(size);
110
+ position_ = 0;
111
+ }
112
+
113
+ } // namespace deukpack
@@ -0,0 +1,380 @@
1
+ /**
2
+ * DeukPack Native C++ Implementation
3
+ * High-performance Thrift engine
4
+ */
5
+
6
+ #include <napi.h>
7
+ #include <iostream>
8
+ #include <vector>
9
+ #include <string>
10
+ #include <unordered_map>
11
+ #include <memory>
12
+ #include <chrono>
13
+ #include "thrift_engine.h"
14
+ #include "binary_writer.h"
15
+
16
+ using namespace deukpack;
17
+
18
+ // ThriftEngine implementation
19
+ class ThriftEngine::Impl
20
+ {
21
+ public:
22
+ Impl() : memoryUsage_(0) {}
23
+
24
+ ThriftAST ParseFiles(const std::vector<std::string> &filePaths)
25
+ {
26
+ auto start = std::chrono::high_resolution_clock::now();
27
+
28
+ ThriftAST ast;
29
+ // TODO: Implement actual parsing logic
30
+ // For now, return empty AST
31
+
32
+ auto end = std::chrono::high_resolution_clock::now();
33
+ auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
34
+ parseTime_ = duration.count();
35
+
36
+ return ast;
37
+ }
38
+
39
+ std::vector<uint8_t> Serialize(const std::unordered_map<std::string, std::string> &data,
40
+ const SerializationOptions &options)
41
+ {
42
+ auto start = std::chrono::high_resolution_clock::now();
43
+
44
+ BinaryWriter writer(options.endianness == Endianness::LITTLE_ENDIAN ? Endianness::LITTLE_ENDIAN : Endianness::BIG_ENDIAN);
45
+
46
+ // Simple serialization for demonstration
47
+ writer.WriteI32(static_cast<int32_t>(data.size()));
48
+ for (const auto &pair : data)
49
+ {
50
+ writer.WriteString(pair.first);
51
+ writer.WriteString(pair.second);
52
+ }
53
+
54
+ auto result = writer.GetBuffer();
55
+
56
+ auto end = std::chrono::high_resolution_clock::now();
57
+ auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
58
+ serializeTime_ = duration.count();
59
+
60
+ return result;
61
+ }
62
+
63
+ std::unordered_map<std::string, std::string> Deserialize(const std::vector<uint8_t> &data,
64
+ const SerializationOptions &options)
65
+ {
66
+ auto start = std::chrono::high_resolution_clock::now();
67
+
68
+ std::unordered_map<std::string, std::string> result;
69
+
70
+ // Simple deserialization for demonstration
71
+ if (data.size() >= 4)
72
+ {
73
+ int32_t count = *reinterpret_cast<const int32_t *>(data.data());
74
+ size_t offset = 4;
75
+
76
+ for (int32_t i = 0; i < count && offset < data.size(); i++)
77
+ {
78
+ if (offset + 4 > data.size())
79
+ break;
80
+
81
+ int32_t keyLen = *reinterpret_cast<const int32_t *>(data.data() + offset);
82
+ offset += 4;
83
+
84
+ if (offset + keyLen > data.size())
85
+ break;
86
+ std::string key(data.data() + offset, data.data() + offset + keyLen);
87
+ offset += keyLen;
88
+
89
+ if (offset + 4 > data.size())
90
+ break;
91
+ int32_t valueLen = *reinterpret_cast<const int32_t *>(data.data() + offset);
92
+ offset += 4;
93
+
94
+ if (offset + valueLen > data.size())
95
+ break;
96
+ std::string value(data.data() + offset, data.data() + offset + valueLen);
97
+ offset += valueLen;
98
+
99
+ result[key] = value;
100
+ }
101
+ }
102
+
103
+ auto end = std::chrono::high_resolution_clock::now();
104
+ auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
105
+ deserializeTime_ = duration.count();
106
+
107
+ return result;
108
+ }
109
+
110
+ size_t GetMemoryUsage() const
111
+ {
112
+ return memoryUsage_;
113
+ }
114
+
115
+ PerformanceMetrics GetPerformanceMetrics() const
116
+ {
117
+ PerformanceMetrics metrics;
118
+ metrics.parseTime = parseTime_;
119
+ metrics.generateTime = generateTime_;
120
+ metrics.serializeTime = serializeTime_;
121
+ metrics.deserializeTime = deserializeTime_;
122
+ metrics.memoryUsage = memoryUsage_;
123
+ metrics.fileCount = fileCount_;
124
+ metrics.lineCount = lineCount_;
125
+ return metrics;
126
+ }
127
+
128
+ void ResetMetrics()
129
+ {
130
+ parseTime_ = 0;
131
+ generateTime_ = 0;
132
+ serializeTime_ = 0;
133
+ deserializeTime_ = 0;
134
+ memoryUsage_ = 0;
135
+ fileCount_ = 0;
136
+ lineCount_ = 0;
137
+ }
138
+
139
+ private:
140
+ double parseTime_ = 0;
141
+ double generateTime_ = 0;
142
+ double serializeTime_ = 0;
143
+ double deserializeTime_ = 0;
144
+ size_t memoryUsage_ = 0;
145
+ int32_t fileCount_ = 0;
146
+ int32_t lineCount_ = 0;
147
+ };
148
+
149
+ ThriftEngine::ThriftEngine() : impl_(std::make_unique<Impl>()) {}
150
+ ThriftEngine::~ThriftEngine() = default;
151
+
152
+ ThriftAST ThriftEngine::ParseFiles(const std::vector<std::string> &filePaths)
153
+ {
154
+ return impl_->ParseFiles(filePaths);
155
+ }
156
+
157
+ std::vector<uint8_t> ThriftEngine::Serialize(const std::unordered_map<std::string, std::string> &data,
158
+ const SerializationOptions &options)
159
+ {
160
+ return impl_->Serialize(data, options);
161
+ }
162
+
163
+ std::unordered_map<std::string, std::string> ThriftEngine::Deserialize(const std::vector<uint8_t> &data,
164
+ const SerializationOptions &options)
165
+ {
166
+ return impl_->Deserialize(data, options);
167
+ }
168
+
169
+ size_t ThriftEngine::GetMemoryUsage() const
170
+ {
171
+ return impl_->GetMemoryUsage();
172
+ }
173
+
174
+ PerformanceMetrics ThriftEngine::GetPerformanceMetrics() const
175
+ {
176
+ return impl_->GetPerformanceMetrics();
177
+ }
178
+
179
+ void ThriftEngine::ResetMetrics()
180
+ {
181
+ impl_->ResetMetrics();
182
+ }
183
+
184
+ // N-API wrapper functions
185
+ Napi::Value CreateEngine(const Napi::CallbackInfo &info)
186
+ {
187
+ Napi::Env env = info.Env();
188
+
189
+ try
190
+ {
191
+ auto engine = std::make_unique<ThriftEngine>();
192
+ return Napi::External<ThriftEngine>::New(env, engine.release());
193
+ }
194
+ catch (const std::exception &e)
195
+ {
196
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
197
+ return env.Null();
198
+ }
199
+ }
200
+
201
+ Napi::Value ParseFiles(const Napi::CallbackInfo &info)
202
+ {
203
+ Napi::Env env = info.Env();
204
+
205
+ if (info.Length() < 2 || !info[0].IsExternal() || !info[1].IsArray())
206
+ {
207
+ Napi::TypeError::New(env, "Expected engine and file paths array").ThrowAsJavaScriptException();
208
+ return env.Null();
209
+ }
210
+
211
+ try
212
+ {
213
+ auto engine = info[0].As<Napi::External<ThriftEngine>>().Data();
214
+ auto filePaths = info[1].As<Napi::Array>();
215
+
216
+ std::vector<std::string> paths;
217
+ for (uint32_t i = 0; i < filePaths.Length(); i++)
218
+ {
219
+ if (filePaths.Get(i).IsString())
220
+ {
221
+ paths.push_back(filePaths.Get(i).As<Napi::String>().Utf8Value());
222
+ }
223
+ }
224
+
225
+ auto ast = engine->ParseFiles(paths);
226
+
227
+ // Convert AST to JavaScript object
228
+ auto result = Napi::Object::New(env);
229
+ result.Set("namespaces", Napi::Array::New(env));
230
+ result.Set("structs", Napi::Array::New(env));
231
+ result.Set("enums", Napi::Array::New(env));
232
+ result.Set("services", Napi::Array::New(env));
233
+ result.Set("includes", Napi::Array::New(env));
234
+
235
+ return result;
236
+ }
237
+ catch (const std::exception &e)
238
+ {
239
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
240
+ return env.Null();
241
+ }
242
+ }
243
+
244
+ Napi::Value Serialize(const Napi::CallbackInfo &info)
245
+ {
246
+ Napi::Env env = info.Env();
247
+
248
+ if (info.Length() < 3 || !info[0].IsExternal() || !info[1].IsObject() || !info[2].IsObject())
249
+ {
250
+ Napi::TypeError::New(env, "Expected engine, data object, and options object").ThrowAsJavaScriptException();
251
+ return env.Null();
252
+ }
253
+
254
+ try
255
+ {
256
+ auto engine = info[0].As<Napi::External<ThriftEngine>>().Data();
257
+ auto dataObj = info[1].As<Napi::Object>();
258
+ auto optionsObj = info[2].As<Napi::Object>();
259
+
260
+ // Convert JavaScript object to map
261
+ std::unordered_map<std::string, std::string> data;
262
+ auto keys = dataObj.GetPropertyNames();
263
+ for (uint32_t i = 0; i < keys.Length(); i++)
264
+ {
265
+ auto key = keys.Get(i).As<Napi::String>().Utf8Value();
266
+ auto value = dataObj.Get(key).As<Napi::String>().Utf8Value();
267
+ data[key] = value;
268
+ }
269
+
270
+ // Create serialization options
271
+ SerializationOptions options;
272
+ options.protocol = ThriftProtocol::BINARY;
273
+ options.endianness = Endianness::LITTLE_ENDIAN;
274
+ options.optimizeForSize = true;
275
+ options.includeDefaultValues = false;
276
+ options.validateTypes = true;
277
+
278
+ auto result = engine->Serialize(data, options);
279
+
280
+ // Convert to Node.js Buffer
281
+ auto buffer = Napi::Buffer<uint8_t>::Copy(env, result.data(), result.size());
282
+ return buffer;
283
+ }
284
+ catch (const std::exception &e)
285
+ {
286
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
287
+ return env.Null();
288
+ }
289
+ }
290
+
291
+ Napi::Value Deserialize(const Napi::CallbackInfo &info)
292
+ {
293
+ Napi::Env env = info.Env();
294
+
295
+ if (info.Length() < 3 || !info[0].IsExternal() || !info[1].IsBuffer() || !info[2].IsObject())
296
+ {
297
+ Napi::TypeError::New(env, "Expected engine, buffer, and options object").ThrowAsJavaScriptException();
298
+ return env.Null();
299
+ }
300
+
301
+ try
302
+ {
303
+ auto engine = info[0].As<Napi::External<ThriftEngine>>().Data();
304
+ auto buffer = info[1].As<Napi::Buffer<uint8_t>>();
305
+ auto optionsObj = info[2].As<Napi::Object>();
306
+
307
+ // Convert buffer to vector
308
+ std::vector<uint8_t> data(buffer.Data(), buffer.Data() + buffer.Length());
309
+
310
+ // Create serialization options
311
+ SerializationOptions options;
312
+ options.protocol = ThriftProtocol::BINARY;
313
+ options.endianness = Endianness::LITTLE_ENDIAN;
314
+ options.optimizeForSize = true;
315
+ options.includeDefaultValues = false;
316
+ options.validateTypes = true;
317
+
318
+ auto result = engine->Deserialize(data, options);
319
+
320
+ // Convert map to JavaScript object
321
+ auto resultObj = Napi::Object::New(env);
322
+ for (const auto &pair : result)
323
+ {
324
+ resultObj.Set(pair.first, pair.second);
325
+ }
326
+
327
+ return resultObj;
328
+ }
329
+ catch (const std::exception &e)
330
+ {
331
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
332
+ return env.Null();
333
+ }
334
+ }
335
+
336
+ Napi::Value GetPerformanceMetrics(const Napi::CallbackInfo &info)
337
+ {
338
+ Napi::Env env = info.Env();
339
+
340
+ if (info.Length() < 1 || !info[0].IsExternal())
341
+ {
342
+ Napi::TypeError::New(env, "Expected engine").ThrowAsJavaScriptException();
343
+ return env.Null();
344
+ }
345
+
346
+ try
347
+ {
348
+ auto engine = info[0].As<Napi::External<ThriftEngine>>().Data();
349
+ auto metrics = engine->GetPerformanceMetrics();
350
+
351
+ auto result = Napi::Object::New(env);
352
+ result.Set("parseTime", metrics.parseTime);
353
+ result.Set("generateTime", metrics.generateTime);
354
+ result.Set("serializeTime", metrics.serializeTime);
355
+ result.Set("deserializeTime", metrics.deserializeTime);
356
+ result.Set("memoryUsage", static_cast<double>(metrics.memoryUsage));
357
+ result.Set("fileCount", metrics.fileCount);
358
+ result.Set("lineCount", metrics.lineCount);
359
+
360
+ return result;
361
+ }
362
+ catch (const std::exception &e)
363
+ {
364
+ Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();
365
+ return env.Null();
366
+ }
367
+ }
368
+
369
+ Napi::Object Init(Napi::Env env, Napi::Object exports)
370
+ {
371
+ exports.Set(Napi::String::New(env, "createEngine"), Napi::Function::New(env, CreateEngine));
372
+ exports.Set(Napi::String::New(env, "parseFiles"), Napi::Function::New(env, ParseFiles));
373
+ exports.Set(Napi::String::New(env, "serialize"), Napi::Function::New(env, Serialize));
374
+ exports.Set(Napi::String::New(env, "deserialize"), Napi::Function::New(env, Deserialize));
375
+ exports.Set(Napi::String::New(env, "getPerformanceMetrics"), Napi::Function::New(env, GetPerformanceMetrics));
376
+
377
+ return exports;
378
+ }
379
+
380
+ NODE_API_MODULE(thrift_engine_native, Init)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deukpack",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "DeukPack — multi-format IDL pipeline (.deuk native, Protobuf, OpenAPI, JSON Schema, CSV, Thrift). Protobuf-aligned wire; fast C#/C++/JS codegen, CLI. v1: no Excel/table editor workflow",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -13,7 +13,7 @@
13
13
  "build:native": "node-gyp rebuild",
14
14
  "build:all": "npm run build && npm run build:cpp && npm run build:cs",
15
15
  "build:cpp": "cd native/cpp && mkdir -p build && cd build && cmake .. && make",
16
- "build:cs": "cd native/csharp && dotnet build -c Release",
16
+ "build:cs": "cd DeukPack.Protocol && dotnet build -c Release",
17
17
  "test": "jest",
18
18
  "benchmark": "node benchmarks/performance.js",
19
19
  "dev": "tsc --watch",
@@ -65,6 +65,8 @@
65
65
  "bin",
66
66
  "scripts/build_deukpack.js",
67
67
  "dist",
68
+ "native/cpp",
69
+ "binding.gyp",
68
70
  "LICENSE",
69
71
  "NOTICE",
70
72
  "README.md",