quickwin 3.0.0 → 3.0.2
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.en.md +3 -0
- package/README.md +2 -0
- package/lib/abort.d.ts +21 -0
- package/lib/assert.d.ts +2 -0
- package/lib/bitmap.d.ts +7 -0
- package/lib/cache-utils.d.ts +6 -0
- package/lib/certs.d.ts +1 -0
- package/lib/dpi.d.ts +9 -0
- package/lib/dumpRects.d.ts +2 -0
- package/lib/exec-log.d.ts +23 -0
- package/lib/fetch.d.ts +4 -0
- package/lib/ffi/bind.d.ts +70 -0
- package/lib/ffi/ctype.d.ts +117 -0
- package/lib/ffi/index.d.ts +2 -0
- package/lib/ffi/struct.d.ts +174 -0
- package/lib/http-common.d.ts +143 -0
- package/lib/http-server.d.ts +59 -0
- package/lib/polyfill.d.ts +22 -0
- package/lib/react-qw/components/Button.d.ts +9 -0
- package/lib/react-qw/components/CheckBox.d.ts +11 -0
- package/lib/react-qw/components/ComboBox.d.ts +11 -0
- package/lib/react-qw/components/DateTimePicker.d.ts +15 -0
- package/lib/react-qw/components/Input.d.ts +15 -0
- package/lib/react-qw/components/Link.d.ts +12 -0
- package/lib/react-qw/components/ListBox.d.ts +13 -0
- package/lib/react-qw/components/ListView.d.ts +37 -0
- package/lib/react-qw/components/PathPicker.d.ts +23 -0
- package/lib/react-qw/components/ProgressBar.d.ts +9 -0
- package/lib/react-qw/components/RadioButton.d.ts +11 -0
- package/lib/react-qw/components/ScrollView.d.ts +9 -0
- package/lib/react-qw/components/Slider.d.ts +12 -0
- package/lib/react-qw/components/Tab.d.ts +14 -0
- package/lib/react-qw/components/Tooltip.d.ts +7 -0
- package/lib/react-qw/components/TreeView.d.ts +18 -0
- package/lib/react-qw/components/index.d.ts +16 -0
- package/lib/react-qw/index.d.ts +24 -0
- package/lib/react-qw/layout.d.ts +29 -0
- package/lib/react-qw/nmhdr.d.ts +1 -0
- package/lib/react-qw/props.d.ts +2 -0
- package/lib/react-qw/reconciler.d.ts +21 -0
- package/lib/stream.d.ts +20 -0
- package/lib/text-codec.d.ts +39 -0
- package/lib/text-measure.d.ts +14 -0
- package/lib/url.d.ts +54 -0
- package/lib/websocket.d.ts +73 -0
- package/lib/windows/{advapi32.ts → advapi32.d.ts} +6 -21
- package/lib/windows/comctl32.d.ts +14 -0
- package/lib/windows/comdlg32.d.ts +4 -0
- package/lib/windows/{gdi32.ts → gdi32.d.ts} +161 -98
- package/lib/windows/{kernel32.ts → kernel32.d.ts} +138 -115
- package/lib/windows/{msimg32.ts → msimg32.d.ts} +11 -14
- package/lib/windows/ntdll.d.ts +5 -0
- package/lib/windows/ole32.d.ts +3 -0
- package/lib/windows/{psapi.ts → psapi.d.ts} +9 -18
- package/lib/windows/{shell32.ts → shell32.d.ts} +25 -24
- package/lib/windows/structs.d.ts +3141 -0
- package/lib/windows/{user32.ts → user32.d.ts} +196 -193
- package/lib/windows/version.d.ts +27 -0
- package/lib/windows/{winspool.ts → winspool.d.ts} +18 -32
- package/package.json +15 -8
- package/qwin-nowasm-x86.exe +0 -0
- package/qwin-nowasm.exe +0 -0
- package/qwin-x86.exe +0 -0
- package/qwin.exe +0 -0
- package/examples/PdfCanvas.js +0 -38
- package/examples/PdfCanvas.tsx +0 -54
- package/examples/execd/main.js +0 -23379
- package/examples/execd/tray.js +0 -192
- package/examples/execd/worker.js +0 -122
- package/examples/pdf_preview2.js +0 -398
- package/examples/pdf_preview2.ts +0 -353
- package/examples/pdf_viewer.js +0 -22515
- package/examples/pdf_viewer.tsx +0 -228
- package/examples/test_gallery.js +0 -18692
- package/examples/test_gallery.tsx +0 -291
- package/examples/test_react_lazy.js +0 -18560
- package/examples/test_react_lazy.tsx +0 -65
- package/examples/test_react_listbox.js +0 -18562
- package/examples/test_react_listbox.tsx +0 -73
- package/examples/test_root_window.js +0 -18532
- package/examples/test_root_window.tsx +0 -41
- package/examples/test_tab.js +0 -18563
- package/examples/test_tab.tsx +0 -77
- package/examples/tray_demo.js +0 -86
- package/examples/tray_demo.tsx +0 -89
- package/lib/abort.ts +0 -69
- package/lib/assert.ts +0 -7
- package/lib/bitmap.ts +0 -39
- package/lib/cache-utils.ts +0 -40
- package/lib/certs.ts +0 -258
- package/lib/dpi.ts +0 -31
- package/lib/dumpRects.ts +0 -34
- package/lib/exec-log.ts +0 -30
- package/lib/fetch.ts +0 -589
- package/lib/ffi/bind.ts +0 -540
- package/lib/ffi/ctype.ts +0 -371
- package/lib/ffi/index.ts +0 -6
- package/lib/ffi/struct.ts +0 -780
- package/lib/http-common.ts +0 -441
- package/lib/http-server.ts +0 -604
- package/lib/polyfill.ts +0 -171
- package/lib/react-qw/components/index.ts +0 -17
- package/lib/react-qw/index.ts +0 -96
- package/lib/react-qw/layout.ts +0 -111
- package/lib/react-qw/nmhdr.ts +0 -7
- package/lib/react-qw/props.ts +0 -41
- package/lib/react-qw/reconciler.ts +0 -379
- package/lib/stream.ts +0 -22
- package/lib/text-codec.ts +0 -171
- package/lib/text-measure.ts +0 -44
- package/lib/url.ts +0 -201
- package/lib/websocket.ts +0 -600
- package/lib/windows/comctl32.ts +0 -20
- package/lib/windows/comdlg32.ts +0 -10
- package/lib/windows/ntdll.ts +0 -11
- package/lib/windows/ole32.ts +0 -9
- package/lib/windows/structs.ts +0 -807
- package/lib/windows/version.ts +0 -35
- package/test/add.wasm +0 -0
- package/test/bench_ffi_callraw.js +0 -235
- package/test/bench_ffi_callraw.ts +0 -235
- package/test/bench_ffi_overhead.js +0 -139
- package/test/bench_ffi_overhead.ts +0 -141
- package/test/bench_sendmessage.js +0 -104
- package/test/bench_sendmessage.ts +0 -100
- package/test/bench_sendmessage_nonnull.js +0 -187
- package/test/bench_sendmessage_nonnull.ts +0 -188
- package/test/complex.wasm +0 -0
- package/test/complex_imports.wasm +0 -0
- package/test/debug/http_server_e2e.js +0 -31
- package/test/debug/minwasm.js +0 -52
- package/test/debug/mupdf_debug.js +0 -86
- package/test/debug/wasm.js +0 -122
- package/test/debug/wasm_export_debug.js +0 -54
- package/test/debug/wasm_names.js +0 -36
- package/test/example.pdf +0 -0
- package/test/global_imports.wasm +0 -0
- package/test/import_func.wasm +0 -0
- package/test/imports.wasm +0 -0
- package/test/mupdf-cdn.js +0 -40
- package/test/mupdf-cdn.ts +0 -43
- package/test/run.js +0 -111
- package/test/run.ts +0 -116
- package/test/sjlj.wasm +0 -0
- package/test/test_basic.js +0 -7
- package/test/test_basic.ts +0 -9
- package/test/test_basic_fetch.js +0 -63
- package/test/test_basic_fetch.ts +0 -59
- package/test/test_brotli.js +0 -48
- package/test/test_brotli.ts +0 -52
- package/test/test_fetch_cache.js +0 -169
- package/test/test_fetch_cache.ts +0 -187
- package/test/test_ffi.js +0 -157
- package/test/test_ffi.ts +0 -170
- package/test/test_ffi_abi.js +0 -290
- package/test/test_ffi_abi.ts +0 -274
- package/test/test_ffi_array.js +0 -116
- package/test/test_ffi_array.ts +0 -141
- package/test/test_ffi_bind.js +0 -656
- package/test/test_ffi_bind.ts +0 -670
- package/test/test_ffi_struct.js +0 -779
- package/test/test_ffi_struct.ts +0 -828
- package/test/test_ffi_struct_layout.js +0 -495
- package/test/test_ffi_struct_layout.ts +0 -543
- package/test/test_ffi_user32.js +0 -103
- package/test/test_ffi_user32.ts +0 -113
- package/test/test_ffi_windows.js +0 -172
- package/test/test_ffi_windows.ts +0 -187
- package/test/test_files.js +0 -102
- package/test/test_files.ts +0 -121
- package/test/test_frame_encoding.js +0 -128
- package/test/test_frame_encoding.ts +0 -132
- package/test/test_gdi_draw.js +0 -681
- package/test/test_gdi_draw.ts +0 -725
- package/test/test_helper.js +0 -91
- package/test/test_helper.ts +0 -88
- package/test/test_http_import.js +0 -96
- package/test/test_http_import.ts +0 -93
- package/test/test_http_server.js +0 -214
- package/test/test_http_server.ts +0 -211
- package/test/test_import_dir.js +0 -4
- package/test/test_import_dir.ts +0 -5
- package/test/test_ipv6.js +0 -134
- package/test/test_ipv6.ts +0 -130
- package/test/test_jsx.js +0 -1314
- package/test/test_meta_url.js +0 -3
- package/test/test_meta_url.ts +0 -4
- package/test/test_mupdf_render.js +0 -51
- package/test/test_mupdf_render.ts +0 -55
- package/test/test_mupdf_twice.js +0 -62
- package/test/test_mupdf_twice.ts +0 -65
- package/test/test_mupdf_wasm.js +0 -39
- package/test/test_mupdf_wasm.ts +0 -32
- package/test/test_net_event.js +0 -57
- package/test/test_net_event.ts +0 -56
- package/test/test_net_fetch.js +0 -384
- package/test/test_net_fetch.ts +0 -373
- package/test/test_net_websocket.js +0 -180
- package/test/test_net_websocket.ts +0 -164
- package/test/test_polyfill.js +0 -144
- package/test/test_polyfill.ts +0 -159
- package/test/test_printer.js +0 -137
- package/test/test_printer.ts +0 -148
- package/test/test_proc.js +0 -141
- package/test/test_proc.ts +0 -163
- package/test/test_react_complex.js +0 -18678
- package/test/test_react_counter.js +0 -18555
- package/test/test_react_flex.js +0 -18871
- package/test/test_react_hidden.js +0 -18560
- package/test/test_react_listview_link.js +0 -18590
- package/test/test_react_notify.js +0 -18797
- package/test/test_react_render.js +0 -18550
- package/test/test_registry.js +0 -74
- package/test/test_registry.ts +0 -95
- package/test/test_sysinfo.js +0 -122
- package/test/test_sysinfo.ts +0 -141
- package/test/test_url.js +0 -173
- package/test/test_url.ts +0 -183
- package/test/test_wasm_basic.js +0 -85
- package/test/test_wasm_basic.ts +0 -73
- package/test/test_wasm_import_global.js +0 -41
- package/test/test_wasm_import_global.ts +0 -45
- package/test/test_wasm_sjlj.js +0 -145
- package/test/test_wasm_sjlj.ts +0 -125
- package/test/test_wasm_types.js +0 -97
- package/test/test_wasm_types.ts +0 -124
- package/test/test_wolfssl_read.js +0 -203
- package/test/test_wolfssl_read.ts +0 -184
- package/test/test_worker.js +0 -21
- package/test/test_worker.ts +0 -24
- package/test/test_worker_concurrent.js +0 -45
- package/test/test_worker_concurrent.ts +0 -56
- package/test/test_worker_data_url.js +0 -46
- package/test/test_worker_data_url.ts +0 -51
- package/test/test_worker_fetch.js +0 -26
- package/test/test_worker_fetch.ts +0 -27
- package/test/test_worker_net.js +0 -69
- package/test/test_worker_net.ts +0 -66
- package/test/test_worker_wasm_concurrent.js +0 -44
- package/test/test_worker_wasm_concurrent.ts +0 -45
- package/test/types.wasm +0 -0
- package/test/worker_fetch.js +0 -13
- package/test/worker_fetch.ts +0 -13
- package/test/worker_helper.js +0 -1
- package/test/worker_helper.ts +0 -1
- package/test/worker_http.js +0 -18
- package/test/worker_http.ts +0 -20
- package/test/worker_import_lib.js +0 -12
- package/test/worker_import_lib.ts +0 -13
- package/test/worker_module.js +0 -16
- package/test/worker_module.ts +0 -17
- package/test/worker_wasm_concurrent.js +0 -22
- package/test/worker_wasm_concurrent.ts +0 -22
package/test/test_files.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import { WCHAR } from '../lib/ffi/bind.js'
|
|
2
|
-
import { NULL, PtrArrayBuffer } from '../lib/ffi/ctype.js'
|
|
3
|
-
import {
|
|
4
|
-
CloseHandle, CopyFile, CreateDirectory, CreateFile, DeleteFile,
|
|
5
|
-
FindClose, FindFirstFile, FindNextFile, GetFileAttributes, GetFileSize,
|
|
6
|
-
GetTempPath, MoveFileEx, ReadFile, RemoveDirectory, SetFilePointer, WriteFile,
|
|
7
|
-
} from '../lib/windows/kernel32.js'
|
|
8
|
-
import { WIN32_FIND_DATAW } from '../lib/windows/structs.js'
|
|
9
|
-
import { Tester } from './test_helper.js'
|
|
10
|
-
import { FileCreation, FileSeekFrom } from '../constants'
|
|
11
|
-
|
|
12
|
-
const GENERIC_READ = 0x80000000
|
|
13
|
-
const GENERIC_WRITE = 0x40000000
|
|
14
|
-
const FILE_ATTRIBUTE_DIRECTORY = 0x10
|
|
15
|
-
const INVALID32 = 0xffffffff
|
|
16
|
-
|
|
17
|
-
// ASCII payload ↔ UTF-16LE 缓冲互转(REG_SZ 同型,测试内联)
|
|
18
|
-
function toWide(s: string): PtrArrayBuffer<string> {
|
|
19
|
-
const p = new PtrArrayBuffer(s.length * 2)
|
|
20
|
-
const dv = new DataView(p)
|
|
21
|
-
for (let i = 0; i < s.length; i++) dv.setUint16(i * 2, s.charCodeAt(i), true)
|
|
22
|
-
return p
|
|
23
|
-
}
|
|
24
|
-
function fromWide(p: PtrArrayBuffer<string>, chars: number): string {
|
|
25
|
-
const dv = new DataView(p)
|
|
26
|
-
let out = ''
|
|
27
|
-
for (let i = 0; i < chars; i++) out += String.fromCharCode(dv.getUint16(i * 2, true))
|
|
28
|
-
return out
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const suite = {
|
|
32
|
-
name: 'files',
|
|
33
|
-
run: (t: Tester) => {
|
|
34
|
-
t.section('GetTempPath + CreateDirectory')
|
|
35
|
-
const tmpW = WCHAR.alloc(260)
|
|
36
|
-
const tmpLen = GetTempPath(260, tmpW)
|
|
37
|
-
t.checkTrue(`temp path non-empty (${tmpLen})`, tmpLen > 0)
|
|
38
|
-
const dir = `${WCHAR.decode(tmpW)}QuickWinTest` // GetTempPath 尾带反斜杠
|
|
39
|
-
// 目录可能残留自上次中断的 run:已存在(且是目录)则静默复用
|
|
40
|
-
if (CreateDirectory(dir, NULL) === 0 &&
|
|
41
|
-
(GetFileAttributes(dir) & FILE_ATTRIBUTE_DIRECTORY) === 0) {
|
|
42
|
-
t.checkTrue('CreateDirectory', false)
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
const pathA = `${dir}\\a.txt`
|
|
46
|
-
const pathB = `${dir}\\b.txt`
|
|
47
|
-
const pathC = `${dir}\\c.txt`
|
|
48
|
-
const pathCn = `${dir}\\中文文件.txt`
|
|
49
|
-
|
|
50
|
-
t.section('CreateFile + WriteFile: write payload')
|
|
51
|
-
const hW = CreateFile(pathA, GENERIC_WRITE, 0, NULL,
|
|
52
|
-
FileCreation.CREATE_ALWAYS, 0x80 /* FILE_ATTRIBUTE_NORMAL */, NULL)
|
|
53
|
-
t.checkTrue(`write handle valid (${hW})`, hW !== -1) // 失败 = INVALID_HANDLE_VALUE(-1)
|
|
54
|
-
const payload = 'hello files'
|
|
55
|
-
const wData = toWide(payload)
|
|
56
|
-
const pWr = new PtrArrayBuffer(4)
|
|
57
|
-
t.checkTrue('WriteFile ok', WriteFile(hW, wData, payload.length * 2, pWr, NULL) !== 0)
|
|
58
|
-
t.check('bytes written', payload.length * 2, new DataView(pWr).getUint32(0, true))
|
|
59
|
-
t.checkTrue('CloseHandle (writer)', CloseHandle(hW) !== 0)
|
|
60
|
-
|
|
61
|
-
t.section('CreateFile(READ) + GetFileSize + SetFilePointer + ReadFile')
|
|
62
|
-
const hR = CreateFile(pathA, GENERIC_READ, 0, NULL,
|
|
63
|
-
FileCreation.OPEN_EXISTING, 0x80, NULL)
|
|
64
|
-
t.checkTrue(`read handle valid (${hR})`, hR !== -1)
|
|
65
|
-
t.check('GetFileSize', payload.length * 2, GetFileSize(hR, NULL))
|
|
66
|
-
t.check('SetFilePointer BEGIN → 0', 0, SetFilePointer(hR, 0, NULL, FileSeekFrom.BEGIN))
|
|
67
|
-
const rData = new PtrArrayBuffer(payload.length * 2)
|
|
68
|
-
const pRd = new PtrArrayBuffer(4)
|
|
69
|
-
t.checkTrue('ReadFile ok', ReadFile(hR, rData, payload.length * 2, pRd, NULL) !== 0)
|
|
70
|
-
t.check('read roundtrip', payload, fromWide(rData, payload.length))
|
|
71
|
-
// seek 到 END-4 验证负偏移 + 读尾 4 字节
|
|
72
|
-
t.check('SetFilePointer END-4', payload.length * 2 - 4,
|
|
73
|
-
SetFilePointer(hR, -4, NULL, FileSeekFrom.END))
|
|
74
|
-
const rTail = new PtrArrayBuffer(8)
|
|
75
|
-
ReadFile(hR, rTail, 4, pRd, NULL)
|
|
76
|
-
t.check('seeked tail', payload.slice(-2), fromWide(rTail, 2))
|
|
77
|
-
CloseHandle(hR)
|
|
78
|
-
|
|
79
|
-
t.section('CopyFile + MoveFileEx + GetFileAttributes')
|
|
80
|
-
const hB = CreateFile(pathB, GENERIC_WRITE, 0, NULL,
|
|
81
|
-
FileCreation.CREATE_ALWAYS, 0x80, NULL)
|
|
82
|
-
const bData = toWide('bb')
|
|
83
|
-
WriteFile(hB, bData, 4, pWr, NULL)
|
|
84
|
-
CloseHandle(hB)
|
|
85
|
-
t.checkTrue('CopyFile ok', CopyFile(pathB, pathC, 0) !== 0)
|
|
86
|
-
const hC = CreateFile(pathC, GENERIC_READ, 0, NULL,
|
|
87
|
-
FileCreation.OPEN_EXISTING, 0x80, NULL)
|
|
88
|
-
t.check('copied size', 4, GetFileSize(hC, NULL))
|
|
89
|
-
t.checkTrue('CloseHandle (copy reader)', CloseHandle(hC) !== 0)
|
|
90
|
-
t.checkTrue('MoveFileEx replace ok',
|
|
91
|
-
MoveFileEx(pathB, pathC, 0x1 /* MOVEFILE_REPLACE_EXISTING */) !== 0)
|
|
92
|
-
t.check('moved: source gone', INVALID32, GetFileAttributes(pathB))
|
|
93
|
-
t.checkTrue('dest is file (not dir)',
|
|
94
|
-
(GetFileAttributes(pathC) & FILE_ATTRIBUTE_DIRECTORY) === 0)
|
|
95
|
-
|
|
96
|
-
t.section('FindFirstFile/FindNextFile: enumerate *.txt incl. CJK name')
|
|
97
|
-
const hCn = CreateFile(pathCn, GENERIC_WRITE, 0, NULL,
|
|
98
|
-
FileCreation.CREATE_ALWAYS, 0x80, NULL)
|
|
99
|
-
CloseHandle(hCn) // 0 字节中文名文件
|
|
100
|
-
const fd = WIN32_FIND_DATAW.alloc()
|
|
101
|
-
const hFind = FindFirstFile(`${dir}\\a.txt`, fd.ptr)
|
|
102
|
-
t.checkTrue(`FindFirstFile ok (${hFind})`, hFind !== -1)
|
|
103
|
-
t.check('found name', 'a.txt', WIN32_FIND_DATAW.decode(fd).cFileName)
|
|
104
|
-
t.checkTrue('FindNextFile exhausted = 0', FindNextFile(hFind, fd.ptr) === 0)
|
|
105
|
-
t.checkTrue('FindClose', FindClose(hFind) !== 0)
|
|
106
|
-
let count = 0
|
|
107
|
-
const hEnum = FindFirstFile(`${dir}\\*.txt`, fd.ptr)
|
|
108
|
-
if (hEnum !== -1) {
|
|
109
|
-
count = 1
|
|
110
|
-
while (FindNextFile(hEnum, fd.ptr) !== 0) count++
|
|
111
|
-
FindClose(hEnum)
|
|
112
|
-
}
|
|
113
|
-
t.check('enum *.txt count (a/c/CJK)', 3, count)
|
|
114
|
-
|
|
115
|
-
t.section('DeleteFile + RemoveDirectory: cleanup')
|
|
116
|
-
t.checkTrue('DeleteFile ×3', DeleteFile(pathA) !== 0 && DeleteFile(pathC) !== 0
|
|
117
|
-
&& DeleteFile(pathCn) !== 0)
|
|
118
|
-
t.checkTrue('RemoveDirectory', RemoveDirectory(dir) !== 0)
|
|
119
|
-
t.check('dir gone', INVALID32, GetFileAttributes(dir))
|
|
120
|
-
},
|
|
121
|
-
}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import * as std from 'std';
|
|
2
|
-
export const suite = {
|
|
3
|
-
name: 'wasm-frame-encoding',
|
|
4
|
-
run: (t) => {
|
|
5
|
-
function createFrameHeader(payloadLen) {
|
|
6
|
-
let headerSize = payloadLen < 126 ? 6 : (payloadLen < 65536 ? 8 : 14);
|
|
7
|
-
let buf = new ArrayBuffer(headerSize);
|
|
8
|
-
let view = new Uint8Array(buf);
|
|
9
|
-
let off = 0;
|
|
10
|
-
view[off++] = 0x81;
|
|
11
|
-
if (payloadLen < 126) {
|
|
12
|
-
view[off++] = 0x80 | payloadLen;
|
|
13
|
-
}
|
|
14
|
-
else if (payloadLen < 65536) {
|
|
15
|
-
view[off++] = 0x80 | 126;
|
|
16
|
-
view[off++] = (payloadLen >> 8) & 0xFF;
|
|
17
|
-
view[off++] = payloadLen & 0xFF;
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
view[off++] = 0x80 | 127;
|
|
21
|
-
const len = payloadLen;
|
|
22
|
-
const hi = Math.floor(len / 0x100000000) >>> 0;
|
|
23
|
-
const lo = len >>> 0;
|
|
24
|
-
view[off++] = (hi >> 24) & 0xFF;
|
|
25
|
-
view[off++] = (hi >> 16) & 0xFF;
|
|
26
|
-
view[off++] = (hi >> 8) & 0xFF;
|
|
27
|
-
view[off++] = hi & 0xFF;
|
|
28
|
-
view[off++] = (lo >> 24) & 0xFF;
|
|
29
|
-
view[off++] = (lo >> 16) & 0xFF;
|
|
30
|
-
view[off++] = (lo >> 8) & 0xFF;
|
|
31
|
-
view[off++] = lo & 0xFF;
|
|
32
|
-
}
|
|
33
|
-
return view;
|
|
34
|
-
}
|
|
35
|
-
function tryParseFrameLen(data) {
|
|
36
|
-
if (data.length < 2)
|
|
37
|
-
return null;
|
|
38
|
-
const b1 = data[1];
|
|
39
|
-
let payloadLen = b1 & 0x7F;
|
|
40
|
-
let offset = 2;
|
|
41
|
-
if (payloadLen === 126) {
|
|
42
|
-
if (data.length < 4)
|
|
43
|
-
return null;
|
|
44
|
-
payloadLen = (data[2] << 8) | data[3];
|
|
45
|
-
}
|
|
46
|
-
else if (payloadLen === 127) {
|
|
47
|
-
if (data.length < 10)
|
|
48
|
-
return null;
|
|
49
|
-
let hi = 0, lo = 0;
|
|
50
|
-
for (let i = 0; i < 4; i++)
|
|
51
|
-
hi = (hi * 256 + data[offset + i]) >>> 0;
|
|
52
|
-
for (let i = 4; i < 8; i++)
|
|
53
|
-
lo = (lo * 256 + data[offset + i]) >>> 0;
|
|
54
|
-
payloadLen = hi * 0x100000000 + lo;
|
|
55
|
-
}
|
|
56
|
-
return payloadLen;
|
|
57
|
-
}
|
|
58
|
-
function assert(name, ok) {
|
|
59
|
-
if (ok) {
|
|
60
|
-
t.ok++;
|
|
61
|
-
std.printf(' PASS: %s\n', name);
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
t.fail++;
|
|
65
|
-
std.printf(' FAIL: %s\n', name);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
// small frame (100 bytes)
|
|
69
|
-
t.section('inline length (<126)');
|
|
70
|
-
let h = createFrameHeader(100);
|
|
71
|
-
assert('length=100', h[1] === (0x80 | 100));
|
|
72
|
-
assert('parse 100', tryParseFrameLen(h) === 100);
|
|
73
|
-
// 1 (edge case)
|
|
74
|
-
h = createFrameHeader(1);
|
|
75
|
-
assert('length=1', h[1] === (0x80 | 1));
|
|
76
|
-
assert('parse 1', tryParseFrameLen(h) === 1);
|
|
77
|
-
// 125 (max inline)
|
|
78
|
-
h = createFrameHeader(125);
|
|
79
|
-
assert('length=125', h[1] === (0x80 | 125));
|
|
80
|
-
assert('parse 125', tryParseFrameLen(h) === 125);
|
|
81
|
-
// 126 (enters 16-bit extended)
|
|
82
|
-
t.section('16-bit extended length (126–65535)');
|
|
83
|
-
h = createFrameHeader(126);
|
|
84
|
-
assert('126 marker', h[1] === (0x80 | 126));
|
|
85
|
-
assert('126 value', h[2] === 0 && h[3] === 126);
|
|
86
|
-
assert('parse 126', tryParseFrameLen(h) === 126);
|
|
87
|
-
// 65535 (max 16-bit)
|
|
88
|
-
h = createFrameHeader(65535);
|
|
89
|
-
assert('65535 marker', h[1] === (0x80 | 126));
|
|
90
|
-
assert('65535 hi byte', h[2] === 0xFF);
|
|
91
|
-
assert('65535 lo byte', h[3] === 0xFF);
|
|
92
|
-
assert('parse 65535', tryParseFrameLen(h) === 65535);
|
|
93
|
-
// 65536 (enters 64-bit extended)
|
|
94
|
-
t.section('64-bit extended length (>=65536)');
|
|
95
|
-
h = createFrameHeader(65536);
|
|
96
|
-
assert('65536 marker', h[1] === (0x80 | 127));
|
|
97
|
-
assert('parse 65536', tryParseFrameLen(h) === 65536);
|
|
98
|
-
// 66000
|
|
99
|
-
h = createFrameHeader(66000);
|
|
100
|
-
assert('66000 marker', h[1] === (0x80 | 127));
|
|
101
|
-
assert('parse 66000', tryParseFrameLen(h) === 66000);
|
|
102
|
-
// 70000 — verify exact bytes
|
|
103
|
-
h = createFrameHeader(70000);
|
|
104
|
-
assert('70000 marker', h[1] === (0x80 | 127));
|
|
105
|
-
// 70000 = 0x11170, big-endian 8 bytes: 00 00 00 00 00 01 11 70
|
|
106
|
-
assert('70000 bytes big-endian', h[2] === 0x00 && h[3] === 0x00 && h[4] === 0x00 && h[5] === 0x00 &&
|
|
107
|
-
h[6] === 0x00 && h[7] === 0x01 && h[8] === 0x11 && h[9] === 0x70);
|
|
108
|
-
assert('parse 70000', tryParseFrameLen(h) === 70000);
|
|
109
|
-
// Large value near 2^32 boundary
|
|
110
|
-
t.section('large values');
|
|
111
|
-
h = createFrameHeader(0xABCD1234);
|
|
112
|
-
assert('0xABCD1234 marker', h[1] === (0x80 | 127));
|
|
113
|
-
assert('parse 0xABCD1234', tryParseFrameLen(h) === 0xABCD1234);
|
|
114
|
-
assert('MSB non-zero', h[2] === 0x00 && h[3] === 0x00 && h[4] === 0x00 && h[5] === 0x00 &&
|
|
115
|
-
h[6] === 0xAB && h[7] === 0xCD && h[8] === 0x12 && h[9] === 0x34);
|
|
116
|
-
// 0x100000001 (just above 2^32)
|
|
117
|
-
h = createFrameHeader(0x100000001);
|
|
118
|
-
assert('2^32+1 parse', tryParseFrameLen(h) === 0x100000001);
|
|
119
|
-
assert('2^32+1 bytes', h[2] === 0x00 && h[3] === 0x00 && h[4] === 0x00 && h[5] === 0x01 &&
|
|
120
|
-
h[6] === 0x00 && h[7] === 0x00 && h[8] === 0x00 && h[9] === 0x01);
|
|
121
|
-
// Full 8-byte roundtrip: 0x0123456789ABCDEF
|
|
122
|
-
// This exceeds Number's safe integer range (2^53) slightly,
|
|
123
|
-
// but our test value 0x0123456789ABCDEF = 81985529216486895 < 2^53 ✓
|
|
124
|
-
const bigVal = 0x0123456789ABCDEF;
|
|
125
|
-
h = createFrameHeader(bigVal);
|
|
126
|
-
assert('big val parse', tryParseFrameLen(h) === bigVal);
|
|
127
|
-
}
|
|
128
|
-
};
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import * as std from 'std'
|
|
2
|
-
import { Tester } from './test_helper.js'
|
|
3
|
-
|
|
4
|
-
export const suite = {
|
|
5
|
-
name: 'wasm-frame-encoding',
|
|
6
|
-
run: (t: Tester) => {
|
|
7
|
-
function createFrameHeader(payloadLen: number): Uint8Array {
|
|
8
|
-
let headerSize = payloadLen < 126 ? 6 : (payloadLen < 65536 ? 8 : 14)
|
|
9
|
-
let buf = new ArrayBuffer(headerSize)
|
|
10
|
-
let view = new Uint8Array(buf)
|
|
11
|
-
let off = 0
|
|
12
|
-
view[off++] = 0x81
|
|
13
|
-
if (payloadLen < 126) {
|
|
14
|
-
view[off++] = 0x80 | payloadLen
|
|
15
|
-
} else if (payloadLen < 65536) {
|
|
16
|
-
view[off++] = 0x80 | 126
|
|
17
|
-
view[off++] = (payloadLen >> 8) & 0xFF
|
|
18
|
-
view[off++] = payloadLen & 0xFF
|
|
19
|
-
} else {
|
|
20
|
-
view[off++] = 0x80 | 127
|
|
21
|
-
const len = payloadLen
|
|
22
|
-
const hi = Math.floor(len / 0x100000000) >>> 0
|
|
23
|
-
const lo = len >>> 0
|
|
24
|
-
view[off++] = (hi >> 24) & 0xFF
|
|
25
|
-
view[off++] = (hi >> 16) & 0xFF
|
|
26
|
-
view[off++] = (hi >> 8) & 0xFF
|
|
27
|
-
view[off++] = hi & 0xFF
|
|
28
|
-
view[off++] = (lo >> 24) & 0xFF
|
|
29
|
-
view[off++] = (lo >> 16) & 0xFF
|
|
30
|
-
view[off++] = (lo >> 8) & 0xFF
|
|
31
|
-
view[off++] = lo & 0xFF
|
|
32
|
-
}
|
|
33
|
-
return view
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function tryParseFrameLen(data: Uint8Array): number | null {
|
|
37
|
-
if (data.length < 2) return null
|
|
38
|
-
const b1 = data[1]!
|
|
39
|
-
let payloadLen = b1 & 0x7F
|
|
40
|
-
let offset = 2
|
|
41
|
-
if (payloadLen === 126) {
|
|
42
|
-
if (data.length < 4) return null
|
|
43
|
-
payloadLen = (data[2]! << 8) | data[3]!
|
|
44
|
-
} else if (payloadLen === 127) {
|
|
45
|
-
if (data.length < 10) return null
|
|
46
|
-
let hi = 0, lo = 0
|
|
47
|
-
for (let i = 0; i < 4; i++) hi = (hi * 256 + data[offset + i]!) >>> 0
|
|
48
|
-
for (let i = 4; i < 8; i++) lo = (lo * 256 + data[offset + i]!) >>> 0
|
|
49
|
-
payloadLen = hi * 0x100000000 + lo
|
|
50
|
-
}
|
|
51
|
-
return payloadLen
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function assert(name: string, ok: boolean): void {
|
|
55
|
-
if (ok) { t.ok++; std.printf(' PASS: %s\n', name) }
|
|
56
|
-
else { t.fail++; std.printf(' FAIL: %s\n', name) }
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// small frame (100 bytes)
|
|
60
|
-
t.section('inline length (<126)')
|
|
61
|
-
let h = createFrameHeader(100)
|
|
62
|
-
assert('length=100', h[1] === (0x80 | 100))
|
|
63
|
-
assert('parse 100', tryParseFrameLen(h) === 100)
|
|
64
|
-
|
|
65
|
-
// 1 (edge case)
|
|
66
|
-
h = createFrameHeader(1)
|
|
67
|
-
assert('length=1', h[1] === (0x80 | 1))
|
|
68
|
-
assert('parse 1', tryParseFrameLen(h) === 1)
|
|
69
|
-
|
|
70
|
-
// 125 (max inline)
|
|
71
|
-
h = createFrameHeader(125)
|
|
72
|
-
assert('length=125', h[1] === (0x80 | 125))
|
|
73
|
-
assert('parse 125', tryParseFrameLen(h) === 125)
|
|
74
|
-
|
|
75
|
-
// 126 (enters 16-bit extended)
|
|
76
|
-
t.section('16-bit extended length (126–65535)')
|
|
77
|
-
h = createFrameHeader(126)
|
|
78
|
-
assert('126 marker', h[1] === (0x80 | 126))
|
|
79
|
-
assert('126 value', h[2] === 0 && h[3] === 126)
|
|
80
|
-
assert('parse 126', tryParseFrameLen(h) === 126)
|
|
81
|
-
|
|
82
|
-
// 65535 (max 16-bit)
|
|
83
|
-
h = createFrameHeader(65535)
|
|
84
|
-
assert('65535 marker', h[1] === (0x80 | 126))
|
|
85
|
-
assert('65535 hi byte', h[2] === 0xFF)
|
|
86
|
-
assert('65535 lo byte', h[3] === 0xFF)
|
|
87
|
-
assert('parse 65535', tryParseFrameLen(h) === 65535)
|
|
88
|
-
|
|
89
|
-
// 65536 (enters 64-bit extended)
|
|
90
|
-
t.section('64-bit extended length (>=65536)')
|
|
91
|
-
h = createFrameHeader(65536)
|
|
92
|
-
assert('65536 marker', h[1] === (0x80 | 127))
|
|
93
|
-
assert('parse 65536', tryParseFrameLen(h) === 65536)
|
|
94
|
-
|
|
95
|
-
// 66000
|
|
96
|
-
h = createFrameHeader(66000)
|
|
97
|
-
assert('66000 marker', h[1] === (0x80 | 127))
|
|
98
|
-
assert('parse 66000', tryParseFrameLen(h) === 66000)
|
|
99
|
-
|
|
100
|
-
// 70000 — verify exact bytes
|
|
101
|
-
h = createFrameHeader(70000)
|
|
102
|
-
assert('70000 marker', h[1] === (0x80 | 127))
|
|
103
|
-
// 70000 = 0x11170, big-endian 8 bytes: 00 00 00 00 00 01 11 70
|
|
104
|
-
assert('70000 bytes big-endian',
|
|
105
|
-
h[2] === 0x00 && h[3] === 0x00 && h[4] === 0x00 && h[5] === 0x00 &&
|
|
106
|
-
h[6] === 0x00 && h[7] === 0x01 && h[8] === 0x11 && h[9] === 0x70)
|
|
107
|
-
assert('parse 70000', tryParseFrameLen(h) === 70000)
|
|
108
|
-
|
|
109
|
-
// Large value near 2^32 boundary
|
|
110
|
-
t.section('large values')
|
|
111
|
-
h = createFrameHeader(0xABCD1234)
|
|
112
|
-
assert('0xABCD1234 marker', h[1] === (0x80 | 127))
|
|
113
|
-
assert('parse 0xABCD1234', tryParseFrameLen(h) === 0xABCD1234)
|
|
114
|
-
assert('MSB non-zero',
|
|
115
|
-
h[2] === 0x00 && h[3] === 0x00 && h[4] === 0x00 && h[5] === 0x00 &&
|
|
116
|
-
h[6] === 0xAB && h[7] === 0xCD && h[8] === 0x12 && h[9] === 0x34)
|
|
117
|
-
|
|
118
|
-
// 0x100000001 (just above 2^32)
|
|
119
|
-
h = createFrameHeader(0x100000001)
|
|
120
|
-
assert('2^32+1 parse', tryParseFrameLen(h) === 0x100000001)
|
|
121
|
-
assert('2^32+1 bytes',
|
|
122
|
-
h[2] === 0x00 && h[3] === 0x00 && h[4] === 0x00 && h[5] === 0x01 &&
|
|
123
|
-
h[6] === 0x00 && h[7] === 0x00 && h[8] === 0x00 && h[9] === 0x01)
|
|
124
|
-
|
|
125
|
-
// Full 8-byte roundtrip: 0x0123456789ABCDEF
|
|
126
|
-
// This exceeds Number's safe integer range (2^53) slightly,
|
|
127
|
-
// but our test value 0x0123456789ABCDEF = 81985529216486895 < 2^53 ✓
|
|
128
|
-
const bigVal = 0x0123456789ABCDEF
|
|
129
|
-
h = createFrameHeader(bigVal)
|
|
130
|
-
assert('big val parse', tryParseFrameLen(h) === bigVal)
|
|
131
|
-
}
|
|
132
|
-
}
|