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!
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

141 lignes
3.5KB

  1. const rx = /^[a-f0-9]{32}\+[0-9]+/;
  2. const rootDir = {};
  3. const streams = [];
  4. onmessage = function(e) {
  5. switch (e.data[0]) {
  6. case 'precreatePaths':
  7. precreatePaths(e.data[1]);
  8. postMessage([ 'precreatePathsResult' ]);
  9. break;
  10. case 'parseStream':
  11. parseStream(e.data[1]);
  12. postMessage([ 'parseStreamResult' ]);
  13. break;
  14. case 'listDirectory': {
  15. const lst = listDirectory(rootDir, e.data[1], e.data[2]);
  16. postMessage([ 'listDirectoryResult', lst ])
  17. break; }
  18. default:
  19. throw Error('Unknown verb: ' + e.data[0]);
  20. }
  21. }
  22. function precreatePaths(paths) {
  23. for (let i = 0; i < paths.length; i++) {
  24. mkpath(rootDir, paths[i]);
  25. }
  26. }
  27. function parseStream(s) {
  28. if (!s) return;
  29. const tokens = s.split(' ');
  30. const streamName = unescapeName(tokens[0]);
  31. let n = tokens.map(t => rx.exec(t));
  32. n = n.indexOf(null, 1);
  33. let locators = tokens.slice(1, n);
  34. let pos = 0;
  35. locators = locators.map(loc => {
  36. const sz = parseInt(loc.split('+')[1], 10);
  37. return [ loc, pos, pos += sz ];
  38. });
  39. let fileTokens = tokens.slice(n);
  40. let lastFile = null;
  41. let lastPath = null;
  42. fileTokens.map(t => {
  43. let seg = t.split(':');
  44. seg = [ parseInt(seg[0], 10), parseInt(seg[1], 10),
  45. unescapeName(seg.slice(2).join(':')) ]
  46. const path = streamName + '/' + seg[2];
  47. let f;
  48. if (path === lastPath) {
  49. f = lastFile;
  50. } else {
  51. let dirName = path.split('/');
  52. const name = dirName[dirName.length - 1];
  53. dirName = dirName.slice(0, dirName.length - 1);
  54. const d = mkpath(rootDir, dirName);
  55. lastFile = f = makeFile(d, name);
  56. lastPath = path;
  57. }
  58. appendFile(f, streams.length, seg);
  59. });
  60. streams.push(locators);
  61. }
  62. function mkdir(parent, name) {
  63. if (name in parent && (parent[name] instanceof Array))
  64. throw Error('File with the same name already exists');
  65. if (name in parent)
  66. return parent[name];
  67. const dir = {};
  68. parent[name] = dir;
  69. return dir;
  70. }
  71. function mkpath(parent, path) {
  72. if (typeof(path) === 'string')
  73. path = path.split('/');
  74. let dir = parent;
  75. for (let i = 1; i < path.length; i++) {
  76. dir = mkdir(dir, path[i]);
  77. }
  78. return dir;
  79. }
  80. function makeFile(dir, name) {
  81. if (name in dir) {
  82. if (!(dir[name] instanceof Array))
  83. throw Error('Directory with the same name already exists');
  84. return dir[name];
  85. }
  86. const f = [[], 0];
  87. dir[name] = f;
  88. return f;
  89. }
  90. function appendFile(f, sidx, seg) {
  91. f[0].push([ sidx, seg[0], seg[1] ]);
  92. f[1] += seg[1];
  93. return f;
  94. }
  95. function unescapeName(name) {
  96. return name.replace(/(\\\\|\\[0-9]{3})/g,
  97. (_, $1) => ($1 === '\\\\' ? '\\' : String.fromCharCode(parseInt($1.substr(1), 8))));
  98. }
  99. function findDir(parent, path, lenient=false) {
  100. if (typeof(path) === 'string')
  101. path = path.split('/');
  102. if (path[0] !== '.')
  103. throw Error('Path must start with a dot (.)');
  104. let dir = parent;
  105. for (let i = 1; i < path.length; i++) {
  106. if (!(path[i] in dir)) {
  107. if (lenient)
  108. return {};
  109. else
  110. throw Error('Directory not found');
  111. }
  112. dir = dir[path[i]];
  113. }
  114. return dir;
  115. }
  116. function listDirectory(rootDir, path, lenient=false) {
  117. let dir = findDir(rootDir, path, lenient);
  118. let keys = Object.keys(dir);
  119. keys.sort();
  120. let subdirs = keys.filter(k => !(dir[k] instanceof Array));
  121. let files = keys.filter(k => (dir[k] instanceof Array));
  122. let res = subdirs.map(k => [ 'd', k, null ]);
  123. res = res.concat(files.map(k => [ 'f', k, dir[k][1] ]));
  124. return res;
  125. }