Spaces:
Runtime error
Runtime error
// ------------------------------------------------- | |
// ------------------ Marshall --------------------- | |
// ------------------------------------------------- | |
// helper functions for virtio and 9p. | |
import { dbg_log } from "./../src/log.js"; | |
const textde = new TextDecoder(); | |
const texten = new TextEncoder(); | |
// Inserts data from an array to a byte aligned struct in memory | |
export function Marshall(typelist, input, struct, offset) { | |
var item; | |
var size = 0; | |
for(var i=0; i < typelist.length; i++) { | |
item = input[i]; | |
switch(typelist[i]) { | |
case "w": | |
struct[offset++] = item & 0xFF; | |
struct[offset++] = (item >> 8) & 0xFF; | |
struct[offset++] = (item >> 16) & 0xFF; | |
struct[offset++] = (item >> 24) & 0xFF; | |
size += 4; | |
break; | |
case "d": // double word | |
struct[offset++] = item & 0xFF; | |
struct[offset++] = (item >> 8) & 0xFF; | |
struct[offset++] = (item >> 16) & 0xFF; | |
struct[offset++] = (item >> 24) & 0xFF; | |
struct[offset++] = 0x0; | |
struct[offset++] = 0x0; | |
struct[offset++] = 0x0; | |
struct[offset++] = 0x0; | |
size += 8; | |
break; | |
case "h": | |
struct[offset++] = item & 0xFF; | |
struct[offset++] = item >> 8; | |
size += 2; | |
break; | |
case "b": | |
struct[offset++] = item; | |
size += 1; | |
break; | |
case "s": | |
var lengthoffset = offset; | |
var length = 0; | |
struct[offset++] = 0; // set the length later | |
struct[offset++] = 0; | |
size += 2; | |
var stringBytes = texten.encode(item); | |
size += stringBytes.byteLength; | |
length += stringBytes.byteLength; | |
struct.set(stringBytes, offset); | |
offset += stringBytes.byteLength; | |
struct[lengthoffset+0] = length & 0xFF; | |
struct[lengthoffset+1] = (length >> 8) & 0xFF; | |
break; | |
case "Q": | |
Marshall(["b", "w", "d"], [item.type, item.version, item.path], struct, offset); | |
offset += 13; | |
size += 13; | |
break; | |
default: | |
dbg_log("Marshall: Unknown type=" + typelist[i]); | |
break; | |
} | |
} | |
return size; | |
} | |
// Extracts data from a byte aligned struct in memory to an array | |
export function Unmarshall(typelist, struct, state) { | |
let offset = state.offset; | |
var output = []; | |
for(var i=0; i < typelist.length; i++) { | |
switch(typelist[i]) { | |
case "w": | |
var val = struct[offset++]; | |
val += struct[offset++] << 8; | |
val += struct[offset++] << 16; | |
val += (struct[offset++] << 24) >>> 0; | |
output.push(val); | |
break; | |
case "d": | |
var val = struct[offset++]; | |
val += struct[offset++] << 8; | |
val += struct[offset++] << 16; | |
val += (struct[offset++] << 24) >>> 0; | |
offset += 4; | |
output.push(val); | |
break; | |
case "h": | |
var val = struct[offset++]; | |
output.push(val + (struct[offset++] << 8)); | |
break; | |
case "b": | |
output.push(struct[offset++]); | |
break; | |
case "s": | |
var len = struct[offset++]; | |
len += struct[offset++] << 8; | |
var stringBytes = struct.slice(offset, offset + len); | |
offset += len; | |
output.push(textde.decode(stringBytes)); | |
break; | |
case "Q": | |
state.offset = offset; | |
const qid = Unmarshall(["b", "w", "d"], struct, state); | |
offset = state.offset; | |
output.push({ | |
type: qid[0], | |
version: qid[1], | |
path: qid[2], | |
}); | |
break; | |
default: | |
dbg_log("Error in Unmarshall: Unknown type=" + typelist[i]); | |
break; | |
} | |
} | |
state.offset = offset; | |
return output; | |
} | |