ya-struct 0.0.3 → 0.0.4

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.
@@ -0,0 +1,200 @@
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 }) => {
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 }) => {
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 }),
174
+ Int16LE: type({ ...model.Int16, endianness: "LE" }),
175
+ Int16BE: type({ ...model.Int16, endianness: "BE" }),
176
+ Int32: type({ ...model.Int32, endianness }),
177
+ Int32LE: type({ ...model.Int32, endianness: "LE" }),
178
+ Int32BE: type({ ...model.Int32, endianness: "BE" }),
179
+ Int64: type({ ...model.Int64, endianness }),
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 }),
185
+ UInt16LE: type({ ...model.UInt16, endianness: "LE" }),
186
+ UInt16BE: type({ ...model.UInt16, endianness: "BE" }),
187
+ UInt32: type({ ...model.UInt32, endianness }),
188
+ UInt32LE: type({ ...model.UInt32, endianness: "LE" }),
189
+ UInt32BE: type({ ...model.UInt32, endianness: "BE" }),
190
+ UInt64: type({ ...model.UInt64, endianness }),
191
+ UInt64LE: type({ ...model.UInt64, endianness: "LE" }),
192
+ UInt64BE: type({ ...model.UInt64, endianness: "BE" }),
193
+
194
+ Pointer: type({ ...model.Pointer, endianness }),
195
+ };
196
+ };
197
+
198
+ export default {
199
+ abi,
200
+ };
@@ -0,0 +1,160 @@
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
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ya-struct",
3
3
  "type": "module",
4
- "version": "0.0.3",
4
+ "version": "0.0.4",
5
5
  "description": "Yet Another Node.js Structure API",
6
6
  "main": "lib/index.js",
7
7
  "scripts": {
@@ -33,8 +33,9 @@
33
33
  },
34
34
  "devDependencies": {
35
35
  "c8": "^7.9.0",
36
- "eslint": "^8.5.0",
36
+ "eslint": "^7.32.0",
37
37
  "mocha": "^9.1.1",
38
- "node-archibald": "^0.0.5"
38
+ "node-archibald": "^0.0.6",
39
+ "tmp-promise": "^3.0.3"
39
40
  }
40
41
  }
package/test/abi.js CHANGED
@@ -5,34 +5,29 @@ import struct from "../lib/index.js";
5
5
  import assert from "assert";
6
6
 
7
7
  describe("abi", () => {
8
- it("should not support endian-less types without ABI specification", () => {
9
- assert.throws(() => {
10
- struct.define(({ field }) => {
11
- field.UInt32("myfield1");
12
- field.UInt32("myfield2");
13
- }).abi({});
14
- });
15
- });
16
-
17
8
  const testEndiannessFor = ({ endianness }) => {
18
9
  it("should support structure definition", () => {
19
- const def = struct.define(({ field }) => {
20
- field.UInt32("myfield1");
21
- field.UInt32("myfield2");
22
- }).abi({ endianness });
10
+ const def = struct
11
+ .define(({ field }) => {
12
+ field.UInt32("myfield1");
13
+ field.UInt32("myfield2");
14
+ })
15
+ .abi({ endianness });
23
16
 
24
17
  assert.strictEqual(def.size, 8);
25
- assert.strictEqual(def.offsetof("myfield1"), 0);
26
- assert.strictEqual(def.sizeof("myfield1"), 4);
27
- assert.strictEqual(def.offsetof("myfield2"), 4);
28
- assert.strictEqual(def.sizeof("myfield2"), 4);
18
+ assert.strictEqual(def.fields.myfield1.offset, 0);
19
+ assert.strictEqual(def.fields.myfield1.size, 4);
20
+ assert.strictEqual(def.fields.myfield2.offset, 4);
21
+ assert.strictEqual(def.fields.myfield2.size, 4);
29
22
  });
30
23
 
31
24
  it("should parse data correctly", () => {
32
- const def = struct.define(({ field }) => {
33
- field.UInt32("myfield1");
34
- field.UInt32("myfield2");
35
- }).abi({ endianness });
25
+ const def = struct
26
+ .define(({ field }) => {
27
+ field.UInt32("myfield1");
28
+ field.UInt32("myfield2");
29
+ })
30
+ .abi({ endianness });
36
31
 
37
32
  const buf = def.format({});
38
33
 
@@ -45,14 +40,16 @@ describe("abi", () => {
45
40
  });
46
41
 
47
42
  it("should format data correctly", () => {
48
- const def = struct.define(({ field }) => {
49
- field.UInt32("myfield1");
50
- field.UInt32("myfield2");
51
- }).abi({ endianness });
43
+ const def = struct
44
+ .define(({ field }) => {
45
+ field.UInt32("myfield1");
46
+ field.UInt32("myfield2");
47
+ })
48
+ .abi({ endianness });
52
49
 
53
50
  const buf = def.format({
54
- "myfield1": 20n,
55
- "myfield2": 30n
51
+ myfield1: 20n,
52
+ myfield2: 30n,
56
53
  });
57
54
 
58
55
  const myfield1 = buf[`readUInt32${endianness}`](0);
@@ -64,11 +61,11 @@ describe("abi", () => {
64
61
  };
65
62
 
66
63
  describe("little endian", () => {
67
- testEndiannessFor({ "endianness": "LE" });
64
+ testEndiannessFor({ endianness: "LE" });
68
65
  });
69
66
 
70
67
  describe("big endian", () => {
71
- testEndiannessFor({ "endianness": "BE" });
68
+ testEndiannessFor({ endianness: "BE" });
72
69
  });
73
70
 
74
71
  describe("data models", () => {
@@ -77,23 +74,27 @@ describe("abi", () => {
77
74
  const dataModel = "LP64";
78
75
 
79
76
  it("should support structure definition", () => {
80
- const def = struct.define(({ field }) => {
81
- field.Pointer("myfield1");
82
- field.Pointer("myfield2");
83
- }).abi({ endianness, dataModel });
77
+ const def = struct
78
+ .define(({ field }) => {
79
+ field.Pointer("myfield1");
80
+ field.Pointer("myfield2");
81
+ })
82
+ .abi({ endianness, dataModel });
84
83
 
85
84
  assert.strictEqual(def.size, 16);
86
- assert.strictEqual(def.offsetof("myfield1"), 0);
87
- assert.strictEqual(def.sizeof("myfield1"), 8);
88
- assert.strictEqual(def.offsetof("myfield2"), 8);
89
- assert.strictEqual(def.sizeof("myfield2"), 8);
85
+ assert.strictEqual(def.fields.myfield1.offset, 0);
86
+ assert.strictEqual(def.fields.myfield1.size, 8);
87
+ assert.strictEqual(def.fields.myfield2.offset, 8);
88
+ assert.strictEqual(def.fields.myfield2.size, 8);
90
89
  });
91
90
 
92
91
  it("should parse data correctly", () => {
93
- const def = struct.define(({ field }) => {
94
- field.Pointer("myfield1");
95
- field.Pointer("myfield2");
96
- }).abi({ endianness, dataModel });
92
+ const def = struct
93
+ .define(({ field }) => {
94
+ field.Pointer("myfield1");
95
+ field.Pointer("myfield2");
96
+ })
97
+ .abi({ endianness, dataModel });
97
98
 
98
99
  const buf = def.format({});
99
100
 
@@ -106,14 +107,16 @@ describe("abi", () => {
106
107
  });
107
108
 
108
109
  it("should format data correctly", () => {
109
- const def = struct.define(({ field }) => {
110
- field.Pointer("myfield1");
111
- field.Pointer("myfield2");
112
- }).abi({ endianness, dataModel });
110
+ const def = struct
111
+ .define(({ field }) => {
112
+ field.Pointer("myfield1");
113
+ field.Pointer("myfield2");
114
+ })
115
+ .abi({ endianness, dataModel });
113
116
 
114
117
  const buf = def.format({
115
- "myfield1": 20n,
116
- "myfield2": 30n
118
+ myfield1: 20n,
119
+ myfield2: 30n,
117
120
  });
118
121
 
119
122
  const myfield1 = buf.readBigUInt64LE(0);
@@ -129,55 +132,63 @@ describe("abi", () => {
129
132
  describe("LP64 - gcc", () => {
130
133
  const endianness = "LE";
131
134
  const dataModel = "LP64";
132
- const alignmentModel = struct.alignmentModels.LP64.gcc;
135
+ const compiler = "gcc";
133
136
 
134
137
  it("should align Int8 correctly", () => {
135
- const def = struct.define(({ field }) => {
136
- field.Int8("myfield1");
137
- field.Int8("myfield2");
138
- }).abi({ endianness, dataModel, alignmentModel });
139
-
140
- assert.strictEqual(def.offsetof("myfield1"), 0);
141
- assert.strictEqual(def.offsetof("myfield2"), 1);
138
+ const def = struct
139
+ .define(({ field }) => {
140
+ field.Int8("myfield1");
141
+ field.Int8("myfield2");
142
+ })
143
+ .abi({ endianness, dataModel, compiler });
144
+
145
+ assert.strictEqual(def.fields.myfield1.offset, 0);
146
+ assert.strictEqual(def.fields.myfield2.offset, 1);
142
147
  });
143
148
 
144
149
  it("should align Int16 correctly", () => {
145
- const def = struct.define(({ field }) => {
146
- field.Int8("myfield1");
147
- field.Int16LE("myfield2");
148
- }).abi({ endianness, dataModel, alignmentModel });
149
-
150
- assert.strictEqual(def.offsetof("myfield1"), 0);
151
- assert.strictEqual(def.offsetof("myfield2"), 2);
150
+ const def = struct
151
+ .define(({ field }) => {
152
+ field.Int8("myfield1");
153
+ field.Int16LE("myfield2");
154
+ })
155
+ .abi({ endianness, dataModel, compiler });
156
+
157
+ assert.strictEqual(def.fields.myfield1.offset, 0);
158
+ assert.strictEqual(def.fields.myfield2.offset, 2);
152
159
  });
153
160
 
154
161
  it("should align Int32 correctly", () => {
155
- const def = struct.define(({ field }) => {
156
- field.Int8("myfield1");
157
- field.Int32LE("myfield2");
158
- }).abi({ endianness, dataModel, alignmentModel });
159
-
160
- assert.strictEqual(def.offsetof("myfield1"), 0);
161
- assert.strictEqual(def.offsetof("myfield2"), 4);
162
+ const def = struct
163
+ .define(({ field }) => {
164
+ field.Int8("myfield1");
165
+ field.Int32LE("myfield2");
166
+ })
167
+ .abi({ endianness, dataModel, compiler });
168
+
169
+ assert.strictEqual(def.fields.myfield1.offset, 0);
170
+ assert.strictEqual(def.fields.myfield2.offset, 4);
162
171
  });
163
172
 
164
173
  it("should align Int64 correctly", () => {
165
- const def = struct.define(({ field }) => {
166
- field.Int8("myfield1");
167
- field.Int64LE("myfield2");
168
- }).abi({ endianness, dataModel, alignmentModel });
169
-
170
- assert.strictEqual(def.offsetof("myfield1"), 0);
171
- assert.strictEqual(def.offsetof("myfield2"), 8);
174
+ const def = struct
175
+ .define(({ field }) => {
176
+ field.Int8("myfield1");
177
+ field.Int64LE("myfield2");
178
+ })
179
+ .abi({ endianness, dataModel, compiler });
180
+
181
+ assert.strictEqual(def.fields.myfield1.offset, 0);
182
+ assert.strictEqual(def.fields.myfield2.offset, 8);
172
183
  });
173
184
  });
174
185
  });
175
186
 
176
187
  const supportedAbiPlatforms = [
177
188
  {
178
- "arch": "x64",
179
- "platform": "linux"
180
- }
189
+ arch: "x64",
190
+ platform: "linux",
191
+ },
181
192
  ];
182
193
 
183
194
  const isHostSupported = supportedAbiPlatforms.some(({ arch, platform }) => {