@isopodlabs/binary_libs 0.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/.vscode/tasks.json +39 -0
- package/README.md +60 -0
- package/dist/CompoundDocument.d.ts +129 -0
- package/dist/CompoundDocument.js +301 -0
- package/dist/arch.d.ts +41 -0
- package/dist/arch.js +94 -0
- package/dist/binary.d.ts +397 -0
- package/dist/binary.js +802 -0
- package/dist/binary_helpers.d.ts +69 -0
- package/dist/binary_helpers.js +328 -0
- package/dist/clr.d.ts +63 -0
- package/dist/clr.js +664 -0
- package/dist/elf.d.ts +11 -0
- package/dist/elf.js +791 -0
- package/dist/mach.d.ts +543 -0
- package/dist/mach.js +1034 -0
- package/dist/pe.d.ts +399 -0
- package/dist/pe.js +489 -0
- package/package.json +33 -0
- package/src/CompoundDocument.ts +314 -0
- package/src/arch.ts +76 -0
- package/src/clr.ts +651 -0
- package/src/elf.ts +803 -0
- package/src/mach.ts +1089 -0
- package/src/pe.ts +510 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0.0",
|
|
3
|
+
"tasks": [
|
|
4
|
+
{
|
|
5
|
+
"type": "npm",
|
|
6
|
+
"script": "build",
|
|
7
|
+
"group": "build",
|
|
8
|
+
"problemMatcher": "$tsc",
|
|
9
|
+
"label": "npm: build",
|
|
10
|
+
"detail": "tsc"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "shell",
|
|
14
|
+
"label": "prepublish",
|
|
15
|
+
"command": "git add .; npm version ${input:version} --force",
|
|
16
|
+
"windows": {
|
|
17
|
+
"command": "git add . & npm version ${input:version} --force",
|
|
18
|
+
},
|
|
19
|
+
"problemMatcher": [],
|
|
20
|
+
"dependsOn": "npm: build"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "shell",
|
|
24
|
+
"label": "PUBLISH",
|
|
25
|
+
"command": "npm publish --access public",
|
|
26
|
+
"problemMatcher": [],
|
|
27
|
+
"dependsOn": "prepublish"
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
"inputs": [
|
|
31
|
+
{
|
|
32
|
+
"id": "version",
|
|
33
|
+
"description": "Version bump:",
|
|
34
|
+
"type": "pickString",
|
|
35
|
+
"options": ["patch", "minor", "major"],
|
|
36
|
+
"default": "none"
|
|
37
|
+
},
|
|
38
|
+
]
|
|
39
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# my-binary-package/my-binary-package/README.md
|
|
2
|
+
|
|
3
|
+
# My Binary Package
|
|
4
|
+
|
|
5
|
+
This package provides a set of utilities for reading and writing binary data in TypeScript. It includes various interfaces, types, and functions to facilitate binary data manipulation.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
To install the package, use npm:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
npm install my-binary-package
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
Here is a basic example of how to use the package:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { stream, ReadStruct, WriteStruct } from 'my-binary-package';
|
|
21
|
+
|
|
22
|
+
// Create a new stream from a Uint8Array
|
|
23
|
+
const data = new Uint8Array([/* binary data */]);
|
|
24
|
+
const binaryStream = new stream(data);
|
|
25
|
+
|
|
26
|
+
// Define a structure to read from the stream
|
|
27
|
+
const MyStruct = ReadStruct({
|
|
28
|
+
// Define your structure here
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Read data from the stream
|
|
32
|
+
const myData = new MyStruct(binaryStream);
|
|
33
|
+
|
|
34
|
+
// Write data back to the stream
|
|
35
|
+
const writeStream = new stream(new Uint8Array(1024));
|
|
36
|
+
const myWriteStruct = WriteStruct({
|
|
37
|
+
// Define your structure here
|
|
38
|
+
});
|
|
39
|
+
myWriteStruct.put(writeStream, myData);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Key Features
|
|
43
|
+
|
|
44
|
+
- **Interfaces**:
|
|
45
|
+
- `_stream`: Base interface for stream handling.
|
|
46
|
+
- `TypeReaderT`, `TypeWriterT`, `TypeT`: Types for reading and writing binary data.
|
|
47
|
+
- `ReadType`: Type for reading structured data.
|
|
48
|
+
|
|
49
|
+
- **Functions**:
|
|
50
|
+
- `ReadStruct`: Create a reader for a specific structure.
|
|
51
|
+
- `WriteStruct`: Create a writer for a specific structure.
|
|
52
|
+
- `read`, `write`: Functions for reading and writing binary data.
|
|
53
|
+
|
|
54
|
+
## Contributing
|
|
55
|
+
|
|
56
|
+
Contributions are welcome! Please open an issue or submit a pull request for any enhancements or bug fixes.
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
|
|
60
|
+
This project is licensed under the MIT License. See the LICENSE file for more details.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import * as binary from '@isopodlabs/binary';
|
|
2
|
+
declare class FAT {
|
|
3
|
+
shift: number;
|
|
4
|
+
sectors: Uint8Array;
|
|
5
|
+
fat: Int32Array;
|
|
6
|
+
freed: number[];
|
|
7
|
+
dirty_fat: Set<number>;
|
|
8
|
+
dirty_sec: Set<number>;
|
|
9
|
+
constructor(size: number, shift: number, sectors: Uint8Array);
|
|
10
|
+
private free;
|
|
11
|
+
private alloc;
|
|
12
|
+
get_chain(id: number): number[];
|
|
13
|
+
resize_chain(chain: number[], data_size: number): void;
|
|
14
|
+
clear_dirty(): void;
|
|
15
|
+
read_chain(chain: number[], dest: Uint8Array): void;
|
|
16
|
+
read_chain_alloc(chain: number[]): Uint8Array;
|
|
17
|
+
read(id: number, dest: Uint8Array): void;
|
|
18
|
+
write_chain(chain: number[], source: Uint8Array): void;
|
|
19
|
+
dirty_chain_part(chain: number[], offset: number): Uint8Array;
|
|
20
|
+
}
|
|
21
|
+
declare const Header_base: (new (s: binary._stream) => {
|
|
22
|
+
magic: bigint;
|
|
23
|
+
id: any;
|
|
24
|
+
revision: number;
|
|
25
|
+
version: number;
|
|
26
|
+
byteorder: number;
|
|
27
|
+
sector_shift: number;
|
|
28
|
+
mini_shift: number;
|
|
29
|
+
unused1: void;
|
|
30
|
+
num_directory: number;
|
|
31
|
+
num_fat: number;
|
|
32
|
+
first_directory: number;
|
|
33
|
+
transaction: void;
|
|
34
|
+
mini_cutoff: number;
|
|
35
|
+
first_mini: number;
|
|
36
|
+
num_mini: number;
|
|
37
|
+
first_difat: number;
|
|
38
|
+
num_difat: number;
|
|
39
|
+
difat: any;
|
|
40
|
+
} & {} & {
|
|
41
|
+
write(w: binary._stream): void;
|
|
42
|
+
}) & {
|
|
43
|
+
get: (s: binary._stream) => {
|
|
44
|
+
magic: bigint;
|
|
45
|
+
id: any;
|
|
46
|
+
revision: number;
|
|
47
|
+
version: number;
|
|
48
|
+
byteorder: number;
|
|
49
|
+
sector_shift: number;
|
|
50
|
+
mini_shift: number;
|
|
51
|
+
unused1: void;
|
|
52
|
+
num_directory: number;
|
|
53
|
+
num_fat: number;
|
|
54
|
+
first_directory: number;
|
|
55
|
+
transaction: void;
|
|
56
|
+
mini_cutoff: number;
|
|
57
|
+
first_mini: number;
|
|
58
|
+
num_mini: number;
|
|
59
|
+
first_difat: number;
|
|
60
|
+
num_difat: number;
|
|
61
|
+
difat: any;
|
|
62
|
+
} & {};
|
|
63
|
+
put: (s: binary._stream, v: any) => void;
|
|
64
|
+
};
|
|
65
|
+
export declare class Header extends Header_base {
|
|
66
|
+
sector_size(): number;
|
|
67
|
+
use_mini(size: number): boolean;
|
|
68
|
+
valid(): boolean;
|
|
69
|
+
}
|
|
70
|
+
declare const DirEntry_base: (new (s: binary._stream) => {
|
|
71
|
+
name: string;
|
|
72
|
+
name_size: number;
|
|
73
|
+
type: number;
|
|
74
|
+
colour: number;
|
|
75
|
+
left: number;
|
|
76
|
+
right: number;
|
|
77
|
+
root: number;
|
|
78
|
+
guid: any;
|
|
79
|
+
flags: number;
|
|
80
|
+
creation: bigint;
|
|
81
|
+
modification: bigint;
|
|
82
|
+
sec_id: number;
|
|
83
|
+
size: number;
|
|
84
|
+
unused: number;
|
|
85
|
+
} & {} & {
|
|
86
|
+
write(w: binary._stream): void;
|
|
87
|
+
}) & {
|
|
88
|
+
get: (s: binary._stream) => {
|
|
89
|
+
name: string;
|
|
90
|
+
name_size: number;
|
|
91
|
+
type: number;
|
|
92
|
+
colour: number;
|
|
93
|
+
left: number;
|
|
94
|
+
right: number;
|
|
95
|
+
root: number;
|
|
96
|
+
guid: any;
|
|
97
|
+
flags: number;
|
|
98
|
+
creation: bigint;
|
|
99
|
+
modification: bigint;
|
|
100
|
+
sec_id: number;
|
|
101
|
+
size: number;
|
|
102
|
+
unused: number;
|
|
103
|
+
} & {};
|
|
104
|
+
put: (s: binary._stream, v: any) => void;
|
|
105
|
+
};
|
|
106
|
+
declare class DirEntry extends DirEntry_base {
|
|
107
|
+
index: number;
|
|
108
|
+
constructor(index: number, r: binary.stream);
|
|
109
|
+
load(fat: FAT): Uint8Array;
|
|
110
|
+
}
|
|
111
|
+
export declare class Master {
|
|
112
|
+
header: Header;
|
|
113
|
+
difat: Int32Array;
|
|
114
|
+
fat: FAT;
|
|
115
|
+
mini_fat: FAT;
|
|
116
|
+
mini_chain: number[];
|
|
117
|
+
constructor(sectors: Uint8Array, header: Header);
|
|
118
|
+
get_fat(mini: boolean): FAT;
|
|
119
|
+
flush(filename: string): Promise<void>;
|
|
120
|
+
}
|
|
121
|
+
export declare class Reader extends Master {
|
|
122
|
+
entries: DirEntry[];
|
|
123
|
+
private entry_chain;
|
|
124
|
+
constructor(sectors: Uint8Array, header: Header);
|
|
125
|
+
find(name: string, i?: number): DirEntry | undefined;
|
|
126
|
+
read(e: DirEntry): Uint8Array;
|
|
127
|
+
write(e: DirEntry, data: Uint8Array): void;
|
|
128
|
+
}
|
|
129
|
+
export {};
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.Reader = exports.Master = exports.Header = void 0;
|
|
27
|
+
const binary = __importStar(require("@isopodlabs/binary"));
|
|
28
|
+
const fs_1 = require("fs");
|
|
29
|
+
class FAT {
|
|
30
|
+
shift;
|
|
31
|
+
sectors;
|
|
32
|
+
fat;
|
|
33
|
+
freed = [];
|
|
34
|
+
dirty_fat = new Set();
|
|
35
|
+
dirty_sec = new Set();
|
|
36
|
+
constructor(size, shift, sectors) {
|
|
37
|
+
this.shift = shift;
|
|
38
|
+
this.sectors = sectors;
|
|
39
|
+
this.fat = new Int32Array(size);
|
|
40
|
+
}
|
|
41
|
+
free(id) {
|
|
42
|
+
this.freed.push(id);
|
|
43
|
+
this.fat[id] = -1 /* SecID.FREE */;
|
|
44
|
+
this.dirty_fat.add(id >> (this.shift - 2));
|
|
45
|
+
}
|
|
46
|
+
alloc(prev) {
|
|
47
|
+
if (!this.freed.length) {
|
|
48
|
+
this.fat.forEach((v, i) => {
|
|
49
|
+
if (v === -1 /* SecID.FREE */)
|
|
50
|
+
this.freed.push(i);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
const id = this.freed.length ? this.freed.pop() : this.fat.length;
|
|
54
|
+
this.fat[prev] = id;
|
|
55
|
+
this.dirty_fat.add(id >> (this.shift - 2));
|
|
56
|
+
return id;
|
|
57
|
+
}
|
|
58
|
+
get_chain(id) {
|
|
59
|
+
const chain = [];
|
|
60
|
+
while (id != -2 /* SecID.ENDOFCHAIN */) {
|
|
61
|
+
chain.push(id);
|
|
62
|
+
id = this.fat[id];
|
|
63
|
+
}
|
|
64
|
+
return chain;
|
|
65
|
+
}
|
|
66
|
+
resize_chain(chain, data_size) {
|
|
67
|
+
const size = (data_size + (1 << this.shift) - 1) >> this.shift;
|
|
68
|
+
while (chain.length > size)
|
|
69
|
+
this.free(chain.pop());
|
|
70
|
+
if (size) {
|
|
71
|
+
let last = chain[size - 1];
|
|
72
|
+
while (chain.length < size)
|
|
73
|
+
chain.push(last = this.alloc(last));
|
|
74
|
+
if (this.fat[last] !== -2 /* SecID.ENDOFCHAIN */) {
|
|
75
|
+
this.fat[last] = -2 /* SecID.ENDOFCHAIN */;
|
|
76
|
+
this.dirty_fat.add(last >> (this.shift - 2));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
chain.push(-2 /* SecID.ENDOFCHAIN */);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
clear_dirty() {
|
|
84
|
+
this.dirty_fat.clear();
|
|
85
|
+
this.dirty_sec.clear();
|
|
86
|
+
}
|
|
87
|
+
read_chain(chain, dest) {
|
|
88
|
+
chain.forEach((id, index) => {
|
|
89
|
+
const id2 = id << this.shift;
|
|
90
|
+
const index2 = index << this.shift;
|
|
91
|
+
dest.set(this.sectors.subarray(id2, id2 + Math.min(dest.length - index2)), index2);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
read_chain_alloc(chain) {
|
|
95
|
+
const dest = new Uint8Array(chain.length << this.shift);
|
|
96
|
+
this.read_chain(chain, dest);
|
|
97
|
+
return dest;
|
|
98
|
+
}
|
|
99
|
+
read(id, dest) {
|
|
100
|
+
this.read_chain(this.get_chain(id), dest);
|
|
101
|
+
}
|
|
102
|
+
write_chain(chain, source) {
|
|
103
|
+
chain.forEach((id, index) => {
|
|
104
|
+
this.sectors.set(source.subarray(index << this.shift, (index + 1) << this.shift), id << this.shift);
|
|
105
|
+
this.dirty_sec.add(id);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
dirty_chain_part(chain, offset) {
|
|
109
|
+
const sector = chain[offset >> this.shift];
|
|
110
|
+
this.dirty_sec.add(sector);
|
|
111
|
+
return this.sectors.subarray((sector << this.shift) + (offset & ((1 << this.shift) - 1)));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
class Header extends binary.ReadWriteStruct({
|
|
115
|
+
magic: binary.UINT64_BE,
|
|
116
|
+
id: binary.Buffer(16),
|
|
117
|
+
revision: binary.UINT16_LE,
|
|
118
|
+
version: binary.UINT16_LE,
|
|
119
|
+
byteorder: binary.UINT16_LE,
|
|
120
|
+
sector_shift: binary.UINT16_LE,
|
|
121
|
+
mini_shift: binary.UINT16_LE,
|
|
122
|
+
unused1: binary.SkipType(6),
|
|
123
|
+
num_directory: binary.UINT32_LE,
|
|
124
|
+
num_fat: binary.UINT32_LE,
|
|
125
|
+
first_directory: binary.UINT32_LE,
|
|
126
|
+
transaction: binary.SkipType(4),
|
|
127
|
+
mini_cutoff: binary.UINT32_LE,
|
|
128
|
+
first_mini: binary.UINT32_LE,
|
|
129
|
+
num_mini: binary.UINT32_LE,
|
|
130
|
+
first_difat: binary.UINT32_LE,
|
|
131
|
+
num_difat: binary.UINT32_LE,
|
|
132
|
+
difat: binary.Buffer(436),
|
|
133
|
+
}) {
|
|
134
|
+
sector_size() { return 1 << this.sector_shift; }
|
|
135
|
+
use_mini(size) { return size < this.mini_cutoff; }
|
|
136
|
+
valid() { return this.magic == 0xd0cf11e0a1b11ae1n; }
|
|
137
|
+
}
|
|
138
|
+
exports.Header = Header;
|
|
139
|
+
const TYPE = {
|
|
140
|
+
Empty: 0,
|
|
141
|
+
UserStorage: 1,
|
|
142
|
+
UserStream: 2,
|
|
143
|
+
LockBytes: 3,
|
|
144
|
+
Property: 4,
|
|
145
|
+
RootStorage: 5,
|
|
146
|
+
};
|
|
147
|
+
const COLOUR = {
|
|
148
|
+
RED: 0, BLACK: 1
|
|
149
|
+
};
|
|
150
|
+
class DirEntry extends binary.ReadWriteStruct({
|
|
151
|
+
name: binary.StringType(64, 'utf16le'),
|
|
152
|
+
name_size: binary.UINT16_LE,
|
|
153
|
+
type: binary.UINT8,
|
|
154
|
+
colour: binary.UINT8,
|
|
155
|
+
left: binary.INT32_LE,
|
|
156
|
+
right: binary.INT32_LE,
|
|
157
|
+
root: binary.INT32_LE,
|
|
158
|
+
guid: binary.Buffer(16),
|
|
159
|
+
flags: binary.UINT32_LE,
|
|
160
|
+
creation: binary.UINT64_LE,
|
|
161
|
+
modification: binary.UINT64_LE,
|
|
162
|
+
sec_id: binary.INT32_LE,
|
|
163
|
+
size: binary.UINT32_LE,
|
|
164
|
+
unused: binary.UINT32_LE
|
|
165
|
+
}) {
|
|
166
|
+
index;
|
|
167
|
+
constructor(index, r) {
|
|
168
|
+
super(r);
|
|
169
|
+
this.index = index;
|
|
170
|
+
this.name = this.name.substring(0, this.name_size / 2 - 1);
|
|
171
|
+
}
|
|
172
|
+
load(fat) {
|
|
173
|
+
const data = new Uint8Array(this.size);
|
|
174
|
+
fat.read(this.sec_id, data);
|
|
175
|
+
return data;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
class Master {
|
|
179
|
+
header;
|
|
180
|
+
difat;
|
|
181
|
+
fat;
|
|
182
|
+
mini_fat;
|
|
183
|
+
mini_chain;
|
|
184
|
+
constructor(sectors, header) {
|
|
185
|
+
this.header = header;
|
|
186
|
+
const shift = header.sector_shift;
|
|
187
|
+
let num = header.num_difat;
|
|
188
|
+
let m_size = 109 + (num << (shift - 2));
|
|
189
|
+
this.difat = new Int32Array(m_size);
|
|
190
|
+
binary.utils.to8(this.difat).set(header.difat, 0);
|
|
191
|
+
let sect = header.first_difat;
|
|
192
|
+
let p = 109 * 4;
|
|
193
|
+
while (num--) {
|
|
194
|
+
const data = sectors.subarray(sect << shift, (sect + 1) << shift);
|
|
195
|
+
const end = data.length - 4;
|
|
196
|
+
sect = new DataView(data.buffer).getUint32(end);
|
|
197
|
+
binary.utils.to8(this.difat).set(data.subarray(0, end), p);
|
|
198
|
+
p += end;
|
|
199
|
+
}
|
|
200
|
+
while (this.difat[m_size - 1] == -1 /* SecID.FREE */)
|
|
201
|
+
--m_size;
|
|
202
|
+
this.fat = new FAT(m_size << (shift - 2), shift, sectors);
|
|
203
|
+
Array.from(this.difat.subarray(0, m_size)).forEach((id, index) => {
|
|
204
|
+
const data = sectors.subarray(id << shift, (id + 1) << shift);
|
|
205
|
+
binary.utils.to8(this.fat.fat).set(data, index << shift);
|
|
206
|
+
});
|
|
207
|
+
const root = new DirEntry(0, new binary.stream(sectors.subarray(header.first_directory << shift)));
|
|
208
|
+
this.mini_chain = this.fat.get_chain(root.sec_id);
|
|
209
|
+
this.mini_fat = new FAT(header.num_mini << (shift - 2), header.mini_shift, root.load(this.fat));
|
|
210
|
+
this.fat.read(header.first_mini, binary.utils.to8(this.mini_fat.fat));
|
|
211
|
+
}
|
|
212
|
+
get_fat(mini) {
|
|
213
|
+
return mini ? this.mini_fat : this.fat;
|
|
214
|
+
}
|
|
215
|
+
async flush(filename) {
|
|
216
|
+
const dirty = new Set(this.fat.dirty_sec);
|
|
217
|
+
function mark_dirty_shift(entries, translate, shift) {
|
|
218
|
+
for (const i of entries)
|
|
219
|
+
dirty.add(translate[i >> shift]);
|
|
220
|
+
}
|
|
221
|
+
const mini_extra = this.fat.shift - this.header.mini_shift;
|
|
222
|
+
mark_dirty_shift(this.fat.dirty_fat.keys(), Array.from(this.difat), 0);
|
|
223
|
+
mark_dirty_shift(this.mini_fat.dirty_sec, this.mini_chain, mini_extra);
|
|
224
|
+
mark_dirty_shift(this.mini_fat.dirty_fat.keys(), this.fat.get_chain(this.header.first_mini), mini_extra);
|
|
225
|
+
if (!dirty.size)
|
|
226
|
+
return;
|
|
227
|
+
let fileHandle;
|
|
228
|
+
try {
|
|
229
|
+
fileHandle = await fs_1.promises.open(filename, 'r+');
|
|
230
|
+
const ss = 1 << this.fat.shift;
|
|
231
|
+
for (const i of dirty.keys()) {
|
|
232
|
+
const position = i * ss;
|
|
233
|
+
await fileHandle.write(this.fat.sectors, position, ss, position + ss);
|
|
234
|
+
}
|
|
235
|
+
this.fat.clear_dirty();
|
|
236
|
+
this.mini_fat.clear_dirty();
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
console.error('An error occurred:', error);
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
if (fileHandle)
|
|
243
|
+
await fileHandle.close();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
exports.Master = Master;
|
|
248
|
+
class Reader extends Master {
|
|
249
|
+
entries = [];
|
|
250
|
+
entry_chain;
|
|
251
|
+
constructor(sectors, header) {
|
|
252
|
+
super(sectors, header);
|
|
253
|
+
this.entry_chain = this.fat.get_chain(header.first_directory);
|
|
254
|
+
const dir_buff = this.fat.read_chain_alloc(this.entry_chain);
|
|
255
|
+
const r2 = new binary.stream(dir_buff);
|
|
256
|
+
for (let i = 0; i < dir_buff.length / 128; i++)
|
|
257
|
+
this.entries[i] = new DirEntry(i, r2.seek(i * 128));
|
|
258
|
+
}
|
|
259
|
+
find(name, i = 0) {
|
|
260
|
+
const stack = [];
|
|
261
|
+
let sp = 0;
|
|
262
|
+
for (;;) {
|
|
263
|
+
const e = this.entries[i];
|
|
264
|
+
if (e.name == name)
|
|
265
|
+
return e;
|
|
266
|
+
if (e.type == TYPE.RootStorage)
|
|
267
|
+
stack[sp++] = e.root;
|
|
268
|
+
if (e.right != -1)
|
|
269
|
+
stack[sp++] = e.right;
|
|
270
|
+
i = e.left;
|
|
271
|
+
if (i == -1) {
|
|
272
|
+
if (sp === 0)
|
|
273
|
+
return undefined;
|
|
274
|
+
i = stack[--sp];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
read(e) {
|
|
279
|
+
const mini = this.header.use_mini(e.size);
|
|
280
|
+
const fat = this.get_fat(mini);
|
|
281
|
+
return e.load(fat);
|
|
282
|
+
}
|
|
283
|
+
write(e, data) {
|
|
284
|
+
const mini1 = this.header.use_mini(e.size);
|
|
285
|
+
const fat1 = this.get_fat(mini1);
|
|
286
|
+
const chain = fat1.get_chain(e.sec_id);
|
|
287
|
+
const mini2 = this.header.use_mini(data.length);
|
|
288
|
+
const fat2 = this.get_fat(mini2);
|
|
289
|
+
if (data.length != e.size) {
|
|
290
|
+
if (mini1 != mini2)
|
|
291
|
+
fat1.resize_chain(chain, 0);
|
|
292
|
+
fat2.resize_chain(chain, data.length);
|
|
293
|
+
e.size = data.length;
|
|
294
|
+
e.sec_id = chain[0];
|
|
295
|
+
const dest = this.fat.dirty_chain_part(this.entry_chain, e.index * 128);
|
|
296
|
+
e.write(new binary.stream(dest));
|
|
297
|
+
}
|
|
298
|
+
fat2.write_chain(chain, data);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
exports.Reader = Reader;
|
package/dist/arch.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as binary from '@isopodlabs/binary';
|
|
2
|
+
declare const AR_MEMBER_HEADER: {
|
|
3
|
+
name: {
|
|
4
|
+
get(s: binary._stream, obj: any): string;
|
|
5
|
+
put(s: binary._stream, v: string): void;
|
|
6
|
+
};
|
|
7
|
+
date: {
|
|
8
|
+
get(s: binary._stream, obj: any): number;
|
|
9
|
+
put(s: binary._stream, v: number): void;
|
|
10
|
+
};
|
|
11
|
+
uid: {
|
|
12
|
+
get(s: binary._stream, obj: any): number;
|
|
13
|
+
put(s: binary._stream, v: number): void;
|
|
14
|
+
};
|
|
15
|
+
gid: {
|
|
16
|
+
get(s: binary._stream, obj: any): number;
|
|
17
|
+
put(s: binary._stream, v: number): void;
|
|
18
|
+
};
|
|
19
|
+
mode: {
|
|
20
|
+
get(s: binary._stream, obj: any): number;
|
|
21
|
+
put(s: binary._stream, v: number): void;
|
|
22
|
+
};
|
|
23
|
+
size: {
|
|
24
|
+
get(s: binary._stream, obj: any): number;
|
|
25
|
+
put(s: binary._stream, v: number): void;
|
|
26
|
+
};
|
|
27
|
+
fmag: {
|
|
28
|
+
get(s: binary._stream, obj: any): string;
|
|
29
|
+
put(s: binary._stream, v: string): void;
|
|
30
|
+
};
|
|
31
|
+
contents: {
|
|
32
|
+
get(s: binary._stream): any;
|
|
33
|
+
put(s: binary._stream, v: any): void;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
export declare class ArchFile {
|
|
37
|
+
members: binary.ReadType<typeof AR_MEMBER_HEADER>[];
|
|
38
|
+
static check(data: Uint8Array): boolean;
|
|
39
|
+
constructor(data: Uint8Array);
|
|
40
|
+
}
|
|
41
|
+
export {};
|
package/dist/arch.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.ArchFile = void 0;
|
|
27
|
+
const binary = __importStar(require("@isopodlabs/binary"));
|
|
28
|
+
const AR_MEMBER_HEADER = {
|
|
29
|
+
name: binary.as(binary.StringType(16), x => { x = x.trim(); return x.endsWith('/') ? x.slice(0, -1) : x; }),
|
|
30
|
+
date: binary.asInt(binary.StringType(12)),
|
|
31
|
+
uid: binary.asInt(binary.StringType(6)),
|
|
32
|
+
gid: binary.asInt(binary.StringType(6)),
|
|
33
|
+
mode: binary.asInt(binary.StringType(8), 8),
|
|
34
|
+
size: binary.asInt(binary.StringType(10)),
|
|
35
|
+
fmag: binary.as(binary.StringType(2), x => x.trim() == '`' ? '' : x),
|
|
36
|
+
contents: binary.DontRead()
|
|
37
|
+
};
|
|
38
|
+
const AR_SYM64 = {
|
|
39
|
+
name: binary.StringType(12),
|
|
40
|
+
offset: binary.asInt(binary.StringType(4))
|
|
41
|
+
};
|
|
42
|
+
class ArchFile {
|
|
43
|
+
members = [];
|
|
44
|
+
static check(data) {
|
|
45
|
+
const x = binary.utils.decodeText(data.subarray(0, 8), 'utf8');
|
|
46
|
+
return x == '!<arch>\n';
|
|
47
|
+
}
|
|
48
|
+
constructor(data) {
|
|
49
|
+
const s = new binary.stream(data);
|
|
50
|
+
const header = binary.read(s, binary.StringType(8));
|
|
51
|
+
if (header !== '!<arch>\n')
|
|
52
|
+
throw new Error('Invalid archive file format');
|
|
53
|
+
let long_names;
|
|
54
|
+
while (s.remaining() > 0) {
|
|
55
|
+
const member = binary.read(s, AR_MEMBER_HEADER);
|
|
56
|
+
const data = s.read_buffer(member.size);
|
|
57
|
+
s.align(2);
|
|
58
|
+
if (member.name == '/') {
|
|
59
|
+
long_names = binary.utils.decodeText(data, 'utf8');
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (member.name[0] == '/' && long_names) {
|
|
63
|
+
const offset = +member.name.substring(1);
|
|
64
|
+
member.name = long_names.substring(offset, long_names.indexOf('/', offset));
|
|
65
|
+
}
|
|
66
|
+
if (member.name == '') {
|
|
67
|
+
const s2 = new binary.stream(data);
|
|
68
|
+
const offsets = binary.ArrayType(binary.INT32_BE, binary.INT32_BE).get(s2);
|
|
69
|
+
member.name = 'Symbols';
|
|
70
|
+
member.contents = offsets.map(offset => [
|
|
71
|
+
binary.NullTerminatedStringType.get(s2),
|
|
72
|
+
offset
|
|
73
|
+
]);
|
|
74
|
+
}
|
|
75
|
+
else if (member.name == '/SYM') {
|
|
76
|
+
const s2 = new binary.stream(data);
|
|
77
|
+
const syms = binary.ArrayType(binary.INT32_BE, binary.NullTerminatedStringType).get(s2);
|
|
78
|
+
member.contents = syms.map(name => ({
|
|
79
|
+
name,
|
|
80
|
+
offset: binary.INT32_BE.get(s2)
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
else if (member.name == '/SYM64') {
|
|
84
|
+
const s2 = new binary.stream(data);
|
|
85
|
+
member.contents = binary.RemainingArrayType(AR_SYM64).get(s2);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
member.contents = data;
|
|
89
|
+
}
|
|
90
|
+
this.members.push(member);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.ArchFile = ArchFile;
|