mirror of
https://github.com/danog/Telegram.git
synced 2024-12-02 09:27:55 +01:00
387 lines
8.3 KiB
Objective-C
387 lines
8.3 KiB
Objective-C
#import "NSInputStream+TL.h"
|
|
|
|
#import <endian.h>
|
|
|
|
static inline int roundUpInput(int numToRound, int multiple)
|
|
{
|
|
if (multiple == 0)
|
|
{
|
|
return numToRound;
|
|
}
|
|
|
|
int remainder = numToRound % multiple;
|
|
if (remainder == 0)
|
|
{
|
|
return numToRound;
|
|
}
|
|
|
|
return numToRound + multiple - remainder;
|
|
}
|
|
|
|
@implementation NSInputStream (TL)
|
|
|
|
- (int32_t)readInt32
|
|
{
|
|
int32_t value = 0;
|
|
|
|
if ([self read:(uint8_t *)&value maxLength:4] != 4)
|
|
{
|
|
TGLog(@"***** Couldn't read int32");
|
|
}
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
return value;
|
|
}
|
|
|
|
- (int32_t)readInt32:(bool *)failed
|
|
{
|
|
int32_t value = 0;
|
|
|
|
if ([self read:(uint8_t *)&value maxLength:4] != 4)
|
|
{
|
|
*failed = true;
|
|
return 0;
|
|
}
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
return value;
|
|
}
|
|
|
|
- (int64_t)readInt64
|
|
{
|
|
int64_t value = 0;
|
|
|
|
if ([self read:(uint8_t *)&value maxLength:8] != 8)
|
|
{
|
|
TGLog(@"***** Couldn't read int64");
|
|
}
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
return value;
|
|
}
|
|
|
|
- (int64_t)readInt64:(bool *)failed
|
|
{
|
|
int64_t value = 0;
|
|
|
|
if ([self read:(uint8_t *)&value maxLength:8] != 8)
|
|
{
|
|
*failed = true;
|
|
return 0;
|
|
}
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
return value;
|
|
}
|
|
|
|
- (double)readDouble
|
|
{
|
|
double value = 0.0;
|
|
|
|
if ([self read:(uint8_t *)&value maxLength:8] != 8)
|
|
{
|
|
TGLog(@"***** Couldn't read double");
|
|
}
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
return value;
|
|
}
|
|
|
|
- (double)readDouble:(bool *)failed
|
|
{
|
|
double value = 0.0;
|
|
|
|
if ([self read:(uint8_t *)&value maxLength:8] != 8)
|
|
{
|
|
*failed = true;
|
|
return 0.0;
|
|
}
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
return value;
|
|
}
|
|
|
|
- (NSData *)readData:(int)length
|
|
{
|
|
uint8_t *bytes = (uint8_t *)malloc(length);
|
|
int readLen = (int)[self read:bytes maxLength:length];
|
|
if (readLen != length)
|
|
{
|
|
TGLog(@"***** Couldn't read %d bytes", length);
|
|
}
|
|
NSData *data = [[NSData alloc] initWithBytesNoCopy:bytes length:length freeWhenDone:true];
|
|
return data;
|
|
}
|
|
|
|
- (NSData *)readData:(int)length failed:(bool *)failed
|
|
{
|
|
uint8_t *bytes = (uint8_t *)malloc(length);
|
|
int readLen = (int)[self read:bytes maxLength:length];
|
|
if (readLen != length)
|
|
{
|
|
free(bytes);
|
|
*failed = true;
|
|
return nil;
|
|
}
|
|
NSData *data = [[NSData alloc] initWithBytesNoCopy:bytes length:length freeWhenDone:true];
|
|
return data;
|
|
}
|
|
|
|
- (NSMutableData *)readMutableData:(int)length
|
|
{
|
|
uint8_t *bytes = (uint8_t *)malloc(length);
|
|
int readLen = (int)[self read:bytes maxLength:length];
|
|
if (readLen != length)
|
|
{
|
|
TGLog(@"***** Couldn't read %d bytes", length);
|
|
}
|
|
NSMutableData *data = [[NSMutableData alloc] initWithBytesNoCopy:bytes length:length freeWhenDone:true];
|
|
return data;
|
|
}
|
|
|
|
- (NSMutableData *)readMutableData:(int)length failed:(bool *)failed
|
|
{
|
|
uint8_t *bytes = (uint8_t *)malloc(length);
|
|
int readLen = (int)[self read:bytes maxLength:length];
|
|
if (readLen != length)
|
|
{
|
|
free(bytes);
|
|
*failed = true;
|
|
return nil;
|
|
}
|
|
NSMutableData *data = [[NSMutableData alloc] initWithBytesNoCopy:bytes length:length freeWhenDone:true];
|
|
return data;
|
|
}
|
|
|
|
- (NSString *)readString
|
|
{
|
|
uint8_t tmp = 0;
|
|
[self read:&tmp maxLength:1];
|
|
|
|
int paddingBytes = 0;
|
|
|
|
int32_t length = tmp;
|
|
if (length == 254)
|
|
{
|
|
length = 0;
|
|
[self read:((uint8_t *)&length) + 1 maxLength:3];
|
|
length >>= 8;
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
paddingBytes = roundUpInput(length, 4) - length;
|
|
}
|
|
else
|
|
{
|
|
paddingBytes = roundUpInput(length + 1, 4) - (length + 1);
|
|
}
|
|
|
|
NSString *string = nil;
|
|
|
|
if (length > 0)
|
|
{
|
|
uint8_t *bytes = (uint8_t *)malloc(length);
|
|
int readLen = (int)[self read:bytes maxLength:length];
|
|
if (readLen != length)
|
|
{
|
|
TGLog(@"***** Couldn't read %d bytes", length);
|
|
}
|
|
|
|
string = [[NSString alloc] initWithBytesNoCopy:bytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
|
|
}
|
|
else
|
|
{
|
|
string = @"";
|
|
}
|
|
|
|
for (int i = 0; i < paddingBytes; i++)
|
|
[self read:&tmp maxLength:1];
|
|
|
|
return string;
|
|
}
|
|
|
|
- (NSString *)readString:(bool *)failed
|
|
{
|
|
uint8_t tmp = 0;
|
|
[self read:&tmp maxLength:1];
|
|
|
|
int paddingBytes = 0;
|
|
|
|
int32_t length = tmp;
|
|
if (length == 254)
|
|
{
|
|
length = 0;
|
|
[self read:((uint8_t *)&length) + 1 maxLength:3];
|
|
length >>= 8;
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
paddingBytes = roundUpInput(length, 4) - length;
|
|
}
|
|
else
|
|
{
|
|
paddingBytes = roundUpInput(length + 1, 4) - (length + 1);
|
|
}
|
|
|
|
NSString *string = nil;
|
|
|
|
if (length > 0)
|
|
{
|
|
uint8_t *bytes = (uint8_t *)malloc(length);
|
|
int readLen = (int)[self read:bytes maxLength:length];
|
|
if (readLen != length)
|
|
{
|
|
free(bytes);
|
|
*failed = true;
|
|
return nil;
|
|
}
|
|
|
|
string = [[NSString alloc] initWithBytesNoCopy:bytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
|
|
}
|
|
else
|
|
{
|
|
string = @"";
|
|
}
|
|
|
|
for (int i = 0; i < paddingBytes; i++)
|
|
[self read:&tmp maxLength:1];
|
|
|
|
return string;
|
|
}
|
|
|
|
- (NSData *)readBytes
|
|
{
|
|
uint8_t tmp = 0;
|
|
[self read:&tmp maxLength:1];
|
|
|
|
int paddingBytes = 0;
|
|
|
|
int32_t length = tmp;
|
|
if (length == 254)
|
|
{
|
|
length = 0;
|
|
[self read:((uint8_t *)&length) + 1 maxLength:3];
|
|
length >>= 8;
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
paddingBytes = roundUpInput(length, 4) - length;
|
|
}
|
|
else
|
|
{
|
|
paddingBytes = roundUpInput(length + 1, 4) - (length + 1);
|
|
}
|
|
|
|
uint8_t *bytes = (uint8_t *)malloc(length);
|
|
int readLen = (int)[self read:bytes maxLength:length];
|
|
if (readLen != length)
|
|
{
|
|
TGLog(@"***** Couldn't read %d bytes", length);
|
|
}
|
|
|
|
NSData *result = [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:true];
|
|
|
|
for (int i = 0; i < paddingBytes; i++)
|
|
[self read:&tmp maxLength:1];
|
|
|
|
return result;
|
|
}
|
|
|
|
- (NSData *)readBytes:(bool *)failed
|
|
{
|
|
uint8_t tmp = 0;
|
|
[self read:&tmp maxLength:1];
|
|
|
|
int paddingBytes = 0;
|
|
|
|
int32_t length = tmp;
|
|
if (length == 254)
|
|
{
|
|
length = 0;
|
|
[self read:((uint8_t *)&length) + 1 maxLength:3];
|
|
length >>= 8;
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
|
# error "Big endian is not implemented"
|
|
#else
|
|
# error "Unknown byte order"
|
|
#endif
|
|
|
|
paddingBytes = roundUpInput(length, 4) - length;
|
|
}
|
|
else
|
|
{
|
|
paddingBytes = roundUpInput(length + 1, 4) - (length + 1);
|
|
}
|
|
|
|
uint8_t *bytes = (uint8_t *)malloc(length);
|
|
int readLen = (int)[self read:bytes maxLength:length];
|
|
if (readLen != length)
|
|
{
|
|
free(bytes);
|
|
*failed = true;
|
|
return nil;
|
|
}
|
|
|
|
NSData *result = [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:true];
|
|
|
|
for (int i = 0; i < paddingBytes; i++)
|
|
[self read:&tmp maxLength:1];
|
|
|
|
return result;
|
|
}
|
|
|
|
@end
|