no message

This commit is contained in:
Peter
2017-07-19 20:26:28 +03:00
parent 138469c9fd
commit bf1c9bebeb
150 changed files with 16748 additions and 37 deletions

View File

@@ -8,12 +8,308 @@
/* Begin PBXBuildFile section */
D017772C1F1F8F100044446D /* LegacyComponents.h in Headers */ = {isa = PBXBuildFile; fileRef = D017772A1F1F8F100044446D /* LegacyComponents.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777511F1F8FE60044446D /* LegacyComponentsGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777381F1F8FE60044446D /* LegacyComponentsGlobals.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777531F1F8FE60044446D /* PSCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = D017773A1F1F8FE60044446D /* PSCoding.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777541F1F8FE60044446D /* PSData.h in Headers */ = {isa = PBXBuildFile; fileRef = D017773B1F1F8FE60044446D /* PSData.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777551F1F8FE60044446D /* PSKeyValueCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D017773C1F1F8FE60044446D /* PSKeyValueCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777561F1F8FE60044446D /* PSKeyValueCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = D017773D1F1F8FE60044446D /* PSKeyValueCoder.m */; };
D01777571F1F8FE60044446D /* PSKeyValueDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D017773E1F1F8FE60044446D /* PSKeyValueDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777581F1F8FE60044446D /* PSKeyValueDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = D017773F1F1F8FE60044446D /* PSKeyValueDecoder.m */; };
D01777591F1F8FE60044446D /* PSKeyValueEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777401F1F8FE60044446D /* PSKeyValueEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017775A1F1F8FE60044446D /* PSKeyValueEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777411F1F8FE60044446D /* PSKeyValueEncoder.m */; };
D017775B1F1F8FE60044446D /* PSKeyValueReader.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777421F1F8FE60044446D /* PSKeyValueReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017775C1F1F8FE60044446D /* PSKeyValueStore.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777431F1F8FE60044446D /* PSKeyValueStore.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017775D1F1F8FE60044446D /* PSKeyValueWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777441F1F8FE60044446D /* PSKeyValueWriter.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017775E1F1F8FE60044446D /* TGBotComandInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777451F1F8FE60044446D /* TGBotComandInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017775F1F1F8FE60044446D /* TGBotComandInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777461F1F8FE60044446D /* TGBotComandInfo.m */; };
D01777601F1F8FE60044446D /* TGBotInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777471F1F8FE60044446D /* TGBotInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777611F1F8FE60044446D /* TGBotInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777481F1F8FE60044446D /* TGBotInfo.m */; };
D01777621F1F8FE60044446D /* TGLocalization.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777491F1F8FE60044446D /* TGLocalization.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777631F1F8FE60044446D /* TGLocalization.m in Sources */ = {isa = PBXBuildFile; fileRef = D017774A1F1F8FE60044446D /* TGLocalization.m */; };
D01777641F1F8FE60044446D /* TGPluralization.h in Headers */ = {isa = PBXBuildFile; fileRef = D017774B1F1F8FE60044446D /* TGPluralization.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777651F1F8FE60044446D /* TGPluralization.m in Sources */ = {isa = PBXBuildFile; fileRef = D017774C1F1F8FE60044446D /* TGPluralization.m */; };
D01777661F1F8FE60044446D /* TGStringUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = D017774D1F1F8FE60044446D /* TGStringUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777671F1F8FE60044446D /* TGStringUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = D017774E1F1F8FE60044446D /* TGStringUtils.mm */; };
D01777681F1F8FE60044446D /* TGUser.h in Headers */ = {isa = PBXBuildFile; fileRef = D017774F1F1F8FE60044446D /* TGUser.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777691F1F8FE60044446D /* TGUser.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777501F1F8FE60044446D /* TGUser.m */; };
D017776B1F1F909E0044446D /* LegacyComponentsGlobals.m in Sources */ = {isa = PBXBuildFile; fileRef = D017776A1F1F909E0044446D /* LegacyComponentsGlobals.m */; };
D01777721F1F92420044446D /* TGPhoneUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777701F1F92420044446D /* TGPhoneUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777731F1F92420044446D /* TGPhoneUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777711F1F92420044446D /* TGPhoneUtils.m */; };
D01777761F1F92570044446D /* RMPhoneFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777741F1F92570044446D /* RMPhoneFormat.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777771F1F92570044446D /* RMPhoneFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777751F1F92570044446D /* RMPhoneFormat.m */; };
D017777A1F1F927A0044446D /* NSObject+TGLock.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777781F1F927A0044446D /* NSObject+TGLock.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017777B1F1F927A0044446D /* NSObject+TGLock.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777791F1F927A0044446D /* NSObject+TGLock.m */; };
D017777E1F1F930B0044446D /* TGConversation.h in Headers */ = {isa = PBXBuildFile; fileRef = D017777C1F1F930B0044446D /* TGConversation.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017777F1F1F930B0044446D /* TGConversation.m in Sources */ = {isa = PBXBuildFile; fileRef = D017777D1F1F930B0044446D /* TGConversation.m */; };
D01777821F1F93250044446D /* TGImageInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777801F1F93250044446D /* TGImageInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777831F1F93250044446D /* TGImageInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = D01777811F1F93250044446D /* TGImageInfo.mm */; };
D01777871F1F93550044446D /* TGMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777851F1F93550044446D /* TGMessage.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777881F1F93550044446D /* TGMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = D01777861F1F93550044446D /* TGMessage.mm */; };
D01777F41F1F961D0044446D /* TGTextCheckingResult.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777891F1F961C0044446D /* TGTextCheckingResult.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777F51F1F961D0044446D /* TGTextCheckingResult.m in Sources */ = {isa = PBXBuildFile; fileRef = D017778A1F1F961C0044446D /* TGTextCheckingResult.m */; };
D01777F61F1F961D0044446D /* TGPeerIdAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = D017778B1F1F961C0044446D /* TGPeerIdAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777F71F1F961D0044446D /* TGChannelBannedRights.h in Headers */ = {isa = PBXBuildFile; fileRef = D017778C1F1F961C0044446D /* TGChannelBannedRights.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777F81F1F961D0044446D /* TGChannelBannedRights.m in Sources */ = {isa = PBXBuildFile; fileRef = D017778D1F1F961D0044446D /* TGChannelBannedRights.m */; };
D01777F91F1F961D0044446D /* TGChannelAdminRights.h in Headers */ = {isa = PBXBuildFile; fileRef = D017778E1F1F961D0044446D /* TGChannelAdminRights.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777FA1F1F961D0044446D /* TGChannelAdminRights.m in Sources */ = {isa = PBXBuildFile; fileRef = D017778F1F1F961D0044446D /* TGChannelAdminRights.m */; };
D01777FB1F1F961D0044446D /* TGDatabaseMessageDraft.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777901F1F961D0044446D /* TGDatabaseMessageDraft.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777FC1F1F961D0044446D /* TGDatabaseMessageDraft.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777911F1F961D0044446D /* TGDatabaseMessageDraft.m */; };
D01777FD1F1F961D0044446D /* TGMessageGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777921F1F961D0044446D /* TGMessageGroup.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01777FE1F1F961D0044446D /* TGMessageGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777931F1F961D0044446D /* TGMessageGroup.m */; };
D01777FF1F1F961D0044446D /* TGMessageHole.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777941F1F961D0044446D /* TGMessageHole.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778001F1F961D0044446D /* TGMessageHole.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777951F1F961D0044446D /* TGMessageHole.m */; };
D01778011F1F961D0044446D /* TGMessageViewCountContentProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777961F1F961D0044446D /* TGMessageViewCountContentProperty.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778021F1F961D0044446D /* TGMessageViewCountContentProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777971F1F961D0044446D /* TGMessageViewCountContentProperty.m */; };
D01778031F1F961D0044446D /* TGAuthorSignatureMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777981F1F961D0044446D /* TGAuthorSignatureMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778041F1F961D0044446D /* TGAuthorSignatureMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777991F1F961D0044446D /* TGAuthorSignatureMediaAttachment.m */; };
D01778051F1F961D0044446D /* TGWebDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = D017779A1F1F961D0044446D /* TGWebDocument.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778061F1F961D0044446D /* TGWebDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = D017779B1F1F961D0044446D /* TGWebDocument.m */; };
D01778071F1F961D0044446D /* TGInvoiceMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D017779C1F1F961D0044446D /* TGInvoiceMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778081F1F961D0044446D /* TGInvoiceMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D017779D1F1F961D0044446D /* TGInvoiceMediaAttachment.m */; };
D01778091F1F961D0044446D /* TGGameMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D017779E1F1F961D0044446D /* TGGameMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017780A1F1F961D0044446D /* TGGameMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D017779F1F1F961D0044446D /* TGGameMediaAttachment.m */; };
D017780B1F1F961D0044446D /* TGViaUserAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777A01F1F961D0044446D /* TGViaUserAttachment.m */; };
D017780C1F1F961D0044446D /* TGViaUserAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777A11F1F961D0044446D /* TGViaUserAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017780D1F1F961D0044446D /* TGBotContextResultAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777A21F1F961D0044446D /* TGBotContextResultAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017780E1F1F961D0044446D /* TGBotContextResultAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777A31F1F961D0044446D /* TGBotContextResultAttachment.m */; };
D017780F1F1F961D0044446D /* TGMessageEntity.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777A41F1F961D0044446D /* TGMessageEntity.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778101F1F961D0044446D /* TGMessageEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777A51F1F961D0044446D /* TGMessageEntity.m */; };
D01778111F1F961D0044446D /* TGMessageEntityBold.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777A61F1F961D0044446D /* TGMessageEntityBold.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778121F1F961D0044446D /* TGMessageEntityBold.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777A71F1F961D0044446D /* TGMessageEntityBold.m */; };
D01778131F1F961D0044446D /* TGMessageEntityBotCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777A81F1F961D0044446D /* TGMessageEntityBotCommand.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778141F1F961D0044446D /* TGMessageEntityBotCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777A91F1F961D0044446D /* TGMessageEntityBotCommand.m */; };
D01778151F1F961D0044446D /* TGMessageEntityCode.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777AA1F1F961D0044446D /* TGMessageEntityCode.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778161F1F961D0044446D /* TGMessageEntityCode.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777AB1F1F961D0044446D /* TGMessageEntityCode.m */; };
D01778171F1F961D0044446D /* TGMessageEntityEmail.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777AC1F1F961D0044446D /* TGMessageEntityEmail.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778181F1F961D0044446D /* TGMessageEntityEmail.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777AD1F1F961D0044446D /* TGMessageEntityEmail.m */; };
D01778191F1F961D0044446D /* TGMessageEntityHashtag.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777AE1F1F961D0044446D /* TGMessageEntityHashtag.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017781A1F1F961D0044446D /* TGMessageEntityHashtag.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777AF1F1F961D0044446D /* TGMessageEntityHashtag.m */; };
D017781B1F1F961D0044446D /* TGMessageEntityItalic.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777B01F1F961D0044446D /* TGMessageEntityItalic.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017781C1F1F961D0044446D /* TGMessageEntityItalic.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777B11F1F961D0044446D /* TGMessageEntityItalic.m */; };
D017781D1F1F961D0044446D /* TGMessageEntityMention.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777B21F1F961D0044446D /* TGMessageEntityMention.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017781E1F1F961D0044446D /* TGMessageEntityMention.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777B31F1F961D0044446D /* TGMessageEntityMention.m */; };
D017781F1F1F961D0044446D /* TGMessageEntityMentionName.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777B41F1F961D0044446D /* TGMessageEntityMentionName.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778201F1F961D0044446D /* TGMessageEntityMentionName.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777B51F1F961D0044446D /* TGMessageEntityMentionName.m */; };
D01778211F1F961D0044446D /* TGMessageEntityPre.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777B61F1F961D0044446D /* TGMessageEntityPre.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778221F1F961D0044446D /* TGMessageEntityPre.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777B71F1F961D0044446D /* TGMessageEntityPre.m */; };
D01778231F1F961D0044446D /* TGMessageEntityTextUrl.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777B81F1F961D0044446D /* TGMessageEntityTextUrl.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778241F1F961D0044446D /* TGMessageEntityTextUrl.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777B91F1F961D0044446D /* TGMessageEntityTextUrl.m */; };
D01778251F1F961D0044446D /* TGMessageEntityUrl.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777BA1F1F961D0044446D /* TGMessageEntityUrl.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778261F1F961D0044446D /* TGMessageEntityUrl.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777BB1F1F961D0044446D /* TGMessageEntityUrl.m */; };
D01778271F1F961D0044446D /* TGMessageEntitiesAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777BC1F1F961D0044446D /* TGMessageEntitiesAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778281F1F961D0044446D /* TGMessageEntitiesAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777BD1F1F961D0044446D /* TGMessageEntitiesAttachment.m */; };
D01778291F1F961D0044446D /* TGBotReplyMarkup.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777BE1F1F961D0044446D /* TGBotReplyMarkup.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017782A1F1F961D0044446D /* TGBotReplyMarkup.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777BF1F1F961D0044446D /* TGBotReplyMarkup.m */; };
D017782B1F1F961D0044446D /* TGBotReplyMarkupButton.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777C01F1F961D0044446D /* TGBotReplyMarkupButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017782C1F1F961D0044446D /* TGBotReplyMarkupButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777C11F1F961D0044446D /* TGBotReplyMarkupButton.m */; };
D017782D1F1F961D0044446D /* TGBotReplyMarkupRow.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777C21F1F961D0044446D /* TGBotReplyMarkupRow.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017782E1F1F961D0044446D /* TGBotReplyMarkupRow.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777C31F1F961D0044446D /* TGBotReplyMarkupRow.m */; };
D017782F1F1F961D0044446D /* TGReplyMarkupAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777C41F1F961D0044446D /* TGReplyMarkupAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778301F1F961D0044446D /* TGReplyMarkupAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777C51F1F961D0044446D /* TGReplyMarkupAttachment.m */; };
D01778311F1F961D0044446D /* TGInstantPage.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777C61F1F961D0044446D /* TGInstantPage.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778321F1F961D0044446D /* TGInstantPage.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777C71F1F961D0044446D /* TGInstantPage.m */; };
D01778331F1F961D0044446D /* TGWebPageMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777C81F1F961D0044446D /* TGWebPageMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778341F1F961D0044446D /* TGWebPageMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777C91F1F961D0044446D /* TGWebPageMediaAttachment.m */; };
D01778351F1F961D0044446D /* TGReplyMessageMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777CA1F1F961D0044446D /* TGReplyMessageMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778361F1F961D0044446D /* TGReplyMessageMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777CB1F1F961D0044446D /* TGReplyMessageMediaAttachment.m */; };
D01778371F1F961D0044446D /* TGAudioMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777CC1F1F961D0044446D /* TGAudioMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778381F1F961D0044446D /* TGAudioMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777CD1F1F961D0044446D /* TGAudioMediaAttachment.m */; };
D01778391F1F961D0044446D /* TGAudioWaveform.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777CE1F1F961D0044446D /* TGAudioWaveform.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017783A1F1F961D0044446D /* TGAudioWaveform.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777CF1F1F961D0044446D /* TGAudioWaveform.m */; };
D017783B1F1F961D0044446D /* TGStickerPackReference.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777D01F1F961D0044446D /* TGStickerPackReference.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017783C1F1F961D0044446D /* TGStickerPackReference.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777D11F1F961D0044446D /* TGStickerPackReference.m */; };
D017783D1F1F961D0044446D /* TGDocumentAttributeFilename.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777D21F1F961D0044446D /* TGDocumentAttributeFilename.m */; };
D017783E1F1F961D0044446D /* TGDocumentAttributeImageSize.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777D31F1F961D0044446D /* TGDocumentAttributeImageSize.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017783F1F1F961D0044446D /* TGDocumentAttributeImageSize.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777D41F1F961D0044446D /* TGDocumentAttributeImageSize.m */; };
D01778401F1F961D0044446D /* TGDocumentAttributeSticker.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777D51F1F961D0044446D /* TGDocumentAttributeSticker.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778411F1F961D0044446D /* TGDocumentAttributeSticker.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777D61F1F961D0044446D /* TGDocumentAttributeSticker.m */; };
D01778421F1F961D0044446D /* TGDocumentAttributeVideo.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777D71F1F961D0044446D /* TGDocumentAttributeVideo.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778431F1F961D0044446D /* TGDocumentAttributeVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777D81F1F961D0044446D /* TGDocumentAttributeVideo.m */; };
D01778441F1F961D0044446D /* TGDocumentAttributeAnimated.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777D91F1F961D0044446D /* TGDocumentAttributeAnimated.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778451F1F961D0044446D /* TGDocumentAttributeAnimated.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777DA1F1F961D0044446D /* TGDocumentAttributeAnimated.m */; };
D01778461F1F961D0044446D /* TGDocumentAttributeAudio.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777DB1F1F961D0044446D /* TGDocumentAttributeAudio.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778471F1F961D0044446D /* TGDocumentAttributeAudio.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777DC1F1F961D0044446D /* TGDocumentAttributeAudio.m */; };
D01778481F1F961D0044446D /* TGDocumentAttributeFilename.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777DD1F1F961D0044446D /* TGDocumentAttributeFilename.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778491F1F961D0044446D /* TGDocumentMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777DE1F1F961D0044446D /* TGDocumentMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017784A1F1F961D0044446D /* TGDocumentMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777DF1F1F961D0044446D /* TGDocumentMediaAttachment.m */; };
D017784B1F1F961D0044446D /* TGUnsupportedMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777E01F1F961D0044446D /* TGUnsupportedMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017784C1F1F961D0044446D /* TGUnsupportedMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777E11F1F961D0044446D /* TGUnsupportedMediaAttachment.m */; };
D017784D1F1F961D0044446D /* TGForwardedMessageMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777E21F1F961D0044446D /* TGForwardedMessageMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017784E1F1F961D0044446D /* TGForwardedMessageMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777E31F1F961D0044446D /* TGForwardedMessageMediaAttachment.m */; };
D017784F1F1F961D0044446D /* TGContactMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777E41F1F961D0044446D /* TGContactMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778501F1F961D0044446D /* TGContactMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777E51F1F961D0044446D /* TGContactMediaAttachment.m */; };
D01778511F1F961D0044446D /* TGVideoInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777E61F1F961D0044446D /* TGVideoInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778521F1F961D0044446D /* TGVideoInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = D01777E71F1F961D0044446D /* TGVideoInfo.mm */; };
D01778531F1F961D0044446D /* TGVideoMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777E81F1F961D0044446D /* TGVideoMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778541F1F961D0044446D /* TGVideoMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777E91F1F961D0044446D /* TGVideoMediaAttachment.m */; };
D01778551F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777EA1F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778561F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777EB1F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.m */; };
D01778571F1F961D0044446D /* TGLocationMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777EC1F1F961D0044446D /* TGLocationMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D01778581F1F961D0044446D /* TGLocationMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777ED1F1F961D0044446D /* TGLocationMediaAttachment.m */; };
D01778591F1F961D0044446D /* TGImageMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777EE1F1F961D0044446D /* TGImageMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017785A1F1F961D0044446D /* TGImageMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777EF1F1F961D0044446D /* TGImageMediaAttachment.m */; };
D017785B1F1F961D0044446D /* TGMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777F01F1F961D0044446D /* TGMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017785C1F1F961D0044446D /* TGMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777F11F1F961D0044446D /* TGMediaAttachment.m */; };
D017785D1F1F961D0044446D /* TGActionMediaAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = D01777F21F1F961D0044446D /* TGActionMediaAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017785E1F1F961D0044446D /* TGActionMediaAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = D01777F31F1F961D0044446D /* TGActionMediaAttachment.m */; };
D01778691F1F99180044446D /* NSInputStream+TL.h in Headers */ = {isa = PBXBuildFile; fileRef = D01778671F1F99180044446D /* NSInputStream+TL.h */; settings = {ATTRIBUTES = (Public, ); }; };
D017786A1F1F99180044446D /* NSInputStream+TL.m in Sources */ = {isa = PBXBuildFile; fileRef = D01778681F1F99180044446D /* NSInputStream+TL.m */; };
D017789D1F1FC99A0044446D /* LegacyComponentsInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = D017789B1F1FC99A0044446D /* LegacyComponentsInternal.h */; };
D017789E1F1FC99A0044446D /* LegacyComponentsInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = D017789C1F1FC99A0044446D /* LegacyComponentsInternal.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
D01777271F1F8F100044446D /* LegacyComponents.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LegacyComponents.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D017772A1F1F8F100044446D /* LegacyComponents.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LegacyComponents.h; sourceTree = "<group>"; };
D017772B1F1F8F100044446D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D01777381F1F8FE60044446D /* LegacyComponentsGlobals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyComponentsGlobals.h; sourceTree = "<group>"; };
D017773A1F1F8FE60044446D /* PSCoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSCoding.h; sourceTree = "<group>"; };
D017773B1F1F8FE60044446D /* PSData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSData.h; sourceTree = "<group>"; };
D017773C1F1F8FE60044446D /* PSKeyValueCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSKeyValueCoder.h; sourceTree = "<group>"; };
D017773D1F1F8FE60044446D /* PSKeyValueCoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSKeyValueCoder.m; sourceTree = "<group>"; };
D017773E1F1F8FE60044446D /* PSKeyValueDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSKeyValueDecoder.h; sourceTree = "<group>"; };
D017773F1F1F8FE60044446D /* PSKeyValueDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSKeyValueDecoder.m; sourceTree = "<group>"; };
D01777401F1F8FE60044446D /* PSKeyValueEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSKeyValueEncoder.h; sourceTree = "<group>"; };
D01777411F1F8FE60044446D /* PSKeyValueEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSKeyValueEncoder.m; sourceTree = "<group>"; };
D01777421F1F8FE60044446D /* PSKeyValueReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSKeyValueReader.h; sourceTree = "<group>"; };
D01777431F1F8FE60044446D /* PSKeyValueStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSKeyValueStore.h; sourceTree = "<group>"; };
D01777441F1F8FE60044446D /* PSKeyValueWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSKeyValueWriter.h; sourceTree = "<group>"; };
D01777451F1F8FE60044446D /* TGBotComandInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGBotComandInfo.h; sourceTree = "<group>"; };
D01777461F1F8FE60044446D /* TGBotComandInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGBotComandInfo.m; sourceTree = "<group>"; };
D01777471F1F8FE60044446D /* TGBotInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGBotInfo.h; sourceTree = "<group>"; };
D01777481F1F8FE60044446D /* TGBotInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGBotInfo.m; sourceTree = "<group>"; };
D01777491F1F8FE60044446D /* TGLocalization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGLocalization.h; sourceTree = "<group>"; };
D017774A1F1F8FE60044446D /* TGLocalization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGLocalization.m; sourceTree = "<group>"; };
D017774B1F1F8FE60044446D /* TGPluralization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGPluralization.h; sourceTree = "<group>"; };
D017774C1F1F8FE60044446D /* TGPluralization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGPluralization.m; sourceTree = "<group>"; };
D017774D1F1F8FE60044446D /* TGStringUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGStringUtils.h; sourceTree = "<group>"; };
D017774E1F1F8FE60044446D /* TGStringUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TGStringUtils.mm; sourceTree = "<group>"; };
D017774F1F1F8FE60044446D /* TGUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGUser.h; sourceTree = "<group>"; };
D01777501F1F8FE60044446D /* TGUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGUser.m; sourceTree = "<group>"; };
D017776A1F1F909E0044446D /* LegacyComponentsGlobals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LegacyComponentsGlobals.m; sourceTree = "<group>"; };
D01777701F1F92420044446D /* TGPhoneUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGPhoneUtils.h; sourceTree = "<group>"; };
D01777711F1F92420044446D /* TGPhoneUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGPhoneUtils.m; sourceTree = "<group>"; };
D01777741F1F92570044446D /* RMPhoneFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMPhoneFormat.h; sourceTree = "<group>"; };
D01777751F1F92570044446D /* RMPhoneFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMPhoneFormat.m; sourceTree = "<group>"; };
D01777781F1F927A0044446D /* NSObject+TGLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+TGLock.h"; sourceTree = "<group>"; };
D01777791F1F927A0044446D /* NSObject+TGLock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+TGLock.m"; sourceTree = "<group>"; };
D017777C1F1F930B0044446D /* TGConversation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGConversation.h; sourceTree = "<group>"; };
D017777D1F1F930B0044446D /* TGConversation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGConversation.m; sourceTree = "<group>"; };
D01777801F1F93250044446D /* TGImageInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGImageInfo.h; sourceTree = "<group>"; };
D01777811F1F93250044446D /* TGImageInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TGImageInfo.mm; sourceTree = "<group>"; };
D01777851F1F93550044446D /* TGMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessage.h; sourceTree = "<group>"; };
D01777861F1F93550044446D /* TGMessage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TGMessage.mm; sourceTree = "<group>"; };
D01777891F1F961C0044446D /* TGTextCheckingResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGTextCheckingResult.h; sourceTree = "<group>"; };
D017778A1F1F961C0044446D /* TGTextCheckingResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGTextCheckingResult.m; sourceTree = "<group>"; };
D017778B1F1F961C0044446D /* TGPeerIdAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGPeerIdAdapter.h; sourceTree = "<group>"; };
D017778C1F1F961C0044446D /* TGChannelBannedRights.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGChannelBannedRights.h; sourceTree = "<group>"; };
D017778D1F1F961D0044446D /* TGChannelBannedRights.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGChannelBannedRights.m; sourceTree = "<group>"; };
D017778E1F1F961D0044446D /* TGChannelAdminRights.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGChannelAdminRights.h; sourceTree = "<group>"; };
D017778F1F1F961D0044446D /* TGChannelAdminRights.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGChannelAdminRights.m; sourceTree = "<group>"; };
D01777901F1F961D0044446D /* TGDatabaseMessageDraft.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGDatabaseMessageDraft.h; sourceTree = "<group>"; };
D01777911F1F961D0044446D /* TGDatabaseMessageDraft.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGDatabaseMessageDraft.m; sourceTree = "<group>"; };
D01777921F1F961D0044446D /* TGMessageGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageGroup.h; sourceTree = "<group>"; };
D01777931F1F961D0044446D /* TGMessageGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageGroup.m; sourceTree = "<group>"; };
D01777941F1F961D0044446D /* TGMessageHole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageHole.h; sourceTree = "<group>"; };
D01777951F1F961D0044446D /* TGMessageHole.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageHole.m; sourceTree = "<group>"; };
D01777961F1F961D0044446D /* TGMessageViewCountContentProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageViewCountContentProperty.h; sourceTree = "<group>"; };
D01777971F1F961D0044446D /* TGMessageViewCountContentProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageViewCountContentProperty.m; sourceTree = "<group>"; };
D01777981F1F961D0044446D /* TGAuthorSignatureMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGAuthorSignatureMediaAttachment.h; sourceTree = "<group>"; };
D01777991F1F961D0044446D /* TGAuthorSignatureMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGAuthorSignatureMediaAttachment.m; sourceTree = "<group>"; };
D017779A1F1F961D0044446D /* TGWebDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGWebDocument.h; sourceTree = "<group>"; };
D017779B1F1F961D0044446D /* TGWebDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGWebDocument.m; sourceTree = "<group>"; };
D017779C1F1F961D0044446D /* TGInvoiceMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGInvoiceMediaAttachment.h; sourceTree = "<group>"; };
D017779D1F1F961D0044446D /* TGInvoiceMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGInvoiceMediaAttachment.m; sourceTree = "<group>"; };
D017779E1F1F961D0044446D /* TGGameMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGGameMediaAttachment.h; sourceTree = "<group>"; };
D017779F1F1F961D0044446D /* TGGameMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGGameMediaAttachment.m; sourceTree = "<group>"; };
D01777A01F1F961D0044446D /* TGViaUserAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGViaUserAttachment.m; sourceTree = "<group>"; };
D01777A11F1F961D0044446D /* TGViaUserAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGViaUserAttachment.h; sourceTree = "<group>"; };
D01777A21F1F961D0044446D /* TGBotContextResultAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGBotContextResultAttachment.h; sourceTree = "<group>"; };
D01777A31F1F961D0044446D /* TGBotContextResultAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGBotContextResultAttachment.m; sourceTree = "<group>"; };
D01777A41F1F961D0044446D /* TGMessageEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntity.h; sourceTree = "<group>"; };
D01777A51F1F961D0044446D /* TGMessageEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntity.m; sourceTree = "<group>"; };
D01777A61F1F961D0044446D /* TGMessageEntityBold.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityBold.h; sourceTree = "<group>"; };
D01777A71F1F961D0044446D /* TGMessageEntityBold.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityBold.m; sourceTree = "<group>"; };
D01777A81F1F961D0044446D /* TGMessageEntityBotCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityBotCommand.h; sourceTree = "<group>"; };
D01777A91F1F961D0044446D /* TGMessageEntityBotCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityBotCommand.m; sourceTree = "<group>"; };
D01777AA1F1F961D0044446D /* TGMessageEntityCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityCode.h; sourceTree = "<group>"; };
D01777AB1F1F961D0044446D /* TGMessageEntityCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityCode.m; sourceTree = "<group>"; };
D01777AC1F1F961D0044446D /* TGMessageEntityEmail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityEmail.h; sourceTree = "<group>"; };
D01777AD1F1F961D0044446D /* TGMessageEntityEmail.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityEmail.m; sourceTree = "<group>"; };
D01777AE1F1F961D0044446D /* TGMessageEntityHashtag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityHashtag.h; sourceTree = "<group>"; };
D01777AF1F1F961D0044446D /* TGMessageEntityHashtag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityHashtag.m; sourceTree = "<group>"; };
D01777B01F1F961D0044446D /* TGMessageEntityItalic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityItalic.h; sourceTree = "<group>"; };
D01777B11F1F961D0044446D /* TGMessageEntityItalic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityItalic.m; sourceTree = "<group>"; };
D01777B21F1F961D0044446D /* TGMessageEntityMention.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityMention.h; sourceTree = "<group>"; };
D01777B31F1F961D0044446D /* TGMessageEntityMention.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityMention.m; sourceTree = "<group>"; };
D01777B41F1F961D0044446D /* TGMessageEntityMentionName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityMentionName.h; sourceTree = "<group>"; };
D01777B51F1F961D0044446D /* TGMessageEntityMentionName.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityMentionName.m; sourceTree = "<group>"; };
D01777B61F1F961D0044446D /* TGMessageEntityPre.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityPre.h; sourceTree = "<group>"; };
D01777B71F1F961D0044446D /* TGMessageEntityPre.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityPre.m; sourceTree = "<group>"; };
D01777B81F1F961D0044446D /* TGMessageEntityTextUrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityTextUrl.h; sourceTree = "<group>"; };
D01777B91F1F961D0044446D /* TGMessageEntityTextUrl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityTextUrl.m; sourceTree = "<group>"; };
D01777BA1F1F961D0044446D /* TGMessageEntityUrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntityUrl.h; sourceTree = "<group>"; };
D01777BB1F1F961D0044446D /* TGMessageEntityUrl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntityUrl.m; sourceTree = "<group>"; };
D01777BC1F1F961D0044446D /* TGMessageEntitiesAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMessageEntitiesAttachment.h; sourceTree = "<group>"; };
D01777BD1F1F961D0044446D /* TGMessageEntitiesAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMessageEntitiesAttachment.m; sourceTree = "<group>"; };
D01777BE1F1F961D0044446D /* TGBotReplyMarkup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGBotReplyMarkup.h; sourceTree = "<group>"; };
D01777BF1F1F961D0044446D /* TGBotReplyMarkup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGBotReplyMarkup.m; sourceTree = "<group>"; };
D01777C01F1F961D0044446D /* TGBotReplyMarkupButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGBotReplyMarkupButton.h; sourceTree = "<group>"; };
D01777C11F1F961D0044446D /* TGBotReplyMarkupButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGBotReplyMarkupButton.m; sourceTree = "<group>"; };
D01777C21F1F961D0044446D /* TGBotReplyMarkupRow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGBotReplyMarkupRow.h; sourceTree = "<group>"; };
D01777C31F1F961D0044446D /* TGBotReplyMarkupRow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGBotReplyMarkupRow.m; sourceTree = "<group>"; };
D01777C41F1F961D0044446D /* TGReplyMarkupAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGReplyMarkupAttachment.h; sourceTree = "<group>"; };
D01777C51F1F961D0044446D /* TGReplyMarkupAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGReplyMarkupAttachment.m; sourceTree = "<group>"; };
D01777C61F1F961D0044446D /* TGInstantPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGInstantPage.h; sourceTree = "<group>"; };
D01777C71F1F961D0044446D /* TGInstantPage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGInstantPage.m; sourceTree = "<group>"; };
D01777C81F1F961D0044446D /* TGWebPageMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGWebPageMediaAttachment.h; sourceTree = "<group>"; };
D01777C91F1F961D0044446D /* TGWebPageMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGWebPageMediaAttachment.m; sourceTree = "<group>"; };
D01777CA1F1F961D0044446D /* TGReplyMessageMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGReplyMessageMediaAttachment.h; sourceTree = "<group>"; };
D01777CB1F1F961D0044446D /* TGReplyMessageMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGReplyMessageMediaAttachment.m; sourceTree = "<group>"; };
D01777CC1F1F961D0044446D /* TGAudioMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGAudioMediaAttachment.h; sourceTree = "<group>"; };
D01777CD1F1F961D0044446D /* TGAudioMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGAudioMediaAttachment.m; sourceTree = "<group>"; };
D01777CE1F1F961D0044446D /* TGAudioWaveform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGAudioWaveform.h; sourceTree = "<group>"; };
D01777CF1F1F961D0044446D /* TGAudioWaveform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGAudioWaveform.m; sourceTree = "<group>"; };
D01777D01F1F961D0044446D /* TGStickerPackReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGStickerPackReference.h; sourceTree = "<group>"; };
D01777D11F1F961D0044446D /* TGStickerPackReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGStickerPackReference.m; sourceTree = "<group>"; };
D01777D21F1F961D0044446D /* TGDocumentAttributeFilename.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGDocumentAttributeFilename.m; sourceTree = "<group>"; };
D01777D31F1F961D0044446D /* TGDocumentAttributeImageSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGDocumentAttributeImageSize.h; sourceTree = "<group>"; };
D01777D41F1F961D0044446D /* TGDocumentAttributeImageSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGDocumentAttributeImageSize.m; sourceTree = "<group>"; };
D01777D51F1F961D0044446D /* TGDocumentAttributeSticker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGDocumentAttributeSticker.h; sourceTree = "<group>"; };
D01777D61F1F961D0044446D /* TGDocumentAttributeSticker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGDocumentAttributeSticker.m; sourceTree = "<group>"; };
D01777D71F1F961D0044446D /* TGDocumentAttributeVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGDocumentAttributeVideo.h; sourceTree = "<group>"; };
D01777D81F1F961D0044446D /* TGDocumentAttributeVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGDocumentAttributeVideo.m; sourceTree = "<group>"; };
D01777D91F1F961D0044446D /* TGDocumentAttributeAnimated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGDocumentAttributeAnimated.h; sourceTree = "<group>"; };
D01777DA1F1F961D0044446D /* TGDocumentAttributeAnimated.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGDocumentAttributeAnimated.m; sourceTree = "<group>"; };
D01777DB1F1F961D0044446D /* TGDocumentAttributeAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGDocumentAttributeAudio.h; sourceTree = "<group>"; };
D01777DC1F1F961D0044446D /* TGDocumentAttributeAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGDocumentAttributeAudio.m; sourceTree = "<group>"; };
D01777DD1F1F961D0044446D /* TGDocumentAttributeFilename.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGDocumentAttributeFilename.h; sourceTree = "<group>"; };
D01777DE1F1F961D0044446D /* TGDocumentMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGDocumentMediaAttachment.h; sourceTree = "<group>"; };
D01777DF1F1F961D0044446D /* TGDocumentMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGDocumentMediaAttachment.m; sourceTree = "<group>"; };
D01777E01F1F961D0044446D /* TGUnsupportedMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGUnsupportedMediaAttachment.h; sourceTree = "<group>"; };
D01777E11F1F961D0044446D /* TGUnsupportedMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGUnsupportedMediaAttachment.m; sourceTree = "<group>"; };
D01777E21F1F961D0044446D /* TGForwardedMessageMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGForwardedMessageMediaAttachment.h; sourceTree = "<group>"; };
D01777E31F1F961D0044446D /* TGForwardedMessageMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGForwardedMessageMediaAttachment.m; sourceTree = "<group>"; };
D01777E41F1F961D0044446D /* TGContactMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGContactMediaAttachment.h; sourceTree = "<group>"; };
D01777E51F1F961D0044446D /* TGContactMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGContactMediaAttachment.m; sourceTree = "<group>"; };
D01777E61F1F961D0044446D /* TGVideoInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGVideoInfo.h; sourceTree = "<group>"; };
D01777E71F1F961D0044446D /* TGVideoInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TGVideoInfo.mm; sourceTree = "<group>"; };
D01777E81F1F961D0044446D /* TGVideoMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGVideoMediaAttachment.h; sourceTree = "<group>"; };
D01777E91F1F961D0044446D /* TGVideoMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGVideoMediaAttachment.m; sourceTree = "<group>"; };
D01777EA1F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGLocalMessageMetaMediaAttachment.h; sourceTree = "<group>"; };
D01777EB1F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGLocalMessageMetaMediaAttachment.m; sourceTree = "<group>"; };
D01777EC1F1F961D0044446D /* TGLocationMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGLocationMediaAttachment.h; sourceTree = "<group>"; };
D01777ED1F1F961D0044446D /* TGLocationMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGLocationMediaAttachment.m; sourceTree = "<group>"; };
D01777EE1F1F961D0044446D /* TGImageMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGImageMediaAttachment.h; sourceTree = "<group>"; };
D01777EF1F1F961D0044446D /* TGImageMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGImageMediaAttachment.m; sourceTree = "<group>"; };
D01777F01F1F961D0044446D /* TGMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGMediaAttachment.h; sourceTree = "<group>"; };
D01777F11F1F961D0044446D /* TGMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGMediaAttachment.m; sourceTree = "<group>"; };
D01777F21F1F961D0044446D /* TGActionMediaAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TGActionMediaAttachment.h; sourceTree = "<group>"; };
D01777F31F1F961D0044446D /* TGActionMediaAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TGActionMediaAttachment.m; sourceTree = "<group>"; };
D01778671F1F99180044446D /* NSInputStream+TL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSInputStream+TL.h"; sourceTree = "<group>"; };
D01778681F1F99180044446D /* NSInputStream+TL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSInputStream+TL.m"; sourceTree = "<group>"; };
D017789B1F1FC99A0044446D /* LegacyComponentsInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyComponentsInternal.h; sourceTree = "<group>"; };
D017789C1F1FC99A0044446D /* LegacyComponentsInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LegacyComponentsInternal.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -46,12 +342,192 @@
D01777291F1F8F100044446D /* LegacyComponents */ = {
isa = PBXGroup;
children = (
D017776F1F1F91B00044446D /* Utils */,
D017776D1F1F91850044446D /* PS Coding */,
D017776C1F1F91780044446D /* Peers */,
D01777841F1F93430044446D /* Message */,
D017772A1F1F8F100044446D /* LegacyComponents.h */,
D017772B1F1F8F100044446D /* Info.plist */,
);
path = LegacyComponents;
sourceTree = "<group>";
};
D017776C1F1F91780044446D /* Peers */ = {
isa = PBXGroup;
children = (
D017778B1F1F961C0044446D /* TGPeerIdAdapter.h */,
D01777471F1F8FE60044446D /* TGBotInfo.h */,
D01777481F1F8FE60044446D /* TGBotInfo.m */,
D017774F1F1F8FE60044446D /* TGUser.h */,
D01777501F1F8FE60044446D /* TGUser.m */,
D017777C1F1F930B0044446D /* TGConversation.h */,
D017777D1F1F930B0044446D /* TGConversation.m */,
);
name = Peers;
sourceTree = "<group>";
};
D017776D1F1F91850044446D /* PS Coding */ = {
isa = PBXGroup;
children = (
D017773A1F1F8FE60044446D /* PSCoding.h */,
D017773B1F1F8FE60044446D /* PSData.h */,
D017773C1F1F8FE60044446D /* PSKeyValueCoder.h */,
D017773D1F1F8FE60044446D /* PSKeyValueCoder.m */,
D017773E1F1F8FE60044446D /* PSKeyValueDecoder.h */,
D017773F1F1F8FE60044446D /* PSKeyValueDecoder.m */,
D01777401F1F8FE60044446D /* PSKeyValueEncoder.h */,
D01777411F1F8FE60044446D /* PSKeyValueEncoder.m */,
D01777421F1F8FE60044446D /* PSKeyValueReader.h */,
D01777431F1F8FE60044446D /* PSKeyValueStore.h */,
D01777441F1F8FE60044446D /* PSKeyValueWriter.h */,
);
name = "PS Coding";
sourceTree = "<group>";
};
D017776F1F1F91B00044446D /* Utils */ = {
isa = PBXGroup;
children = (
D01777381F1F8FE60044446D /* LegacyComponentsGlobals.h */,
D017776A1F1F909E0044446D /* LegacyComponentsGlobals.m */,
D017789B1F1FC99A0044446D /* LegacyComponentsInternal.h */,
D017789C1F1FC99A0044446D /* LegacyComponentsInternal.m */,
D01777491F1F8FE60044446D /* TGLocalization.h */,
D017774A1F1F8FE60044446D /* TGLocalization.m */,
D017774B1F1F8FE60044446D /* TGPluralization.h */,
D017774C1F1F8FE60044446D /* TGPluralization.m */,
D017774D1F1F8FE60044446D /* TGStringUtils.h */,
D017774E1F1F8FE60044446D /* TGStringUtils.mm */,
D01777701F1F92420044446D /* TGPhoneUtils.h */,
D01777711F1F92420044446D /* TGPhoneUtils.m */,
D01777781F1F927A0044446D /* NSObject+TGLock.h */,
D01777791F1F927A0044446D /* NSObject+TGLock.m */,
D01777741F1F92570044446D /* RMPhoneFormat.h */,
D01777751F1F92570044446D /* RMPhoneFormat.m */,
D01778671F1F99180044446D /* NSInputStream+TL.h */,
D01778681F1F99180044446D /* NSInputStream+TL.m */,
);
name = Utils;
sourceTree = "<group>";
};
D01777841F1F93430044446D /* Message */ = {
isa = PBXGroup;
children = (
D01777891F1F961C0044446D /* TGTextCheckingResult.h */,
D017778A1F1F961C0044446D /* TGTextCheckingResult.m */,
D017778C1F1F961C0044446D /* TGChannelBannedRights.h */,
D017778D1F1F961D0044446D /* TGChannelBannedRights.m */,
D017778E1F1F961D0044446D /* TGChannelAdminRights.h */,
D017778F1F1F961D0044446D /* TGChannelAdminRights.m */,
D01777901F1F961D0044446D /* TGDatabaseMessageDraft.h */,
D01777911F1F961D0044446D /* TGDatabaseMessageDraft.m */,
D01777451F1F8FE60044446D /* TGBotComandInfo.h */,
D01777461F1F8FE60044446D /* TGBotComandInfo.m */,
D01777921F1F961D0044446D /* TGMessageGroup.h */,
D01777931F1F961D0044446D /* TGMessageGroup.m */,
D01777941F1F961D0044446D /* TGMessageHole.h */,
D01777951F1F961D0044446D /* TGMessageHole.m */,
D01777961F1F961D0044446D /* TGMessageViewCountContentProperty.h */,
D01777971F1F961D0044446D /* TGMessageViewCountContentProperty.m */,
D01777981F1F961D0044446D /* TGAuthorSignatureMediaAttachment.h */,
D01777991F1F961D0044446D /* TGAuthorSignatureMediaAttachment.m */,
D017779A1F1F961D0044446D /* TGWebDocument.h */,
D017779B1F1F961D0044446D /* TGWebDocument.m */,
D017779C1F1F961D0044446D /* TGInvoiceMediaAttachment.h */,
D017779D1F1F961D0044446D /* TGInvoiceMediaAttachment.m */,
D017779E1F1F961D0044446D /* TGGameMediaAttachment.h */,
D017779F1F1F961D0044446D /* TGGameMediaAttachment.m */,
D01777A11F1F961D0044446D /* TGViaUserAttachment.h */,
D01777A01F1F961D0044446D /* TGViaUserAttachment.m */,
D01777A21F1F961D0044446D /* TGBotContextResultAttachment.h */,
D01777A31F1F961D0044446D /* TGBotContextResultAttachment.m */,
D01777A41F1F961D0044446D /* TGMessageEntity.h */,
D01777A51F1F961D0044446D /* TGMessageEntity.m */,
D01777A61F1F961D0044446D /* TGMessageEntityBold.h */,
D01777A71F1F961D0044446D /* TGMessageEntityBold.m */,
D01777A81F1F961D0044446D /* TGMessageEntityBotCommand.h */,
D01777A91F1F961D0044446D /* TGMessageEntityBotCommand.m */,
D01777AA1F1F961D0044446D /* TGMessageEntityCode.h */,
D01777AB1F1F961D0044446D /* TGMessageEntityCode.m */,
D01777AC1F1F961D0044446D /* TGMessageEntityEmail.h */,
D01777AD1F1F961D0044446D /* TGMessageEntityEmail.m */,
D01777AE1F1F961D0044446D /* TGMessageEntityHashtag.h */,
D01777AF1F1F961D0044446D /* TGMessageEntityHashtag.m */,
D01777B01F1F961D0044446D /* TGMessageEntityItalic.h */,
D01777B11F1F961D0044446D /* TGMessageEntityItalic.m */,
D01777B21F1F961D0044446D /* TGMessageEntityMention.h */,
D01777B31F1F961D0044446D /* TGMessageEntityMention.m */,
D01777B41F1F961D0044446D /* TGMessageEntityMentionName.h */,
D01777B51F1F961D0044446D /* TGMessageEntityMentionName.m */,
D01777B61F1F961D0044446D /* TGMessageEntityPre.h */,
D01777B71F1F961D0044446D /* TGMessageEntityPre.m */,
D01777B81F1F961D0044446D /* TGMessageEntityTextUrl.h */,
D01777B91F1F961D0044446D /* TGMessageEntityTextUrl.m */,
D01777BA1F1F961D0044446D /* TGMessageEntityUrl.h */,
D01777BB1F1F961D0044446D /* TGMessageEntityUrl.m */,
D01777BC1F1F961D0044446D /* TGMessageEntitiesAttachment.h */,
D01777BD1F1F961D0044446D /* TGMessageEntitiesAttachment.m */,
D01777BE1F1F961D0044446D /* TGBotReplyMarkup.h */,
D01777BF1F1F961D0044446D /* TGBotReplyMarkup.m */,
D01777C01F1F961D0044446D /* TGBotReplyMarkupButton.h */,
D01777C11F1F961D0044446D /* TGBotReplyMarkupButton.m */,
D01777C21F1F961D0044446D /* TGBotReplyMarkupRow.h */,
D01777C31F1F961D0044446D /* TGBotReplyMarkupRow.m */,
D01777C41F1F961D0044446D /* TGReplyMarkupAttachment.h */,
D01777C51F1F961D0044446D /* TGReplyMarkupAttachment.m */,
D01777C61F1F961D0044446D /* TGInstantPage.h */,
D01777C71F1F961D0044446D /* TGInstantPage.m */,
D01777C81F1F961D0044446D /* TGWebPageMediaAttachment.h */,
D01777C91F1F961D0044446D /* TGWebPageMediaAttachment.m */,
D01777CA1F1F961D0044446D /* TGReplyMessageMediaAttachment.h */,
D01777CB1F1F961D0044446D /* TGReplyMessageMediaAttachment.m */,
D01777CC1F1F961D0044446D /* TGAudioMediaAttachment.h */,
D01777CD1F1F961D0044446D /* TGAudioMediaAttachment.m */,
D01777CE1F1F961D0044446D /* TGAudioWaveform.h */,
D01777CF1F1F961D0044446D /* TGAudioWaveform.m */,
D01777D01F1F961D0044446D /* TGStickerPackReference.h */,
D01777D11F1F961D0044446D /* TGStickerPackReference.m */,
D01777DD1F1F961D0044446D /* TGDocumentAttributeFilename.h */,
D01777D21F1F961D0044446D /* TGDocumentAttributeFilename.m */,
D01777D31F1F961D0044446D /* TGDocumentAttributeImageSize.h */,
D01777D41F1F961D0044446D /* TGDocumentAttributeImageSize.m */,
D01777D51F1F961D0044446D /* TGDocumentAttributeSticker.h */,
D01777D61F1F961D0044446D /* TGDocumentAttributeSticker.m */,
D01777D71F1F961D0044446D /* TGDocumentAttributeVideo.h */,
D01777D81F1F961D0044446D /* TGDocumentAttributeVideo.m */,
D01777D91F1F961D0044446D /* TGDocumentAttributeAnimated.h */,
D01777DA1F1F961D0044446D /* TGDocumentAttributeAnimated.m */,
D01777DB1F1F961D0044446D /* TGDocumentAttributeAudio.h */,
D01777DC1F1F961D0044446D /* TGDocumentAttributeAudio.m */,
D01777DE1F1F961D0044446D /* TGDocumentMediaAttachment.h */,
D01777DF1F1F961D0044446D /* TGDocumentMediaAttachment.m */,
D01777E01F1F961D0044446D /* TGUnsupportedMediaAttachment.h */,
D01777E11F1F961D0044446D /* TGUnsupportedMediaAttachment.m */,
D01777E21F1F961D0044446D /* TGForwardedMessageMediaAttachment.h */,
D01777E31F1F961D0044446D /* TGForwardedMessageMediaAttachment.m */,
D01777E41F1F961D0044446D /* TGContactMediaAttachment.h */,
D01777E51F1F961D0044446D /* TGContactMediaAttachment.m */,
D01777E61F1F961D0044446D /* TGVideoInfo.h */,
D01777E71F1F961D0044446D /* TGVideoInfo.mm */,
D01777E81F1F961D0044446D /* TGVideoMediaAttachment.h */,
D01777E91F1F961D0044446D /* TGVideoMediaAttachment.m */,
D01777EA1F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.h */,
D01777EB1F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.m */,
D01777EC1F1F961D0044446D /* TGLocationMediaAttachment.h */,
D01777ED1F1F961D0044446D /* TGLocationMediaAttachment.m */,
D01777EE1F1F961D0044446D /* TGImageMediaAttachment.h */,
D01777EF1F1F961D0044446D /* TGImageMediaAttachment.m */,
D01777F01F1F961D0044446D /* TGMediaAttachment.h */,
D01777F11F1F961D0044446D /* TGMediaAttachment.m */,
D01777F21F1F961D0044446D /* TGActionMediaAttachment.h */,
D01777F31F1F961D0044446D /* TGActionMediaAttachment.m */,
D01777801F1F93250044446D /* TGImageInfo.h */,
D01777811F1F93250044446D /* TGImageInfo.mm */,
D01777851F1F93550044446D /* TGMessage.h */,
D01777861F1F93550044446D /* TGMessage.mm */,
);
name = Message;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -59,7 +535,84 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
D01778691F1F99180044446D /* NSInputStream+TL.h in Headers */,
D01777531F1F8FE60044446D /* PSCoding.h in Headers */,
D017781D1F1F961D0044446D /* TGMessageEntityMention.h in Headers */,
D01778031F1F961D0044446D /* TGAuthorSignatureMediaAttachment.h in Headers */,
D01778511F1F961D0044446D /* TGVideoInfo.h in Headers */,
D01777601F1F8FE60044446D /* TGBotInfo.h in Headers */,
D01778191F1F961D0044446D /* TGMessageEntityHashtag.h in Headers */,
D01777721F1F92420044446D /* TGPhoneUtils.h in Headers */,
D01777761F1F92570044446D /* RMPhoneFormat.h in Headers */,
D01777F61F1F961D0044446D /* TGPeerIdAdapter.h in Headers */,
D017782F1F1F961D0044446D /* TGReplyMarkupAttachment.h in Headers */,
D01778371F1F961D0044446D /* TGAudioMediaAttachment.h in Headers */,
D017775C1F1F8FE60044446D /* PSKeyValueStore.h in Headers */,
D01777511F1F8FE60044446D /* LegacyComponentsGlobals.h in Headers */,
D01778211F1F961D0044446D /* TGMessageEntityPre.h in Headers */,
D017772C1F1F8F100044446D /* LegacyComponents.h in Headers */,
D01778111F1F961D0044446D /* TGMessageEntityBold.h in Headers */,
D017789D1F1FC99A0044446D /* LegacyComponentsInternal.h in Headers */,
D01777621F1F8FE60044446D /* TGLocalization.h in Headers */,
D01778481F1F961D0044446D /* TGDocumentAttributeFilename.h in Headers */,
D01778171F1F961D0044446D /* TGMessageEntityEmail.h in Headers */,
D01777F41F1F961D0044446D /* TGTextCheckingResult.h in Headers */,
D01778231F1F961D0044446D /* TGMessageEntityTextUrl.h in Headers */,
D01778391F1F961D0044446D /* TGAudioWaveform.h in Headers */,
D01777FF1F1F961D0044446D /* TGMessageHole.h in Headers */,
D017777E1F1F930B0044446D /* TGConversation.h in Headers */,
D017781F1F1F961D0044446D /* TGMessageEntityMentionName.h in Headers */,
D01777551F1F8FE60044446D /* PSKeyValueCoder.h in Headers */,
D01778011F1F961D0044446D /* TGMessageViewCountContentProperty.h in Headers */,
D017777A1F1F927A0044446D /* NSObject+TGLock.h in Headers */,
D01778311F1F961D0044446D /* TGInstantPage.h in Headers */,
D01778271F1F961D0044446D /* TGMessageEntitiesAttachment.h in Headers */,
D017775B1F1F8FE60044446D /* PSKeyValueReader.h in Headers */,
D01778131F1F961D0044446D /* TGMessageEntityBotCommand.h in Headers */,
D017782B1F1F961D0044446D /* TGBotReplyMarkupButton.h in Headers */,
D017784D1F1F961D0044446D /* TGForwardedMessageMediaAttachment.h in Headers */,
D01777F71F1F961D0044446D /* TGChannelBannedRights.h in Headers */,
D01778401F1F961D0044446D /* TGDocumentAttributeSticker.h in Headers */,
D017783E1F1F961D0044446D /* TGDocumentAttributeImageSize.h in Headers */,
D017780F1F1F961D0044446D /* TGMessageEntity.h in Headers */,
D01777681F1F8FE60044446D /* TGUser.h in Headers */,
D01778571F1F961D0044446D /* TGLocationMediaAttachment.h in Headers */,
D01778531F1F961D0044446D /* TGVideoMediaAttachment.h in Headers */,
D01777641F1F8FE60044446D /* TGPluralization.h in Headers */,
D017783B1F1F961D0044446D /* TGStickerPackReference.h in Headers */,
D01777571F1F8FE60044446D /* PSKeyValueDecoder.h in Headers */,
D017780D1F1F961D0044446D /* TGBotContextResultAttachment.h in Headers */,
D01778071F1F961D0044446D /* TGInvoiceMediaAttachment.h in Headers */,
D01778421F1F961D0044446D /* TGDocumentAttributeVideo.h in Headers */,
D01778331F1F961D0044446D /* TGWebPageMediaAttachment.h in Headers */,
D01777821F1F93250044446D /* TGImageInfo.h in Headers */,
D017782D1F1F961D0044446D /* TGBotReplyMarkupRow.h in Headers */,
D017775E1F1F8FE60044446D /* TGBotComandInfo.h in Headers */,
D01777871F1F93550044446D /* TGMessage.h in Headers */,
D01777591F1F8FE60044446D /* PSKeyValueEncoder.h in Headers */,
D017784B1F1F961D0044446D /* TGUnsupportedMediaAttachment.h in Headers */,
D01778461F1F961D0044446D /* TGDocumentAttributeAudio.h in Headers */,
D017785B1F1F961D0044446D /* TGMediaAttachment.h in Headers */,
D01778351F1F961D0044446D /* TGReplyMessageMediaAttachment.h in Headers */,
D017780C1F1F961D0044446D /* TGViaUserAttachment.h in Headers */,
D017775D1F1F8FE60044446D /* PSKeyValueWriter.h in Headers */,
D01777FD1F1F961D0044446D /* TGMessageGroup.h in Headers */,
D01777541F1F8FE60044446D /* PSData.h in Headers */,
D01778091F1F961D0044446D /* TGGameMediaAttachment.h in Headers */,
D01778551F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.h in Headers */,
D01778151F1F961D0044446D /* TGMessageEntityCode.h in Headers */,
D01778251F1F961D0044446D /* TGMessageEntityUrl.h in Headers */,
D01777F91F1F961D0044446D /* TGChannelAdminRights.h in Headers */,
D01778051F1F961D0044446D /* TGWebDocument.h in Headers */,
D017781B1F1F961D0044446D /* TGMessageEntityItalic.h in Headers */,
D01777661F1F8FE60044446D /* TGStringUtils.h in Headers */,
D017785D1F1F961D0044446D /* TGActionMediaAttachment.h in Headers */,
D017784F1F1F961D0044446D /* TGContactMediaAttachment.h in Headers */,
D01778491F1F961D0044446D /* TGDocumentMediaAttachment.h in Headers */,
D01778441F1F961D0044446D /* TGDocumentAttributeAnimated.h in Headers */,
D01778591F1F961D0044446D /* TGImageMediaAttachment.h in Headers */,
D01778291F1F961D0044446D /* TGBotReplyMarkup.h in Headers */,
D01777FB1F1F961D0044446D /* TGDatabaseMessageDraft.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -95,8 +648,7 @@
TargetAttributes = {
D01777261F1F8F100044446D = {
CreatedOnToolsVersion = 8.3.2;
DevelopmentTeam = X834Q8SBVP;
ProvisioningStyle = Automatic;
ProvisioningStyle = Manual;
};
};
};
@@ -132,13 +684,226 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D01778241F1F961D0044446D /* TGMessageEntityTextUrl.m in Sources */,
D01778471F1F961D0044446D /* TGDocumentAttributeAudio.m in Sources */,
D01778181F1F961D0044446D /* TGMessageEntityEmail.m in Sources */,
D017784A1F1F961D0044446D /* TGDocumentMediaAttachment.m in Sources */,
D017782E1F1F961D0044446D /* TGBotReplyMarkupRow.m in Sources */,
D01778561F1F961D0044446D /* TGLocalMessageMetaMediaAttachment.m in Sources */,
D01778081F1F961D0044446D /* TGInvoiceMediaAttachment.m in Sources */,
D017782C1F1F961D0044446D /* TGBotReplyMarkupButton.m in Sources */,
D01777771F1F92570044446D /* RMPhoneFormat.m in Sources */,
D017781E1F1F961D0044446D /* TGMessageEntityMention.m in Sources */,
D01777FC1F1F961D0044446D /* TGDatabaseMessageDraft.m in Sources */,
D017777F1F1F930B0044446D /* TGConversation.m in Sources */,
D01777F51F1F961D0044446D /* TGTextCheckingResult.m in Sources */,
D01778581F1F961D0044446D /* TGLocationMediaAttachment.m in Sources */,
D017785C1F1F961D0044446D /* TGMediaAttachment.m in Sources */,
D01778061F1F961D0044446D /* TGWebDocument.m in Sources */,
D01778001F1F961D0044446D /* TGMessageHole.m in Sources */,
D01777FA1F1F961D0044446D /* TGChannelAdminRights.m in Sources */,
D01778041F1F961D0044446D /* TGAuthorSignatureMediaAttachment.m in Sources */,
D01778411F1F961D0044446D /* TGDocumentAttributeSticker.m in Sources */,
D01778221F1F961D0044446D /* TGMessageEntityPre.m in Sources */,
D01777561F1F8FE60044446D /* PSKeyValueCoder.m in Sources */,
D01777831F1F93250044446D /* TGImageInfo.mm in Sources */,
D017780E1F1F961D0044446D /* TGBotContextResultAttachment.m in Sources */,
D017781A1F1F961D0044446D /* TGMessageEntityHashtag.m in Sources */,
D01777881F1F93550044446D /* TGMessage.mm in Sources */,
D017782A1F1F961D0044446D /* TGBotReplyMarkup.m in Sources */,
D01778321F1F961D0044446D /* TGInstantPage.m in Sources */,
D017776B1F1F909E0044446D /* LegacyComponentsGlobals.m in Sources */,
D01778301F1F961D0044446D /* TGReplyMarkupAttachment.m in Sources */,
D01778501F1F961D0044446D /* TGContactMediaAttachment.m in Sources */,
D017786A1F1F99180044446D /* NSInputStream+TL.m in Sources */,
D017777B1F1F927A0044446D /* NSObject+TGLock.m in Sources */,
D01778281F1F961D0044446D /* TGMessageEntitiesAttachment.m in Sources */,
D01777581F1F8FE60044446D /* PSKeyValueDecoder.m in Sources */,
D017783F1F1F961D0044446D /* TGDocumentAttributeImageSize.m in Sources */,
D017783D1F1F961D0044446D /* TGDocumentAttributeFilename.m in Sources */,
D017780B1F1F961D0044446D /* TGViaUserAttachment.m in Sources */,
D01777671F1F8FE60044446D /* TGStringUtils.mm in Sources */,
D017783C1F1F961D0044446D /* TGStickerPackReference.m in Sources */,
D017775A1F1F8FE60044446D /* PSKeyValueEncoder.m in Sources */,
D01778021F1F961D0044446D /* TGMessageViewCountContentProperty.m in Sources */,
D01778261F1F961D0044446D /* TGMessageEntityUrl.m in Sources */,
D017785A1F1F961D0044446D /* TGImageMediaAttachment.m in Sources */,
D017784C1F1F961D0044446D /* TGUnsupportedMediaAttachment.m in Sources */,
D01777611F1F8FE60044446D /* TGBotInfo.m in Sources */,
D01778521F1F961D0044446D /* TGVideoInfo.mm in Sources */,
D01777651F1F8FE60044446D /* TGPluralization.m in Sources */,
D01777F81F1F961D0044446D /* TGChannelBannedRights.m in Sources */,
D01778451F1F961D0044446D /* TGDocumentAttributeAnimated.m in Sources */,
D01778141F1F961D0044446D /* TGMessageEntityBotCommand.m in Sources */,
D01778541F1F961D0044446D /* TGVideoMediaAttachment.m in Sources */,
D01778361F1F961D0044446D /* TGReplyMessageMediaAttachment.m in Sources */,
D01778341F1F961D0044446D /* TGWebPageMediaAttachment.m in Sources */,
D01778431F1F961D0044446D /* TGDocumentAttributeVideo.m in Sources */,
D01778101F1F961D0044446D /* TGMessageEntity.m in Sources */,
D01778381F1F961D0044446D /* TGAudioMediaAttachment.m in Sources */,
D017775F1F1F8FE60044446D /* TGBotComandInfo.m in Sources */,
D01777FE1F1F961D0044446D /* TGMessageGroup.m in Sources */,
D01778121F1F961D0044446D /* TGMessageEntityBold.m in Sources */,
D01778201F1F961D0044446D /* TGMessageEntityMentionName.m in Sources */,
D017780A1F1F961D0044446D /* TGGameMediaAttachment.m in Sources */,
D017783A1F1F961D0044446D /* TGAudioWaveform.m in Sources */,
D01777631F1F8FE60044446D /* TGLocalization.m in Sources */,
D01777731F1F92420044446D /* TGPhoneUtils.m in Sources */,
D017781C1F1F961D0044446D /* TGMessageEntityItalic.m in Sources */,
D01777691F1F8FE60044446D /* TGUser.m in Sources */,
D017789E1F1FC99A0044446D /* LegacyComponentsInternal.m in Sources */,
D017784E1F1F961D0044446D /* TGForwardedMessageMediaAttachment.m in Sources */,
D01778161F1F961D0044446D /* TGMessageEntityCode.m in Sources */,
D017785E1F1F961D0044446D /* TGActionMediaAttachment.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
D017772D1F1F8F100044446D /* Debug */ = {
D017772D1F1F8F100044446D /* Debug AppStore */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = "Debug AppStore";
};
D017772E1F1F8F100044446D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
D01777301F1F8F100044446D /* Debug AppStore */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = LegacyComponents/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
PRODUCT_BUNDLE_IDENTIFIER = org.Telegram.LegacyComponents;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = "Debug AppStore";
};
D01777311F1F8F100044446D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = LegacyComponents/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
PRODUCT_BUNDLE_IDENTIFIER = org.Telegram.LegacyComponents;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;
};
D01778931F1FA58C0044446D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
@@ -190,7 +955,29 @@
};
name = Debug;
};
D017772E1F1F8F100044446D /* Release */ = {
D01778941F1FA58C0044446D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = LegacyComponents/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
PRODUCT_BUNDLE_IDENTIFIER = org.Telegram.LegacyComponents;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
};
D01778951F1FA5960044446D /* Hockeyapp */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
@@ -234,43 +1021,29 @@
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
name = Hockeyapp;
};
D01777301F1F8F100044446D /* Debug */ = {
D01778961F1FA5960044446D /* Hockeyapp */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = X834Q8SBVP;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = LegacyComponents/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACH_O_TYPE = staticlib;
PRODUCT_BUNDLE_IDENTIFIER = org.Telegram.LegacyComponents;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
};
D01777311F1F8F100044446D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = X834Q8SBVP;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = LegacyComponents/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.Telegram.LegacyComponents;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
name = Hockeyapp;
};
/* End XCBuildConfiguration section */
@@ -278,8 +1051,10 @@
D01777211F1F8F100044446D /* Build configuration list for PBXProject "LegacyComponents" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D017772D1F1F8F100044446D /* Debug */,
D017772D1F1F8F100044446D /* Debug AppStore */,
D01778931F1FA58C0044446D /* Debug */,
D017772E1F1F8F100044446D /* Release */,
D01778951F1FA5960044446D /* Hockeyapp */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@@ -287,10 +1062,13 @@
D017772F1F1F8F100044446D /* Build configuration list for PBXNativeTarget "LegacyComponents" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D01777301F1F8F100044446D /* Debug */,
D01777301F1F8F100044446D /* Debug AppStore */,
D01778941F1FA58C0044446D /* Debug */,
D01777311F1F8F100044446D /* Release */,
D01778961F1FA5960044446D /* Hockeyapp */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};

View File

@@ -1,11 +1,3 @@
//
// LegacyComponents.h
// LegacyComponents
//
// Created by Peter on 7/19/17.
// Copyright © 2017 Telegram. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for LegacyComponents.
@@ -14,6 +6,81 @@ FOUNDATION_EXPORT double LegacyComponentsVersionNumber;
//! Project version string for LegacyComponents.
FOUNDATION_EXPORT const unsigned char LegacyComponentsVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <LegacyComponents/PublicHeader.h>
#import <LegacyComponents/LegacyComponentsGlobals.h>
#import <LegacyComponents/TGLocalization.h>
#import <LegacyComponents/TGPluralization.h>
#import <LegacyComponents/TGStringUtils.h>
#import <LegacyComponents/TGPhoneUtils.h>
#import <LegacyComponents/NSObject+TGLock.h>
#import <LegacyComponents/RMPhoneFormat.h>
#import <LegacyComponents/NSInputStream+TL.h>
#import <LegacyComponents/PSCoding.h>
#import <LegacyComponents/PSData.h>
#import <LegacyComponents/PSKeyValueCoder.h>
#import <LegacyComponents/PSKeyValueDecoder.h>
#import <LegacyComponents/PSKeyValueEncoder.h>
#import <LegacyComponents/PSKeyValueReader.h>
#import <LegacyComponents/PSKeyValueStore.h>
#import <LegacyComponents/PSKeyValueWriter.h>
#import <LegacyComponents/TGPeerIdAdapter.h>
#import <LegacyComponents/TGUser.h>
#import <LegacyComponents/TGBotInfo.h>
#import <LegacyComponents/TGBotComandInfo.h>
#import <LegacyComponents/TGConversation.h>
#import <LegacyComponents/TGTextCheckingResult.h>
#import <LegacyComponents/TGChannelBannedRights.h>
#import <LegacyComponents/TGChannelAdminRights.h>
#import <LegacyComponents/TGDatabaseMessageDraft.h>
#import <LegacyComponents/TGMessageGroup.h>
#import <LegacyComponents/TGMessageHole.h>
#import <LegacyComponents/TGMessageViewCountContentProperty.h>
#import <LegacyComponents/TGAuthorSignatureMediaAttachment.h>
#import <LegacyComponents/TGWebDocument.h>
#import <LegacyComponents/TGInvoiceMediaAttachment.h>
#import <LegacyComponents/TGGameMediaAttachment.h>
#import <LegacyComponents/TGViaUserAttachment.h>
#import <LegacyComponents/TGBotContextResultAttachment.h>
#import <LegacyComponents/TGMessageEntity.h>
#import <LegacyComponents/TGMessageEntityBold.h>
#import <LegacyComponents/TGMessageEntityBotCommand.h>
#import <LegacyComponents/TGMessageEntityCode.h>
#import <LegacyComponents/TGMessageEntityEmail.h>
#import <LegacyComponents/TGMessageEntityHashtag.h>
#import <LegacyComponents/TGMessageEntityItalic.h>
#import <LegacyComponents/TGMessageEntityMention.h>
#import <LegacyComponents/TGMessageEntityMentionName.h>
#import <LegacyComponents/TGMessageEntityPre.h>
#import <LegacyComponents/TGMessageEntityTextUrl.h>
#import <LegacyComponents/TGMessageEntityUrl.h>
#import <LegacyComponents/TGMessageEntitiesAttachment.h>
#import <LegacyComponents/TGBotReplyMarkup.h>
#import <LegacyComponents/TGBotReplyMarkupButton.h>
#import <LegacyComponents/TGBotReplyMarkupRow.h>
#import <LegacyComponents/TGReplyMarkupAttachment.h>
#import <LegacyComponents/TGInstantPage.h>
#import <LegacyComponents/TGWebPageMediaAttachment.h>
#import <LegacyComponents/TGAudioMediaAttachment.h>
#import <LegacyComponents/TGAudioWaveform.h>
#import <LegacyComponents/TGStickerPackReference.h>
#import <LegacyComponents/TGDocumentAttributeFilename.h>
#import <LegacyComponents/TGDocumentAttributeImageSize.h>
#import <LegacyComponents/TGDocumentAttributeSticker.h>
#import <LegacyComponents/TGDocumentAttributeVideo.h>
#import <LegacyComponents/TGDocumentAttributeAnimated.h>
#import <LegacyComponents/TGDocumentAttributeAudio.h>
#import <LegacyComponents/TGDocumentMediaAttachment.h>
#import <LegacyComponents/TGUnsupportedMediaAttachment.h>
#import <LegacyComponents/TGForwardedMessageMediaAttachment.h>
#import <LegacyComponents/TGContactMediaAttachment.h>
#import <LegacyComponents/TGVideoInfo.h>
#import <LegacyComponents/TGVideoMediaAttachment.h>
#import <LegacyComponents/TGLocalMessageMetaMediaAttachment.h>
#import <LegacyComponents/TGLocationMediaAttachment.h>
#import <LegacyComponents/TGImageMediaAttachment.h>
#import <LegacyComponents/TGMediaAttachment.h>
#import <LegacyComponents/TGImageInfo.h>
#import <LegacyComponents/TGMessage.h>

View File

@@ -0,0 +1,18 @@
#import <Foundation/Foundation.h>
@class TGLocalization;
@protocol LegacyComponentsGlobalsProvider <NSObject>
- (TGLocalization *)effectiveLocalization;
- (void)log:(NSString *)format :(va_list)args;
@end
@interface LegacyComponentsGlobals : NSObject
+ (void)setProvider:(id<LegacyComponentsGlobalsProvider>)provider;
+ (id<LegacyComponentsGlobalsProvider>)provider;
@end

View File

@@ -0,0 +1,19 @@
#import <Foundation/Foundation.h>
#import "LegacyComponentsInternal.h"
#import "TGLocalization.h"
static id<LegacyComponentsGlobalsProvider> _provider;
@implementation LegacyComponentsGlobals
+ (void)setProvider:(id<LegacyComponentsGlobalsProvider>)provider {
_provider = provider;
}
+ (id<LegacyComponentsGlobalsProvider>)provider {
return _provider;
}
@end

View File

@@ -0,0 +1,18 @@
#import "LegacyComponentsGlobals.h"
@class TGLocalization;
#ifdef __cplusplus
extern "C" {
#endif
TGLocalization *effectiveLocalization();
NSString *TGLocalized(NSString *s);
bool TGObjectCompare(id obj1, id obj2);
bool TGStringCompare(NSString *s1, NSString *s2);
void TGLog(NSString *format, ...);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,36 @@
#import "LegacyComponentsInternal.h"
#import "TGLocalization.h"
TGLocalization *effectiveLocalization() {
return [[LegacyComponentsGlobals provider] effectiveLocalization];
}
NSString *TGLocalized(NSString *s) {
return [effectiveLocalization() get:s];
}
bool TGObjectCompare(id obj1, id obj2) {
if (obj1 == nil && obj2 == nil)
return true;
return [obj1 isEqual:obj2];
}
bool TGStringCompare(NSString *s1, NSString *s2) {
if (s1.length == 0 && s2.length == 0)
return true;
if ((s1 == nil) != (s2 == nil))
return false;
return s1 == nil || [s1 isEqualToString:s2];
}
void TGLog(NSString *format, ...)
{
va_list L;
va_start(L, format);
[[LegacyComponentsGlobals provider] log:format :L];
va_end(L);
}

View File

@@ -0,0 +1,28 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <Foundation/Foundation.h>
@interface NSInputStream (TL)
- (int32_t)readInt32;
- (int32_t)readInt32:(bool *)failed __attribute__((nonnull(1)));
- (int64_t)readInt64;
- (int64_t)readInt64:(bool *)failed __attribute__((nonnull(1)));
- (double)readDouble;
- (double)readDouble:(bool *)failed __attribute__((nonnull(1)));
- (NSData *)readData:(int)length;
- (NSData *)readData:(int)length failed:(bool *)failed __attribute__((nonnull(2)));
- (NSMutableData *)readMutableData:(int)length;
- (NSMutableData *)readMutableData:(int)length failed:(bool *)failed __attribute__((nonnull(2)));
- (NSString *)readString;
- (NSString *)readString:(bool *)failed __attribute__((nonnull(1)));
- (NSData *)readBytes;
- (NSData *)readBytes:(bool *)failed __attribute__((nonnull(1)));
@end

View File

@@ -0,0 +1,390 @@
#import "NSInputStream+TL.h"
#import "LegacyComponentsInternal.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");
@throw [[NSException alloc] initWithName:@"NSInputStream+TLException" reason:@"readInt32 end of stream" userInfo:@{}];
}
#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

View File

@@ -0,0 +1,23 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <Foundation/Foundation.h>
#import <pthread.h>
#define TG_SYNCHRONIZED_DEFINE(lock) pthread_mutex_t _TG_SYNCHRONIZED_##lock
#define TG_SYNCHRONIZED_INIT(lock) pthread_mutex_init(&_TG_SYNCHRONIZED_##lock, NULL)
#define TG_SYNCHRONIZED_BEGIN(lock) pthread_mutex_lock(&_TG_SYNCHRONIZED_##lock);
#define TG_SYNCHRONIZED_END(lock) pthread_mutex_unlock(&_TG_SYNCHRONIZED_##lock);
@interface NSObject (TGLock)
- (void)tgLockObject;
- (void)tgUnlockObject;
@end

View File

@@ -0,0 +1,73 @@
#import "NSObject+TGLock.h"
#import <objc/runtime.h>
static const char *lockPropertyKey = "TGObjectLock::lock";
@interface TGObjectLockImpl : NSObject
{
TG_SYNCHRONIZED_DEFINE(objectLock);
}
- (void)tgTakeLock;
- (void)tgFreeLock;
@end
@implementation TGObjectLockImpl
- (id)init
{
self = [super init];
if (self != nil)
{
TG_SYNCHRONIZED_INIT(objectLock);
}
return self;
}
- (void)tgTakeLock
{
TG_SYNCHRONIZED_BEGIN(objectLock);
}
- (void)tgFreeLock
{
TG_SYNCHRONIZED_END(objectLock);
}
@end
@implementation NSObject (TGLock)
- (void)tgLockObject
{
TGObjectLockImpl *lock = (TGObjectLockImpl *)objc_getAssociatedObject(self, lockPropertyKey);
if (lock == nil)
{
@synchronized(self)
{
lock = [[TGObjectLockImpl alloc] init];
objc_setAssociatedObject(self, lockPropertyKey, lock, OBJC_ASSOCIATION_RETAIN);
}
}
[lock tgTakeLock];
}
- (void)tgUnlockObject
{
TGObjectLockImpl *lock = (TGObjectLockImpl *)objc_getAssociatedObject(self, lockPropertyKey);
if (lock == nil)
{
@synchronized(self)
{
lock = [[TGObjectLockImpl alloc] init];
objc_setAssociatedObject(self, lockPropertyKey, lock, OBJC_ASSOCIATION_RETAIN);
}
}
[lock tgFreeLock];
}
@end

View File

@@ -0,0 +1,10 @@
#import <Foundation/Foundation.h>
@class PSKeyValueCoder;
@protocol PSCoding <NSObject>
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder;
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder;
@end

14
LegacyComponents/PSData.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef __PSData_h
#define __PSData_h
typedef struct
{
uint8_t *data;
NSUInteger length;
} PSData;
typedef PSData PSConstData;
#define PSDataOffset(d, offset) {d.data += offset; d.length -= offset;}
#endif

View File

@@ -0,0 +1,54 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
typedef enum {
PSKeyValueCoderFieldTypeString = 1,
PSKeyValueCoderFieldTypeInt32 = 2,
PSKeyValueCoderFieldTypeInt64 = 3,
PSKeyValueCoderFieldTypeCustomClass = 4,
PSKeyValueCoderFieldTypeArray = 5,
PSKeyValueCoderFieldTypeData = 6,
PSKeyValueCoderFieldTypeInt32Array = 7,
PSKeyValueCoderFieldTypeInt32Dictionary = 8,
PSKeyValueCoderFieldTypeDouble = 9
} PSKeyValueCoderFieldType;
@interface PSKeyValueCoder : NSObject
- (void)encodeString:(NSString *)string forKey:(NSString *)key;
- (void)encodeString:(NSString *)string forCKey:(const char *)key;
- (void)encodeInt32:(int32_t)number forKey:(NSString *)key;
- (void)encodeInt32:(int32_t)number forCKey:(const char *)key;
- (void)encodeInt64:(int64_t)number forKey:(NSString *)key;
- (void)encodeInt64:(int64_t)number forCKey:(const char *)key;
- (void)encodeObject:(id<PSCoding>)object forKey:(NSString *)key;
- (void)encodeObject:(id<PSCoding>)object forCKey:(const char *)key;
- (void)encodeArray:(NSArray *)array forKey:(NSString *)key;
- (void)encodeArray:(NSArray *)array forCKey:(const char *)key;
- (void)encodeData:(NSData *)data forCKey:(const char *)key;
- (void)encodeBytes:(uint8_t const *)value length:(NSUInteger)length forCKey:(const char *)key;
- (void)encodeInt32Array:(NSArray *)value forCKey:(const char *)key;
- (void)encodeInt32Dictionary:(NSDictionary *)value forCKey:(const char *)key;
- (void)encodeDouble:(double)value forCKey:(const char *)key;
- (NSString *)decodeStringForKey:(NSString *)key;
- (NSString *)decodeStringForCKey:(const char *)key;
- (int32_t)decodeInt32ForKey:(NSString *)key;
- (int32_t)decodeInt32ForCKey:(const char *)key;
- (int64_t)decodeInt64ForKey:(NSString *)key;
- (int64_t)decodeInt64ForCKey:(const char *)key;
- (id<PSCoding>)decodeObjectForKey:(NSString *)key;
- (id<PSCoding>)decodeObjectForCKey:(const char *)key;
- (NSArray *)decodeArrayForKey:(NSString *)key;
- (NSArray *)decodeArrayForCKey:(const char *)key;
- (NSData *)decodeDataCorCKey:(const char *)key;
- (void)decodeBytesForCKey:(const char *)key value:(uint8_t *)value length:(NSUInteger)length;
- (NSDictionary *)decodeObjectsByKeys;
- (NSArray *)decodeInt32ArrayForCKey:(const char *)key;
- (NSDictionary *)decodeInt32DictionaryForCKey:(const char *)key;
- (double)decodeDoubleForCKey:(const char *)key;
+ (Class<PSCoding>)classForName:(NSString *)name;
@end

View File

@@ -0,0 +1,180 @@
#import "PSKeyValueCoder.h"
#import <pthread.h>
pthread_rwlock_t classNameCacheLock = PTHREAD_RWLOCK_INITIALIZER;
NSMutableDictionary *classNameCache()
{
static NSMutableDictionary *dict = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
dict = [[NSMutableDictionary alloc] init];
});
return dict;
}
@implementation PSKeyValueCoder
+ (Class<PSCoding>)classForName:(NSString *)name
{
if (name == nil)
return nil;
Class<PSCoding> result = nil;
pthread_rwlock_rdlock(&classNameCacheLock);
result = [classNameCache() objectForKey:name];
pthread_rwlock_unlock(&classNameCacheLock);
if (result == nil)
{
result = NSClassFromString(name);
if (result != nil)
{
pthread_rwlock_wrlock(&classNameCacheLock);
classNameCache()[name] = result;
pthread_rwlock_unlock(&classNameCacheLock);
}
}
return result;
}
- (void)encodeString:(NSString *)__unused string forKey:(NSString *)__unused key
{
}
- (void)encodeInt32:(int32_t)__unused number forKey:(NSString *)__unused key
{
}
- (void)encodeInt64:(int64_t)__unused number forKey:(NSString *)__unused key
{
}
- (void)encodeObject:(id<PSCoding>)__unused object forKey:(NSString *)__unused key
{
}
- (NSString *)decodeStringForKey:(NSString *)__unused key
{
return nil;
}
- (int32_t)decodeInt32ForKey:(NSString *)__unused key
{
return 0;
}
- (int64_t)decodeInt64ForKey:(NSString *)__unused key
{
return 0;
}
- (id<PSCoding>)decodeObjectForKey:(NSString *)__unused key
{
return nil;
}
- (void)encodeString:(NSString *)__unused string forCKey:(const char *)__unused key
{
}
- (void)encodeInt32:(int32_t)__unused number forCKey:(const char *)__unused key
{
}
- (void)encodeInt64:(int64_t)__unused number forCKey:(const char *)__unused key
{
}
- (void)encodeObject:(id<PSCoding>)__unused object forCKey:(const char *)__unused key
{
}
- (void)encodeArray:(NSArray *)__unused array forKey:(NSString *)__unused key
{
}
- (void)encodeArray:(NSArray *)__unused array forCKey:(const char *)__unused key
{
}
- (void)encodeData:(NSData *)__unused data forCKey:(const char *)__unused key
{
}
- (void)encodeBytes:(uint8_t const *)__unused value length:(NSUInteger)__unused length forCKey:(const char *)__unused key
{
}
- (void)encodeInt32Array:(NSArray *)__unused value forCKey:(const char *)__unused key
{
}
- (void)encodeInt32Dictionary:(NSDictionary *)__unused value forCKey:(const char *)__unused key {
}
- (void)encodeDouble:(double)__unused value forCKey:(const char *)__unused key {
}
- (NSString *)decodeStringForCKey:(const char *)__unused key
{
return nil;
}
- (int32_t)decodeInt32ForCKey:(const char *)__unused key
{
return 0;
}
- (int64_t)decodeInt64ForCKey:(const char *)__unused key
{
return 0;
}
- (id<PSCoding>)decodeObjectForCKey:(const char *)__unused key
{
return nil;
}
- (NSArray *)decodeArrayForKey:(NSString *)__unused key
{
return nil;
}
- (NSArray *)decodeArrayForCKey:(const char *)__unused key
{
return nil;
}
- (NSData *)decodeDataCorCKey:(const char *)__unused key
{
return nil;
}
- (void)decodeBytesForCKey:(const char *)__unused key value:(uint8_t *)__unused value length:(NSUInteger)__unused length
{
}
- (NSDictionary *)decodeObjectsByKeys
{
return nil;
}
- (NSArray *)decodeInt32ArrayForCKey:(const char *)__unused key {
return nil;
}
- (NSDictionary *)decodeInt32DictionaryForCKey:(const char *)__unused key {
return nil;
}
- (double)decodeDoubleForCKey:(const char *)__unused key {
return 0.0f;
}
@end

View File

@@ -0,0 +1,12 @@
#import <LegacyComponents/PSKeyValueCoder.h>
@interface PSKeyValueDecoder : PSKeyValueCoder
- (instancetype)init;
- (instancetype)initWithData:(NSData *)data;
- (void)resetData:(NSData *)data;
- (void)resetBytes:(uint8_t const *)bytes length:(NSUInteger)length;
- (void)rewind;
@end

View File

@@ -0,0 +1,698 @@
#import "PSKeyValueDecoder.h"
#import <objc/runtime.h>
@interface PSKeyValueDecoder ()
{
NSData *_data;
@public
uint8_t const *_currentPtr;
uint8_t const *_begin;
uint8_t const *_end;
PSKeyValueDecoder *_tempCoder;
}
@end
static uint32_t readLength(uint8_t const **currentPtr)
{
uint32_t result = 0;
result |= (*(*currentPtr)) & 127;
if ((*(*currentPtr)) & 128)
{
(*currentPtr)++;
result |= ((*(*currentPtr)) & 127) << (7 * 1);
if ((*(*currentPtr)) & 128)
{
(*currentPtr)++;
result |= ((*(*currentPtr)) & 127) << (7 * 2);
if ((*(*currentPtr)) & 128)
{
(*currentPtr)++;
result |= ((*(*currentPtr)) & 127) << (7 * 3);
if ((*(*currentPtr)) & 128)
{
(*currentPtr)++;
result |= ((*(*currentPtr)) & 127) << (7 * 4);
}
}
}
}
(*currentPtr)++;
return result;
}
static NSString *readString(uint8_t const **currentPtr)
{
uint32_t stringLength = readLength(currentPtr);
NSString *string = [[NSString alloc] initWithBytes:*currentPtr length:stringLength encoding:NSUTF8StringEncoding];
(*currentPtr) += stringLength;
return string;
}
static void skipString(uint8_t const **currentPtr)
{
uint32_t stringLength = readLength(currentPtr);
(*currentPtr) += stringLength;
}
static int32_t readInt32(uint8_t const **currentPtr)
{
int32_t number = *((int32_t *)(*currentPtr));
(*currentPtr) += 4;
return number;
}
static void skipInt32(uint8_t const **currentPtr)
{
(*currentPtr) += 4;
}
static int64_t readInt64(uint8_t const **currentPtr)
{
int64_t number;
memcpy(&number, *currentPtr, 8);
(*currentPtr) += 8;
return number;
}
static double readDouble(uint8_t const **currentPtr)
{
double number;
memcpy(&number, *currentPtr, 8);
(*currentPtr) += 8;
return number;
}
static void skipInt64(uint8_t const **currentPtr)
{
(*currentPtr) += 8;
}
static id<PSCoding> readObject(uint8_t const **currentPtr, PSKeyValueDecoder *tempCoder)
{
uint32_t objectLength = *((uint32_t *)(*currentPtr));
(*currentPtr) += 4;
uint8_t const *objectEnd = (*currentPtr) + objectLength;
const char *className = (const char *)(*currentPtr);
NSUInteger classNameLength = strlen(className) + 1;
(*currentPtr) += classNameLength;
id<PSCoding> object = nil;
Class<PSCoding> objectClass = objc_getClass(className);
if (objectClass != nil)
{
tempCoder->_begin = *currentPtr;
tempCoder->_end = objectEnd;
tempCoder->_currentPtr = tempCoder->_begin;
object = [(id<PSCoding>)[(id)objectClass alloc] initWithKeyValueCoder:tempCoder];
}
*currentPtr = objectEnd;
return object;
}
static void skipObject(uint8_t const **currentPtr)
{
uint32_t objectLength = *((uint32_t *)(*currentPtr));
(*currentPtr) += 4 + objectLength;
}
static NSArray *readArray(uint8_t const **currentPtr, PSKeyValueDecoder *tempCoder)
{
uint32_t objectLength = *((uint32_t *)(*currentPtr));
(*currentPtr) += 4;
uint8_t const *objectEnd = (*currentPtr) + objectLength;
uint32_t count = readLength(currentPtr);
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:count];
for (uint32_t i = 0; i < count; i++)
{
id<PSCoding> object = readObject(currentPtr, tempCoder);
if (object != nil)
[array addObject:object];
}
*currentPtr = objectEnd;
return array;
}
static void skipArray(uint8_t const **currentPtr)
{
uint32_t objectLength = ((uint32_t *)*currentPtr)[0];
(*currentPtr) += 4 + objectLength;
}
static NSDictionary *readInt32Dictionary(uint8_t const **currentPtr, PSKeyValueDecoder *tempCoder)
{
uint32_t objectLength = *((uint32_t *)(*currentPtr));
(*currentPtr) += 4;
uint8_t const *objectEnd = (*currentPtr) + objectLength;
uint32_t count = readLength(currentPtr);
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:count];
for (uint32_t i = 0; i < count; i++)
{
int32_t key = *((int32_t *)(*currentPtr));
(*currentPtr) += 4;
id<PSCoding> object = readObject(currentPtr, tempCoder);
if (object != nil) {
dict[@(key)] = object;
}
}
*currentPtr = objectEnd;
return dict;
}
static void skipInt32Dictionary(uint8_t const **currentPtr)
{
uint32_t objectLength = ((uint32_t *)*currentPtr)[0];
(*currentPtr) += 4 + objectLength;
}
static NSData *readData(uint8_t const **currentPtr)
{
uint32_t length = readLength(currentPtr);
NSData *data = [[NSData alloc] initWithBytes:*currentPtr length:length];
*currentPtr += length;
return data;
}
static void readBytes(uint8_t const **currentPtr, uint8_t *value, NSUInteger maxLength)
{
uint32_t length = readLength(currentPtr);
memcpy(value, *currentPtr, MIN((uint32_t)maxLength, length));
*currentPtr += length;
}
static void skipData(uint8_t const **currentPtr)
{
uint32_t length = readLength(currentPtr);
(*currentPtr) += length;
}
static void skipField(uint8_t const **currentPtr)
{
uint8_t fieldType = *(*currentPtr);
(*currentPtr)++;
switch (fieldType)
{
case PSKeyValueCoderFieldTypeString:
{
skipString(currentPtr);
break;
}
case PSKeyValueCoderFieldTypeInt32:
{
skipInt32(currentPtr);
break;
}
case PSKeyValueCoderFieldTypeInt64:
{
skipInt64(currentPtr);
break;
}
case PSKeyValueCoderFieldTypeCustomClass:
{
skipObject(currentPtr);
break;
}
case PSKeyValueCoderFieldTypeArray:
{
skipArray(currentPtr);
break;
}
case PSKeyValueCoderFieldTypeData:
{
skipData(currentPtr);
break;
}
case PSKeyValueCoderFieldTypeInt32Dictionary:
{
skipInt32Dictionary(currentPtr);
break;
}
case PSKeyValueCoderFieldTypeDouble:
{
skipInt64(currentPtr);
break;
}
default:
break;
}
}
@implementation PSKeyValueDecoder
- (instancetype)init
{
self = [super init];
if (self != nil)
{
}
return self;
}
- (instancetype)initWithData:(NSData *)data
{
self = [super init];
if (self != nil)
{
_data = data;
_begin = (uint8_t const *)[_data bytes];
_end = _begin + [_data length];
_currentPtr = _begin;
}
return self;
}
- (void)resetData:(NSData *)data
{
_data = data;
_begin = (uint8_t const *)[_data bytes];
_end = _begin + [_data length];
_currentPtr = _begin;
}
- (void)resetBytes:(uint8_t const *)bytes length:(NSUInteger)length
{
_data = nil;
_begin = bytes;
_end = _begin + length;
_currentPtr = _begin;
}
- (void)rewind {
_begin = (uint8_t const *)[_data bytes];
_end = _begin + [_data length];
_currentPtr = _begin;
}
static bool skipToValueForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
{
uint8_t const *middlePtr = self->_currentPtr;
for (int i = 0; i < 2; i++)
{
uint8_t const *scanEnd = self->_end;
if (i == 1)
{
self->_currentPtr = self->_begin;
scanEnd = middlePtr;
}
while (self->_currentPtr < scanEnd)
{
uint32_t compareKeyLength = readLength(&self->_currentPtr);
if (compareKeyLength != keyLength || memcmp(key, self->_currentPtr, keyLength))
{
if (compareKeyLength > 1000) {
return false;
}
self->_currentPtr += compareKeyLength;
skipField(&self->_currentPtr);
continue;
}
self->_currentPtr += compareKeyLength;
return true;
}
}
return false;
}
static NSString *decodeStringForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
{
if (skipToValueForRawKey(self, key, keyLength))
{
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeString)
return readString(&self->_currentPtr);
else if (fieldType == PSKeyValueCoderFieldTypeInt32)
return [[NSString alloc] initWithFormat:@"%" PRId32 "", readInt32(&self->_currentPtr)];
else if (fieldType == PSKeyValueCoderFieldTypeInt64)
return [[NSString alloc] initWithFormat:@"%" PRId64 "", readInt64(&self->_currentPtr)];
else
{
skipField(&self->_currentPtr);
return nil;
}
}
return nil;
}
- (NSString *)decodeStringForKey:(NSString *)key
{
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
return decodeStringForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
}
- (NSString *)decodeStringForCKey:(const char *)key
{
return decodeStringForRawKey(self, (uint8_t const *)key, (NSUInteger)strlen(key));
}
static int32_t decodeInt32ForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
{
if (skipToValueForRawKey(self, key, keyLength))
{
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeString)
return (int32_t)[readString(&self->_currentPtr) intValue];
else if (fieldType == PSKeyValueCoderFieldTypeInt32)
return readInt32(&self->_currentPtr);
else if (fieldType == PSKeyValueCoderFieldTypeInt64)
return (int32_t)readInt64(&self->_currentPtr);
else
{
skipField(&self->_currentPtr);
return 0;
}
}
return 0;
}
- (int32_t)decodeInt32ForKey:(NSString *)key
{
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
return decodeInt32ForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
}
- (int32_t)decodeInt32ForCKey:(const char *)key
{
return decodeInt32ForRawKey(self, (uint8_t const *)key, strlen(key));
}
static int64_t decodeInt64ForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
{
if (skipToValueForRawKey(self, key, keyLength))
{
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeString)
return (int64_t)[readString(&self->_currentPtr) longLongValue];
else if (fieldType == PSKeyValueCoderFieldTypeInt32)
return readInt32(&self->_currentPtr);
else if (fieldType == PSKeyValueCoderFieldTypeInt64)
return readInt64(&self->_currentPtr);
else
{
skipField(&self->_currentPtr);
return 0;
}
}
return 0;
}
- (int64_t)decodeInt64ForKey:(NSString *)key
{
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
return decodeInt64ForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
}
- (int64_t)decodeInt64ForCKey:(const char *)key
{
return decodeInt64ForRawKey(self, (uint8_t const *)key, strlen(key));
}
static id<PSCoding> decodeObjectForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
{
if (skipToValueForRawKey(self, key, keyLength))
{
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeCustomClass)
{
if (self->_tempCoder == nil)
self->_tempCoder = [[PSKeyValueDecoder alloc] init];
return readObject(&self->_currentPtr, self->_tempCoder);
}
else
{
skipField(&self->_currentPtr);
return nil;
}
}
return nil;
}
- (id<PSCoding>)decodeObjectForKey:(NSString *)key
{
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
return decodeObjectForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
}
- (id<PSCoding>)decodeObjectForCKey:(const char *)key
{
return decodeObjectForRawKey(self, (uint8_t const *)key, strlen(key));
}
static NSArray *decodeArrayForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
{
if (skipToValueForRawKey(self, key, keyLength))
{
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeArray)
{
if (self->_tempCoder == nil)
self->_tempCoder = [[PSKeyValueDecoder alloc] init];
return readArray(&self->_currentPtr, self->_tempCoder);
}
else
{
skipField(&self->_currentPtr);
return nil;
}
}
return nil;
}
- (NSArray *)decodeArrayForKey:(NSString *)key
{
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
return decodeArrayForRawKey(self, (uint8_t const *)[keyData bytes], [keyData length]);
}
- (NSArray *)decodeArrayForCKey:(const char *)key
{
return decodeArrayForRawKey(self, (uint8_t const *)key, strlen(key));
}
static NSData *decodeDataForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength)
{
if (skipToValueForRawKey(self, key, keyLength))
{
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeData)
{
return readData(&self->_currentPtr);
}
else
{
skipField(&self->_currentPtr);
return nil;
}
}
return nil;
}
static void decodeBytesForRawKey(PSKeyValueDecoder *self, uint8_t const *key, NSUInteger keyLength, uint8_t *value, NSUInteger maxLength)
{
if (skipToValueForRawKey(self, key, keyLength))
{
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeData)
{
readBytes(&self->_currentPtr, value, maxLength);
}
else
{
skipField(&self->_currentPtr);
}
}
}
- (NSData *)decodeDataCorCKey:(const char *)key
{
return decodeDataForRawKey(self, (uint8_t const *)key, strlen(key));
}
- (void)decodeBytesForCKey:(const char *)key value:(uint8_t *)value length:(NSUInteger)length
{
decodeBytesForRawKey(self, (uint8_t const *)key, strlen(key), value, length);
}
- (NSDictionary *)decodeObjectsByKeys
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
if (self->_tempCoder == nil)
self->_tempCoder = [[PSKeyValueDecoder alloc] init];
self->_currentPtr = self->_begin;
while (self->_currentPtr < self->_end)
{
uint32_t keyLength = readLength(&self->_currentPtr);
NSString *key = [[NSString alloc] initWithBytes:self->_currentPtr length:keyLength encoding:NSUTF8StringEncoding];
self->_currentPtr += keyLength;
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeCustomClass)
{
id<PSCoding> value = readObject(&self->_currentPtr, self->_tempCoder);
if (value == nil)
continue;
dict[key] = value;
}
else
break;
}
self->_currentPtr = self->_begin;
return dict;
}
- (NSArray *)decodeInt32ArrayForCKey:(const char *)key {
if (skipToValueForRawKey(self, (void *)key, strlen(key))) {
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeInt32Array) {
int32_t count = 0;
memcpy(&count, self->_currentPtr, 4);
self->_currentPtr += 4;
NSMutableArray *array = [[NSMutableArray alloc] init];
for (int32_t i = 0; i < count; i++) {
int32_t number = 0;
memcpy(&number, self->_currentPtr, 4);
self->_currentPtr += 4;
[array addObject:@(number)];
}
return array;
} else {
self->_currentPtr--;
skipField(&self->_currentPtr);
return nil;
}
} else {
return nil;
}
}
- (NSDictionary *)decodeInt32DictionaryForCKey:(const char *)key {
if (skipToValueForRawKey(self, (uint8_t const *)key, strlen(key))) {
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeInt32Dictionary) {
if (self->_tempCoder == nil)
self->_tempCoder = [[PSKeyValueDecoder alloc] init];
return readInt32Dictionary(&self->_currentPtr, self->_tempCoder);
}
else {
skipField(&self->_currentPtr);
}
}
return nil;
}
- (double)decodeDoubleForCKey:(const char *)key {
if (skipToValueForRawKey(self, (uint8_t const *)key, strlen(key)))
{
uint8_t fieldType = *self->_currentPtr;
self->_currentPtr++;
if (fieldType == PSKeyValueCoderFieldTypeString)
return (int32_t)[readString(&self->_currentPtr) doubleValue];
else if (fieldType == PSKeyValueCoderFieldTypeInt32)
return readInt32(&self->_currentPtr);
else if (fieldType == PSKeyValueCoderFieldTypeInt64)
return (double)readInt64(&self->_currentPtr);
else if (fieldType == PSKeyValueCoderFieldTypeDouble)
return readDouble(&self->_currentPtr);
else
{
skipField(&self->_currentPtr);
return 0;
}
}
return 0.0;
}
@end

View File

@@ -0,0 +1,8 @@
#import <LegacyComponents/PSKeyValueCoder.h>
@interface PSKeyValueEncoder : PSKeyValueCoder
- (void)reset;
- (NSData *)data;
@end

View File

@@ -0,0 +1,373 @@
#import "PSKeyValueEncoder.h"
#import <objc/runtime.h>
@interface PSKeyValueEncoder ()
{
@public
NSMutableData *_data;
}
@end
@implementation PSKeyValueEncoder
- (instancetype)init
{
self = [super init];
if (self != nil)
{
_data = [[NSMutableData alloc] init];
}
return self;
}
static inline void writeLength(PSKeyValueEncoder *self, uint32_t value)
{
uint8_t bytes[5];
int length = 0;
if (value > 127)
{
bytes[length++] = ((uint8_t)(value & 127)) | 128;
value >>= 7;
}
if (value > 127)
{
bytes[length++] = ((uint8_t)(value & 127)) | 128;
value >>= 7;
}
if (value > 127)
{
bytes[length++] = ((uint8_t)(value & 127)) | 128;
value >>= 7;
}
if (value > 127)
{
bytes[length++] = ((uint8_t)(value & 127)) | 128;
value >>= 7;
}
bytes[length++] = ((uint8_t)(value & 127));
[self->_data appendBytes:bytes length:length];
}
- (void)encodeString:(NSString *)string forKey:(NSString *)key
{
if (key == nil || string == nil)
return;
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
writeLength(self, (uint32_t)keyData.length);
[_data appendData:keyData];
uint8_t fieldType = PSKeyValueCoderFieldTypeString;
[_data appendBytes:&fieldType length:1];
NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding];
writeLength(self, (uint32_t)stringData.length);
[_data appendData:stringData];
}
- (void)encodeString:(NSString *)string forCKey:(const char *)key
{
if (key == nil || string == nil)
return;
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeString;
[_data appendBytes:&fieldType length:1];
NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding];
writeLength(self, (uint32_t)stringData.length);
[_data appendData:stringData];
}
- (void)encodeInt32:(int32_t)number forKey:(NSString *)key
{
if (key == nil)
return;
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
writeLength(self, (uint32_t)keyData.length);
[_data appendData:keyData];
uint8_t fieldType = PSKeyValueCoderFieldTypeInt32;
[_data appendBytes:&fieldType length:1];
[_data appendBytes:&number length:4];
}
- (void)encodeInt32:(int32_t)number forCKey:(const char *)key
{
if (key == nil)
return;
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeInt32;
[_data appendBytes:&fieldType length:1];
[_data appendBytes:&number length:4];
}
- (void)encodeInt64:(int64_t)number forKey:(NSString *)key
{
if (key == nil)
return;
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
writeLength(self, (uint32_t)keyData.length);
[_data appendData:keyData];
uint8_t fieldType = PSKeyValueCoderFieldTypeInt64;
[_data appendBytes:&fieldType length:1];
[_data appendBytes:&number length:8];
}
- (void)encodeInt64:(int64_t)number forCKey:(const char *)key
{
if (key == nil)
return;
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeInt64;
[_data appendBytes:&fieldType length:1];
[_data appendBytes:&number length:8];
}
- (void)encodeObject:(id<PSCoding>)object forKey:(NSString *)key
{
if (key == nil || object == nil)
return;
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
writeLength(self, (uint32_t)keyData.length);
[_data appendData:keyData];
uint8_t fieldType = PSKeyValueCoderFieldTypeCustomClass;
[_data appendBytes:&fieldType length:1];
uint32_t objectLength = 0;
NSUInteger objectLengthPosition = [_data length];
[_data appendBytes:&objectLength length:4];
NSString *className = NSStringFromClass([object class]);
NSData *classNameData = [className dataUsingEncoding:NSUTF8StringEncoding];
[_data appendData:classNameData];
uint8_t zero = 0;
[_data appendBytes:&zero length:1];
[object encodeWithKeyValueCoder:self];
objectLength = (int)([_data length] - objectLengthPosition - 4);
[_data replaceBytesInRange:NSMakeRange(objectLengthPosition, 4) withBytes:&objectLength];
}
static void encodeObjectValue(PSKeyValueEncoder *self, id<PSCoding> object)
{
uint32_t objectLength = 0;
NSUInteger objectLengthPosition = [self->_data length];
[self->_data appendBytes:&objectLength length:4];
Class objectClass = object_getClass(object);
const char *className = class_getName(objectClass);
[self->_data appendBytes:className length:strlen(className) + 1];
[object encodeWithKeyValueCoder:self];
objectLength = (int)([self->_data length] - objectLengthPosition - 4);
[self->_data replaceBytesInRange:NSMakeRange(objectLengthPosition, 4) withBytes:&objectLength];
}
- (void)encodeObject:(id<PSCoding>)object forCKey:(const char *)key
{
if (key == nil || object == nil)
return;
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeCustomClass;
[_data appendBytes:&fieldType length:1];
encodeObjectValue(self, object);
}
- (void)encodeArray:(NSArray *)array forKey:(NSString *)key
{
if (key == nil || array == nil)
return;
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
writeLength(self, (uint32_t)keyData.length);
[_data appendData:keyData];
uint8_t fieldType = PSKeyValueCoderFieldTypeArray;
[_data appendBytes:&fieldType length:1];
uint32_t objectLength = 0;
NSUInteger objectLengthPosition = [self->_data length];
[self->_data appendBytes:&objectLength length:4];
uint32_t count = (uint32_t)[array count];
writeLength(self, count);
for (uint32_t i = 0; i < count; i++)
{
encodeObjectValue(self, array[i]);
}
objectLength = (int)([_data length] - objectLengthPosition - 4);
[_data replaceBytesInRange:NSMakeRange(objectLengthPosition, 4) withBytes:&objectLength];
}
- (void)encodeArray:(NSArray *)array forCKey:(const char *)key
{
if (key == nil || array == nil)
return;
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeArray;
[_data appendBytes:&fieldType length:1];
uint32_t objectLength = 0;
NSUInteger objectLengthPosition = [self->_data length];
[self->_data appendBytes:&objectLength length:4];
uint32_t count = (uint32_t)[array count];
writeLength(self, count);
for (uint32_t i = 0; i < count; i++)
{
encodeObjectValue(self, array[i]);
}
objectLength = (int)([_data length] - objectLengthPosition - 4);
[_data replaceBytesInRange:NSMakeRange(objectLengthPosition, 4) withBytes:&objectLength];
}
- (void)encodeData:(NSData *)data forCKey:(const char *)key
{
if (key == nil || data == nil)
return;
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeData;
[_data appendBytes:&fieldType length:1];
writeLength(self, (uint32_t)data.length);
[_data appendData:data];
}
- (void)encodeBytes:(uint8_t const *)value length:(NSUInteger)length forCKey:(const char *)key
{
if (key == nil)
return;
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeData;
[_data appendBytes:&fieldType length:1];
writeLength(self, (uint32_t)length);
[_data appendBytes:value length:length];
}
- (void)encodeInt32Array:(NSArray *)value forCKey:(const char *)key {
if (key == NULL) {
return;
}
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeInt32Array;
[_data appendBytes:&fieldType length:1];
int32_t count = (int32_t)value.count;
[_data appendBytes:&count length:4];
for (NSNumber *nNumber in value) {
int32_t number = [nNumber intValue];
[_data appendBytes:&number length:4];
}
}
- (void)encodeInt32Dictionary:(NSDictionary *)value forCKey:(const char *)key {
if (key == NULL) {
return;
}
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeInt32Dictionary;
[_data appendBytes:&fieldType length:1];
uint32_t objectLength = 0;
NSUInteger objectLengthPosition = [self->_data length];
[self->_data appendBytes:&objectLength length:4];
NSArray *allKeys = [value allKeys];
uint32_t count = (uint32_t)[allKeys count];
writeLength(self, count);
for (NSNumber *nKey in allKeys) {
id<PSCoding> object = value[nKey];
int32_t objectKey = [nKey intValue];
[self->_data appendBytes:&objectKey length:4];
encodeObjectValue(self, object);
}
objectLength = (int)([_data length] - objectLengthPosition - 4);
[_data replaceBytesInRange:NSMakeRange(objectLengthPosition, 4) withBytes:&objectLength];
}
- (void)encodeDouble:(double)value forCKey:(const char *)key {
uint32_t keyLength = (uint32_t)strlen(key);
writeLength(self, keyLength);
[_data appendBytes:key length:keyLength];
uint8_t fieldType = PSKeyValueCoderFieldTypeDouble;
[_data appendBytes:&fieldType length:1];
[_data appendBytes:&value length:8];
}
- (void)reset
{
[_data setLength:0];
}
- (NSData *)data
{
return _data;
}
@end

View File

@@ -0,0 +1,24 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSData.h>
typedef enum {
PSKeyValueReaderSelectLowerKey = 0,
PSKeyValueReaderSelectHigherKey = 1
} PSKeyValueReaderSelectKey;
typedef enum {
PSKeyValueReaderEnumerationReverse = 1,
PSKeyValueReaderEnumerationLowerBoundExclusive = 2,
PSKeyValueReaderEnumerationUpperBoundExclusive = 4
} PSKeyValueReaderEnumerationOptions;
@protocol PSKeyValueReader <NSObject>
- (bool)readValueForRawKey:(PSConstData *)key value:(PSConstData *)value;
- (bool)readValueBetweenLowerBoundKey:(PSConstData *)lowerBoundKey upperBoundKey:(PSConstData *)upperBoundKey selectKey:(PSKeyValueReaderSelectKey)selectKey selectedKey:(PSConstData *)selectedKey selectedValue:(PSConstData *)selectedValue;
- (void)enumerateKeysAndValuesBetweenLowerBoundKey:(PSConstData *)lowerBoundKey upperBoundKey:(PSConstData *)upperBoundKey options:(NSInteger)options withBlock:(void (^)(PSConstData *key, PSConstData *value, bool *stop))block;
@end

View File

@@ -0,0 +1,11 @@
#import <LegacyComponents/PSKeyValueReader.h>
#import <LegacyComponents/PSKeyValueWriter.h>
@protocol PSKeyValueStore <NSObject>
- (void)readInTransaction:(void (^)(id<PSKeyValueReader>))transaction;
- (void)readWriteInTransaction:(void (^)(id<PSKeyValueReader, PSKeyValueWriter>))transaction;
- (void)sync;
@end

View File

@@ -0,0 +1,11 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSData.h>
@protocol PSKeyValueWriter <NSObject>
- (void)writeValueForRawKey:(const uint8_t *)key keyLength:(NSUInteger)keyLength value:(const uint8_t *)value valueLength:(NSUInteger)valueLength;
- (bool)deleteValueForRawKey:(PSData *)key;
- (void)deleteAllValues;
@end

View File

@@ -0,0 +1,58 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
//
// RMPhoneFormat.h v1.0
// Copyright (c) 2012, Rick Maddy
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import <Foundation/Foundation.h>
@interface RMPhoneFormat : NSObject
+ (RMPhoneFormat *)instance;
- (id)init;
- (id)initWithDefaultCountry:(NSString *)countryCode;
- (NSString *)format:(NSString *)str implicitPlus:(bool)implicitPlus;
// Calling code for the user's default country based on their Region Format setting
- (NSString *)defaultCallingCode;
// countryCode must be 2-letter ISO 3166-1 code. Result does not include a leading +
- (NSString *)callingCodeForCountryCode:(NSString *)countryCode;
// callingCode should be 1 to 3 digit calling code. Result is a set of matching, lowercase, 2-letter ISO 3166-1 country codes
- (NSSet *)countriesForCallingCode:(NSString *)callingCode;
#ifdef DEBUG
- (void)dump;
#endif
@end

View File

@@ -0,0 +1,754 @@
#import "RMPhoneFormat.h"
@interface PhoneRule : NSObject
@property (nonatomic, assign) int minVal;
@property (nonatomic, assign) int maxVal;
@property (nonatomic, assign) int byte8;
@property (nonatomic, assign) int maxLen;
@property (nonatomic, assign) int otherFlag;
@property (nonatomic, assign) int prefixLen;
@property (nonatomic, assign) int flag12;
@property (nonatomic, assign) int flag13;
@property (nonatomic) NSString *format;
#ifdef DEBUG
@property (nonatomic) NSSet *countries;
@property (nonatomic) NSString *callingCode;
@property (nonatomic, assign) int matchLen;
#endif
- (NSString *)format:(NSString *)str intlPrefix:(NSString *)intlPrefix trunkPrefix:(NSString *)trunkPrefix;
@end
@implementation PhoneRule
@synthesize minVal = _minVal;
@synthesize maxVal = _maxVal;
@synthesize byte8 = _byte8;
@synthesize maxLen = _maxLen;
@synthesize otherFlag = _otherFlag;
@synthesize prefixLen = _prefixLen;
@synthesize flag12 = _flag12;
@synthesize flag13 = _flag13;
@synthesize format = _format;
#ifdef DEBUG
@synthesize countries = _countries;
@synthesize callingCode = _callingCode;
@synthesize matchLen = _matchLen;
#endif
- (NSString *)format:(NSString *)str intlPrefix:(NSString *)intlPrefix trunkPrefix:(NSString *)trunkPrefix {
BOOL hadC = NO;
BOOL hadN = NO;
BOOL hasOpen = NO;
int spot = 0;
NSMutableString *res = [[NSMutableString alloc] initWithCapacity:20];
for (int i = 0; i < (int)[self.format length]; i++) {
unichar ch = [self.format characterAtIndex:i];
switch (ch) {
case 'c':
// Add international prefix if there is one.
hadC = YES;
if (intlPrefix != nil) {
[res appendString:intlPrefix];
}
break;
case 'n':
// Add trunk prefix if there is one.
hadN = YES;
if (trunkPrefix != nil) {
[res appendString:trunkPrefix];
}
break;
case '#':
// Add next digit from number. If there aren't enough digits left then do nothing unless we need to
// space-fill a pair of parenthesis.
if (spot < (int)[str length]) {
[res appendString:[str substringWithRange:NSMakeRange(spot, 1)]];
spot++;
} else if (hasOpen) {
[res appendString:@" "];
}
break;
case '(':
// Flag we found an open paren so it can be space-filled. But only do so if we aren't beyond the
// end of the number.
if (spot < (int)[str length]) {
hasOpen = YES;
}
// fall through
default: // rest like ) and -
// Don't show space after n if no trunkPrefix or after c if no intlPrefix
if (!(ch == ' ' && i > 0 && (([self.format characterAtIndex:i - 1] == 'n' && trunkPrefix == nil) || ([self.format characterAtIndex:i - 1] == 'c' && intlPrefix == nil)))) {
// Only show punctuation if not beyond the end of the supplied number.
// The only exception is to show a close paren if we had found
if (spot < (int)[str length] || (hasOpen && ch == ')')) {
[res appendString:[self.format substringWithRange:NSMakeRange(i, 1)]];
if (ch == ')') {
hasOpen = NO; // close it
}
}
}
break;
}
}
// Not all format strings have a 'c' or 'n' in them. If we have an international prefix or a trunk prefix but the
// format string doesn't explictly say where to put it then simply add it to the beginning.
if (intlPrefix != nil && !hadC) {
[res insertString:[NSString stringWithFormat:@"%@ ", intlPrefix] atIndex:0];
} else if (trunkPrefix != nil && !hadN) {
[res insertString:trunkPrefix atIndex:0];
}
return res;
}
- (NSString *)description {
#ifdef DEBUG
return [NSString stringWithFormat:@"Rule: { countries: %@, calling code: %@, matchlen: %d, minVal: %d, maxVal: %d, byte8: %d, maxLen: %d, nFlag: %d, prefixLen: %d, flag12: %d, flag13: %d, format: %@ }", self.countries, self.callingCode, self.matchLen, self.minVal, self.maxVal, self.byte8, self.maxLen, self.otherFlag, self.prefixLen, self.flag12, self.flag13, self.format];
#else
return [NSString stringWithFormat:@"Rule: { minVal: %d, maxVal: %d, byte8: %d, maxLen: %d, nFlag: %d, prefixLen: %d, flag12: %d, flag13: %d, format: %@ }", self.minVal, self.maxVal, self.byte8, self.maxLen, self.otherFlag, self.prefixLen, self.flag12, self.flag13, self.format];
#endif
}
@end
@interface RuleSet : NSObject
@property (nonatomic, assign) int matchLen;
@property (nonatomic) NSMutableArray *rules;
- (NSString *)format:(NSString *)str intlPrefix:(NSString *)intlPrefix trunkPrefix:(NSString *)trunkPrefix prefixRequired:(BOOL)prefixRequired;
@end
@implementation RuleSet
@synthesize matchLen = _matchLen;
@synthesize rules = _rules;
- (NSString *)format:(NSString *)str intlPrefix:(NSString *)intlPrefix trunkPrefix:(NSString *)trunkPrefix prefixRequired:(BOOL)prefixRequired {
if ((int)[str length] >= self.matchLen)
{
NSString *begin = [str substringToIndex:self.matchLen];
int val = [begin intValue];
for (PhoneRule *rule in self.rules)
{
if (val >= rule.minVal && val <= rule.maxVal && (int)[str length] <= rule.maxLen)
{
if (prefixRequired)
{
if (
((rule.flag12 & 0x03) == 0 &&
trunkPrefix == nil &&
intlPrefix == nil) ||
(trunkPrefix != nil && (rule.flag12 & 0x01)) ||
(intlPrefix != nil && (rule.flag12 & 0x02))
)
{
return [rule format:str intlPrefix:intlPrefix trunkPrefix:trunkPrefix];
}
}
else
{
if ((trunkPrefix == nil && intlPrefix == nil) || (trunkPrefix != nil && (rule.flag12 & 0x01)) || (intlPrefix != nil && (rule.flag12 & 0x02)))
{
return [rule format:str intlPrefix:intlPrefix trunkPrefix:trunkPrefix];
}
}
}
}
if (!prefixRequired)
{
if (intlPrefix != nil)
{
for (PhoneRule *rule in self.rules)
{
if (val >= rule.minVal && val <= rule.maxVal && (int)[str length] <= rule.maxLen)
{
if (trunkPrefix == nil || (rule.flag12 & 0x01))
{
return [rule format:str intlPrefix:intlPrefix trunkPrefix:trunkPrefix];
}
}
}
} else if (trunkPrefix != nil)
{
for (PhoneRule *rule in self.rules)
{
if (val >= rule.minVal && val <= rule.maxVal && (int)[str length] <= rule.maxLen)
{
if (intlPrefix == nil || (rule.flag12 & 0x02))
{
return [rule format:str intlPrefix:intlPrefix trunkPrefix:trunkPrefix];
}
}
}
}
}
return nil; // no match found
} else {
return nil; // not long enough to compare
}
}
- (NSString *)description {
NSMutableString *res = [NSMutableString stringWithCapacity:100];
[res appendFormat:@"RuleSet: { matchLen: %d, rules: %@ }", self.matchLen, self.rules];
return res;
}
@end
@interface CallingCodeInfo : NSObject
@property (nonatomic) NSSet *countries;
@property (nonatomic) NSString *callingCode;
@property (nonatomic) NSMutableArray *trunkPrefixes;
@property (nonatomic) NSMutableArray *intlPrefixes;
@property (nonatomic) NSMutableArray *ruleSets;
@property (nonatomic) NSMutableArray *formatStrings;
- (NSString *)matchingAccessCode:(NSString *)str;
- (NSString *)format:(NSString *)str;
@end
@implementation CallingCodeInfo
@synthesize countries = _countries;
@synthesize callingCode = _callingCode;
@synthesize trunkPrefixes = _trunkPrefixes;
@synthesize intlPrefixes = _intlPrefixes;
@synthesize ruleSets = _ruleSets;
@synthesize formatStrings = _formatStrings;
- (NSString *)matchingAccessCode:(NSString *)str {
for (NSString *code in self.intlPrefixes) {
if ([str hasPrefix:code]) {
return code;
}
}
return nil;
}
- (NSString *)matchingTrunkCode:(NSString *)str {
for (NSString *code in self.trunkPrefixes) {
if ([str hasPrefix:code]) {
return code;
}
}
return nil;
}
- (NSString *)format:(NSString *)orig
{
NSString *str = orig;
NSString *trunkPrefix = nil;
NSString *intlPrefix = nil;
if ([str hasPrefix:self.callingCode])
{
intlPrefix = self.callingCode;
str = [str substringFromIndex:[intlPrefix length]];
}
else
{
NSString *trunk = [self matchingTrunkCode:str];
if (trunk)
{
trunkPrefix = trunk;
str = [str substringFromIndex:[trunkPrefix length]];
}
}
for (RuleSet *set in self.ruleSets)
{
NSString *phone = [set format:str intlPrefix:intlPrefix trunkPrefix:trunkPrefix prefixRequired:YES];
if (phone)
{
return phone;
}
}
for (RuleSet *set in self.ruleSets)
{
NSString *phone = [set format:str intlPrefix:intlPrefix trunkPrefix:trunkPrefix prefixRequired:NO];
if (phone)
{
return phone;
}
}
if (intlPrefix != nil && [str length])
{
return [NSString stringWithFormat:@"%@ %@", intlPrefix, str];
}
return orig;
}
- (NSString *)description {
NSMutableString *res = [NSMutableString stringWithCapacity:100];
[res appendFormat:@"CountryInfo { countries: %@, code: %@, trunkPrefixes: %@, intlPrefixes: %@", self.countries, self.callingCode, self.trunkPrefixes, self.intlPrefixes];
[res appendFormat:@", rule sets: %@ }", self.ruleSets];
return res;
}
@end
static NSCharacterSet *phoneChars = nil;
#ifdef DEBUG
static NSMutableDictionary *extra1CallingCodes = nil;
static NSMutableDictionary *extra2CallingCodes = nil;
static NSMutableDictionary *extra3CallingCodes = nil;
static NSMutableDictionary *flagRules = nil;
#endif
@implementation RMPhoneFormat {
NSData *_data;
NSString *_defaultCountry;
NSString *_defaultCallingCode;
NSMutableDictionary *_callingCodeOffsets;
NSMutableDictionary *_callingCodeCountries;
NSMutableDictionary *_callingCodeData;
NSMutableDictionary *_countryCallingCode;
}
+ (void)initialize {
phoneChars = [NSCharacterSet characterSetWithCharactersInString:@"0123456789+*#"];
#ifdef DEBUG
extra1CallingCodes = [[NSMutableDictionary alloc] init];
extra2CallingCodes = [[NSMutableDictionary alloc] init];
extra3CallingCodes = [[NSMutableDictionary alloc] init];
flagRules = [[NSMutableDictionary alloc] init];
#endif
}
+ (NSString *)strip:(NSString *)str {
NSMutableString *res = [NSMutableString stringWithString:str];
for (int i = (int)[res length] - 1; i >= 0; i--) {
if (![phoneChars characterIsMember:[res characterAtIndex:i]]) {
[res deleteCharactersInRange:NSMakeRange(i, 1)];
}
}
return res;
}
+ (RMPhoneFormat *)instance {
static RMPhoneFormat *instance = nil;
static dispatch_once_t predicate = 0;
dispatch_once(&predicate, ^{ instance = [self new]; });
return instance;
}
- (id)init {
self = [self initWithDefaultCountry:nil];
return self;
}
- (id)initWithDefaultCountry:(NSString *)countryCode {
if ((self = [super init])) {
_data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"PhoneFormats" ofType:@"dat"]];
NSAssert(_data, @"The file PhoneFormats.dat is not in the resource bundle. See the README.");
if (countryCode.length) {
_defaultCountry = countryCode;
} else {
NSLocale *loc = [NSLocale currentLocale];
_defaultCountry = [[loc objectForKey:NSLocaleCountryCode] lowercaseString];
}
_callingCodeOffsets = [[NSMutableDictionary alloc] initWithCapacity:255];
_callingCodeCountries = [[NSMutableDictionary alloc] initWithCapacity:255];
_callingCodeData = [[NSMutableDictionary alloc] initWithCapacity:10];
_countryCallingCode = [[NSMutableDictionary alloc] initWithCapacity:255];
[self parseDataHeader];
}
return self;
}
- (NSString *)defaultCallingCode {
return [self callingCodeForCountryCode:_defaultCountry];
}
- (NSString *)callingCodeForCountryCode:(NSString *)countryCode {
return [_countryCallingCode objectForKey:[countryCode lowercaseString]];
}
- (NSSet *)countriesForCallingCode:(NSString *)callingCode {
if ([callingCode hasPrefix:@"+"]) {
callingCode = [callingCode substringFromIndex:1];
}
return [_callingCodeCountries objectForKey:callingCode];
}
- (CallingCodeInfo *)findCallingCodeInfo:(NSString *)str {
CallingCodeInfo *res = nil;
for (int i = 0; i < 3; i++) {
if (i < (int)[str length]) {
res = [self callingCodeInfo:[str substringToIndex:i + 1]];
if (res) {
break;
}
} else {
break;
}
}
return res;
}
- (NSString *)format:(NSString *)orig implicitPlus:(bool)implicitPlus
{
NSString *str = [RMPhoneFormat strip:orig];
bool hasPlusPrefix = [str hasPrefix:@"+"];
if ([str hasPrefix:@"+"] || implicitPlus)
{
NSString *rest = hasPlusPrefix ? [str substringFromIndex:1] : str;
CallingCodeInfo *info = [self findCallingCodeInfo:rest];
if (info)
{
NSString *phone = [info format:rest];
return [@"+" stringByAppendingString:phone];
} else
{
return orig;
}
}
else
{
CallingCodeInfo *info = [self callingCodeInfo:_defaultCallingCode];
if (info == nil)
{
return orig;
}
NSString *accessCode = [info matchingAccessCode:str];
if (accessCode)
{
NSString *rest = [str substringFromIndex:[accessCode length]];
NSString *phone = rest;
CallingCodeInfo *info2 = [self findCallingCodeInfo:rest];
if (info2)
{
phone = [info2 format:rest];
}
if ([phone length] == 0)
{
return accessCode;
}
else
{
return [NSString stringWithFormat:@"%@ %@", accessCode, phone];
}
}
else
{
NSString *phone = [info format:str];
return phone;
}
}
return orig;
}
- (uint32_t)value32:(NSUInteger)offset {
if (offset + 4 <= [_data length]) {
return OSReadLittleInt32([_data bytes], offset);
} else {
return 0;
}
}
- (int)value16:(NSUInteger)offset {
if (offset + 2 <= [_data length]) {
return OSReadLittleInt16([_data bytes], offset);
} else {
return 0;
}
}
- (int)value16BE:(NSUInteger)offset {
if (offset + 2 <= [_data length]) {
return OSReadBigInt16([_data bytes], offset);
} else {
return 0;
}
}
- (CallingCodeInfo *)callingCodeInfo:(NSString *)callingCode
{
CallingCodeInfo *res = [_callingCodeData objectForKey:callingCode];
if (res == nil)
{
NSNumber *num = [_callingCodeOffsets objectForKey:callingCode];
if (num)
{
const uint8_t *bytes = [_data bytes];
uint32_t start = (int)[num longValue];
uint32_t offset = start;
res = [[CallingCodeInfo alloc] init];
res.callingCode = callingCode;
res.countries = [_callingCodeCountries objectForKey:callingCode];
[_callingCodeData setObject:res forKey:callingCode];
uint16_t block1Len = (uint16_t)[self value16:offset];
offset += 2;
#ifdef DEBUG
uint16_t extra1 = (uint16_t)[self value16:offset];
#endif
offset += 2;
uint16_t block2Len = (uint16_t)[self value16:offset];
offset += 2;
#ifdef DEBUG
uint16_t extra2 = (uint16_t)[self value16:offset];
#endif
offset += 2;
uint16_t setCnt = (uint16_t)[self value16:offset];
offset += 2;
#ifdef DEBUG
uint16_t extra3 = (uint16_t)[self value16:offset];
#endif
offset += 2;
#ifdef DEBUG
if (extra1) {
NSMutableArray *vals = [extra1CallingCodes objectForKey:[NSNumber numberWithInt:extra1]];
if (!vals) {
vals = [[NSMutableArray alloc] init];
[extra1CallingCodes setObject:vals forKey:[NSNumber numberWithInt:extra1]];
}
[vals addObject:res];
}
if (extra2) {
NSMutableArray *vals = [extra2CallingCodes objectForKey:[NSNumber numberWithInt:extra2]];
if (!vals) {
vals = [[NSMutableArray alloc] init];
[extra2CallingCodes setObject:vals forKey:[NSNumber numberWithInt:extra2]];
}
[vals addObject:res];
}
if (extra3) {
NSMutableArray *vals = [extra3CallingCodes objectForKey:[NSNumber numberWithInt:extra3]];
if (!vals) {
vals = [[NSMutableArray alloc] init];
[extra3CallingCodes setObject:vals forKey:[NSNumber numberWithInt:extra3]];
}
[vals addObject:res];
}
#endif
NSMutableArray *strs = [NSMutableArray arrayWithCapacity:5];
NSString *str;
while ([(str = [NSString stringWithCString:(char *)bytes + offset encoding:NSUTF8StringEncoding]) length]) {
[strs addObject:str];
offset += [str length] + 1;
}
res.trunkPrefixes = strs;
offset++; // skip NULL
strs = [NSMutableArray arrayWithCapacity:5];
while ([(str = [NSString stringWithCString:(char *)bytes + offset encoding:NSUTF8StringEncoding]) length]) {
[strs addObject:str];
offset += [str length] + 1;
}
res.intlPrefixes = strs;
NSMutableArray *ruleSets = [NSMutableArray arrayWithCapacity:setCnt];
offset = start + block1Len; // Start of rule sets
for (int s = 0; s < setCnt; s++) {
RuleSet *ruleSet = [[RuleSet alloc] init];
int matchCnt = [self value16:offset];
ruleSet.matchLen = matchCnt;
offset += 2;
int ruleCnt = [self value16:offset];
offset += 2;
NSMutableArray *rules = [NSMutableArray arrayWithCapacity:ruleCnt];
for (int r = 0; r < ruleCnt; r++) {
PhoneRule *rule = [[PhoneRule alloc] init];
rule.minVal = [self value32:offset];
offset += 4;
rule.maxVal = [self value32:offset];
offset += 4;
rule.byte8 = (int)bytes[offset++];
rule.maxLen = (int)bytes[offset++];
rule.otherFlag = (int)bytes[offset++];
rule.prefixLen = (int)bytes[offset++];
rule.flag12 = (int)bytes[offset++];
rule.flag13 = (int)bytes[offset++];
uint16_t strOffset = (uint16_t)[self value16:offset];
offset += 2;
rule.format = [NSString stringWithCString:(char *)bytes + start + block1Len + block2Len + strOffset encoding:NSUTF8StringEncoding];
// Several formats contain [[9]] or [[8]]. Using the Contacts app as a test, I can find no use
// for these. Do they mean "optional"? They don't seem to have any use. This code strips out
// anything in [[..]]
NSRange openPos = [rule.format rangeOfString:@"[["];
if (openPos.location != NSNotFound) {
NSRange closePos = [rule.format rangeOfString:@"]]"];
rule.format = [NSString stringWithFormat:@"%@%@", [rule.format substringToIndex:openPos.location], [rule.format substringFromIndex:closePos.location + closePos.length]];
}
[rules addObject:rule];
#ifdef DEBUG
rule.countries = res.countries;
rule.callingCode = res.callingCode;
rule.matchLen = matchCnt;
if (rule.byte8) {
NSMutableDictionary *data = [flagRules objectForKey:@"byte8"];
if (!data) {
data = [[NSMutableDictionary alloc] init];
[flagRules setObject:data forKey:@"byte8"];
}
NSMutableArray *list = [data objectForKey:[NSNumber numberWithInt:rule.byte8]];
if (!list) {
list = [[NSMutableArray alloc] init];
[data setObject:list forKey:[NSNumber numberWithInt:rule.byte8]];
}
[list addObject:rule];
}
if (rule.prefixLen) {
NSMutableDictionary *data = [flagRules objectForKey:@"prefixLen"];
if (!data) {
data = [[NSMutableDictionary alloc] init];
[flagRules setObject:data forKey:@"prefixLen"];
}
NSMutableArray *list = [data objectForKey:[NSNumber numberWithInt:rule.prefixLen]];
if (!list) {
list = [[NSMutableArray alloc] init];
[data setObject:list forKey:[NSNumber numberWithInt:rule.prefixLen]];
}
[list addObject:rule];
}
if (rule.otherFlag) {
NSMutableDictionary *data = [flagRules objectForKey:@"otherFlag"];
if (!data) {
data = [[NSMutableDictionary alloc] init];
[flagRules setObject:data forKey:@"otherFlag"];
}
NSMutableArray *list = [data objectForKey:[NSNumber numberWithInt:rule.otherFlag]];
if (!list) {
list = [[NSMutableArray alloc] init];
[data setObject:list forKey:[NSNumber numberWithInt:rule.otherFlag]];
}
[list addObject:rule];
}
if (rule.flag12) {
NSMutableDictionary *data = [flagRules objectForKey:@"flag12"];
if (!data) {
data = [[NSMutableDictionary alloc] init];
[flagRules setObject:data forKey:@"flag12"];
}
NSMutableArray *list = [data objectForKey:[NSNumber numberWithInt:rule.flag12]];
if (!list) {
list = [[NSMutableArray alloc] init];
[data setObject:list forKey:[NSNumber numberWithInt:rule.flag12]];
}
[list addObject:rule];
}
if (rule.flag13) {
NSMutableDictionary *data = [flagRules objectForKey:@"flag13"];
if (!data) {
data = [[NSMutableDictionary alloc] init];
[flagRules setObject:data forKey:@"flag13"];
}
NSMutableArray *list = [data objectForKey:[NSNumber numberWithInt:rule.flag13]];
if (!list) {
list = [[NSMutableArray alloc] init];
[data setObject:list forKey:[NSNumber numberWithInt:rule.flag13]];
}
[list addObject:rule];
}
#endif
}
ruleSet.rules = rules;
[ruleSets addObject:ruleSet];
}
res.ruleSets = ruleSets;
}
}
return res;
}
- (void)parseDataHeader {
int count = [self value32:0];
uint32_t base = count * 12 + 4;
const void *bytes = [_data bytes];
NSUInteger spot = 4;
for (int i = 0; i < count; i++) {
NSString *callingCode = [NSString stringWithCString:bytes + spot encoding:NSUTF8StringEncoding];
spot += 4;
NSString *country = [NSString stringWithCString:bytes + spot encoding:NSUTF8StringEncoding];
spot += 4;
uint32_t offset = [self value32:spot] + base;
spot += 4;
if ([country isEqualToString:_defaultCountry]) {
_defaultCallingCode = callingCode;
}
[_countryCallingCode setObject:callingCode forKey:country];
[_callingCodeOffsets setObject:[NSNumber numberWithLong:offset] forKey:callingCode];
NSMutableSet *countries = [_callingCodeCountries objectForKey:callingCode];
if (!countries) {
countries = [[NSMutableSet alloc] init];
[_callingCodeCountries setObject:countries forKey:callingCode];
}
[countries addObject:country];
}
if (_defaultCallingCode) {
[self callingCodeInfo:_defaultCallingCode];
}
}
#ifdef DEBUG
- (void)dump {
NSArray *callingCodes = [[_callingCodeOffsets allKeys] sortedArrayUsingSelector:@selector(compare:)];
for (NSString *callingCode in callingCodes) {
CallingCodeInfo *info = [self callingCodeInfo:callingCode];
NSLog(@"%@", info);
}
NSLog(@"flagRules: %@", flagRules);
NSLog(@"extra1 calling codes: %@", extra1CallingCodes);
NSLog(@"extra2 calling codes: %@", extra2CallingCodes);
NSLog(@"extra3 calling codes: %@", extra3CallingCodes);
}
#endif
@end

View File

@@ -0,0 +1,52 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <LegacyComponents/TGMediaAttachment.h>
#define TGActionMediaAttachmentType 0x1167E28B
typedef enum {
TGMessageActionNone = 0,
TGMessageActionChatEditTitle = 1,
TGMessageActionChatAddMember = 2,
TGMessageActionChatDeleteMember = 3,
TGMessageActionCreateChat = 4,
TGMessageActionChatEditPhoto = 5,
TGMessageActionContactRequest = 6,
TGMessageActionAcceptContactRequest = 7,
TGMessageActionContactRegistered = 8,
TGMessageActionUserChangedPhoto = 9,
TGMessageActionEncryptedChatRequest = 10,
TGMessageActionEncryptedChatAccept = 11,
TGMessageActionEncryptedChatDecline = 12,
TGMessageActionEncryptedChatMessageLifetime = 13,
TGMessageActionEncryptedChatScreenshot = 14,
TGMessageActionEncryptedChatMessageScreenshot = 15,
TGMessageActionCreateBroadcastList = 16,
TGMessageActionJoinedByLink = 17,
TGMessageActionChannelCreated = 18,
TGMessageActionChannelCommentsStatusChanged = 19,
TGMessageActionChannelInviter = 20,
TGMessageActionGroupMigratedTo = 21,
TGMessageActionGroupDeactivated = 22,
TGMessageActionGroupActivated = 23,
TGMessageActionChannelMigratedFrom = 24,
TGMessageActionPinnedMessage = 25,
TGMessageActionClearChat = 26,
TGMessageActionGameScore = 27,
TGMessageActionPhoneCall = 28,
TGMessageActionPaymentSent = 29,
TGMessageActionCustom = 1000
} TGMessageAction;
@interface TGActionMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser>
@property (nonatomic) TGMessageAction actionType;
@property (nonatomic, strong) NSDictionary *actionData;
@end

View File

@@ -0,0 +1,388 @@
#import "TGActionMediaAttachment.h"
#import "TGImageMediaAttachment.h"
@implementation TGActionMediaAttachment
- (id)init
{
self = [super init];
if (self != nil)
{
self.type = TGActionMediaAttachmentType;
}
return self;
}
- (void)serialize:(NSMutableData *)data
{
int dataLengthPtr = (int)data.length;
int zero = 0;
[data appendBytes:&zero length:4];
int actionType = _actionType;
[data appendBytes:&actionType length:4];
if (actionType == TGMessageActionChatAddMember || actionType == TGMessageActionChatDeleteMember)
{
int uid = [[_actionData objectForKey:@"uid"] intValue];
[data appendBytes:&uid length:4];
NSArray *uids = _actionData[@"uids"];
int32_t uidsCount = (int32_t)uids.count;
[data appendBytes:&uidsCount length:4];
for (NSNumber *nUid in uids) {
int32_t listUid = [nUid intValue];
[data appendBytes:&listUid length:4];
}
}
else if (actionType == TGMessageActionJoinedByLink)
{
int uid = [[_actionData objectForKey:@"inviterId"] intValue];
[data appendBytes:&uid length:4];
}
else if (actionType == TGMessageActionChatEditTitle)
{
NSString *title = [_actionData objectForKey:@"title"];
NSData *titleData = [title dataUsingEncoding:NSUTF8StringEncoding];
int length = (int)titleData.length;
[data appendBytes:&length length:4];
[data appendData:titleData];
}
else if (actionType == TGMessageActionCreateChat)
{
NSString *title = [_actionData objectForKey:@"title"];
NSData *titleData = [title dataUsingEncoding:NSUTF8StringEncoding];
int length = (int)titleData.length;
[data appendBytes:&length length:4];
[data appendData:titleData];
NSArray *uids = [_actionData objectForKey:@"uids"];
int count = (int)uids.count;
[data appendBytes:&count length:4];
for (NSNumber *nUid in uids)
{
int uid = [nUid intValue];
[data appendBytes:&uid length:4];
}
}
else if (actionType == TGMessageActionCreateBroadcastList)
{
NSString *title = [_actionData objectForKey:@"title"];
NSData *titleData = [title dataUsingEncoding:NSUTF8StringEncoding];
int length = (int)titleData.length;
[data appendBytes:&length length:4];
[data appendData:titleData];
NSArray *uids = [_actionData objectForKey:@"uids"];
int count = (int)uids.count;
[data appendBytes:&count length:4];
for (NSNumber *nUid in uids)
{
int uid = [nUid intValue];
[data appendBytes:&uid length:4];
}
}
else if (actionType == TGMessageActionChatEditPhoto)
{
TGImageMediaAttachment *photo = [_actionData objectForKey:@"photo"];
if (photo != nil)
{
[photo serialize:data];
}
}
else if (actionType == TGMessageActionContactRequest)
{
int hasPhone = [[_actionData objectForKey:@"hasPhone"] boolValue] ? 1 : 0;
[data appendBytes:&hasPhone length:4];
}
else if (actionType == TGMessageActionAcceptContactRequest)
{
}
else if (actionType == TGMessageActionContactRegistered)
{
}
else if (actionType == TGMessageActionUserChangedPhoto)
{
TGImageMediaAttachment *photo = [_actionData objectForKey:@"photo"];
if (photo != nil)
{
[photo serialize:data];
}
}
else if (actionType == TGMessageActionEncryptedChatRequest)
{
}
else if (actionType == TGMessageActionEncryptedChatAccept)
{
}
else if (actionType == TGMessageActionEncryptedChatDecline)
{
}
else if (actionType == TGMessageActionEncryptedChatMessageLifetime)
{
int32_t messageLifetime = [_actionData[@"messageLifetime"] intValue];
[data appendBytes:&messageLifetime length:4];
}
else if (actionType == TGMessageActionEncryptedChatScreenshot)
{
}
else if (actionType == TGMessageActionChannelCreated)
{
NSString *title = [_actionData objectForKey:@"title"];
NSData *titleData = [title dataUsingEncoding:NSUTF8StringEncoding];
int length = (int)titleData.length;
[data appendBytes:&length length:4];
[data appendData:titleData];
}
else if (actionType == TGMessageActionChannelCommentsStatusChanged) {
uint8_t enabled = [_actionData[@"enabled"] boolValue];
[data appendBytes:&enabled length:1];
} else if (actionType == TGMessageActionChannelInviter) {
int32_t inviter = [_actionData[@"uid"] intValue];
[data appendBytes:&inviter length:4];
} else if (actionType == TGMessageActionGroupMigratedTo) {
int32_t channelId = [_actionData[@"channelId"] intValue];
[data appendBytes:&channelId length:4];
} else if (actionType == TGMessageActionGroupDeactivated) {
} else if (actionType == TGMessageActionGroupActivated) {
} else if (actionType == TGMessageActionChannelMigratedFrom) {
NSString *title = [_actionData objectForKey:@"title"];
NSData *titleData = [title dataUsingEncoding:NSUTF8StringEncoding];
int length = (int)titleData.length;
[data appendBytes:&length length:4];
[data appendData:titleData];
int32_t channelId = [_actionData[@"groupId"] intValue];
[data appendBytes:&channelId length:4];
} else if (actionType == TGMessageActionPinnedMessage) {
} else if (actionType == TGMessageActionClearChat) {
} else if (actionType == TGMessageActionGameScore) {
int32_t gameId = [_actionData[@"gameId"] intValue];
[data appendBytes:&gameId length:4];
int32_t score = [_actionData[@"score"] intValue];
[data appendBytes:&score length:4];
} else if (actionType == TGMessageActionPhoneCall) {
int64_t callId = [_actionData[@"callId"] longLongValue];
[data appendBytes:&callId length:8];
int32_t reason = [_actionData[@"reason"] intValue];
[data appendBytes:&reason length:4];
int32_t duration = [_actionData[@"duration"] intValue];
[data appendBytes:&duration length:4];
} else if (actionType == TGMessageActionPaymentSent) {
NSString *curreny = _actionData[@"currency"];
NSData *currencyBytes = [curreny dataUsingEncoding:NSUTF8StringEncoding];
int32_t currencyLength = (int32_t)currencyBytes.length;
[data appendBytes:&currencyLength length:4];
[data appendData:currencyBytes];
int32_t totalAmount = [_actionData[@"totalAmount"] intValue];
[data appendBytes:&totalAmount length:4];
}
int dataLength = (int)data.length - dataLengthPtr - 4;
[data replaceBytesInRange:NSMakeRange(dataLengthPtr, 4) withBytes:&dataLength];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int dataLength = 0;
[is read:(uint8_t *)&dataLength maxLength:4];
TGActionMediaAttachment *actionAttachment = [[TGActionMediaAttachment alloc] init];
int actionType = 0;
[is read:(uint8_t *)&actionType maxLength:4];
dataLength -= 4;
actionAttachment.actionType = (TGMessageAction)actionType;
if (actionType == TGMessageActionChatAddMember || actionType == TGMessageActionChatDeleteMember)
{
int uid = 0;
[is read:(uint8_t *)&uid maxLength:4];
dataLength -= 4;
NSMutableArray *uids = [[NSMutableArray alloc] init];
if (dataLength >= 4) {
int32_t uidsCount = 0;
[is read:(uint8_t *)&uidsCount maxLength:4];
dataLength -= 4;
for (int32_t i = 0; dataLength > 0 && i < uidsCount; i++) {
int32_t listUid = 0;
[is read:(uint8_t *)&listUid maxLength:4];
[uids addObject:@(listUid)];
dataLength -= 4;
}
}
if (uids.count != 0) {
actionAttachment.actionData = @{@"uid": @(uid), @"uids": uids};
} else {
actionAttachment.actionData = @{@"uid": @(uid)};
}
}
else if (actionType == TGMessageActionJoinedByLink)
{
int uid = 0;
[is read:(uint8_t *)&uid maxLength:4];
actionAttachment.actionData = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:uid] forKey:@"inviterId"];
}
else if (actionType == TGMessageActionChatEditTitle)
{
int length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *titleBytes = malloc(length);
[is read:titleBytes maxLength:length];
NSString *title = [[NSString alloc] initWithBytesNoCopy:titleBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
actionAttachment.actionData = [NSDictionary dictionaryWithObject:(title == nil ? @"" : title) forKey:@"title"];
}
else if (actionType == TGMessageActionCreateChat)
{
int length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *titleBytes = malloc(length);
[is read:titleBytes maxLength:length];
NSString *title = [[NSString alloc] initWithBytesNoCopy:titleBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
int count = 0;
[is read:(uint8_t *)&count maxLength:4];
NSMutableArray *uids = [[NSMutableArray alloc] initWithCapacity:count];
for (int i = 0; i < count; i++)
{
int uid = 0;
[is read:(uint8_t *)&uid maxLength:4];
if (uid != 0)
[uids addObject:[[NSNumber alloc] initWithInt:uid]];
}
actionAttachment.actionData = [[NSDictionary alloc] initWithObjectsAndKeys:(title == nil ? @"" : title), @"title", uids, @"uids", nil];
}
else if (actionType == TGMessageActionCreateBroadcastList)
{
int length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *titleBytes = malloc(length);
[is read:titleBytes maxLength:length];
NSString *title = [[NSString alloc] initWithBytesNoCopy:titleBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
int count = 0;
[is read:(uint8_t *)&count maxLength:4];
NSMutableArray *uids = [[NSMutableArray alloc] initWithCapacity:count];
for (int i = 0; i < count; i++)
{
int uid = 0;
[is read:(uint8_t *)&uid maxLength:4];
if (uid != 0)
[uids addObject:[[NSNumber alloc] initWithInt:uid]];
}
actionAttachment.actionData = [[NSDictionary alloc] initWithObjectsAndKeys:(title == nil ? @"" : title), @"title", uids, @"uids", nil];
}
else if (actionType == TGMessageActionChatEditPhoto)
{
TGImageMediaAttachment *photo = (TGImageMediaAttachment *)[[[TGImageMediaAttachment alloc] init] parseMediaAttachment:is];
if (photo != nil)
actionAttachment.actionData = [[NSDictionary alloc] initWithObjectsAndKeys:photo, @"photo", nil];
}
else if (actionType == TGMessageActionContactRequest)
{
int hasPhone = 0;
[is read:(uint8_t *)&hasPhone maxLength:4];
actionAttachment.actionData = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSNumber alloc] initWithBool:hasPhone != 0], @"hasPhone", nil];
}
else if (actionType == TGMessageActionAcceptContactRequest)
{
}
else if (actionType == TGMessageActionContactRegistered)
{
}
else if (actionType == TGMessageActionUserChangedPhoto)
{
TGImageMediaAttachment *photo = (TGImageMediaAttachment *)[[[TGImageMediaAttachment alloc] init] parseMediaAttachment:is];
if (photo != nil)
actionAttachment.actionData = [[NSDictionary alloc] initWithObjectsAndKeys:photo, @"photo", nil];
}
else if (actionType == TGMessageActionEncryptedChatRequest)
{
}
else if (actionType == TGMessageActionEncryptedChatAccept)
{
}
else if (actionType == TGMessageActionEncryptedChatDecline)
{
}
else if (actionType == TGMessageActionEncryptedChatMessageLifetime)
{
int32_t messageLifetime = 0;
[is read:(uint8_t *)&messageLifetime maxLength:4];
actionAttachment.actionData = [[NSDictionary alloc] initWithObjectsAndKeys:[[NSNumber alloc] initWithInt:messageLifetime], @"messageLifetime", nil];
}
else if (actionType == TGMessageActionEncryptedChatScreenshot)
{
}
else if (actionType == TGMessageActionChannelCreated)
{
int length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *titleBytes = malloc(length);
[is read:titleBytes maxLength:length];
NSString *title = [[NSString alloc] initWithBytesNoCopy:titleBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
actionAttachment.actionData = [NSDictionary dictionaryWithObject:(title == nil ? @"" : title) forKey:@"title"];
}
else if (actionType == TGMessageActionChannelCommentsStatusChanged) {
uint8_t enabled = 0;
[is read:(uint8_t *)&enabled maxLength:1];
actionAttachment.actionData = @{@"enabled": @(enabled != 0)};
} else if (actionType == TGMessageActionChannelInviter) {
int32_t uid = 0;
[is read:(uint8_t *)&uid maxLength:4];
actionAttachment.actionData = @{@"uid": @(uid)};
} else if (actionType == TGMessageActionGroupMigratedTo) {
int32_t channelId = 0;
[is read:(uint8_t *)&channelId maxLength:4];
actionAttachment.actionData = @{@"channelId": @(channelId)};
} else if (actionType == TGMessageActionChannelMigratedFrom) {
int length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *titleBytes = malloc(length);
[is read:titleBytes maxLength:length];
NSString *title = [[NSString alloc] initWithBytesNoCopy:titleBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
int32_t groupId = 0;
[is read:(uint8_t *)&groupId maxLength:4];
actionAttachment.actionData = @{@"groupId": @(groupId), @"title": title};
} else if (actionType == TGMessageActionPinnedMessage) {
} else if (actionType == TGMessageActionClearChat) {
} else if (actionType == TGMessageActionGameScore) {
int gameId = 0;
[is read:(uint8_t *)&gameId maxLength:4];
int score = 0;
[is read:(uint8_t *)&score maxLength:4];
actionAttachment.actionData = @{@"gameId": @(gameId), @"score": @(score)};
} else if (actionType == TGMessageActionPhoneCall) {
int64_t callId = 0;
[is read:(uint8_t *)&callId maxLength:8];
int32_t reason = 0;
[is read:(uint8_t *)&reason maxLength:4];
int32_t duration = 0;
[is read:(uint8_t *)&duration maxLength:4];
actionAttachment.actionData = @{@"callId": @(callId), @"reason": @(reason), @"duration": @(duration)};
} else if (actionType == TGMessageActionPaymentSent) {
int32_t currencyLength = 0;
[is read:(uint8_t *)&currencyLength maxLength:4];
uint8_t *titleBytes = malloc(currencyLength);
[is read:titleBytes maxLength:currencyLength];
NSString *title = [[NSString alloc] initWithBytesNoCopy:titleBytes length:currencyLength encoding:NSUTF8StringEncoding freeWhenDone:true];
int32_t totalAmount = 0;
[is read:(uint8_t *)&totalAmount maxLength:4];
actionAttachment.actionData = @{@"currency": title, @"totalAmount": @(totalAmount)};
}
return actionAttachment;
}
@end

View File

@@ -0,0 +1,33 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <LegacyComponents/TGMediaAttachment.h>
#define TGAudioMediaAttachmentType 0x3A0E7A32
@interface TGAudioMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser>
@property (nonatomic) int64_t audioId;
@property (nonatomic) int64_t accessHash;
@property (nonatomic) int32_t datacenterId;
@property (nonatomic) int64_t localAudioId;
@property (nonatomic) int32_t duration;
@property (nonatomic) int32_t fileSize;
@property (nonatomic, strong) NSString *audioUri;
/*- (NSString *)localFilePath;
+ (NSString *)localAudioFileDirectoryForLocalAudioId:(int64_t)audioId;
+ (NSString *)localAudioFileDirectoryForRemoteAudioId:(int64_t)audioId;
+ (NSString *)localAudioFilePathForLocalAudioId:(int64_t)audioId;
+ (NSString *)localAudioFilePathForRemoteAudioId:(int64_t)audioId;*/
@end

View File

@@ -0,0 +1,71 @@
#import "TGAudioMediaAttachment.h"
@implementation TGAudioMediaAttachment
- (instancetype)init
{
self = [super init];
if (self != nil)
{
self.type = TGAudioMediaAttachmentType;
}
return self;
}
- (void)serialize:(NSMutableData *)data
{
int dataLengthPtr = (int)data.length;
int32_t zero = 0;
[data appendBytes:&zero length:4];
[data appendBytes:&_audioId length:8];
[data appendBytes:&_accessHash length:8];
[data appendBytes:&_datacenterId length:4];
[data appendBytes:&_localAudioId length:8];
[data appendBytes:&_duration length:4];
[data appendBytes:&_fileSize length:4];
NSData *audioUriData = [_audioUri dataUsingEncoding:NSUTF8StringEncoding];
int32_t audioUriLength = (int32_t)audioUriData.length;
[data appendBytes:&audioUriLength length:4];
if (audioUriLength != 0)
[data appendData:audioUriData];
int dataLength = (int)(data.length - dataLengthPtr - 4);
[data replaceBytesInRange:NSMakeRange(dataLengthPtr, 4) withBytes:&dataLength];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int dataLength = 0;
[is read:(uint8_t *)&dataLength maxLength:4];
TGAudioMediaAttachment *attachment = [[TGAudioMediaAttachment alloc] init];
if (attachment != nil)
{
[is read:(uint8_t *)&attachment->_audioId maxLength:8];
[is read:(uint8_t *)&attachment->_accessHash maxLength:8];
[is read:(uint8_t *)&attachment->_datacenterId maxLength:4];
[is read:(uint8_t *)&attachment->_localAudioId maxLength:8];
[is read:(uint8_t *)&attachment->_duration maxLength:4];
[is read:(uint8_t *)&attachment->_fileSize maxLength:4];
int32_t audioUriLength = 0;
[is read:(uint8_t *)&audioUriLength maxLength:4];
if (audioUriLength != 0)
{
uint8_t *audioUriBytes = malloc(audioUriLength);
[is read:audioUriBytes maxLength:audioUriLength];
attachment.audioUri = [[NSString alloc] initWithBytesNoCopy:audioUriBytes length:audioUriLength encoding:NSUTF8StringEncoding freeWhenDone:true];
}
}
return attachment;
}
@end

View File

@@ -0,0 +1,15 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
@interface TGAudioWaveform : NSObject <NSCoding, PSCoding>
@property (nonatomic, strong, readonly) NSData *samples;
@property (nonatomic, readonly) int32_t peak;
- (instancetype)initWithSamples:(NSData *)samples peak:(int32_t)peak;
- (instancetype)initWithBitstream:(NSData *)bitstream bitsPerSample:(NSUInteger)bitsPerSample;
- (NSData *)bitstream;
@end

View File

@@ -0,0 +1,85 @@
#import "TGAudioWaveform.h"
#import "LegacyComponentsInternal.h"
#import "PSKeyValueCoder.h"
static int32_t get_bits(uint8_t const *bytes, unsigned int bitOffset, unsigned int numBits)
{
uint8_t const *data = bytes;
numBits = (unsigned int)pow(2, numBits) - 1; //this will only work up to 32 bits, of course
data += bitOffset / 8;
bitOffset %= 8;
return (*((int*)data) >> bitOffset) & numBits;
}
static void set_bits(uint8_t *bytes, int32_t bitOffset, int32_t numBits, int32_t value) {
numBits = (unsigned int)pow(2, numBits) - 1; //this will only work up to 32 bits, of course
uint8_t *data = bytes;
data += bitOffset / 8;
bitOffset %= 8;
*((int32_t *)data) |= ((value) << bitOffset);
}
@implementation TGAudioWaveform
- (instancetype)initWithSamples:(NSData *)samples peak:(int32_t)peak {
self = [super init];
if (self != nil) {
_samples = samples;
_peak = peak;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithSamples:[aDecoder decodeObjectForKey:@"samples"] peak:[aDecoder decodeInt32ForKey:@"peak"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_samples forKey:@"samples"];
[aCoder encodeInt32:_peak forKey:@"peak"];
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
return [self initWithSamples:[coder decodeDataCorCKey:"samples"] peak:[coder decodeInt32ForCKey:"peak"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeData:_samples forCKey:"samples"];
[coder encodeInt32:_peak forCKey:"peak"];
}
- (instancetype)initWithBitstream:(NSData *)bitstream bitsPerSample:(NSUInteger)bitsPerSample {
int numSamples = (int)(bitstream.length * 8 / bitsPerSample);
uint8_t const *bytes = bitstream.bytes;
int32_t maxSample = (1 << bitsPerSample) - 1;
NSMutableData *result = [[NSMutableData alloc] initWithLength:numSamples * 2];
int16_t *samples = result.mutableBytes;
int32_t norm = (1 << bitsPerSample) - 1;
for (int i = 0; i < numSamples; i++) {
samples[i] = (int16_t)(((int64_t)get_bits(bytes, i * 5, 5) * maxSample) / norm);
}
return [self initWithSamples:result peak:31];
}
- (NSData *)bitstream {
int numSamples = (int)(_samples.length / 2);
int bitstreamLength = (numSamples * 5) / 8 + (((numSamples * 5) % 8) == 0 ? 0 : 1);
NSMutableData *result = [[NSMutableData alloc] initWithLength:bitstreamLength];
int32_t maxSample = _peak;
uint16_t const *samples = _samples.bytes;
uint8_t *bytes = result.mutableBytes;
for (int i = 0; i < numSamples; i++) {
int32_t value = MIN(31, ABS((int32_t)samples[i]) * 31 / maxSample);
set_bits(bytes, i * 5, 5, value & 31);
}
return result;
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGAudioWaveform class]] && TGObjectCompare(_samples, ((TGAudioWaveform *)object)->_samples) && _peak == ((TGAudioWaveform *)object)->_peak;
}
@end

View File

@@ -0,0 +1,15 @@
#import <LegacyComponents/TGMediaAttachment.h>
@class TGImageMediaAttachment;
@class TGDocumentMediaAttachment;
@class TGWebPageMediaAttachment;
#define TGAuthorSignatureMediaAttachmentType ((int)0x157b8516)
@interface TGAuthorSignatureMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser, NSCoding>
@property (nonatomic, strong, readonly) NSString *signature;
- (instancetype)initWithSignature:(NSString *)signature;
@end

View File

@@ -0,0 +1,46 @@
#import "TGAuthorSignatureMediaAttachment.h"
#import "LegacyComponentsInternal.h"
#import "NSInputStream+TL.h"
@implementation TGAuthorSignatureMediaAttachment
- (instancetype)initWithSignature:(NSString *)signature {
self = [super init];
if (self != nil) {
self.type = TGAuthorSignatureMediaAttachmentType;
_signature = signature;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithSignature:[aDecoder decodeObjectForKey:@"signature"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_signature forKey:@"signature"];
}
- (void)serialize:(NSMutableData *)data
{
NSData *serializedData = [NSKeyedArchiver archivedDataWithRootObject:self];
int32_t length = (int32_t)serializedData.length;
[data appendBytes:&length length:4];
[data appendData:serializedData];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int32_t length = [is readInt32];
NSData *data = [is readData:length];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGAuthorSignatureMediaAttachment class]] && TGStringCompare(((TGAuthorSignatureMediaAttachment *)object)->_signature, _signature);
}
@end

View File

@@ -0,0 +1,12 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
@interface TGBotComandInfo : NSObject <PSCoding>
@property (nonatomic, strong, readonly) NSString *command;
@property (nonatomic, strong, readonly) NSString *commandDescription;
- (instancetype)initWithCommand:(NSString *)command commandDescription:(NSString *)commandDescription;
@end

View File

@@ -0,0 +1,29 @@
#import "TGBotComandInfo.h"
#import "PSKeyValueCoder.h"
@implementation TGBotComandInfo
- (instancetype)initWithCommand:(NSString *)command commandDescription:(NSString *)commandDescription
{
self = [super init];
if (self != nil)
{
_command = command;
_commandDescription = commandDescription;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithCommand:[coder decodeStringForCKey:"command"] commandDescription:[coder decodeStringForCKey:"commandDescription"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeString:_command forCKey:"command"];
[coder encodeString:_commandDescription forCKey:"commandDescription"];
}
@end

View File

@@ -0,0 +1,16 @@
#import <LegacyComponents/TGMediaAttachment.h>
#import <LegacyComponents/TGImageInfo.h>
#import <LegacyComponents/TGDocumentMediaAttachment.h>
#define TGBotContextResultAttachmentType ((int)0x1718023f)
@interface TGBotContextResultAttachment : TGMediaAttachment <TGMediaAttachmentParser, NSCoding>
@property (nonatomic, readonly) int32_t userId;
@property (nonatomic, strong, readonly) NSString *resultId;
@property (nonatomic, readonly) int64_t queryId;
- (instancetype)initWithUserId:(int32_t)userId resultId:(NSString *)resultId queryId:(int64_t)queryId;
@end

View File

@@ -0,0 +1,44 @@
#import "TGBotContextResultAttachment.h"
#import "NSInputStream+TL.h"
@implementation TGBotContextResultAttachment
- (instancetype)initWithUserId:(int32_t)userId resultId:(NSString *)resultId queryId:(int64_t)queryId {
self = [super init];
if (self != nil) {
self.type = TGBotContextResultAttachmentType;
_userId = userId;
_resultId = resultId;
_queryId = queryId;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithUserId:[aDecoder decodeInt32ForKey:@"userId"] resultId:[aDecoder decodeObjectForKey:@"resultId"] queryId:[aDecoder decodeInt64ForKey:@"queryId"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt32:_userId forKey:@"userId"];
[aCoder encodeObject:_resultId forKey:@"resultId"];
[aCoder encodeInt64:_queryId forKey:@"queryId"];
}
- (void)serialize:(NSMutableData *)data
{
NSData *serializedData = [NSKeyedArchiver archivedDataWithRootObject:self];
int32_t length = (int32_t)serializedData.length;
[data appendBytes:&length length:4];
[data appendData:serializedData];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int32_t length = [is readInt32];
NSData *data = [is readData:length];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
@end

View File

@@ -0,0 +1,15 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
#import <LegacyComponents/TGBotComandInfo.h>
@interface TGBotInfo : NSObject <PSCoding>
@property (nonatomic, readonly) int32_t version;
@property (nonatomic, strong, readonly) NSString *shortDescription;
@property (nonatomic, strong, readonly) NSString *botDescription;
@property (nonatomic, strong, readonly) NSArray *commandList;
- (instancetype)initWithVersion:(int32_t)version shortDescription:(NSString *)shortDescription botDescription:(NSString *)botDescription commandList:(NSArray *)commandList;
@end

View File

@@ -0,0 +1,33 @@
#import "TGBotInfo.h"
#import "PSKeyValueCoder.h"
@implementation TGBotInfo
- (instancetype)initWithVersion:(int32_t)version shortDescription:(NSString *)shortDescription botDescription:(NSString *)botDescription commandList:(NSArray *)commandList
{
self = [super init];
if (self != nil)
{
_version = version;
_botDescription = botDescription;
_shortDescription = shortDescription;
_commandList = commandList;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithVersion:[coder decodeInt32ForCKey:"version"] shortDescription:[coder decodeStringForCKey:"shortDescription"] botDescription:[coder decodeStringForCKey:"botDescription"] commandList:[coder decodeArrayForCKey:"commandList"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeInt32:_version forCKey:"version"];
[coder encodeString:_shortDescription forCKey:"shortDescription"];
[coder encodeString:_botDescription forCKey:"botDescription"];
[coder encodeArray:_commandList forCKey:"commandList"];
}
@end

View File

@@ -0,0 +1,24 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
#import <LegacyComponents/TGBotReplyMarkupRow.h>
@interface TGBotReplyMarkup : NSObject <NSCoding, PSCoding>
@property (nonatomic, readonly) int32_t userId;
@property (nonatomic, readonly) int32_t messageId;
@property (nonatomic, strong, readonly) NSArray *rows;
@property (nonatomic) bool matchDefaultHeight;
@property (nonatomic) bool hideKeyboardOnActivation;
@property (nonatomic) bool alreadyActivated;
@property (nonatomic) bool manuallyHidden;
@property (nonatomic) bool isInline;
- (instancetype)initWithUserId:(int32_t)userId messageId:(int32_t)messageId rows:(NSArray *)rows matchDefaultHeight:(bool)matchDefaultHeight hideKeyboardOnActivation:(bool)hideKeyboardOnActivation alreadyActivated:(bool)alreadyActivated manuallyHidden:(bool)manuallyHidden isInline:(bool)isInline;
- (TGBotReplyMarkup *)activatedMarkup;
- (TGBotReplyMarkup *)manuallyHide;
- (TGBotReplyMarkup *)manuallyUnhide;
@end

View File

@@ -0,0 +1,87 @@
#import "TGBotReplyMarkup.h"
#import "PSKeyValueCoder.h"
@implementation TGBotReplyMarkup
- (instancetype)initWithUserId:(int32_t)userId messageId:(int32_t)messageId rows:(NSArray *)rows matchDefaultHeight:(bool)matchDefaultHeight hideKeyboardOnActivation:(bool)hideKeyboardOnActivation alreadyActivated:(bool)alreadyActivated manuallyHidden:(bool)manuallyHidden isInline:(bool)isInline
{
self = [super init];
if (self != nil)
{
_userId = userId;
_messageId = messageId;
_rows = rows;
_matchDefaultHeight = matchDefaultHeight;
_hideKeyboardOnActivation = hideKeyboardOnActivation;
_alreadyActivated = alreadyActivated;
_manuallyHidden = manuallyHidden;
_isInline = isInline;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithUserId:[coder decodeInt32ForCKey:"userId"] messageId:[coder decodeInt32ForCKey:"messageId"] rows:[coder decodeArrayForCKey:"rows"] matchDefaultHeight:[coder decodeInt32ForCKey:"matchDefaultHeight"] hideKeyboardOnActivation:[coder decodeInt32ForCKey:"hideKeyboardOnActivation"] alreadyActivated:[coder decodeInt32ForCKey:"alreadyActivated"] manuallyHidden:[coder decodeInt32ForCKey:"manuallyHidden"] isInline:[coder decodeInt32ForCKey:"isInline"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeInt32:_userId forCKey:"userId"];
[coder encodeInt32:_messageId forCKey:"messageId"];
[coder encodeArray:_rows forCKey:"rows"];
[coder encodeInt32:_matchDefaultHeight forCKey:"matchDefaultHeight"];
[coder encodeInt32:_hideKeyboardOnActivation forCKey:"hideKeyboardOnActivation"];
[coder encodeInt32:_alreadyActivated forCKey:"alreadyActivated"];
[coder encodeInt32:_manuallyHidden forCKey:"manuallyHidden"];
[coder encodeInt32:_isInline forCKey:"isInline"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithUserId:[aDecoder decodeInt32ForKey:@"userId"] messageId:[aDecoder decodeInt32ForKey:@"messageId"] rows:[aDecoder decodeObjectForKey:@"rows"] matchDefaultHeight:[aDecoder decodeBoolForKey:@"matchDefaultHeight"] hideKeyboardOnActivation:[aDecoder decodeBoolForKey:@"hideKeyboardOnDeactivation"] alreadyActivated:[aDecoder decodeBoolForKey:@"alreadyActivated"] manuallyHidden:[aDecoder decodeBoolForKey:@"manuallyHidden"] isInline:[aDecoder decodeBoolForKey:@"isInline"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt32:_userId forKey:@"userId"];
[aCoder encodeInt32:_messageId forKey:@"messageId"];
[aCoder encodeObject:_rows forKey:@"rows"];
[aCoder encodeBool:_matchDefaultHeight forKey:@"matchDefaultHeight"];
[aCoder encodeBool:_hideKeyboardOnActivation forKey:@"hideKeyboardOnActivation"];
[aCoder encodeBool:_alreadyActivated forKey:@"alreadyActivated"];
[aCoder encodeBool:_manuallyHidden forKey:@"manuallyHidden"];
[aCoder encodeBool:_isInline forKey:@"isInline"];
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGBotReplyMarkup class]] && [((TGBotReplyMarkup *)object)->_rows isEqual:_rows] && ((TGBotReplyMarkup *)object)->_userId == _userId && ((TGBotReplyMarkup *)object)->_messageId == _messageId && ((TGBotReplyMarkup *)object)->_matchDefaultHeight == _matchDefaultHeight && _isInline == ((TGBotReplyMarkup *)object)->_isInline;
}
- (TGBotReplyMarkup *)activatedMarkup
{
if (_alreadyActivated)
return self;
return [[TGBotReplyMarkup alloc] initWithUserId:_userId messageId:_messageId rows:_rows matchDefaultHeight:_matchDefaultHeight hideKeyboardOnActivation:_hideKeyboardOnActivation alreadyActivated:true manuallyHidden:_manuallyHidden isInline:_isInline];
}
- (TGBotReplyMarkup *)manuallyHide
{
if (_manuallyHidden) {
return self;
}
return [[TGBotReplyMarkup alloc] initWithUserId:_userId messageId:_messageId rows:_rows matchDefaultHeight:_matchDefaultHeight hideKeyboardOnActivation:_hideKeyboardOnActivation alreadyActivated:_alreadyActivated manuallyHidden:true isInline:_isInline];
}
- (TGBotReplyMarkup *)manuallyUnhide
{
if (!_manuallyHidden) {
return self;
}
return [[TGBotReplyMarkup alloc] initWithUserId:_userId messageId:_messageId rows:_rows matchDefaultHeight:_matchDefaultHeight hideKeyboardOnActivation:_hideKeyboardOnActivation alreadyActivated:_alreadyActivated manuallyHidden:false isInline:_isInline];
}
@end

View File

@@ -0,0 +1,61 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
@interface TGBotReplyMarkupButtonActionUrl : NSObject <PSCoding, NSCoding>
@property (nonatomic, strong, readonly) NSString *url;
- (instancetype)initWithUrl:(NSString *)url;
@end
@interface TGBotReplyMarkupButtonActionCallback : NSObject <PSCoding, NSCoding>
@property (nonatomic, strong, readonly) NSData *data;
- (instancetype)initWithData:(NSData *)data;
@end
@interface TGBotReplyMarkupButtonActionRequestPhone : NSObject <PSCoding, NSCoding>
@end
@interface TGBotReplyMarkupButtonActionRequestLocation : NSObject <PSCoding, NSCoding>
@end
@interface TGBotReplyMarkupButtonActionSwitchInline : NSObject <PSCoding, NSCoding>
@property (nonatomic, strong, readonly) NSString *query;
@property (nonatomic, readonly) bool samePeer;
- (instancetype)initWithQuery:(NSString *)query samePeer:(bool)samePeer;
@end
@interface TGBotReplyMarkupButtonActionGame : NSObject <PSCoding, NSCoding>
@property (nonatomic, strong, readonly) NSString *text;
- (instancetype)initWithText:(NSString *)text;
@end
@interface TGBotReplyMarkupButtonActionPurchase : NSObject <PSCoding, NSCoding>
@property (nonatomic, strong, readonly) NSString *text;
- (instancetype)initWithText:(NSString *)text;
@end
@interface TGBotReplyMarkupButton : NSObject <PSCoding, NSCoding>
@property (nonatomic, strong, readonly) NSString *text;
@property (nonatomic, strong, readonly) id<PSCoding, NSCoding> action;
- (instancetype)initWithText:(NSString *)text action:(id<PSCoding, NSCoding>)action;
@end

View File

@@ -0,0 +1,262 @@
#import "TGBotReplyMarkupButton.h"
#import "LegacyComponentsInternal.h"
#import "PSKeyValueCoder.h"
@implementation TGBotReplyMarkupButtonActionUrl
- (instancetype)initWithUrl:(NSString *)url {
self = [super init];
if (self != nil) {
_url = url;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
return [self initWithUrl:[coder decodeStringForCKey:"url"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeString:_url forCKey:"url"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithUrl:[aDecoder decodeObjectForKey:@"url"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_url forKey:@"url"];
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGBotReplyMarkupButtonActionUrl class]] && TGStringCompare(_url, ((TGBotReplyMarkupButtonActionUrl *)object)->_url);
}
@end
@implementation TGBotReplyMarkupButtonActionCallback
- (instancetype)initWithData:(NSData *)data {
self = [super init];
if (self != nil) {
_data = data;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
return [self initWithData:[coder decodeDataCorCKey:"data"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeData:_data forCKey:"data"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithData:[aDecoder decodeObjectForKey:@"data"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_data forKey:@"data"];
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGBotReplyMarkupButtonActionCallback class]] && TGObjectCompare(_data, ((TGBotReplyMarkupButtonActionCallback *)object)->_data);
}
@end
@implementation TGBotReplyMarkupButtonActionRequestPhone
- (instancetype)init {
return [super init];
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)__unused coder {
return [self init];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)__unused coder {
}
- (instancetype)initWithCoder:(NSCoder *)__unused aDecoder {
return [self init];
}
- (void)encodeWithCoder:(NSCoder *)__unused aCoder {
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGBotReplyMarkupButtonActionRequestPhone class]];
}
@end
@implementation TGBotReplyMarkupButtonActionRequestLocation
- (instancetype)init {
return [super init];
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)__unused coder {
return [self init];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)__unused coder {
}
- (instancetype)initWithCoder:(NSCoder *)__unused aDecoder {
return [self init];
}
- (void)encodeWithCoder:(NSCoder *)__unused aCoder {
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGBotReplyMarkupButtonActionRequestLocation class]];
}
@end
@implementation TGBotReplyMarkupButtonActionSwitchInline
- (instancetype)initWithQuery:(NSString *)query samePeer:(bool)samePeer {
self = [super init];
if (self != nil) {
_query = query;
_samePeer = samePeer;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
return [self initWithQuery:[coder decodeStringForCKey:"query"] samePeer:[coder decodeInt32ForCKey:"samePeer"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeString:_query forCKey:"query"];
[coder encodeInt32:_samePeer ? 1 : 0 forCKey:"samePeer"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithQuery:[aDecoder decodeObjectForKey:@"query"] samePeer:[aDecoder decodeBoolForKey:@"samePeer"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_query forKey:@"query"];
[aCoder encodeBool:_samePeer forKey:@"samePeer"];
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGBotReplyMarkupButtonActionSwitchInline class]] && TGStringCompare(_query, ((TGBotReplyMarkupButtonActionSwitchInline *)object)->_query) && _samePeer == ((TGBotReplyMarkupButtonActionSwitchInline *)object)->_samePeer;
}
@end
@implementation TGBotReplyMarkupButtonActionGame
- (instancetype)initWithText:(NSString *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
return [self initWithText:[coder decodeStringForCKey:"text"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeString:_text forCKey:"text"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithText:[aDecoder decodeObjectForKey:@"text"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGBotReplyMarkupButtonActionGame class]] && TGStringCompare(_text, ((TGBotReplyMarkupButtonActionGame *)object)->_text);
}
@end
@implementation TGBotReplyMarkupButtonActionPurchase
- (instancetype)initWithText:(NSString *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
return [self initWithText:[coder decodeStringForCKey:"text"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeString:_text forCKey:"text"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithText:[aDecoder decodeObjectForKey:@"text"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGBotReplyMarkupButtonActionPurchase class]] && TGStringCompare(_text, ((TGBotReplyMarkupButtonActionPurchase *)object)->_text);
}
@end
@implementation TGBotReplyMarkupButton
- (instancetype)initWithText:(NSString *)text action:(id<PSCoding, NSCoding>)action
{
self = [super init];
if (self != nil)
{
_text = text;
_action = action;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithText:[coder decodeStringForCKey:"text"] action:(id)[coder decodeObjectForKey:@"action"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeString:_text forCKey:"text"];
[coder encodeObject:_action forCKey:"action"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithText:[aDecoder decodeObjectForKey:@"text"] action:[aDecoder decodeObjectForKey:@"action"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
[aCoder encodeObject:_action forKey:@"action"];
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGBotReplyMarkupButton class]] && [((TGBotReplyMarkupButton *)object)->_text isEqualToString:_text] && TGObjectCompare(_action, ((TGBotReplyMarkupButton *)object)->_action);
}
@end

View File

@@ -0,0 +1,13 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
#import <LegacyComponents/TGBotReplyMarkupButton.h>
@interface TGBotReplyMarkupRow : NSObject <PSCoding, NSCoding>
@property (nonatomic, strong, readonly) NSArray *buttons;
- (instancetype)initWithButtons:(NSArray *)buttons;
@end

View File

@@ -0,0 +1,40 @@
#import "TGBotReplyMarkupRow.h"
#import "PSKeyValueCoder.h"
@implementation TGBotReplyMarkupRow
- (instancetype)initWithButtons:(NSArray *)buttons
{
self = [super init];
if (self != nil)
{
_buttons = buttons;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithButtons:[coder decodeArrayForCKey:"buttons"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeArray:_buttons forCKey:"buttons"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithButtons:[aDecoder decodeObjectForKey:@"buttons"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_buttons forKey:@"buttons"];
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGBotReplyMarkupRow class]] && [((TGBotReplyMarkupRow *)object)->_buttons isEqual:_buttons];
}
@end

View File

@@ -0,0 +1,27 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
@class TLChannelAdminRights;
@interface TGChannelAdminRights : NSObject <PSCoding>
@property (nonatomic, readonly) bool canChangeInfo;
@property (nonatomic, readonly) bool canPostMessages;
@property (nonatomic, readonly) bool canEditMessages;
@property (nonatomic, readonly) bool canDeleteMessages;
@property (nonatomic, readonly) bool canBanUsers;
@property (nonatomic, readonly) bool canInviteUsers;
@property (nonatomic, readonly) bool canChangeInviteLink;
@property (nonatomic, readonly) bool canPinMessages;
@property (nonatomic, readonly) bool canAddAdmins;
- (instancetype)initWithCanChangeInfo:(bool)canChangeInfo canPostMessages:(bool)canPostMessages canEditMessages:(bool)canEditMessages canDeleteMessages:(bool)canDeleteMessages canBanUsers:(bool)canBanUsers canInviteUsers:(bool)canInviteUsers canChangeInviteLink:(bool)canChangeInviteLink canPinMessages:(bool)canPinMessages canAddAdmins:(bool)canAddAdmins;
- (instancetype)initWithFlags:(int32_t)flags;
- (int32_t)tlFlags;
- (bool)hasAnyRights;
- (int32_t)numberOfRights;
@end

View File

@@ -0,0 +1,95 @@
#import "TGChannelAdminRights.h"
#import "PSKeyValueCoder.h"
@implementation TGChannelAdminRights
- (instancetype)initWithCanChangeInfo:(bool)canChangeInfo canPostMessages:(bool)canPostMessages canEditMessages:(bool)canEditMessages canDeleteMessages:(bool)canDeleteMessages canBanUsers:(bool)canBanUsers canInviteUsers:(bool)canInviteUsers canChangeInviteLink:(bool)canChangeInviteLink canPinMessages:(bool)canPinMessages canAddAdmins:(bool)canAddAdmins {
self = [super init];
if (self != nil) {
_canChangeInfo = canChangeInfo;
_canPostMessages = canPostMessages;
_canEditMessages = canEditMessages;
_canDeleteMessages = canDeleteMessages;
_canBanUsers = canBanUsers;
_canInviteUsers = canInviteUsers;
_canChangeInviteLink = canChangeInviteLink;
_canPinMessages = canPinMessages;
_canAddAdmins = canAddAdmins;
}
return self;
}
- (instancetype)initWithFlags:(int32_t)flags {
return [self initWithCanChangeInfo:flags & (1 << 0) canPostMessages:flags & (1 << 1) canEditMessages:flags & (1 << 2) canDeleteMessages:flags & (1 << 3) canBanUsers:flags & (1 << 4) canInviteUsers:flags & (1 << 5) canChangeInviteLink:flags & (1 << 6) canPinMessages:flags & (1 << 7) canAddAdmins:flags & (1 << 9)];
}
- (int32_t)tlFlags {
int32_t flags = 0;
if (_canChangeInfo) {
flags |= (1 << 0);
}
if (_canPostMessages) {
flags |= (1 << 1);
}
if (_canEditMessages) {
flags |= (1 << 2);
}
if (_canDeleteMessages) {
flags |= (1 << 3);
}
if (_canBanUsers) {
flags |= (1 << 4);
}
if (_canInviteUsers) {
flags |= (1 << 5);
}
if (_canChangeInviteLink) {
flags |= (1 << 6);
}
if (_canPinMessages) {
flags |= (1 << 7);
}
if (_canAddAdmins) {
flags |= (1 << 9);
}
return flags;
}
- (bool)hasAnyRights {
return [self tlFlags] != 0;
}
- (int32_t)numberOfRights {
int32_t flags = [self tlFlags];
int32_t count = 0;
for (int i = 0; i < 31; i++) {
if (flags == 0) {
break;
}
if ((flags & 1) != 0) {
count++;
}
flags = flags >> 1;
}
return count;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
int32_t flags = [coder decodeInt32ForCKey:"f"];
return [self initWithFlags:flags];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeInt32:[self tlFlags] forCKey:"f"];
}
- (BOOL)isEqual:(id)object {
if (![object isKindOfClass:[TGChannelAdminRights class]]) {
return false;
}
TGChannelAdminRights *other = object;
return [self tlFlags] == [other tlFlags];
}
@end

View File

@@ -0,0 +1,25 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
@interface TGChannelBannedRights : NSObject <PSCoding>
@property (nonatomic, readonly) bool banReadMessages;
@property (nonatomic, readonly) bool banSendMessages;
@property (nonatomic, readonly) bool banSendMedia;
@property (nonatomic, readonly) bool banSendStickers;
@property (nonatomic, readonly) bool banSendGifs;
@property (nonatomic, readonly) bool banSendGames;
@property (nonatomic, readonly) bool banSendInline;
@property (nonatomic, readonly) bool banEmbedLinks;
@property (nonatomic, readonly) int32_t timeout;
- (instancetype)initWithBanReadMessages:(bool)banReadMessages banSendMessages:(bool)banSendMessages banSendMedia:(bool)banSendMedia banSendStickers:(bool)banSendStickers banSendGifs:(bool)banSendGifs banSendGames:(bool)banSendGames banSendInline:(bool)banSendInline banEmbedLinks:(bool)banEmbedLinks timeout:(int32_t)timeout;
- (instancetype)initWithFlags:(int32_t)flags timeout:(int32_t)timeout;
- (int32_t)tlFlags;
- (int32_t)numberOfRestrictions;
@end

View File

@@ -0,0 +1,90 @@
#import "TGChannelBannedRights.h"
#import "PSKeyValueCoder.h"
@implementation TGChannelBannedRights
- (instancetype)initWithBanReadMessages:(bool)banReadMessages banSendMessages:(bool)banSendMessages banSendMedia:(bool)banSendMedia banSendStickers:(bool)banSendStickers banSendGifs:(bool)banSendGifs banSendGames:(bool)banSendGames banSendInline:(bool)banSendInline banEmbedLinks:(bool)banEmbedLinks timeout:(int32_t)timeout {
self = [super init];
if (self != nil) {
_banReadMessages = banReadMessages;
_banSendMessages = banSendMessages;
_banSendMedia = banSendMedia;
_banSendStickers = banSendStickers;
_banSendGifs = banSendGifs;
_banSendGames = banSendGames;
_banSendInline = banSendInline;
_banEmbedLinks = banEmbedLinks;
_timeout = timeout;
}
return self;
}
- (int32_t)tlFlags {
int32_t flags = 0;
if (_banReadMessages) {
flags |= (1 << 0);
}
if (_banSendMessages) {
flags |= (1 << 1);
}
if (_banSendMedia) {
flags |= (1 << 2);
}
if (_banSendStickers) {
flags |= (1 << 3);
}
if (_banSendGifs) {
flags |= (1 << 4);
}
if (_banSendGames) {
flags |= (1 << 5);
}
if (_banSendInline) {
flags |= (1 << 6);
}
if (_banEmbedLinks) {
flags |= (1 << 7);
}
return flags;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
int32_t flags = [coder decodeInt32ForCKey:"f"];
int32_t until_date = [coder decodeInt32ForCKey:"t"];
return [self initWithFlags:flags timeout:until_date];
}
- (instancetype)initWithFlags:(int32_t)flags timeout:(int32_t)timeout {
return [self initWithBanReadMessages:flags & (1 << 0) banSendMessages:flags & (1 << 1) banSendMedia:flags & (1 << 2) banSendStickers:flags & (1 << 3) banSendGifs:flags & (1 << 4) banSendGames:flags & (1 << 5) banSendInline:flags & (1 << 6) banEmbedLinks:flags & (1 << 7) timeout:timeout];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeInt32:[self tlFlags] forCKey:"f"];
[coder encodeInt32:_timeout forCKey:"t"];
}
- (BOOL)isEqual:(id)object {
if ([object isKindOfClass:[TGChannelBannedRights class]] && [((TGChannelBannedRights *)object) tlFlags] == [self tlFlags] && ((TGChannelBannedRights *)object)->_timeout == _timeout) {
return true;
} else {
return false;
}
}
- (int32_t)numberOfRestrictions {
int32_t flags = [self tlFlags];
int32_t count = 0;
for (int i = 0; i < 31; i++) {
if (flags == 0) {
break;
}
if ((flags & 1) != 0) {
count++;
}
flags = flags >> 1;
}
return count;
}
@end

View File

@@ -0,0 +1,20 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <LegacyComponents/TGMediaAttachment.h>
#define TGContactMediaAttachmentType ((int)0xB90A5663)
@interface TGContactMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser, NSCoding>
@property (nonatomic) int uid;
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSString *phoneNumber;
@end

View File

@@ -0,0 +1,98 @@
#import "TGContactMediaAttachment.h"
@implementation TGContactMediaAttachment
@synthesize uid = _uid;
@synthesize firstName = _firstName;
@synthesize lastName = _lastName;
@synthesize phoneNumber = _phoneNumber;
- (id)init
{
self = [super init];
if (self != nil)
{
self.type = TGContactMediaAttachmentType;
}
return self;
}
- (void)serialize:(NSMutableData *)data
{
int dataLengthPtr = (int)data.length;
int zero = 0;
[data appendBytes:&zero length:4];
[data appendBytes:&_uid length:4];
NSData *firstNameData = [_firstName dataUsingEncoding:NSUTF8StringEncoding];
int length = (int)firstNameData.length;
[data appendBytes:&length length:4];
[data appendData:firstNameData];
NSData *lastNameData = [_lastName dataUsingEncoding:NSUTF8StringEncoding];
length = (int)lastNameData.length;
[data appendBytes:&length length:4];
[data appendData:lastNameData];
NSData *phoneData = [_phoneNumber dataUsingEncoding:NSUTF8StringEncoding];
length = (int)phoneData.length;
[data appendBytes:&length length:4];
[data appendData:phoneData];
int dataLength = (int)data.length - dataLengthPtr - 4;
[data replaceBytesInRange:NSMakeRange(dataLengthPtr, 4) withBytes:&dataLength];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int dataLength = 0;
[is read:(uint8_t *)&dataLength maxLength:4];
TGContactMediaAttachment *contactAttachment = [[TGContactMediaAttachment alloc] init];
int uid = 0;
[is read:(uint8_t *)&uid maxLength:4];
contactAttachment.uid = uid;
int length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *firstNameBytes = malloc(length);
[is read:firstNameBytes maxLength:length];
contactAttachment.firstName = [[NSString alloc] initWithBytesNoCopy:firstNameBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *lastNameBytes = malloc(length);
[is read:lastNameBytes maxLength:length];
contactAttachment.lastName = [[NSString alloc] initWithBytesNoCopy:lastNameBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *phoneBytes = malloc(length);
[is read:phoneBytes maxLength:length];
contactAttachment.phoneNumber = [[NSString alloc] initWithBytesNoCopy:phoneBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
return contactAttachment;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
self.type = TGContactMediaAttachmentType;
_uid = [aDecoder decodeInt32ForKey:@"uid"];
_firstName = [aDecoder decodeObjectForKey:@"firstName"];
_lastName = [aDecoder decodeObjectForKey:@"lastName"];
_phoneNumber = [aDecoder decodeObjectForKey:@"phoneNumber"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt32:_uid forKey:@"uid"];
[aCoder encodeObject:_firstName forKey:@"firstName"];
[aCoder encodeObject:_lastName forKey:@"lastName"];
[aCoder encodeObject:_phoneNumber forKey:@"phoneNumber"];
}
@end

View File

@@ -0,0 +1,296 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <Foundation/Foundation.h>
#import <LegacyComponents/TGImageInfo.h>
#import <LegacyComponents/TGMessage.h>
#import <LegacyComponents/PSKeyValueCoder.h>
#import <LegacyComponents/TGDatabaseMessageDraft.h>
#import <LegacyComponents/TGChannelAdminRights.h>
#import <LegacyComponents/TGChannelBannedRights.h>
#define TGConversationKindPersistentChannel 0
#define TGConversationKindTemporaryChannel 1
#define TGChannelDisplayVariantImportant 0
#define TGChannelDisplayVariantAll 1
#define TGConversationPinnedDateBase 1600000000
typedef enum {
TGConversationFlagPostAsChannel = (1 << 1),
TGConversationFlagKicked = (1 << 2),
TGConversationFlagVerified = (1 << 3),
TGConversationFlagHasAdmins = (1 << 4),
TGConversationFlagIsAdmin = (1 << 5),
TGConversationFlagIsCreator = (1 << 6),
TGConversationFlagIsChannelGroup = (1 << 7),
TGConversationFlagIsDeactivated = (1 << 8),
TGConversationFlagHasExplicitContent = (1 << 9),
TGConversationFlagEverybodyCanAddMembers = (1 << 10),
TGConversationFlagSignaturesEnabled = (1 << 11),
TGConversationFlagPinnedMessageHidden = (1 << 12),
TGConversationFlagIsMin = (1 << 13),
TGConversationFlagCanNotSetUsername = (1 << 14)
} TGConversationFlags;
typedef struct {
uint8_t key[9];
} TGConversationSortKey;
static inline int TGConversationSortKeyCompare(TGConversationSortKey lhs, TGConversationSortKey rhs) {
return memcmp(lhs.key, rhs.key, 9);
}
static inline TGConversationSortKey TGConversationSortKeyDecode(PSKeyValueCoder *coder, const char *name) {
TGConversationSortKey key;
[coder decodeBytesForCKey:name value:key.key length:9];
return key;
}
static inline void TGConversationSortKeyEncode(PSKeyValueCoder *coder, const char *name, TGConversationSortKey key) {
[coder encodeBytes:key.key length:9 forCKey:name];
}
static inline TGConversationSortKey TGConversationSortKeyMake(uint8_t kind, int32_t timestamp, int32_t mid) {
TGConversationSortKey key;
key.key[0] = kind;
timestamp = NSSwapInt(timestamp);
memcpy(key.key + 1, &timestamp, 4);
mid = NSSwapInt(mid);
memcpy(key.key + 1 + 4, &mid, 4);
return key;
}
static inline TGConversationSortKey TGConversationSortKeyLowerBound(uint8_t kind) {
return TGConversationSortKeyMake(kind, 0, 0);
}
static inline TGConversationSortKey TGConversationSortKeyUpperBound(uint8_t kind) {
return TGConversationSortKeyMake(kind, INT32_MAX, INT32_MAX);
}
static inline uint8_t TGConversationSortKeyKind(TGConversationSortKey key) {
return key.key[0];
}
static inline TGConversationSortKey TGConversationSortKeyUpdateKind(TGConversationSortKey key, uint8_t kind) {
TGConversationSortKey updatedKey;
memcpy(updatedKey.key, key.key, 8);
updatedKey.key[0] = kind;
return updatedKey;
}
static inline int32_t TGConversationSortKeyTimestamp(TGConversationSortKey key) {
int32_t timestamp = 0;
memcpy(&timestamp, key.key + 1, 4);
return NSSwapInt(timestamp);
}
static inline int32_t TGConversationSortKeyMid(TGConversationSortKey key) {
int32_t mid = 0;
memcpy(&mid, key.key + 1 + 4, 4);
return NSSwapInt(mid);
}
static inline NSData *TGConversationSortKeyData(TGConversationSortKey key) {
return [NSData dataWithBytes:key.key length:9];
}
static inline TGConversationSortKey TGConversationSortKeyFromData(NSData *data) {
TGConversationSortKey key;
memcpy(key.key, data.bytes, 9);
return key;
}
typedef enum {
TGChannelRoleMember,
TGChannelRoleCreator,
TGChannelRoleModerator,
TGChannelRolePublisher
} TGChannelRole;
@interface TGConversationParticipantsData : NSObject <NSCopying>
{
NSData *_serializedData;
}
@property (nonatomic, strong) NSArray *chatParticipantUids;
@property (nonatomic, strong) NSDictionary *chatInvitedBy;
@property (nonatomic, strong) NSDictionary *chatInvitedDates;
@property (nonatomic, strong) NSSet *chatAdminUids;
@property (nonatomic, strong) NSArray *chatParticipantSecretChatPeerIds;
@property (nonatomic, strong) NSArray *chatParticipantChatPeerIds;
@property (nonatomic) int chatAdminId;
@property (nonatomic) int version;
@property (nonatomic, strong) NSString *exportedChatInviteString;
+ (TGConversationParticipantsData *)deserializeData:(NSData *)data;
- (NSData *)serializedData;
- (void)addParticipantWithId:(int32_t)uid invitedBy:(int32_t)invitedBy date:(int32_t)date;
- (void)removeParticipantWithId:(int32_t)uid;
- (void)addSecretChatPeerWithId:(int64_t)peerId;
- (void)removeSecretChatPeerWithId:(int64_t)peerId;
- (void)addChatPeerWithId:(int64_t)peerId;
- (void)removeChatPeerWithId:(int64_t)peerId;
@end
@interface TGEncryptedConversationData : NSObject <NSCopying>
@property (nonatomic) int64_t encryptedConversationId;
@property (nonatomic) int64_t accessHash;
@property (nonatomic) int64_t keyFingerprint;
@property (nonatomic) int32_t handshakeState;
@property (nonatomic) int64_t currentRekeyExchangeId;
@property (nonatomic) bool currentRekeyIsInitiatedByLocalClient;
@property (nonatomic) NSData *currentRekeyNumber;
@property (nonatomic) NSData *currentRekeyKey;
@property (nonatomic) int64_t currentRekeyKeyId;
@end
@interface TGConversation : NSObject <NSCopying, PSCoding>
@property (nonatomic) int64_t conversationId;
@property (nonatomic) int64_t accessHash;
@property (nonatomic) int32_t displayVariant;
@property (nonatomic) uint8_t kind;
@property (nonatomic, readonly) TGConversationSortKey databaseSortKey;
@property (nonatomic) TGConversationSortKey variantSortKey;
@property (nonatomic) TGConversationSortKey importantSortKey;
@property (nonatomic) TGConversationSortKey unimportantSortKey;
@property (nonatomic) int32_t pts;
@property (nonatomic) int32_t maxReadMessageId;
@property (nonatomic) int32_t maxOutgoingReadMessageId;
@property (nonatomic) int32_t maxKnownMessageId;
@property (nonatomic) int32_t maxLocallyReadMessageId;
@property (nonatomic) int32_t maxReadDate;
@property (nonatomic) int32_t maxOutgoingReadDate;
@property (nonatomic, strong) NSString *about;
@property (nonatomic, strong) NSString *username;
@property (nonatomic) id additionalProperties;
@property (nonatomic) bool outgoing;
@property (nonatomic) bool unread;
@property (nonatomic) bool deliveryError;
@property (nonatomic) TGMessageDeliveryState deliveryState;
@property (nonatomic) int32_t messageDate;
@property (nonatomic) int32_t minMessageDate;
@property (nonatomic) int32_t pinnedDate;
@property (nonatomic) int fromUid;
@property (nonatomic, strong) NSString *text;
@property (nonatomic, strong) NSArray *media;
@property (nonatomic, strong) NSData *mediaData;
@property (nonatomic) int unreadCount;
@property (nonatomic) int serviceUnreadCount;
@property (nonatomic, strong) NSString *chatTitle;
@property (nonatomic, strong) NSString *chatPhotoSmall;
@property (nonatomic, strong) NSString *chatPhotoMedium;
@property (nonatomic, strong) NSString *chatPhotoBig;
@property (nonatomic) int chatParticipantCount;
@property (nonatomic) bool leftChat;
@property (nonatomic) bool kickedFromChat;
@property (nonatomic) TGChannelRole channelRole;
@property (nonatomic) int chatCreationDate;
@property (nonatomic) int chatVersion;
@property (nonatomic) bool chatIsAdmin;
@property (nonatomic) bool channelIsReadOnly;
@property (nonatomic) bool isVerified;
@property (nonatomic) bool hasExplicitContent;
@property (nonatomic, strong) NSString *restrictionReason;
@property (nonatomic, strong) TGConversationParticipantsData *chatParticipants;
@property (nonatomic, strong) NSDictionary *dialogListData;
@property (nonatomic) bool isChat;
@property (nonatomic) bool isDeleted;
@property (nonatomic) bool isBroadcast;
@property (nonatomic) bool isChannel;
@property (nonatomic) bool postAsChannel;
@property (nonatomic) bool hasAdmins;
@property (nonatomic) bool isAdmin;
@property (nonatomic) bool isCreator;
@property (nonatomic) bool isChannelGroup;
@property (nonatomic) bool everybodyCanAddMembers;
@property (nonatomic) bool signaturesEnabled;
@property (nonatomic) bool isDeactivated;
@property (nonatomic) bool isMigrated;
@property (nonatomic) int32_t migratedToChannelId;
@property (nonatomic) int64_t migratedToChannelAccessHash;
@property (nonatomic) int32_t pinnedMessageId;
@property (nonatomic) bool pinnedMessageHidden;
@property (nonatomic) int64_t flags;
@property (nonatomic) bool isMin;
@property (nonatomic) bool canNotSetUsername;
@property (nonatomic, strong) TGEncryptedConversationData *encryptedData;
@property (nonatomic, strong, readonly) TGDatabaseMessageDraft *draft;
@property (nonatomic, readonly) int32_t date;
@property (nonatomic, readonly) int32_t unpinnedDate;
@property (nonatomic, strong) TGChannelAdminRights *channelAdminRights;
@property (nonatomic, strong) TGChannelBannedRights *channelBannedRights;
- (id)initWithConversationId:(int64_t)conversationId unreadCount:(int)unreadCount serviceUnreadCount:(int)serviceUnreadCount;
- (void)mergeMessage:(TGMessage *)message;
- (void)mergeEmptyMessage;
- (BOOL)isEqualToConversation:(TGConversation *)other;
- (BOOL)isEqualToConversationIgnoringMessage:(TGConversation *)other;
- (NSData *)serializeChatPhoto;
- (void)deserializeChatPhoto:(NSData *)data;
- (bool)isEncrypted;
- (void)mergeConversation:(TGConversation *)conversation;
- (void)mergeChannel:(TGConversation *)channel;
- (void)mergeDraft:(TGDatabaseMessageDraft *)draft;
- (bool)currentUserCanSendMessages;
+ (NSString *)chatTitleForDecoder:(PSKeyValueCoder *)coder;
- (bool)isMessageUnread:(TGMessage *)message;
- (bool)isMessageUnread:(int32_t)messageId date:(int32_t)messageDate outgoing:(bool)outgoing;
- (bool)pinnedToTop;
@end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
#import <LegacyComponents/TGMessageEntity.h>
@interface TGDatabaseMessageDraft : NSObject <PSCoding>
@property (nonatomic, strong, readonly) NSString *text;
@property (nonatomic, strong, readonly) NSArray<TGMessageEntity *> *entities;
@property (nonatomic, readonly) bool disableLinkPreview;
@property (nonatomic, readonly) int32_t replyToMessageId;
@property (nonatomic, readonly) int32_t date;
- (instancetype)initWithText:(NSString *)text entities:(NSArray<TGMessageEntity *> *)entities disableLinkPreview:(bool)disableLinkPreview replyToMessageId:(int32_t)replyToMessageId date:(int32_t)date;
- (bool)isEmpty;
- (TGDatabaseMessageDraft *)updateDate:(int32_t)date;
@end

View File

@@ -0,0 +1,46 @@
#import "TGDatabaseMessageDraft.h"
#import "LegacyComponentsInternal.h"
#import "PSKeyValueEncoder.h"
#import "PSKeyValueDecoder.h"
@implementation TGDatabaseMessageDraft
- (instancetype)initWithText:(NSString *)text entities:(NSArray<TGMessageEntity *> *)entities disableLinkPreview:(bool)disableLinkPreview replyToMessageId:(int32_t)replyToMessageId date:(int32_t)date {
self = [super init];
if (self != nil) {
_text = text;
_entities = entities;
_disableLinkPreview = disableLinkPreview;
_replyToMessageId = replyToMessageId;
_date = date;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
return [self initWithText:[coder decodeStringForCKey:"text"] entities:[coder decodeArrayForCKey:"entities"] disableLinkPreview:[coder decodeInt32ForCKey:"disableLinkPreview"] replyToMessageId:[coder decodeInt32ForCKey:"replyToMessageId"] date:[coder decodeInt32ForCKey:"date"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeString:_text forCKey:"text"];
[coder encodeArray:_entities forCKey:"entities"];
[coder encodeInt32:_disableLinkPreview ? 1 : 0 forCKey:"disableLinkPreview"];
[coder encodeInt32:_replyToMessageId forCKey:"replyToMessageId"];
[coder encodeInt32:_date forCKey:"date"];
}
- (bool)isEqual:(id)object {
return [object isKindOfClass:[TGDatabaseMessageDraft class]] && TGStringCompare(((TGDatabaseMessageDraft *)object)->_text, _text) && TGObjectCompare(((TGDatabaseMessageDraft *)object)->_entities, _entities) && ((TGDatabaseMessageDraft *)object)->_disableLinkPreview == _disableLinkPreview && ((TGDatabaseMessageDraft *)object)->_replyToMessageId == _replyToMessageId && ((TGDatabaseMessageDraft *)object)->_date == _date;
}
- (bool)isEmpty {
return _text.length == 0 && _replyToMessageId == 0;
}
- (TGDatabaseMessageDraft *)updateDate:(int32_t)date {
return [[TGDatabaseMessageDraft alloc] initWithText:_text entities:_entities disableLinkPreview:_disableLinkPreview replyToMessageId:_replyToMessageId date:date];
}
@end

View File

@@ -0,0 +1,5 @@
#import <LegacyComponents/PSCoding.h>
@interface TGDocumentAttributeAnimated : NSObject <PSCoding, NSCoding>
@end

View File

@@ -0,0 +1,28 @@
#import "TGDocumentAttributeAnimated.h"
@implementation TGDocumentAttributeAnimated
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)__unused coder
{
return [self init];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)__unused coder
{
}
- (instancetype)initWithCoder:(NSCoder *)__unused aDecoder
{
return [self init];
}
- (void)encodeWithCoder:(NSCoder *)__unused aCoder
{
}
- (BOOL)isEqual:(id)object
{
return [object isEqual:[TGDocumentAttributeAnimated class]];
}
@end

View File

@@ -0,0 +1,17 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
#import <LegacyComponents/TGAudioWaveform.h>
@interface TGDocumentAttributeAudio : NSObject <NSCoding, PSCoding>
@property (nonatomic, readonly) bool isVoice;
@property (nonatomic, strong, readonly) NSString *title;
@property (nonatomic, strong, readonly) NSString *performer;
@property (nonatomic, readonly) int32_t duration;
@property (nonatomic, strong, readonly) TGAudioWaveform *waveform;
- (instancetype)initWithIsVoice:(bool)isVoice title:(NSString *)title performer:(NSString *)performer duration:(int32_t)duration waveform:(TGAudioWaveform *)waveform;
@end

View File

@@ -0,0 +1,56 @@
#import "TGDocumentAttributeAudio.h"
#import "LegacyComponentsInternal.h"
#import "PSKeyValueCoder.h"
@implementation TGDocumentAttributeAudio
- (instancetype)initWithIsVoice:(bool)isVoice title:(NSString *)title performer:(NSString *)performer duration:(int32_t)duration waveform:(TGAudioWaveform *)waveform
{
self = [super init];
if (self != nil)
{
_isVoice = isVoice;
_title = title;
_performer = performer;
_duration = duration;
_waveform = waveform;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
return [self initWithIsVoice:[aDecoder decodeBoolForKey:@"isVoice"] title:[aDecoder decodeObjectForKey:@"title"] performer:[aDecoder decodeObjectForKey:@"performer"] duration:[aDecoder decodeInt32ForKey:@"duration"] waveform:[aDecoder decodeObjectForKey:@"waveform"]];
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithIsVoice:[coder decodeInt32ForCKey:"isVoice"] title:[coder decodeStringForCKey:"title"] performer:[coder decodeStringForCKey:"performer"] duration:[coder decodeInt32ForCKey:"duration"] waveform:(TGAudioWaveform *)[coder decodeObjectForCKey:"waveform"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeBool:_isVoice forKey:@"isVoice"];
[aCoder encodeObject:_title forKey:@"title"];
[aCoder encodeObject:_performer forKey:@"performer"];
[aCoder encodeInt32:_duration forKey:@"duration"];
[aCoder encodeObject:_waveform forKey:@"waveform"];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeInt32:_isVoice ? 1 : 0 forCKey:"isVoice"];
[coder encodeString:_title forCKey:"title"];
[coder encodeString:_performer forCKey:"performer"];
[coder encodeInt32:_duration forCKey:"duration"];
[coder encodeObject:_waveform forCKey:"waveform"];
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGDocumentAttributeAudio class]] && TGStringCompare(((TGDocumentAttributeAudio *)object)->_title, _title) && TGStringCompare(((TGDocumentAttributeAudio *)object)->_performer, _performer) && ((TGDocumentAttributeAudio *)object)->_duration == _duration && _isVoice == ((TGDocumentAttributeAudio *)object)->_isVoice;
}
@end

View File

@@ -0,0 +1,9 @@
#import <LegacyComponents/PSCoding.h>
@interface TGDocumentAttributeFilename : NSObject <PSCoding, NSCoding>
@property (nonatomic, strong, readonly) NSString *filename;
- (instancetype)initWithFilename:(NSString *)filename;
@end

View File

@@ -0,0 +1,45 @@
#import "TGDocumentAttributeFilename.h"
#import "LegacyComponentsInternal.h"
#import "PSKeyValueCoder.h"
@implementation TGDocumentAttributeFilename
- (instancetype)initWithFilename:(NSString *)filename
{
self = [super init];
if (self != nil)
{
_filename = filename;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithFilename:[coder decodeStringForCKey:"f"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeString:_filename forCKey:"f"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
return [self initWithFilename:[aDecoder decodeObjectForKey:@"filename"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
if (_filename != nil)
[aCoder encodeObject:_filename forKey:@"filename"];
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGDocumentAttributeFilename class]] && TGObjectCompare(_filename, ((TGDocumentAttributeFilename *)object)->_filename);
}
@end

View File

@@ -0,0 +1,11 @@
#import <LegacyComponents/PSCoding.h>
#import <UIKit/UIKit.h>
@interface TGDocumentAttributeImageSize : NSObject <PSCoding, NSCoding>
@property (nonatomic, readonly) CGSize size;
- (instancetype)initWithSize:(CGSize)size;
@end

View File

@@ -0,0 +1,43 @@
#import "TGDocumentAttributeImageSize.h"
#import "PSKeyValueCoder.h"
@implementation TGDocumentAttributeImageSize
- (instancetype)initWithSize:(CGSize)size
{
self = [super init];
if (self != nil)
{
_size = size;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithSize:CGSizeMake([coder decodeInt32ForCKey:"w"], [coder decodeInt32ForCKey:"h"])];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeInt32:(int32_t)_size.width forCKey:"w"];
[coder encodeInt32:(int32_t)_size.height forCKey:"h"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
return [self initWithSize:[aDecoder decodeCGSizeForKey:@"size"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeCGSize:_size forKey:@"size"];
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGDocumentAttributeImageSize class]] && CGSizeEqualToSize(_size, ((TGDocumentAttributeImageSize *)object)->_size);
}
@end

View File

@@ -0,0 +1,25 @@
#import <UIKit/UIKit.h>
#import <LegacyComponents/PSCoding.h>
#import <LegacyComponents/TGStickerPackReference.h>
@interface TGStickerMaskDescription : NSObject <PSCoding, NSCoding>
@property (nonatomic, readonly) int32_t n;
@property (nonatomic, readonly) CGPoint point;
@property (nonatomic, readonly) CGFloat zoom;
- (instancetype)initWithN:(int32_t)n point:(CGPoint)point zoom:(CGFloat)zoom;
@end
@interface TGDocumentAttributeSticker : NSObject <PSCoding, NSCoding>
@property (nonatomic, strong, readonly) NSString *alt;
@property (nonatomic, strong, readonly) id<TGStickerPackReference> packReference;
@property (nonatomic, strong, readonly) TGStickerMaskDescription *mask;
- (instancetype)initWithAlt:(NSString *)alt packReference:(id<TGStickerPackReference>)packReference mask:(TGStickerMaskDescription *)mask;
@end

View File

@@ -0,0 +1,105 @@
#import "TGDocumentAttributeSticker.h"
#import "LegacyComponentsInternal.h"
#import "PSKeyValueCoder.h"
@implementation TGStickerMaskDescription
- (instancetype)initWithN:(int32_t)n point:(CGPoint)point zoom:(CGFloat)zoom {
self = [super init];
if (self != nil) {
_n = n;
_point = point;
_zoom = zoom;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
return [self initWithN:[coder decodeInt32ForCKey:"n"] point:CGPointMake([coder decodeDoubleForCKey:"x"], [coder decodeDoubleForCKey:"y"]) zoom:[coder decodeDoubleForCKey:"z"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeInt32:_n forCKey:"n"];
[coder encodeDouble:_point.x forCKey:"x"];
[coder encodeDouble:_point.y forCKey:"y"];
[coder encodeDouble:_zoom forCKey:"z"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithN:[aDecoder decodeInt32ForKey:@"n"] point:CGPointMake([aDecoder decodeDoubleForKey:@"x"], [aDecoder decodeDoubleForKey:@"y"]) zoom:[aDecoder decodeDoubleForKey:@"z"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt32:_n forKey:@"n"];
[aCoder encodeDouble:_point.x forKey:@"x"];
[aCoder encodeDouble:_point.y forKey:@"y"];
[aCoder encodeDouble:_zoom forKey:@"z"];
}
@end
@implementation TGDocumentAttributeSticker
- (instancetype)initWithAlt:(NSString *)alt packReference:(id<TGStickerPackReference>)packReference mask:(TGStickerMaskDescription *)mask
{
self = [super init];
if (self != nil)
{
_alt = alt;
_packReference = packReference;
_mask = mask;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithAlt:[coder decodeStringForCKey:"alt"] packReference:(id<TGStickerPackReference>)[coder decodeObjectForCKey:"packReference"] mask:(TGStickerMaskDescription *)[coder decodeObjectForCKey:"mask"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeString:_alt forCKey:"alt"];
[coder encodeObject:_packReference forCKey:"packReference"];
[coder encodeObject:_mask forCKey:"mask"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
return [self initWithAlt:[aDecoder decodeObjectForKey:@"alt"] packReference:[aDecoder decodeObjectForKey:@"packReference"] mask:[aDecoder decodeObjectForKey:@"mask"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
if (_alt != nil)
[aCoder encodeObject:_alt forKey:@"alt"];
if (_packReference != nil)
[aCoder encodeObject:_packReference forKey:@"packReference"];
if (_mask != nil)
[aCoder encodeObject:_mask forKey:@"mask"];
}
- (BOOL)isEqual:(id)object
{
if (![object isKindOfClass:[TGDocumentAttributeSticker class]]) {
return false;
}
if (!TGObjectCompare(_packReference, ((TGDocumentAttributeSticker *)object)->_packReference)) {
return false;
}
if (!TGObjectCompare(_mask, ((TGDocumentAttributeSticker *)object)->_mask)) {
return false;
}
if (!TGStringCompare(_alt, ((TGDocumentAttributeSticker *)object)->_alt)) {
return false;
}
return true;
}
@end

View File

@@ -0,0 +1,13 @@
#import <UIKit/UIKit.h>
#import <LegacyComponents/PSCoding.h>
@interface TGDocumentAttributeVideo : NSObject <PSCoding, NSCoding>
@property (nonatomic, readonly) bool isRoundMessage;
@property (nonatomic, readonly) CGSize size;
@property (nonatomic, readonly) int32_t duration;
- (instancetype)initWithRoundMessage:(bool)isRoundMessage size:(CGSize)size duration:(int32_t)duration;
@end

View File

@@ -0,0 +1,42 @@
#import "TGDocumentAttributeVideo.h"
#import "PSKeyValueCoder.h"
@implementation TGDocumentAttributeVideo
- (instancetype)initWithRoundMessage:(bool)isRoundMessage size:(CGSize)size duration:(int32_t)duration {
self = [super init];
if (self != nil) {
_isRoundMessage = isRoundMessage;
_size = size;
_duration = duration;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithRoundMessage:[aDecoder decodeBoolForKey:@"roundMessage"] size:[aDecoder decodeCGSizeForKey:@"size"] duration:[aDecoder decodeInt32ForKey:@"duration"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeBool:_isRoundMessage forKey:@"roundMessage"];
[aCoder encodeCGSize:_size forKey:@"size"];
[aCoder encodeInt32:_duration forKey:@"duration"];
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder {
return [self initWithRoundMessage:[coder decodeInt32ForCKey:"r"] size:CGSizeMake([coder decodeInt32ForCKey:"s.w"], [coder decodeInt32ForCKey:"s.h"]) duration:[coder decodeInt32ForCKey:"d"]];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder {
[coder encodeInt32:(int32_t)_isRoundMessage forKey:@"r"];
[coder encodeInt32:(int32_t)_size.width forCKey:"s.w"];
[coder encodeInt32:(int32_t)_size.height forCKey:"s.h"];
[coder encodeInt32:_duration forCKey:"d"];
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGDocumentAttributeVideo class]] && _isRoundMessage == ((TGDocumentAttributeVideo *)object)->_isRoundMessage && CGSizeEqualToSize(_size, ((TGDocumentAttributeVideo *)object)->_size) && _duration == ((TGDocumentAttributeVideo *)object)->_duration;
}
@end

View File

@@ -0,0 +1,55 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <LegacyComponents/TGMediaAttachment.h>
#import <LegacyComponents/TGImageInfo.h>
#import <LegacyComponents/TGDocumentAttributeFilename.h>
#import <LegacyComponents/TGDocumentAttributeAnimated.h>
#import <LegacyComponents/TGDocumentAttributeSticker.h>
#import <LegacyComponents/TGDocumentAttributeImageSize.h>
#import <LegacyComponents/TGDocumentAttributeAudio.h>
#import <LegacyComponents/TGDocumentAttributeVideo.h>
#define TGDocumentMediaAttachmentType ((int)0xE6C64318)
@interface TGDocumentMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser, NSCoding, NSCopying>
@property (nonatomic) int64_t localDocumentId;
@property (nonatomic) int64_t documentId;
@property (nonatomic) int64_t accessHash;
@property (nonatomic) int datacenterId;
@property (nonatomic) int32_t userId;
@property (nonatomic) int date;
@property (nonatomic, strong) NSString *mimeType;
@property (nonatomic) int size;
@property (nonatomic) int32_t version;
@property (nonatomic, strong) TGImageInfo *thumbnailInfo;
@property (nonatomic, strong) NSString *documentUri;
@property (nonatomic, strong) NSArray *attributes;
@property (nonatomic, strong) NSString *caption;
@property (nonatomic, readonly) NSArray *textCheckingResults;
- (NSString *)safeFileName;
+ (NSString *)safeFileNameForFileName:(NSString *)fileName;
- (NSString *)fileName;
- (bool)isAnimated;
- (bool)isSticker;
- (bool)isStickerWithPack;
- (id<TGStickerPackReference>)stickerPackReference;
- (bool)isVoice;
- (CGSize)pictureSize;
- (bool)isRoundVideo;
@end

View File

@@ -0,0 +1,404 @@
#import "TGDocumentMediaAttachment.h"
#import "LegacyComponentsInternal.h"
#import "PSCoding.h"
#import "PSKeyValueEncoder.h"
#import "PSKeyValueDecoder.h"
#import "TGMessage.h"
@interface TGDocumentMediaAttachment () {
NSArray *_textCheckingResults;
}
@end
@implementation TGDocumentMediaAttachment
- (id)init
{
self = [super init];
if (self != nil)
{
self.type = TGDocumentMediaAttachmentType;
}
return self;
}
- (instancetype)copyWithZone:(NSZone *)__unused zone {
TGDocumentMediaAttachment *document = [[TGDocumentMediaAttachment alloc] init];
document->_documentId = _documentId;
document->_localDocumentId = _localDocumentId;
document->_accessHash = _accessHash;
document->_datacenterId = _datacenterId;
document->_userId = _userId;
document->_date = _date;
document->_mimeType = _mimeType;
document->_size = _size;
document->_thumbnailInfo = _thumbnailInfo;
document->_documentUri = _documentUri;
document->_attributes = _attributes;
document->_caption = _caption;
document->_textCheckingResults = _textCheckingResults;
document->_version = _version;
return document;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self != nil)
{
self.type = TGDocumentMediaAttachmentType;
_documentId = [aDecoder decodeInt64ForKey:@"documentId"];
_localDocumentId = [aDecoder decodeInt64ForKey:@"localDocumentId"];
_accessHash = [aDecoder decodeInt64ForKey:@"accessHash"];
_datacenterId = [aDecoder decodeInt32ForKey:@"datacenterId"];
_userId = [aDecoder decodeInt32ForKey:@"userId"];
_date = [aDecoder decodeInt32ForKey:@"date"];
_mimeType = [aDecoder decodeObjectForKey:@"mimeType"];
_size = [aDecoder decodeInt32ForKey:@"size"];
_thumbnailInfo = [aDecoder decodeObjectForKey:@"thumbnailInfo"];
_documentUri = [aDecoder decodeObjectForKey:@"documentUri"];
_attributes = [aDecoder decodeObjectForKey:@"attributes"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
_version = [aDecoder decodeInt32ForKey:@"version"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeInt64:_documentId forKey:@"documentId"];
[aCoder encodeInt64:_localDocumentId forKey:@"localDocumentId"];
[aCoder encodeInt64:_accessHash forKey:@"accessHash"];
[aCoder encodeInt32:_datacenterId forKey:@"datacenterId"];
[aCoder encodeInt32:_userId forKey:@"userId"];
[aCoder encodeInt32:_date forKey:@"date"];
[aCoder encodeInt32:_version forKey:@"version"];
if (_mimeType != nil)
[aCoder encodeObject:_mimeType forKey:@"mimeType"];
[aCoder encodeInt32:_size forKey:@"size"];
if (_thumbnailInfo != nil)
[aCoder encodeObject:_thumbnailInfo forKey:@"thumbnailInfo"];
if (_documentUri != nil)
[aCoder encodeObject:_documentUri forKey:@"documentUri"];
if (_attributes != nil)
[aCoder encodeObject:_attributes forKey:@"attributes"];
if (_caption != nil) {
[aCoder encodeObject:_caption forKey:@"caption"];
}
}
- (BOOL)isEqual:(id)object
{
if (object == self)
return true;
if (![object isKindOfClass:[TGDocumentMediaAttachment class]])
return false;
TGDocumentMediaAttachment *other = object;
if (_documentId == other->_documentId && _localDocumentId == other->_localDocumentId && _accessHash == other->_accessHash && _datacenterId == other->_datacenterId && _userId == other->_userId && _date == other->_date && TGObjectCompare(_mimeType, other->_mimeType) && _size == other->_size && TGObjectCompare(_thumbnailInfo, other->_thumbnailInfo) && TGObjectCompare(_documentUri, other->_documentUri) && TGObjectCompare(_attributes, other->_attributes) && TGStringCompare(_caption, other->_caption) && _version == other->_version)
return true;
return false;
}
- (void)serialize:(NSMutableData *)data
{
int dataLengthPtr = (int)data.length;
int zero = 0;
[data appendBytes:&zero length:4];
uint8_t version = 6;
[data appendBytes:&version length:sizeof(version)];
[data appendBytes:&_localDocumentId length:sizeof(_localDocumentId)];
[data appendBytes:&_documentId length:sizeof(_documentId)];
[data appendBytes:&_accessHash length:sizeof(_accessHash)];
[data appendBytes:&_datacenterId length:sizeof(_datacenterId)];
[data appendBytes:&_userId length:sizeof(_userId)];
[data appendBytes:&_date length:sizeof(_date)];
NSData *filenameData = [[self fileName] dataUsingEncoding:NSUTF8StringEncoding];
int filenameLength = (int)filenameData.length;
[data appendBytes:&filenameLength length:sizeof(filenameLength)];
[data appendData:filenameData];
NSData *mimeData = [_mimeType dataUsingEncoding:NSUTF8StringEncoding];
int mimeLength = (int)mimeData.length;
[data appendBytes:&mimeLength length:sizeof(mimeLength)];
[data appendData:mimeData];
[data appendBytes:&_size length:sizeof(_size)];
uint8_t thumbnailExists = _thumbnailInfo != nil;
[data appendBytes:&thumbnailExists length:sizeof(thumbnailExists)];
[_thumbnailInfo serialize:data];
NSData *uriData = [_documentUri dataUsingEncoding:NSUTF8StringEncoding];
int uriLength = (int)uriData.length;
[data appendBytes:&uriLength length:sizeof(uriLength)];
if (uriData != nil)
[data appendData:uriData];
PSKeyValueEncoder *encoder = [[PSKeyValueEncoder alloc] init];
[encoder encodeArray:_attributes forCKey:"attributes"];
int32_t attributesLength = (int32_t)encoder.data.length;
[data appendBytes:&attributesLength length:4];
[data appendData:encoder.data];
NSData *captionData = [_caption dataUsingEncoding:NSUTF8StringEncoding];
int32_t captionLength = (int)captionData.length;
[data appendBytes:&captionLength length:sizeof(captionLength)];
if (captionData != nil) {
[data appendData:captionData];
}
[data appendBytes:&_version length:4];
int dataLength = (int)(data.length - dataLengthPtr - 4);
[data replaceBytesInRange:NSMakeRange(dataLengthPtr, 4) withBytes:&dataLength];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int dataLength = 0;
[is read:(uint8_t *)&dataLength maxLength:4];
uint8_t version = 0;
[is read:&version maxLength:sizeof(version)];
if (version != 1 && version != 2 && version != 3 && version != 4 && version != 5 && version != 6)
{
TGLog(@"***** Document serialized version mismatch");
return nil;
}
TGDocumentMediaAttachment *documentAttachment = [[TGDocumentMediaAttachment alloc] init];
if (version >= 2)
[is read:(uint8_t *)&documentAttachment->_localDocumentId maxLength:sizeof(documentAttachment->_localDocumentId)];
[is read:(uint8_t *)&documentAttachment->_documentId maxLength:sizeof(documentAttachment->_documentId)];
[is read:(uint8_t *)&documentAttachment->_accessHash maxLength:sizeof(documentAttachment->_accessHash)];
[is read:(uint8_t *)&documentAttachment->_datacenterId maxLength:sizeof(documentAttachment->_datacenterId)];
[is read:(uint8_t *)&documentAttachment->_userId maxLength:sizeof(documentAttachment->_userId)];
[is read:(uint8_t *)&documentAttachment->_date maxLength:sizeof(documentAttachment->_date)];
NSString *legacyFileName = @"file";
int filenameLength = 0;
[is read:(uint8_t *)&filenameLength maxLength:sizeof(filenameLength)];
if (filenameLength != 0)
{
uint8_t *filenameBytes = malloc(filenameLength);
[is read:filenameBytes maxLength:filenameLength];
legacyFileName = [[NSString alloc] initWithBytesNoCopy:filenameBytes length:filenameLength encoding:NSUTF8StringEncoding freeWhenDone:true];
}
int mimeLength = 0;
[is read:(uint8_t *)&mimeLength maxLength:sizeof(mimeLength)];
if (mimeLength != 0)
{
uint8_t *mimeBytes = malloc(mimeLength);
[is read:mimeBytes maxLength:mimeLength];
documentAttachment.mimeType = [[NSString alloc] initWithBytesNoCopy:mimeBytes length:mimeLength encoding:NSUTF8StringEncoding freeWhenDone:true];
}
[is read:(uint8_t *)&documentAttachment->_size maxLength:sizeof(documentAttachment->_size)];
uint8_t thumbnailExists = 0;
[is read:&thumbnailExists maxLength:sizeof(thumbnailExists)];
if (thumbnailExists)
{
documentAttachment.thumbnailInfo = [TGImageInfo deserialize:is];
}
if (version >= 3)
{
int uriLength = 0;
[is read:(uint8_t *)&uriLength maxLength:sizeof(uriLength)];
if (uriLength > 0)
{
uint8_t *uriBytes = malloc(uriLength);
[is read:uriBytes maxLength:uriLength];
documentAttachment.documentUri = [[NSString alloc] initWithBytesNoCopy:uriBytes length:uriLength encoding:NSUTF8StringEncoding freeWhenDone:true];
}
}
if (version >= 4)
{
int32_t attributesSize = 0;
[is read:(uint8_t *)&attributesSize maxLength:4];
if (attributesSize > 0)
{
uint8_t *attributeBytes = malloc(attributesSize);
[is read:attributeBytes maxLength:attributesSize];
NSData *data = [[NSData alloc] initWithBytesNoCopy:attributeBytes length:attributesSize freeWhenDone:true];
PSKeyValueDecoder *decoder = [[PSKeyValueDecoder alloc] initWithData:data];
documentAttachment.attributes = [decoder decodeArrayForCKey:"attributes"];
}
}
if (version >= 5) {
int32_t captionLength = 0;
[is read:(uint8_t *)&captionLength maxLength:sizeof(captionLength)];
if (captionLength > 0)
{
uint8_t *captionBytes = malloc(captionLength);
[is read:captionBytes maxLength:captionLength];
documentAttachment.caption = [[NSString alloc] initWithBytesNoCopy:captionBytes length:captionLength encoding:NSUTF8StringEncoding freeWhenDone:true];
}
}
if (version >= 6) {
int32_t fileVersion = 0;
[is read:(uint8_t *)&fileVersion maxLength:4];
documentAttachment.version = fileVersion;
}
bool hasFilenameAttribute = false;
for (id attribute in documentAttachment.attributes)
{
if ([attribute isKindOfClass:[TGDocumentAttributeFilename class]])
{
hasFilenameAttribute = true;
break;
}
}
if (!hasFilenameAttribute)
{
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:documentAttachment.attributes];
[array addObject:[[TGDocumentAttributeFilename alloc] initWithFilename:legacyFileName]];
documentAttachment.attributes = array;
}
return documentAttachment;
}
- (NSString *)fileName
{
NSString *fileName = @"file";
for (id attribute in _attributes)
{
if ([attribute isKindOfClass:[TGDocumentAttributeFilename class]])
{
fileName = ((TGDocumentAttributeFilename *)attribute).filename;
break;
}
}
return fileName;
}
- (NSString *)safeFileName
{
return [TGDocumentMediaAttachment safeFileNameForFileName:[self fileName]];
}
+ (NSString *)safeFileNameForFileName:(NSString *)fileName
{
if (fileName.length == 0)
return @"file";
return [fileName stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
}
- (bool)isAnimated {
for (id attribute in _attributes) {
if ([attribute isKindOfClass:[TGDocumentAttributeAnimated class]]) {
return true;
}
}
return false;
}
- (bool)isSticker {
for (id attribute in _attributes) {
if ([attribute isKindOfClass:[TGDocumentAttributeSticker class]]) {
return true;
}
}
return false;
}
- (bool)isStickerWithPack {
for (id attribute in _attributes) {
if ([attribute isKindOfClass:[TGDocumentAttributeSticker class]]) {
return ((TGDocumentAttributeSticker *)attribute).packReference != nil;
}
}
return false;
}
- (id<TGStickerPackReference>)stickerPackReference {
for (id attribute in _attributes) {
if ([attribute isKindOfClass:[TGDocumentAttributeSticker class]]) {
return ((TGDocumentAttributeSticker *)attribute).packReference;
}
}
return nil;
}
- (bool)isVoice {
for (id attribute in _attributes) {
if ([attribute isKindOfClass:[TGDocumentAttributeAudio class]]) {
TGDocumentAttributeAudio *audio = attribute;
if (audio.isVoice) {
return true;
}
}
}
return false;
}
- (bool)isRoundVideo {
for (id attribute in _attributes) {
if ([attribute isKindOfClass:[TGDocumentAttributeVideo class]]) {
TGDocumentAttributeVideo *video = attribute;
if (video.isRoundMessage) {
return true;
}
}
}
return false;
}
- (CGSize)pictureSize {
for (id attribute in _attributes) {
if ([attribute isKindOfClass:[TGDocumentAttributeImageSize class]]) {
return ((TGDocumentAttributeImageSize *)attribute).size;
} else if ([attribute isKindOfClass:[TGDocumentAttributeVideo class]]) {
return ((TGDocumentAttributeVideo *)attribute).size;
}
}
return CGSizeZero;
}
- (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

View File

@@ -0,0 +1,27 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <LegacyComponents/TGMediaAttachment.h>
#define TGForwardedMessageMediaAttachmentType ((int)0xAA1050C1)
@interface TGForwardedMessageMediaAttachment : TGMediaAttachment <NSCopying, TGMediaAttachmentParser>
@property (nonatomic) int64_t forwardSourcePeerId;
@property (nonatomic) int64_t forwardPeerId;
@property (nonatomic) int forwardDate;
@property (nonatomic) int32_t forwardAuthorUserId;
@property (nonatomic) int32_t forwardPostId;
@property (nonatomic) NSString *forwardAuthorSignature;
@property (nonatomic) int forwardMid;
@end

View File

@@ -0,0 +1,133 @@
#import "TGForwardedMessageMediaAttachment.h"
@implementation TGForwardedMessageMediaAttachment
- (id)init
{
self = [super init];
if (self != nil)
{
self.type = TGForwardedMessageMediaAttachmentType;
}
return self;
}
- (id)copyWithZone:(NSZone *)__unused zone
{
TGForwardedMessageMediaAttachment *attachment = [[TGForwardedMessageMediaAttachment alloc] init];
attachment.forwardSourcePeerId = _forwardSourcePeerId;
attachment.forwardPeerId = _forwardPeerId;
attachment.forwardDate = _forwardDate;
attachment.forwardAuthorUserId = _forwardAuthorUserId;
attachment.forwardPostId = _forwardPostId;
attachment.forwardMid = _forwardMid;
return attachment;
}
- (void)serialize:(NSMutableData *)data
{
int32_t magic = 0x72413fad;
[data appendBytes:&magic length:4];
int dataLengthPtr = (int)data.length;
int zero = 0;
[data appendBytes:&zero length:4];
[data appendBytes:&_forwardPeerId length:8];
[data appendBytes:&_forwardDate length:4];
[data appendBytes:&_forwardMid length:4];
[data appendBytes:&_forwardAuthorUserId length:4];
[data appendBytes:&_forwardPostId length:4];
[data appendBytes:&_forwardSourcePeerId length:8];
NSData *signatureData = [_forwardAuthorSignature dataUsingEncoding:NSUTF8StringEncoding];
int32_t signatureLength = (int32_t)signatureData.length;
[data appendBytes:&signatureLength length:4];
[data appendData:signatureData];
int dataLength = (int)(data.length - dataLengthPtr - 4);
[data replaceBytesInRange:NSMakeRange(dataLengthPtr, 4) withBytes:&dataLength];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int32_t magic = 0;
[is read:(uint8_t *)&magic maxLength:4];
int32_t dataLength = 0;
int32_t version = 0;
if (magic == 0x72413faa) {
version = 2;
[is read:(uint8_t *)&dataLength maxLength:4];
} else if (magic == 0x72413fab) {
version = 3;
[is read:(uint8_t *)&dataLength maxLength:4];
} else if (magic == 0x72413fac) {
version = 4;
[is read:(uint8_t *)&dataLength maxLength:4];
} else if (magic == 0x72413fad) {
version = 5;
[is read:(uint8_t *)&dataLength maxLength:4];
} else {
dataLength = magic;
}
TGForwardedMessageMediaAttachment *messageAttachment = [[TGForwardedMessageMediaAttachment alloc] init];
if (version >= 2) {
int64_t forwardPeerId = 0;
[is read:(uint8_t *)&forwardPeerId maxLength:8];
messageAttachment.forwardPeerId = forwardPeerId;
} else {
int32_t forwardUid = 0;
[is read:(uint8_t *)&forwardUid maxLength:4];
messageAttachment.forwardPeerId = forwardUid;
}
int forwardDate = 0;
[is read:(uint8_t *)&forwardDate maxLength:4];
messageAttachment.forwardDate = forwardDate;
int forwardMid = 0;
[is read:(uint8_t *)&forwardMid maxLength:4];
messageAttachment.forwardMid = forwardMid;
if (version >= 3) {
int32_t forwardAuthorUserId = 0;
[is read:(uint8_t *)&forwardAuthorUserId maxLength:4];
messageAttachment.forwardAuthorUserId = forwardAuthorUserId;
int32_t forwardPostId = 0;
[is read:(uint8_t *)&forwardPostId maxLength:4];
messageAttachment.forwardPostId = forwardPostId;
}
if (version >= 4) {
int64_t forwardSourcePeerId = 0;
[is read:(uint8_t *)&forwardSourcePeerId maxLength:8];
messageAttachment.forwardSourcePeerId = forwardSourcePeerId;
}
if (version >= 5) {
int32_t signatureLength = 0;
[is read:(uint8_t *)&signatureLength maxLength:4];
uint8_t *signatureBytes = malloc(signatureLength);
[is read:signatureBytes maxLength:signatureLength];
NSString *signature = [[NSString alloc] initWithBytesNoCopy:signatureBytes length:signatureLength encoding:NSUTF8StringEncoding freeWhenDone:true];
if (signatureLength != 0) {
messageAttachment.forwardAuthorSignature = signature;
} else {
messageAttachment.forwardAuthorSignature = nil;
}
}
return messageAttachment;
}
@end

View File

@@ -0,0 +1,23 @@
#import <LegacyComponents/TGMediaAttachment.h>
@class TGImageMediaAttachment;
@class TGDocumentMediaAttachment;
@class TGWebPageMediaAttachment;
#define TGGameAttachmentType ((int)0x57af081e)
@interface TGGameMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser, NSCoding>
@property (nonatomic, readonly) int64_t gameId;
@property (nonatomic, readonly) int64_t accessHash;
@property (nonatomic, strong, readonly) NSString *shortName;
@property (nonatomic, strong, readonly) NSString *title;
@property (nonatomic, strong, readonly) NSString *gameDescription;
@property (nonatomic, strong, readonly) TGImageMediaAttachment *photo;
@property (nonatomic, strong, readonly) TGDocumentMediaAttachment *document;
- (instancetype)initWithGameId:(int64_t)gameId accessHash:(int64_t)accessHash shortName:(NSString *)shortName title:(NSString *)title gameDescription:(NSString *)gameDescription photo:(TGImageMediaAttachment *)photo document:(TGDocumentMediaAttachment *)document;
- (TGWebPageMediaAttachment *)webPageWithText:(NSString *)text entities:(NSArray *)entities;
@end

View File

@@ -0,0 +1,72 @@
#import "TGGameMediaAttachment.h"
#import "LegacyComponentsInternal.h"
#import "NSInputStream+TL.h"
#import "TGWebPageMediaAttachment.h"
@implementation TGGameMediaAttachment
- (instancetype)initWithGameId:(int64_t)gameId accessHash:(int64_t)accessHash shortName:(NSString *)shortName title:(NSString *)title gameDescription:(NSString *)gameDescription photo:(TGImageMediaAttachment *)photo document:(TGDocumentMediaAttachment *)document {
self = [super init];
if (self != nil) {
self.type = TGGameAttachmentType;
_gameId = gameId;
_accessHash = accessHash;
_shortName = shortName;
_title = title;
_gameDescription = gameDescription;
_photo = photo;
_document = document;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithGameId:[aDecoder decodeInt64ForKey:@"gameId"] accessHash:[aDecoder decodeInt64ForKey:@"accessHash"] shortName:[aDecoder decodeObjectForKey:@"shortName"] title:[aDecoder decodeObjectForKey:@"title"] gameDescription:[aDecoder decodeObjectForKey:@"gameDescription"] photo:[aDecoder decodeObjectForKey:@"photo"] document:[aDecoder decodeObjectForKey:@"document"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt64:_gameId forKey:@"gameId"];
[aCoder encodeInt64:_accessHash forKey:@"accessHash"];
[aCoder encodeObject:_shortName forKey:@"shortName"];
[aCoder encodeObject:_title forKey:@"title"];
[aCoder encodeObject:_gameDescription forKey:@"gameDescription"];
[aCoder encodeObject:_photo forKey:@"photo"];
[aCoder encodeObject:_document forKey:@"document"];
}
- (void)serialize:(NSMutableData *)data
{
NSData *serializedData = [NSKeyedArchiver archivedDataWithRootObject:self];
int32_t length = (int32_t)serializedData.length;
[data appendBytes:&length length:4];
[data appendData:serializedData];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int32_t length = [is readInt32];
NSData *data = [is readData:length];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
- (TGWebPageMediaAttachment *)webPageWithText:(NSString *)text entities:(NSArray *)entities {
TGWebPageMediaAttachment *webPage = [[TGWebPageMediaAttachment alloc] init];
webPage.siteName = self.title;
webPage.pageDescription = (text.length == 0 || [text isEqualToString:@" "]) ? self.gameDescription : text;
webPage.photo = self.photo;
webPage.document = self.document;
webPage.pageType = @"game";
webPage.pageDescriptionEntities = (text.length == 0 || [text isEqualToString:@" "]) ? nil : entities;
return webPage;
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[TGGameMediaAttachment class]] && ((TGGameMediaAttachment *)object)->_gameId == _gameId && ((TGGameMediaAttachment *)object)->_accessHash == _accessHash && TGStringCompare(((TGGameMediaAttachment *)object)->_title, _title) && TGStringCompare(((TGGameMediaAttachment *)object)->_gameDescription, _gameDescription) && TGStringCompare(((TGGameMediaAttachment *)object)->_shortName, _shortName);
}
@end

View File

@@ -0,0 +1,34 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <UIKit/UIKit.h>
@interface TGImageInfo : NSObject <NSCoding>
- (void)addImageWithSize:(CGSize)size url:(NSString *)url;
- (void)addImageWithSize:(CGSize)size url:(NSString *)url fileSize:(int)fileSize;
- (NSString *)closestImageUrlWithWidth:(int)width resultingSize:(CGSize *)resultingSize;
- (NSString *)closestImageUrlWithHeight:(int)height resultingSize:(CGSize *)resultingSize;
- (NSString *)closestImageUrlWithSize:(CGSize)size resultingSize:(CGSize *)resultingSize;
- (NSString *)closestImageUrlWithSize:(CGSize)size resultingSize:(CGSize *)resultingSize pickLargest:(bool)pickLargest;
- (NSString *)closestImageUrlWithSize:(CGSize)size resultingSize:(CGSize *)resultingSize resultingFileSize:(int *)resultingFileSize;
- (NSString *)closestImageUrlWithSize:(CGSize)size resultingSize:(CGSize *)resultingSize resultingFileSize:(int *)resultingFileSize pickLargest:(bool)pickLargest;
- (NSString *)imageUrlWithExactSize:(CGSize)size;
- (NSString *)imageUrlForLargestSize:(CGSize *)actualSize;
- (NSString *)imageUrlForSizeLargerThanSize:(CGSize)size actualSize:(CGSize *)actualSize;
- (bool)containsSizeWithUrl:(NSString *)url;
- (NSDictionary *)allSizes;
- (bool)empty;
- (void)serialize:(NSMutableData *)data;
+ (TGImageInfo *)deserialize:(NSInputStream *)is;
@end

View File

@@ -0,0 +1,358 @@
#import "TGImageInfo.h"
#import <vector>
struct TGImageSizeRecord
{
CGSize size;
NSString *url;
int fileSize;
TGImageSizeRecord(CGSize size_, NSString *url_, int fileSize_) :
size(size_), fileSize(fileSize_)
{
url = url_;
}
TGImageSizeRecord(const TGImageSizeRecord &other)
{
url = other.url;
size = other.size;
fileSize = other.fileSize;
}
TGImageSizeRecord & operator= (const TGImageSizeRecord &other)
{
if (this != &other)
{
url = other.url;
size = other.size;
fileSize = other.fileSize;
}
return *this;
}
~TGImageSizeRecord()
{
url = nil;
}
};
@interface TGImageInfo ()
{
std::vector<TGImageSizeRecord> sizes;
}
@end
@implementation TGImageInfo
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self != nil)
{
for (NSDictionary *sizeDict in [aDecoder decodeObjectForKey:@"sizes"])
{
[self addImageWithSize:CGSizeMake([sizeDict[@"width"] floatValue], [sizeDict[@"height"] floatValue]) url:sizeDict[@"url"] fileSize:[sizeDict[@"fileSize"] intValue]];
}
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
NSMutableArray *array = [[NSMutableArray alloc] init];
for (auto it : sizes)
{
[array addObject:@{@"width": @(it.size.width), @"height": @(it.size.height), @"url": it.url == nil ? @"" : it.url, @"fileSize": @(it.fileSize)}];
}
[aCoder encodeObject:array forKey:@"sizes"];
}
- (BOOL)isEqual:(id)object
{
if (![object isKindOfClass:[TGImageInfo class]])
return false;
TGImageInfo *other = (TGImageInfo *)object;
if (sizes.size() != other->sizes.size())
return false;
for (int i = 0; i < (int)sizes.size(); i++)
{
if (!CGSizeEqualToSize(sizes[i].size, other->sizes[i].size))
return false;
if (![sizes[i].url isEqualToString:other->sizes[i].url])
return false;
}
return true;
}
- (void)addImageWithSize:(CGSize)size url:(NSString *)url
{
sizes.push_back(TGImageSizeRecord(size, url, 0));
}
- (void)addImageWithSize:(CGSize)size url:(NSString *)url fileSize:(int)fileSize
{
sizes.push_back(TGImageSizeRecord(size, url, fileSize));
}
- (NSString *)closestImageUrlWithWidth:(int)width resultingSize:(CGSize *)resultingSize
{
CGSize closestSize = CGSizeZero;
NSString *closestUrl = nil;
for (std::vector<TGImageSizeRecord>::iterator it = sizes.begin(); it != sizes.end(); it++)
{
if (closestUrl == nil)
{
closestUrl = it->url;
closestSize = it->size;
}
else
{
if (ABS(width - it->size.width) < ABS(width - closestSize.width))
{
closestUrl = it->url;
closestSize = it->size;
}
}
}
if (resultingSize != NULL)
*resultingSize = closestSize;
return closestUrl;
}
- (NSString *)closestImageUrlWithHeight:(int)height resultingSize:(CGSize *)resultingSize
{
CGSize closestSize = CGSizeZero;
NSString *closestUrl = nil;
for (std::vector<TGImageSizeRecord>::iterator it = sizes.begin(); it != sizes.end(); it++)
{
if (closestUrl == nil)
{
closestUrl = it->url;
closestSize = it->size;
}
else
{
if (ABS(height - it->size.height) < ABS(height - closestSize.height))
{
closestUrl = it->url;
closestSize = it->size;
}
}
}
if (resultingSize != NULL)
*resultingSize = closestSize;
return closestUrl;
}
- (NSString *)closestImageUrlWithSize:(CGSize)size resultingSize:(CGSize *)resultingSize
{
return [self closestImageUrlWithSize:size resultingSize:resultingSize pickLargest:false];
}
- (NSString *)closestImageUrlWithSize:(CGSize)size resultingSize:(CGSize *)resultingSize resultingFileSize:(int *)resultingFileSize
{
return [self closestImageUrlWithSize:size resultingSize:resultingSize resultingFileSize:resultingFileSize pickLargest:false];
}
- (NSString *)closestImageUrlWithSize:(CGSize)size resultingSize:(CGSize *)resultingSize pickLargest:(bool)pickLargest
{
return [self closestImageUrlWithSize:size resultingSize:resultingSize resultingFileSize:NULL pickLargest:pickLargest];
}
- (NSString *)closestImageUrlWithSize:(CGSize)size resultingSize:(CGSize *)resultingSize resultingFileSize:(int *)resultingFileSize pickLargest:(bool)pickLargest
{
CGSize closestSize = CGSizeZero;
int closestFileSize = 0;
CGFloat closestDeltaSquared = FLT_MAX;
NSString *closestUrl = nil;
for (std::vector<TGImageSizeRecord>::iterator it = sizes.begin(); it != sizes.end(); it++)
{
CGFloat deltaWidth = ABS(size.width - it->size.width);
CGFloat deltaHeight = ABS(size.height - it->size.height);
CGFloat currentDeltaSquared = deltaWidth * deltaWidth + deltaHeight * deltaHeight;
if (closestUrl == nil || currentDeltaSquared < closestDeltaSquared || (pickLargest && ((currentDeltaSquared <= closestDeltaSquared + FLT_EPSILON) || ((closestSize.width < size.width || closestSize.height < size.height) && (it->size.width > closestSize.width && it->size.height > closestSize.height)))))
{
closestUrl = it->url;
closestSize = it->size;
closestFileSize = it->fileSize;
closestDeltaSquared = deltaWidth * deltaWidth + deltaHeight * deltaHeight;
}
}
if (resultingSize != NULL)
*resultingSize = closestSize;
if (resultingFileSize != NULL)
*resultingFileSize = closestFileSize;
return closestUrl;
}
- (NSString *)imageUrlWithExactSize:(CGSize)size
{
for (std::vector<TGImageSizeRecord>::iterator it = sizes.begin(); it != sizes.end(); it++)
{
CGFloat deltaWidth = ABS(size.width - it->size.width);
CGFloat deltaHeight = ABS(size.height - it->size.height);
if (deltaWidth < 1 + FLT_EPSILON && deltaHeight < 1 + FLT_EPSILON)
{
return it->url;
}
}
return nil;
}
- (NSString *)imageUrlForLargestSize:(CGSize *)actualSize
{
NSString *largestUrl = nil;
CGSize largestSize = CGSizeZero;
for (auto it = sizes.begin(); it != sizes.end(); it++)
{
if (it->size.width > largestSize.width)
{
largestUrl = it->url;
largestSize = it->size;
}
}
if (actualSize != NULL)
*actualSize = largestSize;
return largestUrl;
}
- (NSString *)imageUrlForSizeLargerThanSize:(CGSize)size actualSize:(CGSize *)actualSize
{
NSString *largestUrl = nil;
CGSize largestSize = CGSizeZero;
for (auto it = sizes.begin(); it != sizes.end(); it++)
{
if (it->size.width > size.width && (largestUrl == nil || it->size.width < largestSize.width))
{
largestUrl = it->url;
largestSize = it->size;
break;
}
}
if (largestUrl == nil)
largestUrl = [self closestImageUrlWithSize:size resultingSize:actualSize pickLargest:true];
else if (actualSize)
*actualSize = largestSize;
return largestUrl;
}
- (bool)containsSizeWithUrl:(NSString *)url
{
if (url == nil)
return false;
for (std::vector<TGImageSizeRecord>::iterator it = sizes.begin(); it != sizes.end(); it++)
{
if ([url isEqualToString:it->url])
return true;
}
return false;
}
- (NSDictionary *)allSizes
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for (std::vector<TGImageSizeRecord>::iterator it = sizes.begin(); it != sizes.end(); it++)
{
[dict setObject:[NSValue valueWithCGSize:it->size] forKey:it->url];
}
return dict;
}
- (bool)empty
{
return sizes.empty();
}
- (void)serialize:(NSMutableData *)data
{
int writtenCount = (int)sizes.size();
writtenCount |= (1 << 31);
[data appendBytes:&writtenCount length:4];
uint16_t version = 1;
[data appendBytes:&version length:2];
for (std::vector<TGImageSizeRecord>::iterator it = sizes.begin(); it != sizes.end(); it++)
{
NSData *urlData = [it->url dataUsingEncoding:NSUTF8StringEncoding];
int length = (int)urlData.length;
[data appendBytes:&length length:4];
[data appendData:urlData];
float width = (float)it->size.width;
float height = (float)it->size.height;
[data appendBytes:&width length:4];
[data appendBytes:&height length:4];
[data appendBytes:&it->fileSize length:4];
}
}
+ (TGImageInfo *)deserialize:(NSInputStream *)is
{
TGImageInfo *info = [[TGImageInfo alloc] init];
uint16_t version = 0;
int count = 0;
[is read:(uint8_t *)&count maxLength:4];
if (count & (1 << 31))
{
count &= ~(1 << 31);
[is read:(uint8_t *)&version maxLength:2];
}
for (int i = 0; i < count; i++)
{
int length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *urlBytes = (uint8_t *)malloc(length);
[is read:urlBytes maxLength:length];
NSString *url = [[NSString alloc] initWithBytesNoCopy:urlBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
float sizeWidth = 0.0f;
float sizeHeight = 0.0f;
[is read:(uint8_t *)&sizeWidth maxLength:4];
[is read:(uint8_t *)&sizeHeight maxLength:4];
int fileSize = 0;
if (version >= 1)
[is read:(uint8_t *)&fileSize maxLength:4];
[info addImageWithSize:CGSizeMake(sizeWidth, sizeHeight) url:url fileSize:fileSize];
}
return info;
}
@end

View File

@@ -0,0 +1,35 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <LegacyComponents/TGMediaAttachment.h>
#import <LegacyComponents/TGImageInfo.h>
#define TGImageMediaAttachmentType 0x269BD8A8
@interface TGImageMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser, NSCopying, NSCoding>
@property (nonatomic) int64_t imageId;
@property (nonatomic, readonly) int64_t localImageId;
@property (nonatomic) int64_t accessHash;
@property (nonatomic) int date;
@property (nonatomic) bool hasLocation;
@property (nonatomic) double locationLatitude;
@property (nonatomic) double locationLongitude;
@property (nonatomic, strong) TGImageInfo *imageInfo;
@property (nonatomic) NSString *caption;
@property (nonatomic) bool hasStickers;
@property (nonatomic, strong) NSArray *embeddedStickerDocuments;
@property (nonatomic, readonly) NSArray *textCheckingResults;
+ (int64_t)localImageIdForImageInfo:(TGImageInfo *)imageInfo;
- (CGSize)dimensions;
@end

View File

@@ -0,0 +1,267 @@
#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"];
}
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"];
}
- (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;
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 = murMurHash32(legacyCacheUrl);
return localImageId;
}
- (void)serialize:(NSMutableData *)data
{
int32_t modernTag = 0x7abacaf1;
[data appendBytes:&modernTag length:4];
uint8_t version = 3;
[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];
}
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];
}
}
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

View File

@@ -0,0 +1,298 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class TGImageMediaAttachment;
@class TGVideoMediaAttachment;
@class TGDocumentMediaAttachment;
@class TGConversation;
@interface TGRichText : NSObject <NSCoding>
@end
@interface TGRichTextPlain : TGRichText
@property (nonatomic, strong, readonly) NSString *text;
- (instancetype)initWithText:(NSString *)text;
@end
@interface TGRichTextBold : TGRichText
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGRichTextItalic : TGRichText
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGRichTextUnderline : TGRichText
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGRichTextStrikethrough : TGRichText
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGRichTextFixed : TGRichText
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGRichTextUrl : TGRichText
@property (nonatomic, strong, readonly) TGRichText *text;
@property (nonatomic, strong, readonly) NSString *url;
@property (nonatomic, readonly) int64_t webpageId;
- (instancetype)initWithText:(TGRichText *)text url:(NSString *)url webpageId:(int64_t)webpageId;
@end
@interface TGRichTextEmail: TGRichText
@property (nonatomic, strong, readonly) TGRichText *text;
@property (nonatomic, strong) NSString *email;
- (instancetype)initWithText:(TGRichText *)text email:(NSString *)email;
@end
@interface TGRichTextCollection : TGRichText
@property (nonatomic, strong, readonly) NSArray<TGRichText *> *texts;
- (instancetype)initWithTexts:(NSArray<TGRichText *> *)texts;
@end
@interface TGInstantPageBlock : NSObject <NSCoding>
@end
@interface TGInstantPageBlockCover : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGInstantPageBlock *block;
- (instancetype)initWithBlock:(TGInstantPageBlock *)block;
@end
@interface TGInstantPageBlockChannel : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGConversation *channel;
- (instancetype)initWithChannel:(TGConversation *)channel;
@end
@interface TGInstantPageBlockTitle : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGInstantPageBlockSubtitle : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGInstantPageBlockAuthorAndDate : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *author;
@property (nonatomic, readonly) int32_t date;
- (instancetype)initWithAuthor:(TGRichText *)author date:(int32_t)date;
@end
@interface TGInstantPageBlockHeader : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGInstantPageBlockSubheader : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGInstantPageBlockParagraph : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGInstantPageBlockPreFormatted : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *text;
@property (nonatomic, strong, readonly) NSString *language;
- (instancetype)initWithText:(TGRichText *)text language:(NSString *)language;
@end
@interface TGInstantPageBlockFooter : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *text;
- (instancetype)initWithText:(TGRichText *)text;
@end
@interface TGInstantPageBlockDivider : TGInstantPageBlock
@end
@interface TGInstantPageBlockList : TGInstantPageBlock
@property (nonatomic, readonly) bool ordered;
@property (nonatomic, strong, readonly) NSArray<TGRichText *> *items;
- (instancetype)initWithOrdered:(bool)ordered items:(NSArray<TGRichText *> *)items;
@end
@interface TGInstantPageBlockBlockQuote : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *text;
@property (nonatomic, strong, readonly) TGRichText *caption;
- (instancetype)initWithText:(TGRichText *)text caption:(TGRichText *)caption;
@end
@interface TGInstantPageBlockPullQuote : TGInstantPageBlock
@property (nonatomic, strong, readonly) TGRichText *text;
@property (nonatomic, strong, readonly) TGRichText *caption;
- (instancetype)initWithText:(TGRichText *)text caption:(TGRichText *)caption;
@end
@interface TGInstantPageBlockPhoto : TGInstantPageBlock
@property (nonatomic, readonly) int64_t photoId;
@property (nonatomic, strong, readonly) TGRichText *caption;
- (instancetype)initWithPhotoId:(int64_t)photoId caption:(TGRichText *)caption;
@end
@interface TGInstantPageBlockVideo : TGInstantPageBlock
@property (nonatomic, readonly) int64_t videoId;
@property (nonatomic, strong, readonly) TGRichText *caption;
@property (nonatomic, readonly) bool autoplay;
@property (nonatomic, readonly) bool loop;
- (instancetype)initWithVideoId:(int64_t)videoId caption:(TGRichText *)caption autoplay:(bool)autoplay loop:(bool)loop;
@end
@interface TGInstantPageBlockEmbed : TGInstantPageBlock
@property (nonatomic, strong, readonly) NSString *url;
@property (nonatomic, strong, readonly) NSString *html;
@property (nonatomic, readonly) int64_t posterPhotoId;
@property (nonatomic, strong, readonly) TGRichText *caption;
@property (nonatomic, readonly) CGSize size;
@property (nonatomic, readonly) bool fillWidth;
@property (nonatomic, readonly) bool enableScrolling;
- (instancetype)initWithUrl:(NSString *)url html:(NSString *)html posterPhotoId:(int64_t)posterPhotoId caption:(TGRichText *)caption size:(CGSize)size fillWidth:(bool)fillWidth enableScrolling:(bool)enableScrolling;
@end
@interface TGInstantPageBlockSlideshow : TGInstantPageBlock
@property (nonatomic, strong, readonly) NSArray<TGInstantPageBlock *> *items;
@property (nonatomic, strong, readonly) TGRichText *caption;
- (instancetype)initWithItems:(NSArray<TGInstantPageBlock *> *)items caption:(TGRichText *)caption;
@end
@interface TGInstantPageBlockCollage : TGInstantPageBlock
@property (nonatomic, strong, readonly) NSArray<TGInstantPageBlock *> *items;
@property (nonatomic, strong, readonly) TGRichText *caption;
- (instancetype)initWithItems:(NSArray<TGInstantPageBlock *> *)items caption:(TGRichText *)caption;
@end
@interface TGInstantPageBlockAnchor : TGInstantPageBlock
@property (nonatomic, strong, readonly) NSString *name;
- (instancetype)initWithName:(NSString *)name;
@end
@interface TGInstantPageBlockEmbedPost : TGInstantPageBlock
@property (nonatomic, strong, readonly) NSString *author;
@property (nonatomic, readonly) int32_t date;
@property (nonatomic, strong, readonly) TGRichText *caption;
@property (nonatomic, strong, readonly) NSString *url;
@property (nonatomic, readonly) int64_t webpageId;
@property (nonatomic, strong, readonly) NSArray<TGInstantPageBlock *> *blocks;
@property (nonatomic, readonly) int64_t authorPhotoId;
- (instancetype)initWithAuthor:(NSString *)author date:(int32_t)date caption:(TGRichText *)caption url:(NSString *)url webpageId:(int64_t)webpageId blocks:(NSArray<TGInstantPageBlock *> *)blocks authorPhotoId:(int64_t)authorPhotoId;
@end
@interface TGInstantPageBlockAudio : TGInstantPageBlock
@property (nonatomic, readonly) int64_t audioId;
@property (nonatomic, strong, readonly) TGRichText *caption;
- (instancetype)initWithAudioId:(int64_t)audioId caption:(TGRichText *)caption;
@end
@interface TGInstantPage : NSObject <NSCoding>
@property (nonatomic, readonly) bool isPartial;
@property (nonatomic, strong, readonly) NSArray<TGInstantPageBlock *> *blocks;
@property (nonatomic, strong, readonly) NSDictionary<NSNumber *, TGImageMediaAttachment *> *images;
@property (nonatomic, strong, readonly) NSDictionary<NSNumber *, TGVideoMediaAttachment *> *videos;
@property (nonatomic, strong, readonly) NSDictionary<NSNumber *, TGDocumentMediaAttachment *> *documents;
- (instancetype)initWithIsPartial:(bool)isPartial blocks:(NSArray<TGInstantPageBlock *> *)blocks images:(NSDictionary<NSNumber *, TGImageMediaAttachment *> *)images videos:(NSDictionary<NSNumber *, TGVideoMediaAttachment *> *)videos documents:(NSDictionary<NSNumber *, TGDocumentMediaAttachment *> *)documents;
@end

View File

@@ -0,0 +1,909 @@
#import "TGInstantPage.h"
#import "TGConversation.h"
#import "PSKeyValueEncoder.h"
#import "PSKeyValueDecoder.h"
@implementation TGRichText
- (instancetype)initWithCoder:(NSCoder *)__unused aDecoder {
self = [super init];
if (self != nil) {
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)__unused aCoder {
}
@end
@implementation TGRichTextPlain
- (instancetype)initWithText:(NSString *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGRichTextBold
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGRichTextItalic
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGRichTextUnderline
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGRichTextStrikethrough
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGRichTextFixed
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGRichTextUrl
- (instancetype)initWithText:(TGRichText *)text url:(NSString *)url webpageId:(int64_t)webpageId {
self = [super init];
if (self != nil) {
_text = text;
_url = url;
_webpageId = webpageId;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
_url = [aDecoder decodeObjectForKey:@"url"];
_webpageId = [aDecoder decodeInt64ForKey:@"wpid"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
[aCoder encodeObject:_url forKey:@"url"];
[aCoder encodeInt64:_webpageId forKey:@"wpid"];
}
@end
@implementation TGRichTextEmail: TGRichText
- (instancetype)initWithText:(TGRichText *)text email:(NSString *)email {
self = [super init];
if (self != nil) {
_text = text;
_email = email;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
_email = [aDecoder decodeObjectForKey:@"email"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
[aCoder encodeObject:_email forKey:@"email"];
}
@end
@implementation TGRichTextCollection
- (instancetype)initWithTexts:(NSArray<TGRichText *> *)texts {
self = [super init];
if (self != nil) {
_texts = texts;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_texts = [aDecoder decodeObjectForKey:@"texts"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_texts forKey:@"texts"];
}
@end
@implementation TGInstantPageBlock
- (instancetype)initWithCoder:(NSCoder *)__unused aDecoder {
self = [super init];
if (self != nil) {
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)__unused aCoder {
}
@end
@implementation TGInstantPageBlockCover
- (instancetype)initWithBlock:(TGInstantPageBlock *)block {
self = [super init];
if (self != nil) {
_block = block;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_block = [aDecoder decodeObjectForKey:@"block"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_block forKey:@"block"];
}
@end
@implementation TGInstantPageBlockChannel
- (instancetype)initWithChannel:(TGConversation *)channel {
self = [super init];
if (self != nil) {
_channel = channel;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
NSData *data = [aDecoder decodeObjectForKey:@"channelData"];
PSKeyValueDecoder *decoder = [[PSKeyValueDecoder alloc] initWithData:data];
_channel = (TGConversation *)[decoder decodeObjectForKey:@"channel"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
PSKeyValueEncoder *encoder = [[PSKeyValueEncoder alloc] init];
[encoder encodeObject:_channel forKey:@"channel"];
[aCoder encodeObject:[encoder data] forKey:@"channelData"];
}
@end
@implementation TGInstantPageBlockTitle
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGInstantPageBlockSubtitle
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGInstantPageBlockAuthorAndDate
- (instancetype)initWithAuthor:(TGRichText *)author date:(int32_t)date {
self = [super init];
if (self != nil) {
_author = author;
_date = date;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
TGRichText *richAuthor = [aDecoder decodeObjectForKey:@"rauthor"];
if (richAuthor != nil) {
_author = richAuthor;
} else {
NSString *author = [aDecoder decodeObjectForKey:@"author"];
_author = [[TGRichTextPlain alloc] initWithText:author];
}
_date = [aDecoder decodeInt32ForKey:@"date"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_author forKey:@"rauthor"];
[aCoder encodeInt32:_date forKey:@"date"];
}
@end
@implementation TGInstantPageBlockHeader
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGInstantPageBlockSubheader
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGInstantPageBlockParagraph
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGInstantPageBlockPreFormatted
- (instancetype)initWithText:(TGRichText *)text language:(NSString *)language {
self = [super init];
if (self != nil) {
_text = text;
_language = language;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
_language = [aDecoder decodeObjectForKey:@"lang"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
[aCoder encodeObject:_language forKey:@"lang"];
}
@end
@implementation TGInstantPageBlockFooter
- (instancetype)initWithText:(TGRichText *)text {
self = [super init];
if (self != nil) {
_text = text;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
}
@end
@implementation TGInstantPageBlockDivider
- (instancetype)initWithCoder:(NSCoder *)__unused aDecoder {
self = [super init];
if (self != nil) {
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)__unused aCoder {
}
@end
@implementation TGInstantPageBlockList
- (instancetype)initWithOrdered:(bool)ordered items:(NSArray<TGRichText *> *)items {
self = [super init];
if (self != nil) {
_ordered = ordered;
_items = items;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_ordered = [aDecoder decodeBoolForKey:@"ord"];
_items = [aDecoder decodeObjectForKey:@"items"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeBool:_ordered forKey:@"ord"];
[aCoder encodeObject:_items forKey:@"items"];
}
@end
@implementation TGInstantPageBlockBlockQuote
- (instancetype)initWithText:(TGRichText *)text caption:(TGRichText *)caption {
self = [super init];
if (self != nil) {
_text = text;
_caption = caption;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
[aCoder encodeObject:_caption forKey:@"caption"];
}
@end
@implementation TGInstantPageBlockPullQuote
- (instancetype)initWithText:(TGRichText *)text caption:(TGRichText *)caption {
self = [super init];
if (self != nil) {
_text = text;
_caption = caption;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_text = [aDecoder decodeObjectForKey:@"text"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_text forKey:@"text"];
[aCoder encodeObject:_caption forKey:@"caption"];
}
@end
@implementation TGInstantPageBlockPhoto
- (instancetype)initWithPhotoId:(int64_t)photoId caption:(TGRichText *)caption {
self = [super init];
if (self != nil) {
_photoId = photoId;
_caption = caption;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_photoId = [aDecoder decodeInt64ForKey:@"pid"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt64:_photoId forKey:@"pid"];
[aCoder encodeObject:_caption forKey:@"caption"];
}
@end
@implementation TGInstantPageBlockVideo
- (instancetype)initWithVideoId:(int64_t)videoId caption:(TGRichText *)caption autoplay:(bool)autoplay loop:(bool)loop {
self = [super init];
if (self != nil) {
_videoId = videoId;
_caption = caption;
_autoplay = autoplay;
_loop = loop;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_videoId = [aDecoder decodeInt64ForKey:@"vid"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
_autoplay = [aDecoder decodeBoolForKey:@"autoplay"];
_loop = [aDecoder decodeBoolForKey:@"loop"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt64:_videoId forKey:@"vid"];
[aCoder encodeObject:_caption forKey:@"caption"];
[aCoder encodeBool:_autoplay forKey:@"autoplay"];
[aCoder encodeBool:_loop forKey:@"loop"];
}
@end
@implementation TGInstantPageBlockEmbed
- (instancetype)initWithUrl:(NSString *)url html:(NSString *)html posterPhotoId:(int64_t)posterPhotoId caption:(TGRichText *)caption size:(CGSize)size fillWidth:(bool)fillWidth enableScrolling:(bool)enableScrolling {
self = [super init];
if (self != nil) {
_url = url;
_html = html;
_posterPhotoId = posterPhotoId;
_caption = caption;
_size = size;
_fillWidth = fillWidth;
_enableScrolling = enableScrolling;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_url = [aDecoder decodeObjectForKey:@"url"];
_html = [aDecoder decodeObjectForKey:@"html"];
_posterPhotoId = [aDecoder decodeInt64ForKey:@"posterPhotoId"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
_size = [aDecoder decodeCGSizeForKey:@"size"];
_fillWidth = [aDecoder decodeBoolForKey:@"fillWidth"];
_enableScrolling = [aDecoder decodeBoolForKey:@"enableScrolling"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_url forKey:@"url"];
[aCoder encodeObject:_html forKey:@"html"];
[aCoder encodeInt64:_posterPhotoId forKey:@"posterPhotoId"];
[aCoder encodeObject:_caption forKey:@"caption"];
[aCoder encodeCGSize:_size forKey:@"size"];
[aCoder encodeBool:_fillWidth forKey:@"fillWidth"];
[aCoder encodeBool:_enableScrolling forKey:@"enableScrolling"];
}
@end
@implementation TGInstantPageBlockSlideshow
- (instancetype)initWithItems:(NSArray<TGInstantPageBlock *> *)items caption:(TGRichText *)caption {
self = [super init];
if (self != nil) {
_items = items;
_caption = caption;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_items = [aDecoder decodeObjectForKey:@"items"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_items forKey:@"items"];
[aCoder encodeObject:_caption forKey:@"caption"];
}
@end
@implementation TGInstantPageBlockCollage
- (instancetype)initWithItems:(NSArray<TGInstantPageBlock *> *)items caption:(TGRichText *)caption {
self = [super init];
if (self != nil) {
_items = items;
_caption = caption;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_items = [aDecoder decodeObjectForKey:@"items"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_items forKey:@"items"];
[aCoder encodeObject:_caption forKey:@"caption"];
}
@end
@implementation TGInstantPageBlockAnchor
- (instancetype)initWithName:(NSString *)name {
self = [super init];
if (self != nil) {
_name = name;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self != nil) {
_name = [aDecoder decodeObjectForKey:@"name"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_name forKey:@"name"];
}
@end
@implementation TGInstantPageBlockEmbedPost
- (instancetype)initWithAuthor:(NSString *)author date:(int32_t)date caption:(TGRichText *)caption url:(NSString *)url webpageId:(int64_t)webpageId blocks:(NSArray<TGInstantPageBlock *> *)blocks authorPhotoId:(int64_t)authorPhotoId {
self = [super init];
if (self != nil) {
_author = author;
_date = date;
_caption = caption;
_url = url;
_webpageId = webpageId;
_blocks = blocks;
_authorPhotoId = authorPhotoId;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_author = [aDecoder decodeObjectForKey:@"author"];
_date = [aDecoder decodeInt32ForKey:@"date"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
_url = [aDecoder decodeObjectForKey:@"url"];
_webpageId = [aDecoder decodeInt64ForKey:@"webpageId"];
_blocks = [aDecoder decodeObjectForKey:@"blocks"];
_authorPhotoId = [aDecoder decodeInt64ForKey:@"authorPhotoId"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_author forKey:@"author"];
[aCoder encodeInt32:_date forKey:@"date"];
[aCoder encodeObject:_caption forKey:@"caption"];
[aCoder encodeObject:_url forKey:@"url"];
[aCoder encodeInt64:_webpageId forKey:@"webpageId"];
[aCoder encodeObject:_blocks forKey:@"blocks"];
[aCoder encodeInt64:_authorPhotoId forKey:@"authorPhotoId"];
}
@end
@implementation TGInstantPageBlockAudio
- (instancetype)initWithAudioId:(int64_t)audioId caption:(TGRichText *)caption {
self = [super init];
if (self != nil) {
_audioId = audioId;
_caption = caption;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_audioId = [aDecoder decodeInt64ForKey:@"audioId"];
_caption = [aDecoder decodeObjectForKey:@"caption"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt64:_audioId forKey:@"audioId"];
[aCoder encodeObject:_caption forKey:@"caption"];
}
@end
@implementation TGInstantPage
- (instancetype)initWithIsPartial:(bool)isPartial blocks:(NSArray<TGInstantPageBlock *> *)blocks images:(NSDictionary *)images videos:(NSDictionary *)videos documents:(NSDictionary<NSNumber *,TGDocumentMediaAttachment *> *)documents {
self = [super init];
if (self != nil) {
_isPartial = isPartial;
_blocks = blocks;
_images = images;
_videos = videos;
_documents = documents;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
_isPartial = [aDecoder decodeBoolForKey:@"partial"];
_blocks = [aDecoder decodeObjectForKey:@"blocks"];
_images = [aDecoder decodeObjectForKey:@"images"];
_videos = [aDecoder decodeObjectForKey:@"videos"];
_documents = [aDecoder decodeObjectForKey:@"documents"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeBool:_isPartial forKey:@"partial"];
[aCoder encodeObject:_blocks forKey:@"blocks"];
[aCoder encodeObject:_images forKey:@"images"];
[aCoder encodeObject:_videos forKey:@"videos"];
[aCoder encodeObject:_documents forKey:@"documents"];
}
- (BOOL)isEqual:(id)object {
if (![object isKindOfClass:[TGInstantPage class]]) {
return false;
}
TGInstantPage *other = object;
if (_blocks.count != other->_blocks.count) {
return false;
}
return true;
}
@end

View File

@@ -0,0 +1,25 @@
#import "TGMediaAttachment.h"
#import <LegacyComponents/TGWebDocument.h>
#define TGInvoiceMediaAttachmentType ((int)0x17af081f)
@class TGWebPageMediaAttachment;
@interface TGInvoiceMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser, NSCoding>
@property (nonatomic, readonly) NSString *title;
@property (nonatomic, readonly) NSString *text;
@property (nonatomic, readonly) TGWebDocument *photo;
@property (nonatomic, strong, readonly) NSString *currency;
@property (nonatomic, readonly) int64_t totalAmount;
@property (nonatomic, readonly) int32_t receiptMessageId;
@property (nonatomic, strong, readonly) NSString *invoiceStartParam;
@property (nonatomic, readonly) bool shippingAddressRequested;
@property (nonatomic, readonly) bool isTest;
- (instancetype)initWithTitle:(NSString *)title text:(NSString *)text photo:(TGWebDocument *)photo currency:(NSString *)currency totalAmount:(int64_t)totalAmount receiptMessageId:(int32_t)receiptMessageId invoiceStartParam:(NSString *)invoiceStartParam shippingAddressRequested:(bool)shippingAddressRequested isTest:(bool)isTest;
- (TGWebPageMediaAttachment *)webpage;
@end

View File

@@ -0,0 +1,121 @@
#import "TGInvoiceMediaAttachment.h"
#import "LegacyComponentsInternal.h"
#import "NSInputStream+TL.h"
#import "TGWebPageMediaAttachment.h"
@implementation TGInvoiceMediaAttachment
- (instancetype)initWithTitle:(NSString *)title text:(NSString *)text photo:(TGWebDocument *)photo currency:(NSString *)currency totalAmount:(int64_t)totalAmount receiptMessageId:(int32_t)receiptMessageId invoiceStartParam:(NSString *)invoiceStartParam shippingAddressRequested:(bool)shippingAddressRequested isTest:(bool)isTest {
self = [super init];
if (self != nil) {
self.type = TGInvoiceMediaAttachmentType;
_title = title;
_text = text;
_photo = photo;
_currency = currency;
_totalAmount = totalAmount;
_receiptMessageId = receiptMessageId;
_invoiceStartParam = invoiceStartParam;
_shippingAddressRequested = shippingAddressRequested;
_isTest = isTest;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithTitle:[aDecoder decodeObjectForKey:@"title"] text:[aDecoder decodeObjectForKey:@"text"] photo:[aDecoder decodeObjectForKey:@"photo"] currency:[aDecoder decodeObjectForKey:@"currency"] totalAmount:[aDecoder decodeInt64ForKey:@"totalAmount"] receiptMessageId:[aDecoder decodeInt32ForKey:@"receiptMessageId"] invoiceStartParam:[aDecoder decodeObjectForKey:@"invoiceStartParam"] shippingAddressRequested:[aDecoder decodeBoolForKey:@"shippingAddressRequested"] isTest:[aDecoder decodeBoolForKey:@"isTest"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_title forKey:@"title"];
[aCoder encodeObject:_text forKey:@"text"];
[aCoder encodeObject:_photo forKey:@"photo"];
[aCoder encodeObject:_currency forKey:@"currency"];
[aCoder encodeInt64:_totalAmount forKey:@"totalAmount"];
[aCoder encodeInt32:_receiptMessageId forKey:@"receiptMessageId"];
[aCoder encodeObject:_invoiceStartParam forKey:@"invoiceStartParam"];
[aCoder encodeBool:_shippingAddressRequested forKey:@"shippingAddressRequested"];
[aCoder encodeBool:_isTest forKey:@"isTest"];
}
- (BOOL)isEqual:(id)object {
if (![object isKindOfClass:[TGInvoiceMediaAttachment class]]) {
return false;
}
TGInvoiceMediaAttachment *other = (TGInvoiceMediaAttachment *)object;
if (!TGStringCompare(_title, other->_title)) {
return false;
}
if (!TGStringCompare(_text, other->_text)) {
return false;
}
if (!TGObjectCompare(_photo, other->_photo)) {
return false;
}
if (!TGStringCompare(_currency, other->_currency)) {
return false;
}
if (_totalAmount != other->_totalAmount) {
return false;
}
if (_receiptMessageId != other->_receiptMessageId) {
return false;
}
if (!TGStringCompare(_invoiceStartParam, other->_invoiceStartParam)) {
return false;
}
if (_shippingAddressRequested != other->_shippingAddressRequested) {
return false;
}
if (_isTest != other->_isTest) {
return false;
}
return true;
}
- (void)serialize:(NSMutableData *)data
{
NSData *serializedData = [NSKeyedArchiver archivedDataWithRootObject:self];
int32_t length = (int32_t)serializedData.length;
[data appendBytes:&length length:4];
[data appendData:serializedData];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int32_t length = [is readInt32];
NSData *data = [is readData:length];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
- (TGWebPageMediaAttachment *)webpage {
TGWebPageMediaAttachment *webPage = [[TGWebPageMediaAttachment alloc] init];
webPage.siteName = self.title;
webPage.pageDescription = _text;
if (_photo != nil) {
TGImageInfo *imageInfo = [[TGImageInfo alloc] init];
for (id attribute in _photo.attributes) {
if ([attribute isKindOfClass:[TGDocumentAttributeImageSize class]]) {
CGSize imageSize = ((TGDocumentAttributeImageSize *)attribute).size;
if (imageSize.width < 1.0f || imageSize.height < 1.0f) {
imageSize = CGSizeMake(480.0f, 480.0f);
}
[imageInfo addImageWithSize:imageSize url:[[_photo reference] toString]];
TGImageMediaAttachment *imageMedia = [[TGImageMediaAttachment alloc] init];
imageMedia.imageInfo = imageInfo;
webPage.photo = imageMedia;
break;
}
}
}
webPage.pageType = @"invoice";
return webPage;
}
@end

View File

@@ -0,0 +1,19 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <LegacyComponents/TGMediaAttachment.h>
#define TGLocalMessageMetaMediaAttachmentType 0x944DE6B6
@interface TGLocalMessageMetaMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser>
@property (nonatomic, strong) NSMutableArray *imageInfoList;
@property (nonatomic, strong) NSMutableDictionary *imageUrlToDataFile;
@property (nonatomic) int localMediaId;
@end

View File

@@ -0,0 +1,101 @@
#import "TGLocalMessageMetaMediaAttachment.h"
#import "TGImageInfo.h"
@implementation TGLocalMessageMetaMediaAttachment
@synthesize imageInfoList = _imageInfoList;
@synthesize imageUrlToDataFile = _imageUrlToDataFile;
@synthesize localMediaId = _localMediaId;
- (id)init
{
self = [super init];
if (self != nil)
{
self.type = TGLocalMessageMetaMediaAttachmentType;
_imageInfoList = [[NSMutableArray alloc] init];
_imageUrlToDataFile = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)serialize:(NSMutableData *)data
{
int dataLengthPtr = (int)data.length;
int zero = 0;
[data appendBytes:&zero length:4];
int count = (int)_imageInfoList.count;
[data appendBytes:&count length:4];
for (int i = 0; i < count; i++)
{
[(TGImageInfo *)[_imageInfoList objectAtIndex:i] serialize:data];
}
count = (int)_imageUrlToDataFile.count;
[data appendBytes:&count length:4];
[_imageUrlToDataFile enumerateKeysAndObjectsUsingBlock:^(NSString *imageUrl, NSString *filePath, __unused BOOL *stop)
{
NSData *byteData = [imageUrl dataUsingEncoding:NSUTF8StringEncoding];
int length = (int)byteData.length;
[data appendBytes:&length length:4];
[data appendData:byteData];
byteData = [filePath dataUsingEncoding:NSUTF8StringEncoding];
length = (int)byteData.length;
[data appendBytes:&length length:4];
[data appendData:byteData];
}];
[data appendBytes:&_localMediaId length:4];
int dataLength = (int)(data.length - dataLengthPtr - 4);
[data replaceBytesInRange:NSMakeRange(dataLengthPtr, 4) withBytes:&dataLength];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int dataLength = 0;
[is read:(uint8_t *)&dataLength maxLength:4];
TGLocalMessageMetaMediaAttachment *attachment = [[TGLocalMessageMetaMediaAttachment alloc] init];
int count = 0;
[is read:(uint8_t *)&count maxLength:4];
for (int i = 0; i < count; i++)
{
TGImageInfo *imageInfo = [TGImageInfo deserialize:is];
if (imageInfo != nil)
[attachment.imageInfoList addObject:imageInfo];
}
count = 0;
[is read:(uint8_t *)&count maxLength:4];
for (int i = 0; i < count; i++)
{
int length = 0;
[is read:(uint8_t *)&length maxLength:4];
uint8_t *bytes = malloc(length);
[is read:bytes maxLength:length];
NSString *imageUrl = [[NSString alloc] initWithBytesNoCopy:bytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
length = 0;
[is read:(uint8_t *)&length maxLength:4];
bytes = malloc(length);
[is read:bytes maxLength:length];
NSString *filePath = [[NSString alloc] initWithBytesNoCopy:bytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
if (imageUrl != nil && filePath != nil)
[attachment.imageUrlToDataFile setObject:filePath forKey:imageUrl];
}
int mediaId = 0;
[is read:(uint8_t *)&mediaId maxLength:4];
attachment.localMediaId = mediaId;
return attachment;
}
@end

View File

@@ -0,0 +1,20 @@
#import <Foundation/Foundation.h>
@interface TGLocalization : NSObject <NSCoding>
@property (nonatomic, readonly) int32_t version;
@property (nonatomic, strong, readonly) NSString *code;
@property (nonatomic, readonly) int languageCodeHash;
@property (nonatomic, readonly) bool isActive;
- (instancetype)initWithVersion:(int32_t)version code:(NSString *)code dict:(NSDictionary<NSString *, NSString *> *)dict isActive:(bool)isActive;
- (TGLocalization *)mergedWith:(NSDictionary<NSString *, NSString *> *)other version:(int32_t)version;
- (TGLocalization *)withUpdatedIsActive:(bool)isActive;
- (NSString *)get:(NSString *)key;
- (NSString *)getPluralized:(NSString *)key count:(int32_t)count;
- (bool)contains:(NSString *)key;
@end

View File

@@ -0,0 +1,124 @@
#import "TGLocalization.h"
#import "TGPluralization.h"
static NSDictionary *fallbackDict() {
static NSDictionary *dict = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"]];
NSString *path = [bundle pathForResource:@"Localizable" ofType:@"strings"];
dict = [NSDictionary dictionaryWithContentsOfFile:path];
});
return dict;
}
static NSString *fallbackString(NSString *key) {
NSString *value = fallbackDict()[key];
if (value == nil) {
return key;
} else {
return value;
}
}
@interface TGLocalization () {
NSDictionary<NSString *, NSString *> *_dict;
}
@end
@implementation TGLocalization
- (instancetype)initWithVersion:(int32_t)version code:(NSString *)code dict:(NSDictionary<NSString *, NSString *> *)dict isActive:(bool)isActive {
self = [super init];
if (self != nil) {
_version = version;
_code = code;
_dict = dict;
_isActive = isActive;
NSString *rawCode = code;
NSRange range = [code rangeOfString:@"_"];
if (range.location != NSNotFound) {
rawCode = [code substringToIndex:range.location];
}
rawCode = [rawCode lowercaseString];
unsigned int lc = 0;
const char *s = rawCode.UTF8String;
for (; *s; s++) { lc = (lc << 8) + *s; }
_languageCodeHash = lc;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithVersion:[aDecoder decodeInt32ForKey:@"version"] code:[aDecoder decodeObjectForKey:@"code"] dict:[aDecoder decodeObjectForKey:@"dict"] isActive:[aDecoder decodeBoolForKey:@"isActive"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt32:_version forKey:@"version"];
[aCoder encodeObject:_code forKey:@"code"];
[aCoder encodeObject:_dict forKey:@"dict"];
[aCoder encodeBool:_isActive forKey:@"isActive"];
}
- (TGLocalization *)mergedWith:(NSDictionary<NSString *, NSString *> *)other version:(int32_t)version {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:_dict];
[dict addEntriesFromDictionary:other];
return [[TGLocalization alloc] initWithVersion:version code:_code dict:dict isActive:_isActive];
}
- (TGLocalization *)withUpdatedIsActive:(bool)isActive {
return [[TGLocalization alloc] initWithVersion:_version code:_code dict:_dict isActive:isActive];
}
- (NSString *)get:(NSString *)key {
if (key == nil) {
return nil;
}
NSString *value = _dict[key];
if (value != nil && value.length != 0) {
return value;
} else {
return fallbackString(key);
}
}
- (NSString *)getPluralized:(NSString *)key count:(int32_t)count {
NSString *suffix = nil;
switch (TGPluralForm(_languageCodeHash, count)) {
case TGPluralFormZero:
suffix = @"_0";
break;
case TGPluralFormOne:
suffix = @"_1";
break;
case TGPluralFormTwo:
suffix = @"_2";
break;
case TGPluralFormFew:
suffix = @"_3_10";
break;
case TGPluralFormMany:
suffix = @"_many";
break;
case TGPluralFormOther:
suffix = @"_any";
break;
}
NSString *finalKey = [key stringByAppendingString:suffix];
if (_dict[finalKey] == nil) {
finalKey = [key stringByAppendingString:@"_any"];
}
return [[NSString alloc] initWithFormat:[self get:finalKey], [NSString stringWithFormat:@"%d", count]];
}
- (bool)contains:(NSString *)key {
return _dict[key] != nil;
}
@end

View File

@@ -0,0 +1,31 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <LegacyComponents/TGMediaAttachment.h>
#define TGLocationMediaAttachmentType 0x0C9ED06E
@interface TGVenueAttachment : NSObject <NSCoding>
@property (nonatomic, strong, readonly) NSString *title;
@property (nonatomic, strong, readonly) NSString *address;
@property (nonatomic, strong, readonly) NSString *provider;
@property (nonatomic, strong, readonly) NSString *venueId;
- (instancetype)initWithTitle:(NSString *)title address:(NSString *)address provider:(NSString *)provider venueId:(NSString *)venueId;
@end
@interface TGLocationMediaAttachment : TGMediaAttachment <TGMediaAttachmentParser, NSCoding>
@property (nonatomic) double latitude;
@property (nonatomic) double longitude;
@property (nonatomic, strong) TGVenueAttachment *venue;
@end

View File

@@ -0,0 +1,117 @@
#import "TGLocationMediaAttachment.h"
@implementation TGVenueAttachment
- (instancetype)initWithTitle:(NSString *)title address:(NSString *)address provider:(NSString *)provider venueId:(NSString *)venueId
{
self = [super init];
if (self != nil)
{
_title = title;
_address = address;
_provider = provider;
_venueId = venueId;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
return [self initWithTitle:[aDecoder decodeObjectForKey:@"title"] address:[aDecoder decodeObjectForKey:@"address"] provider:[aDecoder decodeObjectForKey:@"provider"] venueId:[aDecoder decodeObjectForKey:@"venueId"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
if (_title != nil)
[aCoder encodeObject:_title forKey:@"title"];
if (_address != nil)
[aCoder encodeObject:_address forKey:@"address"];
if (_provider != nil)
[aCoder encodeObject:_provider forKey:@"provider"];
if (_venueId != nil)
[aCoder encodeObject:_venueId forKey:@"venueId"];
}
@end
@implementation TGLocationMediaAttachment
- (id)init
{
self = [super init];
if (self != nil)
{
self.type = TGLocationMediaAttachmentType;
}
return self;
}
- (void)serialize:(NSMutableData *)data
{
int dataLengthPtr = (int)data.length;
int zero = 0;
[data appendBytes:&zero length:4];
[data appendBytes:&_latitude length:8];
[data appendBytes:&_longitude length:8];
NSData *venueData = nil;
if (_venue != nil)
venueData = [NSKeyedArchiver archivedDataWithRootObject:_venue];
int32_t venueDataLength = (int32_t)venueData.length;
[data appendBytes:&venueDataLength length:4];
[data appendData:venueData];
int dataLength = (int)(data.length - dataLengthPtr - 4);
[data replaceBytesInRange:NSMakeRange(dataLengthPtr, 4) withBytes:&dataLength];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int dataLength = 0;
[is read:(uint8_t *)&dataLength maxLength:4];
TGLocationMediaAttachment *locationAttachment = [[TGLocationMediaAttachment alloc] init];
double tmp = 0;
[is read:(uint8_t *)&tmp maxLength:8];
locationAttachment.latitude = tmp;
tmp = 0;
[is read:(uint8_t *)&tmp maxLength:8];
locationAttachment.longitude = tmp;
if (dataLength >= 8 + 8 + 4)
{
int32_t venueDataLength = 0;
[is read:(uint8_t *)&venueDataLength maxLength:4];
if (venueDataLength > 0)
{
uint8_t *venueBytes = malloc(venueDataLength);
[is read:venueBytes maxLength:venueDataLength];
NSData *venueData = [[NSData alloc] initWithBytesNoCopy:venueBytes length:venueDataLength freeWhenDone:true];
locationAttachment.venue = [NSKeyedUnarchiver unarchiveObjectWithData:venueData];
}
}
return locationAttachment;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self != nil) {
self.type = TGLocationMediaAttachmentType;
_latitude = [aDecoder decodeDoubleForKey:@"latitude"];
_longitude = [aDecoder decodeDoubleForKey:@"longitude"];
_venue = [aDecoder decodeObjectForKey:@"venue"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeDouble:_latitude forKey:@"latitude"];
[aCoder encodeDouble:_longitude forKey:@"longitude"];
[aCoder encodeObject:_venue forKey:@"venue"];
}
@end

View File

@@ -0,0 +1,26 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <Foundation/Foundation.h>
@interface TGMediaAttachment : NSObject
@property (nonatomic) int type;
@property (nonatomic) bool isMeta;
- (void)serialize:(NSMutableData *)data;
@end
@protocol TGMediaAttachmentParser <NSObject>
@required
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is;
@end

View File

@@ -0,0 +1,15 @@
#import "TGMediaAttachment.h"
#import "LegacyComponentsInternal.h"
@implementation TGMediaAttachment
@synthesize type = _type;
@synthesize isMeta = _isMeta;
- (void)serialize:(NSMutableData *)__unused data
{
TGLog(@"***** TGMediaAttachment: default implementation not provided");
}
@end

View File

@@ -0,0 +1,285 @@
/*
* This is the source code of Telegram for iOS v. 1.1
* It is licensed under GNU GPL v. 2 or later.
* You should have received a copy of the license in this archive (see LICENSE).
*
* Copyright Peter Iakovlev, 2013.
*/
#import <Foundation/Foundation.h>
#import <LegacyComponents/TGActionMediaAttachment.h>
#import <LegacyComponents/TGMediaAttachment.h>
#import <LegacyComponents/TGImageMediaAttachment.h>
#import <LegacyComponents/TGLocationMediaAttachment.h>
#import <LegacyComponents/TGLocalMessageMetaMediaAttachment.h>
#import <LegacyComponents/TGVideoMediaAttachment.h>
#import <LegacyComponents/TGContactMediaAttachment.h>
#import <LegacyComponents/TGForwardedMessageMediaAttachment.h>
#import <LegacyComponents/TGUnsupportedMediaAttachment.h>
#import <LegacyComponents/TGDocumentMediaAttachment.h>
#import <LegacyComponents/TGAudioMediaAttachment.h>
#import <LegacyComponents/TGReplyMessageMediaAttachment.h>
#import <LegacyComponents/TGWebPageMediaAttachment.h>
#import <LegacyComponents/TGReplyMarkupAttachment.h>
#import <LegacyComponents/TGMessageEntitiesAttachment.h>
#import <LegacyComponents/TGBotContextResultAttachment.h>
#import <LegacyComponents/TGViaUserAttachment.h>
#import <LegacyComponents/TGGameMediaAttachment.h>
#import <LegacyComponents/TGInvoiceMediaAttachment.h>
#import <LegacyComponents/TGAuthorSignatureMediaAttachment.h>
#import <LegacyComponents/TGMessageViewCountContentProperty.h>
#import <LegacyComponents/TGBotReplyMarkup.h>
#import <LegacyComponents/PSCoding.h>
#import <LegacyComponents/TGMessageHole.h>
#import <LegacyComponents/TGMessageGroup.h>
typedef enum {
TGMessageDeliveryStateDelivered = 0,
TGMessageDeliveryStatePending = 1,
TGMessageDeliveryStateFailed = 2
} TGMessageDeliveryState;
#define TGMessageLocalMidBaseline 800000000
typedef struct {
uint8_t key[8 + 1 + 4 + 4];
} TGMessageSortKey;
typedef struct {
uint8_t key[8 + 4 + 4 + 1];
} TGMessageTransparentSortKey;
#define TGMessageSpaceUnimportant 0
#define TGMessageSpaceImportant 1
#define TGMessageSpaceUnimportantGroup 126
#define TGMessageSpaceHole 127
static inline TGMessageSortKey TGMessageSortKeyMake(int64_t peerId, uint8_t space, int32_t timestamp, int32_t mid) {
TGMessageSortKey key;
memcpy(key.key, &peerId, 8);
key.key[8] = space;
timestamp = NSSwapInt(timestamp);
memcpy(key.key + 8 + 1, &timestamp, 4);
mid = NSSwapInt(mid);
memcpy(key.key + 8 + 1 + 4, &mid, 4);
return key;
}
static inline TGMessageTransparentSortKey TGMessageTransparentSortKeyMake(int64_t peerId, int32_t timestamp, int32_t mid, uint8_t space) {
TGMessageTransparentSortKey key;
memcpy(key.key, &peerId, 8);
timestamp = NSSwapInt(timestamp);
memcpy(key.key + 8, &timestamp, 4);
mid = NSSwapInt(mid);
memcpy(key.key + 8 + 4, &mid, 4);
key.key[8 + 4 + 4] = space;
return key;
}
static inline TGMessageTransparentSortKey TGMessageTransparentSortKeyLowerBound(int64_t peerId) {
return TGMessageTransparentSortKeyMake(peerId, 0, 0, 0);
}
static inline TGMessageTransparentSortKey TGMessageTransparentSortKeyUpperBound(int64_t peerId) {
return TGMessageTransparentSortKeyMake(peerId, INT32_MAX, INT32_MAX, 127);
}
static inline TGMessageSortKey TGMessageSortKeyLowerBound(int64_t peerId, uint8_t space) {
return TGMessageSortKeyMake(peerId, space, 0, 0);
}
static inline TGMessageSortKey TGMessageSortKeyUpperBound(int64_t peerId, uint8_t space) {
return TGMessageSortKeyMake(peerId, space, INT32_MAX, INT32_MAX);
}
static inline TGMessageSortKey TGMessageSortKeyFromData(NSData *data) {
TGMessageSortKey key;
memcpy(key.key, data.bytes, 8 + 1 + 4 + 4);
return key;
}
static inline NSData *TGMessageSortKeyData(TGMessageSortKey key) {
return [NSData dataWithBytes:key.key length: 8 + 1 + 4 + 4];
}
static inline NSData *TGMessageTransparentSortKeyData(TGMessageTransparentSortKey key) {
return [NSData dataWithBytes:key.key length: 8 + 4 + 4 + 1];
}
static inline TGMessageTransparentSortKey TGMessageTransparentSortKeyFromData(NSData *data) {
TGMessageTransparentSortKey key;
memcpy(key.key, data.bytes, 8 + 4 + 4 + 1);
return key;
}
static inline int TGMessageSortKeyCompare(TGMessageSortKey lhs, TGMessageSortKey rhs) {
return memcmp(lhs.key, rhs.key, 8 + 1 + 4 + 4);
}
static inline int TGMessageTransparentSortKeyCompare(TGMessageTransparentSortKey lhs, TGMessageTransparentSortKey rhs) {
return memcmp(lhs.key, rhs.key, 8 + 4 + 4 + 1);
}
static inline int64_t TGMessageSortKeyPeerId(TGMessageSortKey key) {
int64_t peerId = 0;
memcpy(&peerId, key.key, 8);
return peerId;
}
static inline int64_t TGMessageTransparentSortKeyPeerId(TGMessageTransparentSortKey key) {
int64_t peerId = 0;
memcpy(&peerId, key.key, 8);
return peerId;
}
static inline uint8_t TGMessageSortKeySpace(TGMessageSortKey key) {
return key.key[8];
}
static inline uint8_t TGMessageTransparentSortKeySpace(TGMessageTransparentSortKey key) {
return key.key[8 + 4 + 4];
}
static inline int32_t TGMessageSortKeyTimestamp(TGMessageSortKey key) {
int32_t timestamp = 0;
memcpy(&timestamp, key.key + 8 + 1, 4);
return NSSwapInt(timestamp);
}
static inline int32_t TGMessageTransparentSortKeyTimestamp(TGMessageTransparentSortKey key) {
int32_t timestamp = 0;
memcpy(&timestamp, key.key + 8, 4);
return NSSwapInt(timestamp);
}
static inline int32_t TGMessageSortKeyMid(TGMessageSortKey key) {
int32_t mid = 0;
memcpy(&mid, key.key + 8 + 1 + 4, 4);
return NSSwapInt(mid);
}
static inline int32_t TGMessageTransparentSortKeyMid(TGMessageTransparentSortKey key) {
int32_t mid = 0;
memcpy(&mid, key.key + 8 + 4, 4);
return NSSwapInt(mid);
}
static inline NSData *TGTaggedMessageSortKeyData(int32_t tag, TGMessageSortKey key) {
uint8_t data[4 + 8 + 1 + 4 + 4];
memcpy(data, &tag, 4);
memcpy(data + 4, key.key, 8 + 1 + 4 + 4);
return [[NSData alloc] initWithBytes:data length:4 + 8 + 1 + 4 + 4];
}
static inline TGMessageSortKey TGTaggedMessageSortKeyExtract(NSData *data, int32_t *outTag) {
if (outTag != NULL) {
[data getBytes:(void *)outTag range:NSMakeRange(0, 4)];
}
TGMessageSortKey sortKey;
[data getBytes:sortKey.key range:NSMakeRange(4, 17)];
return sortKey;
}
@interface TGMessage : NSObject <NSCopying, PSCoding>
@property (nonatomic) int mid;
@property (nonatomic) TGMessageSortKey sortKey;
@property (nonatomic, readonly) TGMessageTransparentSortKey transparentSortKey;
@property (nonatomic) int32_t pts;
//@property (nonatomic, readonly) bool unread;
@property (nonatomic) bool hintUnread;
@property (nonatomic) bool outgoing;
@property (nonatomic) TGMessageDeliveryState deliveryState;
@property (nonatomic) int64_t fromUid;
@property (nonatomic) int64_t toUid;
@property (nonatomic) int64_t cid;
@property (nonatomic, copy) NSString *text;
@property (nonatomic) NSTimeInterval date;
@property (nonatomic, strong) NSArray *mediaAttachments;
@property (nonatomic) int32_t realDate;
@property (nonatomic) int64_t randomId;
@property (nonatomic, readonly) int64_t forwardPeerId;
@property (nonatomic) bool containsMention;
@property (nonatomic, strong) TGActionMediaAttachment *actionInfo;
@property (nonatomic, strong) NSArray *textCheckingResults;
@property (nonatomic) int32_t messageLifetime;
@property (nonatomic) int64_t flags;
@property (nonatomic) int32_t seqIn;
@property (nonatomic) int32_t seqOut;
@property (nonatomic) bool isBroadcast;
@property (nonatomic) NSUInteger layer;
@property (nonatomic, strong) TGBotReplyMarkup *replyMarkup;
@property (nonatomic) bool hideReplyMarkup;
@property (nonatomic) bool forceReply;
@property (nonatomic) bool isSilent;
@property (nonatomic) bool isEdited;
@property (nonatomic, strong) TGMessageViewCountContentProperty *viewCount;
@property (nonatomic, strong) NSArray *entities;
@property (nonatomic, strong, readonly) NSString *authorSignature;
@property (nonatomic, strong, readonly) NSString *forwardAuthorSignature;
@property (nonatomic, strong) NSDictionary *contentProperties;
@property (nonatomic, strong) TGMessageHole *hole;
@property (nonatomic, strong) TGMessageGroup *group;
- (NSArray *)effectiveTextAndEntities;
- (bool)local;
+ (void)registerMediaAttachmentParser:(int)type parser:(id<TGMediaAttachmentParser>)parser;
+ (NSArray *)textCheckingResultsForText:(NSString *)text highlightMentionsAndTags:(bool)highlightMentionsAndTags highlightCommands:(bool)highlightCommands entities:(NSArray *)entities;
+ (NSArray *)entitiesForMarkedUpText:(NSString *)text resultingText:(__autoreleasing NSString **)resultingText;
- (NSData *)serializeMediaAttachments:(bool)includeMeta;
+ (NSData *)serializeMediaAttachments:(bool)includeMeta attachments:(NSArray *)attachments;
+ (NSData *)serializeAttachment:(TGMediaAttachment *)attachment;
+ (NSArray *)parseMediaAttachments:(NSData *)data;
+ (NSUInteger)layerFromFlags:(int64_t)flags;
- (NSData *)serializeContentProperties;
+ (NSData *)serializeContentProperties:(NSDictionary *)contentProperties;
+ (NSDictionary *)parseContentProperties:(NSData *)data;
- (void)removeReplyAndMarkup;
- (void)filterOutExpiredMedia;
- (bool)hasExpiredMedia;
@end
@interface TGMediaId : NSObject <NSCopying>
@property (nonatomic, readonly) uint8_t type;
@property (nonatomic, readonly) int64_t itemId;
- (id)initWithType:(uint8_t)type itemId:(int64_t)itemId;
@end
@interface NSTextCheckingResult (TGMessage)
- (bool)isTelegramHiddenLink;
@end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
#import "TGMediaAttachment.h"
#import <LegacyComponents/TGMessageEntityUrl.h>
#import <LegacyComponents/TGMessageEntityEmail.h>
#import <LegacyComponents/TGMessageEntityTextUrl.h>
#import <LegacyComponents/TGMessageEntityMention.h>
#import <LegacyComponents/TGMessageEntityHashtag.h>
#import <LegacyComponents/TGMessageEntityBotCommand.h>
#import <LegacyComponents/TGMessageEntityBold.h>
#import <LegacyComponents/TGMessageEntityItalic.h>
#import <LegacyComponents/TGMessageEntityCode.h>
#import <LegacyComponents/TGMessageEntityPre.h>
#import <LegacyComponents/TGMessageEntityMentionName.h>
#define TGMessageEntitiesAttachmentType ((int)0x8C2E3CCE)
@interface TGMessageEntitiesAttachment : TGMediaAttachment <TGMediaAttachmentParser, NSCoding>
@property (nonatomic, strong) NSArray *entities;
@end

View File

@@ -0,0 +1,62 @@
#import "TGMessageEntitiesAttachment.h"
#import "LegacyComponentsInternal.h"
#import "PSKeyValueEncoder.h"
#import "PSKeyValueDecoder.h"
#import "NSInputStream+TL.h"
@implementation TGMessageEntitiesAttachment
- (instancetype)init
{
self = [super init];
if (self != nil)
{
self.type = TGMessageEntitiesAttachmentType;
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self != nil)
{
self.type = TGMessageEntitiesAttachmentType;
NSData *entitiesData = [aDecoder decodeObjectForKey:@"entitiesData"];
_entities = [[[PSKeyValueDecoder alloc] initWithData:entitiesData] decodeArrayForCKey:"_"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
PSKeyValueEncoder *encoder = [[PSKeyValueEncoder alloc] init];
[encoder encodeArray:_entities forCKey:"_"];
[aCoder encodeObject:[encoder data] forKey:@"entitiesData"];
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGMessageEntitiesAttachment class]] && TGObjectCompare(((TGMessageEntitiesAttachment *)object)->_entities, _entities);
}
- (void)serialize:(NSMutableData *)data
{
NSData *serializedData = [NSKeyedArchiver archivedDataWithRootObject:self];
int32_t length = (int32_t)serializedData.length;
[data appendBytes:&length length:4];
[data appendData:serializedData];
}
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
{
int32_t length = [is readInt32];
NSData *data = [is readData:length];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
@end

View File

@@ -0,0 +1,11 @@
#import <Foundation/Foundation.h>
#import <LegacyComponents/PSCoding.h>
@interface TGMessageEntity : NSObject <PSCoding, NSCoding>
@property (nonatomic, readonly) NSRange range;
- (instancetype)initWithRange:(NSRange)range;
@end

View File

@@ -0,0 +1,42 @@
#import "TGMessageEntity.h"
#import "PSKeyValueCoder.h"
@implementation TGMessageEntity
- (instancetype)initWithRange:(NSRange)range
{
self = [super init];
if (self != nil)
{
_range = range;
}
return self;
}
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
return [self initWithRange:NSMakeRange([coder decodeInt32ForCKey:"r.s"], [coder decodeInt32ForCKey:"r.l"])];
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeInt32:(int32_t)_range.location forCKey:"r.s"];
[coder encodeInt32:(int32_t)_range.length forCKey:"r.l"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
return [self initWithRange:NSMakeRange([aDecoder decodeInt32ForKey:@"r.s"], [aDecoder decodeInt32ForKey:@"r.l"])];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeInt32:(int32_t)_range.location forKey:@"r.s"];
[aCoder encodeInt32:(int32_t)_range.length forKey:@"r.l"];
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGMessageEntity class]] && ((TGMessageEntity *)object)->_range.location == _range.location && ((TGMessageEntity *)object)->_range.length == _range.length;
}
@end

View File

@@ -0,0 +1,5 @@
#import <LegacyComponents/TGMessageEntity.h>
@interface TGMessageEntityBold : TGMessageEntity
@end

View File

@@ -0,0 +1,10 @@
#import "TGMessageEntityBold.h"
@implementation TGMessageEntityBold
- (BOOL)isEqual:(id)object
{
return [super isEqual:object] && [object isKindOfClass:[TGMessageEntityBold class]];
}
@end

View File

@@ -0,0 +1,5 @@
#import <LegacyComponents/TGMessageEntity.h>
@interface TGMessageEntityBotCommand : TGMessageEntity
@end

View File

@@ -0,0 +1,10 @@
#import "TGMessageEntityBotCommand.h"
@implementation TGMessageEntityBotCommand
- (BOOL)isEqual:(id)object
{
return [super isEqual:object] && [object isKindOfClass:[TGMessageEntityBotCommand class]];
}
@end

View File

@@ -0,0 +1,5 @@
#import <LegacyComponents/TGMessageEntity.h>
@interface TGMessageEntityCode : TGMessageEntity
@end

View File

@@ -0,0 +1,10 @@
#import "TGMessageEntityCode.h"
@implementation TGMessageEntityCode
- (BOOL)isEqual:(id)object
{
return [super isEqual:object] && [object isKindOfClass:[TGMessageEntityCode class]];
}
@end

View File

@@ -0,0 +1,5 @@
#import <LegacyComponents/TGMessageEntity.h>
@interface TGMessageEntityEmail : TGMessageEntity
@end

Some files were not shown because too many files have changed in this diff Show More