swf-toolkit 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.
Files changed (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -2
  3. package/README.tr.md +126 -0
  4. package/dist/abc/abc-file.d.ts +168 -0
  5. package/dist/abc/abc-file.js +656 -0
  6. package/dist/abc/analysis.d.ts +36 -0
  7. package/dist/abc/analysis.js +213 -0
  8. package/dist/abc/code.d.ts +59 -0
  9. package/dist/abc/code.js +379 -0
  10. package/dist/abc/constants.d.ts +80 -0
  11. package/dist/abc/constants.js +93 -0
  12. package/dist/abc/interner.d.ts +46 -0
  13. package/dist/abc/interner.js +168 -0
  14. package/dist/abc/model.d.ts +40 -0
  15. package/dist/abc/model.js +146 -0
  16. package/dist/abc/opcodes.d.ts +39 -0
  17. package/dist/abc/opcodes.js +196 -0
  18. package/dist/abc/pcode/assembler.d.ts +42 -0
  19. package/dist/abc/pcode/assembler.js +635 -0
  20. package/dist/abc/pcode/disassembler.d.ts +17 -0
  21. package/dist/abc/pcode/disassembler.js +147 -0
  22. package/dist/abc/pcode/format.d.ts +23 -0
  23. package/dist/abc/pcode/format.js +131 -0
  24. package/dist/abc/pcode/lexer.d.ts +34 -0
  25. package/dist/abc/pcode/lexer.js +183 -0
  26. package/dist/assets/assets.d.ts +26 -0
  27. package/dist/assets/assets.js +151 -0
  28. package/dist/assets/images.d.ts +31 -0
  29. package/dist/assets/images.js +238 -0
  30. package/dist/assets/png.d.ts +12 -0
  31. package/dist/assets/png.js +196 -0
  32. package/dist/assets/sounds.d.ts +37 -0
  33. package/dist/assets/sounds.js +236 -0
  34. package/dist/avm1/avm1.d.ts +55 -0
  35. package/dist/avm1/avm1.js +642 -0
  36. package/dist/avm1/project.d.ts +16 -0
  37. package/dist/avm1/project.js +81 -0
  38. package/dist/cjs/abc/abc-file.d.ts +168 -0
  39. package/dist/cjs/abc/abc-file.js +663 -0
  40. package/dist/cjs/abc/analysis.d.ts +36 -0
  41. package/dist/cjs/abc/analysis.js +221 -0
  42. package/dist/cjs/abc/code.d.ts +59 -0
  43. package/dist/cjs/abc/code.js +387 -0
  44. package/dist/cjs/abc/constants.d.ts +80 -0
  45. package/dist/cjs/abc/constants.js +97 -0
  46. package/dist/cjs/abc/interner.d.ts +46 -0
  47. package/dist/cjs/abc/interner.js +172 -0
  48. package/dist/cjs/abc/model.d.ts +40 -0
  49. package/dist/cjs/abc/model.js +155 -0
  50. package/dist/cjs/abc/opcodes.d.ts +39 -0
  51. package/dist/cjs/abc/opcodes.js +201 -0
  52. package/dist/cjs/abc/pcode/assembler.d.ts +42 -0
  53. package/dist/cjs/abc/pcode/assembler.js +640 -0
  54. package/dist/cjs/abc/pcode/disassembler.d.ts +17 -0
  55. package/dist/cjs/abc/pcode/disassembler.js +152 -0
  56. package/dist/cjs/abc/pcode/format.d.ts +23 -0
  57. package/dist/cjs/abc/pcode/format.js +141 -0
  58. package/dist/cjs/abc/pcode/lexer.d.ts +34 -0
  59. package/dist/cjs/abc/pcode/lexer.js +188 -0
  60. package/dist/cjs/assets/assets.d.ts +26 -0
  61. package/dist/cjs/assets/assets.js +159 -0
  62. package/dist/cjs/assets/images.d.ts +31 -0
  63. package/dist/cjs/assets/images.js +246 -0
  64. package/dist/cjs/assets/png.d.ts +12 -0
  65. package/dist/cjs/assets/png.js +202 -0
  66. package/dist/cjs/assets/sounds.d.ts +37 -0
  67. package/dist/cjs/assets/sounds.js +246 -0
  68. package/dist/cjs/avm1/avm1.d.ts +55 -0
  69. package/dist/cjs/avm1/avm1.js +649 -0
  70. package/dist/cjs/avm1/project.d.ts +16 -0
  71. package/dist/cjs/avm1/project.js +88 -0
  72. package/dist/cjs/compiler/ast.d.ts +285 -0
  73. package/dist/cjs/compiler/ast.js +3 -0
  74. package/dist/cjs/compiler/class-compiler.d.ts +34 -0
  75. package/dist/cjs/compiler/class-compiler.js +440 -0
  76. package/dist/cjs/compiler/codegen.d.ts +144 -0
  77. package/dist/cjs/compiler/codegen.js +1589 -0
  78. package/dist/cjs/compiler/lexer.d.ts +27 -0
  79. package/dist/cjs/compiler/lexer.js +254 -0
  80. package/dist/cjs/compiler/parser.d.ts +58 -0
  81. package/dist/cjs/compiler/parser.js +989 -0
  82. package/dist/cjs/compiler/program.d.ts +29 -0
  83. package/dist/cjs/compiler/program.js +36 -0
  84. package/dist/cjs/compiler/scope.d.ts +22 -0
  85. package/dist/cjs/compiler/scope.js +242 -0
  86. package/dist/cjs/compression/lzma.d.ts +37 -0
  87. package/dist/cjs/compression/lzma.js +575 -0
  88. package/dist/cjs/compression/swf-container.d.ts +19 -0
  89. package/dist/cjs/compression/swf-container.js +92 -0
  90. package/dist/cjs/decompiler/ast.d.ts +228 -0
  91. package/dist/cjs/decompiler/ast.js +455 -0
  92. package/dist/cjs/decompiler/cfg.d.ts +40 -0
  93. package/dist/cjs/decompiler/cfg.js +236 -0
  94. package/dist/cjs/decompiler/class-printer.d.ts +9 -0
  95. package/dist/cjs/decompiler/class-printer.js +173 -0
  96. package/dist/cjs/decompiler/method.d.ts +41 -0
  97. package/dist/cjs/decompiler/method.js +436 -0
  98. package/dist/cjs/decompiler/simulate.d.ts +55 -0
  99. package/dist/cjs/decompiler/simulate.js +591 -0
  100. package/dist/cjs/decompiler/structure.d.ts +48 -0
  101. package/dist/cjs/decompiler/structure.js +764 -0
  102. package/dist/cjs/errors.d.ts +11 -0
  103. package/dist/cjs/errors.js +25 -0
  104. package/dist/cjs/index.d.ts +41 -0
  105. package/dist/cjs/index.js +82 -0
  106. package/dist/cjs/io/reader.d.ts +48 -0
  107. package/dist/cjs/io/reader.js +180 -0
  108. package/dist/cjs/io/writer.d.ts +37 -0
  109. package/dist/cjs/io/writer.js +175 -0
  110. package/dist/cjs/package.json +1 -0
  111. package/dist/cjs/project/pcode-project.d.ts +32 -0
  112. package/dist/cjs/project/pcode-project.js +210 -0
  113. package/dist/cjs/project/source-export.d.ts +12 -0
  114. package/dist/cjs/project/source-export.js +51 -0
  115. package/dist/cjs/project/source-import.d.ts +13 -0
  116. package/dist/cjs/project/source-import.js +73 -0
  117. package/dist/cjs/swf/swf.d.ts +63 -0
  118. package/dist/cjs/swf/swf.js +147 -0
  119. package/dist/cjs/swf/tag-codes.d.ts +77 -0
  120. package/dist/cjs/swf/tag-codes.js +109 -0
  121. package/dist/cjs/swf/tags.d.ts +118 -0
  122. package/dist/cjs/swf/tags.js +330 -0
  123. package/dist/cli.d.ts +2 -0
  124. package/dist/cli.js +296 -0
  125. package/dist/compiler/ast.d.ts +285 -0
  126. package/dist/compiler/ast.js +2 -0
  127. package/dist/compiler/class-compiler.d.ts +34 -0
  128. package/dist/compiler/class-compiler.js +437 -0
  129. package/dist/compiler/codegen.d.ts +144 -0
  130. package/dist/compiler/codegen.js +1585 -0
  131. package/dist/compiler/lexer.d.ts +27 -0
  132. package/dist/compiler/lexer.js +249 -0
  133. package/dist/compiler/parser.d.ts +58 -0
  134. package/dist/compiler/parser.js +984 -0
  135. package/dist/compiler/program.d.ts +29 -0
  136. package/dist/compiler/program.js +32 -0
  137. package/dist/compiler/scope.d.ts +22 -0
  138. package/dist/compiler/scope.js +238 -0
  139. package/dist/compression/lzma.d.ts +37 -0
  140. package/dist/compression/lzma.js +569 -0
  141. package/dist/compression/swf-container.d.ts +19 -0
  142. package/dist/compression/swf-container.js +87 -0
  143. package/dist/decompiler/ast.d.ts +228 -0
  144. package/dist/decompiler/ast.js +441 -0
  145. package/dist/decompiler/cfg.d.ts +40 -0
  146. package/dist/decompiler/cfg.js +231 -0
  147. package/dist/decompiler/class-printer.d.ts +9 -0
  148. package/dist/decompiler/class-printer.js +170 -0
  149. package/dist/decompiler/method.d.ts +41 -0
  150. package/dist/decompiler/method.js +427 -0
  151. package/dist/decompiler/simulate.d.ts +55 -0
  152. package/dist/decompiler/simulate.js +586 -0
  153. package/dist/decompiler/structure.d.ts +48 -0
  154. package/dist/decompiler/structure.js +760 -0
  155. package/dist/errors.d.ts +11 -0
  156. package/dist/errors.js +20 -0
  157. package/dist/index.d.ts +41 -0
  158. package/dist/index.js +49 -0
  159. package/dist/io/reader.d.ts +48 -0
  160. package/dist/io/reader.js +176 -0
  161. package/dist/io/writer.d.ts +37 -0
  162. package/dist/io/writer.js +169 -0
  163. package/dist/project/pcode-project.d.ts +32 -0
  164. package/dist/project/pcode-project.js +203 -0
  165. package/dist/project/source-export.d.ts +12 -0
  166. package/dist/project/source-export.js +47 -0
  167. package/dist/project/source-import.d.ts +13 -0
  168. package/dist/project/source-import.js +70 -0
  169. package/dist/swf/swf.d.ts +63 -0
  170. package/dist/swf/swf.js +143 -0
  171. package/dist/swf/tag-codes.d.ts +77 -0
  172. package/dist/swf/tag-codes.js +105 -0
  173. package/dist/swf/tags.d.ts +118 -0
  174. package/dist/swf/tags.js +316 -0
  175. package/package.json +71 -4
@@ -0,0 +1,11 @@
1
+ /** Thrown when SWF / ABC binary data is malformed or truncated. */
2
+ export declare class SwfFormatError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ /** Thrown by the P-code assembler, with source position information. */
6
+ export declare class AssemblerError extends Error {
7
+ readonly line: number;
8
+ readonly column: number;
9
+ readonly source?: string;
10
+ constructor(message: string, line: number, column: number, source?: string);
11
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,20 @@
1
+ /** Thrown when SWF / ABC binary data is malformed or truncated. */
2
+ export class SwfFormatError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = 'SwfFormatError';
6
+ }
7
+ }
8
+ /** Thrown by the P-code assembler, with source position information. */
9
+ export class AssemblerError extends Error {
10
+ line;
11
+ column;
12
+ source;
13
+ constructor(message, line, column, source) {
14
+ super(`${source ? source + ':' : ''}${line}:${column}: ${message}`);
15
+ this.name = 'AssemblerError';
16
+ this.line = line;
17
+ this.column = column;
18
+ this.source = source;
19
+ }
20
+ }
@@ -0,0 +1,41 @@
1
+ export * from './errors.js';
2
+ export { ByteReader } from './io/reader.js';
3
+ export { ByteWriter } from './io/writer.js';
4
+ export * from './compression/lzma.js';
5
+ export * from './compression/swf-container.js';
6
+ export * from './swf/tag-codes.js';
7
+ export * from './swf/tags.js';
8
+ export * from './swf/swf.js';
9
+ export * from './abc/constants.js';
10
+ export * from './abc/abc-file.js';
11
+ export * from './abc/opcodes.js';
12
+ export * from './abc/code.js';
13
+ export * from './abc/analysis.js';
14
+ export * from './abc/interner.js';
15
+ export * from './abc/model.js';
16
+ export * from './abc/pcode/format.js';
17
+ export * from './abc/pcode/disassembler.js';
18
+ export * from './abc/pcode/assembler.js';
19
+ export { tokenizeLine } from './abc/pcode/lexer.js';
20
+ export * from './project/pcode-project.js';
21
+ export * from './decompiler/ast.js';
22
+ export { buildCfg, findLoops, dominates, type Cfg, type Block, type Loop } from './decompiler/cfg.js';
23
+ export { simulate, SimulationError, type MethodContext, type Terminator } from './decompiler/simulate.js';
24
+ export { Structurer } from './decompiler/structure.js';
25
+ export * from './decompiler/method.js';
26
+ export * from './decompiler/class-printer.js';
27
+ export * from './project/source-export.js';
28
+ export { CompileError, tokenize as tokenizeAs3 } from './compiler/lexer.js';
29
+ export type * as As3Ast from './compiler/ast.js';
30
+ export { parseAs3, Parser as As3Parser } from './compiler/parser.js';
31
+ export { FunctionCompiler, TOPLEVEL_NAMES, type ClassScope, type FunctionOptions } from './compiler/codegen.js';
32
+ export { buildClassScope } from './compiler/scope.js';
33
+ export * from './compiler/class-compiler.js';
34
+ export * from './compiler/program.js';
35
+ export * from './project/source-import.js';
36
+ export * from './assets/png.js';
37
+ export * from './assets/images.js';
38
+ export * from './assets/sounds.js';
39
+ export * from './assets/assets.js';
40
+ export * from './avm1/avm1.js';
41
+ export * from './avm1/project.js';
package/dist/index.js ADDED
@@ -0,0 +1,49 @@
1
+ export * from './errors.js';
2
+ export { ByteReader } from './io/reader.js';
3
+ export { ByteWriter } from './io/writer.js';
4
+ // Compression
5
+ export * from './compression/lzma.js';
6
+ export * from './compression/swf-container.js';
7
+ // SWF container and tags
8
+ export * from './swf/tag-codes.js';
9
+ export * from './swf/tags.js';
10
+ export * from './swf/swf.js';
11
+ // AVM2 / ABC
12
+ export * from './abc/constants.js';
13
+ export * from './abc/abc-file.js';
14
+ export * from './abc/opcodes.js';
15
+ export * from './abc/code.js';
16
+ export * from './abc/analysis.js';
17
+ export * from './abc/interner.js';
18
+ export * from './abc/model.js';
19
+ // P-code
20
+ export * from './abc/pcode/format.js';
21
+ export * from './abc/pcode/disassembler.js';
22
+ export * from './abc/pcode/assembler.js';
23
+ export { tokenizeLine } from './abc/pcode/lexer.js';
24
+ // Project-level workflows
25
+ export * from './project/pcode-project.js';
26
+ // Decompiler
27
+ export * from './decompiler/ast.js';
28
+ export { buildCfg, findLoops, dominates } from './decompiler/cfg.js';
29
+ export { simulate, SimulationError } from './decompiler/simulate.js';
30
+ export { Structurer } from './decompiler/structure.js';
31
+ export * from './decompiler/method.js';
32
+ export * from './decompiler/class-printer.js';
33
+ export * from './project/source-export.js';
34
+ // Compiler
35
+ export { CompileError, tokenize as tokenizeAs3 } from './compiler/lexer.js';
36
+ export { parseAs3, Parser as As3Parser } from './compiler/parser.js';
37
+ export { FunctionCompiler, TOPLEVEL_NAMES } from './compiler/codegen.js';
38
+ export { buildClassScope } from './compiler/scope.js';
39
+ export * from './compiler/class-compiler.js';
40
+ export * from './compiler/program.js';
41
+ export * from './project/source-import.js';
42
+ // Assets
43
+ export * from './assets/png.js';
44
+ export * from './assets/images.js';
45
+ export * from './assets/sounds.js';
46
+ export * from './assets/assets.js';
47
+ // AVM1 (AS1/AS2)
48
+ export * from './avm1/avm1.js';
49
+ export * from './avm1/project.js';
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Little-endian binary reader with SWF bit-field support.
3
+ *
4
+ * Bit reads (`ub`, `sb`, `fb`) share an internal bit buffer; any byte-aligned
5
+ * read implicitly re-aligns to the next byte boundary, as required by the SWF
6
+ * specification.
7
+ */
8
+ export declare class ByteReader {
9
+ readonly bytes: Uint8Array;
10
+ readonly view: DataView;
11
+ pos: number;
12
+ readonly end: number;
13
+ private bitBuf;
14
+ private bitCount;
15
+ constructor(bytes: Uint8Array, start?: number, end?: number);
16
+ get remaining(): number;
17
+ get eof(): boolean;
18
+ private need;
19
+ align(): void;
20
+ u8(): number;
21
+ s8(): number;
22
+ u16(): number;
23
+ s16(): number;
24
+ u24(): number;
25
+ s24(): number;
26
+ u32(): number;
27
+ s32(): number;
28
+ f32(): number;
29
+ f64(): number;
30
+ /** 8.8 fixed point. */
31
+ fixed8(): number;
32
+ /** 16.16 fixed point. */
33
+ fixed(): number;
34
+ bytesView(n: number): Uint8Array;
35
+ /** Copy of the next `n` bytes. */
36
+ bytesCopy(n: number): Uint8Array;
37
+ rest(): Uint8Array;
38
+ /** Null-terminated UTF-8 string. */
39
+ cstring(): string;
40
+ /** Unsigned bit field (MSB first). */
41
+ ub(n: number): number;
42
+ /** Signed bit field. */
43
+ sb(n: number): number;
44
+ /** Signed 16.16 fixed-point bit field. */
45
+ fb(n: number): number;
46
+ /** SWF EncodedU32 / AVM2 variable-length unsigned 32-bit integer. */
47
+ encodedU32(): number;
48
+ }
@@ -0,0 +1,176 @@
1
+ import { SwfFormatError } from '../errors.js';
2
+ const utf8Decoder = new TextDecoder('utf-8');
3
+ /**
4
+ * Little-endian binary reader with SWF bit-field support.
5
+ *
6
+ * Bit reads (`ub`, `sb`, `fb`) share an internal bit buffer; any byte-aligned
7
+ * read implicitly re-aligns to the next byte boundary, as required by the SWF
8
+ * specification.
9
+ */
10
+ export class ByteReader {
11
+ bytes;
12
+ view;
13
+ pos;
14
+ end;
15
+ bitBuf = 0;
16
+ bitCount = 0;
17
+ constructor(bytes, start = 0, end = bytes.length) {
18
+ this.bytes = bytes;
19
+ this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
20
+ this.pos = start;
21
+ this.end = end;
22
+ }
23
+ get remaining() {
24
+ return this.end - this.pos;
25
+ }
26
+ get eof() {
27
+ return this.pos >= this.end;
28
+ }
29
+ need(n) {
30
+ if (this.pos + n > this.end) {
31
+ throw new SwfFormatError(`Unexpected end of data at offset ${this.pos} (need ${n} byte(s), ${this.remaining} left)`);
32
+ }
33
+ }
34
+ align() {
35
+ this.bitCount = 0;
36
+ this.bitBuf = 0;
37
+ }
38
+ u8() {
39
+ this.align();
40
+ this.need(1);
41
+ return this.bytes[this.pos++];
42
+ }
43
+ s8() {
44
+ const v = this.u8();
45
+ return v >= 0x80 ? v - 0x100 : v;
46
+ }
47
+ u16() {
48
+ this.align();
49
+ this.need(2);
50
+ const v = this.view.getUint16(this.pos, true);
51
+ this.pos += 2;
52
+ return v;
53
+ }
54
+ s16() {
55
+ this.align();
56
+ this.need(2);
57
+ const v = this.view.getInt16(this.pos, true);
58
+ this.pos += 2;
59
+ return v;
60
+ }
61
+ u24() {
62
+ this.align();
63
+ this.need(3);
64
+ const b = this.bytes;
65
+ const v = b[this.pos] | (b[this.pos + 1] << 8) | (b[this.pos + 2] << 16);
66
+ this.pos += 3;
67
+ return v;
68
+ }
69
+ s24() {
70
+ const v = this.u24();
71
+ return v & 0x800000 ? v - 0x1000000 : v;
72
+ }
73
+ u32() {
74
+ this.align();
75
+ this.need(4);
76
+ const v = this.view.getUint32(this.pos, true);
77
+ this.pos += 4;
78
+ return v;
79
+ }
80
+ s32() {
81
+ this.align();
82
+ this.need(4);
83
+ const v = this.view.getInt32(this.pos, true);
84
+ this.pos += 4;
85
+ return v;
86
+ }
87
+ f32() {
88
+ this.align();
89
+ this.need(4);
90
+ const v = this.view.getFloat32(this.pos, true);
91
+ this.pos += 4;
92
+ return v;
93
+ }
94
+ f64() {
95
+ this.align();
96
+ this.need(8);
97
+ const v = this.view.getFloat64(this.pos, true);
98
+ this.pos += 8;
99
+ return v;
100
+ }
101
+ /** 8.8 fixed point. */
102
+ fixed8() {
103
+ return this.s16() / 256;
104
+ }
105
+ /** 16.16 fixed point. */
106
+ fixed() {
107
+ return this.s32() / 65536;
108
+ }
109
+ bytesView(n) {
110
+ this.align();
111
+ this.need(n);
112
+ const v = this.bytes.subarray(this.pos, this.pos + n);
113
+ this.pos += n;
114
+ return v;
115
+ }
116
+ /** Copy of the next `n` bytes. */
117
+ bytesCopy(n) {
118
+ return this.bytesView(n).slice();
119
+ }
120
+ rest() {
121
+ return this.bytesView(this.remaining);
122
+ }
123
+ /** Null-terminated UTF-8 string. */
124
+ cstring() {
125
+ this.align();
126
+ const start = this.pos;
127
+ while (this.pos < this.end && this.bytes[this.pos] !== 0)
128
+ this.pos++;
129
+ if (this.pos >= this.end)
130
+ throw new SwfFormatError(`Unterminated string at offset ${start}`);
131
+ const s = utf8Decoder.decode(this.bytes.subarray(start, this.pos));
132
+ this.pos++;
133
+ return s;
134
+ }
135
+ /** Unsigned bit field (MSB first). */
136
+ ub(n) {
137
+ let result = 0;
138
+ for (let i = 0; i < n; i++) {
139
+ if (this.bitCount === 0) {
140
+ this.need(1);
141
+ this.bitBuf = this.bytes[this.pos++];
142
+ this.bitCount = 8;
143
+ }
144
+ this.bitCount--;
145
+ result = result * 2 + ((this.bitBuf >> this.bitCount) & 1);
146
+ }
147
+ return result;
148
+ }
149
+ /** Signed bit field. */
150
+ sb(n) {
151
+ if (n === 0)
152
+ return 0;
153
+ const v = this.ub(n);
154
+ const sign = 2 ** (n - 1);
155
+ return v >= sign ? v - 2 * sign : v;
156
+ }
157
+ /** Signed 16.16 fixed-point bit field. */
158
+ fb(n) {
159
+ return this.sb(n) / 65536;
160
+ }
161
+ /** SWF EncodedU32 / AVM2 variable-length unsigned 32-bit integer. */
162
+ encodedU32() {
163
+ this.align();
164
+ let result = 0;
165
+ let shift = 0;
166
+ for (let i = 0; i < 5; i++) {
167
+ this.need(1);
168
+ const b = this.bytes[this.pos++];
169
+ result += (b & 0x7f) * 2 ** shift;
170
+ if ((b & 0x80) === 0)
171
+ break;
172
+ shift += 7;
173
+ }
174
+ return result >>> 0;
175
+ }
176
+ }
@@ -0,0 +1,37 @@
1
+ /** Growable little-endian binary writer with SWF bit-field support. */
2
+ export declare class ByteWriter {
3
+ private buf;
4
+ private view;
5
+ length: number;
6
+ private bitBuf;
7
+ private bitCount;
8
+ constructor(initialCapacity?: number);
9
+ private ensure;
10
+ /** Flush pending bits (pads the current byte with zeros). */
11
+ align(): void;
12
+ u8(v: number): this;
13
+ s8(v: number): this;
14
+ u16(v: number): this;
15
+ s16(v: number): this;
16
+ u24(v: number): this;
17
+ s24(v: number): this;
18
+ u32(v: number): this;
19
+ s32(v: number): this;
20
+ f32(v: number): this;
21
+ f64(v: number): this;
22
+ fixed8(v: number): this;
23
+ fixed(v: number): this;
24
+ bytes(data: Uint8Array): this;
25
+ cstring(s: string): this;
26
+ ub(n: number, v: number): this;
27
+ sb(n: number, v: number): this;
28
+ fb(n: number, v: number): this;
29
+ encodedU32(v: number): this;
30
+ /** Overwrite a little-endian u32 at an absolute offset. */
31
+ patchU32(offset: number, v: number): void;
32
+ toBytes(): Uint8Array;
33
+ }
34
+ /** Number of bits needed to store `v` as an unsigned bit field. */
35
+ export declare function unsignedBits(v: number): number;
36
+ /** Number of bits needed to store `v` as a signed bit field. */
37
+ export declare function signedBits(v: number): number;
@@ -0,0 +1,169 @@
1
+ const utf8Encoder = new TextEncoder();
2
+ /** Growable little-endian binary writer with SWF bit-field support. */
3
+ export class ByteWriter {
4
+ buf;
5
+ view;
6
+ length = 0;
7
+ bitBuf = 0;
8
+ bitCount = 0;
9
+ constructor(initialCapacity = 1024) {
10
+ this.buf = new Uint8Array(Math.max(16, initialCapacity));
11
+ this.view = new DataView(this.buf.buffer);
12
+ }
13
+ ensure(n) {
14
+ const required = this.length + n;
15
+ if (required <= this.buf.length)
16
+ return;
17
+ let cap = this.buf.length * 2;
18
+ while (cap < required)
19
+ cap *= 2;
20
+ const next = new Uint8Array(cap);
21
+ next.set(this.buf.subarray(0, this.length));
22
+ this.buf = next;
23
+ this.view = new DataView(next.buffer);
24
+ }
25
+ /** Flush pending bits (pads the current byte with zeros). */
26
+ align() {
27
+ if (this.bitCount > 0) {
28
+ this.ensure(1);
29
+ this.buf[this.length++] = (this.bitBuf << (8 - this.bitCount)) & 0xff;
30
+ this.bitBuf = 0;
31
+ this.bitCount = 0;
32
+ }
33
+ }
34
+ u8(v) {
35
+ this.align();
36
+ this.ensure(1);
37
+ this.buf[this.length++] = v & 0xff;
38
+ return this;
39
+ }
40
+ s8(v) {
41
+ return this.u8(v < 0 ? v + 0x100 : v);
42
+ }
43
+ u16(v) {
44
+ this.align();
45
+ this.ensure(2);
46
+ this.view.setUint16(this.length, v & 0xffff, true);
47
+ this.length += 2;
48
+ return this;
49
+ }
50
+ s16(v) {
51
+ this.align();
52
+ this.ensure(2);
53
+ this.view.setInt16(this.length, v, true);
54
+ this.length += 2;
55
+ return this;
56
+ }
57
+ u24(v) {
58
+ this.align();
59
+ this.ensure(3);
60
+ const x = v & 0xffffff;
61
+ this.buf[this.length++] = x & 0xff;
62
+ this.buf[this.length++] = (x >> 8) & 0xff;
63
+ this.buf[this.length++] = (x >> 16) & 0xff;
64
+ return this;
65
+ }
66
+ s24(v) {
67
+ return this.u24(v < 0 ? v + 0x1000000 : v);
68
+ }
69
+ u32(v) {
70
+ this.align();
71
+ this.ensure(4);
72
+ this.view.setUint32(this.length, v >>> 0, true);
73
+ this.length += 4;
74
+ return this;
75
+ }
76
+ s32(v) {
77
+ this.align();
78
+ this.ensure(4);
79
+ this.view.setInt32(this.length, v | 0, true);
80
+ this.length += 4;
81
+ return this;
82
+ }
83
+ f32(v) {
84
+ this.align();
85
+ this.ensure(4);
86
+ this.view.setFloat32(this.length, v, true);
87
+ this.length += 4;
88
+ return this;
89
+ }
90
+ f64(v) {
91
+ this.align();
92
+ this.ensure(8);
93
+ this.view.setFloat64(this.length, v, true);
94
+ this.length += 8;
95
+ return this;
96
+ }
97
+ fixed8(v) {
98
+ return this.s16(Math.round(v * 256));
99
+ }
100
+ fixed(v) {
101
+ return this.s32(Math.round(v * 65536));
102
+ }
103
+ bytes(data) {
104
+ this.align();
105
+ this.ensure(data.length);
106
+ this.buf.set(data, this.length);
107
+ this.length += data.length;
108
+ return this;
109
+ }
110
+ cstring(s) {
111
+ this.bytes(utf8Encoder.encode(s));
112
+ return this.u8(0);
113
+ }
114
+ ub(n, v) {
115
+ for (let i = n - 1; i >= 0; i--) {
116
+ const bit = Math.floor(v / 2 ** i) & 1;
117
+ this.bitBuf = (this.bitBuf << 1) | bit;
118
+ this.bitCount++;
119
+ if (this.bitCount === 8) {
120
+ this.ensure(1);
121
+ this.buf[this.length++] = this.bitBuf & 0xff;
122
+ this.bitBuf = 0;
123
+ this.bitCount = 0;
124
+ }
125
+ }
126
+ return this;
127
+ }
128
+ sb(n, v) {
129
+ return this.ub(n, v < 0 ? v + 2 ** n : v);
130
+ }
131
+ fb(n, v) {
132
+ return this.sb(n, Math.round(v * 65536));
133
+ }
134
+ encodedU32(v) {
135
+ this.align();
136
+ let x = v >>> 0;
137
+ do {
138
+ let b = x & 0x7f;
139
+ x = x >>> 7;
140
+ if (x !== 0)
141
+ b |= 0x80;
142
+ this.u8(b);
143
+ } while (x !== 0);
144
+ return this;
145
+ }
146
+ /** Overwrite a little-endian u32 at an absolute offset. */
147
+ patchU32(offset, v) {
148
+ this.view.setUint32(offset, v >>> 0, true);
149
+ }
150
+ toBytes() {
151
+ this.align();
152
+ return this.buf.slice(0, this.length);
153
+ }
154
+ }
155
+ /** Number of bits needed to store `v` as an unsigned bit field. */
156
+ export function unsignedBits(v) {
157
+ let n = 0;
158
+ while (v > 0) {
159
+ n++;
160
+ v = Math.floor(v / 2);
161
+ }
162
+ return n;
163
+ }
164
+ /** Number of bits needed to store `v` as a signed bit field. */
165
+ export function signedBits(v) {
166
+ if (v === 0)
167
+ return 0;
168
+ return unsignedBits(v < 0 ? -v - 1 : v) + 1;
169
+ }
@@ -0,0 +1,32 @@
1
+ import type { Swf } from '../swf/swf.js';
2
+ export declare const MANIFEST_NAME = "swf-toolkit.json";
3
+ /** Make a class / package name safe as a path segment on all platforms. */
4
+ export declare function safeSegment(s: string): string;
5
+ export interface ExportPcodeResult {
6
+ outDir: string;
7
+ files: string[];
8
+ methodCount: number;
9
+ }
10
+ /** Writes one `.pcode` file per class (plus a manifest) into `outDir`. */
11
+ export declare function exportPcode(swf: Swf, outDir: string): Promise<ExportPcodeResult>;
12
+ /** Splits a P-code document into `method ... end` blocks with their method index. */
13
+ export declare function splitMethodBlocks(text: string): Array<{
14
+ text: string;
15
+ startLine: number;
16
+ methodIndex: number | 'new';
17
+ }>;
18
+ export interface ImportPcodeResult {
19
+ /** Methods that were re-assembled. */
20
+ changed: Array<{
21
+ file: string;
22
+ methodIndex: number;
23
+ }>;
24
+ /** Number of method blocks that were identical to the current SWF. */
25
+ unchanged: number;
26
+ }
27
+ export interface ImportPcodeOptions {
28
+ /** Only import these files (paths relative to the project dir). */
29
+ files?: string[];
30
+ }
31
+ /** Applies edited `.pcode` files from `dir` (created by {@link exportPcode}) to `swf`. */
32
+ export declare function importPcode(swf: Swf, dir: string, options?: ImportPcodeOptions): Promise<ImportPcodeResult>;