|
- class CMDirectory {
- constructor() {
- this.directories = {};
- this.files = {};
- }
- }
-
- class CMFile {
- constructor() {
- this.blockRefs = [];
- this.size = 0;
- }
-
- append(locators, position, size) {
- if (size === 0)
- return;
-
- let cum = 0;
- let locHashes = locators.map(loc => loc[0]);
- let locSizes = locators.map(loc => loc[1]);
- let locPositions = locators.map(loc => {
- let res = cum;
- cum += loc[1];
- return res;
- });
-
- let used = locators.map((_, i) => (locPositions[i] + locSizes[i] > position &&
- locPositions[i] < position + size));
-
- let startBlock = used.indexOf(true);
- let endBlock = used.lastIndexOf(true) + 1;
-
- console.log('startBlock: ' + startBlock + ', endBlock: ' + endBlock);
-
- if (startBlock === -1)
- return;
-
- let blockRefs = [];
- let runPos = position;
- let runSize = size;
-
- for (let i = startBlock; i < endBlock; i++) {
- let blockPos = runPos - locPositions[i];
- let blockSize = Math.min(runSize, locSizes[i] - blockPos);
- blockRefs.push([ locHashes[i], blockPos, blockSize ]);
- runPos += blockSize;
- runSize -= blockSize;
- }
-
- this.blockRefs = this.blockRefs.concat(blockRefs);
- this.size += size;
- }
- }
-
- class WBManifestReader {
- constructor(manifest_text) {
- this.rootDir = new CMDirectory();
-
- if (!manifest_text)
- return;
-
- this.parse(manifest_text);
- }
-
- makeDir(parent, name) {
- if (!(name in parent.directories))
- parent.directories[name] = new CMDirectory();
- return parent.directories[name];
- }
-
- makePath(path) {
- if (typeof(path) === 'string')
- path = path.split('/');
- let dir = this.rootDir;
- for (let i = 1; i < path.length; i++)
- dir = this.makeDir(dir, path[i]);
- return dir;
- }
-
- appendFile(streamName, locators, position, size, fileName) {
- let path = streamName + '/' + fileName;
- path = path.split('/');
- let dir = this.makePath(path.slice(0, path.length - 1));
- if (!(fileName in dir.files))
- dir.files[fileName] = new CMFile();
- dir.files[fileName].append(locators, position, size);
- }
-
- parse(manifest_text) {
- let rx = /^[a-f0-9]{32}\+[0-9]+/;
-
- let streams = manifest_text.split('\n');
-
- streams.map(s => {
- let tokens = s.split(' ');
- let streamName = tokens[0];
-
- let n = tokens.map(t => rx.exec(t));
- n = n.indexOf(null, 1);
-
- let locators = tokens.slice(1, n);
- locators = locators.map(loc => [ loc, Number(loc.split('+')[1]) ]);
-
- let fileTokens = tokens.slice(n);
- fileTokens.map(t => {
- let [ position, size, fileName ] = t.split(':');
- this.appendFile(streamName, locators,
- Number(position), Number(size), fileName);
- });
- });
- }
- }
-
- export { WBManifestReader };
|