@gandlaf21/bc-ur
Version:
A JS implementation of the Uniform Resources (UR) specification from Blockchain Commons
139 lines • 5.29 kB
JavaScript
import FountainDecoder from './fountainDecoder';
import bytewords from './bytewords';
import { isURType, toUint32 } from './utils';
import { InvalidSchemeError, InvalidPathLengthError, InvalidTypeError, InvalidSequenceComponentError } from './errors';
import UR from './ur';
import { FountainEncoderPart } from './fountainEncoder';
import { Buffer } from "buffer";
var URDecoder = /** @class */ (function () {
function URDecoder(fountainDecoder, type) {
if (fountainDecoder === void 0) { fountainDecoder = new FountainDecoder(); }
if (type === void 0) { type = 'bytes'; }
this.fountainDecoder = fountainDecoder;
this.type = type;
if (!isURType(type)) {
throw new Error("Invalid UR type");
}
this.expected_type = '';
}
URDecoder.decodeBody = function (type, message) {
var cbor = bytewords.decode(message, bytewords.STYLES.MINIMAL);
return new UR(Buffer.from(cbor, 'hex'), type);
};
URDecoder.prototype.validatePart = function (type) {
if (this.expected_type) {
return this.expected_type === type;
}
if (!isURType(type)) {
return false;
}
this.expected_type = type;
return true;
};
URDecoder.decode = function (message) {
var _a = this.parse(message), type = _a[0], components = _a[1];
if (components.length === 0) {
throw new InvalidPathLengthError();
}
var body = components[0];
return URDecoder.decodeBody(type, body);
};
URDecoder.parse = function (message) {
var lowercase = message.toLowerCase();
var prefix = lowercase.slice(0, 3);
if (prefix !== 'ur:') {
throw new InvalidSchemeError();
}
var components = lowercase.slice(3).split('/');
var type = components[0];
if (components.length < 2) {
throw new InvalidPathLengthError();
}
if (!isURType(type)) {
throw new InvalidTypeError();
}
return [type, components.slice(1)];
};
URDecoder.parseSequenceComponent = function (s) {
var components = s.split('-');
if (components.length !== 2) {
throw new InvalidSequenceComponentError();
}
var seqNum = toUint32(Number(components[0]));
var seqLength = Number(components[1]);
if (seqNum < 1 || seqLength < 1) {
throw new InvalidSequenceComponentError();
}
return [seqNum, seqLength];
};
URDecoder.prototype.receivePart = function (s) {
if (this.result !== undefined) {
return false;
}
var _a = URDecoder.parse(s), type = _a[0], components = _a[1];
if (!this.validatePart(type)) {
return false;
}
// If this is a single-part UR then we're done
if (components.length === 1) {
this.result = URDecoder.decodeBody(type, components[0]);
return true;
}
if (components.length !== 2) {
throw new InvalidPathLengthError();
}
var seq = components[0], fragment = components[1];
var _b = URDecoder.parseSequenceComponent(seq), seqNum = _b[0], seqLength = _b[1];
var cbor = bytewords.decode(fragment, bytewords.STYLES.MINIMAL);
var part = FountainEncoderPart.fromCBOR(cbor);
if (seqNum !== part.seqNum || seqLength !== part.seqLength) {
return false;
}
if (!this.fountainDecoder.receivePart(part)) {
return false;
}
if (this.fountainDecoder.isSuccess()) {
this.result = new UR(this.fountainDecoder.resultMessage(), type);
}
else if (this.fountainDecoder.isFailure()) {
this.error = new InvalidSchemeError();
}
return true;
};
URDecoder.prototype.resultUR = function () {
return this.result ? this.result : new UR(Buffer.from([]));
};
URDecoder.prototype.isComplete = function () {
return this.result && this.result.cbor.length > 0 ? true : false;
};
URDecoder.prototype.isSuccess = function () {
return !this.error && this.isComplete();
};
URDecoder.prototype.isError = function () {
return this.error !== undefined;
};
URDecoder.prototype.resultError = function () {
return this.error ? this.error.message : '';
};
URDecoder.prototype.expectedPartCount = function () {
return this.fountainDecoder.expectedPartCount();
};
URDecoder.prototype.expectedPartIndexes = function () {
return this.fountainDecoder.getExpectedPartIndexes();
};
URDecoder.prototype.receivedPartIndexes = function () {
return this.fountainDecoder.getReceivedPartIndexes();
};
URDecoder.prototype.lastPartIndexes = function () {
return this.fountainDecoder.getLastPartIndexes();
};
URDecoder.prototype.estimatedPercentComplete = function () {
return this.fountainDecoder.estimatedPercentComplete();
};
URDecoder.prototype.getProgress = function () {
return this.fountainDecoder.getProgress();
};
return URDecoder;
}());
export default URDecoder;
//# sourceMappingURL=urDecoder.js.map