utf8.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. function byteLength (string) {
  2. let length = 0
  3. for (let i = 0, n = string.length; i < n; i++) {
  4. const code = string.charCodeAt(i)
  5. if (code >= 0xd800 && code <= 0xdbff && i + 1 < n) {
  6. const code = string.charCodeAt(i + 1)
  7. if (code >= 0xdc00 && code <= 0xdfff) {
  8. length += 4
  9. i++
  10. continue
  11. }
  12. }
  13. if (code <= 0x7f) length += 1
  14. else if (code <= 0x7ff) length += 2
  15. else length += 3
  16. }
  17. return length
  18. }
  19. let toString
  20. if (typeof TextDecoder !== 'undefined') {
  21. const decoder = new TextDecoder()
  22. toString = function toString (buffer) {
  23. return decoder.decode(buffer)
  24. }
  25. } else {
  26. toString = function toString (buffer) {
  27. const len = buffer.byteLength
  28. let output = ''
  29. let i = 0
  30. while (i < len) {
  31. let byte = buffer[i]
  32. if (byte <= 0x7f) {
  33. output += String.fromCharCode(byte)
  34. i++
  35. continue
  36. }
  37. let bytesNeeded = 0
  38. let codePoint = 0
  39. if (byte <= 0xdf) {
  40. bytesNeeded = 1
  41. codePoint = byte & 0x1f
  42. } else if (byte <= 0xef) {
  43. bytesNeeded = 2
  44. codePoint = byte & 0x0f
  45. } else if (byte <= 0xf4) {
  46. bytesNeeded = 3
  47. codePoint = byte & 0x07
  48. }
  49. if (len - i - bytesNeeded > 0) {
  50. let k = 0
  51. while (k < bytesNeeded) {
  52. byte = buffer[i + k + 1]
  53. codePoint = (codePoint << 6) | (byte & 0x3f)
  54. k += 1
  55. }
  56. } else {
  57. codePoint = 0xfffd
  58. bytesNeeded = len - i
  59. }
  60. output += String.fromCodePoint(codePoint)
  61. i += bytesNeeded + 1
  62. }
  63. return output
  64. }
  65. }
  66. let write
  67. if (typeof TextEncoder !== 'undefined') {
  68. const encoder = new TextEncoder()
  69. write = function write (buffer, string, offset = 0, length = byteLength(string)) {
  70. const len = Math.min(length, buffer.byteLength - offset)
  71. encoder.encodeInto(string, buffer.subarray(offset, offset + len))
  72. return len
  73. }
  74. } else {
  75. write = function write (buffer, string, offset = 0, length = byteLength(string)) {
  76. const len = Math.min(length, buffer.byteLength - offset)
  77. buffer = buffer.subarray(offset, offset + len)
  78. let i = 0
  79. let j = 0
  80. while (i < string.length) {
  81. const code = string.codePointAt(i)
  82. if (code <= 0x7f) {
  83. buffer[j++] = code
  84. i++
  85. continue
  86. }
  87. let count = 0
  88. let bits = 0
  89. if (code <= 0x7ff) {
  90. count = 6
  91. bits = 0xc0
  92. } else if (code <= 0xffff) {
  93. count = 12
  94. bits = 0xe0
  95. } else if (code <= 0x1fffff) {
  96. count = 18
  97. bits = 0xf0
  98. }
  99. buffer[j++] = bits | (code >> count)
  100. count -= 6
  101. while (count >= 0) {
  102. buffer[j++] = 0x80 | ((code >> count) & 0x3f)
  103. count -= 6
  104. }
  105. i += code >= 0x10000 ? 2 : 1
  106. }
  107. return len
  108. }
  109. }
  110. module.exports = {
  111. byteLength,
  112. toString,
  113. write
  114. }