@wener/utils 1.1.45 → 1.1.46
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/lib/cn/formatChineseAmount.js +77 -0
- package/lib/cn/formatChineseAmount.js.map +1 -0
- package/lib/cn/index.js +1 -0
- package/lib/cn/index.js.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/io/ByteBuffer.js +23 -46
- package/lib/io/ByteBuffer.js.map +1 -1
- package/lib/io/dump.js +31 -0
- package/lib/io/dump.js.map +1 -0
- package/package.json +5 -5
- package/src/cn/formatChineseAmount.ts +61 -0
- package/src/cn/index.ts +1 -1
- package/src/cn/parseChineseNumber.test.ts +135 -0
- package/src/index.ts +1 -0
- package/src/io/ByteBuffer.test.ts +14 -0
- package/src/io/ByteBuffer.ts +24 -52
- package/src/io/dump.ts +35 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see https://gist.github.com/tonyc726/00c829a54a40cf80409f
|
|
3
|
+
* @see https://github.com/Siykt/javascript-algorithms/blob/master/src/algorithms/string/getChinesePrice.ts 人民币金额转中文大写
|
|
4
|
+
*/ export function formatChineseAmount(price) {
|
|
5
|
+
if (price === 0) return '零元整';
|
|
6
|
+
if (price >= 1e12) return '整数位已超过最大值';
|
|
7
|
+
const CHINESE_NUMBER_MAP = [
|
|
8
|
+
'零',
|
|
9
|
+
'壹',
|
|
10
|
+
'贰',
|
|
11
|
+
'叁',
|
|
12
|
+
'肆',
|
|
13
|
+
'伍',
|
|
14
|
+
'陆',
|
|
15
|
+
'柒',
|
|
16
|
+
'捌',
|
|
17
|
+
'玖'
|
|
18
|
+
];
|
|
19
|
+
const CHINESE_UNIT_MAP = [
|
|
20
|
+
'',
|
|
21
|
+
'拾',
|
|
22
|
+
'佰',
|
|
23
|
+
'仟'
|
|
24
|
+
];
|
|
25
|
+
const CHINESE_BIG_UNIT_MAP = [
|
|
26
|
+
'',
|
|
27
|
+
'万',
|
|
28
|
+
'亿'
|
|
29
|
+
];
|
|
30
|
+
const CHINESE_SMALL_UNIT_MAP = [
|
|
31
|
+
'角',
|
|
32
|
+
'分',
|
|
33
|
+
'厘',
|
|
34
|
+
'毫'
|
|
35
|
+
];
|
|
36
|
+
const priceStr = price.toString();
|
|
37
|
+
const priceArr = priceStr.split('.');
|
|
38
|
+
const integer = priceArr[0];
|
|
39
|
+
const decimal = priceArr[1];
|
|
40
|
+
let chineseIntegerPrice = '';
|
|
41
|
+
let zeroCount = 0;
|
|
42
|
+
for(let i = 0; i < integer.length; i++){
|
|
43
|
+
const num = +integer[i];
|
|
44
|
+
const unit = integer.length - i - 1; // 当前数字的单位
|
|
45
|
+
const quotient = Math.floor(unit / 4); // 1w为进位单位, 除 4 即为 万 亿
|
|
46
|
+
const remainder = unit % 4; // 1w为进位单位, 取模 4 即为 个 十 百 千
|
|
47
|
+
if (num === 0) {
|
|
48
|
+
zeroCount++;
|
|
49
|
+
} else {
|
|
50
|
+
// 处理前置的零
|
|
51
|
+
if (zeroCount > 0) chineseIntegerPrice += CHINESE_NUMBER_MAP[0];
|
|
52
|
+
zeroCount = 0;
|
|
53
|
+
chineseIntegerPrice += CHINESE_NUMBER_MAP[num] + CHINESE_UNIT_MAP[remainder];
|
|
54
|
+
}
|
|
55
|
+
if (remainder === 0 && zeroCount < 4) {
|
|
56
|
+
chineseIntegerPrice += CHINESE_BIG_UNIT_MAP[quotient];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// 价格为小数时,整数部分不显示
|
|
60
|
+
if (price < 1) chineseIntegerPrice = '';
|
|
61
|
+
else chineseIntegerPrice += '元';
|
|
62
|
+
let chineseDecimalPrice = '';
|
|
63
|
+
if (!decimal) {
|
|
64
|
+
chineseDecimalPrice = '整';
|
|
65
|
+
} else {
|
|
66
|
+
let hasZero = false;
|
|
67
|
+
for(let i = 0; i < decimal.length; i++){
|
|
68
|
+
const num = +decimal[i];
|
|
69
|
+
if (num) chineseDecimalPrice += CHINESE_NUMBER_MAP[num] + CHINESE_SMALL_UNIT_MAP[i];
|
|
70
|
+
else hasZero = true;
|
|
71
|
+
}
|
|
72
|
+
if (chineseIntegerPrice && hasZero) chineseIntegerPrice += '零';
|
|
73
|
+
}
|
|
74
|
+
return chineseIntegerPrice + chineseDecimalPrice;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=formatChineseAmount.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cn/formatChineseAmount.ts"],"sourcesContent":["/**\n * @see https://gist.github.com/tonyc726/00c829a54a40cf80409f\n * @see https://github.com/Siykt/javascript-algorithms/blob/master/src/algorithms/string/getChinesePrice.ts 人民币金额转中文大写\n */\nexport function formatChineseAmount(price: number) {\n if (price === 0) return '零元整';\n if (price >= 1e12) return '整数位已超过最大值';\n\n const CHINESE_NUMBER_MAP = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];\n const CHINESE_UNIT_MAP = ['', '拾', '佰', '仟'];\n const CHINESE_BIG_UNIT_MAP = ['', '万', '亿'];\n const CHINESE_SMALL_UNIT_MAP = ['角', '分', '厘', '毫'];\n\n const priceStr = price.toString();\n const priceArr = priceStr.split('.');\n const integer = priceArr[0];\n const decimal = priceArr[1];\n\n let chineseIntegerPrice = '';\n let zeroCount = 0;\n\n for (let i = 0; i < integer.length; i++) {\n const num = +integer[i];\n const unit = integer.length - i - 1; // 当前数字的单位\n const quotient = Math.floor(unit / 4); // 1w为进位单位, 除 4 即为 万 亿\n const remainder = unit % 4; // 1w为进位单位, 取模 4 即为 个 十 百 千\n\n if (num === 0) {\n zeroCount++;\n } else {\n // 处理前置的零\n if (zeroCount > 0) chineseIntegerPrice += CHINESE_NUMBER_MAP[0];\n zeroCount = 0;\n chineseIntegerPrice += CHINESE_NUMBER_MAP[num] + CHINESE_UNIT_MAP[remainder];\n }\n if (remainder === 0 && zeroCount < 4) {\n chineseIntegerPrice += CHINESE_BIG_UNIT_MAP[quotient];\n }\n }\n\n // 价格为小数时,整数部分不显示\n if (price < 1) chineseIntegerPrice = '';\n else chineseIntegerPrice += '元';\n\n let chineseDecimalPrice = '';\n\n if (!decimal) {\n chineseDecimalPrice = '整';\n } else {\n let hasZero = false;\n for (let i = 0; i < decimal.length; i++) {\n const num = +decimal[i];\n if (num) chineseDecimalPrice += CHINESE_NUMBER_MAP[num] + CHINESE_SMALL_UNIT_MAP[i];\n else hasZero = true;\n }\n\n if (chineseIntegerPrice && hasZero) chineseIntegerPrice += '零';\n }\n\n return chineseIntegerPrice + chineseDecimalPrice;\n}\n"],"names":["formatChineseAmount","price","CHINESE_NUMBER_MAP","CHINESE_UNIT_MAP","CHINESE_BIG_UNIT_MAP","CHINESE_SMALL_UNIT_MAP","priceStr","toString","priceArr","split","integer","decimal","chineseIntegerPrice","zeroCount","i","length","num","unit","quotient","Math","floor","remainder","chineseDecimalPrice","hasZero"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;CAGC,GACD,OAAO,SAASA,oBAAoBC,KAAa;IAC/C,IAAIA,UAAU,GAAG,OAAO;IACxB,IAAIA,SAAS,MAAM,OAAO;IAE1B,MAAMC,qBAAqB;QAAC;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;KAAI;IAC7E,MAAMC,mBAAmB;QAAC;QAAI;QAAK;QAAK;KAAI;IAC5C,MAAMC,uBAAuB;QAAC;QAAI;QAAK;KAAI;IAC3C,MAAMC,yBAAyB;QAAC;QAAK;QAAK;QAAK;KAAI;IAEnD,MAAMC,WAAWL,MAAMM,QAAQ;IAC/B,MAAMC,WAAWF,SAASG,KAAK,CAAC;IAChC,MAAMC,UAAUF,QAAQ,CAAC,EAAE;IAC3B,MAAMG,UAAUH,QAAQ,CAAC,EAAE;IAE3B,IAAII,sBAAsB;IAC1B,IAAIC,YAAY;IAEhB,IAAK,IAAIC,IAAI,GAAGA,IAAIJ,QAAQK,MAAM,EAAED,IAAK;QACvC,MAAME,MAAM,CAACN,OAAO,CAACI,EAAE;QACvB,MAAMG,OAAOP,QAAQK,MAAM,GAAGD,IAAI,GAAG,UAAU;QAC/C,MAAMI,WAAWC,KAAKC,KAAK,CAACH,OAAO,IAAI,sBAAsB;QAC7D,MAAMI,YAAYJ,OAAO,GAAG,2BAA2B;QAEvD,IAAID,QAAQ,GAAG;YACbH;QACF,OAAO;YACL,SAAS;YACT,IAAIA,YAAY,GAAGD,uBAAuBV,kBAAkB,CAAC,EAAE;YAC/DW,YAAY;YACZD,uBAAuBV,kBAAkB,CAACc,IAAI,GAAGb,gBAAgB,CAACkB,UAAU;QAC9E;QACA,IAAIA,cAAc,KAAKR,YAAY,GAAG;YACpCD,uBAAuBR,oBAAoB,CAACc,SAAS;QACvD;IACF;IAEA,iBAAiB;IACjB,IAAIjB,QAAQ,GAAGW,sBAAsB;SAChCA,uBAAuB;IAE5B,IAAIU,sBAAsB;IAE1B,IAAI,CAACX,SAAS;QACZW,sBAAsB;IACxB,OAAO;QACL,IAAIC,UAAU;QACd,IAAK,IAAIT,IAAI,GAAGA,IAAIH,QAAQI,MAAM,EAAED,IAAK;YACvC,MAAME,MAAM,CAACL,OAAO,CAACG,EAAE;YACvB,IAAIE,KAAKM,uBAAuBpB,kBAAkB,CAACc,IAAI,GAAGX,sBAAsB,CAACS,EAAE;iBAC9ES,UAAU;QACjB;QAEA,IAAIX,uBAAuBW,SAASX,uBAAuB;IAC7D;IAEA,OAAOA,sBAAsBU;AAC/B"}
|
package/lib/cn/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
*/ export { parseChineseNumber } from './parseChineseNumber.js';
|
|
6
|
+
export { formatChineseAmount } from './formatChineseAmount.js';
|
|
6
7
|
export { isUSCC } from './uscc/isUSCC.js';
|
|
7
8
|
export { USCC } from './uscc/USCC.js';
|
|
8
9
|
export { ResidentIdNumber } from './id/ResidentIdNumber.js';
|
package/lib/cn/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cn/index.ts"],"sourcesContent":["/**\n * China related utilities.\n *\n * @packageDocumentation\n */\n\nexport { parseChineseNumber } from './parseChineseNumber';\
|
|
1
|
+
{"version":3,"sources":["../../src/cn/index.ts"],"sourcesContent":["/**\n * China related utilities.\n *\n * @packageDocumentation\n */\n\nexport { parseChineseNumber } from './parseChineseNumber';\nexport { formatChineseAmount } from './formatChineseAmount';\nexport { isUSCC } from './uscc/isUSCC';\nexport { USCC } from './uscc/USCC';\n\nexport { ResidentIdNumber } from './id/ResidentIdNumber';\n\nexport { DivisionCode } from './division/DivisionCode';\n\nexport { toPinyinPure, toPinyinPureFirst, getCharToPinyinTable } from './pinyin/toPinyinPure';\nexport { loadCharToPinyinTable } from './pinyin/loader';\n"],"names":["parseChineseNumber","formatChineseAmount","isUSCC","USCC","ResidentIdNumber","DivisionCode","toPinyinPure","toPinyinPureFirst","getCharToPinyinTable","loadCharToPinyinTable"],"rangeMappings":";;;;;;;;;;;","mappings":"AAAA;;;;CAIC,GAED,SAASA,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,mBAAmB,QAAQ,wBAAwB;AAC5D,SAASC,MAAM,QAAQ,gBAAgB;AACvC,SAASC,IAAI,QAAQ,cAAc;AAEnC,SAASC,gBAAgB,QAAQ,wBAAwB;AAEzD,SAASC,YAAY,QAAQ,0BAA0B;AAEvD,SAASC,YAAY,EAAEC,iBAAiB,EAAEC,oBAAoB,QAAQ,wBAAwB;AAC9F,SAASC,qBAAqB,QAAQ,kBAAkB"}
|
package/lib/index.js
CHANGED
|
@@ -54,6 +54,7 @@ export { isBuffer } from './io/isBuffer.js';
|
|
|
54
54
|
export { isTransferable } from './io/isTransferable.js';
|
|
55
55
|
export { ArrayBuffers } from './io/ArrayBuffers.js';
|
|
56
56
|
export { ByteBuffer } from './io/ByteBuffer.js';
|
|
57
|
+
export { fromHexDump, toHexDump } from './io/dump.js';
|
|
57
58
|
export { Buffer } from './io/Buffer.js';
|
|
58
59
|
export { parseDataUri } from './io/parseDataUri.js';
|
|
59
60
|
// browser
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// arrays\nexport {\n firstOfMaybeArray,\n lastOfMaybeArray,\n arrayOfMaybeArray,\n objectOfMaybeArray,\n type MaybeArray,\n} from './arrays/MaybeArray';\nexport { arrayFromAsync } from './arrays/arrayFromAsync';\n\n// object\nexport { get } from './objects/get';\nexport { set } from './objects/set';\nexport { parseObjectPath } from './objects/parseObjectPath';\nexport { computeIfAbsent } from './objects/computeIfAbsent';\nexport { merge, type MergeOptions } from './objects/merge';\n\n// async\nexport { createLazyPromise, type LazyPromise } from './asyncs/createLazyPromise';\nexport { setAsyncInterval, clearAsyncInterval } from './asyncs/AsyncInterval';\nexport { type MaybePromise } from './asyncs/MaybePromise';\n// async - iterator\nexport { createAsyncIterator } from './asyncs/createAsyncIterator';\nexport { firstOfAsyncIterator } from './asyncs/firstOfAsyncIterator';\nexport { nextOfAsyncIterator } from './asyncs/nextOfAsyncIterator';\nexport { isIterator } from './asyncs/isIterator';\n\nexport { sleep } from './asyncs/sleep';\nexport { timeout, TimeoutError } from './asyncs/timeout';\nexport { isPromise } from './asyncs/isPromise';\n// export * from './async/promiseOfCallback';\n\n// langs\nexport { shallowEqual } from './langs/shallowEqual';\nexport { deepEqual } from './langs/deepEqual';\nexport { deepFreeze } from './langs/deepFreeze';\nexport { classOf } from './langs/classOf';\nexport { shallowClone } from './langs/shallowClone';\nexport { isClass } from './langs/isClass';\nexport { isDefined } from './langs/isDefined';\nexport { isEmptyObject } from './langs/isEmptyObject';\nexport { isPlainObject } from './langs/isPlainObject';\nexport { parseBoolean } from './langs/parseBoolean';\nexport { maybeFunction, type MaybeFunction } from './langs/MaybeFunction';\nexport { memoize } from './langs/memoize';\nexport { mixin } from './langs/mixin';\nexport type { MixinFunction, MixinInstance, MixinReturnValue } from './langs/mixin';\n\nexport { AsyncCloser } from './runtime/AsyncCloser';\nexport { Closer } from './runtime/Closer';\n\nexport { isUUID } from './validations/isUUID';\nexport { parseTimestamp } from './validations/parseTimestamp';\n\n// modules\nexport { parseModuleId, type ParsedModuleId } from './modules/parseModuleId';\nexport { isModule, type Module } from './modules/isModule';\n\n// logging\nexport { type Logger, type LogLevel } from './logging/Logger';\nexport { createLogger } from './logging/createLogger';\nexport { createNoopLogger } from './logging/createNoopLogger';\nexport { createChildLogger } from './logging/createChildLogger';\n\n// strings\nexport { pascalCase, camelCase } from './strings/camelCase';\nexport { renderTemplate } from './strings/renderTemplate';\nexport { formatBytes } from './strings/formatBytes';\n\n// i18n\nexport { createTranslate } from './i18n/createTranslate';\n\n// io\nexport { isBuffer } from './io/isBuffer';\nexport { isTransferable } from './io/isTransferable';\nexport { ArrayBuffers } from './io/ArrayBuffers';\nexport { ByteBuffer } from './io/ByteBuffer';\nexport { Buffer } from './io/Buffer';\nexport { parseDataUri, type ParsedDataUri } from './io/parseDataUri';\nexport type { AbstractEncoding } from './io/AbstractEncoding';\n\n// browser\nexport { copy } from './browsers/copy';\nexport { download } from './browsers/download';\nexport { loadScripts, loadStyles } from './browsers/loaders';\nexport { getFileFromDataTransfer } from './browsers/getFileFromDataTransfer';\n\n// polyfills\nexport { getGlobalThis } from './runtime/getGlobalThis';\nexport { structuredClone } from './runtime/structuredClone';\n\n// crypto\nexport { randomUUID } from './crypto/randomUUID';\nexport { getRandomValues } from './crypto/getRandomValues';\nexport { sha1, sha256, sha384, sha512, hmac, type DigestOptions } from './crypto/hashing';\nexport { md5 } from './crypto/md5';\nexport { hex } from './crypto/base';\nexport { isULID, createULID, ulid, parseULID } from './crypto/ulid';\nexport { PEM } from './crypto/pem/pem';\n\n// math\nexport { createRandom } from './maths/random';\nexport { clamp } from './maths/clamp';\n\n// network\nexport {\n type FetchLike,\n createFetchWith,\n createFetchWithLogging,\n dumpResponse,\n dumpRequest,\n createFetchWithRetry,\n type FetchWithRetryOptions,\n} from './fetch';\n\n// bundled\nexport { default as ms } from './libs/ms';\n\n// error\nexport { Errors, DetailError, type ErrorDetail, type ErrorDetailInit } from './errors/Errors';\n// http\nexport { getHttpStatusText, isRetryableHttpStatus } from './fetch/HttpStatus';\n\nexport type * from './types';\n"],"names":["firstOfMaybeArray","lastOfMaybeArray","arrayOfMaybeArray","objectOfMaybeArray","arrayFromAsync","get","set","parseObjectPath","computeIfAbsent","merge","createLazyPromise","setAsyncInterval","clearAsyncInterval","createAsyncIterator","firstOfAsyncIterator","nextOfAsyncIterator","isIterator","sleep","timeout","TimeoutError","isPromise","shallowEqual","deepEqual","deepFreeze","classOf","shallowClone","isClass","isDefined","isEmptyObject","isPlainObject","parseBoolean","maybeFunction","memoize","mixin","AsyncCloser","Closer","isUUID","parseTimestamp","parseModuleId","isModule","createLogger","createNoopLogger","createChildLogger","pascalCase","camelCase","renderTemplate","formatBytes","createTranslate","isBuffer","isTransferable","ArrayBuffers","ByteBuffer","Buffer","parseDataUri","copy","download","loadScripts","loadStyles","getFileFromDataTransfer","getGlobalThis","structuredClone","randomUUID","getRandomValues","sha1","sha256","sha384","sha512","hmac","md5","hex","isULID","createULID","ulid","parseULID","PEM","createRandom","clamp","createFetchWith","createFetchWithLogging","dumpResponse","dumpRequest","createFetchWithRetry","default","ms","Errors","DetailError","getHttpStatusText","isRetryableHttpStatus"],"rangeMappings":"
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// arrays\nexport {\n firstOfMaybeArray,\n lastOfMaybeArray,\n arrayOfMaybeArray,\n objectOfMaybeArray,\n type MaybeArray,\n} from './arrays/MaybeArray';\nexport { arrayFromAsync } from './arrays/arrayFromAsync';\n\n// object\nexport { get } from './objects/get';\nexport { set } from './objects/set';\nexport { parseObjectPath } from './objects/parseObjectPath';\nexport { computeIfAbsent } from './objects/computeIfAbsent';\nexport { merge, type MergeOptions } from './objects/merge';\n\n// async\nexport { createLazyPromise, type LazyPromise } from './asyncs/createLazyPromise';\nexport { setAsyncInterval, clearAsyncInterval } from './asyncs/AsyncInterval';\nexport { type MaybePromise } from './asyncs/MaybePromise';\n// async - iterator\nexport { createAsyncIterator } from './asyncs/createAsyncIterator';\nexport { firstOfAsyncIterator } from './asyncs/firstOfAsyncIterator';\nexport { nextOfAsyncIterator } from './asyncs/nextOfAsyncIterator';\nexport { isIterator } from './asyncs/isIterator';\n\nexport { sleep } from './asyncs/sleep';\nexport { timeout, TimeoutError } from './asyncs/timeout';\nexport { isPromise } from './asyncs/isPromise';\n// export * from './async/promiseOfCallback';\n\n// langs\nexport { shallowEqual } from './langs/shallowEqual';\nexport { deepEqual } from './langs/deepEqual';\nexport { deepFreeze } from './langs/deepFreeze';\nexport { classOf } from './langs/classOf';\nexport { shallowClone } from './langs/shallowClone';\nexport { isClass } from './langs/isClass';\nexport { isDefined } from './langs/isDefined';\nexport { isEmptyObject } from './langs/isEmptyObject';\nexport { isPlainObject } from './langs/isPlainObject';\nexport { parseBoolean } from './langs/parseBoolean';\nexport { maybeFunction, type MaybeFunction } from './langs/MaybeFunction';\nexport { memoize } from './langs/memoize';\nexport { mixin } from './langs/mixin';\nexport type { MixinFunction, MixinInstance, MixinReturnValue } from './langs/mixin';\n\nexport { AsyncCloser } from './runtime/AsyncCloser';\nexport { Closer } from './runtime/Closer';\n\nexport { isUUID } from './validations/isUUID';\nexport { parseTimestamp } from './validations/parseTimestamp';\n\n// modules\nexport { parseModuleId, type ParsedModuleId } from './modules/parseModuleId';\nexport { isModule, type Module } from './modules/isModule';\n\n// logging\nexport { type Logger, type LogLevel } from './logging/Logger';\nexport { createLogger } from './logging/createLogger';\nexport { createNoopLogger } from './logging/createNoopLogger';\nexport { createChildLogger } from './logging/createChildLogger';\n\n// strings\nexport { pascalCase, camelCase } from './strings/camelCase';\nexport { renderTemplate } from './strings/renderTemplate';\nexport { formatBytes } from './strings/formatBytes';\n\n// i18n\nexport { createTranslate } from './i18n/createTranslate';\n\n// io\nexport { isBuffer } from './io/isBuffer';\nexport { isTransferable } from './io/isTransferable';\nexport { ArrayBuffers } from './io/ArrayBuffers';\nexport { ByteBuffer } from './io/ByteBuffer';\nexport { fromHexDump, toHexDump } from './io/dump';\nexport { Buffer } from './io/Buffer';\nexport { parseDataUri, type ParsedDataUri } from './io/parseDataUri';\nexport type { AbstractEncoding } from './io/AbstractEncoding';\n\n// browser\nexport { copy } from './browsers/copy';\nexport { download } from './browsers/download';\nexport { loadScripts, loadStyles } from './browsers/loaders';\nexport { getFileFromDataTransfer } from './browsers/getFileFromDataTransfer';\n\n// polyfills\nexport { getGlobalThis } from './runtime/getGlobalThis';\nexport { structuredClone } from './runtime/structuredClone';\n\n// crypto\nexport { randomUUID } from './crypto/randomUUID';\nexport { getRandomValues } from './crypto/getRandomValues';\nexport { sha1, sha256, sha384, sha512, hmac, type DigestOptions } from './crypto/hashing';\nexport { md5 } from './crypto/md5';\nexport { hex } from './crypto/base';\nexport { isULID, createULID, ulid, parseULID } from './crypto/ulid';\nexport { PEM } from './crypto/pem/pem';\n\n// math\nexport { createRandom } from './maths/random';\nexport { clamp } from './maths/clamp';\n\n// network\nexport {\n type FetchLike,\n createFetchWith,\n createFetchWithLogging,\n dumpResponse,\n dumpRequest,\n createFetchWithRetry,\n type FetchWithRetryOptions,\n} from './fetch';\n\n// bundled\nexport { default as ms } from './libs/ms';\n\n// error\nexport { Errors, DetailError, type ErrorDetail, type ErrorDetailInit } from './errors/Errors';\n// http\nexport { getHttpStatusText, isRetryableHttpStatus } from './fetch/HttpStatus';\n\nexport type * from './types';\n"],"names":["firstOfMaybeArray","lastOfMaybeArray","arrayOfMaybeArray","objectOfMaybeArray","arrayFromAsync","get","set","parseObjectPath","computeIfAbsent","merge","createLazyPromise","setAsyncInterval","clearAsyncInterval","createAsyncIterator","firstOfAsyncIterator","nextOfAsyncIterator","isIterator","sleep","timeout","TimeoutError","isPromise","shallowEqual","deepEqual","deepFreeze","classOf","shallowClone","isClass","isDefined","isEmptyObject","isPlainObject","parseBoolean","maybeFunction","memoize","mixin","AsyncCloser","Closer","isUUID","parseTimestamp","parseModuleId","isModule","createLogger","createNoopLogger","createChildLogger","pascalCase","camelCase","renderTemplate","formatBytes","createTranslate","isBuffer","isTransferable","ArrayBuffers","ByteBuffer","fromHexDump","toHexDump","Buffer","parseDataUri","copy","download","loadScripts","loadStyles","getFileFromDataTransfer","getGlobalThis","structuredClone","randomUUID","getRandomValues","sha1","sha256","sha384","sha512","hmac","md5","hex","isULID","createULID","ulid","parseULID","PEM","createRandom","clamp","createFetchWith","createFetchWithLogging","dumpResponse","dumpRequest","createFetchWithRetry","default","ms","Errors","DetailError","getHttpStatusText","isRetryableHttpStatus"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
package/lib/io/ByteBuffer.js
CHANGED
|
@@ -28,8 +28,9 @@ function asBuffer(o) {
|
|
|
28
28
|
// return new DataView(o);
|
|
29
29
|
// }
|
|
30
30
|
/**
|
|
31
|
-
* @see https://www.egret.uk/docs/egretengine/engine/egret.ByteArray
|
|
32
|
-
* @see https://
|
|
31
|
+
* @see {@link https://www.egret.uk/docs/egretengine/engine/egret.ByteArray egret.ByteArray}
|
|
32
|
+
* @see {@link https://github.com/protobufjs/bytebuffer.js protobufjs/bytebuffer.js}
|
|
33
|
+
* @see {@link https://netty.io/4.1/api/io/netty/buffer/ByteBuf.html ByteBuf}
|
|
33
34
|
*/ export class ByteBuffer {
|
|
34
35
|
position = 0;
|
|
35
36
|
#buffer;
|
|
@@ -38,7 +39,7 @@ function asBuffer(o) {
|
|
|
38
39
|
maxByteLength: 1024
|
|
39
40
|
})){
|
|
40
41
|
this.#buffer = asBuffer(buffer);
|
|
41
|
-
//
|
|
42
|
+
// NOTE prefer view over buffer, avoid the slice overhead ?
|
|
42
43
|
this.#view = new DataView(this.#buffer);
|
|
43
44
|
}
|
|
44
45
|
get view() {
|
|
@@ -57,7 +58,7 @@ function asBuffer(o) {
|
|
|
57
58
|
set length(length) {
|
|
58
59
|
this.resize(length);
|
|
59
60
|
}
|
|
60
|
-
|
|
61
|
+
willWrite(length) {
|
|
61
62
|
if (this.remaining() < length) {
|
|
62
63
|
this.resize(this.length + length);
|
|
63
64
|
}
|
|
@@ -74,61 +75,62 @@ function asBuffer(o) {
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
writeByte(value) {
|
|
77
|
-
this.
|
|
78
|
+
this.willWrite(1);
|
|
78
79
|
this.view.setUint8(this.position++, value);
|
|
79
80
|
}
|
|
80
|
-
writeBytes(bytes) {
|
|
81
|
-
this.
|
|
81
|
+
writeBytes(bytes, len = bytes.byteLength) {
|
|
82
|
+
this.willWrite(len);
|
|
83
|
+
if (len !== bytes.byteLength) bytes = bytes.slice(0, len);
|
|
82
84
|
new Uint8Array(this.buffer).set(new Uint8Array(bytes), this.position);
|
|
83
85
|
this.position += bytes.byteLength;
|
|
84
86
|
}
|
|
85
87
|
writeInt8(value) {
|
|
86
|
-
this.
|
|
88
|
+
this.willWrite(1);
|
|
87
89
|
this.view.setInt8(this.position, value);
|
|
88
90
|
this.position += 1;
|
|
89
91
|
}
|
|
90
92
|
writeUint8(value) {
|
|
91
|
-
this.
|
|
93
|
+
this.willWrite(1);
|
|
92
94
|
this.view.setUint8(this.position, value);
|
|
93
95
|
this.position += 1;
|
|
94
96
|
}
|
|
95
97
|
writeInt16(value) {
|
|
96
|
-
this.
|
|
98
|
+
this.willWrite(2);
|
|
97
99
|
this.view.setInt16(this.position, value);
|
|
98
100
|
this.position += 2;
|
|
99
101
|
}
|
|
100
102
|
writeUint16(value) {
|
|
101
|
-
this.
|
|
103
|
+
this.willWrite(2);
|
|
102
104
|
this.view.setUint16(this.position, value);
|
|
103
105
|
this.position += 2;
|
|
104
106
|
}
|
|
105
107
|
writeInt32(value) {
|
|
106
|
-
this.
|
|
108
|
+
this.willWrite(4);
|
|
107
109
|
this.view.setInt32(this.position, value);
|
|
108
110
|
this.position += 4;
|
|
109
111
|
}
|
|
110
112
|
writeUint32(value) {
|
|
111
|
-
this.
|
|
113
|
+
this.willWrite(4);
|
|
112
114
|
this.view.setUint32(this.position, value);
|
|
113
115
|
this.position += 4;
|
|
114
116
|
}
|
|
115
117
|
writeInt64(value) {
|
|
116
|
-
this.
|
|
118
|
+
this.willWrite(8);
|
|
117
119
|
this.view.setBigInt64(this.position, value);
|
|
118
120
|
this.position += 8;
|
|
119
121
|
}
|
|
120
122
|
writeUint64(value) {
|
|
121
|
-
this.
|
|
123
|
+
this.willWrite(8);
|
|
122
124
|
this.view.setBigUint64(this.position, value);
|
|
123
125
|
this.position += 8;
|
|
124
126
|
}
|
|
125
127
|
writeFloat32(value) {
|
|
126
|
-
this.
|
|
128
|
+
this.willWrite(4);
|
|
127
129
|
this.view.setFloat32(this.position, value);
|
|
128
130
|
this.position += 4;
|
|
129
131
|
}
|
|
130
132
|
writeFloat64(value) {
|
|
131
|
-
this.
|
|
133
|
+
this.willWrite(8);
|
|
132
134
|
this.view.setFloat64(this.position, value);
|
|
133
135
|
this.position += 8;
|
|
134
136
|
}
|
|
@@ -138,7 +140,7 @@ function asBuffer(o) {
|
|
|
138
140
|
writeString(value, len) {
|
|
139
141
|
let encoder = new TextEncoder();
|
|
140
142
|
let bytes = encoder.encode(value);
|
|
141
|
-
this.writeBytes(
|
|
143
|
+
this.writeBytes(bytes, len);
|
|
142
144
|
}
|
|
143
145
|
readByte() {
|
|
144
146
|
return this.view.getUint8(this.position++);
|
|
@@ -288,34 +290,9 @@ function asBuffer(o) {
|
|
|
288
290
|
toHex() {
|
|
289
291
|
return ArrayBuffers.toHex(this.buffer);
|
|
290
292
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
let idxPrefix = `${i.toString(16).padStart(8, '0')}:`;
|
|
295
|
-
let content = Array.from(v.match(/.{4}/g) ?? []).join(' ');
|
|
296
|
-
let chars = Array.from(new Uint8Array(ArrayBuffers.fromHex(v).buffer)).map((v)=>{
|
|
297
|
-
let c = String.fromCharCode(v);
|
|
298
|
-
if (v < 32 || v > 126) {
|
|
299
|
-
c = '.';
|
|
300
|
-
}
|
|
301
|
-
return c;
|
|
302
|
-
});
|
|
303
|
-
return [
|
|
304
|
-
idxPrefix,
|
|
305
|
-
content.padEnd(40, ' '),
|
|
306
|
-
chars.join('')
|
|
307
|
-
].join(' ');
|
|
308
|
-
}).join('\n');
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Chrome Websocket Binary format
|
|
312
|
-
* ```
|
|
313
|
-
* 00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
|
314
|
-
* ```
|
|
315
|
-
*/ export function fromDump(dump) {
|
|
316
|
-
return ArrayBuffers.fromHex(dump.split('\n').map((v)=>{
|
|
317
|
-
return v.substring(10, 10 + 41).replaceAll(' ', '');
|
|
318
|
-
}).join(''));
|
|
293
|
+
toBase64() {
|
|
294
|
+
return ArrayBuffers.toBase64(this.buffer);
|
|
295
|
+
}
|
|
319
296
|
}
|
|
320
297
|
function safeNumber(n) {
|
|
321
298
|
if (n > Number.MAX_SAFE_INTEGER) {
|
package/lib/io/ByteBuffer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/io/ByteBuffer.ts"],"sourcesContent":["import { isDefined } from '../langs/isDefined';\nimport { ArrayBuffers } from './ArrayBuffers';\n\ntype AnyBuffer = BufferSource | ArrayBufferLike;\n\nfunction asBuffer(o: AnyBuffer) {\n if (o instanceof ArrayBuffer) {\n return o;\n }\n if (ArrayBuffer.isView(o)) {\n // 保留 offset&length\n if (o.byteLength !== o.buffer.byteLength) {\n // ArrayBuffer 没有 subarray\n // if ('subarray' in o.buffer) {\n // return (o.buffer as any).subarray(o.byteOffset, o.byteOffset + o.byteLength);\n // }\n return o.buffer.slice(o.byteOffset, o.byteOffset + o.byteLength);\n }\n return o.buffer;\n }\n return o;\n}\n\n// function asView(o: AnyBuffer) {\n// if (o instanceof DataView) {\n// return o;\n// }\n// if (ArrayBuffer.isView(o)) {\n// // 不 clone 也能保留 offset&length\n// return new DataView(o.buffer, o.byteOffset, o.byteLength);\n// }\n// return new DataView(o);\n// }\n\n/**\n * @see https://www.egret.uk/docs/egretengine/engine/egret.ByteArray\n * @see https://netty.io/4.1/api/io/netty/buffer/ByteBuf.html\n */\nexport class ByteBuffer {\n position = 0;\n\n #buffer: ArrayBufferLike;\n #view: DataView;\n\n constructor(buffer: AnyBuffer = new ArrayBuffer(0, { maxByteLength: 1024 })) {\n this.#buffer = asBuffer(buffer);\n // note prefer view over buffer, avoid the slice overhead ?\n this.#view = new DataView(this.#buffer);\n }\n\n get view() {\n return this.#view;\n }\n\n get buffer(): ArrayBufferLike {\n return this.#buffer;\n }\n\n set buffer(buffer: AnyBuffer) {\n this.#buffer = asBuffer(buffer);\n this.#view = new DataView(this.#buffer);\n }\n\n get length() {\n return this.view.byteLength;\n }\n\n set length(length: number) {\n this.resize(length);\n }\n\n private ensureSpace(length: number) {\n if (this.remaining() < length) {\n this.resize(this.length + length);\n }\n }\n\n resize(newLength: number) {\n // Chrome 111, Nodejs 20\n let buf = this.buffer;\n if (buf.resize && (!isDefined(buf.resizable) || buf.resizable)) {\n buf.resize(newLength);\n } else {\n let newBuffer = new ArrayBuffer(newLength);\n new Uint8Array(newBuffer).set(new Uint8Array(buf));\n this.buffer = newBuffer;\n }\n }\n\n writeByte(value: number) {\n this.ensureSpace(1);\n this.view.setUint8(this.position++, value);\n }\n\n writeBytes(bytes: ArrayBufferLike) {\n this.ensureSpace(bytes.byteLength);\n new Uint8Array(this.buffer).set(new Uint8Array(bytes), this.position);\n this.position += bytes.byteLength;\n }\n\n writeInt8(value: number) {\n this.ensureSpace(1);\n this.view.setInt8(this.position, value);\n this.position += 1;\n }\n\n writeUint8(value: number) {\n this.ensureSpace(1);\n this.view.setUint8(this.position, value);\n this.position += 1;\n }\n\n writeInt16(value: number) {\n this.ensureSpace(2);\n this.view.setInt16(this.position, value);\n this.position += 2;\n }\n\n writeUint16(value: number) {\n this.ensureSpace(2);\n this.view.setUint16(this.position, value);\n this.position += 2;\n }\n\n writeInt32(value: number) {\n this.ensureSpace(4);\n this.view.setInt32(this.position, value);\n this.position += 4;\n }\n\n writeUint32(value: number) {\n this.ensureSpace(4);\n this.view.setUint32(this.position, value);\n this.position += 4;\n }\n\n writeInt64(value: bigint) {\n this.ensureSpace(8);\n this.view.setBigInt64(this.position, value);\n this.position += 8;\n }\n\n writeUint64(value: bigint) {\n this.ensureSpace(8);\n this.view.setBigUint64(this.position, value);\n this.position += 8;\n }\n\n writeFloat32(value: number) {\n this.ensureSpace(4);\n this.view.setFloat32(this.position, value);\n this.position += 4;\n }\n\n writeFloat64(value: number) {\n this.ensureSpace(8);\n this.view.setFloat64(this.position, value);\n this.position += 8;\n }\n\n writeBoolean(value: boolean) {\n this.writeByte(value ? 1 : 0);\n }\n\n writeString(value: string): void;\n writeString(value: string, len?: number): void;\n writeString(value: string, len?: number) {\n let encoder = new TextEncoder();\n let bytes = encoder.encode(value);\n this.writeBytes(ArrayBuffers.resize(bytes.buffer, len));\n }\n\n readByte() {\n return this.view.getUint8(this.position++);\n }\n\n readBytes(length: number) {\n let bytes = this.buffer.slice(this.position, this.position + length);\n this.position += length;\n return bytes;\n }\n\n readInt8() {\n let value = this.view.getInt8(this.position);\n this.position += 1;\n return value;\n }\n\n readUint8() {\n let value = this.view.getUint8(this.position);\n this.position += 1;\n return value;\n }\n\n readInt16() {\n let value = this.view.getInt16(this.position);\n this.position += 2;\n return value;\n }\n\n readUint16() {\n let value = this.view.getUint16(this.position);\n this.position += 2;\n return value;\n }\n\n readInt32() {\n let value = this.view.getInt32(this.position);\n this.position += 4;\n return value;\n }\n\n readUint32() {\n let value = this.view.getUint32(this.position);\n this.position += 4;\n return value;\n }\n\n readInt64() {\n let value = this.view.getBigInt64(this.position);\n this.position += 8;\n return safeNumber(value);\n }\n\n readUint64() {\n let value = this.view.getBigUint64(this.position);\n this.position += 8;\n return safeNumber(value);\n }\n\n readFloat32() {\n let value = this.view.getFloat32(this.position);\n this.position += 4;\n return value;\n }\n\n readFloat64() {\n let value = this.view.getFloat64(this.position);\n this.position += 8;\n return value;\n }\n\n readBoolean() {\n return this.readByte() === 1;\n }\n\n readString(length: number) {\n let bytes = this.readBytes(length);\n let decoder = new TextDecoder();\n let a = new Uint8Array(bytes);\n let idx = a.indexOf(0);\n if (idx !== -1) {\n bytes = bytes.slice(0, idx);\n }\n return decoder.decode(bytes);\n }\n\n readHexString(length: number) {\n let bytes = this.readBytes(length);\n return ArrayBuffers.toHex(bytes);\n }\n\n writeInt24(value: number) {\n this.writeUint8(value & 0xff);\n this.writeUint16(value >> 8);\n }\n\n readInt24() {\n return this.readUint8() | (this.readUint16() << 8);\n }\n\n writeZero(length: number) {\n this.writeBytes(new Uint8Array(length).buffer);\n }\n\n writeValue(typ: TypedValue['type'], val: TypedValue['value']): void;\n writeValue(tv: TypedValue): void;\n writeValue(a: any, b?: any) {\n const tv: TypedValue = typeof a === 'string' ? { type: a, value: b } : a;\n const { type, value, length } = tv;\n switch (type) {\n case 'uint8':\n this.writeUint8(value);\n break;\n case 'byte':\n case 'int8':\n this.writeInt8(value);\n break;\n case 'uint16':\n this.writeUint16(value);\n break;\n case 'int16':\n this.writeInt16(value);\n break;\n case 'uint32':\n this.writeUint32(value);\n break;\n case 'int32':\n this.writeInt32(value);\n break;\n case 'float32':\n this.writeFloat32(value);\n break;\n case 'float64':\n this.writeFloat64(value);\n break;\n case 'string':\n this.writeString(value, length);\n break;\n case 'boolean':\n this.writeBoolean(value);\n break;\n case 'bytes':\n this.writeBytes(value);\n break;\n default:\n throw new Error(`Unknown type ${type}`);\n }\n }\n\n readInt() {\n return this.readInt32();\n }\n\n readFloat() {\n return this.readFloat32();\n }\n\n readDouble() {\n return this.readFloat64();\n }\n\n remaining() {\n return this.view.byteLength - this.position;\n }\n\n toUint8Array() {\n return new Uint8Array(this.buffer);\n }\n\n toHex() {\n return ArrayBuffers.toHex(this.buffer);\n }\n}\n\nexport interface TypedValue {\n type:\n | 'byte'\n | 'bytes'\n | 'uint8'\n | 'int8'\n | 'uint16'\n | 'int16'\n | 'uint32'\n | 'int32'\n | 'float32'\n | 'float64'\n | 'string'\n | 'boolean';\n value: any;\n length?: number;\n}\n\nexport function toDump(data: BufferSource) {\n return Array.from(ArrayBuffers.toHex(data).match(/.{1,32}/g) ?? [])\n .map((v, i) => {\n let idxPrefix = `${i.toString(16).padStart(8, '0')}:`;\n let content = Array.from(v.match(/.{4}/g) ?? []).join(' ');\n let chars = Array.from(new Uint8Array(ArrayBuffers.fromHex(v).buffer)).map((v) => {\n let c = String.fromCharCode(v);\n if (v < 32 || v > 126) {\n c = '.';\n }\n return c;\n });\n return [idxPrefix, content.padEnd(40, ' '), chars.join('')].join(' ');\n })\n .join('\\n');\n}\n\n/**\n * Chrome Websocket Binary format\n * ```\n * 00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................\n * ```\n */\nexport function fromDump(dump: string) {\n return ArrayBuffers.fromHex(\n dump\n .split('\\n')\n .map((v) => {\n return v.substring(10, 10 + 41).replaceAll(' ', '');\n })\n .join(''),\n );\n}\n\nfunction safeNumber(n: bigint) {\n if (n > Number.MAX_SAFE_INTEGER) {\n return n;\n }\n return Number(n);\n}\n"],"names":["isDefined","ArrayBuffers","asBuffer","o","ArrayBuffer","isView","byteLength","buffer","slice","byteOffset","ByteBuffer","position","view","constructor","maxByteLength","DataView","length","resize","ensureSpace","remaining","newLength","buf","resizable","newBuffer","Uint8Array","set","writeByte","value","setUint8","writeBytes","bytes","writeInt8","setInt8","writeUint8","writeInt16","setInt16","writeUint16","setUint16","writeInt32","setInt32","writeUint32","setUint32","writeInt64","setBigInt64","writeUint64","setBigUint64","writeFloat32","setFloat32","writeFloat64","setFloat64","writeBoolean","writeString","len","encoder","TextEncoder","encode","readByte","getUint8","readBytes","readInt8","getInt8","readUint8","readInt16","getInt16","readUint16","getUint16","readInt32","getInt32","readUint32","getUint32","readInt64","getBigInt64","safeNumber","readUint64","getBigUint64","readFloat32","getFloat32","readFloat64","getFloat64","readBoolean","readString","decoder","TextDecoder","a","idx","indexOf","decode","readHexString","toHex","writeInt24","readInt24","writeZero","writeValue","b","tv","type","Error","readInt","readFloat","readDouble","toUint8Array","toDump","data","Array","from","match","map","v","i","idxPrefix","toString","padStart","content","join","chars","fromHex","c","String","fromCharCode","padEnd","fromDump","dump","split","substring","replaceAll","n","Number","MAX_SAFE_INTEGER"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/io/ByteBuffer.ts"],"sourcesContent":["import { isDefined } from '../langs/isDefined';\nimport { ArrayBuffers } from './ArrayBuffers';\n\ntype AnyBuffer = BufferSource | ArrayBufferLike;\n\nfunction asBuffer(o: AnyBuffer) {\n if (o instanceof ArrayBuffer) {\n return o;\n }\n if (ArrayBuffer.isView(o)) {\n // 保留 offset&length\n if (o.byteLength !== o.buffer.byteLength) {\n // ArrayBuffer 没有 subarray\n // if ('subarray' in o.buffer) {\n // return (o.buffer as any).subarray(o.byteOffset, o.byteOffset + o.byteLength);\n // }\n return o.buffer.slice(o.byteOffset, o.byteOffset + o.byteLength);\n }\n return o.buffer;\n }\n return o;\n}\n\n// function asView(o: AnyBuffer) {\n// if (o instanceof DataView) {\n// return o;\n// }\n// if (ArrayBuffer.isView(o)) {\n// // 不 clone 也能保留 offset&length\n// return new DataView(o.buffer, o.byteOffset, o.byteLength);\n// }\n// return new DataView(o);\n// }\n\n/**\n * @see {@link https://www.egret.uk/docs/egretengine/engine/egret.ByteArray egret.ByteArray}\n * @see {@link https://github.com/protobufjs/bytebuffer.js protobufjs/bytebuffer.js}\n * @see {@link https://netty.io/4.1/api/io/netty/buffer/ByteBuf.html ByteBuf}\n */\nexport class ByteBuffer {\n position = 0;\n\n #buffer: ArrayBufferLike;\n #view: DataView;\n\n constructor(buffer: AnyBuffer = new ArrayBuffer(0, { maxByteLength: 1024 })) {\n this.#buffer = asBuffer(buffer);\n // NOTE prefer view over buffer, avoid the slice overhead ?\n this.#view = new DataView(this.#buffer);\n }\n\n get view() {\n return this.#view;\n }\n\n get buffer(): ArrayBufferLike {\n return this.#buffer;\n }\n\n set buffer(buffer: AnyBuffer) {\n this.#buffer = asBuffer(buffer);\n this.#view = new DataView(this.#buffer);\n }\n\n get length() {\n return this.view.byteLength;\n }\n\n set length(length: number) {\n this.resize(length);\n }\n\n private willWrite(length: number) {\n if (this.remaining() < length) {\n this.resize(this.length + length);\n }\n }\n\n resize(newLength: number) {\n // Chrome 111, Nodejs 20\n let buf = this.buffer;\n if (buf.resize && (!isDefined(buf.resizable) || buf.resizable)) {\n buf.resize(newLength);\n } else {\n let newBuffer = new ArrayBuffer(newLength);\n new Uint8Array(newBuffer).set(new Uint8Array(buf));\n this.buffer = newBuffer;\n }\n }\n\n writeByte(value: number) {\n this.willWrite(1);\n this.view.setUint8(this.position++, value);\n }\n\n writeBytes(bytes: ArrayBufferLike, len: number = bytes.byteLength) {\n this.willWrite(len);\n if (len !== bytes.byteLength) bytes = bytes.slice(0, len);\n new Uint8Array(this.buffer).set(new Uint8Array(bytes), this.position);\n this.position += bytes.byteLength;\n }\n\n writeInt8(value: number) {\n this.willWrite(1);\n this.view.setInt8(this.position, value);\n this.position += 1;\n }\n\n writeUint8(value: number) {\n this.willWrite(1);\n this.view.setUint8(this.position, value);\n this.position += 1;\n }\n\n writeInt16(value: number) {\n this.willWrite(2);\n this.view.setInt16(this.position, value);\n this.position += 2;\n }\n\n writeUint16(value: number) {\n this.willWrite(2);\n this.view.setUint16(this.position, value);\n this.position += 2;\n }\n\n writeInt32(value: number) {\n this.willWrite(4);\n this.view.setInt32(this.position, value);\n this.position += 4;\n }\n\n writeUint32(value: number) {\n this.willWrite(4);\n this.view.setUint32(this.position, value);\n this.position += 4;\n }\n\n writeInt64(value: bigint) {\n this.willWrite(8);\n this.view.setBigInt64(this.position, value);\n this.position += 8;\n }\n\n writeUint64(value: bigint) {\n this.willWrite(8);\n this.view.setBigUint64(this.position, value);\n this.position += 8;\n }\n\n writeFloat32(value: number) {\n this.willWrite(4);\n this.view.setFloat32(this.position, value);\n this.position += 4;\n }\n\n writeFloat64(value: number) {\n this.willWrite(8);\n this.view.setFloat64(this.position, value);\n this.position += 8;\n }\n\n writeBoolean(value: boolean) {\n this.writeByte(value ? 1 : 0);\n }\n\n writeString(value: string): void;\n writeString(value: string, len?: number): void;\n writeString(value: string, len?: number) {\n let encoder = new TextEncoder();\n let bytes = encoder.encode(value);\n this.writeBytes(bytes, len);\n }\n\n readByte() {\n return this.view.getUint8(this.position++);\n }\n\n readBytes(length: number) {\n let bytes = this.buffer.slice(this.position, this.position + length);\n this.position += length;\n return bytes;\n }\n\n readInt8() {\n let value = this.view.getInt8(this.position);\n this.position += 1;\n return value;\n }\n\n readUint8() {\n let value = this.view.getUint8(this.position);\n this.position += 1;\n return value;\n }\n\n readInt16() {\n let value = this.view.getInt16(this.position);\n this.position += 2;\n return value;\n }\n\n readUint16() {\n let value = this.view.getUint16(this.position);\n this.position += 2;\n return value;\n }\n\n readInt32() {\n let value = this.view.getInt32(this.position);\n this.position += 4;\n return value;\n }\n\n readUint32() {\n let value = this.view.getUint32(this.position);\n this.position += 4;\n return value;\n }\n\n readInt64() {\n let value = this.view.getBigInt64(this.position);\n this.position += 8;\n return safeNumber(value);\n }\n\n readUint64() {\n let value = this.view.getBigUint64(this.position);\n this.position += 8;\n return safeNumber(value);\n }\n\n readFloat32() {\n let value = this.view.getFloat32(this.position);\n this.position += 4;\n return value;\n }\n\n readFloat64() {\n let value = this.view.getFloat64(this.position);\n this.position += 8;\n return value;\n }\n\n readBoolean() {\n return this.readByte() === 1;\n }\n\n readString(length: number) {\n let bytes = this.readBytes(length);\n let decoder = new TextDecoder();\n let a = new Uint8Array(bytes);\n let idx = a.indexOf(0);\n if (idx !== -1) {\n bytes = bytes.slice(0, idx);\n }\n return decoder.decode(bytes);\n }\n\n readHexString(length: number) {\n let bytes = this.readBytes(length);\n return ArrayBuffers.toHex(bytes);\n }\n\n writeInt24(value: number) {\n this.writeUint8(value & 0xff);\n this.writeUint16(value >> 8);\n }\n\n readInt24() {\n return this.readUint8() | (this.readUint16() << 8);\n }\n\n writeZero(length: number) {\n this.writeBytes(new Uint8Array(length).buffer);\n }\n\n writeValue(typ: TypedValue['type'], val: TypedValue['value']): void;\n writeValue(tv: TypedValue): void;\n writeValue(a: any, b?: any) {\n const tv: TypedValue = typeof a === 'string' ? { type: a, value: b } : a;\n const { type, value, length } = tv;\n switch (type) {\n case 'uint8':\n this.writeUint8(value);\n break;\n case 'byte':\n case 'int8':\n this.writeInt8(value);\n break;\n case 'uint16':\n this.writeUint16(value);\n break;\n case 'int16':\n this.writeInt16(value);\n break;\n case 'uint32':\n this.writeUint32(value);\n break;\n case 'int32':\n this.writeInt32(value);\n break;\n case 'float32':\n this.writeFloat32(value);\n break;\n case 'float64':\n this.writeFloat64(value);\n break;\n case 'string':\n this.writeString(value, length);\n break;\n case 'boolean':\n this.writeBoolean(value);\n break;\n case 'bytes':\n this.writeBytes(value);\n break;\n default:\n throw new Error(`Unknown type ${type}`);\n }\n }\n\n readInt() {\n return this.readInt32();\n }\n\n readFloat() {\n return this.readFloat32();\n }\n\n readDouble() {\n return this.readFloat64();\n }\n\n remaining() {\n return this.view.byteLength - this.position;\n }\n\n toUint8Array() {\n return new Uint8Array(this.buffer);\n }\n\n toHex() {\n return ArrayBuffers.toHex(this.buffer);\n }\n\n toBase64() {\n return ArrayBuffers.toBase64(this.buffer);\n }\n}\n\nexport interface TypedValue {\n type:\n | 'byte'\n | 'bytes'\n | 'uint8'\n | 'int8'\n | 'uint16'\n | 'int16'\n | 'uint32'\n | 'int32'\n | 'float32'\n | 'float64'\n | 'string'\n | 'boolean';\n value: any;\n length?: number;\n}\n\nfunction safeNumber(n: bigint) {\n if (n > Number.MAX_SAFE_INTEGER) {\n return n;\n }\n return Number(n);\n}\n"],"names":["isDefined","ArrayBuffers","asBuffer","o","ArrayBuffer","isView","byteLength","buffer","slice","byteOffset","ByteBuffer","position","view","constructor","maxByteLength","DataView","length","resize","willWrite","remaining","newLength","buf","resizable","newBuffer","Uint8Array","set","writeByte","value","setUint8","writeBytes","bytes","len","writeInt8","setInt8","writeUint8","writeInt16","setInt16","writeUint16","setUint16","writeInt32","setInt32","writeUint32","setUint32","writeInt64","setBigInt64","writeUint64","setBigUint64","writeFloat32","setFloat32","writeFloat64","setFloat64","writeBoolean","writeString","encoder","TextEncoder","encode","readByte","getUint8","readBytes","readInt8","getInt8","readUint8","readInt16","getInt16","readUint16","getUint16","readInt32","getInt32","readUint32","getUint32","readInt64","getBigInt64","safeNumber","readUint64","getBigUint64","readFloat32","getFloat32","readFloat64","getFloat64","readBoolean","readString","decoder","TextDecoder","a","idx","indexOf","decode","readHexString","toHex","writeInt24","readInt24","writeZero","writeValue","b","tv","type","Error","readInt","readFloat","readDouble","toUint8Array","toBase64","n","Number","MAX_SAFE_INTEGER"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
package/lib/io/dump.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ArrayBuffers } from './ArrayBuffers.js';
|
|
2
|
+
export function toHexDump(data) {
|
|
3
|
+
return Array.from(ArrayBuffers.toHex(data).match(/.{1,32}/g) ?? []).map((v, i)=>{
|
|
4
|
+
let idxPrefix = `${i.toString(16).padStart(8, '0')}:`;
|
|
5
|
+
let content = Array.from(v.match(/.{4}/g) ?? []).join(' ');
|
|
6
|
+
let chars = Array.from(new Uint8Array(ArrayBuffers.fromHex(v).buffer)).map((v)=>{
|
|
7
|
+
let c = String.fromCharCode(v);
|
|
8
|
+
if (v < 32 || v > 126) {
|
|
9
|
+
c = '.';
|
|
10
|
+
}
|
|
11
|
+
return c;
|
|
12
|
+
});
|
|
13
|
+
return [
|
|
14
|
+
idxPrefix,
|
|
15
|
+
content.padEnd(40, ' '),
|
|
16
|
+
chars.join('')
|
|
17
|
+
].join(' ');
|
|
18
|
+
}).join('\n');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Chrome Websocket Binary format
|
|
22
|
+
* ```
|
|
23
|
+
* 00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
|
24
|
+
* ```
|
|
25
|
+
*/ export function fromHexDump(dump) {
|
|
26
|
+
return ArrayBuffers.fromHex(dump.split('\n').map((v)=>{
|
|
27
|
+
return v.substring(10, 10 + 41).replaceAll(' ', '');
|
|
28
|
+
}).join(''));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=dump.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/io/dump.ts"],"sourcesContent":["import { ArrayBuffers } from './ArrayBuffers';\n\nexport function toHexDump(data: BufferSource) {\n return Array.from(ArrayBuffers.toHex(data).match(/.{1,32}/g) ?? [])\n .map((v, i) => {\n let idxPrefix = `${i.toString(16).padStart(8, '0')}:`;\n let content = Array.from(v.match(/.{4}/g) ?? []).join(' ');\n let chars = Array.from(new Uint8Array(ArrayBuffers.fromHex(v).buffer)).map((v) => {\n let c = String.fromCharCode(v);\n if (v < 32 || v > 126) {\n c = '.';\n }\n return c;\n });\n return [idxPrefix, content.padEnd(40, ' '), chars.join('')].join(' ');\n })\n .join('\\n');\n}\n\n/**\n * Chrome Websocket Binary format\n * ```\n * 00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................\n * ```\n */\nexport function fromHexDump(dump: string) {\n return ArrayBuffers.fromHex(\n dump\n .split('\\n')\n .map((v) => {\n return v.substring(10, 10 + 41).replaceAll(' ', '');\n })\n .join(''),\n );\n}\n"],"names":["ArrayBuffers","toHexDump","data","Array","from","toHex","match","map","v","i","idxPrefix","toString","padStart","content","join","chars","Uint8Array","fromHex","buffer","c","String","fromCharCode","padEnd","fromHexDump","dump","split","substring","replaceAll"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,YAAY,QAAQ,iBAAiB;AAE9C,OAAO,SAASC,UAAUC,IAAkB;IAC1C,OAAOC,MAAMC,IAAI,CAACJ,aAAaK,KAAK,CAACH,MAAMI,KAAK,CAAC,eAAe,EAAE,EAC/DC,GAAG,CAAC,CAACC,GAAGC;QACP,IAAIC,YAAY,CAAC,EAAED,EAAEE,QAAQ,CAAC,IAAIC,QAAQ,CAAC,GAAG,KAAK,CAAC,CAAC;QACrD,IAAIC,UAAUV,MAAMC,IAAI,CAACI,EAAEF,KAAK,CAAC,YAAY,EAAE,EAAEQ,IAAI,CAAC;QACtD,IAAIC,QAAQZ,MAAMC,IAAI,CAAC,IAAIY,WAAWhB,aAAaiB,OAAO,CAACT,GAAGU,MAAM,GAAGX,GAAG,CAAC,CAACC;YAC1E,IAAIW,IAAIC,OAAOC,YAAY,CAACb;YAC5B,IAAIA,IAAI,MAAMA,IAAI,KAAK;gBACrBW,IAAI;YACN;YACA,OAAOA;QACT;QACA,OAAO;YAACT;YAAWG,QAAQS,MAAM,CAAC,IAAI;YAAMP,MAAMD,IAAI,CAAC;SAAI,CAACA,IAAI,CAAC;IACnE,GACCA,IAAI,CAAC;AACV;AAEA;;;;;CAKC,GACD,OAAO,SAASS,YAAYC,IAAY;IACtC,OAAOxB,aAAaiB,OAAO,CACzBO,KACGC,KAAK,CAAC,MACNlB,GAAG,CAAC,CAACC;QACJ,OAAOA,EAAEkB,SAAS,CAAC,IAAI,KAAK,IAAIC,UAAU,CAAC,KAAK;IAClD,GACCb,IAAI,CAAC;AAEZ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wener/utils",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.46",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Utils for daily use",
|
|
6
6
|
"repository": {
|
|
@@ -78,15 +78,15 @@
|
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@sinclair/typebox": "^0.32.
|
|
82
|
-
"@types/lodash": "^4.17.
|
|
81
|
+
"@sinclair/typebox": "^0.32.29",
|
|
82
|
+
"@types/lodash": "^4.17.1",
|
|
83
83
|
"@types/ws": "^8.5.10",
|
|
84
84
|
"@wener/utils": "link:",
|
|
85
85
|
"https-proxy-agent": "^7.0.4",
|
|
86
86
|
"lodash": "^4.17.21",
|
|
87
87
|
"node-fetch": "^3.3.2",
|
|
88
|
-
"undici": "^6.
|
|
89
|
-
"zod": "^3.23.
|
|
88
|
+
"undici": "^6.16.0",
|
|
89
|
+
"zod": "^3.23.8"
|
|
90
90
|
},
|
|
91
91
|
"publishConfig": {
|
|
92
92
|
"registry": "https://registry.npmjs.org",
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see https://gist.github.com/tonyc726/00c829a54a40cf80409f
|
|
3
|
+
* @see https://github.com/Siykt/javascript-algorithms/blob/master/src/algorithms/string/getChinesePrice.ts 人民币金额转中文大写
|
|
4
|
+
*/
|
|
5
|
+
export function formatChineseAmount(price: number) {
|
|
6
|
+
if (price === 0) return '零元整';
|
|
7
|
+
if (price >= 1e12) return '整数位已超过最大值';
|
|
8
|
+
|
|
9
|
+
const CHINESE_NUMBER_MAP = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
|
|
10
|
+
const CHINESE_UNIT_MAP = ['', '拾', '佰', '仟'];
|
|
11
|
+
const CHINESE_BIG_UNIT_MAP = ['', '万', '亿'];
|
|
12
|
+
const CHINESE_SMALL_UNIT_MAP = ['角', '分', '厘', '毫'];
|
|
13
|
+
|
|
14
|
+
const priceStr = price.toString();
|
|
15
|
+
const priceArr = priceStr.split('.');
|
|
16
|
+
const integer = priceArr[0];
|
|
17
|
+
const decimal = priceArr[1];
|
|
18
|
+
|
|
19
|
+
let chineseIntegerPrice = '';
|
|
20
|
+
let zeroCount = 0;
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < integer.length; i++) {
|
|
23
|
+
const num = +integer[i];
|
|
24
|
+
const unit = integer.length - i - 1; // 当前数字的单位
|
|
25
|
+
const quotient = Math.floor(unit / 4); // 1w为进位单位, 除 4 即为 万 亿
|
|
26
|
+
const remainder = unit % 4; // 1w为进位单位, 取模 4 即为 个 十 百 千
|
|
27
|
+
|
|
28
|
+
if (num === 0) {
|
|
29
|
+
zeroCount++;
|
|
30
|
+
} else {
|
|
31
|
+
// 处理前置的零
|
|
32
|
+
if (zeroCount > 0) chineseIntegerPrice += CHINESE_NUMBER_MAP[0];
|
|
33
|
+
zeroCount = 0;
|
|
34
|
+
chineseIntegerPrice += CHINESE_NUMBER_MAP[num] + CHINESE_UNIT_MAP[remainder];
|
|
35
|
+
}
|
|
36
|
+
if (remainder === 0 && zeroCount < 4) {
|
|
37
|
+
chineseIntegerPrice += CHINESE_BIG_UNIT_MAP[quotient];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 价格为小数时,整数部分不显示
|
|
42
|
+
if (price < 1) chineseIntegerPrice = '';
|
|
43
|
+
else chineseIntegerPrice += '元';
|
|
44
|
+
|
|
45
|
+
let chineseDecimalPrice = '';
|
|
46
|
+
|
|
47
|
+
if (!decimal) {
|
|
48
|
+
chineseDecimalPrice = '整';
|
|
49
|
+
} else {
|
|
50
|
+
let hasZero = false;
|
|
51
|
+
for (let i = 0; i < decimal.length; i++) {
|
|
52
|
+
const num = +decimal[i];
|
|
53
|
+
if (num) chineseDecimalPrice += CHINESE_NUMBER_MAP[num] + CHINESE_SMALL_UNIT_MAP[i];
|
|
54
|
+
else hasZero = true;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (chineseIntegerPrice && hasZero) chineseIntegerPrice += '零';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return chineseIntegerPrice + chineseDecimalPrice;
|
|
61
|
+
}
|
package/src/cn/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { expect, test } from 'vitest';
|
|
2
|
+
import { formatChineseAmount } from './formatChineseAmount';
|
|
2
3
|
import { parseChineseNumber } from './parseChineseNumber';
|
|
3
4
|
|
|
4
5
|
test('parseChineseNumber', () => {
|
|
@@ -18,7 +19,141 @@ test('parseChineseNumber', () => {
|
|
|
18
19
|
['捌玖', 89],
|
|
19
20
|
['捌玖零', 890],
|
|
20
21
|
['零捌玖', 89],
|
|
22
|
+
['肆仟叁佰陆拾', 4360],
|
|
23
|
+
// ['陆仟捌佰捌拾捌元肆角贰分', 89],
|
|
21
24
|
] as const) {
|
|
22
25
|
expect(parseChineseNumber(a)).toBe(b);
|
|
26
|
+
console.log(
|
|
27
|
+
a,
|
|
28
|
+
b,
|
|
29
|
+
formatChineseNumber(b),
|
|
30
|
+
formatChineseAmount0(b) === formatChineseAmount(b),
|
|
31
|
+
formatChineseAmount0(b),
|
|
32
|
+
formatChineseAmount(b),
|
|
33
|
+
);
|
|
23
34
|
}
|
|
24
35
|
});
|
|
36
|
+
|
|
37
|
+
function formatChineseNumber(v: number): string {
|
|
38
|
+
if (v < 0) {
|
|
39
|
+
return '负' + formatChineseNumber(-v);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 数字对应的中文表示
|
|
43
|
+
const digits = ['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
|
|
44
|
+
const units = ['', '十', '百', '千'];
|
|
45
|
+
const bigUnits = ['', '万', '亿', '兆'];
|
|
46
|
+
|
|
47
|
+
if (v < 10) {
|
|
48
|
+
return digits[v];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 将数字分割成千位分隔的数组
|
|
52
|
+
let parts = [];
|
|
53
|
+
while (v > 0) {
|
|
54
|
+
parts.push(v % 10000);
|
|
55
|
+
v = Math.floor(v / 10000);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// 从最高位开始处理每个部分
|
|
59
|
+
let result = parts
|
|
60
|
+
.map((part, idx) => {
|
|
61
|
+
let str = '';
|
|
62
|
+
let zeroFlag = false; // 标记是否需要添加零
|
|
63
|
+
|
|
64
|
+
for (let i = 0; part > 0; i++) {
|
|
65
|
+
let currentDigit = part % 10;
|
|
66
|
+
if (currentDigit !== 0) {
|
|
67
|
+
str = digits[currentDigit] + (i > 0 ? units[i] : '') + str;
|
|
68
|
+
zeroFlag = true; // 若当前位不为零,则后面可能需要加零
|
|
69
|
+
} else if (zeroFlag) {
|
|
70
|
+
str = digits[0] + str; // 加零操作
|
|
71
|
+
zeroFlag = false; // 重置零标志
|
|
72
|
+
}
|
|
73
|
+
part = Math.floor(part / 10);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 返回处理后的字符串,加上相应的大单位
|
|
77
|
+
return str + bigUnits[idx];
|
|
78
|
+
})
|
|
79
|
+
.reverse()
|
|
80
|
+
.join('')
|
|
81
|
+
.replace(/〇+/g, '〇')
|
|
82
|
+
.replace(/〇([万亿兆])/g, '$1');
|
|
83
|
+
|
|
84
|
+
// 处理连续〇的情况以及〇位于大单位前的情况
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function formatChineseAmount0(amount: number): string {
|
|
89
|
+
// 检查金额是否合理
|
|
90
|
+
if (amount < 0) {
|
|
91
|
+
return '(负)' + formatChineseAmount0(-amount);
|
|
92
|
+
}
|
|
93
|
+
// 大写数字和单位
|
|
94
|
+
const digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
|
|
95
|
+
const basicUnits = ['', '拾', '佰', '仟'];
|
|
96
|
+
const bigUnits = ['元', '万', '亿'];
|
|
97
|
+
|
|
98
|
+
// 转换为整数处理
|
|
99
|
+
let integerAmount = Math.round(amount * 100); // 转为分为单位
|
|
100
|
+
|
|
101
|
+
if (integerAmount === 0) {
|
|
102
|
+
return '零元整';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let result = '';
|
|
106
|
+
|
|
107
|
+
// 处理小数部分(分、角)
|
|
108
|
+
const cents = integerAmount % 100;
|
|
109
|
+
const jiao = Math.floor(cents / 10);
|
|
110
|
+
const fen = cents % 10;
|
|
111
|
+
integerAmount = Math.floor(integerAmount / 100); // 转为元为单位
|
|
112
|
+
|
|
113
|
+
if (fen > 0) {
|
|
114
|
+
result = digits[fen] + '分' + result;
|
|
115
|
+
}
|
|
116
|
+
if (jiao > 0) {
|
|
117
|
+
result = digits[jiao] + '角' + result;
|
|
118
|
+
}
|
|
119
|
+
if (cents === 0) {
|
|
120
|
+
result += '整';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 处理整数部分
|
|
124
|
+
let unitIndex = 0;
|
|
125
|
+
let zeroCount = 0;
|
|
126
|
+
let needZero = false;
|
|
127
|
+
|
|
128
|
+
while (integerAmount > 0) {
|
|
129
|
+
let segment = integerAmount % 10000;
|
|
130
|
+
let segmentString = '';
|
|
131
|
+
|
|
132
|
+
for (let i = 0; i < 4 && segment > 0; i++) {
|
|
133
|
+
let digit = segment % 10;
|
|
134
|
+
if (digit === 0) {
|
|
135
|
+
zeroCount++;
|
|
136
|
+
} else {
|
|
137
|
+
if (zeroCount > 0 || needZero) {
|
|
138
|
+
segmentString = digits[0] + segmentString;
|
|
139
|
+
zeroCount = 0;
|
|
140
|
+
needZero = false;
|
|
141
|
+
}
|
|
142
|
+
segmentString = digits[digit] + basicUnits[i] + segmentString;
|
|
143
|
+
}
|
|
144
|
+
segment = Math.floor(segment / 10);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (segment > 0 || unitIndex === 0 || segmentString !== '') {
|
|
148
|
+
result = segmentString + bigUnits[unitIndex] + result;
|
|
149
|
+
needZero = true;
|
|
150
|
+
}
|
|
151
|
+
integerAmount = Math.floor(integerAmount / 10000);
|
|
152
|
+
unitIndex++;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 去除多余的零,调整单位和数位
|
|
156
|
+
result = result.replace(/零+/g, '零').replace(/零元/, '元').replace(/零万/, '万');
|
|
157
|
+
|
|
158
|
+
return result;
|
|
159
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -75,6 +75,7 @@ export { isBuffer } from './io/isBuffer';
|
|
|
75
75
|
export { isTransferable } from './io/isTransferable';
|
|
76
76
|
export { ArrayBuffers } from './io/ArrayBuffers';
|
|
77
77
|
export { ByteBuffer } from './io/ByteBuffer';
|
|
78
|
+
export { fromHexDump, toHexDump } from './io/dump';
|
|
78
79
|
export { Buffer } from './io/Buffer';
|
|
79
80
|
export { parseDataUri, type ParsedDataUri } from './io/parseDataUri';
|
|
80
81
|
export type { AbstractEncoding } from './io/AbstractEncoding';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { assert, test } from 'vitest';
|
|
2
|
+
import { ByteBuffer } from './ByteBuffer';
|
|
3
|
+
|
|
4
|
+
test('ByteBuffer', async () => {
|
|
5
|
+
let buf = new ByteBuffer();
|
|
6
|
+
buf.writeString('Hello');
|
|
7
|
+
buf.writeString('World');
|
|
8
|
+
assert.equal(buf.length, 10);
|
|
9
|
+
assert.equal(buf.position, 10);
|
|
10
|
+
buf.length = 5;
|
|
11
|
+
assert.equal(buf.length, 5);
|
|
12
|
+
buf.position = 0;
|
|
13
|
+
assert.equal(buf.readString(5), 'Hello');
|
|
14
|
+
});
|
package/src/io/ByteBuffer.ts
CHANGED
|
@@ -33,8 +33,9 @@ function asBuffer(o: AnyBuffer) {
|
|
|
33
33
|
// }
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
* @see https://www.egret.uk/docs/egretengine/engine/egret.ByteArray
|
|
37
|
-
* @see https://
|
|
36
|
+
* @see {@link https://www.egret.uk/docs/egretengine/engine/egret.ByteArray egret.ByteArray}
|
|
37
|
+
* @see {@link https://github.com/protobufjs/bytebuffer.js protobufjs/bytebuffer.js}
|
|
38
|
+
* @see {@link https://netty.io/4.1/api/io/netty/buffer/ByteBuf.html ByteBuf}
|
|
38
39
|
*/
|
|
39
40
|
export class ByteBuffer {
|
|
40
41
|
position = 0;
|
|
@@ -44,7 +45,7 @@ export class ByteBuffer {
|
|
|
44
45
|
|
|
45
46
|
constructor(buffer: AnyBuffer = new ArrayBuffer(0, { maxByteLength: 1024 })) {
|
|
46
47
|
this.#buffer = asBuffer(buffer);
|
|
47
|
-
//
|
|
48
|
+
// NOTE prefer view over buffer, avoid the slice overhead ?
|
|
48
49
|
this.#view = new DataView(this.#buffer);
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -69,7 +70,7 @@ export class ByteBuffer {
|
|
|
69
70
|
this.resize(length);
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
private
|
|
73
|
+
private willWrite(length: number) {
|
|
73
74
|
if (this.remaining() < length) {
|
|
74
75
|
this.resize(this.length + length);
|
|
75
76
|
}
|
|
@@ -88,72 +89,73 @@ export class ByteBuffer {
|
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
writeByte(value: number) {
|
|
91
|
-
this.
|
|
92
|
+
this.willWrite(1);
|
|
92
93
|
this.view.setUint8(this.position++, value);
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
writeBytes(bytes: ArrayBufferLike) {
|
|
96
|
-
this.
|
|
96
|
+
writeBytes(bytes: ArrayBufferLike, len: number = bytes.byteLength) {
|
|
97
|
+
this.willWrite(len);
|
|
98
|
+
if (len !== bytes.byteLength) bytes = bytes.slice(0, len);
|
|
97
99
|
new Uint8Array(this.buffer).set(new Uint8Array(bytes), this.position);
|
|
98
100
|
this.position += bytes.byteLength;
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
writeInt8(value: number) {
|
|
102
|
-
this.
|
|
104
|
+
this.willWrite(1);
|
|
103
105
|
this.view.setInt8(this.position, value);
|
|
104
106
|
this.position += 1;
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
writeUint8(value: number) {
|
|
108
|
-
this.
|
|
110
|
+
this.willWrite(1);
|
|
109
111
|
this.view.setUint8(this.position, value);
|
|
110
112
|
this.position += 1;
|
|
111
113
|
}
|
|
112
114
|
|
|
113
115
|
writeInt16(value: number) {
|
|
114
|
-
this.
|
|
116
|
+
this.willWrite(2);
|
|
115
117
|
this.view.setInt16(this.position, value);
|
|
116
118
|
this.position += 2;
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
writeUint16(value: number) {
|
|
120
|
-
this.
|
|
122
|
+
this.willWrite(2);
|
|
121
123
|
this.view.setUint16(this.position, value);
|
|
122
124
|
this.position += 2;
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
writeInt32(value: number) {
|
|
126
|
-
this.
|
|
128
|
+
this.willWrite(4);
|
|
127
129
|
this.view.setInt32(this.position, value);
|
|
128
130
|
this.position += 4;
|
|
129
131
|
}
|
|
130
132
|
|
|
131
133
|
writeUint32(value: number) {
|
|
132
|
-
this.
|
|
134
|
+
this.willWrite(4);
|
|
133
135
|
this.view.setUint32(this.position, value);
|
|
134
136
|
this.position += 4;
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
writeInt64(value: bigint) {
|
|
138
|
-
this.
|
|
140
|
+
this.willWrite(8);
|
|
139
141
|
this.view.setBigInt64(this.position, value);
|
|
140
142
|
this.position += 8;
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
writeUint64(value: bigint) {
|
|
144
|
-
this.
|
|
146
|
+
this.willWrite(8);
|
|
145
147
|
this.view.setBigUint64(this.position, value);
|
|
146
148
|
this.position += 8;
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
writeFloat32(value: number) {
|
|
150
|
-
this.
|
|
152
|
+
this.willWrite(4);
|
|
151
153
|
this.view.setFloat32(this.position, value);
|
|
152
154
|
this.position += 4;
|
|
153
155
|
}
|
|
154
156
|
|
|
155
157
|
writeFloat64(value: number) {
|
|
156
|
-
this.
|
|
158
|
+
this.willWrite(8);
|
|
157
159
|
this.view.setFloat64(this.position, value);
|
|
158
160
|
this.position += 8;
|
|
159
161
|
}
|
|
@@ -167,7 +169,7 @@ export class ByteBuffer {
|
|
|
167
169
|
writeString(value: string, len?: number) {
|
|
168
170
|
let encoder = new TextEncoder();
|
|
169
171
|
let bytes = encoder.encode(value);
|
|
170
|
-
this.writeBytes(
|
|
172
|
+
this.writeBytes(bytes, len);
|
|
171
173
|
}
|
|
172
174
|
|
|
173
175
|
readByte() {
|
|
@@ -341,6 +343,10 @@ export class ByteBuffer {
|
|
|
341
343
|
toHex() {
|
|
342
344
|
return ArrayBuffers.toHex(this.buffer);
|
|
343
345
|
}
|
|
346
|
+
|
|
347
|
+
toBase64() {
|
|
348
|
+
return ArrayBuffers.toBase64(this.buffer);
|
|
349
|
+
}
|
|
344
350
|
}
|
|
345
351
|
|
|
346
352
|
export interface TypedValue {
|
|
@@ -361,40 +367,6 @@ export interface TypedValue {
|
|
|
361
367
|
length?: number;
|
|
362
368
|
}
|
|
363
369
|
|
|
364
|
-
export function toDump(data: BufferSource) {
|
|
365
|
-
return Array.from(ArrayBuffers.toHex(data).match(/.{1,32}/g) ?? [])
|
|
366
|
-
.map((v, i) => {
|
|
367
|
-
let idxPrefix = `${i.toString(16).padStart(8, '0')}:`;
|
|
368
|
-
let content = Array.from(v.match(/.{4}/g) ?? []).join(' ');
|
|
369
|
-
let chars = Array.from(new Uint8Array(ArrayBuffers.fromHex(v).buffer)).map((v) => {
|
|
370
|
-
let c = String.fromCharCode(v);
|
|
371
|
-
if (v < 32 || v > 126) {
|
|
372
|
-
c = '.';
|
|
373
|
-
}
|
|
374
|
-
return c;
|
|
375
|
-
});
|
|
376
|
-
return [idxPrefix, content.padEnd(40, ' '), chars.join('')].join(' ');
|
|
377
|
-
})
|
|
378
|
-
.join('\n');
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Chrome Websocket Binary format
|
|
383
|
-
* ```
|
|
384
|
-
* 00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
|
385
|
-
* ```
|
|
386
|
-
*/
|
|
387
|
-
export function fromDump(dump: string) {
|
|
388
|
-
return ArrayBuffers.fromHex(
|
|
389
|
-
dump
|
|
390
|
-
.split('\n')
|
|
391
|
-
.map((v) => {
|
|
392
|
-
return v.substring(10, 10 + 41).replaceAll(' ', '');
|
|
393
|
-
})
|
|
394
|
-
.join(''),
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
370
|
function safeNumber(n: bigint) {
|
|
399
371
|
if (n > Number.MAX_SAFE_INTEGER) {
|
|
400
372
|
return n;
|
package/src/io/dump.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ArrayBuffers } from './ArrayBuffers';
|
|
2
|
+
|
|
3
|
+
export function toHexDump(data: BufferSource) {
|
|
4
|
+
return Array.from(ArrayBuffers.toHex(data).match(/.{1,32}/g) ?? [])
|
|
5
|
+
.map((v, i) => {
|
|
6
|
+
let idxPrefix = `${i.toString(16).padStart(8, '0')}:`;
|
|
7
|
+
let content = Array.from(v.match(/.{4}/g) ?? []).join(' ');
|
|
8
|
+
let chars = Array.from(new Uint8Array(ArrayBuffers.fromHex(v).buffer)).map((v) => {
|
|
9
|
+
let c = String.fromCharCode(v);
|
|
10
|
+
if (v < 32 || v > 126) {
|
|
11
|
+
c = '.';
|
|
12
|
+
}
|
|
13
|
+
return c;
|
|
14
|
+
});
|
|
15
|
+
return [idxPrefix, content.padEnd(40, ' '), chars.join('')].join(' ');
|
|
16
|
+
})
|
|
17
|
+
.join('\n');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Chrome Websocket Binary format
|
|
22
|
+
* ```
|
|
23
|
+
* 00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function fromHexDump(dump: string) {
|
|
27
|
+
return ArrayBuffers.fromHex(
|
|
28
|
+
dump
|
|
29
|
+
.split('\n')
|
|
30
|
+
.map((v) => {
|
|
31
|
+
return v.substring(10, 10 + 41).replaceAll(' ', '');
|
|
32
|
+
})
|
|
33
|
+
.join(''),
|
|
34
|
+
);
|
|
35
|
+
}
|