2014-12-02 19:01:13 +01:00
|
|
|
// -------------------------------------------------
|
|
|
|
// ------------------ Marshall ---------------------
|
|
|
|
// -------------------------------------------------
|
|
|
|
// helper functions for virtio and 9p.
|
|
|
|
|
2018-07-13 04:21:23 +02:00
|
|
|
"use strict";
|
|
|
|
|
2016-01-04 04:16:00 +01:00
|
|
|
var marshall = {};
|
|
|
|
|
2014-12-02 19:01:13 +01:00
|
|
|
|
|
|
|
// Inserts data from an array to a byte aligned struct in memory
|
2016-01-04 04:16:00 +01:00
|
|
|
marshall.Marshall = function(typelist, input, struct, offset) {
|
2014-12-02 19:01:13 +01:00
|
|
|
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;
|
2018-10-01 20:18:49 +02:00
|
|
|
for (var j of item) {
|
|
|
|
var utf8 = UnicodeToUTF8Stream(j.charCodeAt(0));
|
2014-12-02 19:01:13 +01:00
|
|
|
utf8.forEach( function(c) {
|
|
|
|
struct[offset++] = c;
|
|
|
|
size += 1;
|
|
|
|
length++;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
struct[lengthoffset+0] = length & 0xFF;
|
|
|
|
struct[lengthoffset+1] = (length >> 8) & 0xFF;
|
|
|
|
break;
|
|
|
|
case "Q":
|
2018-07-13 04:21:23 +02:00
|
|
|
marshall.Marshall(["b", "w", "d"], [item.type, item.version, item.path], struct, offset);
|
2014-12-02 19:01:13 +01:00
|
|
|
offset += 13;
|
|
|
|
size += 13;
|
|
|
|
break;
|
|
|
|
default:
|
2016-01-04 04:16:00 +01:00
|
|
|
message.Debug("Marshall: Unknown type=" + typelist[i]);
|
2014-12-02 19:01:13 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return size;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Extracts data from a byte aligned struct in memory to an array
|
2018-05-02 20:13:07 +02:00
|
|
|
marshall.Unmarshall = function(typelist, struct, state) {
|
|
|
|
let offset = state.offset;
|
2014-12-02 19:01:13 +01:00
|
|
|
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 str = '';
|
|
|
|
var utf8converter = new UTF8StreamToUnicode();
|
|
|
|
for (var j=0; j < len; j++) {
|
2018-07-13 04:21:23 +02:00
|
|
|
var c = utf8converter.Put(struct[offset++]);
|
2014-12-02 19:01:13 +01:00
|
|
|
if (c == -1) continue;
|
|
|
|
str += String.fromCharCode(c);
|
|
|
|
}
|
|
|
|
output.push(str);
|
|
|
|
break;
|
2018-07-13 01:32:30 +02:00
|
|
|
case "Q":
|
|
|
|
state.offset = offset;
|
|
|
|
const qid = marshall.Unmarshall(["b", "w", "d"], struct, state);
|
|
|
|
offset = state.offset;
|
|
|
|
output.push({
|
|
|
|
type: qid[0],
|
|
|
|
version: qid[1],
|
|
|
|
path: qid[2],
|
|
|
|
});
|
|
|
|
break;
|
2014-12-02 19:01:13 +01:00
|
|
|
default:
|
2016-01-04 04:16:00 +01:00
|
|
|
message.Debug("Error in Unmarshall: Unknown type=" + typelist[i]);
|
2014-12-02 19:01:13 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-05-02 20:13:07 +02:00
|
|
|
state.offset = offset;
|
2014-12-02 19:01:13 +01:00
|
|
|
return output;
|
|
|
|
};
|