index.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. (function() {
  2. var nodeEnv = typeof require !== 'undefined' && typeof process !== 'undefined';
  3. var __module = nodeEnv ? module : {exports:{}};
  4. var __filename = 'preview-scripts/__node_modules/string_decoder/index.js';
  5. var __require = nodeEnv ? function (request) {
  6. return cc.require(request);
  7. } : function (request) {
  8. return __quick_compile_project__.require(request, __filename);
  9. };
  10. function __define (exports, require, module) {
  11. if (!nodeEnv) {__quick_compile_project__.registerModule(__filename, module);}// Copyright Joyent, Inc. and other Node contributors.
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining a
  14. // copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to permit
  18. // persons to whom the Software is furnished to do so, subject to the
  19. // following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be included
  22. // in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  25. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  27. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  28. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  29. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  30. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. var Buffer = require('buffer').Buffer;
  32. var isBufferEncoding = Buffer.isEncoding
  33. || function(encoding) {
  34. switch (encoding && encoding.toLowerCase()) {
  35. case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
  36. default: return false;
  37. }
  38. }
  39. function assertEncoding(encoding) {
  40. if (encoding && !isBufferEncoding(encoding)) {
  41. throw new Error('Unknown encoding: ' + encoding);
  42. }
  43. }
  44. // StringDecoder provides an interface for efficiently splitting a series of
  45. // buffers into a series of JS strings without breaking apart multi-byte
  46. // characters. CESU-8 is handled as part of the UTF-8 encoding.
  47. //
  48. // @TODO Handling all encodings inside a single object makes it very difficult
  49. // to reason about this code, so it should be split up in the future.
  50. // @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
  51. // points as used by CESU-8.
  52. var StringDecoder = exports.StringDecoder = function(encoding) {
  53. this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
  54. assertEncoding(encoding);
  55. switch (this.encoding) {
  56. case 'utf8':
  57. // CESU-8 represents each of Surrogate Pair by 3-bytes
  58. this.surrogateSize = 3;
  59. break;
  60. case 'ucs2':
  61. case 'utf16le':
  62. // UTF-16 represents each of Surrogate Pair by 2-bytes
  63. this.surrogateSize = 2;
  64. this.detectIncompleteChar = utf16DetectIncompleteChar;
  65. break;
  66. case 'base64':
  67. // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
  68. this.surrogateSize = 3;
  69. this.detectIncompleteChar = base64DetectIncompleteChar;
  70. break;
  71. default:
  72. this.write = passThroughWrite;
  73. return;
  74. }
  75. // Enough space to store all bytes of a single character. UTF-8 needs 4
  76. // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
  77. this.charBuffer = new Buffer(6);
  78. // Number of bytes received for the current incomplete multi-byte character.
  79. this.charReceived = 0;
  80. // Number of bytes expected for the current incomplete multi-byte character.
  81. this.charLength = 0;
  82. };
  83. // write decodes the given buffer and returns it as JS string that is
  84. // guaranteed to not contain any partial multi-byte characters. Any partial
  85. // character found at the end of the buffer is buffered up, and will be
  86. // returned when calling write again with the remaining bytes.
  87. //
  88. // Note: Converting a Buffer containing an orphan surrogate to a String
  89. // currently works, but converting a String to a Buffer (via `new Buffer`, or
  90. // Buffer#write) will replace incomplete surrogates with the unicode
  91. // replacement character. See https://codereview.chromium.org/121173009/ .
  92. StringDecoder.prototype.write = function(buffer) {
  93. var charStr = '';
  94. // if our last write ended with an incomplete multibyte character
  95. while (this.charLength) {
  96. // determine how many remaining bytes this buffer has to offer for this char
  97. var available = (buffer.length >= this.charLength - this.charReceived) ?
  98. this.charLength - this.charReceived :
  99. buffer.length;
  100. // add the new bytes to the char buffer
  101. buffer.copy(this.charBuffer, this.charReceived, 0, available);
  102. this.charReceived += available;
  103. if (this.charReceived < this.charLength) {
  104. // still not enough chars in this buffer? wait for more ...
  105. return '';
  106. }
  107. // remove bytes belonging to the current character from the buffer
  108. buffer = buffer.slice(available, buffer.length);
  109. // get the character that was split
  110. charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
  111. // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
  112. var charCode = charStr.charCodeAt(charStr.length - 1);
  113. if (charCode >= 0xD800 && charCode <= 0xDBFF) {
  114. this.charLength += this.surrogateSize;
  115. charStr = '';
  116. continue;
  117. }
  118. this.charReceived = this.charLength = 0;
  119. // if there are no more bytes in this buffer, just emit our char
  120. if (buffer.length === 0) {
  121. return charStr;
  122. }
  123. break;
  124. }
  125. // determine and set charLength / charReceived
  126. this.detectIncompleteChar(buffer);
  127. var end = buffer.length;
  128. if (this.charLength) {
  129. // buffer the incomplete character bytes we got
  130. buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
  131. end -= this.charReceived;
  132. }
  133. charStr += buffer.toString(this.encoding, 0, end);
  134. var end = charStr.length - 1;
  135. var charCode = charStr.charCodeAt(end);
  136. // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
  137. if (charCode >= 0xD800 && charCode <= 0xDBFF) {
  138. var size = this.surrogateSize;
  139. this.charLength += size;
  140. this.charReceived += size;
  141. this.charBuffer.copy(this.charBuffer, size, 0, size);
  142. buffer.copy(this.charBuffer, 0, 0, size);
  143. return charStr.substring(0, end);
  144. }
  145. // or just emit the charStr
  146. return charStr;
  147. };
  148. // detectIncompleteChar determines if there is an incomplete UTF-8 character at
  149. // the end of the given buffer. If so, it sets this.charLength to the byte
  150. // length that character, and sets this.charReceived to the number of bytes
  151. // that are available for this character.
  152. StringDecoder.prototype.detectIncompleteChar = function(buffer) {
  153. // determine how many bytes we have to check at the end of this buffer
  154. var i = (buffer.length >= 3) ? 3 : buffer.length;
  155. // Figure out if one of the last i bytes of our buffer announces an
  156. // incomplete char.
  157. for (; i > 0; i--) {
  158. var c = buffer[buffer.length - i];
  159. // See http://en.wikipedia.org/wiki/UTF-8#Description
  160. // 110XXXXX
  161. if (i == 1 && c >> 5 == 0x06) {
  162. this.charLength = 2;
  163. break;
  164. }
  165. // 1110XXXX
  166. if (i <= 2 && c >> 4 == 0x0E) {
  167. this.charLength = 3;
  168. break;
  169. }
  170. // 11110XXX
  171. if (i <= 3 && c >> 3 == 0x1E) {
  172. this.charLength = 4;
  173. break;
  174. }
  175. }
  176. this.charReceived = i;
  177. };
  178. StringDecoder.prototype.end = function(buffer) {
  179. var res = '';
  180. if (buffer && buffer.length)
  181. res = this.write(buffer);
  182. if (this.charReceived) {
  183. var cr = this.charReceived;
  184. var buf = this.charBuffer;
  185. var enc = this.encoding;
  186. res += buf.slice(0, cr).toString(enc);
  187. }
  188. return res;
  189. };
  190. function passThroughWrite(buffer) {
  191. return buffer.toString(this.encoding);
  192. }
  193. function utf16DetectIncompleteChar(buffer) {
  194. this.charReceived = buffer.length % 2;
  195. this.charLength = this.charReceived ? 2 : 0;
  196. }
  197. function base64DetectIncompleteChar(buffer) {
  198. this.charReceived = buffer.length % 3;
  199. this.charLength = this.charReceived ? 3 : 0;
  200. }
  201. }
  202. if (nodeEnv) {
  203. __define(__module.exports, __require, __module);
  204. }
  205. else {
  206. __quick_compile_project__.registerModuleFunc(__filename, function () {
  207. __define(__module.exports, __require, __module);
  208. });
  209. }
  210. })();