mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
301 lines
9.1 KiB
Objective-C
301 lines
9.1 KiB
Objective-C
#import "TGImageMediaAttachment.h"
|
|
|
|
#import "TGMessage.h"
|
|
#import "TGStringUtils.h"
|
|
|
|
@interface TGImageMediaAttachment ()
|
|
{
|
|
NSArray *_textCheckingResults;
|
|
}
|
|
@end
|
|
|
|
@implementation TGImageMediaAttachment
|
|
|
|
- (id)init
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
self.type = TGImageMediaAttachmentType;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (instancetype)initWithCoder:(NSCoder *)aDecoder
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
self.type = TGImageMediaAttachmentType;
|
|
_imageId = [aDecoder decodeInt64ForKey:@"imageId"];
|
|
_accessHash = [aDecoder decodeInt64ForKey:@"accessHash"];
|
|
_date = [aDecoder decodeInt32ForKey:@"date"];
|
|
_hasLocation = false;
|
|
_locationLatitude = 0;
|
|
_locationLongitude = 0;
|
|
_imageInfo = [aDecoder decodeObjectForKey:@"imageInfo"];
|
|
_caption = [aDecoder decodeObjectForKey:@"caption"];
|
|
_hasStickers = [aDecoder decodeBoolForKey:@"hasStickers"];
|
|
_embeddedStickerDocuments = [aDecoder decodeObjectForKey:@"embeddedStickerDocuments"];
|
|
_originInfo = [aDecoder decodeObjectForKey:@"origin"];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)encodeWithCoder:(NSCoder *)aCoder
|
|
{
|
|
[aCoder encodeInt64:_imageId forKey:@"imageId"];
|
|
[aCoder encodeInt64:_accessHash forKey:@"accessHash"];
|
|
[aCoder encodeInt32:_date forKey:@"date"];
|
|
[aCoder encodeObject:_imageInfo forKey:@"imageInfo"];
|
|
[aCoder encodeObject:_caption forKey:@"caption"];
|
|
[aCoder encodeBool:_hasStickers forKey:@"hasStickers"];
|
|
[aCoder encodeObject:_embeddedStickerDocuments forKey:@"embeddedStickerDocuments"];
|
|
[aCoder encodeObject:_originInfo forKey:@"origin"];
|
|
}
|
|
|
|
- (id)copyWithZone:(NSZone *)__unused zone
|
|
{
|
|
TGImageMediaAttachment *imageAttachment = [[TGImageMediaAttachment alloc] init];
|
|
|
|
imageAttachment.imageId = _imageId;
|
|
imageAttachment.accessHash = _accessHash;
|
|
imageAttachment.date = _date;
|
|
imageAttachment.hasLocation = _hasLocation;
|
|
imageAttachment.locationLatitude = _locationLatitude;
|
|
imageAttachment.locationLongitude = _locationLongitude;
|
|
imageAttachment.imageInfo = _imageInfo;
|
|
imageAttachment.caption = _caption;
|
|
imageAttachment.hasStickers = _hasStickers;
|
|
imageAttachment.embeddedStickerDocuments = _embeddedStickerDocuments;
|
|
imageAttachment.originInfo = _originInfo;
|
|
|
|
return imageAttachment;
|
|
}
|
|
|
|
- (BOOL)isEqual:(id)object {
|
|
if (![object isKindOfClass:[TGImageMediaAttachment class]]) {
|
|
return false;
|
|
}
|
|
TGImageMediaAttachment *other = object;
|
|
if (_imageId != other->_imageId || _accessHash != other->_accessHash || _date != other->_date || _hasLocation != other->_hasLocation) {
|
|
return false;
|
|
}
|
|
if (![_imageInfo isEqual:other->_imageInfo]) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
- (int64_t)localImageId
|
|
{
|
|
return [TGImageMediaAttachment localImageIdForImageInfo:self.imageInfo];
|
|
}
|
|
|
|
+ (int64_t)localImageIdForImageInfo:(TGImageInfo *)imageInfo {
|
|
NSString *legacyCacheUrl = [imageInfo imageUrlForLargestSize:NULL];
|
|
int64_t localImageId = 0;
|
|
if (legacyCacheUrl.length != 0)
|
|
localImageId = legacy_murMurHash32(legacyCacheUrl);
|
|
|
|
return localImageId;
|
|
}
|
|
|
|
- (void)serialize:(NSMutableData *)data
|
|
{
|
|
int32_t modernTag = 0x7abacaf1;
|
|
[data appendBytes:&modernTag length:4];
|
|
|
|
uint8_t version = 4;
|
|
[data appendBytes:&version length:1];
|
|
|
|
int dataLengthPtr = (int)data.length;
|
|
int zero = 0;
|
|
[data appendBytes:&zero length:4];
|
|
|
|
[data appendBytes:&_imageId length:8];
|
|
|
|
[data appendBytes:(uint8_t *)&_date length:4];
|
|
|
|
uint8_t hasLocation = _hasLocation ? 1 : 0;
|
|
[data appendBytes:&hasLocation length:1];
|
|
|
|
if (_hasLocation)
|
|
{
|
|
[data appendBytes:(uint8_t *)&_locationLatitude length:8];
|
|
[data appendBytes:(uint8_t *)&_locationLongitude length:8];
|
|
}
|
|
|
|
uint8_t hasImageInfo = _imageInfo != nil ? 1 : 0;
|
|
[data appendBytes:&hasImageInfo length:1];
|
|
if (hasImageInfo != 0)
|
|
{
|
|
[_imageInfo serialize:data];
|
|
}
|
|
|
|
[data appendBytes:&_accessHash length:8];
|
|
|
|
NSData *captionData = [_caption dataUsingEncoding:NSUTF8StringEncoding];
|
|
int32_t captionLength = (int32_t)captionData.length;
|
|
[data appendBytes:&captionLength length:4];
|
|
if (captionLength != 0)
|
|
[data appendData:captionData];
|
|
|
|
int8_t hasStickers = _hasStickers ? 1 : 0;
|
|
[data appendBytes:&hasStickers length:1];
|
|
|
|
if (_embeddedStickerDocuments.count == 0) {
|
|
int32_t zero = 0;
|
|
[data appendBytes:&zero length:4];
|
|
} else {
|
|
NSData *stickerData = [NSKeyedArchiver archivedDataWithRootObject:_embeddedStickerDocuments];
|
|
int32_t length = (int32_t)stickerData.length;
|
|
[data appendBytes:&length length:4];
|
|
[data appendData:stickerData];
|
|
}
|
|
|
|
NSData *originData = nil;
|
|
@try {
|
|
originData = [NSKeyedArchiver archivedDataWithRootObject:_originInfo];
|
|
} @catch (NSException *e) {
|
|
|
|
}
|
|
int32_t originLength = (int)originData.length;
|
|
[data appendBytes:&originLength length:sizeof(originLength)];
|
|
if (originData != nil) {
|
|
[data appendData:originData];
|
|
}
|
|
|
|
int dataLength = (int)(data.length - dataLengthPtr - 4);
|
|
[data replaceBytesInRange:NSMakeRange(dataLengthPtr, 4) withBytes:&dataLength];
|
|
}
|
|
|
|
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
|
|
{
|
|
int32_t dataLength = 0;
|
|
[is read:(uint8_t *)&dataLength maxLength:4];
|
|
|
|
uint8_t version = 1;
|
|
if (dataLength == 0x7abacaf1)
|
|
{
|
|
[is read:(uint8_t *)&version maxLength:1];
|
|
[is read:(uint8_t *)&dataLength maxLength:4];
|
|
}
|
|
|
|
TGImageMediaAttachment *imageAttachment = [[TGImageMediaAttachment alloc] init];
|
|
|
|
int64_t imageId = 0;
|
|
[is read:(uint8_t *)&imageId maxLength:8];
|
|
dataLength -= 8;
|
|
|
|
imageAttachment.imageId = imageId;
|
|
|
|
int date = 0;
|
|
[is read:(uint8_t *)&date maxLength:4];
|
|
dataLength -= 4;
|
|
|
|
imageAttachment.date = date;
|
|
|
|
uint8_t hasLocation = 0;
|
|
[is read:&hasLocation maxLength:1];
|
|
dataLength -= 1;
|
|
|
|
imageAttachment.hasLocation = hasLocation != 0;
|
|
|
|
if (hasLocation != 0)
|
|
{
|
|
double value = 0;
|
|
[is read:(uint8_t *)&value maxLength:8];
|
|
imageAttachment.locationLatitude = value;
|
|
[is read:(uint8_t *)&value maxLength:8];
|
|
imageAttachment.locationLongitude = value;
|
|
|
|
dataLength -= 16;
|
|
}
|
|
|
|
uint8_t hasImageInfo = 0;
|
|
[is read:&hasImageInfo maxLength:1];
|
|
dataLength -= 1;
|
|
|
|
if (hasImageInfo != 0)
|
|
{
|
|
TGImageInfo *imageInfo = [TGImageInfo deserialize:is];
|
|
if (imageInfo != nil)
|
|
imageAttachment.imageInfo = imageInfo;
|
|
}
|
|
|
|
int64_t accessHash = 0;
|
|
[is read:(uint8_t *)&accessHash maxLength:8];
|
|
imageAttachment.accessHash = accessHash;
|
|
|
|
if (version >= 2)
|
|
{
|
|
int32_t captionLength = 0;
|
|
[is read:(uint8_t *)&captionLength maxLength:4];
|
|
if (captionLength != 0)
|
|
{
|
|
uint8_t *captionBytes = malloc(captionLength);
|
|
[is read:captionBytes maxLength:captionLength];
|
|
imageAttachment.caption = [[NSString alloc] initWithBytes:captionBytes length:captionLength encoding:NSUTF8StringEncoding];
|
|
free(captionBytes);
|
|
}
|
|
}
|
|
|
|
if (version >= 3) {
|
|
int8_t hasStickers = 0;
|
|
[is read:(uint8_t *)&hasStickers maxLength:1];
|
|
imageAttachment.hasStickers = hasStickers != 0;
|
|
|
|
int32_t stickerDataLength = 0;
|
|
[is read:(uint8_t *)&stickerDataLength maxLength:4];
|
|
if (stickerDataLength != 0) {
|
|
uint8_t *stickerBytes = malloc(stickerDataLength);
|
|
[is read:stickerBytes maxLength:stickerDataLength];
|
|
NSData *stickerData = [[NSData alloc] initWithBytesNoCopy:stickerBytes length:stickerDataLength freeWhenDone:true];
|
|
imageAttachment.embeddedStickerDocuments = [NSKeyedUnarchiver unarchiveObjectWithData:stickerData];
|
|
}
|
|
}
|
|
|
|
if (version >= 4) {
|
|
int32_t originLength = 0;
|
|
[is read:(uint8_t *)&originLength maxLength:sizeof(originLength)];
|
|
if (originLength > 0)
|
|
{
|
|
uint8_t *originBytes = malloc(originLength);
|
|
[is read:originBytes maxLength:originLength];
|
|
NSData *data = [[NSData alloc] initWithBytesNoCopy:originBytes length:originLength freeWhenDone:true];
|
|
TGMediaOriginInfo *origin = nil;
|
|
@try {
|
|
origin = [NSKeyedUnarchiver unarchiveObjectWithData:data];
|
|
} @catch (NSException *e) {
|
|
|
|
}
|
|
imageAttachment.originInfo = origin;
|
|
}
|
|
}
|
|
|
|
return imageAttachment;
|
|
}
|
|
|
|
- (NSArray *)textCheckingResults
|
|
{
|
|
if (_caption.length < 2)
|
|
_textCheckingResults = [NSArray array];
|
|
|
|
if (_textCheckingResults == nil)
|
|
{
|
|
NSArray *textCheckingResults = [TGMessage textCheckingResultsForText:_caption highlightMentionsAndTags:true highlightCommands:true entities:nil];
|
|
_textCheckingResults = textCheckingResults ?: [NSArray array];
|
|
}
|
|
|
|
return _textCheckingResults;
|
|
}
|
|
|
|
- (CGSize)dimensions {
|
|
CGSize size = CGSizeZero;
|
|
[_imageInfo imageUrlForLargestSize:&size];
|
|
return size;
|
|
}
|
|
|
|
@end
|