nv-buf-cmp 1.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.
Files changed (3) hide show
  1. package/TEST/check.js +76 -0
  2. package/index.js +124 -0
  3. package/package.json +15 -0
package/TEST/check.js ADDED
@@ -0,0 +1,76 @@
1
+ const cmp = require("../index");
2
+
3
+ // Node 18+ 有 Blob
4
+ const { Blob } = global;
5
+
6
+ const log = async (name, fn) => {
7
+ try {
8
+ const r = await fn();
9
+ console.log(name, "=>", r);
10
+ } catch (e) {
11
+ console.error(name, "ERROR:", e);
12
+ }
13
+ };
14
+
15
+ (async () => {
16
+
17
+ // ===== 1. Uint8Array vs Uint8Array =====
18
+ await log("u8a == u8a (true)", async () => {
19
+ const a = new Uint8Array([1,2,3]);
20
+ const b = new Uint8Array([1,2,3]);
21
+ return await cmp(a,b);
22
+ });
23
+
24
+ await log("u8a == u8a (false)", async () => {
25
+ const a = new Uint8Array([1,2,3]);
26
+ const b = new Uint8Array([1,2,4]);
27
+ return await cmp(a,b);
28
+ });
29
+
30
+ // ===== 2. Buffer vs Uint8Array =====
31
+ await log("buffer == u8a", async () => {
32
+ const a = Buffer.from([1,2,3]);
33
+ const b = new Uint8Array([1,2,3]);
34
+ return await cmp(a,b);
35
+ });
36
+
37
+ // ===== 3. Blob vs Blob(走 stream)=====
38
+ await log("blob == blob (true)", async () => {
39
+ const a = new Blob([Buffer.from("hello world")]);
40
+ const b = new Blob([Buffer.from("hello world")]);
41
+ return await cmp(a,b);
42
+ });
43
+
44
+ await log("blob == blob (false)", async () => {
45
+ const a = new Blob([Buffer.from("hello world")]);
46
+ const b = new Blob([Buffer.from("hello worle")]);
47
+ return await cmp(a,b);
48
+ });
49
+
50
+ // ===== 4. u8a vs blob(混合路径)=====
51
+ await log("u8a == blob", async () => {
52
+ const a = new Uint8Array([1,2,3,4]);
53
+ const b = new Blob([Buffer.from([1,2,3,4])]);
54
+ return await cmp(a,b);
55
+ });
56
+
57
+ // ===== 5. 大数据(测试 stream 对齐)=====
58
+ await log("big blob stream eq", async () => {
59
+ const big1 = Buffer.alloc(1024 * 1024 * 5, 7); // 5MB
60
+ const big2 = Buffer.alloc(1024 * 1024 * 5, 7);
61
+
62
+ const a = new Blob([big1]);
63
+ const b = new Blob([big2]);
64
+
65
+ return await cmp(a,b);
66
+ });
67
+
68
+ // ===== 6. meta 测试 =====
69
+ await log("blob type mismatch", async () => {
70
+ const a = new Blob([Buffer.from("abc")], { type: "text/plain" });
71
+ const b = new Blob([Buffer.from("abc")], { type: "application/json" });
72
+
73
+ return await cmp(a,b, { type: true });
74
+ });
75
+
76
+ })();
package/index.js ADDED
@@ -0,0 +1,124 @@
1
+ const size = require("nv-buf-size");
2
+ const eq = require("nv-buf-eq").buf_eq_buf;
3
+ //eq(u8a,u8a)->boolean
4
+
5
+ // ===== 转 Uint8Array =====
6
+ const to_u8a_or_stream = (o) => {
7
+ const nm = o.constructor.name;
8
+ if (nm === "Uint8Array") {
9
+ return o;
10
+ } else if (ArrayBuffer.isView(o)) {
11
+ return new Uint8Array(o.buffer, o.byteOffset, o.byteLength);
12
+ } else if (nm === "ArrayBuffer" || nm === "SharedArrayBuffer") {
13
+ return new Uint8Array(o);
14
+ } else if (nm === "Buffer") { // Node.js
15
+ return new Uint8Array(o.buffer, o.byteOffset, o.byteLength);
16
+ } else {
17
+ return o.stream(); //我要比较的非常大 直接读arrayBuffer会奔溃
18
+ }
19
+ };
20
+
21
+ // ===== meta 比较 =====
22
+ const cmp_meta = (o0, o1, cfg) => {
23
+ if (cfg.type) {
24
+ if ((o0?.type || "") !== (o1?.type || "")) return false;
25
+ }
26
+ if (cfg.name) {
27
+ if ((o0?.name || "") !== (o1?.name || "")) return false;
28
+ }
29
+ if (cfg.lastModified) {
30
+ if ((o0?.lastModified || 0) !== (o1?.lastModified || 0)) return false;
31
+ }
32
+ return true;
33
+ };
34
+
35
+ const stream_eq = async (s0, s1) => {
36
+ const r0 = s0.getReader();
37
+ const r1 = s1.getReader();
38
+
39
+ let b0 = new Uint8Array(0);
40
+ let b1 = new Uint8Array(0);
41
+
42
+ let done0 = false;
43
+ let done1 = false;
44
+
45
+ while (true) {
46
+ // ===== 补数据 =====
47
+ if (!done0 && b0.length === 0) {
48
+ const r = await r0.read();
49
+ done0 = r.done;
50
+ if (!done0) b0 = r.value;
51
+ }
52
+
53
+ if (!done1 && b1.length === 0) {
54
+ const r = await r1.read();
55
+ done1 = r.done;
56
+ if (!done1) b1 = r.value;
57
+ }
58
+
59
+ // ===== 都结束 =====
60
+ if (done0 && done1 && b0.length === 0 && b1.length === 0) {
61
+ return true;
62
+ }
63
+
64
+ // ===== 一个结束一个没结束 =====
65
+ if ((done0 && b0.length === 0) !== (done1 && b1.length === 0)) {
66
+ return false;
67
+ }
68
+
69
+ // ===== 对齐最小长度 =====
70
+ const minLen = Math.min(b0.length, b1.length);
71
+
72
+ for (let i = 0; i < minLen; i++) {
73
+ if (b0[i] !== b1[i]) return false;
74
+ }
75
+
76
+ // ===== 切掉已比较部分 =====
77
+ b0 = b0.subarray(minLen);
78
+ b1 = b1.subarray(minLen);
79
+ }
80
+ };
81
+
82
+ const is_stream = (x) => x && typeof x.getReader === "function";
83
+
84
+ // 把 Uint8Array 转成 stream(关键补全)
85
+ const u8a_to_stream = (u8a) => {
86
+ return new ReadableStream({
87
+ start(controller) {
88
+ controller.enqueue(u8a);
89
+ controller.close();
90
+ }
91
+ });
92
+ };
93
+
94
+ module.exports = async (o0,o1,cfg={type:true,name:false,lastModified:false})=>{
95
+ var ncfg = Object.assign({type:true,name:false,lastModified:false},cfg);
96
+ //o: TypedArray | ArrayBuffer| SharedArrayBuffer | File |Blob
97
+ var sz0 = size(o0);
98
+ var sz1 = size(o1);
99
+ if(sz0 === sz1) {
100
+ if(cmp_meta(o0,o1,cfg)) {
101
+ var u8a_or_s0 = to_u8a_or_stream(o0);
102
+ var u8a_or_s1 = to_u8a_or_stream(o1);
103
+ if(u8a_or_s0.getReader === undefined && u8a_or_s1.getReader === undefined){
104
+ return eq(o0,o1); //这个eq我已经写好
105
+ } else if(u8a_or_s0.getReader === undefined && u8a_or_s1.getReader !== undefined){
106
+ u8a_or_s0 = await u8a_to_stream(u8a_or_s0);
107
+ return await stream_eq(u8a_or_s0,u8a_or_s1);
108
+ } else if(u8a_or_s0.getReader !== undefined && u8a_or_s1.getReader === undefined){
109
+ u8a_or_s1 = await u8a_to_stream(u8a_or_s1);
110
+ return await stream_eq(u8a_or_s0,u8a_or_s1);
111
+ } else {
112
+ return await stream_eq(u8a_or_s0,u8a_or_s1);
113
+ }
114
+ } else {
115
+ return false;
116
+ }
117
+ } else {
118
+ return false;
119
+ }
120
+ }
121
+
122
+ module.exports.u8a_to_stream = u8a_to_stream;
123
+ module.exports.stream_eq = stream_eq;
124
+
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "nv-buf-cmp",
3
+ "version": "1.0.1",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1"
7
+ },
8
+ "author": "",
9
+ "license": "ISC",
10
+ "description": "",
11
+ "dependencies": {
12
+ "nv-buf-eq": "^1.0.8",
13
+ "nv-buf-size": "^1.0.0"
14
+ }
15
+ }