1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-02 09:27:55 +01:00
Telegram/legacy/TL/NSInputStream+TL.m
2015-10-01 19:19:52 +03:00

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