dns-packet/buffer.js
2026-04-08 23:23:29 +08:00

205 lines
4.9 KiB
JavaScript

'use strict'
// Allocate a new Uint8Array buffer
function allocBuffer (size) {
return new Uint8Array(size)
}
// Allocate an uninitialized Uint8Array (same as allocBuffer for Uint8Array)
function allocUnsafeBuffer (size) {
return new Uint8Array(size)
}
// Check if an object is a Uint8Array
function isBuffer (obj) {
return obj instanceof Uint8Array
}
// Create Uint8Array from data with optional encoding
function fromBuffer (data, encoding) {
if (data instanceof Uint8Array) {
return new Uint8Array(data)
}
if (Array.isArray(data)) {
return new Uint8Array(data)
}
if (typeof data === 'string') {
if (encoding === 'base64') {
return base64ToBuffer(data)
} else if (encoding === 'hex') {
return hexToBuffer(data)
} else {
return stringToBuffer(data)
}
}
return new Uint8Array(data)
}
// Convert string to Uint8Array (UTF-8 encoding)
function stringToBuffer (str) {
const encoder = new TextEncoder()
return encoder.encode(str)
}
// Convert Base64 string to Uint8Array
function base64ToBuffer (base64Str) {
if (typeof window !== 'undefined' && window.atob) {
// Browser environment
const binaryString = window.atob(base64Str)
const bytes = new Uint8Array(binaryString.length)
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i)
}
return bytes
} else {
// Node.js environment
return new Uint8Array(Buffer.from(base64Str, 'base64'))
}
}
// Convert hex string to Uint8Array
function hexToBuffer (hexStr) {
const bytes = new Uint8Array(hexStr.length / 2)
for (let i = 0; i < hexStr.length; i += 2) {
bytes[i / 2] = parseInt(hexStr.substr(i, 2), 16)
}
return bytes
}
// Convert Uint8Array to hex string
function bufferToHex (buf) {
let hex = ''
for (let i = 0; i < buf.length; i++) {
const byte = buf[i]
hex += (byte < 16 ? '0' : '') + byte.toString(16)
}
return hex.toUpperCase()
}
// Convert Uint8Array to string
function bufferToString (buf, encoding, start, end) {
encoding = encoding || 'utf-8'
start = start || 0
end = end || buf.length
if (encoding !== 'utf-8' && encoding !== 'utf8') {
throw new Error('Unsupported encoding: ' + encoding)
}
const slice = buf.slice(start, end)
const decoder = new TextDecoder('utf-8')
return decoder.decode(slice)
}
// Write string to buffer, return number of bytes written
function writeString (buf, str, offset) {
offset = offset || 0
const encoded = stringToBuffer(str)
for (let i = 0; i < encoded.length && offset + i < buf.length; i++) {
buf[offset + i] = encoded[i]
}
return encoded.length
}
// Get byte length of a string
function byteLength (str) {
const encoder = new TextEncoder()
return encoder.encode(str).length
}
// Read big-endian 16-bit unsigned integer
function readUInt16BE (buf, offset) {
offset = offset || 0
return (buf[offset] << 8) | buf[offset + 1]
}
// Write big-endian 16-bit unsigned integer
function writeUInt16BE (buf, value, offset) {
offset = offset || 0
buf[offset] = (value >> 8) & 0xff
buf[offset + 1] = value & 0xff
}
// Read big-endian 32-bit unsigned integer
function readUInt32BE (buf, offset) {
offset = offset || 0
return ((buf[offset] << 24) | (buf[offset + 1] << 16) | (buf[offset + 2] << 8) | buf[offset + 3]) >>> 0
}
// Write big-endian 32-bit unsigned integer
function writeUInt32BE (buf, value, offset) {
offset = offset || 0
buf[offset] = (value >> 24) & 0xff
buf[offset + 1] = (value >> 16) & 0xff
buf[offset + 2] = (value >> 8) & 0xff
buf[offset + 3] = value & 0xff
}
// Read 8-bit unsigned integer
function readUInt8 (buf, offset) {
offset = offset || 0
return buf[offset]
}
// Write 8-bit unsigned integer
function writeUInt8 (buf, value, offset) {
offset = offset || 0
buf[offset] = value & 0xff
}
// Copy buffer contents
function bufferCopy (source, target, targetStart, sourceStart, sourceEnd) {
targetStart = targetStart || 0
sourceStart = sourceStart || 0
sourceEnd = sourceEnd !== undefined ? sourceEnd : source.length
for (let i = sourceStart; i < sourceEnd; i++) {
target[targetStart + (i - sourceStart)] = source[i]
}
}
// Concatenate multiple buffers
function bufferConcat (buffers, totalLength) {
if (!Array.isArray(buffers)) {
throw new Error('buffers must be an Array')
}
if (buffers.length === 0) {
return new Uint8Array(0)
}
totalLength = totalLength || buffers.reduce((sum, buf) => sum + buf.length, 0)
const result = new Uint8Array(totalLength)
let offset = 0
for (let i = 0; i < buffers.length; i++) {
const buf = buffers[i]
result.set(buf, offset)
offset += buf.length
}
return result
}
module.exports = {
allocBuffer,
allocUnsafeBuffer,
isBuffer,
fromBuffer,
stringToBuffer,
base64ToBuffer,
hexToBuffer,
bufferToHex,
bufferToString,
writeString,
byteLength,
readUInt8,
writeUInt8,
readUInt16BE,
writeUInt16BE,
readUInt32BE,
writeUInt32BE,
bufferCopy,
bufferConcat
}