react-native-nitro-buffer 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/README.md +129 -0
- package/cpp/HybridNitroBuffer.cpp +497 -0
- package/cpp/HybridNitroBuffer.hpp +44 -0
- package/lib/Buffer.d.ts +79 -0
- package/lib/Buffer.js +642 -0
- package/lib/NitroBuffer.nitro.d.ts +18 -0
- package/lib/NitroBuffer.nitro.js +2 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.js +34 -0
- package/lib/utils.d.ts +7 -0
- package/lib/utils.js +90 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/NitroBuffer+autolinking.cmake +81 -0
- package/nitrogen/generated/android/NitroBuffer+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NitroBufferOnLoad.cpp +44 -0
- package/nitrogen/generated/android/NitroBufferOnLoad.hpp +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitro_buffer/NitroBufferOnLoad.kt +35 -0
- package/nitrogen/generated/ios/NitroBuffer+autolinking.rb +60 -0
- package/nitrogen/generated/ios/NitroBuffer-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/NitroBuffer-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/NitroBuffer-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/NitroBufferAutolinking.mm +35 -0
- package/nitrogen/generated/ios/NitroBufferAutolinking.swift +12 -0
- package/nitrogen/generated/shared/c++/HybridNitroBufferSpec.cpp +32 -0
- package/nitrogen/generated/shared/c++/HybridNitroBufferSpec.hpp +74 -0
- package/package.json +55 -0
- package/react-native-nitro-buffer.podspec +40 -0
- package/src/Buffer.ts +675 -0
- package/src/NitroBuffer.nitro.ts +19 -0
- package/src/index.ts +18 -0
- package/src/utils.ts +76 -0
package/src/Buffer.ts
ADDED
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
import { NitroModules } from 'react-native-nitro-modules'
|
|
2
|
+
import type { NitroBuffer } from './NitroBuffer.nitro'
|
|
3
|
+
|
|
4
|
+
// Lazily load the native module
|
|
5
|
+
let _native: NitroBuffer | undefined
|
|
6
|
+
|
|
7
|
+
function getNative(): NitroBuffer {
|
|
8
|
+
if (!_native) {
|
|
9
|
+
_native = NitroModules.createHybridObject<NitroBuffer>('NitroBuffer')
|
|
10
|
+
}
|
|
11
|
+
return _native
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class Buffer extends Uint8Array {
|
|
15
|
+
constructor(length: number)
|
|
16
|
+
constructor(array: Uint8Array)
|
|
17
|
+
constructor(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number)
|
|
18
|
+
constructor(string: string, encoding?: string)
|
|
19
|
+
constructor(arg: any, encodingOrOffset?: any, length?: any) {
|
|
20
|
+
// Handling different constructor arguments roughly
|
|
21
|
+
if (typeof arg === 'number') {
|
|
22
|
+
super(arg)
|
|
23
|
+
} else if (typeof arg === 'string') {
|
|
24
|
+
const encoding = encodingOrOffset || 'utf8'
|
|
25
|
+
const len = getNative().byteLength(arg, encoding)
|
|
26
|
+
super(len)
|
|
27
|
+
getNative().write(this.buffer as ArrayBuffer, arg, 0, len, encoding)
|
|
28
|
+
} else if (arg instanceof Uint8Array) {
|
|
29
|
+
super(arg)
|
|
30
|
+
} else if (arg instanceof ArrayBuffer) {
|
|
31
|
+
super(arg, encodingOrOffset, length)
|
|
32
|
+
} else if (Object.prototype.toString.call(arg) === '[object ArrayBuffer]') {
|
|
33
|
+
super(arg, encodingOrOffset, length)
|
|
34
|
+
} else if (typeof arg === 'object' && arg !== null && arg.type === 'Buffer' && Array.isArray(arg.data)) {
|
|
35
|
+
// Buffer.from({ type: 'Buffer', data: [...] })
|
|
36
|
+
super(arg.data)
|
|
37
|
+
} else {
|
|
38
|
+
super(arg)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get parent(): ArrayBuffer {
|
|
43
|
+
return this.buffer as ArrayBuffer
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static from(value: any, encodingOrOffset?: any, length?: any): Buffer {
|
|
47
|
+
if (typeof value === 'string') {
|
|
48
|
+
return new Buffer(value, encodingOrOffset)
|
|
49
|
+
}
|
|
50
|
+
if (value instanceof Uint8Array) {
|
|
51
|
+
// Copy
|
|
52
|
+
const buf = new Buffer(value.length)
|
|
53
|
+
buf.set(value)
|
|
54
|
+
return buf
|
|
55
|
+
}
|
|
56
|
+
if (value instanceof ArrayBuffer) {
|
|
57
|
+
return new Buffer(value, encodingOrOffset, length)
|
|
58
|
+
}
|
|
59
|
+
if (Array.isArray(value)) {
|
|
60
|
+
return new Buffer(new Uint8Array(value).buffer)
|
|
61
|
+
}
|
|
62
|
+
throw new TypeError('Unsupported type for Buffer.from')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer {
|
|
66
|
+
// Fast path: use Uint8Array directly to avoid Buffer constructor overhead
|
|
67
|
+
const buf = new Uint8Array(size) as unknown as Buffer
|
|
68
|
+
Object.setPrototypeOf(buf, Buffer.prototype)
|
|
69
|
+
|
|
70
|
+
if (fill !== undefined) {
|
|
71
|
+
buf.fill(fill, encoding)
|
|
72
|
+
}
|
|
73
|
+
return buf
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static allocUnsafe(size: number): Buffer {
|
|
77
|
+
// In JS, memory is always zeroed for security, so allocUnsafe is same as alloc usually.
|
|
78
|
+
// Unless we recycled buffers (not implemented).
|
|
79
|
+
// Using native allocUnsafe might give uninitialized memory, but bridge overhead (~0.05ms)
|
|
80
|
+
// might outweight the zeroing cost (~0.02ms).
|
|
81
|
+
// So we stick to JS native alloc for now.
|
|
82
|
+
const buf = new Uint8Array(size) as unknown as Buffer
|
|
83
|
+
Object.setPrototypeOf(buf, Buffer.prototype)
|
|
84
|
+
return buf
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static allocUnsafeSlow(size: number): Buffer {
|
|
88
|
+
return Buffer.allocUnsafe(size)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static byteLength(string: string, encoding: string = 'utf8'): number {
|
|
92
|
+
return getNative().byteLength(string, encoding)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static isBuffer(obj: any): obj is Buffer {
|
|
96
|
+
return obj instanceof Buffer
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static compare(buf1: Uint8Array, buf2: Uint8Array): number {
|
|
100
|
+
return getNative().compare(buf1.buffer as ArrayBuffer, buf1.byteOffset, buf1.byteLength, buf2.buffer as ArrayBuffer, buf2.byteOffset, buf2.byteLength)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static copyBytesFrom(view: ArrayBufferView, offset?: number, length?: number): Buffer {
|
|
104
|
+
if (offset === undefined) offset = 0
|
|
105
|
+
if (length === undefined) length = view.byteLength - offset
|
|
106
|
+
if (offset < 0 || length < 0 || offset + length > view.byteLength) {
|
|
107
|
+
throw new RangeError('offset or length out of bounds')
|
|
108
|
+
}
|
|
109
|
+
const buf = Buffer.allocUnsafe(length)
|
|
110
|
+
const src = new Uint8Array(view.buffer, view.byteOffset + offset, length)
|
|
111
|
+
buf.set(src)
|
|
112
|
+
return buf
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static concat(list: Uint8Array[], totalLength?: number): Buffer {
|
|
116
|
+
if (totalLength === undefined) {
|
|
117
|
+
totalLength = list.reduce((acc, curr) => acc + curr.length, 0)
|
|
118
|
+
}
|
|
119
|
+
const buf = Buffer.allocUnsafe(totalLength!)
|
|
120
|
+
let offset = 0
|
|
121
|
+
for (const item of list) {
|
|
122
|
+
buf.set(item, offset)
|
|
123
|
+
offset += item.length
|
|
124
|
+
}
|
|
125
|
+
return buf
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
write(string: string, offset?: number, length?: number, encoding?: string): number {
|
|
129
|
+
// Argument handling
|
|
130
|
+
if (offset === undefined) {
|
|
131
|
+
offset = 0
|
|
132
|
+
length = this.length
|
|
133
|
+
encoding = 'utf8'
|
|
134
|
+
} else if (length === undefined && typeof offset === 'string') {
|
|
135
|
+
encoding = offset
|
|
136
|
+
offset = 0
|
|
137
|
+
length = this.length
|
|
138
|
+
} else if (length === undefined) {
|
|
139
|
+
length = this.length - offset
|
|
140
|
+
encoding = 'utf8'
|
|
141
|
+
} else if (encoding === undefined) {
|
|
142
|
+
encoding = 'utf8'
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return getNative().write(this.buffer as ArrayBuffer, string, this.byteOffset + (offset as number), length as number, encoding as string)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
toString(encoding?: string, start?: number, end?: number): string {
|
|
149
|
+
if (encoding === undefined) encoding = 'utf8'
|
|
150
|
+
if (start === undefined) start = 0
|
|
151
|
+
if (end === undefined) end = this.length
|
|
152
|
+
|
|
153
|
+
if (start < 0) start = 0
|
|
154
|
+
if (end > this.length) end = this.length
|
|
155
|
+
if (start >= end) return ''
|
|
156
|
+
|
|
157
|
+
return getNative().decode(this.buffer as ArrayBuffer, this.byteOffset + start, end - start, encoding)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
indexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: string): number {
|
|
161
|
+
if (typeof value === 'string') {
|
|
162
|
+
const needle = Buffer.from(value, encoding)
|
|
163
|
+
return getNative().indexOfBuffer(this.buffer as ArrayBuffer, needle.buffer as ArrayBuffer, byteOffset || 0, this.length)
|
|
164
|
+
}
|
|
165
|
+
if (value instanceof Uint8Array) {
|
|
166
|
+
return getNative().indexOfBuffer(this.buffer as ArrayBuffer, value.buffer as ArrayBuffer, byteOffset || 0, this.length)
|
|
167
|
+
}
|
|
168
|
+
if (typeof value === 'number') {
|
|
169
|
+
return getNative().indexOf(this.buffer as ArrayBuffer, value, byteOffset || 0, this.length)
|
|
170
|
+
}
|
|
171
|
+
throw new TypeError('"value" argument must be string, number or Buffer')
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
lastIndexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: string): number {
|
|
175
|
+
// Node.js defaults byteOffset to buf.length - 1
|
|
176
|
+
// If byteOffset is provided, it is the index to start searching backwards from.
|
|
177
|
+
// We implement this by defining a window [0, limit] where limit is calculated.
|
|
178
|
+
|
|
179
|
+
if (byteOffset === undefined || byteOffset > this.length) {
|
|
180
|
+
byteOffset = this.length
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (typeof value === 'string') {
|
|
184
|
+
const needle = Buffer.from(value, encoding)
|
|
185
|
+
if (needle.length === 0) return -1
|
|
186
|
+
// We search in [0, byteOffset + needle.length].
|
|
187
|
+
// The match must start at <= byteOffset.
|
|
188
|
+
// So the match must be fully contained in [0, byteOffset + needle.length].
|
|
189
|
+
return getNative().lastIndexOfBuffer(this.buffer as ArrayBuffer, needle.buffer as ArrayBuffer, 0, byteOffset + needle.length)
|
|
190
|
+
}
|
|
191
|
+
if (value instanceof Uint8Array) {
|
|
192
|
+
if (value.length === 0) return -1
|
|
193
|
+
return getNative().lastIndexOfBuffer(this.buffer as ArrayBuffer, value.buffer as ArrayBuffer, 0, byteOffset + value.length)
|
|
194
|
+
}
|
|
195
|
+
if (typeof value === 'number') {
|
|
196
|
+
// Search in [0, byteOffset + 1]. The last byte checked is at byteOffset.
|
|
197
|
+
return getNative().lastIndexOfByte(this.buffer as ArrayBuffer, value, 0, byteOffset + 1)
|
|
198
|
+
}
|
|
199
|
+
throw new TypeError('"value" argument must be string, number or Buffer')
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean {
|
|
203
|
+
return this.indexOf(value, byteOffset, encoding) !== -1
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
fill(value: string | Buffer | number | Uint8Array, offset?: any, end?: any, encoding?: string): this {
|
|
207
|
+
// Handle argument shifting
|
|
208
|
+
if (typeof offset === 'string') {
|
|
209
|
+
encoding = offset
|
|
210
|
+
offset = 0
|
|
211
|
+
end = this.length
|
|
212
|
+
} else if (typeof end === 'string') {
|
|
213
|
+
encoding = end
|
|
214
|
+
end = this.length
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (offset === undefined) offset = 0
|
|
218
|
+
if (end === undefined) end = this.length
|
|
219
|
+
|
|
220
|
+
const len = end - offset
|
|
221
|
+
if (len <= 0) return this
|
|
222
|
+
|
|
223
|
+
if (typeof value === 'number') {
|
|
224
|
+
getNative().fill(this.buffer as ArrayBuffer, value, this.byteOffset + offset, len)
|
|
225
|
+
return this
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
let valBuf: Uint8Array
|
|
229
|
+
if (typeof value === 'string') {
|
|
230
|
+
valBuf = Buffer.from(value, encoding)
|
|
231
|
+
} else if (value instanceof Uint8Array) {
|
|
232
|
+
valBuf = value
|
|
233
|
+
} else {
|
|
234
|
+
throw new TypeError('"value" argument must be string, number or Buffer')
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (valBuf.length === 0) return this
|
|
238
|
+
|
|
239
|
+
// Native fillBuffer takes ArrayBuffer, assumes generic fill logic
|
|
240
|
+
getNative().fillBuffer(this.buffer as ArrayBuffer, valBuf.buffer as ArrayBuffer, this.byteOffset + offset, len)
|
|
241
|
+
return this
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
compare(target: Uint8Array, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number {
|
|
245
|
+
if (targetStart === undefined) targetStart = 0
|
|
246
|
+
if (targetEnd === undefined) targetEnd = target.length
|
|
247
|
+
if (sourceStart === undefined) sourceStart = 0
|
|
248
|
+
if (sourceEnd === undefined) sourceEnd = this.length
|
|
249
|
+
|
|
250
|
+
return getNative().compare(
|
|
251
|
+
this.buffer as ArrayBuffer, this.byteOffset + sourceStart, sourceEnd - sourceStart,
|
|
252
|
+
target.buffer as ArrayBuffer, target.byteOffset + targetStart, targetEnd - targetStart
|
|
253
|
+
)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
slice(start?: number, end?: number): Buffer {
|
|
257
|
+
// Uint8Array.prototype.slice returns a copy (new buffer).
|
|
258
|
+
// Buffer.prototype.slice (legacy) returned a view.
|
|
259
|
+
// Buffer.prototype.subarray returns a view.
|
|
260
|
+
// In Node.js Buffer.slice is deprecated and acts like subarray? No, Buffer.slice returns a view (unlike Uint8Array.slice which returns copy).
|
|
261
|
+
// Wait, Node Buffer.slice returns a NEW Buffer that references the SAME memory.
|
|
262
|
+
// But Uint8Array.prototype.slice returns a COPY.
|
|
263
|
+
// So we should override slice to return a view (subarray behavior) but wrapped in Buffer?
|
|
264
|
+
// Actually Node documentation says: "The Buffer.prototype.slice() method is deprecated... use subarray() instead."
|
|
265
|
+
// BUT for compatibility, often libs expect slice to duplicate memory? No, Buffer.slice(start, end) shares memory.
|
|
266
|
+
// Uint8Array.prototype.slice(start, end) copies memory.
|
|
267
|
+
// So we should override slice to be compatible with Node behavior (view), OR standard Uint8Array behavior (copy).
|
|
268
|
+
// Node's `slice` shares memory. `Uint8Array`'s `slice` copies. This is a conflict.
|
|
269
|
+
// Let's implement `subarray` which returns a Buffer view.
|
|
270
|
+
|
|
271
|
+
const sub = this.subarray(start, end)
|
|
272
|
+
// sub is Uint8Array. We need to cast it to Buffer.
|
|
273
|
+
// We can use Object.setPrototypeOf or just new Buffer via constructor that takes Uint8Array
|
|
274
|
+
// but that constructor usually copies?
|
|
275
|
+
// `new Buffer(uint8Array)` copies.
|
|
276
|
+
// We need `new Buffer(arrayBuffer, byteOffset, length)`.
|
|
277
|
+
return new Buffer(sub.buffer as ArrayBuffer, sub.byteOffset, sub.byteLength)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
subarray(begin?: number, end?: number): Buffer {
|
|
281
|
+
const sub = super.subarray(begin, end)
|
|
282
|
+
// Ensure we return a Buffer, not just a Uint8Array
|
|
283
|
+
if (sub instanceof Buffer) return sub
|
|
284
|
+
|
|
285
|
+
// Wrap the Uint8Array's memory view into a new Buffer
|
|
286
|
+
// Note: new Buffer(arrayBuffer, byteOffset, length) creates a view
|
|
287
|
+
return new Buffer(sub.buffer as ArrayBuffer, sub.byteOffset, sub.byteLength)
|
|
288
|
+
}
|
|
289
|
+
// ================== Read Methods ==================
|
|
290
|
+
|
|
291
|
+
readInt8(offset: number = 0): number {
|
|
292
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getInt8(offset)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
readUInt8(offset: number = 0): number {
|
|
296
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getUint8(offset)
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
readInt16LE(offset: number = 0): number {
|
|
300
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getInt16(offset, true)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
readInt16BE(offset: number = 0): number {
|
|
304
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getInt16(offset, false)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
readUInt16LE(offset: number = 0): number {
|
|
308
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getUint16(offset, true)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
readUInt16BE(offset: number = 0): number {
|
|
312
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getUint16(offset, false)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
readInt32LE(offset: number = 0): number {
|
|
316
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getInt32(offset, true)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
readInt32BE(offset: number = 0): number {
|
|
320
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getInt32(offset, false)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
readUInt32LE(offset: number = 0): number {
|
|
324
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getUint32(offset, true)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
readUInt32BE(offset: number = 0): number {
|
|
328
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getUint32(offset, false)
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
readBigInt64LE(offset: number = 0): bigint {
|
|
332
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getBigInt64(offset, true)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
readBigInt64BE(offset: number = 0): bigint {
|
|
336
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getBigInt64(offset, false)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
readBigUInt64LE(offset: number = 0): bigint {
|
|
340
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getBigUint64(offset, true)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
readBigUInt64BE(offset: number = 0): bigint {
|
|
344
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getBigUint64(offset, false)
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
readFloatLE(offset: number = 0): number {
|
|
348
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getFloat32(offset, true)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
readFloatBE(offset: number = 0): number {
|
|
352
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getFloat32(offset, false)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
readDoubleLE(offset: number = 0): number {
|
|
356
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getFloat64(offset, true)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
readDoubleBE(offset: number = 0): number {
|
|
360
|
+
return new DataView(this.buffer, this.byteOffset, this.byteLength).getFloat64(offset, false)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
readIntLE(offset: number, byteLength: number): number {
|
|
364
|
+
if (offset === undefined) throw new TypeError('"offset" is invalid')
|
|
365
|
+
if (byteLength > 6 || byteLength < 0) throw new RangeError('"byteLength" out of range')
|
|
366
|
+
|
|
367
|
+
offset = offset >>> 0
|
|
368
|
+
byteLength = byteLength >>> 0
|
|
369
|
+
|
|
370
|
+
let val = this[offset]
|
|
371
|
+
let mul = 1
|
|
372
|
+
let i = 0
|
|
373
|
+
while (++i < byteLength && (mul *= 0x100)) {
|
|
374
|
+
val += this[offset + i] * mul
|
|
375
|
+
}
|
|
376
|
+
mul *= 0x80
|
|
377
|
+
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
|
378
|
+
return val
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
readIntBE(offset: number, byteLength: number): number {
|
|
382
|
+
if (offset === undefined) throw new TypeError('"offset" is invalid')
|
|
383
|
+
if (byteLength > 6 || byteLength < 0) throw new RangeError('"byteLength" out of range')
|
|
384
|
+
|
|
385
|
+
offset = offset >>> 0
|
|
386
|
+
byteLength = byteLength >>> 0
|
|
387
|
+
|
|
388
|
+
let i = byteLength
|
|
389
|
+
let mul = 1
|
|
390
|
+
let val = this[offset + --i]
|
|
391
|
+
while (i > 0 && (mul *= 0x100)) {
|
|
392
|
+
val += this[offset + --i] * mul
|
|
393
|
+
}
|
|
394
|
+
mul *= 0x80
|
|
395
|
+
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
|
|
396
|
+
return val
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
readUIntLE(offset: number, byteLength: number): number {
|
|
400
|
+
if (offset === undefined) throw new TypeError('"offset" is invalid')
|
|
401
|
+
if (byteLength > 6 || byteLength < 0) throw new RangeError('"byteLength" out of range')
|
|
402
|
+
|
|
403
|
+
offset = offset >>> 0
|
|
404
|
+
byteLength = byteLength >>> 0
|
|
405
|
+
|
|
406
|
+
let val = this[offset]
|
|
407
|
+
let mul = 1
|
|
408
|
+
let i = 0
|
|
409
|
+
while (++i < byteLength && (mul *= 0x100)) {
|
|
410
|
+
val += this[offset + i] * mul
|
|
411
|
+
}
|
|
412
|
+
return val
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
readUIntBE(offset: number, byteLength: number): number {
|
|
416
|
+
if (offset === undefined) throw new TypeError('"offset" is invalid')
|
|
417
|
+
if (byteLength > 6 || byteLength < 0) throw new RangeError('"byteLength" out of range')
|
|
418
|
+
|
|
419
|
+
offset = offset >>> 0
|
|
420
|
+
byteLength = byteLength >>> 0
|
|
421
|
+
|
|
422
|
+
let i = byteLength
|
|
423
|
+
let mul = 1
|
|
424
|
+
let val = this[offset + --i]
|
|
425
|
+
while (i > 0 && (mul *= 0x100)) {
|
|
426
|
+
val += this[offset + --i] * mul
|
|
427
|
+
}
|
|
428
|
+
return val
|
|
429
|
+
}
|
|
430
|
+
// ================== Write Methods ==================
|
|
431
|
+
|
|
432
|
+
writeInt8(value: number, offset: number = 0): number {
|
|
433
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setInt8(offset, value)
|
|
434
|
+
return offset + 1
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
writeUInt8(value: number, offset: number = 0): number {
|
|
438
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setUint8(offset, value)
|
|
439
|
+
return offset + 1
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
writeInt16LE(value: number, offset: number = 0): number {
|
|
443
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setInt16(offset, value, true)
|
|
444
|
+
return offset + 2
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
writeInt16BE(value: number, offset: number = 0): number {
|
|
448
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setInt16(offset, value, false)
|
|
449
|
+
return offset + 2
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
writeUInt16LE(value: number, offset: number = 0): number {
|
|
453
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setUint16(offset, value, true)
|
|
454
|
+
return offset + 2
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
writeUInt16BE(value: number, offset: number = 0): number {
|
|
458
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setUint16(offset, value, false)
|
|
459
|
+
return offset + 2
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
writeInt32LE(value: number, offset: number = 0): number {
|
|
463
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setInt32(offset, value, true)
|
|
464
|
+
return offset + 4
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
writeInt32BE(value: number, offset: number = 0): number {
|
|
468
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setInt32(offset, value, false)
|
|
469
|
+
return offset + 4
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
writeUInt32LE(value: number, offset: number = 0): number {
|
|
473
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setUint32(offset, value, true)
|
|
474
|
+
return offset + 4
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
writeUInt32BE(value: number, offset: number = 0): number {
|
|
478
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setUint32(offset, value, false)
|
|
479
|
+
return offset + 4
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
writeBigInt64LE(value: bigint, offset: number = 0): number {
|
|
483
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setBigInt64(offset, value, true)
|
|
484
|
+
return offset + 8
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
writeBigInt64BE(value: bigint, offset: number = 0): number {
|
|
488
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setBigInt64(offset, value, false)
|
|
489
|
+
return offset + 8
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
writeBigUInt64LE(value: bigint, offset: number = 0): number {
|
|
493
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setBigUint64(offset, value, true)
|
|
494
|
+
return offset + 8
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
writeBigUInt64BE(value: bigint, offset: number = 0): number {
|
|
498
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setBigUint64(offset, value, false)
|
|
499
|
+
return offset + 8
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
writeFloatLE(value: number, offset: number = 0): number {
|
|
503
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setFloat32(offset, value, true)
|
|
504
|
+
return offset + 4
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
writeFloatBE(value: number, offset: number = 0): number {
|
|
508
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setFloat32(offset, value, false)
|
|
509
|
+
return offset + 4
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
writeDoubleLE(value: number, offset: number = 0): number {
|
|
513
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setFloat64(offset, value, true)
|
|
514
|
+
return offset + 8
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
writeDoubleBE(value: number, offset: number = 0): number {
|
|
518
|
+
new DataView(this.buffer, this.byteOffset, this.byteLength).setFloat64(offset, value, false)
|
|
519
|
+
return offset + 8
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
writeIntLE(value: number, offset: number, byteLength: number): number {
|
|
523
|
+
if (offset === undefined) throw new TypeError('"offset" is invalid')
|
|
524
|
+
if (byteLength > 6 || byteLength < 0) throw new RangeError('"byteLength" out of range')
|
|
525
|
+
|
|
526
|
+
offset = offset >>> 0
|
|
527
|
+
byteLength = byteLength >>> 0
|
|
528
|
+
|
|
529
|
+
let i = 0
|
|
530
|
+
let mul = 1
|
|
531
|
+
let sub = 0
|
|
532
|
+
this[offset] = value & 0xFF
|
|
533
|
+
while (++i < byteLength && (mul *= 0x100)) {
|
|
534
|
+
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
|
|
535
|
+
sub = 1
|
|
536
|
+
}
|
|
537
|
+
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
|
538
|
+
}
|
|
539
|
+
return offset + byteLength
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
writeIntBE(value: number, offset: number, byteLength: number): number {
|
|
543
|
+
if (offset === undefined) throw new TypeError('"offset" is invalid')
|
|
544
|
+
if (byteLength > 6 || byteLength < 0) throw new RangeError('"byteLength" out of range')
|
|
545
|
+
|
|
546
|
+
offset = offset >>> 0
|
|
547
|
+
byteLength = byteLength >>> 0
|
|
548
|
+
|
|
549
|
+
let i = byteLength - 1
|
|
550
|
+
let mul = 1
|
|
551
|
+
let sub = 0
|
|
552
|
+
this[offset + i] = value & 0xFF
|
|
553
|
+
while (--i >= 0 && (mul *= 0x100)) {
|
|
554
|
+
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
|
|
555
|
+
sub = 1
|
|
556
|
+
}
|
|
557
|
+
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
|
|
558
|
+
}
|
|
559
|
+
return offset + byteLength
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
writeUIntLE(value: number, offset: number, byteLength: number): number {
|
|
563
|
+
if (offset === undefined) throw new TypeError('"offset" is invalid')
|
|
564
|
+
if (byteLength > 6 || byteLength < 0) throw new RangeError('"byteLength" out of range')
|
|
565
|
+
|
|
566
|
+
offset = offset >>> 0
|
|
567
|
+
byteLength = byteLength >>> 0
|
|
568
|
+
|
|
569
|
+
let i = 0
|
|
570
|
+
let mul = 1
|
|
571
|
+
this[offset] = value & 0xFF
|
|
572
|
+
while (++i < byteLength && (mul *= 0x100)) {
|
|
573
|
+
this[offset + i] = (value / mul) & 0xFF
|
|
574
|
+
}
|
|
575
|
+
return offset + byteLength
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
writeUIntBE(value: number, offset: number, byteLength: number): number {
|
|
579
|
+
if (offset === undefined) throw new TypeError('"offset" is invalid')
|
|
580
|
+
if (byteLength > 6 || byteLength < 0) throw new RangeError('"byteLength" out of range')
|
|
581
|
+
|
|
582
|
+
offset = offset >>> 0
|
|
583
|
+
byteLength = byteLength >>> 0
|
|
584
|
+
|
|
585
|
+
let i = byteLength - 1
|
|
586
|
+
let mul = 1
|
|
587
|
+
this[offset + i] = value & 0xFF
|
|
588
|
+
while (--i >= 0 && (mul *= 0x100)) {
|
|
589
|
+
this[offset + i] = (value / mul) & 0xFF
|
|
590
|
+
}
|
|
591
|
+
return offset + byteLength
|
|
592
|
+
}
|
|
593
|
+
// ================== Utils ==================
|
|
594
|
+
toJSON(): { type: 'Buffer', data: number[] } {
|
|
595
|
+
return {
|
|
596
|
+
type: 'Buffer',
|
|
597
|
+
data: Array.from(this)
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
static poolSize: number = 8192
|
|
602
|
+
|
|
603
|
+
static isEncoding(encoding: string): boolean {
|
|
604
|
+
switch (encoding.toLowerCase()) {
|
|
605
|
+
case 'utf8':
|
|
606
|
+
case 'utf-8':
|
|
607
|
+
case 'hex':
|
|
608
|
+
case 'base64':
|
|
609
|
+
case 'binary':
|
|
610
|
+
case 'latin1':
|
|
611
|
+
case 'ascii':
|
|
612
|
+
case 'utf16le':
|
|
613
|
+
case 'ucs2':
|
|
614
|
+
return true
|
|
615
|
+
default:
|
|
616
|
+
return false
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
swap16(): Buffer {
|
|
621
|
+
const len = this.length
|
|
622
|
+
if (len % 2 !== 0) throw new RangeError('Buffer size must be a multiple of 16-bits')
|
|
623
|
+
for (let i = 0; i < len; i += 2) {
|
|
624
|
+
const v = this[i]
|
|
625
|
+
this[i] = this[i + 1]
|
|
626
|
+
this[i + 1] = v
|
|
627
|
+
}
|
|
628
|
+
return this
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
swap32(): Buffer {
|
|
632
|
+
const len = this.length
|
|
633
|
+
if (len % 4 !== 0) throw new RangeError('Buffer size must be a multiple of 32-bits')
|
|
634
|
+
for (let i = 0; i < len; i += 4) {
|
|
635
|
+
const v0 = this[i]; const v1 = this[i + 1]; const v2 = this[i + 2]; const v3 = this[i + 3];
|
|
636
|
+
this[i] = v3; this[i + 1] = v2; this[i + 2] = v1; this[i + 3] = v0;
|
|
637
|
+
}
|
|
638
|
+
return this
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
swap64(): Buffer {
|
|
642
|
+
const len = this.length
|
|
643
|
+
if (len % 8 !== 0) throw new RangeError('Buffer size must be a multiple of 64-bits')
|
|
644
|
+
for (let i = 0; i < len; i += 8) {
|
|
645
|
+
const v0 = this[i]; const v1 = this[i + 1]; const v2 = this[i + 2]; const v3 = this[i + 3];
|
|
646
|
+
const v4 = this[i + 4]; const v5 = this[i + 5]; const v6 = this[i + 6]; const v7 = this[i + 7];
|
|
647
|
+
this[i] = v7; this[i + 1] = v6; this[i + 2] = v5; this[i + 3] = v4;
|
|
648
|
+
this[i + 4] = v3; this[i + 5] = v2; this[i + 6] = v1; this[i + 7] = v0;
|
|
649
|
+
}
|
|
650
|
+
return this
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
copy(target: Uint8Array, targetStart?: number, sourceStart?: number, sourceEnd?: number): number {
|
|
654
|
+
if (!target) throw new TypeError('argument must be a Buffer')
|
|
655
|
+
if (targetStart === undefined) targetStart = 0
|
|
656
|
+
if (sourceStart === undefined) sourceStart = 0
|
|
657
|
+
if (sourceEnd === undefined) sourceEnd = this.length
|
|
658
|
+
|
|
659
|
+
if (targetStart >= target.length) return 0
|
|
660
|
+
if (sourceStart >= sourceEnd) return 0
|
|
661
|
+
|
|
662
|
+
if (sourceStart < 0) sourceStart = 0
|
|
663
|
+
if (sourceEnd > this.length) sourceEnd = this.length
|
|
664
|
+
if (targetStart < 0) targetStart = 0
|
|
665
|
+
|
|
666
|
+
let len = sourceEnd - sourceStart
|
|
667
|
+
if (target.length - targetStart < len) {
|
|
668
|
+
len = target.length - targetStart
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
target.set(this.subarray(sourceStart, sourceStart + len), targetStart)
|
|
672
|
+
return len
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type HybridObject } from 'react-native-nitro-modules'
|
|
2
|
+
|
|
3
|
+
export interface NitroBuffer extends HybridObject<{ ios: 'c++', android: 'c++' }> {
|
|
4
|
+
// Allocation
|
|
5
|
+
alloc(size: number): ArrayBuffer
|
|
6
|
+
allocUnsafe(size: number): ArrayBuffer
|
|
7
|
+
|
|
8
|
+
// Operations
|
|
9
|
+
byteLength(string: string, encoding: string): number
|
|
10
|
+
write(buffer: ArrayBuffer, string: string, offset: number, length: number, encoding: string): number
|
|
11
|
+
decode(buffer: ArrayBuffer, offset: number, length: number, encoding: string): string
|
|
12
|
+
compare(a: ArrayBuffer, aOffset: number, aLength: number, b: ArrayBuffer, bOffset: number, bLength: number): number
|
|
13
|
+
fill(buffer: ArrayBuffer, value: number, offset: number, length: number): void
|
|
14
|
+
indexOf(buffer: ArrayBuffer, value: number, offset: number, length: number): number
|
|
15
|
+
indexOfBuffer(buffer: ArrayBuffer, needle: ArrayBuffer, offset: number, length: number): number
|
|
16
|
+
lastIndexOfByte(buffer: ArrayBuffer, value: number, offset: number, length: number): number
|
|
17
|
+
lastIndexOfBuffer(buffer: ArrayBuffer, needle: ArrayBuffer, offset: number, length: number): number
|
|
18
|
+
fillBuffer(buffer: ArrayBuffer, value: ArrayBuffer, offset: number, length: number): void
|
|
19
|
+
}
|