telegram-mtproto
Version:
Telegram MTProto library
194 lines (166 loc) • 4.88 kB
JavaScript
import { isNode } from '../runtime';
import Logger from 'mtproto-logger';
var log = Logger('tl', 'type-buffer');
// import { immediate } from 'mtproto-shared'
import { TypeBufferIntError } from '../error';
// import { bigint, uintToInt, intToUint, bytesToHex,
// gzipUncompress, bytesToArrayBuffer, longToInts, lshift32 } from '../bin'
function findType(val) {
return val.type == this;
}
function findPred(val) {
return val.predicate == this;
}
function findId(val) {
return val.id == this;
}
export var getNakedType = (type, schema) => {
var checkType = type.substr(1);
var result = schema.constructors.find(findType, checkType);
if (!result) throw new Error(`Constructor not found for type: ${type}`);
return result;
};
export var getPredicate = (type, schema) => {
var result = schema.constructors.find(findPred, type);
if (!result) throw new Error(`Constructor not found for predicate: ${type}`);
return result;
};
export var getTypeConstruct = (construct, schema) => schema.constructors.find(findId, construct);
var getChar = e => String.fromCharCode(e);
export var getString = (length, buffer) => {
var bytes = buffer.next(length);
var result = [...bytes].map(getChar).join('');
buffer.addPadding();
return result;
};
var countNewLength = (maxLength, need, offset) => {
var max = Math.max(maxLength * 2, offset + need + 16) / 4;
var rounded = Math.ceil(max) * 4;
return rounded;
};
// const writeIntLogger = log('writeInt')
// const writeIntLog = (i: number, field: string) => {
// const hex = i && i.toString(16) || 'UNDEF'
// writeIntLogger(hex, i, field)
// }
export class TypeWriter {
// in bytes
constructor() /*startMaxLength: number*/{
// this.maxLength = startMaxLength
// this.reset()
this.offset = 0;
}
reset() {
this.buffer = new ArrayBuffer(this.maxLength);
this.intView = new Int32Array(this.buffer);
this.byteView = new Uint8Array(this.buffer);
}
set(list, length) {
this.byteView.set(list, this.offset);
this.offset += length;
}
next(data) {
this.byteView[this.offset] = data;
this.offset++;
}
checkLength(needBytes) {
if (this.offset + needBytes < this.maxLength) {
return;
}
log('Increase buffer')(this.offset, needBytes, this.maxLength);
this.maxLength = countNewLength(this.maxLength, needBytes, this.offset);
var previousBuffer = this.buffer;
var previousArray = new Int32Array(previousBuffer);
this.reset();
new Int32Array(this.buffer).set(previousArray);
}
getArray() {
var resultBuffer = new ArrayBuffer(this.offset);
var resultArray = new Int32Array(resultBuffer);
resultArray.set(this.intView.subarray(0, this.offset / 4));
return resultArray;
}
getBuffer() {
return this.getArray().buffer;
}
getBytesTyped() {
var resultBuffer = new ArrayBuffer(this.offset);
var resultArray = new Uint8Array(resultBuffer);
resultArray.set(this.byteView.subarray(0, this.offset));
return resultArray;
}
getBytesPlain() {
return Array.from(this.byteView.subarray(0, this.offset));
}
writeInt(i, field) {
// immediate(writeIntLog, i, field)
this.checkLength(4);
this.intView[this.offset / 4] = i;
this.offset += 4;
}
writePair(n1, n2, field1, field2) {
this.writeInt(n1, field1);
this.writeInt(n2, field2);
}
addPadding() {
while (this.offset % 4) {
this.next(0);
}
}
}
export class TypeBuffer {
constructor(buffer) {
this.offset = 0;
this.buffer = buffer;
this.intView = toUint32(buffer);
this.byteView = new Uint8Array(buffer);
}
nextByte() {
return this.byteView[this.offset++];
}
nextInt() {
if (this.offset >= this.intView.length * 4) throw new TypeBufferIntError(this);
var int = this.intView[this.offset / 4];
this.offset += 4;
return int;
}
readPair() {
var int1 = this.nextInt();
var int2 = this.nextInt();
return [int1, int2];
}
next(length) {
var result = this.byteView.subarray(this.offset, this.offset + length);
this.offset += length;
return result;
}
isEnd() {
return this.offset === this.byteView.length;
}
addPadding() {
var offset = this.offset % 4;
if (offset > 0) this.offset += 4 - offset;
}
}
function toUint32(buf) {
var ln = void 0,
res = void 0;
if (!isNode) //TODO browser behavior not equals, why?
return new Uint32Array(buf);
if (buf instanceof Buffer) {
ln = buf.byteLength / 4;
res = new Uint32Array(ln);
for (var i = 0; i < ln; i++) {
res[i] = buf.readUInt32LE(i * 4);
}
} else {
var data = new DataView(buf);
ln = data.byteLength / 4;
res = new Uint32Array(ln);
for (var _i = 0; _i < ln; _i++) {
res[_i] = data.getUint32(_i * 4, true);
}
}
return res;
}
//# sourceMappingURL=type-buffer.js.map