@swf2es/format 0.0.0-stage → 0.1.0
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/LICENSE +202 -0
- package/LICENSE.third-party +35 -0
- package/README.md +22 -2
- package/dist/abc-names.d.ts +3 -0
- package/dist/abc-names.d.ts.map +1 -0
- package/dist/abc-names.js +127 -0
- package/dist/abc-names.js.map +1 -0
- package/dist/actions.d.ts +106 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +223 -0
- package/dist/actions.js.map +1 -0
- package/dist/air-descriptor.d.ts +11 -0
- package/dist/air-descriptor.d.ts.map +1 -0
- package/dist/air-descriptor.js +64 -0
- package/dist/air-descriptor.js.map +1 -0
- package/dist/api-versions.d.ts +12 -0
- package/dist/api-versions.d.ts.map +1 -0
- package/dist/api-versions.js +23 -0
- package/dist/api-versions.js.map +1 -0
- package/dist/bitmap.d.ts +34 -0
- package/dist/bitmap.d.ts.map +1 -0
- package/dist/bitmap.js +200 -0
- package/dist/bitmap.js.map +1 -0
- package/dist/button.d.ts +39 -0
- package/dist/button.d.ts.map +1 -0
- package/dist/button.js +61 -0
- package/dist/button.js.map +1 -0
- package/dist/compression.d.ts +47 -0
- package/dist/compression.d.ts.map +1 -0
- package/dist/compression.js +201 -0
- package/dist/compression.js.map +1 -0
- package/dist/display.d.ts +106 -0
- package/dist/display.d.ts.map +1 -0
- package/dist/display.js +306 -0
- package/dist/display.js.map +1 -0
- package/dist/filters.d.ts +66 -0
- package/dist/filters.d.ts.map +1 -0
- package/dist/filters.js +137 -0
- package/dist/filters.js.map +1 -0
- package/dist/font.d.ts +60 -0
- package/dist/font.d.ts.map +1 -0
- package/dist/font.js +169 -0
- package/dist/font.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/lzma.d.ts +33 -0
- package/dist/lzma.d.ts.map +1 -0
- package/dist/lzma.js +279 -0
- package/dist/lzma.js.map +1 -0
- package/dist/pbj.d.ts +178 -0
- package/dist/pbj.d.ts.map +1 -0
- package/dist/pbj.js +485 -0
- package/dist/pbj.js.map +1 -0
- package/dist/shape.d.ts +152 -0
- package/dist/shape.d.ts.map +1 -0
- package/dist/shape.js +412 -0
- package/dist/shape.js.map +1 -0
- package/dist/sound.d.ts +71 -0
- package/dist/sound.d.ts.map +1 -0
- package/dist/sound.js +92 -0
- package/dist/sound.js.map +1 -0
- package/dist/swf.d.ts +77 -0
- package/dist/swf.d.ts.map +1 -0
- package/dist/swf.js +164 -0
- package/dist/swf.js.map +1 -0
- package/dist/tags.d.ts +57 -0
- package/dist/tags.d.ts.map +1 -0
- package/dist/tags.js +59 -0
- package/dist/tags.js.map +1 -0
- package/dist/text.d.ts +75 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +136 -0
- package/dist/text.js.map +1 -0
- package/dist/zip.d.ts +17 -0
- package/dist/zip.d.ts.map +1 -0
- package/dist/zip.js +92 -0
- package/dist/zip.js.map +1 -0
- package/package.json +33 -3
- package/src/abc-names.ts +138 -0
- package/src/actions.ts +319 -0
- package/src/air-descriptor.ts +84 -0
- package/src/api-versions.ts +27 -0
- package/src/bitmap.ts +259 -0
- package/src/button.ts +99 -0
- package/src/compression.ts +243 -0
- package/src/display.ts +419 -0
- package/src/filters.ts +206 -0
- package/src/font.ts +238 -0
- package/src/index.ts +151 -0
- package/src/pbj.ts +651 -0
- package/src/shape.ts +618 -0
- package/src/sound.ts +173 -0
- package/src/swf.ts +234 -0
- package/src/tags.ts +58 -0
- package/src/text.ts +213 -0
- package/src/zip.ts +135 -0
package/src/zip.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// A ZIP archive's files, as an AIR package (`.air`) and any zip of an
|
|
2
|
+
// application's folder hold them: the central directory read from the
|
|
3
|
+
// archive's end, each file stored or deflated. Enough for what packagers
|
|
4
|
+
// write; ZIP64, encryption and the other methods are refused.
|
|
5
|
+
import { zlibUncompress } from "./compression.js";
|
|
6
|
+
import { utf8 } from "./display.js";
|
|
7
|
+
|
|
8
|
+
const END_SIGNATURE = 0x06054b50;
|
|
9
|
+
const CENTRAL_SIGNATURE = 0x02014b50;
|
|
10
|
+
const LOCAL_SIGNATURE = 0x04034b50;
|
|
11
|
+
/** The end record's size without its comment, and the most its comment may add. */
|
|
12
|
+
const END_SIZE = 22;
|
|
13
|
+
const MAX_COMMENT = 0xffff;
|
|
14
|
+
const STORED = 0;
|
|
15
|
+
const DEFLATED = 8;
|
|
16
|
+
|
|
17
|
+
export class ZipError extends Error {
|
|
18
|
+
override name = "ZipError";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** One file of an archive; a directory's name ends in "/". */
|
|
22
|
+
export interface ZipEntry {
|
|
23
|
+
/** Its path in the archive, "/"-separated. */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Its uncompressed size in bytes. */
|
|
26
|
+
size: number;
|
|
27
|
+
/** When it was last changed, in ms since 1970, read as local time as DOS's fields are. */
|
|
28
|
+
modified: number;
|
|
29
|
+
/** Its bytes, inflated on each call. */
|
|
30
|
+
bytes(): Uint8Array;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The files of the archive `zip`, in its central directory's order. */
|
|
34
|
+
export function readZip(zip: Uint8Array): ZipEntry[] {
|
|
35
|
+
const view = new DataView(zip.buffer, zip.byteOffset, zip.byteLength);
|
|
36
|
+
const end = findEnd(zip, view);
|
|
37
|
+
const count = view.getUint16(end + 10, true);
|
|
38
|
+
let at = view.getUint32(end + 16, true);
|
|
39
|
+
const entries: ZipEntry[] = [];
|
|
40
|
+
for (let i = 0; i < count; i++) {
|
|
41
|
+
if (at + 46 > zip.length || view.getUint32(at, true) !== CENTRAL_SIGNATURE) {
|
|
42
|
+
throw new ZipError("the central directory is cut short");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const method = view.getUint16(at + 10, true);
|
|
46
|
+
const time = view.getUint16(at + 12, true);
|
|
47
|
+
const date = view.getUint16(at + 14, true);
|
|
48
|
+
const compressed = view.getUint32(at + 20, true);
|
|
49
|
+
const size = view.getUint32(at + 24, true);
|
|
50
|
+
const nameLength = view.getUint16(at + 28, true);
|
|
51
|
+
const extraLength = view.getUint16(at + 30, true);
|
|
52
|
+
const commentLength = view.getUint16(at + 32, true);
|
|
53
|
+
const local = view.getUint32(at + 42, true);
|
|
54
|
+
const name = utf8(zip.subarray(at + 46, at + 46 + nameLength));
|
|
55
|
+
if (compressed === 0xffffffff || size === 0xffffffff || local === 0xffffffff) {
|
|
56
|
+
throw new ZipError(`${name}: ZIP64 archives are not read`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if ((view.getUint16(at + 8, true) & 1) !== 0) {
|
|
60
|
+
throw new ZipError(`${name}: encrypted`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (method !== STORED && method !== DEFLATED) {
|
|
64
|
+
throw new ZipError(`${name}: compression method ${method} is not read`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
entries.push({
|
|
68
|
+
name,
|
|
69
|
+
size,
|
|
70
|
+
modified: dosTime(date, time),
|
|
71
|
+
bytes: () => entryBytes(zip, view, name, local, method, compressed, size),
|
|
72
|
+
});
|
|
73
|
+
at += 46 + nameLength + extraLength + commentLength;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return entries;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Where the end of central directory record starts: the last signature
|
|
81
|
+
* whose comment the archive holds, as some tools leave bytes after it.
|
|
82
|
+
*/
|
|
83
|
+
function findEnd(zip: Uint8Array, view: DataView): number {
|
|
84
|
+
const last = zip.length - END_SIZE;
|
|
85
|
+
for (let at = last; at >= 0 && at >= last - MAX_COMMENT; at--) {
|
|
86
|
+
if (
|
|
87
|
+
view.getUint32(at, true) === END_SIGNATURE &&
|
|
88
|
+
at + END_SIZE + view.getUint16(at + 20, true) <= zip.length
|
|
89
|
+
) {
|
|
90
|
+
return at;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
throw new ZipError("not a ZIP archive: no end of central directory");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function entryBytes(
|
|
98
|
+
zip: Uint8Array,
|
|
99
|
+
view: DataView,
|
|
100
|
+
name: string,
|
|
101
|
+
local: number,
|
|
102
|
+
method: number,
|
|
103
|
+
compressed: number,
|
|
104
|
+
size: number,
|
|
105
|
+
): Uint8Array {
|
|
106
|
+
if (local + 30 > zip.length || view.getUint32(local, true) !== LOCAL_SIGNATURE) {
|
|
107
|
+
throw new ZipError(`${name}: no local header where the directory says`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// The local header's own name and extra lengths, which may differ from the directory's.
|
|
111
|
+
const start = local + 30 + view.getUint16(local + 26, true) + view.getUint16(local + 28, true);
|
|
112
|
+
if (start + compressed > zip.length) {
|
|
113
|
+
throw new ZipError(`${name}: cut short`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const data = zip.subarray(start, start + compressed);
|
|
117
|
+
const bytes = method === STORED ? data.slice() : zlibUncompress(data, true);
|
|
118
|
+
if (bytes.length !== size) {
|
|
119
|
+
throw new ZipError(`${name}: ${bytes.length} bytes where the directory says ${size}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return bytes;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** A DOS date and time (2-second steps) as ms since 1970, read as local time. */
|
|
126
|
+
function dosTime(date: number, time: number): number {
|
|
127
|
+
return new Date(
|
|
128
|
+
1980 + (date >> 9),
|
|
129
|
+
((date >> 5) & 15) - 1,
|
|
130
|
+
date & 31,
|
|
131
|
+
time >> 11,
|
|
132
|
+
(time >> 5) & 63,
|
|
133
|
+
(time & 31) * 2,
|
|
134
|
+
).getTime();
|
|
135
|
+
}
|