decodeText.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. 'use strict'
  2. // Node has always utf-8
  3. const utf8Decoder = new TextDecoder('utf-8')
  4. const textDecoders = new Map([
  5. ['utf-8', utf8Decoder],
  6. ['utf8', utf8Decoder]
  7. ])
  8. function getDecoder (charset) {
  9. let lc
  10. while (true) {
  11. switch (charset) {
  12. case 'utf-8':
  13. case 'utf8':
  14. return decoders.utf8
  15. case 'latin1':
  16. case 'ascii': // TODO: Make these a separate, strict decoder?
  17. case 'us-ascii':
  18. case 'iso-8859-1':
  19. case 'iso8859-1':
  20. case 'iso88591':
  21. case 'iso_8859-1':
  22. case 'windows-1252':
  23. case 'iso_8859-1:1987':
  24. case 'cp1252':
  25. case 'x-cp1252':
  26. return decoders.latin1
  27. case 'utf16le':
  28. case 'utf-16le':
  29. case 'ucs2':
  30. case 'ucs-2':
  31. return decoders.utf16le
  32. case 'base64':
  33. return decoders.base64
  34. default:
  35. if (lc === undefined) {
  36. lc = true
  37. charset = charset.toLowerCase()
  38. continue
  39. }
  40. return decoders.other.bind(charset)
  41. }
  42. }
  43. }
  44. const decoders = {
  45. utf8: (data, sourceEncoding) => {
  46. if (data.length === 0) {
  47. return ''
  48. }
  49. if (typeof data === 'string') {
  50. data = Buffer.from(data, sourceEncoding)
  51. }
  52. return data.utf8Slice(0, data.length)
  53. },
  54. latin1: (data, sourceEncoding) => {
  55. if (data.length === 0) {
  56. return ''
  57. }
  58. if (typeof data === 'string') {
  59. return data
  60. }
  61. return data.latin1Slice(0, data.length)
  62. },
  63. utf16le: (data, sourceEncoding) => {
  64. if (data.length === 0) {
  65. return ''
  66. }
  67. if (typeof data === 'string') {
  68. data = Buffer.from(data, sourceEncoding)
  69. }
  70. return data.ucs2Slice(0, data.length)
  71. },
  72. base64: (data, sourceEncoding) => {
  73. if (data.length === 0) {
  74. return ''
  75. }
  76. if (typeof data === 'string') {
  77. data = Buffer.from(data, sourceEncoding)
  78. }
  79. return data.base64Slice(0, data.length)
  80. },
  81. other: (data, sourceEncoding) => {
  82. if (data.length === 0) {
  83. return ''
  84. }
  85. if (typeof data === 'string') {
  86. data = Buffer.from(data, sourceEncoding)
  87. }
  88. if (textDecoders.has(this.toString())) {
  89. try {
  90. return textDecoders.get(this).decode(data)
  91. } catch {}
  92. }
  93. return typeof data === 'string'
  94. ? data
  95. : data.toString()
  96. }
  97. }
  98. function decodeText (text, sourceEncoding, destEncoding) {
  99. if (text) {
  100. return getDecoder(destEncoding)(text, sourceEncoding)
  101. }
  102. return text
  103. }
  104. module.exports = decodeText