TLSharp/TLSharp.Core/Utils/UploadHelper.cs
CheshireCaat c5a2c816fc Improvements for async methods
Added CancellationToken with default value to all async methods in TLSharp.Core
Added ConfigureAwait(false) to all async methods in TLSharp.Core
SendRequestAsync replaced to SendAuthenticatedRequestAsync in methods that need auth
Private modifier in SendAuthenticatedRequestAsync changed to internal

Based on PR created by @IaRuslan
2020-01-28 10:10:49 +03:00

139 lines
4.3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TeleSharp.TL;
using TeleSharp.TL.Upload;
namespace TLSharp.Core.Utils
{
public static class UploadHelper
{
private static string GetFileHash(byte[] data)
{
string md5_checksum;
using (var md5 = MD5.Create())
{
var hash = md5.ComputeHash(data);
var hashResult = new StringBuilder(hash.Length * 2);
foreach (byte t in hash)
hashResult.Append(t.ToString("x2"));
md5_checksum = hashResult.ToString();
}
return md5_checksum;
}
public static async Task<TLAbsInputFile> UploadFile(this TelegramClient client, string name, StreamReader reader, CancellationToken token = default(CancellationToken))
{
const long tenMb = 10 * 1024 * 1024;
return await UploadFile(name, reader, client, reader.BaseStream.Length >= tenMb, token).ConfigureAwait(false);
}
private static byte[] GetFile(StreamReader reader)
{
var file = new byte[reader.BaseStream.Length];
using (reader)
{
reader.BaseStream.Read(file, 0, (int)reader.BaseStream.Length);
}
return file;
}
private static Queue<byte[]> GetFileParts(byte[] file)
{
var fileParts = new Queue<byte[]>();
const int maxFilePart = 512 * 1024;
using (var stream = new MemoryStream(file))
{
while (stream.Position != stream.Length)
{
if ((stream.Length - stream.Position) > maxFilePart)
{
var temp = new byte[maxFilePart];
stream.Read(temp, 0, maxFilePart);
fileParts.Enqueue(temp);
}
else
{
var length = stream.Length - stream.Position;
var temp = new byte[length];
stream.Read(temp, 0, (int)(length));
fileParts.Enqueue(temp);
}
}
}
return fileParts;
}
private static async Task<TLAbsInputFile> UploadFile(string name, StreamReader reader,
TelegramClient client, bool isBigFileUpload, CancellationToken token = default(CancellationToken))
{
token.ThrowIfCancellationRequested();
var file = GetFile(reader);
var fileParts = GetFileParts(file);
int partNumber = 0;
int partsCount = fileParts.Count;
long file_id = BitConverter.ToInt64(Helpers.GenerateRandomBytes(8), 0);
while (fileParts.Count != 0)
{
var part = fileParts.Dequeue();
if (isBigFileUpload)
{
await client.SendAuthenticatedRequestAsync<bool>(new TLRequestSaveBigFilePart
{
FileId = file_id,
FilePart = partNumber,
Bytes = part,
FileTotalParts = partsCount
}, token).ConfigureAwait(false);
}
else
{
await client.SendAuthenticatedRequestAsync<bool>(new TLRequestSaveFilePart
{
FileId = file_id,
FilePart = partNumber,
Bytes = part
}, token).ConfigureAwait(false);
}
partNumber++;
}
if (isBigFileUpload)
{
return new TLInputFileBig
{
Id = file_id,
Name = name,
Parts = partsCount
};
}
else
{
return new TLInputFile
{
Id = file_id,
Name = name,
Parts = partsCount,
Md5Checksum = GetFileHash(file)
};
}
}
}
}