ConvertFb2.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. const ConvertBase = require('./ConvertBase');
  2. const iconv = require('iconv-lite');
  3. const textUtils = require('./textUtils');
  4. class ConvertFb2 extends ConvertBase {
  5. check(data, opts) {
  6. const {dataType} = opts;
  7. return (dataType && dataType.ext == 'xml' && data.toString().indexOf('<FictionBook') >= 0);
  8. }
  9. async run(data, opts) {
  10. let newData = data;
  11. //Корректируем кодировку, 16-битные кодировки должны стать utf-8
  12. const encoding = textUtils.getEncoding(newData);
  13. if (encoding.indexOf('UTF-16') == 0) {
  14. newData = Buffer.from(iconv.decode(newData, encoding));
  15. }
  16. if (!this.check(newData, opts))
  17. return false;
  18. return this.checkEncoding(newData);
  19. }
  20. checkEncoding(data) {
  21. let result = data;
  22. let q = '"';
  23. let left = data.indexOf('<?xml version="1.0"');
  24. if (left < 0) {
  25. left = data.indexOf('<?xml version=\'1.0\'');
  26. q = '\'';
  27. }
  28. if (left >= 0) {
  29. const right = data.indexOf('?>', left);
  30. if (right >= 0) {
  31. const head = data.slice(left, right + 2).toString();
  32. const m = head.match(/encoding=['"](.*?)['"]/);
  33. if (m) {
  34. let encoding = m[1].toLowerCase();
  35. if (encoding != 'utf-8') {
  36. //encoding может не соответсвовать реальной кодировке файла, поэтому:
  37. let calcEncoding = textUtils.getEncoding(data);
  38. if (calcEncoding.indexOf('ISO-8859') >= 0) {
  39. calcEncoding = encoding;
  40. }
  41. result = iconv.decode(data, calcEncoding);
  42. result = Buffer.from(result.toString().replace(m[0], `encoding=${q}utf-8${q}`));
  43. }
  44. }
  45. }
  46. }
  47. return result;
  48. }
  49. }
  50. module.exports = ConvertFb2;