init
commit
093392be0d
|
@ -0,0 +1,15 @@
|
|||
dist
|
||||
node_modules
|
||||
index.html
|
||||
.httpserver
|
||||
|
||||
package-lock.json
|
||||
|
||||
._*
|
||||
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
src/
|
||||
test/
|
||||
build.js
|
||||
.prettierrc.yaml
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
jsxBracketSameLine: true
|
||||
jsxSingleQuote: true
|
||||
semi: false
|
||||
singleQuote: true
|
||||
printWidth: 80
|
||||
useTabs: false
|
||||
tabWidth: 2
|
||||
trailingComma: none
|
||||
bracketSpacing: true
|
||||
arrowParens: avoid
|
|
@ -0,0 +1,28 @@
|
|||
import { encode, decode } from './helper.js'
|
||||
|
||||
// string 转 binary
|
||||
export function str2bin(str) {
|
||||
let bin = ''
|
||||
let u8 = encode(str) // 转成Uint8Array
|
||||
for (let i = 0; i < u8.length; i++) {
|
||||
bin += String.fromCharCode(u8[i])
|
||||
}
|
||||
return bin
|
||||
}
|
||||
|
||||
export function bin2str(b) {
|
||||
let u8 = new Uint8Array(b.length)
|
||||
for (let i = 0; i < u8.length; i++) {
|
||||
u8[i] = b[i].charCodeAt(0)
|
||||
}
|
||||
return decode(u8)
|
||||
}
|
||||
|
||||
// 支持对中文的base64编码
|
||||
export function base64encode(str) {
|
||||
return btoa(str2bin(str))
|
||||
}
|
||||
|
||||
export function base64decode(str) {
|
||||
return bin2str(atob(str))
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
const encoder = new TextEncoder()
|
||||
const decoder = new TextDecoder()
|
||||
|
||||
/**
|
||||
* String 转 Uint8Array
|
||||
*/
|
||||
export function encode(txt) {
|
||||
return encoder.encode(txt)
|
||||
}
|
||||
|
||||
/**
|
||||
* Uint8Array 转 String
|
||||
*/
|
||||
export function decode(u8) {
|
||||
return decoder.decode(u8)
|
||||
}
|
||||
|
||||
export function getType(val) {
|
||||
return Object.prototype.toString.call(val).slice(8, -1)
|
||||
}
|
||||
|
||||
export function to16(n) {
|
||||
let p = ''
|
||||
if (n < 16) {
|
||||
p = '0'
|
||||
}
|
||||
return p + n.toString(16)
|
||||
}
|
||||
|
||||
// 将16进制的文本, 转成uint8array
|
||||
export function hex2u8(str) {
|
||||
if (str.length % 2) {
|
||||
throw new Error('Argument str is not a vaild hex string')
|
||||
}
|
||||
let u8 = new Uint8Array(str.length / 2)
|
||||
for (let i = 0; i <= u8.length; i++) {
|
||||
u8[i] = parseInt(str.slice(i * 2, i * 2 + 2), 16)
|
||||
}
|
||||
return u8
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算二维数组的总长度
|
||||
*/
|
||||
export function sum(list) {
|
||||
return list.reduce((total, it) => total + it.length, 0)
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
/**
|
||||
* Buffer对象的 polyfill
|
||||
* @author yutent<yutent.io@gmail.com>
|
||||
* @date 2024/05/29 12:29:17
|
||||
*/
|
||||
|
||||
import { encode, decode, getType, to16, hex2u8, sum } from './helper.js'
|
||||
import { base64encode, base64decode, str2bin, bin2str } from './base64.js'
|
||||
|
||||
/**
|
||||
* 将其他类型的值, 转为uint8array
|
||||
*/
|
||||
function any2u8(data = '', encoding = 'utf8') {
|
||||
if (typeof data === 'object') {
|
||||
let type = getType(data)
|
||||
|
||||
switch (type) {
|
||||
case 'Buffer':
|
||||
case 'Uint8Array':
|
||||
return data
|
||||
|
||||
case 'ArrayBuffer':
|
||||
break
|
||||
|
||||
case 'DataView':
|
||||
data = data.buffer
|
||||
break
|
||||
}
|
||||
return new Uint8Array(data)
|
||||
} else {
|
||||
switch (encoding) {
|
||||
case 'base64':
|
||||
data = base64decode(data)
|
||||
break
|
||||
|
||||
case 'hex':
|
||||
return hex2u8(data)
|
||||
|
||||
case 'binary':
|
||||
data = bin2str(data)
|
||||
break
|
||||
}
|
||||
|
||||
return encode(data + '')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建基于Uint8Array的Buffer类
|
||||
*/
|
||||
export default class Buffer extends Uint8Array {
|
||||
get [Symbol.toStringTag]() {
|
||||
return 'Buffer'
|
||||
}
|
||||
|
||||
static from(data, offsetOrEncoding, end) {
|
||||
let buf = data
|
||||
let start = 0
|
||||
let _encoding = 'utf8'
|
||||
|
||||
if (offsetOrEncoding !== void 0) {
|
||||
if (typeof offsetOrEncoding === 'number') {
|
||||
start = offsetOrEncoding
|
||||
} else if (typeof offsetOrEncoding === 'string') {
|
||||
_encoding = offsetOrEncoding
|
||||
}
|
||||
}
|
||||
|
||||
buf = any2u8(data, _encoding)
|
||||
|
||||
return new Buffer(buf.slice(start, end))
|
||||
}
|
||||
|
||||
static alloc(len, str = '', encoding) {
|
||||
let buf = new Buffer(len)
|
||||
if (str) {
|
||||
buf.fill(str, 0, len, encoding)
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
static concat(list, encoding) {
|
||||
let len = sum(list)
|
||||
let buf = Buffer.alloc(len)
|
||||
|
||||
let offset = 0
|
||||
for (let it of list) {
|
||||
it.copy(buf, offset)
|
||||
offset += it.length
|
||||
}
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
static isBuffer(target) {
|
||||
return getType(target) === 'Buffer'
|
||||
}
|
||||
|
||||
#replace(target, start, end) {
|
||||
for (let i = 0; i < end - start; i++) {
|
||||
this[start + i] = target[i]
|
||||
}
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return { type: 'Buffer', data: [...this].map(to16) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 这个重构为nodejs版的buf.toString()的功能
|
||||
*/
|
||||
toString(encoding = 'utf8', start = 0, end) {
|
||||
let buf = this.slice(start, end)
|
||||
|
||||
switch (encoding) {
|
||||
case 'base64':
|
||||
return base64encode(buf)
|
||||
|
||||
case 'hex':
|
||||
return [...buf].map(to16).join('')
|
||||
|
||||
case 'binary':
|
||||
return str2bin(decode(buf))
|
||||
|
||||
default:
|
||||
return decode(buf)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 原生的 Uint8Array的fill只支持数字,
|
||||
* 这里拓展, 支持字符串和其他Array对象, 与nodejs版相似
|
||||
*/
|
||||
fill(val, start = 0, end, encoding = 'utf8') {
|
||||
//
|
||||
end ??= this.length
|
||||
|
||||
if (typeof val === 'number') {
|
||||
super.fill(val, start, end)
|
||||
} else {
|
||||
val = [...any2u8(val, encoding)]
|
||||
if (val.length === 0) {
|
||||
val = [0]
|
||||
}
|
||||
let tmp = val
|
||||
|
||||
while (tmp.length < end - start) {
|
||||
tmp = tmp.concat(val)
|
||||
}
|
||||
tmp = tmp.slice(0, end)
|
||||
this.#replace(tmp, start, end)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向目标对象中复制内容 (改变的是目标对象, 不是自己)
|
||||
*/
|
||||
copy(target, targetStart = 0, sourceStart = 0, sourceEnd) {
|
||||
if (!(target instanceof Buffer)) {
|
||||
throw new TypeError(
|
||||
"copy()'s argument target must be a Buffer Object, but got %s",
|
||||
getType(target)
|
||||
)
|
||||
}
|
||||
sourceEnd ??= this.length
|
||||
// 复制的总长度, 默认等于总长
|
||||
let copied = sourceEnd - sourceStart
|
||||
|
||||
if (copied > 0) {
|
||||
target.#replace(
|
||||
this.slice(sourceStart, sourceEnd),
|
||||
targetStart,
|
||||
targetStart + copied
|
||||
)
|
||||
}
|
||||
|
||||
return copied
|
||||
}
|
||||
|
||||
/**
|
||||
* 在指定位置, 写入指定内容
|
||||
*/
|
||||
write(str = '', offset = 0, len, encoding = 'utf8') {
|
||||
len ??= this.length
|
||||
let written = len - offset
|
||||
let end = offset + written
|
||||
let u8 = any2u8(str, encoding)
|
||||
|
||||
if (u8.length < written) {
|
||||
written = u8.length
|
||||
end = offset + written
|
||||
}
|
||||
if (written > 0) {
|
||||
this.#replace(u8, offset, end)
|
||||
}
|
||||
return written
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue