ConvertFb2.js 2.1 KB

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