Fix serializing negative longs
Parse JSONValue
This commit is contained in:
parent
04ae258f7a
commit
f6f35f4b70
2
src/layer.d.ts
vendored
2
src/layer.d.ts
vendored
@ -13015,7 +13015,7 @@ export interface MethodDeclMap {
|
|||||||
'help.getTermsOfServiceUpdate': {req: HelpGetTermsOfServiceUpdate, res: HelpTermsOfServiceUpdate},
|
'help.getTermsOfServiceUpdate': {req: HelpGetTermsOfServiceUpdate, res: HelpTermsOfServiceUpdate},
|
||||||
'help.acceptTermsOfService': {req: HelpAcceptTermsOfService, res: boolean},
|
'help.acceptTermsOfService': {req: HelpAcceptTermsOfService, res: boolean},
|
||||||
'help.getDeepLinkInfo': {req: HelpGetDeepLinkInfo, res: HelpDeepLinkInfo},
|
'help.getDeepLinkInfo': {req: HelpGetDeepLinkInfo, res: HelpDeepLinkInfo},
|
||||||
'help.getAppConfig': {req: HelpGetAppConfig, res: JSONValue},
|
'help.getAppConfig': {req: HelpGetAppConfig, res: any},
|
||||||
'help.saveAppLog': {req: HelpSaveAppLog, res: boolean},
|
'help.saveAppLog': {req: HelpSaveAppLog, res: boolean},
|
||||||
'help.getPassportConfig': {req: HelpGetPassportConfig, res: HelpPassportConfig},
|
'help.getPassportConfig': {req: HelpGetPassportConfig, res: HelpPassportConfig},
|
||||||
'help.getSupportName': {req: HelpGetSupportName, res: HelpSupportName},
|
'help.getSupportName': {req: HelpGetSupportName, res: HelpSupportName},
|
||||||
|
@ -9,17 +9,29 @@
|
|||||||
* https://github.com/zhukov/webogram/blob/master/LICENSE
|
* https://github.com/zhukov/webogram/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { bytesToHex } from '../../helpers/bytes';
|
import { bytesFromHex, bytesToHex } from '../../helpers/bytes';
|
||||||
import { isObject, longFromInts } from './bin_utils';
|
import { addPadding, isObject, longFromInts } from './bin_utils';
|
||||||
import { MOUNT_CLASS_TO } from '../../config/debug';
|
import { MOUNT_CLASS_TO } from '../../config/debug';
|
||||||
import { str2bigInt, dup, divide_, bigInt2str } from '../../vendor/leemon';
|
import { str2bigInt, bigInt2str, int2bigInt, sub_ } from '../../vendor/leemon';
|
||||||
import Schema, { MTProtoConstructor } from './schema';
|
import Schema, { MTProtoConstructor } from './schema';
|
||||||
|
import { JSONValue } from '../../layer';
|
||||||
|
|
||||||
/// #if MTPROTO_WORKER
|
/// #if MTPROTO_WORKER
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { gzipUncompress } from '../crypto/crypto_utils';
|
import { gzipUncompress } from '../crypto/crypto_utils';
|
||||||
/// #endif
|
/// #endif
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
/* import {BigInteger} from 'jsbn';
|
||||||
|
|
||||||
|
export function bigint(num: number) {
|
||||||
|
return new BigInteger(num.toString(16), 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bigStringInt(strNum: string) {
|
||||||
|
return new BigInteger(strNum, 10)
|
||||||
|
} */
|
||||||
|
|
||||||
const boolFalse = +Schema.API.constructors.find(c => c.predicate === 'boolFalse').id;
|
const boolFalse = +Schema.API.constructors.find(c => c.predicate === 'boolFalse').id;
|
||||||
const boolTrue = +Schema.API.constructors.find(c => c.predicate === 'boolTrue').id;
|
const boolTrue = +Schema.API.constructors.find(c => c.predicate === 'boolTrue').id;
|
||||||
const vector = +Schema.API.constructors.find(c => c.predicate === 'vector').id;
|
const vector = +Schema.API.constructors.find(c => c.predicate === 'vector').id;
|
||||||
@ -155,28 +167,33 @@ class TLSerialization {
|
|||||||
sLong = sLong ? sLong.toString() : '0';
|
sLong = sLong ? sLong.toString() : '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
const R = 0x100000000;
|
/* let perf = performance.now();
|
||||||
//const divRem = bigStringInt(sLong).divideAndRemainder(bigint(R));
|
const jsbnBytes: Uint8Array = new Uint8Array(8);
|
||||||
|
const jsbnBigInt = bigStringInt(sLong);
|
||||||
|
for(let i = 0; i < 8; i++) {
|
||||||
|
jsbnBytes[i] = +jsbnBigInt.shiftRight(8 * i).and(bigint(255)).toString(10);
|
||||||
|
}
|
||||||
|
console.log('perf1', performance.now() - perf); */
|
||||||
|
|
||||||
const a = str2bigInt(sLong, 10, 64);
|
// perf = performance.now();
|
||||||
const q = dup(a);
|
let bigInt: number[];
|
||||||
const r = dup(a);
|
if(sLong[0] === '-') { // leemon library can't parse signed numbers
|
||||||
divide_(a, str2bigInt((R).toString(16), 16, 64), q, r);
|
bigInt = int2bigInt(0, 64, 8);
|
||||||
//divInt_(a, R);
|
sub_(bigInt, str2bigInt(sLong.slice(1), 10, 64));
|
||||||
|
} else {
|
||||||
const high = +bigInt2str(q, 10);
|
bigInt = str2bigInt(sLong, 10, 64);
|
||||||
let low = +bigInt2str(r, 10);
|
|
||||||
|
|
||||||
if(high < low) {
|
|
||||||
low -= R;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log('storeLong', sLong, divRem[0].intValue(), divRem[1].intValue(), high, low);
|
const hex = bigInt2str(bigInt, 16).slice(-16);
|
||||||
|
const bytes = addPadding(bytesFromHex(hex).reverse(), 8, true, true, false);
|
||||||
|
|
||||||
//this.writeInt(divRem[1].intValue(), (field || '') + ':long[low]');
|
// console.log('perf2', performance.now() - perf);
|
||||||
//this.writeInt(divRem[0].intValue(), (field || '') + ':long[high]');
|
|
||||||
this.writeInt(low, (field || '') + ':long[low]');
|
this.storeRawBytes(bytes);
|
||||||
this.writeInt(high, (field || '') + ':long[high]');
|
|
||||||
|
// if(jsbnBytes.hex !== bytes.hex) {
|
||||||
|
// console.error(bigInt, sLong, bigInt2str(bigInt, 10), negative(bigInt), jsbnBytes.hex, bigInt2str(bigInt, 16), bytes.hex);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public storeDouble(f: any, field?: string) {
|
public storeDouble(f: any, field?: string) {
|
||||||
@ -807,9 +824,32 @@ class TLDeserialization<FetchLongAs extends Long> {
|
|||||||
this.mtproto = true;
|
this.mtproto = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(type === 'JSONValue') {
|
||||||
|
return this.formatJSONValue(result);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private formatJSONValue(jsonValue: JSONValue): any {
|
||||||
|
if(!jsonValue._) return jsonValue;
|
||||||
|
switch(jsonValue._) {
|
||||||
|
case 'jsonNull':
|
||||||
|
return null;
|
||||||
|
case 'jsonObject': {
|
||||||
|
const out: any = {};
|
||||||
|
const objectValues = jsonValue.value;
|
||||||
|
for(let i = 0, length = objectValues.length; i < length; ++i) {
|
||||||
|
const objectValue = objectValues[i];
|
||||||
|
out[objectValue.key] = this.formatJSONValue(objectValue.value);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return jsonValue.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public getOffset() {
|
public getOffset() {
|
||||||
return this.offset;
|
return this.offset;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,10 @@ mtproto.methods.forEach((_method) => {
|
|||||||
|
|
||||||
const camelizedMethod = camelizeName(method, true, true);
|
const camelizedMethod = camelizeName(method, true, true);
|
||||||
|
|
||||||
methodsMap[method] = {req: camelizedMethod, res: processParamType(type, false/* , overrideMethodTypes */)};
|
methodsMap[method] = {
|
||||||
|
req: camelizedMethod,
|
||||||
|
res: processParamType(type, false, {'JSONValue': 'any'}/* , overrideMethodTypes */)
|
||||||
|
};
|
||||||
|
|
||||||
let str = `export type ${camelizedMethod} = {\n`;
|
let str = `export type ${camelizedMethod} = {\n`;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user