marshall.js 4.6 KB

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