Support GZipped array in RpcResult

This commit is contained in:
Wizou 2022-01-17 15:06:29 +01:00
parent cba347dc89
commit 0ed77ef984
4 changed files with 34 additions and 27 deletions

View file

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Sockets;
@ -777,12 +778,19 @@ namespace WTelegram
{
if (!type.IsArray)
result = reader.ReadTLValue(type);
else if (reader.ReadUInt32() == Layer.RpcErrorCtor)
result = reader.ReadTLObject(Layer.RpcErrorCtor);
else
{
reader.BaseStream.Position -= 4;
result = reader.ReadTLValue(type);
var peek = reader.ReadUInt32();
if (peek == Layer.RpcErrorCtor)
result = reader.ReadTLObject(Layer.RpcErrorCtor);
else if (peek == Layer.GZipedCtor)
using (var gzipReader = new TL.BinaryReader(new GZipStream(new MemoryStream(reader.ReadTLBytes()), CompressionMode.Decompress), reader.Client))
result = gzipReader.ReadTLValue(type);
else
{
reader.BaseStream.Position -= 4;
result = reader.ReadTLValue(type);
}
}
if (type.IsEnum) result = Enum.ToObject(type, result);
if (result is RpcError rpcError)

View file

@ -14,6 +14,7 @@ namespace TL
internal const uint RpcErrorCtor = 0x2144CA19;
internal const uint MsgContainerCtor = 0x73F1F8DC;
internal const uint BadMsgCtor = 0xA7EFF811;
internal const uint GZipedCtor = 0x3072CFA1;
[EditorBrowsable(EditorBrowsableState.Never)]
public readonly static Dictionary<uint, Type> Table = new()

View file

@ -53,6 +53,9 @@ namespace TL
internal static IObject ReadTLObject(this BinaryReader reader, uint ctorNb = 0)
{
if (ctorNb == 0) ctorNb = reader.ReadUInt32();
if (ctorNb == Layer.GZipedCtor)
using (var gzipReader = new BinaryReader(new GZipStream(new MemoryStream(reader.ReadTLBytes()), CompressionMode.Decompress), reader.Client))
return ReadTLObject(gzipReader);
if (!Layer.Table.TryGetValue(ctorNb, out var type))
throw new ApplicationException($"Cannot find type for ctor #{ctorNb:x}");
if (type == null) return null; // nullable ctor (class meaning is associated with null)
@ -70,7 +73,7 @@ namespace TL
if (field.Name == "flags") flags = (int)value;
else if (field.Name == "access_hash") reader.Client?.UpdateAccessHash(obj, type, value);
}
return type == typeof(GzipPacked) ? UnzipPacket((GzipPacked)obj, reader.Client) : (IObject)obj;
return (IObject)obj;
}
internal static void WriteTLValue(this BinaryWriter writer, object value, Type valueType)
@ -292,13 +295,6 @@ namespace TL
writer.Write(0); // null arrays/strings are serialized as empty
}
internal static IObject UnzipPacket(GzipPacked obj, WTelegram.Client client)
{
using var reader = new BinaryReader(new GZipStream(new MemoryStream(obj.packed_data), CompressionMode.Decompress), client);
var result = reader.ReadTLObject();
return result;
}
#if DEBUG
private static void ShouldntBeHere() => System.Diagnostics.Debugger.Break();
#else