feat(core): 在线版支持通过web serial烧录k210固件
This commit is contained in:
@@ -50,6 +50,33 @@
|
|||||||
"hid": false,
|
"hid": false,
|
||||||
"usb": false
|
"usb": false
|
||||||
},
|
},
|
||||||
|
"burn": {
|
||||||
|
"erase": true,
|
||||||
|
"MixGo AI": {
|
||||||
|
"binFile": [
|
||||||
|
{
|
||||||
|
"offset": "0x0000",
|
||||||
|
"path": "./build/MixGo_AI-ASR_V2.0.kfpkg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"MixGo AI sensor": {
|
||||||
|
"binFile": [
|
||||||
|
{
|
||||||
|
"offset": "0x0000",
|
||||||
|
"path": "./build/MixGo_AI-Sensor_V1.0.kfpkg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"MixGo AI sensor2": {
|
||||||
|
"binFile": [
|
||||||
|
{
|
||||||
|
"offset": "0x0000",
|
||||||
|
"path": "./build/MixGo_AI-Sensor_V1.2.kfpkg"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"upload": {
|
"upload": {
|
||||||
"reset": []
|
"reset": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,6 +255,18 @@
|
|||||||
"path": "modules/web-modules/dayjs/dayjs.min.js",
|
"path": "modules/web-modules/dayjs/dayjs.min.js",
|
||||||
"provide": ["dayjs"],
|
"provide": ["dayjs"],
|
||||||
"require": []
|
"require": []
|
||||||
|
}, {
|
||||||
|
"path": "modules/web-modules/crc.min.js",
|
||||||
|
"provide": ["crc"],
|
||||||
|
"require": []
|
||||||
|
}, {
|
||||||
|
"path": "modules/web-modules/pako.min.js",
|
||||||
|
"provide": ["pako"],
|
||||||
|
"require": []
|
||||||
|
}, {
|
||||||
|
"path": "modules/web-modules/struct.min.js",
|
||||||
|
"provide": ["struct"],
|
||||||
|
"require": []
|
||||||
}, {
|
}, {
|
||||||
"path": "modules/web-modules/dayjs/duration.min.js",
|
"path": "modules/web-modules/dayjs/duration.min.js",
|
||||||
"provide": ["dayjs.duration"],
|
"provide": ["dayjs.duration"],
|
||||||
|
|||||||
@@ -1587,6 +1587,7 @@
|
|||||||
"PartialFlashing",
|
"PartialFlashing",
|
||||||
"esptooljs",
|
"esptooljs",
|
||||||
"CryptoJS",
|
"CryptoJS",
|
||||||
|
"JSZip",
|
||||||
"Mixly.Env",
|
"Mixly.Env",
|
||||||
"Mixly.LayerExt",
|
"Mixly.LayerExt",
|
||||||
"Mixly.Config",
|
"Mixly.Config",
|
||||||
@@ -1601,6 +1602,7 @@
|
|||||||
"Mixly.LayerProgress",
|
"Mixly.LayerProgress",
|
||||||
"Mixly.Web.Serial",
|
"Mixly.Web.Serial",
|
||||||
"Mixly.Web.Ampy",
|
"Mixly.Web.Ampy",
|
||||||
|
"Mixly.Web.KFlash",
|
||||||
"Mixly.Web.SerialTransport"
|
"Mixly.Web.SerialTransport"
|
||||||
],
|
],
|
||||||
"provide": [
|
"provide": [
|
||||||
@@ -1668,6 +1670,20 @@
|
|||||||
"Mixly.Web.HID"
|
"Mixly.Web.HID"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "/web/kflash.js",
|
||||||
|
"require": [
|
||||||
|
"crc",
|
||||||
|
"pako",
|
||||||
|
"struct",
|
||||||
|
"Mixly.Debug",
|
||||||
|
"Mixly.Events",
|
||||||
|
"Mixly.Web"
|
||||||
|
],
|
||||||
|
"provide": [
|
||||||
|
"Mixly.Web.KFlash"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "/web/serial-transport.js",
|
"path": "/web/serial-transport.js",
|
||||||
"require": [
|
"require": [
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ goog.require('DAPWrapper');
|
|||||||
goog.require('PartialFlashing');
|
goog.require('PartialFlashing');
|
||||||
goog.require('esptooljs');
|
goog.require('esptooljs');
|
||||||
goog.require('CryptoJS');
|
goog.require('CryptoJS');
|
||||||
|
goog.require('JSZip');
|
||||||
goog.require('Mixly.Env');
|
goog.require('Mixly.Env');
|
||||||
goog.require('Mixly.LayerExt');
|
goog.require('Mixly.LayerExt');
|
||||||
goog.require('Mixly.Config');
|
goog.require('Mixly.Config');
|
||||||
@@ -21,6 +22,7 @@ goog.require('Mixly.LayerFirmware');
|
|||||||
goog.require('Mixly.LayerProgress');
|
goog.require('Mixly.LayerProgress');
|
||||||
goog.require('Mixly.Web.Serial');
|
goog.require('Mixly.Web.Serial');
|
||||||
goog.require('Mixly.Web.Ampy');
|
goog.require('Mixly.Web.Ampy');
|
||||||
|
goog.require('Mixly.Web.KFlash');
|
||||||
goog.require('Mixly.Web.SerialTransport');
|
goog.require('Mixly.Web.SerialTransport');
|
||||||
goog.provide('Mixly.Web.BU');
|
goog.provide('Mixly.Web.BU');
|
||||||
|
|
||||||
@@ -44,6 +46,7 @@ const {
|
|||||||
Serial,
|
Serial,
|
||||||
BU,
|
BU,
|
||||||
Ampy,
|
Ampy,
|
||||||
|
KFlash,
|
||||||
SerialTransport
|
SerialTransport
|
||||||
} = Web;
|
} = Web;
|
||||||
|
|
||||||
@@ -62,13 +65,8 @@ BU.firmwareLayer = new LayerFirmware({
|
|||||||
cancelDisplay: false
|
cancelDisplay: false
|
||||||
});
|
});
|
||||||
BU.firmwareLayer.bind('burn', (info) => {
|
BU.firmwareLayer.bind('burn', (info) => {
|
||||||
const boardKey = Boards.getSelectedBoardKey();
|
|
||||||
const { web } = SELECTED_BOARD;
|
const { web } = SELECTED_BOARD;
|
||||||
if (boardKey.indexOf('micropython:esp32s2') !== -1) {
|
BU.burnWithEsptool(info, web.burn.erase);
|
||||||
BU.burnWithAdafruitEsptool(info, web.burn.erase);
|
|
||||||
} else {
|
|
||||||
BU.burnWithEsptool(info, web.burn.erase);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
BU.progressLayer = new LayerProgress({
|
BU.progressLayer = new LayerProgress({
|
||||||
width: 200,
|
width: 200,
|
||||||
@@ -136,9 +134,46 @@ const readBinFileAsArrayBuffer = (path, offset) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const decodeKfpkgFromArrayBuffer = async(arrayBuf) => {
|
||||||
|
const zip = await JSZip.loadAsync(arrayBuf);
|
||||||
|
const manifestEntry = zip.file('flash-list.json');
|
||||||
|
if (!manifestEntry) {
|
||||||
|
throw new Error('kfpkg is missing flash-list.json');
|
||||||
|
}
|
||||||
|
const manifestText = await manifestEntry.async('string');
|
||||||
|
const manifest = JSON.parse(manifestText);
|
||||||
|
|
||||||
|
const items = [];
|
||||||
|
for (const f of manifest.files || []) {
|
||||||
|
const entry = zip.file(f.bin);
|
||||||
|
if (!entry) {
|
||||||
|
throw new Error(`Missing files in package: ${f.bin}`);
|
||||||
|
}
|
||||||
|
const data = new Uint8Array(await entry.async('uint8array'));
|
||||||
|
items.push({
|
||||||
|
address: f.address >>> 0,
|
||||||
|
filename: f.bin,
|
||||||
|
sha256Prefix: !!f.sha256Prefix,
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { manifest, items };
|
||||||
|
}
|
||||||
|
|
||||||
BU.initBurn = async () => {
|
BU.initBurn = async () => {
|
||||||
if (['BBC micro:bit', 'Mithon CC'].includes(BOARD.boardType)) {
|
if (['BBC micro:bit', 'Mithon CC'].includes(BOARD.boardType)) {
|
||||||
await BU.burnByUSB();
|
await BU.burnWithDAP();
|
||||||
|
} else if (['MixGo AI'].includes(BOARD.boardType)) {
|
||||||
|
const { web } = SELECTED_BOARD;
|
||||||
|
const boardKey = Boards.getSelectedBoardKey();
|
||||||
|
if (!web?.burn?.binFile) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof web.burn.binFile !== 'object') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await BU.burnWithKFlash(web.burn.binFile, web.burn.erase);
|
||||||
} else {
|
} else {
|
||||||
const { web } = SELECTED_BOARD;
|
const { web } = SELECTED_BOARD;
|
||||||
const boardKey = Boards.getSelectedBoardKey();
|
const boardKey = Boards.getSelectedBoardKey();
|
||||||
@@ -156,7 +191,7 @@ BU.initBurn = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BU.burnByUSB = async () => {
|
BU.burnWithDAP = async () => {
|
||||||
const { mainStatusBarTabs } = Mixly;
|
const { mainStatusBarTabs } = Mixly;
|
||||||
let portName = Serial.getSelectedPortName();
|
let portName = Serial.getSelectedPortName();
|
||||||
if (!portName) {
|
if (!portName) {
|
||||||
@@ -353,6 +388,88 @@ BU.burnWithEsptool = async (binFile, erase) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BU.burnWithKFlash = async (binFile, erase) => {
|
||||||
|
const { mainStatusBarTabs } = Mixly;
|
||||||
|
let portName = Serial.getSelectedPortName();
|
||||||
|
if (!portName) {
|
||||||
|
try {
|
||||||
|
await BU.requestPort();
|
||||||
|
portName = Serial.getSelectedPortName();
|
||||||
|
if (!portName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
Debug.error(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const port = Serial.getPort(portName);
|
||||||
|
if (['HIDDevice', 'USBDevice'].includes(port.constructor.name)) {
|
||||||
|
layer.msg(Msg.Lang['burn.notSupport'], { time: 1000 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const statusBarSerial = mainStatusBarTabs.getStatusBarById(portName);
|
||||||
|
if (statusBarSerial) {
|
||||||
|
await statusBarSerial.close();
|
||||||
|
}
|
||||||
|
const statusBarTerminal = mainStatusBarTabs.getStatusBarById('output');
|
||||||
|
statusBarTerminal.setValue(Msg.Lang['shell.burning'] + '...\n');
|
||||||
|
mainStatusBarTabs.show();
|
||||||
|
mainStatusBarTabs.changeTo('output');
|
||||||
|
BU.progressLayer.title(`${Msg.Lang['shell.burning']}...`);
|
||||||
|
BU.progressLayer.show();
|
||||||
|
statusBarTerminal.addValue(Msg.Lang['shell.bin.reading'] + "...");
|
||||||
|
statusBarTerminal.addValue("\n");
|
||||||
|
|
||||||
|
let data = [];
|
||||||
|
try {
|
||||||
|
for (let i of binFile) {
|
||||||
|
if (i.path && i.offset) {
|
||||||
|
const extname = path.extname(i.path);
|
||||||
|
const absolutePath = path.join(Env.boardDirPath, i.path);
|
||||||
|
const info = await readBinFileAsArrayBuffer(absolutePath, i.offset);
|
||||||
|
if (extname === '.kfpkg') {
|
||||||
|
const result = await decodeKfpkgFromArrayBuffer(info.data);
|
||||||
|
data.push(...result.items);
|
||||||
|
} else {
|
||||||
|
data.push(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
statusBarTerminal.addValue("Failed!\n" + Msg.Lang['shell.bin.readFailed'] + "!\n");
|
||||||
|
statusBarTerminal.addValue("\n" + error + "\n", true);
|
||||||
|
BU.progressLayer.hide();
|
||||||
|
statusBarTerminal.addValue(`==${Msg.Lang['shell.burnFailed']}==\n`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
statusBarTerminal.addValue("Done!\n");
|
||||||
|
let serial = null;
|
||||||
|
try {
|
||||||
|
serial = new Serial(portName);
|
||||||
|
const kflash = new KFlash(serial, (message) => {
|
||||||
|
statusBarTerminal.addValue(message);
|
||||||
|
});
|
||||||
|
await kflash.enter();
|
||||||
|
for (let item of data) {
|
||||||
|
await kflash.write(item.data, item.address, item.sha256Prefix ?? true, item?.filename ?? 'main.bin');
|
||||||
|
}
|
||||||
|
BU.progressLayer.hide();
|
||||||
|
layer.msg(Msg.Lang['shell.burnSucc'], { time: 1000 });
|
||||||
|
statusBarTerminal.addValue(`==${Msg.Lang['shell.burnSucc']}==\n`);
|
||||||
|
} catch (error) {
|
||||||
|
statusBarTerminal.addValue(`[ERROR] ${error.message}\n`);
|
||||||
|
BU.progressLayer.hide();
|
||||||
|
statusBarTerminal.addValue(`==${Msg.Lang['shell.burnFailed']}==\n`);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
serial && await serial.close();
|
||||||
|
} catch (error) {
|
||||||
|
Debug.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BU.getImportModulesName = (code) => {
|
BU.getImportModulesName = (code) => {
|
||||||
// 正则表达式: 匹配 import 或 from 导入语句
|
// 正则表达式: 匹配 import 或 from 导入语句
|
||||||
const importRegex = /(?:import\s+([a-zA-Z0-9_]+)|from\s+([a-zA-Z0-9_]+)\s+import)/g;
|
const importRegex = /(?:import\s+([a-zA-Z0-9_]+)|from\s+([a-zA-Z0-9_]+)\s+import)/g;
|
||||||
@@ -426,13 +543,13 @@ BU.initUpload = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (['BBC micro:bit', 'Mithon CC'].includes(BOARD.boardType)) {
|
if (['BBC micro:bit', 'Mithon CC'].includes(BOARD.boardType)) {
|
||||||
await BU.uploadByUSB(portName);
|
await BU.uploadWithDAP(portName);
|
||||||
} else {
|
} else {
|
||||||
await BU.uploadWithAmpy(portName);
|
await BU.uploadWithAmpy(portName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BU.uploadByUSB = async (portName) => {
|
BU.uploadWithDAP = async (portName) => {
|
||||||
const { mainStatusBarTabs } = Mixly;
|
const { mainStatusBarTabs } = Mixly;
|
||||||
if (!portName) {
|
if (!portName) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
509
common/modules/mixly-modules/web/kflash.js
Normal file
509
common/modules/mixly-modules/web/kflash.js
Normal file
File diff suppressed because one or more lines are too long
1777
common/modules/web-modules/crc.min.js
vendored
Normal file
1777
common/modules/web-modules/crc.min.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
common/modules/web-modules/pako.min.js
vendored
Normal file
2
common/modules/web-modules/pako.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
171
common/modules/web-modules/struct.min.js
vendored
Normal file
171
common/modules/web-modules/struct.min.js
vendored
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
/*eslint-env es6*/
|
||||||
|
const rechk = /^([<>])?(([1-9]\d*)?([xcbB?hHiIfdsp]))*$/;
|
||||||
|
const refmt = /([1-9]\d*)?([xcbB?hHiIfdsp])/g;
|
||||||
|
const str = (v, o, c) =>
|
||||||
|
String.fromCharCode(...new Uint8Array(v.buffer, v.byteOffset + o, c));
|
||||||
|
const rts = (v, o, c, s) =>
|
||||||
|
new Uint8Array(v.buffer, v.byteOffset + o, c).set(
|
||||||
|
s.split("").map((str) => str.charCodeAt(0))
|
||||||
|
);
|
||||||
|
const pst = (v, o, c) => str(v, o + 1, Math.min(v.getUint8(o), c - 1));
|
||||||
|
const tsp = (v, o, c, s) => {
|
||||||
|
v.setUint8(o, s.length);
|
||||||
|
rts(v, o + 1, c - 1, s);
|
||||||
|
};
|
||||||
|
const lut = (le) => ({
|
||||||
|
x: (c) => [1, c, 0],
|
||||||
|
c: (c) => [
|
||||||
|
c,
|
||||||
|
1,
|
||||||
|
(o) => ({ u: (v) => str(v, o, 1), p: (v, c) => rts(v, o, 1, c) }),
|
||||||
|
],
|
||||||
|
"?": (c) => [
|
||||||
|
c,
|
||||||
|
1,
|
||||||
|
(o) => ({
|
||||||
|
u: (v) => Boolean(v.getUint8(o)),
|
||||||
|
p: (v, B) => v.setUint8(o, B),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
b: (c) => [
|
||||||
|
c,
|
||||||
|
1,
|
||||||
|
(o) => ({ u: (v) => v.getInt8(o), p: (v, b) => v.setInt8(o, b) }),
|
||||||
|
],
|
||||||
|
B: (c) => [
|
||||||
|
c,
|
||||||
|
1,
|
||||||
|
(o) => ({ u: (v) => v.getUint8(o), p: (v, B) => v.setUint8(o, B) }),
|
||||||
|
],
|
||||||
|
h: (c) => [
|
||||||
|
c,
|
||||||
|
2,
|
||||||
|
(o) => ({ u: (v) => v.getInt16(o, le), p: (v, h) => v.setInt16(o, h, le) }),
|
||||||
|
],
|
||||||
|
H: (c) => [
|
||||||
|
c,
|
||||||
|
2,
|
||||||
|
(o) => ({
|
||||||
|
u: (v) => v.getUint16(o, le),
|
||||||
|
p: (v, H) => v.setUint16(o, H, le),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
i: (c) => [
|
||||||
|
c,
|
||||||
|
4,
|
||||||
|
(o) => ({ u: (v) => v.getInt32(o, le), p: (v, i) => v.setInt32(o, i, le) }),
|
||||||
|
],
|
||||||
|
I: (c) => [
|
||||||
|
c,
|
||||||
|
4,
|
||||||
|
(o) => ({
|
||||||
|
u: (v) => v.getUint32(o, le),
|
||||||
|
p: (v, I) => v.setUint32(o, I, le),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
f: (c) => [
|
||||||
|
c,
|
||||||
|
4,
|
||||||
|
(o) => ({
|
||||||
|
u: (v) => v.getFloat32(o, le),
|
||||||
|
p: (v, f) => v.setFloat32(o, f, le),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
d: (c) => [
|
||||||
|
c,
|
||||||
|
8,
|
||||||
|
(o) => ({
|
||||||
|
u: (v) => v.getFloat64(o, le),
|
||||||
|
p: (v, d) => v.setFloat64(o, d, le),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
s: (c) => [
|
||||||
|
1,
|
||||||
|
c,
|
||||||
|
(o) => ({
|
||||||
|
u: (v) => str(v, o, c),
|
||||||
|
p: (v, s) => rts(v, o, c, s.slice(0, c)),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
p: (c) => [
|
||||||
|
1,
|
||||||
|
c,
|
||||||
|
(o) => ({
|
||||||
|
u: (v) => pst(v, o, c),
|
||||||
|
p: (v, s) => tsp(v, o, c, s.slice(0, c - 1)),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const errbuf = new RangeError("Structure larger than remaining buffer");
|
||||||
|
const errval = new RangeError("Not enough values for structure");
|
||||||
|
function struct(format) {
|
||||||
|
let fns = [],
|
||||||
|
size = 0,
|
||||||
|
m = rechk.exec(format);
|
||||||
|
if (!m) {
|
||||||
|
throw new RangeError("Invalid format string");
|
||||||
|
}
|
||||||
|
const t = lut("<" === m[1]),
|
||||||
|
lu = (n, c) => t[c](n ? parseInt(n, 10) : 1);
|
||||||
|
while ((m = refmt.exec(format))) {
|
||||||
|
((r, s, f) => {
|
||||||
|
for (let i = 0; i < r; ++i, size += s) {
|
||||||
|
if (f) {
|
||||||
|
fns.push(f(size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(...lu(...m.slice(1)));
|
||||||
|
}
|
||||||
|
const unpack_from = (arrb, offs) => {
|
||||||
|
if (arrb.byteLength < (offs | 0) + size) {
|
||||||
|
throw errbuf;
|
||||||
|
}
|
||||||
|
let v = new DataView(arrb, offs | 0);
|
||||||
|
return fns.map((f) => f.u(v));
|
||||||
|
};
|
||||||
|
const pack_into = (arrb, offs, ...values) => {
|
||||||
|
if (values.length < fns.length) {
|
||||||
|
throw errval;
|
||||||
|
}
|
||||||
|
if (arrb.byteLength < offs + size) {
|
||||||
|
throw errbuf;
|
||||||
|
}
|
||||||
|
const v = new DataView(arrb, offs);
|
||||||
|
new Uint8Array(arrb, offs, size).fill(0);
|
||||||
|
fns.forEach((f, i) => f.p(v, values[i]));
|
||||||
|
};
|
||||||
|
const pack = (...values) => {
|
||||||
|
let b = new ArrayBuffer(size);
|
||||||
|
pack_into(b, 0, ...values);
|
||||||
|
return b;
|
||||||
|
};
|
||||||
|
const unpack = (arrb) => unpack_from(arrb, 0);
|
||||||
|
function* iter_unpack(arrb) {
|
||||||
|
for (let offs = 0; offs + size <= arrb.byteLength; offs += size) {
|
||||||
|
yield unpack_from(arrb, offs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object.freeze({
|
||||||
|
unpack,
|
||||||
|
pack,
|
||||||
|
unpack_from,
|
||||||
|
pack_into,
|
||||||
|
iter_unpack,
|
||||||
|
format,
|
||||||
|
size,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.struct = struct;
|
||||||
|
/*
|
||||||
|
const pack = (format, ...values) => struct(format).pack(...values)
|
||||||
|
const unpack = (format, buffer) => struct(format).unpack(buffer)
|
||||||
|
const pack_into = (format, arrb, offs, ...values) =>
|
||||||
|
struct(format).pack_into(arrb, offs, ...values)
|
||||||
|
const unpack_from = (format, arrb, offset) =>
|
||||||
|
struct(format).unpack_from(arrb, offset)
|
||||||
|
const iter_unpack = (format, arrb) => struct(format).iter_unpack(arrb)
|
||||||
|
const calcsize = format => struct(format).size
|
||||||
|
module.exports = {
|
||||||
|
struct, pack, unpack, pack_into, unpack_from, iter_unpack, calcsize }
|
||||||
|
*/
|
||||||
Reference in New Issue
Block a user