ya-struct 0.0.5 → 0.0.7

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.
Files changed (61) hide show
  1. package/.editorconfig +8 -0
  2. package/.github/workflows/ci.yml +23 -0
  3. package/.github/workflows/npm-publish.yml +28 -0
  4. package/README.md +150 -18
  5. package/dist/lib/common.d.ts +14 -0
  6. package/dist/lib/common.js +30 -0
  7. package/dist/lib/index.d.ts +5 -0
  8. package/dist/lib/index.js +21 -0
  9. package/dist/lib/layout.d.ts +48 -0
  10. package/dist/lib/layout.js +278 -0
  11. package/dist/lib/parser.d.ts +51 -0
  12. package/dist/lib/parser.js +87 -0
  13. package/dist/lib/types/array.d.ts +10 -0
  14. package/dist/lib/types/array.js +90 -0
  15. package/dist/lib/types/c-types.d.ts +13 -0
  16. package/dist/lib/types/c-types.js +222 -0
  17. package/dist/lib/types/index.d.ts +93 -0
  18. package/dist/lib/types/index.js +122 -0
  19. package/dist/lib/types/integer.d.ts +9 -0
  20. package/dist/lib/types/integer.js +160 -0
  21. package/dist/lib/types/pointer.d.ts +8 -0
  22. package/dist/lib/types/pointer.js +27 -0
  23. package/dist/lib/types/string.d.ts +6 -0
  24. package/dist/lib/types/string.js +56 -0
  25. package/dist/lib/types/struct.d.ts +11 -0
  26. package/dist/lib/types/struct.js +113 -0
  27. package/dist/lib/types/value.d.ts +12 -0
  28. package/dist/lib/types/value.js +8 -0
  29. package/eslint.config.js +127 -0
  30. package/lib/bit-buffer.ts +70 -0
  31. package/lib/common.ts +30 -0
  32. package/lib/index.ts +21 -0
  33. package/lib/layout.ts +278 -0
  34. package/lib/parser.ts +87 -0
  35. package/lib/types/array.ts +90 -0
  36. package/lib/types/c-types.ts +222 -0
  37. package/lib/types/index.ts +122 -0
  38. package/lib/types/integer.ts +160 -0
  39. package/lib/types/pointer.ts +27 -0
  40. package/lib/types/string.ts +56 -0
  41. package/lib/types/struct.ts +113 -0
  42. package/lib/types/value.ts +8 -0
  43. package/package.json +19 -15
  44. package/package.npm.json +25 -0
  45. package/samples/basic.ts +40 -0
  46. package/test/c-structs.ts +399 -0
  47. package/test/compile-util.ts +92 -0
  48. package/tsconfig.json +10 -0
  49. package/.eslintrc +0 -92
  50. package/.github/workflows/CI.yml +0 -39
  51. package/.prettierrc +0 -5
  52. package/lib/builder.js +0 -62
  53. package/lib/index.js +0 -159
  54. package/lib/marshaller.js +0 -88
  55. package/lib/refbuf.js +0 -11
  56. package/lib/types/basic.js +0 -200
  57. package/lib/types/ctypes.js +0 -160
  58. package/test/abi.js +0 -203
  59. package/test/basic.js +0 -92
  60. package/test/ctypes.js +0 -166
  61. package/test/ref.js +0 -35
package/lib/index.js DELETED
@@ -1,159 +0,0 @@
1
- import b2a from "buffer2address";
2
- import os from "os";
3
-
4
- import fieldBuilder from "./builder.js";
5
-
6
- const defineWithBuilderAndAbi = ({ builder, abi }) => {
7
- const { fields, size, marshal, unmarshal } =
8
- fieldBuilder.createFieldsViaBuilder({ builder, abi });
9
-
10
- const parse = (buf) => {
11
- if (!Buffer.isBuffer(buf)) {
12
- throw new Error(`given argument is not a buffer`);
13
- }
14
-
15
- if (buf.length < size) {
16
- throw new Error(
17
- `given buffer is too small for structure (has ${buf.length} bytes, needs ${size} bytes)`
18
- );
19
- }
20
-
21
- return unmarshal({ buffer: buf });
22
- };
23
-
24
- let emptyData = {};
25
- Object.keys(fields).forEach((fieldName) => {
26
- emptyData = {
27
- ...emptyData,
28
- [fieldName]: 0n,
29
- };
30
- });
31
-
32
- const format = (data) => {
33
- if (typeof data !== "object") {
34
- throw new Error(`given argument is not a object`);
35
- }
36
-
37
- let primitives = {};
38
- let buffers = {};
39
- let links = [];
40
-
41
- Object.keys(data).forEach((fieldName) => {
42
- const value = data[fieldName];
43
- if (Buffer.isBuffer(value)) {
44
- buffers = Object.assign({}, buffers, {
45
- [fieldName]: value,
46
- });
47
- links = [...links, value];
48
- } else if (typeof value === "bigint") {
49
- primitives = Object.assign({}, primitives, {
50
- [fieldName]: value,
51
- });
52
- } else {
53
- throw new Error(
54
- `only Buffer and BigInt supported, "${fieldName}" was of type "${typeof value}"`
55
- );
56
- }
57
- });
58
-
59
- let bufferDataToMarshal = {};
60
-
61
- Object.keys(buffers).forEach((fieldName) => {
62
- const value = b2a.buffer2address(data[fieldName]);
63
-
64
- bufferDataToMarshal = {
65
- ...bufferDataToMarshal,
66
- [fieldName]: value,
67
- };
68
- });
69
-
70
- return marshal({
71
- data: {
72
- ...emptyData,
73
- ...primitives,
74
- ...bufferDataToMarshal,
75
- },
76
- links,
77
- });
78
- };
79
-
80
- return {
81
- fields,
82
- size,
83
-
84
- parse,
85
- format,
86
- };
87
- };
88
-
89
- const hostDataModels = {
90
- x64: {
91
- win32: "LLP64",
92
- linux: "LP64",
93
- },
94
- arm: {
95
- linux: "ILP32",
96
- },
97
- arm64: {
98
- linux: "LP64",
99
- },
100
- };
101
-
102
- const findDataModelFor = ({ arch, platform }) => {
103
- const archDataModels = hostDataModels[arch];
104
- if (!archDataModels) {
105
- throw new Error(`unsupported CPU architecture ${arch}`);
106
- }
107
-
108
- const dataModel = archDataModels[platform];
109
- if (!dataModel) {
110
- throw new Error(`unsupported platform ${platform}`);
111
- }
112
-
113
- return dataModel;
114
- };
115
-
116
- const findHostDataModel = () => {
117
- return findDataModelFor({
118
- arch: process.arch,
119
- platform: process.platform,
120
- });
121
- };
122
-
123
- const findLikelyHostCompiler = () => {
124
- return "gcc";
125
- };
126
-
127
- const define = (builder) => {
128
- const abi = ({ endianness, dataModel, compiler }) => {
129
- return defineWithBuilderAndAbi({
130
- builder,
131
- abi: {
132
- endianness,
133
- dataModel,
134
- compiler,
135
- },
136
- });
137
- };
138
-
139
- const forHost = () => {
140
- const endianness = os.endianness();
141
- const dataModel = findHostDataModel();
142
- const compiler = findLikelyHostCompiler();
143
-
144
- return abi({
145
- endianness,
146
- dataModel,
147
- compiler,
148
- });
149
- };
150
-
151
- return {
152
- abi,
153
- forHost,
154
- };
155
- };
156
-
157
- export default {
158
- define,
159
- };
package/lib/marshaller.js DELETED
@@ -1,88 +0,0 @@
1
- import refbuf from "./refbuf.js";
2
-
3
- const createInterpretingMarshaller = ({ fieldDefinitions, size }) => {
4
- const findReadWriteMethodName = ({ signed, fieldSizeInBits, endianness }) => {
5
- const bigOrNot = fieldSizeInBits === 64 ? "Big" : "";
6
- const signedOrNot = signed ? "" : "U";
7
- const intType = `Int${fieldSizeInBits}`;
8
-
9
- return `${bigOrNot}${signedOrNot}${intType}${endianness || ""}`;
10
- };
11
-
12
- const marshal = ({ data, links }) => {
13
- const result = refbuf.create({ links, size });
14
-
15
- Object.keys(fieldDefinitions).forEach((fieldName) => {
16
- const {
17
- signed,
18
- offset,
19
- size: fieldSize,
20
- endianness,
21
- } = fieldDefinitions[fieldName];
22
-
23
- const fieldSizeInBits = fieldSize * 8;
24
- const writeFuncName = `write${findReadWriteMethodName({
25
- signed,
26
- fieldSizeInBits,
27
- endianness,
28
- })}`;
29
- const valueToWrite = writeFuncName.includes("Big")
30
- ? BigInt(data[fieldName])
31
- : Number(data[fieldName]);
32
-
33
- if (!result[writeFuncName]) {
34
- throw Error(`can't marshal "${fieldName}" ${JSON.stringify(fieldDefinitions[fieldName])}`);
35
- }
36
-
37
- result[writeFuncName](valueToWrite, offset);
38
- });
39
-
40
- return result;
41
- };
42
-
43
- const unmarshal = ({ buffer }) => {
44
- let result = {};
45
-
46
- Object.keys(fieldDefinitions).forEach((fieldName) => {
47
- const {
48
- signed,
49
- offset,
50
- size: fieldSize,
51
- endianness,
52
- } = fieldDefinitions[fieldName];
53
-
54
- const fieldSizeInBits = fieldSize * 8;
55
- const readFuncName = `read${findReadWriteMethodName({
56
- signed,
57
- fieldSizeInBits,
58
- endianness,
59
- })}`;
60
-
61
- if (!buffer[readFuncName]) {
62
- throw Error(`can't unmarshal "${fieldName}" ${JSON.stringify(fieldDefinitions[fieldName])}`);
63
- }
64
-
65
- const val = buffer[readFuncName](offset);
66
-
67
- result = {
68
- ...result,
69
- [fieldName]: BigInt(val),
70
- };
71
- });
72
-
73
- return result;
74
- };
75
-
76
- return {
77
- marshal,
78
- unmarshal,
79
- };
80
- };
81
-
82
- const create = ({ fieldDefinitions, size }) => {
83
- return createInterpretingMarshaller({ fieldDefinitions, size });
84
- };
85
-
86
- export default {
87
- create,
88
- };
package/lib/refbuf.js DELETED
@@ -1,11 +0,0 @@
1
- const create = ({ links, size }) => {
2
- const buf = Buffer.alloc(size);
3
-
4
- buf.referencedBuffers = links;
5
-
6
- return buf;
7
- };
8
-
9
- export default {
10
- create,
11
- };
@@ -1,200 +0,0 @@
1
- const dataAndAlignmentModels = {
2
- LP64: {
3
- gcc: {
4
- Int8: {
5
- signed: true,
6
- align: 1,
7
- size: 1,
8
- },
9
- Int16: {
10
- signed: true,
11
- align: 2,
12
- size: 2,
13
- },
14
- Int32: {
15
- signed: true,
16
- align: 4,
17
- size: 4,
18
- },
19
- Int64: {
20
- signed: true,
21
- align: 8,
22
- size: 8,
23
- },
24
-
25
- UInt8: {
26
- signed: false,
27
- align: 1,
28
- size: 1,
29
- },
30
- UInt16: {
31
- signed: false,
32
- align: 2,
33
- size: 2,
34
- },
35
- UInt32: {
36
- signed: false,
37
- align: 4,
38
- size: 4,
39
- },
40
- UInt64: {
41
- signed: false,
42
- align: 8,
43
- size: 8,
44
- },
45
-
46
- Pointer: {
47
- signed: false,
48
- align: 8,
49
- size: 8,
50
- },
51
- },
52
- },
53
- ILP32: {
54
- gcc: {
55
- Int8: {
56
- signed: true,
57
- align: 1,
58
- size: 1,
59
- },
60
- Int16: {
61
- signed: true,
62
- align: 2,
63
- size: 2,
64
- },
65
- Int32: {
66
- signed: true,
67
- align: 4,
68
- size: 4,
69
- },
70
- Int64: {
71
- signed: true,
72
- align: 8,
73
- size: 8,
74
- },
75
-
76
- UInt8: {
77
- signed: false,
78
- align: 1,
79
- size: 1,
80
- },
81
- UInt16: {
82
- signed: false,
83
- align: 2,
84
- size: 2,
85
- },
86
- UInt32: {
87
- signed: false,
88
- align: 4,
89
- size: 4,
90
- },
91
- UInt64: {
92
- signed: false,
93
- align: 8,
94
- size: 8,
95
- },
96
-
97
- Pointer: {
98
- signed: false,
99
- align: 4,
100
- size: 4,
101
- },
102
- },
103
- },
104
- default: {
105
- Int8: {
106
- signed: true,
107
- align: 1,
108
- size: 1,
109
- },
110
- Int16: {
111
- signed: true,
112
- align: 2,
113
- size: 2,
114
- },
115
- Int32: {
116
- signed: true,
117
- align: 4,
118
- size: 4,
119
- },
120
- Int64: {
121
- signed: true,
122
- align: 8,
123
- size: 8,
124
- },
125
-
126
- UInt8: {
127
- signed: false,
128
- align: 1,
129
- size: 1,
130
- },
131
- UInt16: {
132
- signed: false,
133
- align: 2,
134
- size: 2,
135
- },
136
- UInt32: {
137
- signed: false,
138
- align: 4,
139
- size: 4,
140
- },
141
- UInt64: {
142
- signed: false,
143
- align: 8,
144
- size: 8,
145
- },
146
- },
147
- };
148
-
149
- const abi = ({ dataModel, compiler, endianness: defaultEndianess }) => {
150
- const model =
151
- dataAndAlignmentModels[dataModel]?.[compiler] ||
152
- dataAndAlignmentModels.default;
153
-
154
- const findAlignedOffset = ({ offset, align }) => {
155
- return Math.floor((offset + align - 1) / align) * align;
156
- };
157
-
158
- const type = ({ signed, align, size, endianness }) => {
159
- return ({ offset }) => {
160
- const alignedOffset = findAlignedOffset({ offset, align });
161
-
162
- return {
163
- signed,
164
- offset: alignedOffset,
165
- size,
166
- endianness,
167
- };
168
- };
169
- };
170
-
171
- return {
172
- Int8: type({ ...model.Int8, endianness: undefined }),
173
- Int16: type({ ...model.Int16, endianness: defaultEndianess }),
174
- Int16LE: type({ ...model.Int16, endianness: "LE" }),
175
- Int16BE: type({ ...model.Int16, endianness: "BE" }),
176
- Int32: type({ ...model.Int32, endianness: defaultEndianess }),
177
- Int32LE: type({ ...model.Int32, endianness: "LE" }),
178
- Int32BE: type({ ...model.Int32, endianness: "BE" }),
179
- Int64: type({ ...model.Int64, endianness: defaultEndianess }),
180
- Int64LE: type({ ...model.Int64, endianness: "LE" }),
181
- Int64BE: type({ ...model.Int64, endianness: "BE" }),
182
-
183
- UInt8: type({ ...model.UInt8, endianness: undefined }),
184
- UInt16: type({ ...model.UInt16, endianness: defaultEndianess }),
185
- UInt16LE: type({ ...model.UInt16, endianness: "LE" }),
186
- UInt16BE: type({ ...model.UInt16, endianness: "BE" }),
187
- UInt32: type({ ...model.UInt32, endianness: defaultEndianess }),
188
- UInt32LE: type({ ...model.UInt32, endianness: "LE" }),
189
- UInt32BE: type({ ...model.UInt32, endianness: "BE" }),
190
- UInt64: type({ ...model.UInt64, endianness: defaultEndianess }),
191
- UInt64LE: type({ ...model.UInt64, endianness: "LE" }),
192
- UInt64BE: type({ ...model.UInt64, endianness: "BE" }),
193
-
194
- Pointer: type({ ...model.Pointer, endianness: defaultEndianess }),
195
- };
196
- };
197
-
198
- export default {
199
- abi,
200
- };
@@ -1,160 +0,0 @@
1
- const dataAndAlignmentModels = {
2
- LP64: {
3
- gcc: {
4
- signedChar: {
5
- signed: true,
6
- size: 1,
7
- align: 1,
8
- },
9
- signedShort: {
10
- signed: true,
11
- size: 2,
12
- align: 2,
13
- },
14
- signedInt: {
15
- signed: true,
16
- size: 4,
17
- align: 4,
18
- },
19
- signedLong: {
20
- signed: true,
21
- size: 8,
22
- align: 8,
23
- },
24
- signedLongLong: {
25
- signed: true,
26
- size: 8,
27
- align: 8,
28
- },
29
- unsignedChar: {
30
- signed: false,
31
- size: 1,
32
- align: 1,
33
- },
34
- unsignedShort: {
35
- signed: false,
36
- size: 2,
37
- align: 2,
38
- },
39
- unsignedInt: {
40
- signed: false,
41
- size: 4,
42
- align: 4,
43
- },
44
- unsignedLong: {
45
- signed: false,
46
- size: 8,
47
- align: 8,
48
- },
49
- unsignedLongLong: {
50
- signed: false,
51
- size: 8,
52
- align: 8,
53
- },
54
- },
55
- },
56
- ILP32: {
57
- gcc: {
58
- signedChar: {
59
- signed: true,
60
- size: 1,
61
- align: 1,
62
- },
63
- signedShort: {
64
- signed: true,
65
- size: 2,
66
- align: 2,
67
- },
68
- signedInt: {
69
- signed: true,
70
- size: 4,
71
- align: 4,
72
- },
73
- signedLong: {
74
- signed: true,
75
- size: 4,
76
- align: 4,
77
- },
78
- signedLongLong: {
79
- signed: true,
80
- size: 8,
81
- align: 8,
82
- },
83
- unsignedChar: {
84
- signed: false,
85
- size: 1,
86
- align: 1,
87
- },
88
- unsignedShort: {
89
- signed: false,
90
- size: 2,
91
- align: 2,
92
- },
93
- unsignedInt: {
94
- signed: false,
95
- size: 4,
96
- align: 4,
97
- },
98
- unsignedLong: {
99
- signed: false,
100
- size: 4,
101
- align: 4,
102
- },
103
- unsignedLongLong: {
104
- signed: false,
105
- size: 8,
106
- align: 8,
107
- },
108
- },
109
- },
110
- };
111
-
112
- const abi = ({ dataModel, compiler, endianness }) => {
113
- const model = dataAndAlignmentModels[dataModel]?.[compiler];
114
- if (!model) {
115
- throw Error(
116
- `data model ${dataModel} on compiler ${compiler} not supported`
117
- );
118
- }
119
-
120
- const findAlignedOffset = ({ offset, align }) => {
121
- return Math.floor((offset + align - 1) / align) * align;
122
- };
123
-
124
- const type = ({ signed, size, align }) => {
125
- return ({ offset }) => {
126
- const alignedOffset = findAlignedOffset({ offset, align });
127
-
128
- return {
129
- signed,
130
- offset: alignedOffset,
131
- size,
132
- endianness: size > 1 ? endianness : undefined,
133
- };
134
- };
135
- };
136
-
137
- return {
138
- char: type(model.signedChar),
139
- short: type(model.signedShort),
140
- int: type(model.signedInt),
141
- long: type(model.signedLong),
142
- longLong: type(model.signedLongLong),
143
-
144
- signedChar: type(model.signedChar),
145
- signedShort: type(model.signedShort),
146
- signedInt: type(model.signedInt),
147
- signedLong: type(model.signedLong),
148
- signedLongLong: type(model.signedLongLong),
149
-
150
- unsignedChar: type(model.unsignedChar),
151
- unsignedShort: type(model.unsignedShort),
152
- unsignedInt: type(model.unsignedInt),
153
- unsignedLong: type(model.unsignedLong),
154
- unsignedLongLong: type(model.unsignedLongLong),
155
- };
156
- };
157
-
158
- export default {
159
- abi,
160
- };