@tgsnake/fileid
Version:
core framework for tgsnake for generating file id
243 lines • 8.67 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mod = exports.Reader = exports.Writer = exports.rle_decode = exports.rle_encode = exports.base64urlTobase64 = exports.base64_url_decode = exports.base64_url_encode = exports.DOCUMENT_TYPES = exports.PHOTO_TYPES = exports.FileTypeUniqueId = exports.ThumbnailSource = exports.FileType = void 0;
/**
* tgsnake - Telegram MTProto framework for nodejs.
* Copyright (C) 2022 butthx <https://github.com/butthx>
*
* THIS FILE IS PART OF TGSNAKE
*
* tgsnake is a free software : you can redistribute it and/or modify
* it under the terms of the MIT License as published.
*/
const node_buffer_1 = require("node:buffer");
var FileType;
(function (FileType) {
FileType[FileType["THUMBNAIL"] = 0] = "THUMBNAIL";
FileType[FileType["CHAT_PHOTO"] = 1] = "CHAT_PHOTO";
FileType[FileType["PHOTO"] = 2] = "PHOTO";
FileType[FileType["VOICE"] = 3] = "VOICE";
FileType[FileType["VIDEO"] = 4] = "VIDEO";
FileType[FileType["DOCUMENT"] = 5] = "DOCUMENT";
FileType[FileType["ENCRYPTED"] = 6] = "ENCRYPTED";
FileType[FileType["TEMP"] = 7] = "TEMP";
FileType[FileType["STICKER"] = 8] = "STICKER";
FileType[FileType["AUDIO"] = 9] = "AUDIO";
FileType[FileType["ANIMATION"] = 10] = "ANIMATION";
FileType[FileType["ENCRYPTED_THUMBNAIL"] = 11] = "ENCRYPTED_THUMBNAIL";
FileType[FileType["WALLPAPER"] = 12] = "WALLPAPER";
FileType[FileType["VIDEO_NOTE"] = 13] = "VIDEO_NOTE";
FileType[FileType["SECURE_RAW"] = 14] = "SECURE_RAW";
FileType[FileType["SECURE"] = 15] = "SECURE";
FileType[FileType["BACKGROUND"] = 16] = "BACKGROUND";
FileType[FileType["DOCUMENT_AS_FILE"] = 17] = "DOCUMENT_AS_FILE";
// InternalOnly! Don't pass with this!!
FileType[FileType["WEB_LOCATION_FLAG"] = 16777216] = "WEB_LOCATION_FLAG";
FileType[FileType["FILE_REFERENCE_FLAG"] = 33554432] = "FILE_REFERENCE_FLAG";
})(FileType = exports.FileType || (exports.FileType = {}));
var ThumbnailSource;
(function (ThumbnailSource) {
ThumbnailSource[ThumbnailSource["LEGACY"] = 0] = "LEGACY";
ThumbnailSource[ThumbnailSource["THUMBNAIL"] = 1] = "THUMBNAIL";
ThumbnailSource[ThumbnailSource["CHAT_PHOTO_SMALL"] = 2] = "CHAT_PHOTO_SMALL";
ThumbnailSource[ThumbnailSource["CHAT_PHOTO_BIG"] = 3] = "CHAT_PHOTO_BIG";
ThumbnailSource[ThumbnailSource["STICKER_SET_THUMBNAIL"] = 4] = "STICKER_SET_THUMBNAIL";
})(ThumbnailSource = exports.ThumbnailSource || (exports.ThumbnailSource = {}));
var FileTypeUniqueId;
(function (FileTypeUniqueId) {
FileTypeUniqueId[FileTypeUniqueId["WEB"] = 0] = "WEB";
FileTypeUniqueId[FileTypeUniqueId["PHOTO"] = 1] = "PHOTO";
FileTypeUniqueId[FileTypeUniqueId["DOCUMENT"] = 2] = "DOCUMENT";
FileTypeUniqueId[FileTypeUniqueId["SECURE"] = 3] = "SECURE";
FileTypeUniqueId[FileTypeUniqueId["ENCRYPTED"] = 4] = "ENCRYPTED";
FileTypeUniqueId[FileTypeUniqueId["TEMP"] = 5] = "TEMP";
})(FileTypeUniqueId = exports.FileTypeUniqueId || (exports.FileTypeUniqueId = {}));
exports.PHOTO_TYPES = [
FileType.THUMBNAIL,
FileType.CHAT_PHOTO,
FileType.PHOTO,
FileType.WALLPAPER,
FileType.ENCRYPTED_THUMBNAIL,
];
exports.DOCUMENT_TYPES = [
FileType.VOICE,
FileType.VIDEO,
FileType.DOCUMENT,
FileType.ENCRYPTED,
FileType.TEMP,
FileType.STICKER,
FileType.AUDIO,
FileType.ANIMATION,
FileType.VIDEO_NOTE,
FileType.SECURE_RAW,
FileType.SECURE,
FileType.BACKGROUND,
FileType.DOCUMENT_AS_FILE,
];
function base64_url_encode(base) {
return typeof base === 'string'
? node_buffer_1.Buffer.from(base).toString('base64url')
: base.toString('base64url');
}
exports.base64_url_encode = base64_url_encode;
function base64_url_decode(base) {
return typeof base === 'string' ? node_buffer_1.Buffer.from(base64urlTobase64(base), 'base64') : base;
}
exports.base64_url_decode = base64_url_decode;
function base64urlTobase64(text) {
const pad = text.length % 4;
if (pad === 1) {
throw new Error('Invalid base64url');
}
return (pad === 2 || pad === 3 ? text.padEnd(4 - pad, '=') : text)
.replace(/\-/g, '+')
.replace(/_/g, '/');
}
exports.base64urlTobase64 = base64urlTobase64;
function rle_encode(base) {
let buffer = typeof base === 'string' ? node_buffer_1.Buffer.from(base) : base;
let r = [];
let n = 0;
for (let b of buffer) {
if (!b) {
n++;
}
else {
if (n) {
r.push(0, n);
n = 0;
}
r.push(b);
}
}
if (n) {
r.push(0, n);
}
const res = node_buffer_1.Buffer.from(r);
return res;
}
exports.rle_encode = rle_encode;
function rle_decode(base) {
let buffer = typeof base === 'string' ? node_buffer_1.Buffer.from(base) : base;
let r = [];
let z = false;
for (let b of buffer) {
if (!b) {
z = true;
continue;
}
if (z) {
for (let i = 0; i < b; i++) {
r.push(0);
}
z = false;
}
else {
r.push(b);
}
}
return node_buffer_1.Buffer.from(r);
}
exports.rle_decode = rle_decode;
class Writer {
constructor() {
this.buffer = node_buffer_1.Buffer.alloc(0);
}
writeInt(int) {
const buf = node_buffer_1.Buffer.alloc(4);
buf.writeInt32LE(int);
this.buffer = node_buffer_1.Buffer.concat([this.buffer, buf]);
return this;
}
writeBigInt(int) {
this.buffer = node_buffer_1.Buffer.concat([this.buffer, packLong(BigInt.asUintN(64, int))]);
return this;
}
writeString(str) {
return this.writeBuffer(node_buffer_1.Buffer.from(str, 'utf8'));
}
writeBuffer(buffer) {
const length = buffer.length;
let buf = node_buffer_1.Buffer.alloc(0);
if (length <= 253) {
buf = node_buffer_1.Buffer.concat([node_buffer_1.Buffer.from([length]), buffer, node_buffer_1.Buffer.alloc(mod(-(length + 1), 4))]);
}
else {
buf = node_buffer_1.Buffer.concat([
node_buffer_1.Buffer.from([254]),
node_buffer_1.Buffer.from([length & 0xff]),
node_buffer_1.Buffer.from([(length >> 8) & 0xff]),
node_buffer_1.Buffer.from([(length >> 16) & 0xff]),
buffer,
node_buffer_1.Buffer.alloc(mod(-length, 4)),
]);
}
this.buffer = node_buffer_1.Buffer.concat([this.buffer, buf]);
return this;
}
results() {
return this.buffer;
}
}
exports.Writer = Writer;
class Reader {
constructor(buffer) {
this.buffer = buffer;
this.start = 0;
this.cur = this.start;
}
readInt() {
const res = this.buffer.readInt32LE(this.cur);
this.cur += 4;
return res;
}
readBigInt(signed = true) {
let res = BigInt(`0x${this.buffer
.slice(this.cur, this.cur + 8)
.reverse()
.toString('hex')}`);
this.cur += 8;
return BigInt.asIntN(64, res);
}
readString() {
return this.readBuffer().toString('utf8');
}
readBuffer() {
const firstBuff = this.buffer[this.cur++];
let length, padding;
if (firstBuff === 254) {
length =
this.buffer[this.cur++] | (this.buffer[this.cur++] << 8) | (this.buffer[this.cur++] << 16);
padding = mod(-length, 4);
}
else {
length = firstBuff;
padding = mod(-(length + 1), 4);
}
const data = this.buffer.slice(this.cur, (this.cur += length === -1 ? this.buffer.length - this.cur : length));
if (padding > 0)
this.cur += 4 - padding;
return data;
}
}
exports.Reader = Reader;
function packLong(long, little = true, signed = false) {
const bytes = node_buffer_1.Buffer.alloc(8);
const shift = BigInt((1 << 16) * (1 << 16));
if (signed) {
bytes.writeInt32LE(Number(String(long % shift)), 0);
bytes.writeInt32LE(Number(String(long / shift)), 4);
return little ? bytes : bytes.reverse();
}
else {
bytes.writeUInt32LE(Number(String(long % shift)), 0);
bytes.writeUInt32LE(Number(String(long / shift)), 4);
return little ? bytes : bytes.reverse();
}
}
// https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers
function mod(n, m) {
return ((n % m) + m) % m;
}
exports.mod = mod;
//# sourceMappingURL=utils.js.map