IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.5KB

  1. //
  2. // Copyright (C) Stanislaw Adaszewski, 2020
  3. // Contact: s.adaszewski@gmail.com
  4. // Website: https://adared.ch/wba
  5. // License: GNU Affero General Public License, Version 3
  6. //
  7. class WBRootDirWrapper {
  8. constructor(rootDir, streams) {
  9. this.rootDir = rootDir;
  10. this.streams = streams;
  11. }
  12. findDir(path) {
  13. if (typeof(path) === 'string')
  14. path = path.split('/');
  15. if (path[0] !== '.')
  16. throw Error('Path must begin with a dot component');
  17. let dir = this.rootDir;
  18. for (let i = 1; i < path.length; i++) {
  19. if (!(path[i] in dir))
  20. throw Error('Directory not found');
  21. if (dir[path[i]] instanceof Array)
  22. throw Error('Path is a file not directory');
  23. dir = dir[path[i]];
  24. }
  25. return dir;
  26. }
  27. listDirectory(path) {
  28. let dir = this.findDir(path);
  29. let keys = Object.keys(dir);
  30. keys.sort();
  31. let subdirs = keys.filter(k => !(dir[k] instanceof Array));
  32. let files = keys.filter(k => (dir[k] instanceof Array));
  33. let res = subdirs.map(k => [ 'd', k, null ]);
  34. res = res.concat(files.map(k => [ 'f', k, dir[k][1] ]));
  35. return res;
  36. }
  37. unescapeName(name) {
  38. return name.replace(/(\\\\|\\[0-9]{3})/g, (_, $1) => ($1 === '\\\\' ? '\\' : String.fromCharCode(parseInt($1.substr(1), 8))));
  39. }
  40. escapeName(name) {
  41. return name.replace(/ /g, '\\040');
  42. }
  43. getFile(path) {
  44. if (typeof(path) === 'string')
  45. path = path.split('/');
  46. if (path.length < 2)
  47. throw Error('Invalid file path');
  48. const name = path[path.length - 1];
  49. const dir = this.findDir(path.slice(0, path.length - 1));
  50. if (!(name in dir))
  51. throw Error('File not found');
  52. if (!(dir[name] instanceof Array))
  53. throw Error('Path points to a directory not a file');
  54. const streams = this.streams;
  55. let file = dir[name];
  56. file = [ file[0].map(seg => {
  57. const stm = streams[seg[0]];
  58. const used = stm.map(loc => !( loc[2] <= seg[1] || loc[1] >= seg[1] + seg[2] ) );
  59. const start = used.indexOf(true);
  60. const end = used.lastIndexOf(true) + 1;
  61. if (start === -1)
  62. return [];
  63. const res = [];
  64. for (let i = start; i < end; i++) {
  65. const loc = stm[i];
  66. res.push([ loc[0], Math.max(0, seg[1] - loc[1]),
  67. Math.min(loc[2] - loc[1], seg[1] + seg[2] - loc[1]) ]);
  68. }
  69. return res;
  70. }), file[1] ];
  71. file[0] = file[0].reduce((a, b) => a.concat(b));
  72. return file;
  73. }
  74. }
  75. export default WBRootDirWrapper;