Swiftgram/submodules/LegacyComponents/Sources/TGVideoMediaAttachment.m
2020-02-22 15:38:54 +04:00

320 lines
10 KiB
Objective-C

#import "TGVideoMediaAttachment.h"
#import "TGMessage.h"
#import "LegacyComponentsInternal.h"
@interface TGVideoMediaAttachment ()
{
NSArray *_textCheckingResults;
}
@end
@implementation TGVideoMediaAttachment
@synthesize videoId = _videoId;
@synthesize accessHash = _accessHash;
@synthesize localVideoId = _localVideoId;
@synthesize duration = _duration;
@synthesize dimensions = _dimensions;
@synthesize videoInfo = _videoInfo;
@synthesize thumbnailInfo = _thumbnailInfo;
- (id)init
{
self = [super init];
if (self != nil)
{
self.type = TGVideoMediaAttachmentType;
}
return self;
}
- (id)copyWithZone:(NSZone *)__unused zone
{
TGVideoMediaAttachment *videoAttachment = [[TGVideoMediaAttachment alloc] init];
videoAttachment.videoId = _videoId;
videoAttachment.accessHash = _accessHash;
videoAttachment.localVideoId = _localVideoId;
videoAttachment.duration = _duration;
videoAttachment.dimensions = _dimensions;
videoAttachment.videoInfo = _videoInfo;
videoAttachment.thumbnailInfo = _thumbnailInfo;
videoAttachment.caption = _caption;
videoAttachment.hasStickers = _hasStickers;
videoAttachment.embeddedStickerDocuments = _embeddedStickerDocuments;
videoAttachment.loopVideo = _loopVideo;
videoAttachment.roundMessage = _roundMessage;
videoAttachment.originInfo = _originInfo;
return videoAttachment;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
self.type = TGVideoMediaAttachmentType;
_videoId = [aDecoder decodeInt64ForKey:@"videoId"];
_accessHash = [aDecoder decodeInt64ForKey:@"accessHash"];
_localVideoId = [aDecoder decodeInt64ForKey:@"localVideoId"];
_duration = [aDecoder decodeInt32ForKey:@"duration"];
_dimensions = [aDecoder decodeCGSizeForKey:@"dimensions"];
_videoInfo = [aDecoder decodeObjectForKey:@"videoInfo"];
_thumbnailInfo = [aDecoder decodeObjectForKey:@"thumbInfo"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
_hasStickers = [aDecoder decodeBoolForKey:@"hasStickers"];
_embeddedStickerDocuments = [aDecoder decodeObjectForKey:@"embeddedStickerDocuments"];
_roundMessage = [aDecoder decodeBoolForKey:@"roundMessage"];
_originInfo = [aDecoder decodeObjectForKey:@"origin"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt64:_videoId forKey:@"videoId"];
[aCoder encodeInt64:_accessHash forKey:@"accessHash"];
[aCoder encodeInt64:_localVideoId forKey:@"localVideoId"];
[aCoder encodeInt32:_duration forKey:@"duration"];
[aCoder encodeCGSize:_dimensions forKey:@"dimensions"];
[aCoder encodeObject:_videoInfo forKey:@"videoInfo"];
[aCoder encodeObject:_thumbnailInfo forKey:@"thumbInfo"];
[aCoder encodeObject:_caption forKey:@"caption"];
[aCoder encodeBool:_hasStickers forKey:@"hasStickers"];
if (_embeddedStickerDocuments != nil) {
[aCoder encodeObject:_embeddedStickerDocuments forKey:@"embeddedStickerDocuments"];
}
[aCoder encodeBool:_roundMessage forKey:@"roundMessage"];
[aCoder encodeObject:_originInfo forKey:@"origin"];
}
- (BOOL)isEqual:(id)object
{
if (![object isKindOfClass:[TGVideoMediaAttachment class]])
return false;
TGVideoMediaAttachment *other = object;
if (_videoId != other.videoId || _accessHash != other.accessHash || _localVideoId != other.localVideoId || _duration != other.duration || !CGSizeEqualToSize(_dimensions, other.dimensions))
return false;
if (!TGObjectCompare(_videoInfo, other.videoInfo))
return false;
if (!TGObjectCompare(_thumbnailInfo, other.thumbnailInfo))
return false;
if (!TGObjectCompare(_caption, other.caption))
return false;
if (_hasStickers != other.hasStickers) {
return false;
}
if (_roundMessage != other.roundMessage) {
return false;
}
return true;
}
- (void)serialize:(NSMutableData *)data
{
int32_t modernTag = 0x7abacaf1;
[data appendBytes:&modernTag length:4];
uint8_t version = 5;
[data appendBytes:&version length:1];
int dataLengthPtr = (int)data.length;
int zero = 0;
[data appendBytes:&zero length:4];
[data appendBytes:&_videoId length:8];
[data appendBytes:&_accessHash length:8];
[data appendBytes:&_localVideoId length:8];
uint8_t hasVideoInfo = _videoInfo != nil ? 1 : 0;
[data appendBytes:&hasVideoInfo length:1];
if (hasVideoInfo != 0)
[_videoInfo serialize:data];
uint8_t hasThumbnailInfo = _thumbnailInfo != nil ? 1 : 0;
[data appendBytes:&hasThumbnailInfo length:1];
if (hasThumbnailInfo != 0)
[_thumbnailInfo serialize:data];
[data appendBytes:&_duration length:4];
int dimension = (int)_dimensions.width;
[data appendBytes:&dimension length:4];
dimension = (int)_dimensions.height;
[data appendBytes:&dimension length:4];
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];
}
int8_t roundMessage = _roundMessage ? 1 : 0;
[data appendBytes:&roundMessage length:1];
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];
}
TGVideoMediaAttachment *videoAttachment = [[TGVideoMediaAttachment alloc] init];
int64_t videoId = 0;
[is read:(uint8_t *)&videoId maxLength:8];
videoAttachment.videoId = videoId;
int64_t accessHash = 0;
[is read:(uint8_t *)&accessHash maxLength:8];
videoAttachment.accessHash = accessHash;
int64_t localVideoId = 0;
[is read:(uint8_t *)&localVideoId maxLength:8];
videoAttachment.localVideoId = localVideoId;
uint8_t hasVideoInfo = 0;
[is read:&hasVideoInfo maxLength:1];
if (hasVideoInfo != 0)
videoAttachment.videoInfo = [TGVideoInfo deserialize:is];
uint8_t hasThumbnailInfo = 0;
[is read:&hasThumbnailInfo maxLength:1];
if (hasThumbnailInfo != 0)
videoAttachment.thumbnailInfo = [TGImageInfo deserialize:is];
int duration = 0;
[is read:(uint8_t *)&duration maxLength:4];
videoAttachment.duration = duration;
CGSize dimensions = CGSizeZero;
int dimension = 0;
[is read:(uint8_t *)&dimension maxLength:4];
dimensions.width = dimension;
dimension = 0;
[is read:(uint8_t *)&dimension maxLength:4];
dimensions.height = dimension;
videoAttachment.dimensions = dimensions;
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];
videoAttachment.caption = [[NSString alloc] initWithBytesNoCopy:captionBytes length:captionLength encoding:NSUTF8StringEncoding freeWhenDone:true];
}
}
if (version >= 3)
{
int8_t hasStickers = 0;
[is read:(uint8_t *)&hasStickers maxLength:1];
videoAttachment.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];
videoAttachment.embeddedStickerDocuments = [NSKeyedUnarchiver unarchiveObjectWithData:stickerData];
}
}
if (version >= 4)
{
int8_t roundMessage = 0;
[is read:(uint8_t *)&roundMessage maxLength:1];
videoAttachment.roundMessage = roundMessage != 0;
}
if (version >= 5)
{
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) {
}
videoAttachment.originInfo = origin;
}
}
return videoAttachment;
}
- (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;
}
@end