ya-struct 0.0.1 → 0.0.5

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: 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
+ };
@@ -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.1",
4
+ "version": "0.0.5",
5
5
  "description": "Yet Another Node.js Structure API",
6
6
  "main": "lib/index.js",
7
7
  "scripts": {
@@ -29,15 +29,13 @@
29
29
  },
30
30
  "homepage": "https://github.com/k13-engineering/node-ya-struct#readme",
31
31
  "dependencies": {
32
- "buffer2address": "^0.0.1"
32
+ "buffer2address": "^0.0.2"
33
33
  },
34
34
  "devDependencies": {
35
- "@babel/core": "^7.12.3",
36
- "@babel/eslint-parser": "^7.12.1",
37
- "@babel/plugin-syntax-top-level-await": "^7.12.1",
38
- "c8": "^7.3.0",
39
- "eslint": "^7.9.0",
40
- "mocha": "^8.1.3",
41
- "node-archibald": "^0.0.5"
35
+ "c8": "^7.9.0",
36
+ "eslint": "^7.32.0",
37
+ "mocha": "^9.1.1",
38
+ "node-archibald": "^0.0.6",
39
+ "tmp-promise": "^3.0.3"
42
40
  }
43
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
- });
14
- });
15
- });
16
-
17
8
  const testEndiannessFor = ({ endianness }) => {
18
9
  it("should support structure definition", () => {
19
- const def = struct.abi({ endianness }).define(({ field }) => {
20
- field.UInt32("myfield1");
21
- field.UInt32("myfield2");
22
- });
23
-
24
- assert.equal(def.size, 8);
25
- assert.equal(def.offsetof("myfield1"), 0);
26
- assert.equal(def.sizeof("myfield1"), 4);
27
- assert.equal(def.offsetof("myfield2"), 4);
28
- assert.equal(def.sizeof("myfield2"), 4);
10
+ const def = struct
11
+ .define(({ field }) => {
12
+ field.UInt32("myfield1");
13
+ field.UInt32("myfield2");
14
+ })
15
+ .abi({ endianness });
16
+
17
+ assert.strictEqual(def.size, 8);
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.abi({ endianness }).define(({ field }) => {
33
- field.UInt32("myfield1");
34
- field.UInt32("myfield2");
35
- });
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
 
@@ -40,59 +35,66 @@ describe("abi", () => {
40
35
  buf[`writeUInt32${endianness}`](30, 4);
41
36
 
42
37
  const data = def.parse(buf);
43
- assert.equal(data.myfield1, 20n);
44
- assert.equal(data.myfield2, 30n);
38
+ assert.strictEqual(data.myfield1, 20n);
39
+ assert.strictEqual(data.myfield2, 30n);
45
40
  });
46
41
 
47
42
  it("should format data correctly", () => {
48
- const def = struct.abi({ endianness }).define(({ field }) => {
49
- field.UInt32("myfield1");
50
- field.UInt32("myfield2");
51
- });
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);
59
56
  const myfield2 = buf[`readUInt32${endianness}`](4);
60
57
 
61
- assert.equal(myfield1, 20n);
62
- assert.equal(myfield2, 30n);
58
+ assert.strictEqual(myfield1, 20);
59
+ assert.strictEqual(myfield2, 30);
63
60
  });
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", () => {
75
72
  describe("LP64", () => {
76
- const structAbi = struct.abi({ "endianness": "LE", "dataModel": "LP64" });
73
+ const endianness = "LE";
74
+ const dataModel = "LP64";
77
75
 
78
76
  it("should support structure definition", () => {
79
- const def = structAbi.define(({ field }) => {
80
- field.Pointer("myfield1");
81
- field.Pointer("myfield2");
82
- });
83
-
84
- assert.equal(def.size, 16);
85
- assert.equal(def.offsetof("myfield1"), 0);
86
- assert.equal(def.sizeof("myfield1"), 8);
87
- assert.equal(def.offsetof("myfield2"), 8);
88
- assert.equal(def.sizeof("myfield2"), 8);
77
+ const def = struct
78
+ .define(({ field }) => {
79
+ field.Pointer("myfield1");
80
+ field.Pointer("myfield2");
81
+ })
82
+ .abi({ endianness, dataModel });
83
+
84
+ assert.strictEqual(def.size, 16);
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);
89
89
  });
90
90
 
91
91
  it("should parse data correctly", () => {
92
- const def = structAbi.define(({ field }) => {
93
- field.Pointer("myfield1");
94
- field.Pointer("myfield2");
95
- });
92
+ const def = struct
93
+ .define(({ field }) => {
94
+ field.Pointer("myfield1");
95
+ field.Pointer("myfield2");
96
+ })
97
+ .abi({ endianness, dataModel });
96
98
 
97
99
  const buf = def.format({});
98
100
 
@@ -100,35 +102,93 @@ describe("abi", () => {
100
102
  buf.writeBigUInt64LE(30n, 8);
101
103
 
102
104
  const data = def.parse(buf);
103
- assert.equal(data.myfield1, 20n);
104
- assert.equal(data.myfield2, 30n);
105
+ assert.strictEqual(data.myfield1, 20n);
106
+ assert.strictEqual(data.myfield2, 30n);
105
107
  });
106
108
 
107
109
  it("should format data correctly", () => {
108
- const def = structAbi.define(({ field }) => {
109
- field.Pointer("myfield1");
110
- field.Pointer("myfield2");
111
- });
110
+ const def = struct
111
+ .define(({ field }) => {
112
+ field.Pointer("myfield1");
113
+ field.Pointer("myfield2");
114
+ })
115
+ .abi({ endianness, dataModel });
112
116
 
113
117
  const buf = def.format({
114
- "myfield1": 20n,
115
- "myfield2": 30n
118
+ myfield1: 20n,
119
+ myfield2: 30n,
116
120
  });
117
121
 
118
122
  const myfield1 = buf.readBigUInt64LE(0);
119
123
  const myfield2 = buf.readBigUInt64LE(8);
120
124
 
121
- assert.equal(myfield1, 20n);
122
- assert.equal(myfield2, 30n);
125
+ assert.strictEqual(myfield1, 20n);
126
+ assert.strictEqual(myfield2, 30n);
127
+ });
128
+ });
129
+ });
130
+
131
+ describe("alignment models", () => {
132
+ describe("LP64 - gcc", () => {
133
+ const endianness = "LE";
134
+ const dataModel = "LP64";
135
+ const compiler = "gcc";
136
+
137
+ it("should align Int8 correctly", () => {
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);
147
+ });
148
+
149
+ it("should align Int16 correctly", () => {
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);
159
+ });
160
+
161
+ it("should align Int32 correctly", () => {
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);
171
+ });
172
+
173
+ it("should align Int64 correctly", () => {
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);
123
183
  });
124
184
  });
125
185
  });
126
186
 
127
187
  const supportedAbiPlatforms = [
128
188
  {
129
- "arch": "x64",
130
- "platform": "linux"
131
- }
189
+ arch: "x64",
190
+ platform: "linux",
191
+ },
132
192
  ];
133
193
 
134
194
  const isHostSupported = supportedAbiPlatforms.some(({ arch, platform }) => {
@@ -137,7 +197,7 @@ describe("abi", () => {
137
197
 
138
198
  describe("host detection", () => {
139
199
  (isHostSupported ? it : it.skip)("should detect host without error", () => {
140
- struct.forHost();
200
+ struct.define(() => {}).forHost();
141
201
  });
142
202
  });
143
203
  });