marshall.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // -------------------------------------------------
  2. // ------------------ Marshall ---------------------
  3. // -------------------------------------------------
  4. // helper functions for virtio and 9p.
  5. "use strict";
  6. var marshall = {};
  7. const textde = new TextDecoder();
  8. const texten = new TextEncoder();
  9. // Inserts data from an array to a byte aligned struct in memory
  10. marshall.Marshall = function(typelist, input, struct, offset) {
  11. var item;
  12. var size = 0;
  13. for(var i=0; i < typelist.length; i++) {
  14. item = input[i];
  15. switch(typelist[i]) {
  16. case "w":
  17. struct[offset++] = item & 0xFF;
  18. struct[offset++] = (item >> 8) & 0xFF;
  19. struct[offset++] = (item >> 16) & 0xFF;
  20. struct[offset++] = (item >> 24) & 0xFF;
  21. size += 4;
  22. break;
  23. case "d": // double word
  24. struct[offset++] = item & 0xFF;
  25. struct[offset++] = (item >> 8) & 0xFF;
  26. struct[offset++] = (item >> 16) & 0xFF;
  27. struct[offset++] = (item >> 24) & 0xFF;
  28. struct[offset++] = 0x0;
  29. struct[offset++] = 0x0;
  30. struct[offset++] = 0x0;
  31. struct[offset++] = 0x0;
  32. size += 8;
  33. break;
  34. case "h":
  35. struct[offset++] = item & 0xFF;
  36. struct[offset++] = item >> 8;
  37. size += 2;
  38. break;
  39. case "b":
  40. struct[offset++] = item;
  41. size += 1;
  42. break;
  43. case "s":
  44. var lengthoffset = offset;
  45. var length = 0;
  46. struct[offset++] = 0; // set the length later
  47. struct[offset++] = 0;
  48. size += 2;
  49. var stringBytes = texten.encode(item);
  50. size += stringBytes.byteLength;
  51. length += stringBytes.byteLength;
  52. struct.set(stringBytes, offset);
  53. offset += stringBytes.byteLength;
  54. struct[lengthoffset+0] = length & 0xFF;
  55. struct[lengthoffset+1] = (length >> 8) & 0xFF;
  56. break;
  57. case "Q":
  58. marshall.Marshall(["b", "w", "d"], [item.type, item.version, item.path], struct, offset);
  59. offset += 13;
  60. size += 13;
  61. break;
  62. default:
  63. message.Debug("Marshall: Unknown type=" + typelist[i]);
  64. break;
  65. }
  66. }
  67. return size;
  68. };
  69. // Extracts data from a byte aligned struct in memory to an array
  70. marshall.Unmarshall = function(typelist, struct, state) {
  71. let offset = state.offset;
  72. var output = [];
  73. for(var i=0; i < typelist.length; i++) {
  74. switch(typelist[i]) {
  75. case "w":
  76. var val = struct[offset++];
  77. val += struct[offset++] << 8;
  78. val += struct[offset++] << 16;
  79. val += (struct[offset++] << 24) >>> 0;
  80. output.push(val);
  81. break;
  82. case "d":
  83. var val = struct[offset++];
  84. val += struct[offset++] << 8;
  85. val += struct[offset++] << 16;
  86. val += (struct[offset++] << 24) >>> 0;
  87. offset += 4;
  88. output.push(val);
  89. break;
  90. case "h":
  91. var val = struct[offset++];
  92. output.push(val + (struct[offset++] << 8));
  93. break;
  94. case "b":
  95. output.push(struct[offset++]);
  96. break;
  97. case "s":
  98. var len = struct[offset++];
  99. len += struct[offset++] << 8;
  100. var stringBytes = struct.slice(offset, offset + len);
  101. offset += len;
  102. output.push(textde.decode(stringBytes));
  103. break;
  104. case "Q":
  105. state.offset = offset;
  106. const qid = marshall.Unmarshall(["b", "w", "d"], struct, state);
  107. offset = state.offset;
  108. output.push({
  109. type: qid[0],
  110. version: qid[1],
  111. path: qid[2],
  112. });
  113. break;
  114. default:
  115. message.Debug("Error in Unmarshall: Unknown type=" + typelist[i]);
  116. break;
  117. }
  118. }
  119. state.offset = offset;
  120. return output;
  121. };