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!
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
2.8KB

  1. class CMDirectory {
  2. constructor() {
  3. this.directories = {};
  4. this.files = {};
  5. }
  6. }
  7. class CMFile {
  8. constructor() {
  9. this.blockRefs = [];
  10. this.size = 0;
  11. }
  12. append(locators, position, size) {
  13. if (size === 0)
  14. return;
  15. let cum = 0;
  16. let locHashes = locators.map(loc => loc[0]);
  17. let locSizes = locators.map(loc => loc[1]);
  18. let locPositions = locators.map(loc => {
  19. let res = cum;
  20. cum += loc[1];
  21. return res;
  22. });
  23. let used = locators.map((_, i) => (locPositions[i] + locSizes[i] > position &&
  24. locPositions[i] < position + size));
  25. let startBlock = used.indexOf(true);
  26. let endBlock = used.lastIndexOf(true) + 1;
  27. console.log('startBlock: ' + startBlock + ', endBlock: ' + endBlock);
  28. if (startBlock === -1)
  29. return;
  30. let blockRefs = [];
  31. let runPos = position;
  32. let runSize = size;
  33. for (let i = startBlock; i < endBlock; i++) {
  34. let blockPos = runPos - locPositions[i];
  35. let blockSize = Math.min(runSize, locSizes[i] - blockPos);
  36. blockRefs.push([ locHashes[i], blockPos, blockSize ]);
  37. runPos += blockSize;
  38. runSize -= blockSize;
  39. }
  40. this.blockRefs = this.blockRefs.concat(blockRefs);
  41. this.size += size;
  42. }
  43. }
  44. class WBManifestReader {
  45. constructor(manifest_text) {
  46. this.rootDir = new CMDirectory();
  47. if (!manifest_text)
  48. return;
  49. this.parse(manifest_text);
  50. }
  51. makeDir(parent, name) {
  52. if (!(name in parent.directories))
  53. parent.directories[name] = new CMDirectory();
  54. return parent.directories[name];
  55. }
  56. makePath(path) {
  57. if (typeof(path) === 'string')
  58. path = path.split('/');
  59. let dir = this.rootDir;
  60. for (let i = 1; i < path.length; i++)
  61. dir = this.makeDir(dir, path[i]);
  62. return dir;
  63. }
  64. appendFile(streamName, locators, position, size, fileName) {
  65. let path = streamName + '/' + fileName;
  66. path = path.split('/');
  67. let dir = this.makePath(path.slice(0, path.length - 1));
  68. if (!(fileName in dir.files))
  69. dir.files[fileName] = new CMFile();
  70. dir.files[fileName].append(locators, position, size);
  71. }
  72. parse(manifest_text) {
  73. let rx = /^[a-f0-9]{32}\+[0-9]+/;
  74. let streams = manifest_text.split('\n');
  75. streams.map(s => {
  76. let tokens = s.split(' ');
  77. let streamName = tokens[0];
  78. let n = tokens.map(t => rx.exec(t));
  79. n = n.indexOf(null, 1);
  80. let locators = tokens.slice(1, n);
  81. locators = locators.map(loc => [ loc, Number(loc.split('+')[1]) ]);
  82. let fileTokens = tokens.slice(n);
  83. fileTokens.map(t => {
  84. let [ position, size, fileName ] = t.split(':');
  85. this.appendFile(streamName, locators,
  86. Number(position), Number(size), fileName);
  87. });
  88. });
  89. }
  90. }
  91. export { WBManifestReader };