@lexmata/micropdf 0.4.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 (170) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +985 -0
  3. package/binding.gyp +73 -0
  4. package/dist/annot.d.ts +458 -0
  5. package/dist/annot.d.ts.map +1 -0
  6. package/dist/annot.js +697 -0
  7. package/dist/annot.js.map +1 -0
  8. package/dist/archive.d.ts +128 -0
  9. package/dist/archive.d.ts.map +1 -0
  10. package/dist/archive.js +268 -0
  11. package/dist/archive.js.map +1 -0
  12. package/dist/buffer.d.ts +572 -0
  13. package/dist/buffer.d.ts.map +1 -0
  14. package/dist/buffer.js +971 -0
  15. package/dist/buffer.js.map +1 -0
  16. package/dist/colorspace.d.ts +287 -0
  17. package/dist/colorspace.d.ts.map +1 -0
  18. package/dist/colorspace.js +542 -0
  19. package/dist/colorspace.js.map +1 -0
  20. package/dist/context.d.ts +184 -0
  21. package/dist/context.d.ts.map +1 -0
  22. package/dist/context.js +320 -0
  23. package/dist/context.js.map +1 -0
  24. package/dist/cookie.d.ts +164 -0
  25. package/dist/cookie.d.ts.map +1 -0
  26. package/dist/cookie.js +306 -0
  27. package/dist/cookie.js.map +1 -0
  28. package/dist/device.d.ts +169 -0
  29. package/dist/device.d.ts.map +1 -0
  30. package/dist/device.js +350 -0
  31. package/dist/device.js.map +1 -0
  32. package/dist/display-list.d.ts +202 -0
  33. package/dist/display-list.d.ts.map +1 -0
  34. package/dist/display-list.js +410 -0
  35. package/dist/display-list.js.map +1 -0
  36. package/dist/document.d.ts +637 -0
  37. package/dist/document.d.ts.map +1 -0
  38. package/dist/document.js +902 -0
  39. package/dist/document.js.map +1 -0
  40. package/dist/easy.d.ts +423 -0
  41. package/dist/easy.d.ts.map +1 -0
  42. package/dist/easy.js +644 -0
  43. package/dist/easy.js.map +1 -0
  44. package/dist/enhanced.d.ts +226 -0
  45. package/dist/enhanced.d.ts.map +1 -0
  46. package/dist/enhanced.js +368 -0
  47. package/dist/enhanced.js.map +1 -0
  48. package/dist/filter.d.ts +51 -0
  49. package/dist/filter.d.ts.map +1 -0
  50. package/dist/filter.js +381 -0
  51. package/dist/filter.js.map +1 -0
  52. package/dist/font.d.ts +222 -0
  53. package/dist/font.d.ts.map +1 -0
  54. package/dist/font.js +381 -0
  55. package/dist/font.js.map +1 -0
  56. package/dist/form.d.ts +214 -0
  57. package/dist/form.d.ts.map +1 -0
  58. package/dist/form.js +497 -0
  59. package/dist/form.js.map +1 -0
  60. package/dist/geometry.d.ts +469 -0
  61. package/dist/geometry.d.ts.map +1 -0
  62. package/dist/geometry.js +780 -0
  63. package/dist/geometry.js.map +1 -0
  64. package/dist/image.d.ts +172 -0
  65. package/dist/image.d.ts.map +1 -0
  66. package/dist/image.js +348 -0
  67. package/dist/image.js.map +1 -0
  68. package/dist/index.d.ts +171 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +339 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/link.d.ts +168 -0
  73. package/dist/link.d.ts.map +1 -0
  74. package/dist/link.js +343 -0
  75. package/dist/link.js.map +1 -0
  76. package/dist/micropdf.d.ts +40 -0
  77. package/dist/micropdf.d.ts.map +1 -0
  78. package/dist/micropdf.js +45 -0
  79. package/dist/micropdf.js.map +1 -0
  80. package/dist/nanopdf.d.ts +40 -0
  81. package/dist/nanopdf.d.ts.map +1 -0
  82. package/dist/nanopdf.js +45 -0
  83. package/dist/nanopdf.js.map +1 -0
  84. package/dist/native.d.ts +242 -0
  85. package/dist/native.d.ts.map +1 -0
  86. package/dist/native.js +509 -0
  87. package/dist/native.js.map +1 -0
  88. package/dist/output.d.ts +166 -0
  89. package/dist/output.d.ts.map +1 -0
  90. package/dist/output.js +365 -0
  91. package/dist/output.js.map +1 -0
  92. package/dist/path.d.ts +420 -0
  93. package/dist/path.d.ts.map +1 -0
  94. package/dist/path.js +687 -0
  95. package/dist/path.js.map +1 -0
  96. package/dist/pdf/object.d.ts +489 -0
  97. package/dist/pdf/object.d.ts.map +1 -0
  98. package/dist/pdf/object.js +1045 -0
  99. package/dist/pdf/object.js.map +1 -0
  100. package/dist/pixmap.d.ts +315 -0
  101. package/dist/pixmap.d.ts.map +1 -0
  102. package/dist/pixmap.js +590 -0
  103. package/dist/pixmap.js.map +1 -0
  104. package/dist/profiler.d.ts +159 -0
  105. package/dist/profiler.d.ts.map +1 -0
  106. package/dist/profiler.js +380 -0
  107. package/dist/profiler.js.map +1 -0
  108. package/dist/render-options.d.ts +227 -0
  109. package/dist/render-options.d.ts.map +1 -0
  110. package/dist/render-options.js +130 -0
  111. package/dist/render-options.js.map +1 -0
  112. package/dist/resource-tracking.d.ts +332 -0
  113. package/dist/resource-tracking.d.ts.map +1 -0
  114. package/dist/resource-tracking.js +653 -0
  115. package/dist/resource-tracking.js.map +1 -0
  116. package/dist/simple.d.ts +276 -0
  117. package/dist/simple.d.ts.map +1 -0
  118. package/dist/simple.js +343 -0
  119. package/dist/simple.js.map +1 -0
  120. package/dist/stext.d.ts +290 -0
  121. package/dist/stext.d.ts.map +1 -0
  122. package/dist/stext.js +312 -0
  123. package/dist/stext.js.map +1 -0
  124. package/dist/stream.d.ts +174 -0
  125. package/dist/stream.d.ts.map +1 -0
  126. package/dist/stream.js +476 -0
  127. package/dist/stream.js.map +1 -0
  128. package/dist/text.d.ts +337 -0
  129. package/dist/text.d.ts.map +1 -0
  130. package/dist/text.js +454 -0
  131. package/dist/text.js.map +1 -0
  132. package/dist/typed-arrays.d.ts +127 -0
  133. package/dist/typed-arrays.d.ts.map +1 -0
  134. package/dist/typed-arrays.js +410 -0
  135. package/dist/typed-arrays.js.map +1 -0
  136. package/dist/types.d.ts +358 -0
  137. package/dist/types.d.ts.map +1 -0
  138. package/dist/types.js +216 -0
  139. package/dist/types.js.map +1 -0
  140. package/native/annot.cc +557 -0
  141. package/native/buffer.cc +204 -0
  142. package/native/colorspace.cc +166 -0
  143. package/native/context.cc +84 -0
  144. package/native/cookie.cc +179 -0
  145. package/native/device.cc +179 -0
  146. package/native/display_list.cc +179 -0
  147. package/native/document.cc +268 -0
  148. package/native/enhanced.cc +70 -0
  149. package/native/font.cc +282 -0
  150. package/native/form.cc +523 -0
  151. package/native/geometry.cc +255 -0
  152. package/native/image.cc +216 -0
  153. package/native/include/micropdf/enhanced.h +38 -0
  154. package/native/include/micropdf/types.h +36 -0
  155. package/native/include/micropdf.h +106 -0
  156. package/native/include/mupdf-ffi.h +39 -0
  157. package/native/include/mupdf.h +11 -0
  158. package/native/include/mupdf_minimal.h +381 -0
  159. package/native/lib/linux-x64/libmicropdf.a +0 -0
  160. package/native/link.cc +234 -0
  161. package/native/micropdf.cc +71 -0
  162. package/native/output.cc +229 -0
  163. package/native/page.cc +572 -0
  164. package/native/path.cc +259 -0
  165. package/native/pixmap.cc +240 -0
  166. package/native/stext.cc +610 -0
  167. package/native/stream.cc +239 -0
  168. package/package.json +120 -0
  169. package/scripts/build-from-rust.js +97 -0
  170. package/scripts/install.js +184 -0
package/dist/buffer.js ADDED
@@ -0,0 +1,971 @@
1
+ /**
2
+ * Buffer - Dynamic byte array wrapper for PDF data manipulation
3
+ *
4
+ * This module provides a flexible buffer implementation for working with binary PDF data.
5
+ * Buffers are used throughout the library for reading, writing, and manipulating
6
+ * PDF content, streams, and binary resources.
7
+ *
8
+ * This implementation mirrors the Rust `fitz::buffer::Buffer` for 100% API compatibility
9
+ * and wraps Node.js Buffer for efficient memory management.
10
+ *
11
+ * @module buffer
12
+ * @example
13
+ * ```typescript
14
+ * import { Buffer } from 'micropdf';
15
+ *
16
+ * // Create from string
17
+ * const buf = Buffer.fromString('Hello, PDF!');
18
+ *
19
+ * // Append data
20
+ * buf.append(Buffer.fromString(' More text.'));
21
+ *
22
+ * // Get as string
23
+ * console.log(buf.toString()); // "Hello, PDF! More text."
24
+ *
25
+ * // Get raw bytes
26
+ * const bytes = buf.toUint8Array();
27
+ *
28
+ * // Get size
29
+ * console.log(buf.length); // 24
30
+ * ```
31
+ */
32
+ import { MicroPDFError, isBufferLike } from './types.js';
33
+ import { createHash } from 'node:crypto';
34
+ // Shared TextDecoder for efficient UTF-8 decoding of large buffers
35
+ const textDecoder = new TextDecoder('utf-8');
36
+ // Threshold in bytes above which TextDecoder is more efficient than Node's toString()
37
+ const TEXT_DECODER_THRESHOLD = 1024;
38
+ // Re-export for convenience
39
+ export { isBufferLike };
40
+ /**
41
+ * A dynamic byte buffer for PDF data manipulation.
42
+ *
43
+ * Buffer provides efficient storage and manipulation of binary data. It's used
44
+ * throughout the library for PDF streams, content, images, and other binary resources.
45
+ *
46
+ * **Key Features:**
47
+ * - Dynamic resizing as data is appended
48
+ * - Zero-copy conversion to/from Node.js Buffer
49
+ * - String encoding/decoding support
50
+ * - Slice and copy operations
51
+ * - Compatible with standard Node.js Buffer operations
52
+ *
53
+ * Mirrors the Rust `Buffer` implementation with `bytes` crate semantics.
54
+ *
55
+ * @class Buffer
56
+ * @example
57
+ * ```typescript
58
+ * // Create empty buffer
59
+ * const buf1 = Buffer.create();
60
+ *
61
+ * // Create from string
62
+ * const buf2 = Buffer.fromString('Hello');
63
+ *
64
+ * // Create from bytes
65
+ * const bytes = new Uint8Array([72, 101, 108, 108, 111]);
66
+ * const buf3 = Buffer.fromUint8Array(bytes);
67
+ *
68
+ * // Append data
69
+ * buf1.append(buf2);
70
+ * buf1.append(Buffer.fromString(' World!'));
71
+ *
72
+ * // Extract data
73
+ * console.log(buf1.toString()); // "Hello World!"
74
+ * console.log(buf1.length); // 12
75
+ *
76
+ * // Slice
77
+ * const hello = buf1.slice(0, 5);
78
+ * console.log(hello.toString()); // "Hello"
79
+ *
80
+ * // Clear
81
+ * buf1.clear();
82
+ * console.log(buf1.length); // 0
83
+ * ```
84
+ */
85
+ export class Buffer {
86
+ /**
87
+ * The underlying Node.js Buffer containing the data.
88
+ * @private
89
+ * @type {globalThis.Buffer}
90
+ */
91
+ _data;
92
+ /**
93
+ * Creates a new Buffer instance.
94
+ *
95
+ * **Note**: Use static factory methods instead of calling this constructor directly.
96
+ *
97
+ * @private
98
+ * @param {globalThis.Buffer} data - The underlying Node.js Buffer
99
+ */
100
+ constructor(data) {
101
+ this._data = data;
102
+ }
103
+ // ============================================================================
104
+ // Static Constructors
105
+ // ============================================================================
106
+ /**
107
+ * Creates a new empty buffer with optional initial capacity.
108
+ *
109
+ * The capacity parameter is a hint for initial memory allocation. The buffer
110
+ * will automatically grow as needed when data is appended.
111
+ *
112
+ * @static
113
+ * @param {number} [capacity=0] - Initial capacity in bytes (optional)
114
+ * @returns {Buffer} A new empty buffer
115
+ * @example
116
+ * ```typescript
117
+ * // Create empty buffer
118
+ * const buf1 = Buffer.create();
119
+ *
120
+ * // Create with initial capacity
121
+ * const buf2 = Buffer.create(1024); // Reserve 1KB
122
+ * ```
123
+ */
124
+ static create(capacity = 0) {
125
+ return new Buffer(globalThis.Buffer.alloc(capacity));
126
+ }
127
+ /**
128
+ * Creates a buffer from a Node.js Buffer (zero-copy).
129
+ *
130
+ * This operation wraps the existing Buffer without copying data, making it
131
+ * very efficient. Modifications to the original Buffer will be visible in
132
+ * the MicroPDF Buffer and vice versa.
133
+ *
134
+ * @static
135
+ * @param {globalThis.Buffer} data - The Node.js Buffer to wrap
136
+ * @returns {Buffer} A new Buffer wrapping the provided data
137
+ * @example
138
+ * ```typescript
139
+ * const nodeBuffer = Buffer.from('Hello');
140
+ * const pdfBuffer = Buffer.fromBuffer(nodeBuffer);
141
+ * console.log(pdfBuffer.toString()); // "Hello"
142
+ * ```
143
+ */
144
+ static fromBuffer(data) {
145
+ return new Buffer(data);
146
+ }
147
+ /**
148
+ * Creates a buffer from a Uint8Array.
149
+ *
150
+ * The data is copied into a new Node.js Buffer.
151
+ *
152
+ * @static
153
+ * @param {Uint8Array} data - The byte array to copy
154
+ * @returns {Buffer} A new Buffer containing the data
155
+ * @example
156
+ * ```typescript
157
+ * const bytes = new Uint8Array([72, 101, 108, 108, 111]);
158
+ * const buf = Buffer.fromUint8Array(bytes);
159
+ * console.log(buf.toString()); // "Hello"
160
+ * ```
161
+ */
162
+ static fromUint8Array(data) {
163
+ return new Buffer(globalThis.Buffer.from(data));
164
+ }
165
+ /**
166
+ * Creates a buffer from an ArrayBuffer.
167
+ *
168
+ * Useful for working with binary data from various Web APIs and file operations.
169
+ *
170
+ * @static
171
+ * @param {ArrayBuffer} data - The ArrayBuffer to convert
172
+ * @returns {Buffer} A new Buffer containing the data
173
+ * @example
174
+ * ```typescript
175
+ * const arrayBuffer = new ArrayBuffer(5);
176
+ * const view = new Uint8Array(arrayBuffer);
177
+ * view.set([72, 101, 108, 108, 111]);
178
+ * const buf = Buffer.fromArrayBuffer(arrayBuffer);
179
+ * console.log(buf.toString()); // "Hello"
180
+ * ```
181
+ */
182
+ static fromArrayBuffer(data) {
183
+ return new Buffer(globalThis.Buffer.from(data));
184
+ }
185
+ /**
186
+ * Creates a buffer from a string with specified encoding.
187
+ *
188
+ * Supports all standard Node.js buffer encodings including UTF-8, ASCII,
189
+ * Base64, Hex, and more.
190
+ *
191
+ * @static
192
+ * @param {string} str - The string to encode
193
+ * @param {BufferEncoding} [encoding='utf-8'] - The character encoding to use
194
+ * @returns {Buffer} A new Buffer containing the encoded string
195
+ * @example
196
+ * ```typescript
197
+ * // UTF-8 (default)
198
+ * const buf1 = Buffer.fromString('Hello');
199
+ *
200
+ * // ASCII
201
+ * const buf2 = Buffer.fromString('Hello', 'ascii');
202
+ *
203
+ * // Base64
204
+ * const buf3 = Buffer.fromString('SGVsbG8=', 'base64');
205
+ * console.log(buf3.toString()); // "Hello"
206
+ *
207
+ * // Hex
208
+ * const buf4 = Buffer.fromString('48656c6c6f', 'hex');
209
+ * console.log(buf4.toString()); // "Hello"
210
+ * ```
211
+ */
212
+ static fromString(str, encoding = 'utf-8') {
213
+ return new Buffer(globalThis.Buffer.from(str, encoding));
214
+ }
215
+ /**
216
+ * Create a buffer from base64-encoded data
217
+ */
218
+ static fromBase64(data) {
219
+ return new Buffer(globalThis.Buffer.from(data, 'base64'));
220
+ }
221
+ /**
222
+ * Create a buffer from hex-encoded data
223
+ */
224
+ static fromHex(data) {
225
+ return new Buffer(globalThis.Buffer.from(data, 'hex'));
226
+ }
227
+ /**
228
+ * Create a buffer from various input types
229
+ */
230
+ static from(data) {
231
+ if (data instanceof Buffer) {
232
+ return Buffer.fromBuffer(data._data);
233
+ }
234
+ if (globalThis.Buffer.isBuffer(data)) {
235
+ return Buffer.fromBuffer(data);
236
+ }
237
+ if (data instanceof Uint8Array) {
238
+ return Buffer.fromUint8Array(data);
239
+ }
240
+ if (data instanceof ArrayBuffer) {
241
+ return Buffer.fromArrayBuffer(data);
242
+ }
243
+ if (typeof data === 'string') {
244
+ return Buffer.fromString(data);
245
+ }
246
+ if (Array.isArray(data)) {
247
+ return new Buffer(globalThis.Buffer.from(data));
248
+ }
249
+ throw MicroPDFError.argument('Expected Buffer, Uint8Array, ArrayBuffer, string, or number[]');
250
+ }
251
+ // ============================================================================
252
+ // Properties
253
+ // ============================================================================
254
+ /**
255
+ * Get the length of the buffer in bytes
256
+ */
257
+ get length() {
258
+ return this._data.length;
259
+ }
260
+ /**
261
+ * Check if the buffer is empty
262
+ */
263
+ get isEmpty() {
264
+ return this._data.length === 0;
265
+ }
266
+ /**
267
+ * Get the buffer capacity
268
+ */
269
+ get capacity() {
270
+ return this._data.length;
271
+ }
272
+ // ============================================================================
273
+ // Conversion Methods
274
+ // ============================================================================
275
+ /**
276
+ * Get the buffer data as a Node.js Buffer
277
+ */
278
+ toNodeBuffer() {
279
+ return this._data;
280
+ }
281
+ /**
282
+ * Get the buffer data as a Uint8Array (copy)
283
+ *
284
+ * Creates a new Uint8Array with a copy of the buffer data.
285
+ * Use `toUint8ArrayView()` for a zero-copy view if you don't need to modify it.
286
+ */
287
+ toUint8Array() {
288
+ return new Uint8Array(this._data);
289
+ }
290
+ /**
291
+ * Get a zero-copy Uint8Array view of the buffer data
292
+ *
293
+ * WARNING: This returns a view, not a copy. Modifying the view will
294
+ * modify the original buffer. The view becomes invalid if the buffer
295
+ * is modified (append, resize, etc.) or freed.
296
+ *
297
+ * Use this for read-only operations where performance matters.
298
+ */
299
+ toUint8ArrayView() {
300
+ // Node.js Buffer is a subclass of Uint8Array, so we can return directly
301
+ return this._data;
302
+ }
303
+ /**
304
+ * Get the buffer data as an ArrayBuffer
305
+ */
306
+ toArrayBuffer() {
307
+ const buf = this._data.buffer.slice(this._data.byteOffset, this._data.byteOffset + this._data.byteLength);
308
+ // Handle SharedArrayBuffer case
309
+ if (buf instanceof SharedArrayBuffer) {
310
+ const ab = new ArrayBuffer(buf.byteLength);
311
+ new Uint8Array(ab).set(new Uint8Array(buf));
312
+ return ab;
313
+ }
314
+ return buf;
315
+ }
316
+ /**
317
+ * Get the buffer data as a string
318
+ *
319
+ * For UTF-8 encoding with buffers larger than 1KB, uses TextDecoder
320
+ * which is more efficient than Node's toString() for large strings.
321
+ */
322
+ toString(encoding = 'utf-8') {
323
+ // Use TextDecoder for large UTF-8 buffers (more efficient)
324
+ if ((encoding === 'utf-8' || encoding === 'utf8') &&
325
+ this._data.length > TEXT_DECODER_THRESHOLD) {
326
+ return textDecoder.decode(this._data);
327
+ }
328
+ return this._data.toString(encoding);
329
+ }
330
+ /**
331
+ * Get the buffer data as base64-encoded string
332
+ */
333
+ toBase64() {
334
+ return this._data.toString('base64');
335
+ }
336
+ /**
337
+ * Get the buffer data as hex-encoded string
338
+ */
339
+ toHex() {
340
+ return this._data.toString('hex');
341
+ }
342
+ /**
343
+ * Get the buffer data as a number array
344
+ */
345
+ toArray() {
346
+ return [...this._data];
347
+ }
348
+ // ============================================================================
349
+ // Modification Methods
350
+ // ============================================================================
351
+ /**
352
+ * Resize the buffer to the specified size
353
+ */
354
+ resize(newLength) {
355
+ if (newLength === this._data.length) {
356
+ return this;
357
+ }
358
+ const newData = globalThis.Buffer.alloc(newLength);
359
+ this._data.copy(newData, 0, 0, Math.min(this._data.length, newLength));
360
+ this._data = newData;
361
+ return this;
362
+ }
363
+ /**
364
+ * Clear all data from the buffer
365
+ */
366
+ clear() {
367
+ this._data = globalThis.Buffer.alloc(0);
368
+ return this;
369
+ }
370
+ /**
371
+ * Append data to the buffer
372
+ */
373
+ append(data) {
374
+ const other = Buffer.from(data);
375
+ this._data = globalThis.Buffer.concat([this._data, other._data]);
376
+ return this;
377
+ }
378
+ /**
379
+ * Append a single byte to the buffer
380
+ */
381
+ appendByte(byte) {
382
+ const newData = globalThis.Buffer.alloc(this._data.length + 1);
383
+ this._data.copy(newData);
384
+ newData[this._data.length] = byte & 0xff;
385
+ this._data = newData;
386
+ return this;
387
+ }
388
+ /**
389
+ * Append a string to the buffer (UTF-8 encoded)
390
+ */
391
+ appendString(str, encoding = 'utf-8') {
392
+ return this.append(globalThis.Buffer.from(str, encoding));
393
+ }
394
+ /**
395
+ * Append a 16-bit integer in little-endian format
396
+ */
397
+ appendInt16LE(value) {
398
+ const buf = globalThis.Buffer.alloc(2);
399
+ buf.writeInt16LE(value, 0);
400
+ return this.append(buf);
401
+ }
402
+ /**
403
+ * Append a 32-bit integer in little-endian format
404
+ */
405
+ appendInt32LE(value) {
406
+ const buf = globalThis.Buffer.alloc(4);
407
+ buf.writeInt32LE(value, 0);
408
+ return this.append(buf);
409
+ }
410
+ /**
411
+ * Append a 16-bit integer in big-endian format
412
+ */
413
+ appendInt16BE(value) {
414
+ const buf = globalThis.Buffer.alloc(2);
415
+ buf.writeInt16BE(value, 0);
416
+ return this.append(buf);
417
+ }
418
+ /**
419
+ * Append a 32-bit integer in big-endian format
420
+ */
421
+ appendInt32BE(value) {
422
+ const buf = globalThis.Buffer.alloc(4);
423
+ buf.writeInt32BE(value, 0);
424
+ return this.append(buf);
425
+ }
426
+ /**
427
+ * Append a 16-bit unsigned integer in little-endian format
428
+ */
429
+ appendUInt16LE(value) {
430
+ const buf = globalThis.Buffer.alloc(2);
431
+ buf.writeUInt16LE(value, 0);
432
+ return this.append(buf);
433
+ }
434
+ /**
435
+ * Append a 32-bit unsigned integer in little-endian format
436
+ */
437
+ appendUInt32LE(value) {
438
+ const buf = globalThis.Buffer.alloc(4);
439
+ buf.writeUInt32LE(value, 0);
440
+ return this.append(buf);
441
+ }
442
+ /**
443
+ * Append a 16-bit unsigned integer in big-endian format
444
+ */
445
+ appendUInt16BE(value) {
446
+ const buf = globalThis.Buffer.alloc(2);
447
+ buf.writeUInt16BE(value, 0);
448
+ return this.append(buf);
449
+ }
450
+ /**
451
+ * Append a 32-bit unsigned integer in big-endian format
452
+ */
453
+ appendUInt32BE(value) {
454
+ const buf = globalThis.Buffer.alloc(4);
455
+ buf.writeUInt32BE(value, 0);
456
+ return this.append(buf);
457
+ }
458
+ /**
459
+ * Append a float in little-endian format
460
+ */
461
+ appendFloatLE(value) {
462
+ const buf = globalThis.Buffer.alloc(4);
463
+ buf.writeFloatLE(value, 0);
464
+ return this.append(buf);
465
+ }
466
+ /**
467
+ * Append a float in big-endian format
468
+ */
469
+ appendFloatBE(value) {
470
+ const buf = globalThis.Buffer.alloc(4);
471
+ buf.writeFloatBE(value, 0);
472
+ return this.append(buf);
473
+ }
474
+ /**
475
+ * Append a double in little-endian format
476
+ */
477
+ appendDoubleLE(value) {
478
+ const buf = globalThis.Buffer.alloc(8);
479
+ buf.writeDoubleLE(value, 0);
480
+ return this.append(buf);
481
+ }
482
+ /**
483
+ * Append a double in big-endian format
484
+ */
485
+ appendDoubleBE(value) {
486
+ const buf = globalThis.Buffer.alloc(8);
487
+ buf.writeDoubleBE(value, 0);
488
+ return this.append(buf);
489
+ }
490
+ // ============================================================================
491
+ // Access Methods
492
+ // ============================================================================
493
+ /**
494
+ * Get a slice of the buffer
495
+ */
496
+ slice(start, end) {
497
+ return new Buffer(globalThis.Buffer.from(this._data.subarray(start, end)));
498
+ }
499
+ /**
500
+ * Split the buffer at the given index
501
+ */
502
+ splitAt(mid) {
503
+ const first = this.slice(0, mid);
504
+ const second = this.slice(mid);
505
+ return [first, second];
506
+ }
507
+ /**
508
+ * Get a byte at the specified index
509
+ */
510
+ at(index) {
511
+ if (index < 0) {
512
+ index = this._data.length + index;
513
+ }
514
+ if (index < 0 || index >= this._data.length) {
515
+ return undefined;
516
+ }
517
+ return this._data[index];
518
+ }
519
+ /**
520
+ * Set a byte at the specified index
521
+ */
522
+ set(index, value) {
523
+ if (index < 0) {
524
+ index = this._data.length + index;
525
+ }
526
+ if (index >= 0 && index < this._data.length) {
527
+ this._data[index] = value & 0xff;
528
+ }
529
+ return this;
530
+ }
531
+ /**
532
+ * Read a 16-bit unsigned integer at offset (big-endian)
533
+ */
534
+ readUInt16BE(offset) {
535
+ return this._data.readUInt16BE(offset);
536
+ }
537
+ /**
538
+ * Read a 32-bit unsigned integer at offset (big-endian)
539
+ */
540
+ readUInt32BE(offset) {
541
+ return this._data.readUInt32BE(offset);
542
+ }
543
+ /**
544
+ * Read a 16-bit unsigned integer at offset (little-endian)
545
+ */
546
+ readUInt16LE(offset) {
547
+ return this._data.readUInt16LE(offset);
548
+ }
549
+ /**
550
+ * Read a 32-bit unsigned integer at offset (little-endian)
551
+ */
552
+ readUInt32LE(offset) {
553
+ return this._data.readUInt32LE(offset);
554
+ }
555
+ /**
556
+ * Read a 16-bit signed integer at offset (big-endian)
557
+ */
558
+ readInt16BE(offset) {
559
+ return this._data.readInt16BE(offset);
560
+ }
561
+ /**
562
+ * Read a 32-bit signed integer at offset (big-endian)
563
+ */
564
+ readInt32BE(offset) {
565
+ return this._data.readInt32BE(offset);
566
+ }
567
+ /**
568
+ * Read a 16-bit signed integer at offset (little-endian)
569
+ */
570
+ readInt16LE(offset) {
571
+ return this._data.readInt16LE(offset);
572
+ }
573
+ /**
574
+ * Read a 32-bit signed integer at offset (little-endian)
575
+ */
576
+ readInt32LE(offset) {
577
+ return this._data.readInt32LE(offset);
578
+ }
579
+ /**
580
+ * Read a float at offset (big-endian)
581
+ */
582
+ readFloatBE(offset) {
583
+ return this._data.readFloatBE(offset);
584
+ }
585
+ /**
586
+ * Read a float at offset (little-endian)
587
+ */
588
+ readFloatLE(offset) {
589
+ return this._data.readFloatLE(offset);
590
+ }
591
+ /**
592
+ * Read a double at offset (big-endian)
593
+ */
594
+ readDoubleBE(offset) {
595
+ return this._data.readDoubleBE(offset);
596
+ }
597
+ /**
598
+ * Read a double at offset (little-endian)
599
+ */
600
+ readDoubleLE(offset) {
601
+ return this._data.readDoubleLE(offset);
602
+ }
603
+ // ============================================================================
604
+ // Hashing Methods
605
+ // ============================================================================
606
+ /**
607
+ * Compute MD5 digest of buffer contents
608
+ */
609
+ md5Digest() {
610
+ const hash = createHash('md5');
611
+ hash.update(this._data);
612
+ return new Uint8Array(hash.digest());
613
+ }
614
+ /**
615
+ * Compute SHA-256 digest of buffer contents
616
+ */
617
+ sha256Digest() {
618
+ const hash = createHash('sha256');
619
+ hash.update(this._data);
620
+ return new Uint8Array(hash.digest());
621
+ }
622
+ // ============================================================================
623
+ // Comparison Methods
624
+ // ============================================================================
625
+ /**
626
+ * Check equality with another buffer
627
+ */
628
+ equals(other) {
629
+ const otherBuf = other instanceof Buffer ? other : Buffer.from(other);
630
+ return this._data.equals(otherBuf._data);
631
+ }
632
+ /**
633
+ * Compare with another buffer
634
+ * Returns -1, 0, or 1
635
+ */
636
+ compare(other) {
637
+ const otherBuf = other instanceof Buffer ? other : Buffer.from(other);
638
+ return this._data.compare(otherBuf._data);
639
+ }
640
+ /**
641
+ * Find index of a byte or pattern
642
+ */
643
+ indexOf(value, start = 0) {
644
+ if (typeof value === 'number') {
645
+ return this._data.indexOf(value, start);
646
+ }
647
+ const pattern = Buffer.from(value);
648
+ return this._data.indexOf(pattern._data, start);
649
+ }
650
+ /**
651
+ * Check if buffer includes a byte or pattern
652
+ */
653
+ includes(value, start = 0) {
654
+ return this.includes(value, start);
655
+ }
656
+ // ============================================================================
657
+ // Iterator Support
658
+ // ============================================================================
659
+ /**
660
+ * Iterate over bytes
661
+ */
662
+ *[Symbol.iterator]() {
663
+ for (const byte of this._data) {
664
+ yield byte;
665
+ }
666
+ }
667
+ /**
668
+ * Get entries iterator
669
+ */
670
+ *entries() {
671
+ for (let i = 0; i < this._data.length; i++) {
672
+ yield [i, this._data[i]];
673
+ }
674
+ }
675
+ /**
676
+ * Get keys iterator
677
+ */
678
+ *keys() {
679
+ for (let i = 0; i < this._data.length; i++) {
680
+ yield i;
681
+ }
682
+ }
683
+ /**
684
+ * Get values iterator
685
+ */
686
+ *values() {
687
+ for (const byte of this._data) {
688
+ yield byte;
689
+ }
690
+ }
691
+ // ============================================================================
692
+ // Clone
693
+ // ============================================================================
694
+ /**
695
+ * Create a copy of the buffer
696
+ */
697
+ clone() {
698
+ return new Buffer(globalThis.Buffer.from(this._data));
699
+ }
700
+ }
701
+ /**
702
+ * A reader for consuming buffer contents
703
+ */
704
+ export class BufferReader {
705
+ data;
706
+ position;
707
+ constructor(buffer) {
708
+ this.data =
709
+ buffer instanceof Buffer ? buffer.toNodeBuffer() : Buffer.from(buffer).toNodeBuffer();
710
+ this.position = 0;
711
+ }
712
+ /**
713
+ * Get the current read position
714
+ */
715
+ get pos() {
716
+ return this.position;
717
+ }
718
+ /**
719
+ * Get the number of bytes remaining
720
+ */
721
+ get remaining() {
722
+ return this.data.length - this.position;
723
+ }
724
+ /**
725
+ * Check if we've reached the end
726
+ */
727
+ get isEof() {
728
+ return this.position >= this.data.length;
729
+ }
730
+ /**
731
+ * Peek at the next byte without consuming it
732
+ */
733
+ peek() {
734
+ if (this.position >= this.data.length) {
735
+ return null;
736
+ }
737
+ return this.data[this.position] ?? null;
738
+ }
739
+ /**
740
+ * Read a single byte
741
+ */
742
+ readByte() {
743
+ if (this.position >= this.data.length) {
744
+ return null;
745
+ }
746
+ return this.data[this.position++] ?? null;
747
+ }
748
+ /**
749
+ * Read bytes into a buffer
750
+ */
751
+ read(length) {
752
+ const end = Math.min(this.position + length, this.data.length);
753
+ const result = new Uint8Array(this.data.subarray(this.position, end));
754
+ this.position = end;
755
+ return result;
756
+ }
757
+ /**
758
+ * Read exactly n bytes, or throw if not enough data
759
+ */
760
+ readExact(length) {
761
+ if (this.remaining < length) {
762
+ throw MicroPDFError.eof();
763
+ }
764
+ return this.read(length);
765
+ }
766
+ /**
767
+ * Read a 16-bit unsigned integer (big-endian)
768
+ */
769
+ readUInt16BE() {
770
+ if (this.remaining < 2)
771
+ throw MicroPDFError.eof();
772
+ const value = this.data.readUInt16BE(this.position);
773
+ this.position += 2;
774
+ return value;
775
+ }
776
+ /**
777
+ * Read a 32-bit unsigned integer (big-endian)
778
+ */
779
+ readUInt32BE() {
780
+ if (this.remaining < 4)
781
+ throw MicroPDFError.eof();
782
+ const value = this.data.readUInt32BE(this.position);
783
+ this.position += 4;
784
+ return value;
785
+ }
786
+ /**
787
+ * Read a 16-bit unsigned integer (little-endian)
788
+ */
789
+ readUInt16LE() {
790
+ if (this.remaining < 2)
791
+ throw MicroPDFError.eof();
792
+ const value = this.data.readUInt16LE(this.position);
793
+ this.position += 2;
794
+ return value;
795
+ }
796
+ /**
797
+ * Read a 32-bit unsigned integer (little-endian)
798
+ */
799
+ readUInt32LE() {
800
+ if (this.remaining < 4)
801
+ throw MicroPDFError.eof();
802
+ const value = this.data.readUInt32LE(this.position);
803
+ this.position += 4;
804
+ return value;
805
+ }
806
+ /**
807
+ * Read a 24-bit unsigned integer (big-endian)
808
+ */
809
+ readUInt24BE() {
810
+ if (this.remaining < 3)
811
+ throw MicroPDFError.eof();
812
+ const b0 = this.data[this.position++];
813
+ const b1 = this.data[this.position++];
814
+ const b2 = this.data[this.position++];
815
+ return (b0 << 16) | (b1 << 8) | b2;
816
+ }
817
+ /**
818
+ * Seek to a position
819
+ */
820
+ seek(pos) {
821
+ this.position = Math.max(0, Math.min(pos, this.data.length));
822
+ return this;
823
+ }
824
+ /**
825
+ * Skip n bytes
826
+ */
827
+ skip(n) {
828
+ this.position = Math.min(this.position + n, this.data.length);
829
+ return this;
830
+ }
831
+ /**
832
+ * Read a line (up to and including newline)
833
+ */
834
+ readLine() {
835
+ if (this.isEof) {
836
+ return null;
837
+ }
838
+ const start = this.position;
839
+ while (this.position < this.data.length) {
840
+ if (this.data[this.position++] === 0x0a) {
841
+ break;
842
+ }
843
+ }
844
+ return new Uint8Array(this.data.subarray(start, this.position));
845
+ }
846
+ /**
847
+ * Read a line as string
848
+ */
849
+ readLineString(encoding = 'utf-8') {
850
+ const line = this.readLine();
851
+ if (line === null) {
852
+ return null;
853
+ }
854
+ return globalThis.Buffer.from(line).toString(encoding);
855
+ }
856
+ }
857
+ /**
858
+ * A writer that accumulates data into a buffer
859
+ */
860
+ export class BufferWriter {
861
+ data;
862
+ position;
863
+ constructor(capacity = 256) {
864
+ this.data = globalThis.Buffer.alloc(capacity);
865
+ this.position = 0;
866
+ }
867
+ /**
868
+ * Get the current length
869
+ */
870
+ get length() {
871
+ return this.position;
872
+ }
873
+ /**
874
+ * Check if empty
875
+ */
876
+ get isEmpty() {
877
+ return this.position === 0;
878
+ }
879
+ /**
880
+ * Ensure capacity
881
+ */
882
+ ensureCapacity(additional) {
883
+ const required = this.position + additional;
884
+ if (required > this.data.length) {
885
+ const newCapacity = Math.max(this.data.length * 2, required);
886
+ const newData = globalThis.Buffer.alloc(newCapacity);
887
+ this.data.copy(newData, 0, 0, this.position);
888
+ this.data = newData;
889
+ }
890
+ }
891
+ /**
892
+ * Write bytes
893
+ */
894
+ write(data) {
895
+ const buf = Buffer.from(data).toNodeBuffer();
896
+ this.ensureCapacity(buf.length);
897
+ buf.copy(this.data, this.position);
898
+ this.position += buf.length;
899
+ return this;
900
+ }
901
+ /**
902
+ * Write a single byte
903
+ */
904
+ writeByte(value) {
905
+ this.ensureCapacity(1);
906
+ this.data[this.position++] = value & 0xff;
907
+ return this;
908
+ }
909
+ /**
910
+ * Write a 16-bit unsigned integer (big-endian)
911
+ */
912
+ writeUInt16BE(value) {
913
+ this.ensureCapacity(2);
914
+ this.data.writeUInt16BE(value, this.position);
915
+ this.position += 2;
916
+ return this;
917
+ }
918
+ /**
919
+ * Write a 32-bit unsigned integer (big-endian)
920
+ */
921
+ writeUInt32BE(value) {
922
+ this.ensureCapacity(4);
923
+ this.data.writeUInt32BE(value, this.position);
924
+ this.position += 4;
925
+ return this;
926
+ }
927
+ /**
928
+ * Write a 16-bit unsigned integer (little-endian)
929
+ */
930
+ writeUInt16LE(value) {
931
+ this.ensureCapacity(2);
932
+ this.data.writeUInt16LE(value, this.position);
933
+ this.position += 2;
934
+ return this;
935
+ }
936
+ /**
937
+ * Write a 32-bit unsigned integer (little-endian)
938
+ */
939
+ writeUInt32LE(value) {
940
+ this.ensureCapacity(4);
941
+ this.data.writeUInt32LE(value, this.position);
942
+ this.position += 4;
943
+ return this;
944
+ }
945
+ /**
946
+ * Write a string
947
+ */
948
+ writeString(str, encoding = 'utf-8') {
949
+ return this.write(globalThis.Buffer.from(str, encoding));
950
+ }
951
+ /**
952
+ * Get the accumulated data as a slice
953
+ */
954
+ toSlice() {
955
+ return new Uint8Array(this.data.subarray(0, this.position));
956
+ }
957
+ /**
958
+ * Convert to Buffer
959
+ */
960
+ toBuffer() {
961
+ return Buffer.fromUint8Array(this.toSlice());
962
+ }
963
+ /**
964
+ * Clear the writer
965
+ */
966
+ clear() {
967
+ this.position = 0;
968
+ return this;
969
+ }
970
+ }
971
+ //# sourceMappingURL=buffer.js.map