marshall.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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, offset) {
  71. var output = [];
  72. for (var i=0; i < typelist.length; i++) {
  73. switch (typelist[i]) {
  74. case "w":
  75. var val = struct[offset++];
  76. val += struct[offset++] << 8;
  77. val += struct[offset++] << 16;
  78. val += (struct[offset++] << 24) >>> 0;
  79. output.push(val);
  80. break;
  81. case "d":
  82. var val = struct[offset++];
  83. val += struct[offset++] << 8;
  84. val += struct[offset++] << 16;
  85. val += (struct[offset++] << 24) >>> 0;
  86. offset += 4;
  87. output.push(val);
  88. break;
  89. case "h":
  90. var val = struct[offset++];
  91. output.push(val + (struct[offset++] << 8));
  92. break;
  93. case "b":
  94. output.push(struct[offset++]);
  95. break;
  96. case "s":
  97. var len = struct[offset++];
  98. len += struct[offset++] << 8;
  99. var str = '';
  100. var utf8converter = new UTF8StreamToUnicode();
  101. for (var j=0; j < len; j++) {
  102. var c = utf8converter.Put(struct[offset++])
  103. if (c == -1) continue;
  104. str += String.fromCharCode(c);
  105. }
  106. output.push(str);
  107. break;
  108. default:
  109. message.Debug("Error in Unmarshall: Unknown type=" + typelist[i]);
  110. break;
  111. }
  112. }
  113. return output;
  114. };
  115. // Extracts data from a byte aligned struct in memory to an array
  116. marshall.Unmarshall2 = function(typelist, GetByte) {
  117. var output = [];
  118. for (var i=0; i < typelist.length; i++) {
  119. switch (typelist[i]) {
  120. case "w":
  121. var val = GetByte();
  122. val += GetByte() << 8;
  123. val += GetByte() << 16;
  124. val += (GetByte() << 24) >>> 0;
  125. output.push(val);
  126. break;
  127. case "d":
  128. var val = GetByte();
  129. val += GetByte() << 8;
  130. val += GetByte() << 16;
  131. val += (GetByte() << 24) >>> 0;
  132. GetByte();GetByte();GetByte();GetByte();
  133. output.push(val);
  134. break;
  135. case "h":
  136. var val = GetByte();
  137. output.push(val + (GetByte() << 8));
  138. break;
  139. case "b":
  140. output.push(GetByte());
  141. break;
  142. case "s":
  143. var len = GetByte();
  144. len += GetByte() << 8;
  145. var str = '';
  146. var utf8converter = new UTF8StreamToUnicode();
  147. for (var j=0; j < len; j++) {
  148. var c = utf8converter.Put(GetByte())
  149. if (c == -1) continue;
  150. str += String.fromCharCode(c);
  151. }
  152. output.push(str);
  153. break;
  154. default:
  155. message.Debug("Error in Unmarshall2: Unknown type=" + typelist[i]);
  156. break;
  157. }
  158. }
  159. return output;
  160. };