marshall.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // -------------------------------------------------
  2. // ------------------ Marshall ---------------------
  3. // -------------------------------------------------
  4. // helper functions for virtio and 9p.
  5. var marshall = {};
  6. // Inserts data from an array to a byte aligned struct in memory
  7. marshall.Marshall = function(typelist, input, struct, offset) {
  8. var item;
  9. var size = 0;
  10. for (var i=0; i < typelist.length; i++) {
  11. item = input[i];
  12. switch (typelist[i]) {
  13. case "w":
  14. struct[offset++] = item & 0xFF;
  15. struct[offset++] = (item >> 8) & 0xFF;
  16. struct[offset++] = (item >> 16) & 0xFF;
  17. struct[offset++] = (item >> 24) & 0xFF;
  18. size += 4;
  19. break;
  20. case "d": // double word
  21. struct[offset++] = item & 0xFF;
  22. struct[offset++] = (item >> 8) & 0xFF;
  23. struct[offset++] = (item >> 16) & 0xFF;
  24. struct[offset++] = (item >> 24) & 0xFF;
  25. struct[offset++] = 0x0;
  26. struct[offset++] = 0x0;
  27. struct[offset++] = 0x0;
  28. struct[offset++] = 0x0;
  29. size += 8;
  30. break;
  31. case "h":
  32. struct[offset++] = item & 0xFF;
  33. struct[offset++] = item >> 8;
  34. size += 2;
  35. break;
  36. case "b":
  37. struct[offset++] = item;
  38. size += 1;
  39. break;
  40. case "s":
  41. var lengthoffset = offset;
  42. var length = 0;
  43. struct[offset++] = 0; // set the length later
  44. struct[offset++] = 0;
  45. size += 2;
  46. for (var j in item) {
  47. var utf8 = UnicodeToUTF8Stream(item.charCodeAt(j));
  48. utf8.forEach( function(c) {
  49. struct[offset++] = c;
  50. size += 1;
  51. length++;
  52. });
  53. }
  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 str = '';
  101. var utf8converter = new UTF8StreamToUnicode();
  102. for (var j=0; j < len; j++) {
  103. var c = utf8converter.Put(struct[offset++])
  104. if (c == -1) continue;
  105. str += String.fromCharCode(c);
  106. }
  107. output.push(str);
  108. break;
  109. default:
  110. message.Debug("Error in Unmarshall: Unknown type=" + typelist[i]);
  111. break;
  112. }
  113. }
  114. state.offset = offset;
  115. return output;
  116. };
  117. // Extracts data from a byte aligned struct in memory to an array
  118. marshall.Unmarshall2 = function(typelist, GetByte) {
  119. var output = [];
  120. for (var i=0; i < typelist.length; i++) {
  121. switch (typelist[i]) {
  122. case "w":
  123. var val = GetByte();
  124. val += GetByte() << 8;
  125. val += GetByte() << 16;
  126. val += (GetByte() << 24) >>> 0;
  127. output.push(val);
  128. break;
  129. case "d":
  130. var val = GetByte();
  131. val += GetByte() << 8;
  132. val += GetByte() << 16;
  133. val += (GetByte() << 24) >>> 0;
  134. GetByte();GetByte();GetByte();GetByte();
  135. output.push(val);
  136. break;
  137. case "h":
  138. var val = GetByte();
  139. output.push(val + (GetByte() << 8));
  140. break;
  141. case "b":
  142. output.push(GetByte());
  143. break;
  144. case "s":
  145. var len = GetByte();
  146. len += GetByte() << 8;
  147. var str = '';
  148. var utf8converter = new UTF8StreamToUnicode();
  149. for (var j=0; j < len; j++) {
  150. var c = utf8converter.Put(GetByte())
  151. if (c == -1) continue;
  152. str += String.fromCharCode(c);
  153. }
  154. output.push(str);
  155. break;
  156. default:
  157. message.Debug("Error in Unmarshall2: Unknown type=" + typelist[i]);
  158. break;
  159. }
  160. }
  161. return output;
  162. };