Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2022-05-10 19:32:31 +04:00
commit ab0ec36112
87 changed files with 942 additions and 867 deletions

View file

@ -1070,7 +1070,7 @@ private final class NotificationServiceHandler {
if let resource = fetchResource {
if let _ = strongSelf.stateManager?.postbox.mediaBox.completedResourcePath(resource) {
} else {
let intervals: Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError> = .single([(0 ..< Int(Int32.max), MediaBoxFetchPriority.maximum)])
let intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError> = .single([(0 ..< Int64.max, MediaBoxFetchPriority.maximum)])
fetchMediaSignal = Signal { subscriber in
let collectedData = Atomic<Data>(value: Data())
return standaloneMultipartFetch(
@ -1121,7 +1121,7 @@ private final class NotificationServiceHandler {
if let path = strongSelf.stateManager?.postbox.mediaBox.completedResourcePath(resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path)) {
fetchNotificationSoundSignal = .single(data)
} else {
let intervals: Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError> = .single([(0 ..< Int(Int32.max), MediaBoxFetchPriority.maximum)])
let intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError> = .single([(0 ..< Int64.max, MediaBoxFetchPriority.maximum)])
fetchNotificationSoundSignal = Signal { subscriber in
let collectedData = Atomic<Data>(value: Data())
return standaloneMultipartFetch(

View file

@ -46,15 +46,15 @@ public func messageMediaFileCancelInteractiveFetch(context: AccountContext, mess
context.fetchManager.cancelInteractiveFetches(category: fetchCategoryForFile(file), location: .chat(messageId.peerId), locationKey: .messageId(messageId), resource: file.resource)
}
public func messageMediaImageInteractiveFetched(context: AccountContext, message: Message, image: TelegramMediaImage, resource: MediaResource, range: Range<Int>? = nil, userInitiated: Bool = true, storeToDownloadsPeerType: MediaAutoDownloadPeerType?) -> Signal<Void, NoError> {
public func messageMediaImageInteractiveFetched(context: AccountContext, message: Message, image: TelegramMediaImage, resource: MediaResource, range: Range<Int64>? = nil, userInitiated: Bool = true, storeToDownloadsPeerType: MediaAutoDownloadPeerType?) -> Signal<Void, NoError> {
return messageMediaImageInteractiveFetched(fetchManager: context.fetchManager, messageId: message.id, messageReference: MessageReference(message), image: image, resource: resource, range: range, userInitiated: userInitiated, priority: .userInitiated, storeToDownloadsPeerType: storeToDownloadsPeerType)
}
public func messageMediaImageInteractiveFetched(fetchManager: FetchManager, messageId: MessageId, messageReference: MessageReference, image: TelegramMediaImage, resource: MediaResource, range: Range<Int>? = nil, userInitiated: Bool, priority: FetchManagerPriority, storeToDownloadsPeerType: MediaAutoDownloadPeerType?) -> Signal<Void, NoError> {
public func messageMediaImageInteractiveFetched(fetchManager: FetchManager, messageId: MessageId, messageReference: MessageReference, image: TelegramMediaImage, resource: MediaResource, range: Range<Int64>? = nil, userInitiated: Bool, priority: FetchManagerPriority, storeToDownloadsPeerType: MediaAutoDownloadPeerType?) -> Signal<Void, NoError> {
let mediaReference = AnyMediaReference.message(message: messageReference, media: image)
let ranges: IndexSet
if let range = range {
ranges = IndexSet(integersIn: range)
ranges = IndexSet(integersIn: Int(range.lowerBound) ..< Int(range.upperBound))
} else {
ranges = FetchCompleteRange
}

View file

@ -200,7 +200,7 @@ public protocol UniversalVideoManager: AnyObject {
func addPlaybackCompleted(id: AnyHashable, _ f: @escaping () -> Void) -> Int
func removePlaybackCompleted(id: AnyHashable, index: Int)
func statusSignal(content: UniversalVideoContent) -> Signal<MediaPlayerStatus?, NoError>
func bufferingStatusSignal(content: UniversalVideoContent) -> Signal<(IndexSet, Int)?, NoError>
func bufferingStatusSignal(content: UniversalVideoContent) -> Signal<(IndexSet, Int64)?, NoError>
}
public enum AudioRecordingState: Equatable {

View file

@ -12,7 +12,7 @@ import AVFoundation
public protocol UniversalVideoContentNode: AnyObject {
var ready: Signal<Void, NoError> { get }
var status: Signal<MediaPlayerStatus, NoError> { get }
var bufferingStatus: Signal<(IndexSet, Int)?, NoError> { get }
var bufferingStatus: Signal<(IndexSet, Int64)?, NoError> { get }
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition)
@ -105,8 +105,8 @@ public final class UniversalVideoNode: ASDisplayNode {
return self._status.get()
}
private let _bufferingStatus = Promise<(IndexSet, Int)?>()
public var bufferingStatus: Signal<(IndexSet, Int)?, NoError> {
private let _bufferingStatus = Promise<(IndexSet, Int64)?>()
public var bufferingStatus: Signal<(IndexSet, Int64)?, NoError> {
return self._bufferingStatus.get()
}

View file

@ -61,7 +61,7 @@ private final class ImportManager {
}
enum State {
case progress(totalBytes: Int, totalUploadedBytes: Int, totalMediaBytes: Int, totalUploadedMediaBytes: Int)
case progress(totalBytes: Int64, totalUploadedBytes: Int64, totalMediaBytes: Int64, totalUploadedMediaBytes: Int64)
case error(ImportError)
case done
}
@ -74,11 +74,11 @@ private final class ImportManager {
private let disposable = MetaDisposable()
private let totalBytes: Int
private let totalMediaBytes: Int
private let mainFileSize: Int
private let totalBytes: Int64
private let totalMediaBytes: Int64
private let mainFileSize: Int64
private var pendingEntries: [(SSZipEntry, String, TelegramEngine.HistoryImport.MediaType)]
private var entryProgress: [String: (Int, Int)] = [:]
private var entryProgress: [String: (Int64, Int64)] = [:]
private var activeEntries: [String: Disposable] = [:]
private var stateValue: State {
@ -99,10 +99,10 @@ private final class ImportManager {
self.mainFileSize = fileSize(mainFile.path) ?? 0
var totalMediaBytes = 0
var totalMediaBytes: Int64 = 0
for entry in self.entries {
self.entryProgress[entry.1] = (Int(entry.0.uncompressedSize), 0)
totalMediaBytes += Int(entry.0.uncompressedSize)
self.entryProgress[entry.1] = (Int64(entry.0.uncompressedSize), 0)
totalMediaBytes += Int64(entry.0.uncompressedSize)
}
self.totalBytes = self.mainFileSize + totalMediaBytes
self.totalMediaBytes = totalMediaBytes
@ -155,7 +155,7 @@ private final class ImportManager {
return
}
var totalUploadedMediaBytes = 0
var totalUploadedMediaBytes: Int64 = 0
for (_, entrySizes) in self.entryProgress {
totalUploadedMediaBytes += entrySizes.1
}
@ -278,7 +278,7 @@ private final class ImportManager {
return
}
if let (size, _) = strongSelf.entryProgress[entry.1] {
strongSelf.entryProgress[entry.1] = (size, Int(progress * Float(entry.0.uncompressedSize)))
strongSelf.entryProgress[entry.1] = (size, Int64(progress * Float(entry.0.uncompressedSize)))
strongSelf.updateProgress()
}
}, error: { [weak self] error in
@ -321,7 +321,7 @@ public final class ChatImportActivityScreen: ViewController {
private var validLayout: (ContainerViewLayout, CGFloat)?
private let totalBytes: Int
private let totalBytes: Int64
private var state: ImportManager.State
private var videoNode: UniversalVideoNode?
@ -329,7 +329,7 @@ public final class ChatImportActivityScreen: ViewController {
fileprivate var remainingAnimationSeconds: Double?
init(controller: ChatImportActivityScreen, context: AccountContext, totalBytes: Int, totalMediaBytes: Int) {
init(controller: ChatImportActivityScreen, context: AccountContext, totalBytes: Int64, totalMediaBytes: Int64) {
self.controller = controller
self.context = context
self.totalBytes = totalBytes
@ -727,8 +727,8 @@ public final class ChatImportActivityScreen: ViewController {
fileprivate var peerId: PeerId
private let archivePath: String?
private let mainEntry: TempBoxFile
private let totalBytes: Int
private let totalMediaBytes: Int
private let totalBytes: Int64
private let totalMediaBytes: Int64
private let otherEntries: [(SSZipEntry, String, TelegramEngine.HistoryImport.MediaType)]
private var importManager: ImportManager?
@ -759,9 +759,9 @@ public final class ChatImportActivityScreen: ViewController {
let mainEntrySize = fileSize(self.mainEntry.path) ?? 0
var totalMediaBytes = 0
var totalMediaBytes: Int64 = 0
for entry in self.otherEntries {
totalMediaBytes += Int(entry.0.uncompressedSize)
totalMediaBytes += Int64(entry.0.uncompressedSize)
}
self.totalBytes = mainEntrySize + totalMediaBytes
self.totalMediaBytes = totalMediaBytes

View file

@ -614,7 +614,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
var totalBytes = 0.0
var totalProgressInBytes = 0.0
for (entry, progress) in entries {
var size = 1024 * 1024 * 1024
var size: Int64 = 1024 * 1024 * 1024
if let sizeValue = entry.resourceReference.resource.size {
size = sizeValue
}

View file

@ -47,14 +47,14 @@ final class ChatListSearchInteraction {
let clearRecentSearch: () -> Void
let addContact: (String) -> Void
let toggleMessageSelection: (EngineMessage.Id, Bool) -> Void
let messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int, isFirstInList: Bool)?) -> Void)
let messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void)
let mediaMessageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?) -> Void)
let peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?) -> Void)?
let present: (ViewController, Any?) -> Void
let dismissInput: () -> Void
let getSelectedMessageIds: () -> Set<EngineMessage.Id>?
init(openPeer: @escaping (EnginePeer, EnginePeer?, Bool) -> Void, openDisabledPeer: @escaping (EnginePeer) -> Void, openMessage: @escaping (EnginePeer, EngineMessage.Id, Bool) -> Void, openUrl: @escaping (String) -> Void, clearRecentSearch: @escaping () -> Void, addContact: @escaping (String) -> Void, toggleMessageSelection: @escaping (EngineMessage.Id, Bool) -> Void, messageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int, isFirstInList: Bool)?) -> Void), mediaMessageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?) -> Void), peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, getSelectedMessageIds: @escaping () -> Set<EngineMessage.Id>?) {
init(openPeer: @escaping (EnginePeer, EnginePeer?, Bool) -> Void, openDisabledPeer: @escaping (EnginePeer) -> Void, openMessage: @escaping (EnginePeer, EngineMessage.Id, Bool) -> Void, openUrl: @escaping (String) -> Void, clearRecentSearch: @escaping () -> Void, addContact: @escaping (String) -> Void, toggleMessageSelection: @escaping (EngineMessage.Id, Bool) -> Void, messageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void), mediaMessageContextAction: @escaping ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?) -> Void), peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?) -> Void)?, present: @escaping (ViewController, Any?) -> Void, dismissInput: @escaping () -> Void, getSelectedMessageIds: @escaping () -> Set<EngineMessage.Id>?) {
self.openPeer = openPeer
self.openDisabledPeer = openDisabledPeer
self.openMessage = openMessage
@ -771,7 +771,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
let _ = self.paneContainerNode.scrollToTop()
}
private func messageContextAction(_ message: EngineMessage, node: ASDisplayNode?, rect: CGRect?, gesture anyRecognizer: UIGestureRecognizer?, paneKey: ChatListSearchPaneKey, downloadResource: (id: String, size: Int, isFirstInList: Bool)?) {
private func messageContextAction(_ message: EngineMessage, node: ASDisplayNode?, rect: CGRect?, gesture anyRecognizer: UIGestureRecognizer?, paneKey: ChatListSearchPaneKey, downloadResource: (id: String, size: Int64, isFirstInList: Bool)?) {
guard let node = node as? ContextExtractedContentContainingNode else {
return
}

View file

@ -278,7 +278,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
case recentlySearchedPeer(EnginePeer, EnginePeer?, (Int32, Bool)?, Int, PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder)
case localPeer(EnginePeer, EnginePeer?, (Int32, Bool)?, Int, PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, ChatListSearchSectionExpandType)
case globalPeer(FoundPeer, (Int32, Bool)?, Int, PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder, ChatListSearchSectionExpandType)
case message(EngineMessage, EngineRenderedPeer, EnginePeerReadCounters?, ChatListPresentationData, Int32, Bool?, Bool, MessageOrderingKey, (id: String, size: Int, isFirstInList: Bool)?, MessageSection, Bool)
case message(EngineMessage, EngineRenderedPeer, EnginePeerReadCounters?, ChatListPresentationData, Int32, Bool?, Bool, MessageOrderingKey, (id: String, size: Int64, isFirstInList: Bool)?, MessageSection, Bool)
case addContact(String, PresentationTheme, PresentationStrings)
public var stableId: ChatListSearchEntryStableId {
@ -418,7 +418,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
}
}
public func item(context: AccountContext, presentationData: PresentationData, enableHeaders: Bool, filter: ChatListNodePeersFilter, key: ChatListSearchPaneKey, tagMask: EngineMessage.Tags?, interaction: ChatListNodeInteraction, listInteraction: ListMessageItemInteraction, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?) -> Void)?, toggleExpandLocalResults: @escaping () -> Void, toggleExpandGlobalResults: @escaping () -> Void, searchPeer: @escaping (EnginePeer) -> Void, searchQuery: String?, searchOptions: ChatListSearchOptions?, messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int, isFirstInList: Bool)?) -> Void)?, openClearRecentlyDownloaded: @escaping () -> Void, toggleAllPaused: @escaping () -> Void) -> ListViewItem {
public func item(context: AccountContext, presentationData: PresentationData, enableHeaders: Bool, filter: ChatListNodePeersFilter, key: ChatListSearchPaneKey, tagMask: EngineMessage.Tags?, interaction: ChatListNodeInteraction, listInteraction: ListMessageItemInteraction, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?) -> Void)?, toggleExpandLocalResults: @escaping () -> Void, toggleExpandGlobalResults: @escaping () -> Void, searchPeer: @escaping (EnginePeer) -> Void, searchQuery: String?, searchOptions: ChatListSearchOptions?, messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void)?, openClearRecentlyDownloaded: @escaping () -> Void, toggleAllPaused: @escaping () -> Void) -> ListViewItem {
switch self {
case let .recentlySearchedPeer(peer, associatedPeer, unreadBadge, _, theme, strings, nameSortOrder, nameDisplayOrder):
let primaryPeer: EnginePeer
@ -720,7 +720,7 @@ private func chatListSearchContainerPreparedRecentTransition(from fromEntries: [
return ChatListSearchContainerRecentTransition(deletions: deletions, insertions: insertions, updates: updates)
}
public func chatListSearchContainerPreparedTransition(from fromEntries: [ChatListSearchEntry], to toEntries: [ChatListSearchEntry], displayingResults: Bool, isEmpty: Bool, isLoading: Bool, animated: Bool, context: AccountContext, presentationData: PresentationData, enableHeaders: Bool, filter: ChatListNodePeersFilter, key: ChatListSearchPaneKey, tagMask: EngineMessage.Tags?, interaction: ChatListNodeInteraction, listInteraction: ListMessageItemInteraction, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?) -> Void)?, toggleExpandLocalResults: @escaping () -> Void, toggleExpandGlobalResults: @escaping () -> Void, searchPeer: @escaping (EnginePeer) -> Void, searchQuery: String?, searchOptions: ChatListSearchOptions?, messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int, isFirstInList: Bool)?) -> Void)?, openClearRecentlyDownloaded: @escaping () -> Void, toggleAllPaused: @escaping () -> Void) -> ChatListSearchContainerTransition {
public func chatListSearchContainerPreparedTransition(from fromEntries: [ChatListSearchEntry], to toEntries: [ChatListSearchEntry], displayingResults: Bool, isEmpty: Bool, isLoading: Bool, animated: Bool, context: AccountContext, presentationData: PresentationData, enableHeaders: Bool, filter: ChatListNodePeersFilter, key: ChatListSearchPaneKey, tagMask: EngineMessage.Tags?, interaction: ChatListNodeInteraction, listInteraction: ListMessageItemInteraction, peerContextAction: ((EnginePeer, ChatListSearchContextActionSource, ASDisplayNode, ContextGesture?) -> Void)?, toggleExpandLocalResults: @escaping () -> Void, toggleExpandGlobalResults: @escaping () -> Void, searchPeer: @escaping (EnginePeer) -> Void, searchQuery: String?, searchOptions: ChatListSearchOptions?, messageContextAction: ((EngineMessage, ASDisplayNode?, CGRect?, UIGestureRecognizer?, ChatListSearchPaneKey, (id: String, size: Int64, isFirstInList: Bool)?) -> Void)?, openClearRecentlyDownloaded: @escaping () -> Void, toggleAllPaused: @escaping () -> Void) -> ChatListSearchContainerTransition {
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
@ -1149,7 +1149,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
}
}
var resource: (id: String, size: Int, isFirstInList: Bool)?
var resource: (id: String, size: Int64, isFirstInList: Bool)?
if let resourceValue = findMediaResourceById(message: item.message, resourceId: item.resourceId), let size = resourceValue.size {
resource = (resourceValue.id.stringRepresentation, size, entries.isEmpty)
}
@ -1784,7 +1784,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
return
}
var fetchResourceId: (id: String, size: Int, isFirstInList: Bool)?
var fetchResourceId: (id: String, size: Int64, isFirstInList: Bool)?
for entry in currentEntries {
switch entry {
case let .message(m, _, _, _, _, _, _, _, resource, _, _):

View file

@ -274,10 +274,10 @@ private enum DebugControllerEntry: ItemListNodeEntry {
TempBox.shared.dispose(tempZip)
let id = Int64.random(in: Int64.min ... Int64.max)
let fileResource = LocalFileMediaResource(fileId: id, size: gzippedData.count, isSecretRelated: false)
let fileResource = LocalFileMediaResource(fileId: id, size: Int64(gzippedData.count), isSecretRelated: false)
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: gzippedData.count, attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
@ -354,10 +354,10 @@ private enum DebugControllerEntry: ItemListNodeEntry {
}
let id = Int64.random(in: Int64.min ... Int64.max)
let fileResource = LocalFileMediaResource(fileId: id, size: logData.count, isSecretRelated: false)
let fileResource = LocalFileMediaResource(fileId: id, size: Int64(logData.count), isSecretRelated: false)
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: logData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: logData.count, attributes: [.FileName(fileName: "Log-iOS-Short.txt")])
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(logData.count), attributes: [.FileName(fileName: "Log-iOS-Short.txt")])
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
@ -440,10 +440,10 @@ private enum DebugControllerEntry: ItemListNodeEntry {
TempBox.shared.dispose(tempZip)
let id = Int64.random(in: Int64.min ... Int64.max)
let fileResource = LocalFileMediaResource(fileId: id, size: gzippedData.count, isSecretRelated: false)
let fileResource = LocalFileMediaResource(fileId: id, size: Int64(gzippedData.count), isSecretRelated: false)
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: gzippedData.count, attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
@ -524,10 +524,10 @@ private enum DebugControllerEntry: ItemListNodeEntry {
TempBox.shared.dispose(tempZip)
let id = Int64.random(in: Int64.min ... Int64.max)
let fileResource = LocalFileMediaResource(fileId: id, size: gzippedData.count, isSecretRelated: false)
let fileResource = LocalFileMediaResource(fileId: id, size: Int64(gzippedData.count), isSecretRelated: false)
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: gzippedData.count, attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
@ -608,10 +608,10 @@ private enum DebugControllerEntry: ItemListNodeEntry {
TempBox.shared.dispose(tempZip)
let id = Int64.random(in: Int64.min ... Int64.max)
let fileResource = LocalFileMediaResource(fileId: id, size: gzippedData.count, isSecretRelated: false)
let fileResource = LocalFileMediaResource(fileId: id, size: Int64(gzippedData.count), isSecretRelated: false)
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: gzippedData.count, attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()
@ -1234,10 +1234,10 @@ public func triggerDebugSendLogsUI(context: AccountContext, additionalInfo: Stri
TempBox.shared.dispose(tempZip)
let id = Int64.random(in: Int64.min ... Int64.max)
let fileResource = LocalFileMediaResource(fileId: id, size: gzippedData.count, isSecretRelated: false)
let fileResource = LocalFileMediaResource(fileId: id, size: Int64(gzippedData.count), isSecretRelated: false)
context.account.postbox.mediaBox.storeResourceData(fileResource.id, data: gzippedData)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: gzippedData.count, attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: id), partialReference: nil, resource: fileResource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "application/text", size: Int64(gzippedData.count), attributes: [.FileName(fileName: "Log-iOS-Full.txt.zip")])
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [message]).start()

View file

@ -184,7 +184,7 @@ public final class DirectMediaImageCache {
return self.account.postbox.mediaBox.cachedRepresentationPathForId(resourceId.stringRepresentation, representationId: representationId, keepDuration: .general)
}
private func getLoadSignal(width: Int, resource: MediaResourceReference, resourceSizeLimit: Int) -> Signal<UIImage?, NoError>? {
private func getLoadSignal(width: Int, resource: MediaResourceReference, resourceSizeLimit: Int64) -> Signal<UIImage?, NoError>? {
return Signal { subscriber in
let cachePath = self.getCachePath(resourceId: resource.resource.id, imageType: .square(width: width))
@ -199,7 +199,7 @@ public final class DirectMediaImageCache {
).start()
let dataSignal: Signal<Data?, NoError>
if resourceSizeLimit < Int(Int32.max) {
if resourceSizeLimit < Int(Int64.max) {
dataSignal = self.account.postbox.mediaBox.resourceData(resource.resource, size: resourceSizeLimit, in: 0 ..< resourceSizeLimit)
|> map { data, _ -> Data? in
return data
@ -239,44 +239,44 @@ public final class DirectMediaImageCache {
}
}
private func getProgressiveSize(mediaReference: AnyMediaReference, width: Int, representations: [TelegramMediaImageRepresentation]) -> (resource: MediaResourceReference, size: Int)? {
private func getProgressiveSize(mediaReference: AnyMediaReference, width: Int, representations: [TelegramMediaImageRepresentation]) -> (resource: MediaResourceReference, size: Int64)? {
if let representation = representations.first(where: { !$0.progressiveSizes.isEmpty }) {
let selectedSize: Int32
let selectedSize: Int64
let progressiveSizes = representation.progressiveSizes
if progressiveSizes.count > 0 && width <= 64 {
selectedSize = progressiveSizes[0]
selectedSize = Int64(progressiveSizes[0])
} else if progressiveSizes.count > 2 && width <= 160 {
selectedSize = progressiveSizes[2]
selectedSize = Int64(progressiveSizes[2])
} else if progressiveSizes.count > 4 && width <= 400 {
selectedSize = progressiveSizes[4]
selectedSize = Int64(progressiveSizes[4])
} else {
selectedSize = Int32.max
selectedSize = Int64.max
}
return (mediaReference.resourceReference(representation.resource), Int(selectedSize))
return (mediaReference.resourceReference(representation.resource), selectedSize)
} else {
for representation in representations.sorted(by: { $0.dimensions.width < $1.dimensions.width }) {
if Int(Float(representation.dimensions.width) * 1.2) >= width {
return (mediaReference.resourceReference(representation.resource), Int(Int32.max))
return (mediaReference.resourceReference(representation.resource), Int64.max)
}
}
if let representation = representations.last {
return (mediaReference.resourceReference(representation.resource), Int(Int32.max))
return (mediaReference.resourceReference(representation.resource), Int64.max)
}
return nil
}
}
private func getResource(message: Message, image: TelegramMediaImage, width: Int) -> (resource: MediaResourceReference, size: Int)? {
private func getResource(message: Message, image: TelegramMediaImage, width: Int) -> (resource: MediaResourceReference, size: Int64)? {
return self.getProgressiveSize(mediaReference: MediaReference.message(message: MessageReference(message), media: image).abstract, width: width, representations: image.representations)
}
private func getResource(message: Message, file: TelegramMediaFile, width: Int) -> (resource: MediaResourceReference, size: Int)? {
private func getResource(message: Message, file: TelegramMediaFile, width: Int) -> (resource: MediaResourceReference, size: Int64)? {
return self.getProgressiveSize(mediaReference: MediaReference.message(message: MessageReference(message), media: file).abstract, width: width, representations: file.previewRepresentations)
}
private func getImageSynchronous(message: Message, media: Media, width: Int, possibleWidths: [Int]) -> GetMediaResult? {
var immediateThumbnailData: Data?
var resource: (resource: MediaResourceReference, size: Int)?
var resource: (resource: MediaResourceReference, size: Int64)?
if let image = media as? TelegramMediaImage {
immediateThumbnailData = image.immediateThumbnailData
resource = self.getResource(message: message, image: image, width: width)

View file

@ -49,7 +49,7 @@ private final class FetchManagerLocationEntry {
var combinedRanges: IndexSet {
var result = IndexSet()
if self.userInitiated {
result.insert(integersIn: 0 ..< Int(Int32.max))
result.insert(integersIn: 0 ..< Int(Int64.max))
} else {
for range in self.ranges.copyItems() {
result.formUnion(range)
@ -220,13 +220,13 @@ private final class FetchManagerCategoryContext {
activeContext.ranges = ranges
let entryCompleted = self.entryCompleted
let storeManager = self.storeManager
let parsedRanges: [(Range<Int>, MediaBoxFetchPriority)]?
if ranges.count == 1 && ranges.min() == 0 && ranges.max() == Int(Int32.max) {
let parsedRanges: [(Range<Int64>, MediaBoxFetchPriority)]?
if ranges.count == 1 && ranges.min() == 0 && ranges.max() == Int(Int64.max) {
parsedRanges = nil
} else {
var resultRanges: [(Range<Int>, MediaBoxFetchPriority)] = []
var resultRanges: [(Range<Int64>, MediaBoxFetchPriority)] = []
for range in ranges.rangeView {
resultRanges.append((range, .default))
resultRanges.append((Int64(range.lowerBound) ..< Int64(range.upperBound), .default))
}
parsedRanges = resultRanges
}
@ -302,14 +302,14 @@ private final class FetchManagerCategoryContext {
if let entry = self.entries[topEntryId] {
let ranges = entry.combinedRanges
let parsedRanges: [(Range<Int>, MediaBoxFetchPriority)]?
let parsedRanges: [(Range<Int64>, MediaBoxFetchPriority)]?
var count = 0
var isCompleteRange = false
var isVideoPreload = false
for range in ranges.rangeView {
count += 1
if range.lowerBound == 0 && range.upperBound == Int(Int32.max) {
if range.lowerBound == 0 && range.upperBound == Int(Int64.max) {
isCompleteRange = true
}
}
@ -321,9 +321,9 @@ private final class FetchManagerCategoryContext {
if count == 1 && isCompleteRange {
parsedRanges = nil
} else {
var resultRanges: [(Range<Int>, MediaBoxFetchPriority)] = []
var resultRanges: [(Range<Int64>, MediaBoxFetchPriority)] = []
for range in ranges.rangeView {
resultRanges.append((range, .default))
resultRanges.append((Int64(range.lowerBound) ..< Int64(range.upperBound), .default))
}
parsedRanges = resultRanges
}

View file

@ -255,11 +255,11 @@ final class ChatVideoGalleryItemScrubberView: UIView {
}))
}
func setBufferingStatusSignal(_ status: Signal<(IndexSet, Int)?, NoError>?) {
func setBufferingStatusSignal(_ status: Signal<(IndexSet, Int64)?, NoError>?) {
self.scrubberNode.bufferingStatus = status
}
func setFetchStatusSignal(_ fetchStatus: Signal<MediaResourceStatus, NoError>?, strings: PresentationStrings, decimalSeparator: String, fileSize: Int?) {
func setFetchStatusSignal(_ fetchStatus: Signal<MediaResourceStatus, NoError>?, strings: PresentationStrings, decimalSeparator: String, fileSize: Int64?) {
let formatting = DataSizeStringFormatting(strings: strings, decimalSeparator: decimalSeparator)
if let fileSize = fileSize {
if let fetchStatus = fetchStatus {

View file

@ -71,9 +71,9 @@ public final class LegacyLiveUploadInterface: VideoConversionWatcher, TGLiveUplo
let result = strongSelf.dataValue.modify { dataValue in
if let dataValue = dataValue, dataValue.complete {
return MediaResourceData(path: path, offset: 0, size: size, complete: true)
return MediaResourceData(path: path, offset: 0, size: Int64(size), complete: true)
} else {
return MediaResourceData(path: path, offset: 0, size: size, complete: false)
return MediaResourceData(path: path, offset: 0, size: Int64(size), complete: false)
}
}
if let result = result {

View file

@ -134,7 +134,7 @@ public func fetchPhotoLibraryResource(localIdentifier: String) -> Signal<MediaRe
#if DEBUG
print("compression completion \((CACurrentMediaTime() - startTime) * 1000.0) ms")
#endif
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< data.count, complete: true))
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< Int64(data.count), complete: true))
subscriber.putCompletion()
} else {
subscriber.putCompletion()

View file

@ -96,6 +96,10 @@ public final class VideoLibraryMediaResource: TelegramMediaResource {
public let localIdentifier: String
public let conversion: VideoLibraryMediaResourceConversion
public var size: Int64? {
return nil
}
public var headerSize: Int32 {
return 32 * 1024
}
@ -148,6 +152,10 @@ public struct LocalFileVideoMediaResourceId {
}
public final class LocalFileVideoMediaResource: TelegramMediaResource {
public var size: Int64? {
return nil
}
public let randomId: Int64
public let path: String
public let adjustments: VideoMediaResourceAdjustments?
@ -209,6 +217,10 @@ public struct PhotoLibraryMediaResourceId {
}
public class PhotoLibraryMediaResource: TelegramMediaResource {
public var size: Int64? {
return nil
}
public let localIdentifier: String
public let uniqueId: Int64
@ -253,6 +265,10 @@ public struct LocalFileGifMediaResourceId {
}
public final class LocalFileGifMediaResource: TelegramMediaResource {
public var size: Int64? {
return nil
}
public let randomId: Int64
public let path: String
@ -302,6 +318,10 @@ public struct BundleResourceId {
}
public class BundleResource: TelegramMediaResource {
public var size: Int64? {
return nil
}
public let nameHash: Int64
public let path: String

View file

@ -97,13 +97,13 @@ public final class ManagedFile {
ftruncate(self.fd, count)
}
public func getSize() -> Int? {
public func getSize() -> Int64? {
if let queue = self.queue {
assert(queue.isCurrent())
}
var value = stat()
if fstat(self.fd, &value) == 0 {
return Int(value.st_size)
return value.st_size
} else {
return nil
}

View file

@ -71,14 +71,14 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
print("maxOffset \(maxOffset)")
#endif*/
let resourceSize: Int = resourceReference.resource.size ?? Int(Int32.max - 1)
let readCount = max(0, min(resourceSize - context.readingOffset, Int(bufferSize)))
let requestRange: Range<Int> = context.readingOffset ..< (context.readingOffset + readCount)
let resourceSize: Int64 = resourceReference.resource.size ?? (Int64.max - 1)
let readCount = max(0, min(resourceSize - context.readingOffset, Int64(bufferSize)))
let requestRange: Range<Int64> = context.readingOffset ..< (context.readingOffset + readCount)
assert(readCount < 16 * 1024 * 1024)
if let maximumFetchSize = context.maximumFetchSize {
context.touchedRanges.insert(integersIn: requestRange)
context.touchedRanges.insert(integersIn: Int(requestRange.lowerBound) ..< Int(requestRange.upperBound))
var totalCount = 0
for range in context.touchedRanges.rangeView {
totalCount += range.count
@ -95,7 +95,7 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
if readCount == 0 {
fetchedData = Data()
} else {
if let tempFilePath = context.tempFilePath, let fileData = (try? Data(contentsOf: URL(fileURLWithPath: tempFilePath), options: .mappedRead))?.subdata(in: requestRange) {
if let tempFilePath = context.tempFilePath, let fileData = (try? Data(contentsOf: URL(fileURLWithPath: tempFilePath), options: .mappedRead))?.subdata(in: Int(requestRange.lowerBound) ..< Int(requestRange.upperBound)) {
fetchedData = fileData
} else {
let semaphore = DispatchSemaphore(value: 0)
@ -124,15 +124,15 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
let fd = open(tempFilePath, O_RDONLY, S_IRUSR)
if fd >= 0 {
let readingOffset = context.readingOffset
let readCount = max(0, min(fileSize - readingOffset, Int(bufferSize)))
let readCount = max(0, min(fileSize - readingOffset, Int64(bufferSize)))
let range = readingOffset ..< (readingOffset + readCount)
assert(readCount < 16 * 1024 * 1024)
lseek(fd, off_t(range.lowerBound), SEEK_SET)
var data = Data(count: readCount)
var data = Data(count: Int(readCount))
data.withUnsafeMutableBytes { bytes -> Void in
precondition(bytes.baseAddress != nil)
let readBytes = read(fd, bytes.baseAddress, readCount)
let readBytes = read(fd, bytes.baseAddress, Int(readCount))
precondition(readBytes <= readCount)
}
fetchedData = data
@ -146,7 +146,7 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
var completedRequest = false
let disposable = data.start(next: { next in
if next.complete {
let readCount = max(0, min(next.size - readingOffset, Int(bufferSize)))
let readCount = max(0, min(next.size - readingOffset, Int64(bufferSize)))
let range = readingOffset ..< (readingOffset + readCount)
assert(readCount < 16 * 1024 * 1024)
@ -154,10 +154,10 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
let fd = open(next.path, O_RDONLY, S_IRUSR)
if fd >= 0 {
lseek(fd, off_t(range.lowerBound), SEEK_SET)
var data = Data(count: readCount)
var data = Data(count: Int(readCount))
data.withUnsafeMutableBytes { bytes -> Void in
precondition(bytes.baseAddress != nil)
let readBytes = read(fd, bytes.baseAddress, readCount)
let readBytes = read(fd, bytes.baseAddress, Int(readCount))
assert(readBytes <= readCount)
precondition(readBytes <= readCount)
}
@ -181,10 +181,10 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
assert(fetchedData.count <= readCount)
fetchedData.withUnsafeBytes { bytes -> Void in
precondition(bytes.baseAddress != nil)
memcpy(buffer, bytes.baseAddress, min(fetchedData.count, readCount))
memcpy(buffer, bytes.baseAddress, min(fetchedData.count, Int(readCount)))
}
fetchedCount = Int32(fetchedData.count)
context.readingOffset += Int(fetchedCount)
context.readingOffset += Int64(fetchedCount)
}
if context.closed {
@ -202,7 +202,7 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
var result: Int64 = offset
let resourceSize: Int
let resourceSize: Int64
if let size = resourceReference.resource.size {
resourceSize = size
} else {
@ -210,14 +210,14 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
if let tempFilePath = context.tempFilePath, let fileSize = fileSize(tempFilePath) {
resourceSize = fileSize
} else {
var resultSize: Int = Int(Int32.max - 1)
var resultSize: Int64 = Int64.max - 1
let data = postbox.mediaBox.resourceData(resourceReference.resource, pathExtension: nil, option: .complete(waitUntilFetchStatus: false))
let semaphore = DispatchSemaphore(value: 0)
let _ = context.currentSemaphore.swap(semaphore)
var completedRequest = false
let disposable = data.start(next: { next in
if next.complete {
resultSize = Int(next.size)
resultSize = next.size
completedRequest = true
semaphore.signal()
}
@ -232,14 +232,14 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
resourceSize = resultSize
}
} else {
resourceSize = Int(Int32.max - 1)
resourceSize = Int64.max - 1
}
}
if (whence & FFMPEG_AVSEEK_SIZE) != 0 {
result = Int64(resourceSize == Int(Int32.max - 1) ? 0 : resourceSize)
} else {
context.readingOffset = Int(min(Int64(resourceSize), offset))
context.readingOffset = min(Int64(resourceSize), offset)
if context.readingOffset != context.requestedDataOffset {
context.requestedDataOffset = context.readingOffset
@ -249,7 +249,7 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
} else {
if streamable {
if context.tempFilePath == nil {
let fetchRange: Range<Int> = context.readingOffset ..< Int(Int32.max)
let fetchRange: Range<Int64> = context.readingOffset ..< Int64.max
context.fetchedDataDisposable.set(fetchedMediaResource(mediaBox: postbox.mediaBox, reference: resourceReference, range: (fetchRange, .elevated), statsCategory: statsCategory, preferBackgroundReferenceRevalidation: streamable).start())
}
} else if !context.requestedCompleteFetch && context.fetchAutomatically {
@ -282,9 +282,9 @@ final class FFMpegMediaFrameSourceContext: NSObject {
fileprivate var statsCategory: MediaResourceStatsCategory?
private let ioBufferSize = 1 * 1024
fileprivate var readingOffset = 0
fileprivate var readingOffset: Int64 = 0
fileprivate var requestedDataOffset: Int?
fileprivate var requestedDataOffset: Int64?
fileprivate let fetchedDataDisposable = MetaDisposable()
fileprivate let keepDataDisposable = MetaDisposable()
fileprivate let fetchedFullDataDisposable = MetaDisposable()
@ -342,7 +342,7 @@ final class FFMpegMediaFrameSourceContext: NSObject {
if streamable {
if self.tempFilePath == nil {
self.fetchedDataDisposable.set(fetchedMediaResource(mediaBox: postbox.mediaBox, reference: resourceReference, range: (0 ..< Int(Int32.max), .elevated), statsCategory: self.statsCategory ?? .generic, preferBackgroundReferenceRevalidation: streamable).start())
self.fetchedDataDisposable.set(fetchedMediaResource(mediaBox: postbox.mediaBox, reference: resourceReference, range: (0 ..< Int64.max, .elevated), statsCategory: self.statsCategory ?? .generic, preferBackgroundReferenceRevalidation: streamable).start())
}
} else if !self.requestedCompleteFetch && self.fetchAutomatically {
self.requestedCompleteFetch = true
@ -449,7 +449,7 @@ final class FFMpegMediaFrameSourceContext: NSObject {
if streamable {
if self.tempFilePath == nil {
self.fetchedFullDataDisposable.set(fetchedMediaResource(mediaBox: postbox.mediaBox, reference: resourceReference, range: (0 ..< Int(Int32.max), .default), statsCategory: self.statsCategory ?? .generic, preferBackgroundReferenceRevalidation: streamable).start())
self.fetchedFullDataDisposable.set(fetchedMediaResource(mediaBox: postbox.mediaBox, reference: resourceReference, range: (0 ..< Int64.max, .default), statsCategory: self.statsCategory ?? .generic, preferBackgroundReferenceRevalidation: streamable).start())
}
self.requestedCompleteFetch = true
}

View file

@ -218,7 +218,7 @@ private final class MediaPlayerScrubbingBufferingNode: ASDisplayNode {
private let containerNode: ASDisplayNode
private let foregroundNode: ASImageNode
private var ranges: (IndexSet, Int)?
private var ranges: (IndexSet, Int64)?
init(color: UIColor, lineCap: MediaPlayerScrubbingNodeCap, lineHeight: CGFloat) {
self.color = color
@ -239,7 +239,7 @@ private final class MediaPlayerScrubbingBufferingNode: ASDisplayNode {
self.addSubnode(self.containerNode)
}
func updateStatus(_ ranges: IndexSet, _ size: Int) {
func updateStatus(_ ranges: IndexSet, _ size: Int64) {
self.ranges = (ranges, size)
if !self.bounds.width.isZero {
self.updateLayout(size: self.bounds.size, transition: .animated(duration: 0.15, curve: .easeInOut))
@ -358,9 +358,9 @@ public final class MediaPlayerScrubbingNode: ASDisplayNode {
}
private var bufferingStatusDisposable: Disposable?
private var bufferingStatusValuePromise = Promise<(IndexSet, Int)?>()
private var bufferingStatusValuePromise = Promise<(IndexSet, Int64)?>()
public var bufferingStatus: Signal<(IndexSet, Int)?, NoError>? {
public var bufferingStatus: Signal<(IndexSet, Int64)?, NoError>? {
didSet {
if let bufferingStatus = self.bufferingStatus {
self.bufferingStatusValuePromise.set(bufferingStatus)

View file

@ -14,8 +14,8 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
let data: Signal<(Data, Bool), NoError>
let readCount = min(256 * 1024, Int(bufferSize))
let requestRange: Range<Int> = context.readingOffset ..< (context.readingOffset + readCount)
let readCount = min(256 * 1024, Int64(bufferSize))
let requestRange: Range<Int64> = context.readingOffset ..< (context.readingOffset + readCount)
context.currentNumberOfReads += 1
context.currentReadBytes += readCount
@ -59,7 +59,7 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
memcpy(buffer, bytes, fetchedData.count)
}
let fetchedCount = Int32(fetchedData.count)
context.readingOffset += Int(fetchedCount)
context.readingOffset += Int64(fetchedCount)
return fetchedCount
} else {
return 0
@ -71,7 +71,7 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
if (whence & FFMPEG_AVSEEK_SIZE) != 0 {
return Int64(context.size)
} else {
context.readingOffset = Int(offset)
context.readingOffset = offset
return offset
}
}
@ -99,7 +99,7 @@ private final class SoftwareVideoStream {
private final class UniversalSoftwareVideoSourceImpl {
fileprivate let mediaBox: MediaBox
fileprivate let fileReference: FileMediaReference
fileprivate let size: Int
fileprivate let size: Int64
fileprivate let automaticallyFetchHeader: Bool
fileprivate let state: ValuePromise<UniversalSoftwareVideoSourceState>
@ -108,12 +108,12 @@ private final class UniversalSoftwareVideoSourceImpl {
fileprivate var avFormatContext: FFMpegAVFormatContext!
fileprivate var videoStream: SoftwareVideoStream!
fileprivate var readingOffset: Int = 0
fileprivate var readingOffset: Int64 = 0
fileprivate var cancelRead: Signal<Bool, NoError>
fileprivate var requiredDataIsNotLocallyAvailable: (() -> Void)?
fileprivate var currentNumberOfReads: Int = 0
fileprivate var currentReadBytes: Int = 0
fileprivate var currentReadBytes: Int64 = 0
init?(mediaBox: MediaBox, fileReference: FileMediaReference, state: ValuePromise<UniversalSoftwareVideoSourceState>, cancelInitialization: Signal<Bool, NoError>, automaticallyFetchHeader: Bool, hintVP9: Bool = false) {
guard let size = fileReference.media.size else {

View file

@ -21,6 +21,10 @@ public class SecureIdLocalImageResource: TelegramMediaResource {
public let localId: Int64
public let source: TelegramMediaResource
public var size: Int64? {
return nil
}
public init(localId: Int64, source: TelegramMediaResource) {
self.localId = localId
self.source = source
@ -61,7 +65,7 @@ public func fetchSecureIdLocalImageResource(postbox: Postbox, resource: SecureId
subscriber.putNext(.reset)
let fetch = fetchResource(resource.source, .single([(0 ..< Int.max, .default)]), nil)
let fetch = fetchResource(resource.source, .single([(0 ..< Int64.max, .default)]), nil)
let buffer = Atomic<Buffer>(value: Buffer())
let disposable = fetch.start(next: { result in
switch result {
@ -106,19 +110,19 @@ public func fetchSecureIdLocalImageResource(postbox: Postbox, resource: SecureId
guard let bytes = buffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
return
}
data.copyBytes(to: bytes, from: range)
data.copyBytes(to: bytes, from: Int(range.lowerBound) ..< Int(range.upperBound))
}
}
case let .dataPart(resourceOffset, data, range, _):
let _ = buffer.with { buffer in
if buffer.data.count < resourceOffset + range.count {
buffer.data.count = resourceOffset + range.count
if buffer.data.count < Int(resourceOffset) + range.count {
buffer.data.count = Int(resourceOffset) + range.count
}
buffer.data.withUnsafeMutableBytes { buffer -> Void in
guard let bytes = buffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
return
}
data.copyBytes(to: bytes.advanced(by: resourceOffset), from: range)
data.copyBytes(to: bytes.advanced(by: Int(resourceOffset)), from: Int(range.lowerBound) ..< Int(range.upperBound))
}
}
}
@ -131,7 +135,7 @@ public func fetchSecureIdLocalImageResource(postbox: Postbox, resource: SecureId
context.setBlendMode(.copy)
context.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size))
}, scale: 1.0), let scaledData = scaledImage.jpegData(compressionQuality: 0.6) {
subscriber.putNext(.dataPart(resourceOffset: 0, data: scaledData, range: 0 ..< scaledData.count, complete: true))
subscriber.putNext(.dataPart(resourceOffset: 0, data: scaledData, range: 0 ..< Int64(scaledData.count), complete: true))
subscriber.putCompletion()
}
}

View file

@ -38,11 +38,11 @@ private let progressiveRangeMap: [(Int, [Int])] = [
(Int(Int32.max), [2, 3, 4])
]
public func representationFetchRangeForDisplayAtSize(representation: TelegramMediaImageRepresentation, dimension: Int?) -> Range<Int>? {
public func representationFetchRangeForDisplayAtSize(representation: TelegramMediaImageRepresentation, dimension: Int?) -> Range<Int64>? {
if representation.progressiveSizes.count > 1, let dimension = dimension {
var largestByteSize = Int(representation.progressiveSizes[0])
var largestByteSize = Int64(representation.progressiveSizes[0])
for (maxDimension, byteSizes) in progressiveRangeMap {
largestByteSize = Int(representation.progressiveSizes[min(representation.progressiveSizes.count - 1, byteSizes.last!)])
largestByteSize = Int64(representation.progressiveSizes[min(representation.progressiveSizes.count - 1, byteSizes.last!)])
if maxDimension >= dimension {
break
}
@ -56,7 +56,7 @@ public func chatMessagePhotoDatas(postbox: Postbox, photoReference: ImageMediaRe
if let progressiveRepresentation = progressiveImageRepresentation(photoReference.media.representations), progressiveRepresentation.progressiveSizes.count > 1 {
enum SizeSource {
case miniThumbnail(data: Data)
case image(size: Int)
case image(size: Int64)
}
var sources: [SizeSource] = []
@ -70,7 +70,7 @@ public func chatMessagePhotoDatas(postbox: Postbox, photoReference: ImageMediaRe
if progressiveRepresentation.progressiveSizes.count - 1 < sizeIndex {
return nil
}
return .image(size: Int(progressiveRepresentation.progressiveSizes[sizeIndex]))
return .image(size: Int64(progressiveRepresentation.progressiveSizes[sizeIndex]))
})
largestByteSize = Int(progressiveRepresentation.progressiveSizes[min(progressiveRepresentation.progressiveSizes.count - 1, byteSizes.last!)])
if maxDimension >= Int(fullRepresentationSize.width) {
@ -78,7 +78,7 @@ public func chatMessagePhotoDatas(postbox: Postbox, photoReference: ImageMediaRe
}
}
if sources.isEmpty {
sources.append(.image(size: largestByteSize))
sources.append(.image(size: Int64(largestByteSize)))
}
if let miniThumbnail = photoReference.media.immediateThumbnailData.flatMap(decodeTinyThumbnail) {
sources.insert(.miniThumbnail(data: miniThumbnail), at: 0)
@ -90,7 +90,7 @@ public func chatMessagePhotoDatas(postbox: Postbox, photoReference: ImageMediaRe
case let .miniThumbnail(data):
return .single((source, data))
case let .image(size):
return postbox.mediaBox.resourceData(progressiveRepresentation.resource, size: Int(progressiveRepresentation.progressiveSizes.last!), in: 0 ..< size, mode: .incremental, notifyAboutIncomplete: true, attemptSynchronously: synchronousLoad)
return postbox.mediaBox.resourceData(progressiveRepresentation.resource, size: Int64(progressiveRepresentation.progressiveSizes.last!), in: 0 ..< size, mode: .incremental, notifyAboutIncomplete: true, attemptSynchronously: synchronousLoad)
|> map { (data, _) -> (SizeSource, Data?) in
return (source, data)
}
@ -127,9 +127,9 @@ public func chatMessagePhotoDatas(postbox: Postbox, photoReference: ImageMediaRe
})
var fetchDisposable: Disposable?
if autoFetchFullSize {
fetchDisposable = fetchedMediaResource(mediaBox: postbox.mediaBox, reference: photoReference.resourceReference(progressiveRepresentation.resource), range: (0 ..< largestByteSize, .default), statsCategory: .image).start()
fetchDisposable = fetchedMediaResource(mediaBox: postbox.mediaBox, reference: photoReference.resourceReference(progressiveRepresentation.resource), range: (0 ..< Int64(largestByteSize), .default), statsCategory: .image).start()
} else if useMiniThumbnailIfAvailable {
fetchDisposable = fetchedMediaResource(mediaBox: postbox.mediaBox, reference: photoReference.resourceReference(progressiveRepresentation.resource), range: (0 ..< thumbnailByteSize, .default), statsCategory: .image).start()
fetchDisposable = fetchedMediaResource(mediaBox: postbox.mediaBox, reference: photoReference.resourceReference(progressiveRepresentation.resource), range: (0 ..< Int64(thumbnailByteSize), .default), statsCategory: .image).start()
}
return ActionDisposable {
@ -1671,7 +1671,7 @@ public func chatMessagePhotoStatus(context: AccountContext, messageId: MessageId
context.account.postbox.mediaBox.resourceRangesStatus(largestRepresentation.resource)
)
|> map { status, rangeStatus -> MediaResourceStatus in
if rangeStatus.contains(integersIn: range) {
if rangeStatus.contains(integersIn: Int(range.lowerBound) ..< Int(range.upperBound)) {
return .Local
}
@ -1708,39 +1708,11 @@ public func standaloneChatMessagePhotoInteractiveFetched(account: Account, photo
public func chatMessagePhotoInteractiveFetched(context: AccountContext, photoReference: ImageMediaReference, displayAtSize: Int?, storeToDownloadsPeerType: MediaAutoDownloadPeerType?) -> Signal<Never, NoError> {
if let largestRepresentation = largestRepresentationForPhoto(photoReference.media) {
var fetchRange: (Range<Int>, MediaBoxFetchPriority)?
var fetchRange: (Range<Int64>, MediaBoxFetchPriority)?
if let displayAtSize = displayAtSize, let range = representationFetchRangeForDisplayAtSize(representation: largestRepresentation, dimension: displayAtSize) {
fetchRange = (range, .default)
}
/*switch photoReference {
case let .message(message, _):
if let id = message.id {
let ranges: IndexSet
if let (range, _) = fetchRange {
ranges = IndexSet(integersIn: range)
} else {
ranges = IndexSet(integersIn: 0 ..< Int(Int32.max) as Range<Int>)
}
return context.fetchManager.interactivelyFetched(
category: .image,
location: .chat(id.peerId),
locationKey: .messageId(id),
mediaReference: photoReference.abstract,
resourceReference: photoReference.resourceReference(largestRepresentation.resource),
ranges: ranges,
statsCategory: .image,
elevatedPriority: false,
userInitiated: false,
priority: .userInitiated,
storeToDownloadsPeerType: nil
)
|> ignoreValues
}
default:
break
}*/
return fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: photoReference.resourceReference(largestRepresentation.resource), range: fetchRange, statsCategory: .image, reportResultStatus: true)
|> mapToSignal { type -> Signal<FetchResourceSourceType, FetchResourceError> in
if case .remote = type, let peerType = storeToDownloadsPeerType {
@ -2294,7 +2266,7 @@ public func svgIconImageFile(account: Account, fileReference: FileMediaReference
} else {
data = Signal { subscriber in
if let url = getAppBundle().url(forResource: "durgerking", withExtension: "placeholder"), let data = try? Data(contentsOf: url, options: .mappedRead) {
subscriber.putNext(MediaResourceData(path: url.path, offset: 0, size: data.count, complete: true))
subscriber.putNext(MediaResourceData(path: url.path, offset: 0, size: Int64(data.count), complete: true))
subscriber.putCompletion()
}
return EmptyDisposable

View file

@ -1,12 +1,12 @@
import Foundation
public func fileSize(_ path: String, useTotalFileAllocatedSize: Bool = false) -> Int? {
public func fileSize(_ path: String, useTotalFileAllocatedSize: Bool = false) -> Int64? {
if useTotalFileAllocatedSize {
let url = URL(fileURLWithPath: path)
if let values = (try? url.resourceValues(forKeys: Set([.isRegularFileKey, .totalFileAllocatedSizeKey]))) {
if values.isRegularFile ?? false {
if let fileSize = values.totalFileAllocatedSize {
return fileSize
return Int64(fileSize)
}
}
}
@ -14,7 +14,7 @@ public func fileSize(_ path: String, useTotalFileAllocatedSize: Bool = false) ->
var value = stat()
if stat(path, &value) == 0 {
return Int(value.st_size)
return value.st_size
} else {
return nil
}

View file

@ -48,11 +48,11 @@ private struct ResourceStorePaths {
public struct MediaResourceData {
public let path: String
public let offset: Int
public let size: Int
public let offset: Int64
public let size: Int64
public let complete: Bool
public init(path: String, offset: Int, size: Int, complete: Bool) {
public init(path: String, offset: Int64, size: Int64, complete: Bool) {
self.path = path
self.offset = offset
self.size = size
@ -71,10 +71,10 @@ public enum MediaBoxFetchPriority: Int32 {
}
public enum MediaResourceDataFetchResult {
case dataPart(resourceOffset: Int, data: Data, range: Range<Int>, complete: Bool)
case resourceSizeUpdated(Int)
case dataPart(resourceOffset: Int64, data: Data, range: Range<Int64>, complete: Bool)
case resourceSizeUpdated(Int64)
case progressUpdated(Float)
case replaceHeader(data: Data, range: Range<Int>)
case replaceHeader(data: Data, range: Range<Int64>)
case moveLocalFile(path: String)
case moveTempFile(file: TempBoxFile)
case copyLocalItem(MediaResourceDataFetchCopyLocalItem)
@ -153,9 +153,9 @@ public final class MediaBox {
private var fileContexts: [MediaResourceId: MediaBoxFileContext] = [:]
private var keepResourceContexts: [MediaResourceId: MediaBoxKeepResourceContext] = [:]
private var wrappedFetchResource = Promise<(MediaResource, Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>>()
private var wrappedFetchResource = Promise<(MediaResource, Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>>()
public var fetchResource: ((MediaResource, Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>)? {
public var fetchResource: ((MediaResource, Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>)? {
didSet {
if let fetchResource = self.fetchResource {
wrappedFetchResource.set(.single(fetchResource))
@ -318,7 +318,7 @@ public final class MediaBox {
return self.resourceStatus(resource.id, resourceSize: resource.size, approximateSynchronousValue: approximateSynchronousValue)
}
public func resourceStatus(_ resourceId: MediaResourceId, resourceSize: Int?, approximateSynchronousValue: Bool = false) -> Signal<MediaResourceStatus, NoError> {
public func resourceStatus(_ resourceId: MediaResourceId, resourceSize: Int64?, approximateSynchronousValue: Bool = false) -> Signal<MediaResourceStatus, NoError> {
let signal = Signal<MediaResourceStatus, NoError> { subscriber in
let disposable = MetaDisposable()
@ -375,7 +375,7 @@ public final class MediaBox {
}
}
}
}, size: resourceSize.flatMap(Int32.init))
}, size: resourceSize)
statusUpdateDisposable.set(ActionDisposable {
statusDisposable.dispose()
releaseContext()
@ -487,7 +487,7 @@ public final class MediaBox {
case let .incremental(waitUntilFetchStatus):
waitUntilAfterInitialFetch = waitUntilFetchStatus
}
let dataDisposable = fileContext.data(range: 0 ..< Int32.max, waitUntilAfterInitialFetch: waitUntilAfterInitialFetch, next: { value in
let dataDisposable = fileContext.data(range: 0 ..< Int64.max, waitUntilAfterInitialFetch: waitUntilAfterInitialFetch, next: { value in
self.dataQueue.async {
if value.complete {
if let pathExtension = pathExtension {
@ -564,7 +564,7 @@ public final class MediaBox {
}
}
public func fetchedResourceData(_ resource: MediaResource, in range: Range<Int>, priority: MediaBoxFetchPriority = .default, parameters: MediaResourceFetchParameters?) -> Signal<Void, FetchResourceError> {
public func fetchedResourceData(_ resource: MediaResource, in range: Range<Int64>, priority: MediaBoxFetchPriority = .default, parameters: MediaResourceFetchParameters?) -> Signal<Void, FetchResourceError> {
return Signal { subscriber in
let disposable = MetaDisposable()
@ -580,7 +580,7 @@ public final class MediaBox {
}
let fetchResource = self.wrappedFetchResource.get()
let fetchedDisposable = fileContext.fetched(range: Int32(range.lowerBound) ..< Int32(range.upperBound), priority: priority, fetch: { intervals in
let fetchedDisposable = fileContext.fetched(range: range.lowerBound ..< range.upperBound, priority: priority, fetch: { intervals in
return fetchResource
|> castError(MediaResourceDataFetchError.self)
|> mapToSignal { fetch in
@ -602,11 +602,11 @@ public final class MediaBox {
}
}
public func resourceData(_ resource: MediaResource, size: Int, in range: Range<Int>, mode: ResourceDataRangeMode = .complete, notifyAboutIncomplete: Bool = false, attemptSynchronously: Bool = false) -> Signal<(Data, Bool), NoError> {
public func resourceData(_ resource: MediaResource, size: Int64, in range: Range<Int64>, mode: ResourceDataRangeMode = .complete, notifyAboutIncomplete: Bool = false, attemptSynchronously: Bool = false) -> Signal<(Data, Bool), NoError> {
return self.resourceData(id: resource.id, size: size, in: range, mode: mode, notifyAboutIncomplete: notifyAboutIncomplete, attemptSynchronously: attemptSynchronously)
}
public func resourceData(id: MediaResourceId, size: Int, in range: Range<Int>, mode: ResourceDataRangeMode = .complete, notifyAboutIncomplete: Bool = false, attemptSynchronously: Bool = false) -> Signal<(Data, Bool), NoError> {
public func resourceData(id: MediaResourceId, size: Int64, in range: Range<Int64>, mode: ResourceDataRangeMode = .complete, notifyAboutIncomplete: Bool = false, attemptSynchronously: Bool = false) -> Signal<(Data, Bool), NoError> {
return Signal { subscriber in
let disposable = MetaDisposable()
@ -622,8 +622,8 @@ public final class MediaBox {
let clippedLowerBound = min(completeSize, max(0, range.lowerBound))
let clippedUpperBound = min(completeSize, max(0, range.upperBound))
if clippedLowerBound < clippedUpperBound {
file.seek(position: Int64(clippedLowerBound))
let data = file.readData(count: clippedUpperBound)
file.seek(position: clippedLowerBound)
let data = file.readData(count: Int(clippedUpperBound - clippedLowerBound))
subscriber.putNext((data, true))
} else {
subscriber.putNext((Data(), isComplete: true))
@ -631,7 +631,7 @@ public final class MediaBox {
subscriber.putCompletion()
return EmptyDisposable
} else {
if let data = MediaBoxPartialFile.extractPartialData(path: paths.partial, metaPath: paths.partial + ".meta", range: Int32(range.lowerBound) ..< Int32(range.upperBound)) {
if let data = MediaBoxPartialFile.extractPartialData(path: paths.partial, metaPath: paths.partial + ".meta", range: range) {
subscriber.putNext((data, true))
subscriber.putCompletion()
return EmptyDisposable
@ -646,8 +646,6 @@ public final class MediaBox {
return
}
let range = Int32(range.lowerBound) ..< Int32(range.upperBound)
let dataDisposable = fileContext.data(range: range, waitUntilAfterInitialFetch: false, next: { result in
if let file = ManagedFile(queue: self.dataQueue, path: result.path, mode: .read), let fileSize = file.getSize() {
if result.complete {
@ -658,7 +656,7 @@ public final class MediaBox {
subscriber.putCompletion()
} else if clippedUpperBound <= fileSize {
file.seek(position: Int64(clippedLowerBound))
let resultData = file.readData(count: clippedUpperBound - clippedLowerBound)
let resultData = file.readData(count: Int(clippedUpperBound - clippedLowerBound))
subscriber.putNext((resultData, true))
subscriber.putCompletion()
} else {

View file

@ -4,9 +4,9 @@ import Crc32
import ManagedFile
private final class MediaBoxFileMap {
fileprivate(set) var sum: Int32
fileprivate(set) var sum: Int64
private(set) var ranges: IndexSet
private(set) var truncationSize: Int32?
private(set) var truncationSize: Int64?
private(set) var progress: Float?
init() {
@ -21,74 +21,146 @@ private final class MediaBoxFileMap {
return nil
}
var crc: UInt32 = 0
var count: Int32 = 0
var sum: Int32 = 0
var ranges: IndexSet = IndexSet()
guard fd.read(&crc, 4) == 4 else {
return nil
}
guard fd.read(&count, 4) == 4 else {
var firstUInt32: UInt32 = 0
guard fd.read(&firstUInt32, 4) == 4 else {
return nil
}
if count < 0 {
return nil
}
if count < 0 || length < 4 + 4 + count * 2 * 4 {
return nil
}
var truncationSizeValue: Int32 = 0
var data = Data(count: Int(4 + count * 2 * 4))
let dataCount = data.count
if !(data.withUnsafeMutableBytes { rawBytes -> Bool in
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
if firstUInt32 == 0x7bac1487 {
var crc: UInt32 = 0
guard fd.read(&crc, 4) == 4 else {
return nil
}
var count: Int32 = 0
var sum: Int64 = 0
var ranges: IndexSet = IndexSet()
guard fd.read(&count, 4) == 4 else {
return nil
}
if count < 0 {
return nil
}
if count < 0 || length < 4 + 4 + 4 + 8 + count * 2 * 8 {
return nil
}
var truncationSizeValue: Int32 = 0
var data = Data(count: Int(8 + count * 2 * 8))
let dataCount = data.count
if !(data.withUnsafeMutableBytes { rawBytes -> Bool in
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
guard fd.read(bytes, dataCount) == dataCount else {
return false
}
memcpy(&truncationSizeValue, bytes, 4)
let calculatedCrc = Crc32(bytes, Int32(dataCount))
if calculatedCrc != crc {
return false
}
var offset = 4
for _ in 0 ..< count {
var intervalOffset: Int32 = 0
var intervalLength: Int32 = 0
memcpy(&intervalOffset, bytes.advanced(by: offset), 4)
memcpy(&intervalLength, bytes.advanced(by: offset + 4), 4)
offset += 8
guard fd.read(bytes, dataCount) == dataCount else {
return false
}
ranges.insert(integersIn: Int(intervalOffset) ..< Int(intervalOffset + intervalLength))
memcpy(&truncationSizeValue, bytes, 8)
sum += intervalLength
let calculatedCrc = Crc32(bytes, Int32(dataCount))
if calculatedCrc != crc {
return false
}
var offset = 8
for _ in 0 ..< count {
var intervalOffset: Int64 = 0
var intervalLength: Int64 = 0
memcpy(&intervalOffset, bytes.advanced(by: offset), 8)
memcpy(&intervalLength, bytes.advanced(by: offset + 8), 8)
offset += 8 * 2
ranges.insert(integersIn: Int(intervalOffset) ..< Int(intervalOffset + intervalLength))
sum += intervalLength
}
return true
}) {
return nil
}
return true
}) {
return nil
}
self.sum = sum
self.ranges = ranges
if truncationSizeValue == -1 {
self.truncationSize = nil
self.sum = sum
self.ranges = ranges
if truncationSizeValue == -1 {
self.truncationSize = nil
} else {
self.truncationSize = Int64(truncationSizeValue)
}
} else {
self.truncationSize = truncationSizeValue
let crc: UInt32 = firstUInt32
var count: Int32 = 0
var sum: Int32 = 0
var ranges: IndexSet = IndexSet()
guard fd.read(&count, 4) == 4 else {
return nil
}
if count < 0 {
return nil
}
if count < 0 || length < 4 + 4 + count * 2 * 4 {
return nil
}
var truncationSizeValue: Int32 = 0
var data = Data(count: Int(4 + count * 2 * 4))
let dataCount = data.count
if !(data.withUnsafeMutableBytes { rawBytes -> Bool in
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
guard fd.read(bytes, dataCount) == dataCount else {
return false
}
memcpy(&truncationSizeValue, bytes, 4)
let calculatedCrc = Crc32(bytes, Int32(dataCount))
if calculatedCrc != crc {
return false
}
var offset = 4
for _ in 0 ..< count {
var intervalOffset: Int32 = 0
var intervalLength: Int32 = 0
memcpy(&intervalOffset, bytes.advanced(by: offset), 4)
memcpy(&intervalLength, bytes.advanced(by: offset + 4), 4)
offset += 8
ranges.insert(integersIn: Int(intervalOffset) ..< Int(intervalOffset + intervalLength))
sum += intervalLength
}
return true
}) {
return nil
}
self.sum = Int64(sum)
self.ranges = ranges
if truncationSizeValue == -1 {
self.truncationSize = nil
} else {
self.truncationSize = Int64(truncationSizeValue)
}
}
}
func serialize(to file: ManagedFile) {
file.seek(position: 0)
let buffer = WriteBuffer()
var magic: UInt32 = 0x7bac1487
buffer.write(&magic, offset: 0, length: 4)
var zero: Int32 = 0
buffer.write(&zero, offset: 0, length: 4)
@ -96,29 +168,29 @@ private final class MediaBoxFileMap {
var count: Int32 = Int32(rangeView.count)
buffer.write(&count, offset: 0, length: 4)
var truncationSizeValue: Int32 = self.truncationSize ?? -1
buffer.write(&truncationSizeValue, offset: 0, length: 4)
var truncationSizeValue: Int64 = self.truncationSize ?? -1
buffer.write(&truncationSizeValue, offset: 0, length: 8)
for range in rangeView {
var intervalOffset = Int32(range.lowerBound)
var intervalLength = Int32(range.count)
buffer.write(&intervalOffset, offset: 0, length: 4)
buffer.write(&intervalLength, offset: 0, length: 4)
buffer.write(&intervalOffset, offset: 0, length: 8)
buffer.write(&intervalLength, offset: 0, length: 8)
}
var crc: UInt32 = Crc32(buffer.memory.advanced(by: 4 * 2), Int32(buffer.length - 4 * 2))
memcpy(buffer.memory, &crc, 4)
var crc: UInt32 = Crc32(buffer.memory.advanced(by: 4 + 4 + 4), Int32(buffer.length - (4 + 4 + 4)))
memcpy(buffer.memory.advanced(by: 4), &crc, 4)
let written = file.write(buffer.memory, count: buffer.length)
assert(written == buffer.length)
}
fileprivate func fill(_ range: Range<Int32>) {
fileprivate func fill(_ range: Range<Int64>) {
let intRange: Range<Int> = Int(range.lowerBound) ..< Int(range.upperBound)
let previousCount = self.ranges.count(in: intRange)
self.ranges.insert(integersIn: intRange)
self.sum += Int32(range.count - previousCount)
self.sum += Int64(range.count - previousCount)
}
fileprivate func truncate(_ size: Int32) {
fileprivate func truncate(_ size: Int64) {
self.truncationSize = size
}
fileprivate func progressUpdated(_ progress: Float) {
@ -132,7 +204,7 @@ private final class MediaBoxFileMap {
self.progress = nil
}
fileprivate func contains(_ range: Range<Int32>) -> Range<Int32>? {
fileprivate func contains(_ range: Range<Int64>) -> Range<Int64>? {
let maxValue: Int
if let truncationSize = self.truncationSize {
maxValue = Int(truncationSize)
@ -141,7 +213,7 @@ private final class MediaBoxFileMap {
}
let intRange: Range<Int> = Int(range.lowerBound) ..< min(maxValue, Int(range.upperBound))
if self.ranges.contains(integersIn: intRange) {
return Int32(intRange.lowerBound) ..< Int32(intRange.upperBound)
return Int64(intRange.lowerBound) ..< Int64(intRange.upperBound)
} else {
return nil
}
@ -149,11 +221,11 @@ private final class MediaBoxFileMap {
}
private class MediaBoxPartialFileDataRequest {
let range: Range<Int32>
let range: Range<Int64>
var waitingUntilAfterInitialFetch: Bool
let completion: (MediaResourceData) -> Void
init(range: Range<Int32>, waitingUntilAfterInitialFetch: Bool, completion: @escaping (MediaResourceData) -> Void) {
init(range: Range<Int64>, waitingUntilAfterInitialFetch: Bool, completion: @escaping (MediaResourceData) -> Void) {
self.range = range
self.waitingUntilAfterInitialFetch = waitingUntilAfterInitialFetch
self.completion = completion
@ -165,21 +237,21 @@ final class MediaBoxPartialFile {
private let path: String
private let metaPath: String
private let completePath: String
private let completed: (Int32) -> Void
private let completed: (Int64) -> Void
private let metadataFd: ManagedFile
private let fd: ManagedFile
fileprivate let fileMap: MediaBoxFileMap
private var dataRequests = Bag<MediaBoxPartialFileDataRequest>()
private let missingRanges: MediaBoxFileMissingRanges
private let rangeStatusRequests = Bag<((IndexSet) -> Void, () -> Void)>()
private let statusRequests = Bag<((MediaResourceStatus) -> Void, Int32?)>()
private let statusRequests = Bag<((MediaResourceStatus) -> Void, Int64?)>()
private let fullRangeRequests = Bag<Disposable>()
private var currentFetch: (Promise<[(Range<Int>, MediaBoxFetchPriority)]>, Disposable)?
private var currentFetch: (Promise<[(Range<Int64>, MediaBoxFetchPriority)]>, Disposable)?
private var processedAtLeastOneFetch: Bool = false
init?(queue: Queue, path: String, metaPath: String, completePath: String, completed: @escaping (Int32) -> Void) {
init?(queue: Queue, path: String, metaPath: String, completePath: String, completed: @escaping (Int64) -> Void) {
assert(queue.isCurrent())
if let metadataFd = ManagedFile(queue: queue, path: metaPath, mode: .readwrite), let fd = ManagedFile(queue: queue, path: path, mode: .readwrite) {
self.queue = queue
@ -217,7 +289,7 @@ final class MediaBoxPartialFile {
self.currentFetch?.1.dispose()
}
static func extractPartialData(path: String, metaPath: String, range: Range<Int32>) -> Data? {
static func extractPartialData(path: String, metaPath: String, range: Range<Int64>) -> Data? {
guard let metadataFd = ManagedFile(queue: nil, path: metaPath, mode: .read) else {
return nil
}
@ -234,7 +306,7 @@ final class MediaBoxPartialFile {
return fd.readData(count: Int(clippedRange.upperBound - clippedRange.lowerBound))
}
var storedSize: Int32 {
var storedSize: Int64 {
assert(self.queue.isCurrent())
return self.fileMap.sum
}
@ -246,7 +318,7 @@ final class MediaBoxPartialFile {
self.fileMap.serialize(to: self.metadataFd)
for request in self.dataRequests.copyItems() {
request.completion(MediaResourceData(path: self.path, offset: Int(request.range.lowerBound), size: 0, complete: false))
request.completion(MediaResourceData(path: self.path, offset: request.range.lowerBound, size: 0, complete: false))
}
if let updatedRanges = self.missingRanges.reset(fileMap: self.fileMap) {
@ -283,7 +355,7 @@ final class MediaBoxPartialFile {
}
for request in self.dataRequests.copyItems() {
request.completion(MediaResourceData(path: self.completePath, offset: Int(request.range.lowerBound), size: max(0, size - Int(request.range.lowerBound)), complete: true))
request.completion(MediaResourceData(path: self.completePath, offset: request.range.lowerBound, size: max(0, size - request.range.lowerBound), complete: true))
}
self.dataRequests.removeAll()
@ -325,7 +397,7 @@ final class MediaBoxPartialFile {
}
for request in self.dataRequests.copyItems() {
request.completion(MediaResourceData(path: self.completePath, offset: Int(request.range.lowerBound), size: max(0, size - Int(request.range.lowerBound)), complete: true))
request.completion(MediaResourceData(path: self.completePath, offset: request.range.lowerBound, size: max(0, size - request.range.lowerBound), complete: true))
}
self.dataRequests.removeAll()
@ -334,17 +406,17 @@ final class MediaBoxPartialFile {
}
self.statusRequests.removeAll()
self.completed(Int32(size))
self.completed(size)
} else {
assertionFailure()
}
}
}
func truncate(_ size: Int32) {
func truncate(_ size: Int64) {
assert(self.queue.isCurrent())
let range: Range<Int32> = size ..< Int32.max
let range: Range<Int64> = size ..< Int64.max
self.fileMap.truncate(size)
self.fileMap.serialize(to: self.metadataFd)
@ -359,24 +431,24 @@ final class MediaBoxPartialFile {
self.updateStatuses()
}
func write(offset: Int32, data: Data, dataRange: Range<Int>) {
func write(offset: Int64, data: Data, dataRange: Range<Int64>) {
assert(self.queue.isCurrent())
self.fd.seek(position: Int64(offset))
self.fd.seek(position: offset)
let written = data.withUnsafeBytes { rawBytes -> Int in
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
return self.fd.write(bytes.advanced(by: dataRange.lowerBound), count: dataRange.count)
return self.fd.write(bytes.advanced(by: Int(dataRange.lowerBound)), count: dataRange.count)
}
assert(written == dataRange.count)
let range: Range<Int32> = offset ..< (offset + Int32(dataRange.count))
let range: Range<Int64> = offset ..< (offset + Int64(dataRange.count))
self.fileMap.fill(range)
self.fileMap.serialize(to: self.metadataFd)
self.checkDataRequestsAfterFill(range: range)
}
func checkDataRequestsAfterFill(range: Range<Int32>) {
func checkDataRequestsAfterFill(range: Range<Int64>) {
var removeIndices: [(Int, MediaBoxPartialFileDataRequest)] = []
for (index, request) in self.dataRequests.copyItemsWithIndices() {
if request.range.overlaps(range) {
@ -402,7 +474,7 @@ final class MediaBoxPartialFile {
if let truncationSize = self.fileMap.truncationSize, truncationSize < maxValue {
maxValue = truncationSize
}
request.completion(MediaResourceData(path: self.path, offset: Int(request.range.lowerBound), size: Int(maxValue) - Int(request.range.lowerBound), complete: true))
request.completion(MediaResourceData(path: self.path, offset: request.range.lowerBound, size: maxValue - request.range.lowerBound, complete: true))
}
}
@ -451,7 +523,7 @@ final class MediaBoxPartialFile {
}
}
func read(range: Range<Int32>) -> Data? {
func read(range: Range<Int64>) -> Data? {
assert(self.queue.isCurrent())
if let actualRange = self.fileMap.contains(range) {
@ -472,11 +544,11 @@ final class MediaBoxPartialFile {
}
}
func data(range: Range<Int32>, waitUntilAfterInitialFetch: Bool, next: @escaping (MediaResourceData) -> Void) -> Disposable {
func data(range: Range<Int64>, waitUntilAfterInitialFetch: Bool, next: @escaping (MediaResourceData) -> Void) -> Disposable {
assert(self.queue.isCurrent())
if let actualRange = self.fileMap.contains(range) {
next(MediaResourceData(path: self.path, offset: Int(actualRange.lowerBound), size: actualRange.count, complete: true))
next(MediaResourceData(path: self.path, offset: actualRange.lowerBound, size: Int64(actualRange.count), complete: true))
return EmptyDisposable
}
@ -484,7 +556,7 @@ final class MediaBoxPartialFile {
if waitUntilAfterInitialFetch && !self.processedAtLeastOneFetch {
waitingUntilAfterInitialFetch = true
} else {
next(MediaResourceData(path: self.path, offset: Int(range.lowerBound), size: 0, complete: false))
next(MediaResourceData(path: self.path, offset: range.lowerBound, size: 0, complete: false))
}
let index = self.dataRequests.add(MediaBoxPartialFileDataRequest(range: range, waitingUntilAfterInitialFetch: waitingUntilAfterInitialFetch, completion: { data in
@ -501,7 +573,7 @@ final class MediaBoxPartialFile {
}
}
func fetched(range: Range<Int32>, priority: MediaBoxFetchPriority, fetch: @escaping (Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>, error: @escaping (MediaResourceDataFetchError) -> Void, completed: @escaping () -> Void) -> Disposable {
func fetched(range: Range<Int64>, priority: MediaBoxFetchPriority, fetch: @escaping (Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>, error: @escaping (MediaResourceDataFetchError) -> Void, completed: @escaping () -> Void) -> Disposable {
assert(self.queue.isCurrent())
if let _ = self.fileMap.contains(range) {
@ -528,14 +600,14 @@ final class MediaBoxPartialFile {
}
}
func fetchedFullRange(fetch: @escaping (Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>, error: @escaping (MediaResourceDataFetchError) -> Void, completed: @escaping () -> Void) -> Disposable {
func fetchedFullRange(fetch: @escaping (Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>, error: @escaping (MediaResourceDataFetchError) -> Void, completed: @escaping () -> Void) -> Disposable {
let queue = self.queue
let disposable = MetaDisposable()
let index = self.fullRangeRequests.add(disposable)
self.updateStatuses()
disposable.set(self.fetched(range: 0 ..< Int32.max, priority: .default, fetch: fetch, error: { e in
disposable.set(self.fetched(range: 0 ..< Int64.max, priority: .default, fetch: fetch, error: { e in
error(e)
}, completed: { [weak self] in
queue.async {
@ -599,7 +671,7 @@ final class MediaBoxPartialFile {
}
}
private func immediateStatus(size: Int32?) -> MediaResourceStatus {
private func immediateStatus(size: Int64?) -> MediaResourceStatus {
let status: MediaResourceStatus
if self.fullRangeRequests.isEmpty && self.currentFetch == nil {
if let truncationSize = self.fileMap.truncationSize, self.fileMap.sum == truncationSize {
@ -629,7 +701,7 @@ final class MediaBoxPartialFile {
return status
}
func status(next: @escaping (MediaResourceStatus) -> Void, completed: @escaping () -> Void, size: Int32?) -> Disposable {
func status(next: @escaping (MediaResourceStatus) -> Void, completed: @escaping () -> Void, size: Int64?) -> Disposable {
let index = self.statusRequests.add((next, size))
let value = self.immediateStatus(size: size)
@ -649,7 +721,7 @@ final class MediaBoxPartialFile {
}
}
private func updateRequestRanges(_ intervals: [(Range<Int>, MediaBoxFetchPriority)], fetch: ((Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>)?) {
private func updateRequestRanges(_ intervals: [(Range<Int64>, MediaBoxFetchPriority)], fetch: ((Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>)?) {
assert(self.queue.isCurrent())
#if DEBUG
@ -667,7 +739,7 @@ final class MediaBoxPartialFile {
if let (promise, _) = self.currentFetch {
promise.set(.single(intervals))
} else if let fetch = fetch {
let promise = Promise<[(Range<Int>, MediaBoxFetchPriority)]>()
let promise = Promise<[(Range<Int64>, MediaBoxFetchPriority)]>()
let disposable = MetaDisposable()
self.currentFetch = (promise, disposable)
self.updateStatuses()
@ -680,15 +752,15 @@ final class MediaBoxPartialFile {
strongSelf.reset()
}
case let .resourceSizeUpdated(size):
strongSelf.truncate(Int32(size))
strongSelf.truncate(size)
case let .dataPart(resourceOffset, data, range, complete):
if !data.isEmpty {
strongSelf.write(offset: Int32(resourceOffset), data: data, dataRange: range)
strongSelf.write(offset: resourceOffset, data: data, dataRange: range)
}
if complete {
if let maxOffset = strongSelf.fileMap.ranges.rangeView.reversed().first?.upperBound {
let maxValue = max(resourceOffset + range.count, maxOffset)
strongSelf.truncate(Int32(maxValue))
let maxValue = max(resourceOffset + Int64(range.count), Int64(maxOffset))
strongSelf.truncate(maxValue)
}
}
case let .replaceHeader(data, range):
@ -710,9 +782,9 @@ final class MediaBoxPartialFile {
request.waitingUntilAfterInitialFetch = false
if let actualRange = strongSelf.fileMap.contains(request.range) {
request.completion(MediaResourceData(path: strongSelf.path, offset: Int(actualRange.lowerBound), size: actualRange.count, complete: true))
request.completion(MediaResourceData(path: strongSelf.path, offset: actualRange.lowerBound, size: Int64(actualRange.count), complete: true))
} else {
request.completion(MediaResourceData(path: strongSelf.path, offset: Int(request.range.lowerBound), size: 0, complete: false))
request.completion(MediaResourceData(path: strongSelf.path, offset: request.range.lowerBound, size: 0, complete: false))
}
}
}
@ -733,13 +805,13 @@ final class MediaBoxPartialFile {
}
private final class MediaBoxFileMissingRange {
var range: Range<Int32>
var range: Range<Int64>
let priority: MediaBoxFetchPriority
var remainingRanges: IndexSet
let error: (MediaResourceDataFetchError) -> Void
let completion: () -> Void
init(range: Range<Int32>, priority: MediaBoxFetchPriority, error: @escaping (MediaResourceDataFetchError) -> Void, completion: @escaping () -> Void) {
init(range: Range<Int64>, priority: MediaBoxFetchPriority, error: @escaping (MediaResourceDataFetchError) -> Void, completion: @escaping () -> Void) {
self.range = range
self.priority = priority
let intRange: Range<Int> = Int(range.lowerBound) ..< Int(range.upperBound)
@ -761,11 +833,11 @@ private final class MediaBoxFileMissingRanges {
return errorsAndCompletions
}
func reset(fileMap: MediaBoxFileMap) -> [(Range<Int>, MediaBoxFetchPriority)]? {
func reset(fileMap: MediaBoxFileMap) -> [(Range<Int64>, MediaBoxFetchPriority)]? {
return self.update(fileMap: fileMap)
}
private func missingRequestedIntervals() -> [(Range<Int>, MediaBoxFetchPriority)] {
private func missingRequestedIntervals() -> [(Range<Int64>, MediaBoxFetchPriority)] {
var intervalsByPriority: [MediaBoxFetchPriority: IndexSet] = [:]
var remainingIntervals = IndexSet()
for item in self.requestedRanges.copyItems() {
@ -780,14 +852,14 @@ private final class MediaBoxFileMissingRanges {
}
}
var result: [(Range<Int>, MediaBoxFetchPriority)] = []
var result: [(Range<Int64>, MediaBoxFetchPriority)] = []
for priority in intervalsByPriority.keys.sorted(by: { $0.rawValue > $1.rawValue }) {
let currentIntervals = intervalsByPriority[priority]!.intersection(remainingIntervals)
remainingIntervals.subtract(currentIntervals)
for range in currentIntervals.rangeView {
if !range.isEmpty {
result.append((range, priority))
result.append((Int64(range.lowerBound) ..< Int64(range.upperBound), priority))
}
}
}
@ -795,7 +867,7 @@ private final class MediaBoxFileMissingRanges {
return result
}
func fill(_ range: Range<Int32>) -> ([(Range<Int>, MediaBoxFetchPriority)], [() -> Void])? {
func fill(_ range: Range<Int64>) -> ([(Range<Int64>, MediaBoxFetchPriority)], [() -> Void])? {
let intRange: Range<Int> = Int(range.lowerBound) ..< Int(range.upperBound)
if self.missingRangesFlattened.intersects(integersIn: intRange) {
self.missingRangesFlattened.remove(integersIn: intRange)
@ -820,18 +892,18 @@ private final class MediaBoxFileMissingRanges {
}
}
func addRequest(fileMap: MediaBoxFileMap, range: Range<Int32>, priority: MediaBoxFetchPriority, error: @escaping (MediaResourceDataFetchError) -> Void, completion: @escaping () -> Void) -> (Int, [(Range<Int>, MediaBoxFetchPriority)]?) {
func addRequest(fileMap: MediaBoxFileMap, range: Range<Int64>, priority: MediaBoxFetchPriority, error: @escaping (MediaResourceDataFetchError) -> Void, completion: @escaping () -> Void) -> (Int, [(Range<Int64>, MediaBoxFetchPriority)]?) {
let index = self.requestedRanges.add(MediaBoxFileMissingRange(range: range, priority: priority, error: error, completion: completion))
return (index, self.update(fileMap: fileMap))
}
func removeRequest(fileMap: MediaBoxFileMap, index: Int) -> [(Range<Int>, MediaBoxFetchPriority)]? {
func removeRequest(fileMap: MediaBoxFileMap, index: Int) -> [(Range<Int64>, MediaBoxFetchPriority)]? {
self.requestedRanges.remove(index)
return self.update(fileMap: fileMap)
}
private func update(fileMap: MediaBoxFileMap) -> [(Range<Int>, MediaBoxFetchPriority)]? {
private func update(fileMap: MediaBoxFileMap) -> [(Range<Int64>, MediaBoxFetchPriority)]? {
var byPriority: [MediaBoxFetchPriority: IndexSet] = [:]
var flattened = IndexSet()
for item in self.requestedRanges.copyItems() {
@ -857,7 +929,7 @@ private final class MediaBoxFileMissingRanges {
}
private enum MediaBoxFileContent {
case complete(String, Int)
case complete(String, Int64)
case partial(MediaBoxPartialFile)
}
@ -883,7 +955,7 @@ final class MediaBoxFileContext {
self.partialPath = partialPath
self.metaPath = metaPath
var completeImpl: ((Int32) -> Void)?
var completeImpl: ((Int64) -> Void)?
if let size = fileSize(path) {
self.content = .complete(path, size)
} else if let file = MediaBoxPartialFile(queue: queue, path: partialPath, metaPath: metaPath, completePath: path, completed: { size in
@ -893,7 +965,7 @@ final class MediaBoxFileContext {
completeImpl = { [weak self] size in
queue.async {
if let strongSelf = self {
strongSelf.content = .complete(path, Int(size))
strongSelf.content = .complete(path, size)
}
}
}
@ -914,35 +986,35 @@ final class MediaBoxFileContext {
self.references.remove(index)
}
func data(range: Range<Int32>, waitUntilAfterInitialFetch: Bool, next: @escaping (MediaResourceData) -> Void) -> Disposable {
func data(range: Range<Int64>, waitUntilAfterInitialFetch: Bool, next: @escaping (MediaResourceData) -> Void) -> Disposable {
switch self.content {
case let .complete(path, size):
var lowerBound = range.lowerBound
if lowerBound < 0 {
lowerBound = 0
}
if lowerBound > Int(size) {
lowerBound = Int32(clamping: size)
if lowerBound > size {
lowerBound = size
}
var upperBound = range.upperBound
if upperBound < 0 {
upperBound = 0
}
if upperBound > Int(size) {
upperBound = Int32(clamping: size)
if upperBound > size {
upperBound = size
}
if upperBound < lowerBound {
upperBound = lowerBound
}
next(MediaResourceData(path: path, offset: Int(lowerBound), size: Int(upperBound - lowerBound), complete: true))
next(MediaResourceData(path: path, offset: lowerBound, size: upperBound - lowerBound, complete: true))
return EmptyDisposable
case let .partial(file):
return file.data(range: range, waitUntilAfterInitialFetch: waitUntilAfterInitialFetch, next: next)
}
}
func fetched(range: Range<Int32>, priority: MediaBoxFetchPriority, fetch: @escaping (Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>, error: @escaping (MediaResourceDataFetchError) -> Void, completed: @escaping () -> Void) -> Disposable {
func fetched(range: Range<Int64>, priority: MediaBoxFetchPriority, fetch: @escaping (Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>, error: @escaping (MediaResourceDataFetchError) -> Void, completed: @escaping () -> Void) -> Disposable {
switch self.content {
case .complete:
return EmptyDisposable
@ -951,7 +1023,7 @@ final class MediaBoxFileContext {
}
}
func fetchedFullRange(fetch: @escaping (Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>, error: @escaping (MediaResourceDataFetchError) -> Void, completed: @escaping () -> Void) -> Disposable {
func fetchedFullRange(fetch: @escaping (Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>, error: @escaping (MediaResourceDataFetchError) -> Void, completed: @escaping () -> Void) -> Disposable {
switch self.content {
case .complete:
return EmptyDisposable
@ -972,7 +1044,7 @@ final class MediaBoxFileContext {
func rangeStatus(next: @escaping (IndexSet) -> Void, completed: @escaping () -> Void) -> Disposable {
switch self.content {
case let .complete(_, size):
next(IndexSet(integersIn: 0 ..< size))
next(IndexSet(integersIn: 0 ..< Int(size)))
completed()
return EmptyDisposable
case let .partial(file):
@ -980,7 +1052,7 @@ final class MediaBoxFileContext {
}
}
func status(next: @escaping (MediaResourceStatus) -> Void, completed: @escaping () -> Void, size: Int32?) -> Disposable {
func status(next: @escaping (MediaResourceStatus) -> Void, completed: @escaping () -> Void, size: Int64?) -> Disposable {
switch self.content {
case .complete:
next(.Local)

View file

@ -10,7 +10,7 @@ public struct MediaResourceId: Equatable, Hashable {
public protocol MediaResource {
var id: MediaResourceId { get }
var size: Int? { get }
var size: Int64? { get }
var streamable: Bool { get }
var headerSize: Int32 { get }
@ -18,10 +18,6 @@ public protocol MediaResource {
}
public extension MediaResource {
var size: Int? {
return nil
}
var streamable: Bool {
return false
}

View file

@ -179,7 +179,7 @@ private struct AutomaticDownloadPeers {
let otherPrivate: Bool
let groups: Bool
let channels: Bool
let size: Int32?
let size: Int64?
init(category: MediaAutoDownloadCategory) {
self.contacts = category.contacts

View file

@ -47,10 +47,10 @@ private enum AutomaticDownloadPeerType {
private final class AutodownloadMediaCategoryControllerArguments {
let togglePeer: (AutomaticDownloadPeerType) -> Void
let adjustSize: (Int32) -> Void
let adjustSize: (Int64) -> Void
let toggleVideoPreload: () -> Void
init(togglePeer: @escaping (AutomaticDownloadPeerType) -> Void, adjustSize: @escaping (Int32) -> Void, toggleVideoPreload: @escaping () -> Void) {
init(togglePeer: @escaping (AutomaticDownloadPeerType) -> Void, adjustSize: @escaping (Int64) -> Void, toggleVideoPreload: @escaping () -> Void) {
self.togglePeer = togglePeer
self.adjustSize = adjustSize
self.toggleVideoPreload = toggleVideoPreload
@ -70,7 +70,7 @@ private enum AutodownloadMediaCategoryEntry: ItemListNodeEntry {
case peerChannels(PresentationTheme, String, Bool)
case sizeHeader(PresentationTheme, String)
case sizeItem(PresentationTheme, PresentationStrings, String, String, Int32)
case sizeItem(PresentationTheme, PresentationStrings, String, String, Int64)
case sizePreload(PresentationTheme, String, Bool, Bool)
case sizePreloadInfo(PresentationTheme, String)
@ -226,7 +226,7 @@ private func autodownloadMediaCategoryControllerEntries(presentationData: Presen
let categories = effectiveAutodownloadCategories(settings: settings, networkType: connectionType.automaticDownloadNetworkType)
let peers: AutomaticDownloadPeers
let size: Int32
let size: Int64
let predownload: Bool
switch category {
@ -270,7 +270,7 @@ private func autodownloadMediaCategoryControllerEntries(presentationData: Presen
}
let sizeText: String
if size == Int32.max {
if size == Int64.max {
sizeText = autodownloadDataSizeString(1536 * 1024 * 1024, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator)
} else {
sizeText = autodownloadDataSizeString(Int64(size), decimalSeparator: presentationData.dateTimeFormat.decimalSeparator)

View file

@ -9,7 +9,7 @@ import LegacyComponents
import ItemListUI
import PresentationDataUtils
private let autodownloadSizeValues: [(CGFloat, Int32)] = [
private let autodownloadSizeValues: [(CGFloat, Int64)] = [
(0.000, 512 * 1024),
(0.257, 1024 * 1024),
(0.520, 10 * 1024 * 1024),
@ -17,7 +17,7 @@ private let autodownloadSizeValues: [(CGFloat, Int32)] = [
(1.000, 1536 * 1024 * 1024)
]
private func sliderValue(for size: Int32) -> CGFloat {
private func sliderValue(for size: Int64) -> CGFloat {
for i in 1 ..< autodownloadSizeValues.count {
let (previousValue, previousValueSize) = autodownloadSizeValues[i - 1]
let (value, valueSize) = autodownloadSizeValues[i]
@ -32,13 +32,13 @@ private func sliderValue(for size: Int32) -> CGFloat {
return 0.0
}
private func sizeValue(for sliderValue: CGFloat) -> Int32 {
private func sizeValue(for sliderValue: CGFloat) -> Int64 {
for i in 1 ..< autodownloadSizeValues.count {
let (previousValue, previousValueSize) = autodownloadSizeValues[i - 1]
let (value, valueSize) = autodownloadSizeValues[i]
if value > sliderValue {
let delta = (sliderValue - previousValue) / (value - previousValue) * CGFloat(valueSize - previousValueSize)
return previousValueSize + Int32(delta)
return previousValueSize + Int64(delta)
} else if previousValue == sliderValue {
return previousValueSize
} else if value == sliderValue || i == autodownloadSizeValues.count - 1 {
@ -53,11 +53,11 @@ final class AutodownloadSizeLimitItem: ListViewItem, ItemListItem {
let strings: PresentationStrings
let decimalSeparator: String
let text: String
let value: Int32
let value: Int64
let sectionId: ItemListSectionId
let updated: (Int32) -> Void
let updated: (Int64) -> Void
init(theme: PresentationTheme, strings: PresentationStrings, decimalSeparator: String, text: String, value: Int32, sectionId: ItemListSectionId, updated: @escaping (Int32) -> Void) {
init(theme: PresentationTheme, strings: PresentationStrings, decimalSeparator: String, text: String, value: Int64, sectionId: ItemListSectionId, updated: @escaping (Int64) -> Void) {
self.theme = theme
self.strings = strings
self.decimalSeparator = decimalSeparator
@ -299,4 +299,3 @@ private final class AutodownloadSizeLimitItemNode: ListViewItemNode {
self.item?.updated(value)
}
}

View file

@ -426,20 +426,20 @@ private func stringForUseLessDataSetting(_ dataSaving: VoiceCallDataSaving, stri
}
}
private func stringForAutoDownloadTypes(strings: PresentationStrings, decimalSeparator: String, photo: Bool, videoSize: Int32?, fileSize: Int32?) -> String {
private func stringForAutoDownloadTypes(strings: PresentationStrings, decimalSeparator: String, photo: Bool, videoSize: Int64?, fileSize: Int64?) -> String {
var types: [String] = []
if photo && videoSize == nil {
types.append(strings.ChatSettings_AutoDownloadSettings_TypePhoto)
}
if let videoSize = videoSize {
if photo {
types.append(strings.ChatSettings_AutoDownloadSettings_TypeMedia(autodownloadDataSizeString(Int64(videoSize), decimalSeparator: decimalSeparator)).string)
types.append(strings.ChatSettings_AutoDownloadSettings_TypeMedia(autodownloadDataSizeString(videoSize, decimalSeparator: decimalSeparator)).string)
} else {
types.append(strings.ChatSettings_AutoDownloadSettings_TypeVideo(autodownloadDataSizeString(Int64(videoSize), decimalSeparator: decimalSeparator)).string)
types.append(strings.ChatSettings_AutoDownloadSettings_TypeVideo(autodownloadDataSizeString(videoSize, decimalSeparator: decimalSeparator)).string)
}
}
if let fileSize = fileSize {
types.append(strings.ChatSettings_AutoDownloadSettings_TypeFile(autodownloadDataSizeString(Int64(fileSize), decimalSeparator: decimalSeparator)).string)
types.append(strings.ChatSettings_AutoDownloadSettings_TypeFile(autodownloadDataSizeString(fileSize, decimalSeparator: decimalSeparator)).string)
}
if types.isEmpty {

View file

@ -55,7 +55,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-247016673] = { return Api.AttachMenuPeerType.parse_attachMenuPeerTypePM($0) }
dict[2104224014] = { return Api.AttachMenuPeerType.parse_attachMenuPeerTypeSameBotPM($0) }
dict[-1392388579] = { return Api.Authorization.parse_authorization($0) }
dict[-532532493] = { return Api.AutoDownloadSettings.parse_autoDownloadSettings($0) }
dict[-1896171181] = { return Api.AutoDownloadSettings.parse_autoDownloadSettings($0) }
dict[-1065882623] = { return Api.AvailableReaction.parse_availableReaction($0) }
dict[-177732982] = { return Api.BankCardOpenUrl.parse_bankCardOpenUrl($0) }
dict[1527845466] = { return Api.BaseTheme.parse_baseThemeArctic($0) }
@ -177,7 +177,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[2004110666] = { return Api.DialogFilterSuggested.parse_dialogFilterSuggested($0) }
dict[-445792507] = { return Api.DialogPeer.parse_dialogPeer($0) }
dict[1363483106] = { return Api.DialogPeer.parse_dialogPeerFolder($0) }
dict[512177195] = { return Api.Document.parse_document($0) }
dict[-1881881384] = { return Api.Document.parse_document($0) }
dict[922273905] = { return Api.Document.parse_documentEmpty($0) }
dict[297109817] = { return Api.DocumentAttribute.parse_documentAttributeAnimated($0) }
dict[-1739392570] = { return Api.DocumentAttribute.parse_documentAttributeAudio($0) }
@ -198,14 +198,14 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1417756512] = { return Api.EncryptedChat.parse_encryptedChatEmpty($0) }
dict[1223809356] = { return Api.EncryptedChat.parse_encryptedChatRequested($0) }
dict[1722964307] = { return Api.EncryptedChat.parse_encryptedChatWaiting($0) }
dict[1248893260] = { return Api.EncryptedFile.parse_encryptedFile($0) }
dict[-1476358952] = { return Api.EncryptedFile.parse_encryptedFile($0) }
dict[-1038136962] = { return Api.EncryptedFile.parse_encryptedFileEmpty($0) }
dict[-317144808] = { return Api.EncryptedMessage.parse_encryptedMessage($0) }
dict[594758406] = { return Api.EncryptedMessage.parse_encryptedMessageService($0) }
dict[179611673] = { return Api.ExportedChatInvite.parse_chatInviteExported($0) }
dict[-317687113] = { return Api.ExportedChatInvite.parse_chatInvitePublicJoinRequests($0) }
dict[1571494644] = { return Api.ExportedMessageLink.parse_exportedMessageLink($0) }
dict[1648543603] = { return Api.FileHash.parse_fileHash($0) }
dict[-207944868] = { return Api.FileHash.parse_fileHash($0) }
dict[-11252123] = { return Api.Folder.parse_folder($0) }
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
dict[-1107729093] = { return Api.Game.parse_game($0) }
@ -557,7 +557,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1471006352] = { return Api.PhoneCallDiscardReason.parse_phoneCallDiscardReasonHangup($0) }
dict[-2048646399] = { return Api.PhoneCallDiscardReason.parse_phoneCallDiscardReasonMissed($0) }
dict[-58224696] = { return Api.PhoneCallProtocol.parse_phoneCallProtocol($0) }
dict[-1655957568] = { return Api.PhoneConnection.parse_phoneConnection($0) }
dict[-1665063993] = { return Api.PhoneConnection.parse_phoneConnection($0) }
dict[1667228533] = { return Api.PhoneConnection.parse_phoneConnectionWebrtc($0) }
dict[-82216347] = { return Api.Photo.parse_photo($0) }
dict[590459437] = { return Api.Photo.parse_photoEmpty($0) }
@ -632,7 +632,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[2137295719] = { return Api.SearchResultsPosition.parse_searchResultPosition($0) }
dict[871426631] = { return Api.SecureCredentialsEncrypted.parse_secureCredentialsEncrypted($0) }
dict[-1964327229] = { return Api.SecureData.parse_secureData($0) }
dict[-534283678] = { return Api.SecureFile.parse_secureFile($0) }
dict[2097791614] = { return Api.SecureFile.parse_secureFile($0) }
dict[1679398724] = { return Api.SecureFile.parse_secureFileEmpty($0) }
dict[-1141711456] = { return Api.SecurePasswordKdfAlgo.parse_securePasswordKdfAlgoPBKDF2HMACSHA512iter100000($0) }
dict[-2042159726] = { return Api.SecurePasswordKdfAlgo.parse_securePasswordKdfAlgoSHA512($0) }

View file

@ -472,18 +472,18 @@ public extension Api {
}
public extension Api {
enum AutoDownloadSettings: TypeConstructorDescription {
case autoDownloadSettings(flags: Int32, photoSizeMax: Int32, videoSizeMax: Int32, fileSizeMax: Int32, videoUploadMaxbitrate: Int32)
case autoDownloadSettings(flags: Int32, photoSizeMax: Int32, videoSizeMax: Int64, fileSizeMax: Int64, videoUploadMaxbitrate: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .autoDownloadSettings(let flags, let photoSizeMax, let videoSizeMax, let fileSizeMax, let videoUploadMaxbitrate):
if boxed {
buffer.appendInt32(-532532493)
buffer.appendInt32(-1896171181)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(photoSizeMax, buffer: buffer, boxed: false)
serializeInt32(videoSizeMax, buffer: buffer, boxed: false)
serializeInt32(fileSizeMax, buffer: buffer, boxed: false)
serializeInt64(videoSizeMax, buffer: buffer, boxed: false)
serializeInt64(fileSizeMax, buffer: buffer, boxed: false)
serializeInt32(videoUploadMaxbitrate, buffer: buffer, boxed: false)
break
}
@ -501,10 +501,10 @@ public extension Api {
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
var _3: Int64?
_3 = reader.readInt64()
var _4: Int64?
_4 = reader.readInt64()
var _5: Int32?
_5 = reader.readInt32()
let _c1 = _1 != nil

View file

@ -1130,15 +1130,16 @@ public extension Api {
}
public extension Api {
enum PhoneConnection: TypeConstructorDescription {
case phoneConnection(id: Int64, ip: String, ipv6: String, port: Int32, peerTag: Buffer)
case phoneConnection(flags: Int32, id: Int64, ip: String, ipv6: String, port: Int32, peerTag: Buffer)
case phoneConnectionWebrtc(flags: Int32, id: Int64, ip: String, ipv6: String, port: Int32, username: String, password: String)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .phoneConnection(let id, let ip, let ipv6, let port, let peerTag):
case .phoneConnection(let flags, let id, let ip, let ipv6, let port, let peerTag):
if boxed {
buffer.appendInt32(-1655957568)
buffer.appendInt32(-1665063993)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false)
serializeString(ip, buffer: buffer, boxed: false)
serializeString(ipv6, buffer: buffer, boxed: false)
@ -1162,31 +1163,34 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .phoneConnection(let id, let ip, let ipv6, let port, let peerTag):
return ("phoneConnection", [("id", String(describing: id)), ("ip", String(describing: ip)), ("ipv6", String(describing: ipv6)), ("port", String(describing: port)), ("peerTag", String(describing: peerTag))])
case .phoneConnection(let flags, let id, let ip, let ipv6, let port, let peerTag):
return ("phoneConnection", [("flags", String(describing: flags)), ("id", String(describing: id)), ("ip", String(describing: ip)), ("ipv6", String(describing: ipv6)), ("port", String(describing: port)), ("peerTag", String(describing: peerTag))])
case .phoneConnectionWebrtc(let flags, let id, let ip, let ipv6, let port, let username, let password):
return ("phoneConnectionWebrtc", [("flags", String(describing: flags)), ("id", String(describing: id)), ("ip", String(describing: ip)), ("ipv6", String(describing: ipv6)), ("port", String(describing: port)), ("username", String(describing: username)), ("password", String(describing: password))])
}
}
public static func parse_phoneConnection(_ reader: BufferReader) -> PhoneConnection? {
var _1: Int64?
_1 = reader.readInt64()
var _2: String?
_2 = parseString(reader)
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: String?
_3 = parseString(reader)
var _4: Int32?
_4 = reader.readInt32()
var _5: Buffer?
_5 = parseBytes(reader)
var _4: String?
_4 = parseString(reader)
var _5: Int32?
_5 = reader.readInt32()
var _6: Buffer?
_6 = parseBytes(reader)
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 {
return Api.PhoneConnection.phoneConnection(id: _1!, ip: _2!, ipv6: _3!, port: _4!, peerTag: _5!)
let _c6 = _6 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
return Api.PhoneConnection.phoneConnection(flags: _1!, id: _2!, ip: _3!, ipv6: _4!, port: _5!, peerTag: _6!)
}
else {
return nil

View file

@ -180,18 +180,18 @@ public extension Api {
}
public extension Api {
enum SecureFile: TypeConstructorDescription {
case secureFile(id: Int64, accessHash: Int64, size: Int32, dcId: Int32, date: Int32, fileHash: Buffer, secret: Buffer)
case secureFile(id: Int64, accessHash: Int64, size: Int64, dcId: Int32, date: Int32, fileHash: Buffer, secret: Buffer)
case secureFileEmpty
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .secureFile(let id, let accessHash, let size, let dcId, let date, let fileHash, let secret):
if boxed {
buffer.appendInt32(-534283678)
buffer.appendInt32(2097791614)
}
serializeInt64(id, buffer: buffer, boxed: false)
serializeInt64(accessHash, buffer: buffer, boxed: false)
serializeInt32(size, buffer: buffer, boxed: false)
serializeInt64(size, buffer: buffer, boxed: false)
serializeInt32(dcId, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
serializeBytes(fileHash, buffer: buffer, boxed: false)
@ -220,8 +220,8 @@ public extension Api {
_1 = reader.readInt64()
var _2: Int64?
_2 = reader.readInt64()
var _3: Int32?
_3 = reader.readInt32()
var _3: Int64?
_3 = reader.readInt64()
var _4: Int32?
_4 = reader.readInt32()
var _5: Int32?

View file

@ -565,11 +565,11 @@ public extension Api.functions.account {
}
}
public extension Api.functions.account {
static func initTakeoutSession(flags: Int32, fileMaxSize: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.account.Takeout>) {
static func initTakeoutSession(flags: Int32, fileMaxSize: Int64?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.account.Takeout>) {
let buffer = Buffer()
buffer.appendInt32(-262453244)
buffer.appendInt32(-1896617296)
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 5) != 0 {serializeInt32(fileMaxSize!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 5) != 0 {serializeInt64(fileMaxSize!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "account.initTakeoutSession", parameters: [("flags", String(describing: flags)), ("fileMaxSize", String(describing: fileMaxSize))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.account.Takeout? in
let reader = BufferReader(buffer)
var result: Api.account.Takeout?
@ -4032,11 +4032,11 @@ public extension Api.functions.messages {
}
}
public extension Api.functions.messages {
static func getDocumentByHash(sha256: Buffer, size: Int32, mimeType: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Document>) {
static func getDocumentByHash(sha256: Buffer, size: Int64, mimeType: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Document>) {
let buffer = Buffer()
buffer.appendInt32(864953444)
buffer.appendInt32(-1309538785)
serializeBytes(sha256, buffer: buffer, boxed: false)
serializeInt32(size, buffer: buffer, boxed: false)
serializeInt64(size, buffer: buffer, boxed: false)
serializeString(mimeType, buffer: buffer, boxed: false)
return (FunctionDescription(name: "messages.getDocumentByHash", parameters: [("sha256", String(describing: sha256)), ("size", String(describing: size)), ("mimeType", String(describing: mimeType))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Document? in
let reader = BufferReader(buffer)
@ -7171,11 +7171,11 @@ public extension Api.functions.updates {
}
}
public extension Api.functions.upload {
static func getCdnFile(fileToken: Buffer, offset: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.upload.CdnFile>) {
static func getCdnFile(fileToken: Buffer, offset: Int64, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.upload.CdnFile>) {
let buffer = Buffer()
buffer.appendInt32(536919235)
buffer.appendInt32(962554330)
serializeBytes(fileToken, buffer: buffer, boxed: false)
serializeInt32(offset, buffer: buffer, boxed: false)
serializeInt64(offset, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription(name: "upload.getCdnFile", parameters: [("fileToken", String(describing: fileToken)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.upload.CdnFile? in
let reader = BufferReader(buffer)
@ -7188,11 +7188,11 @@ public extension Api.functions.upload {
}
}
public extension Api.functions.upload {
static func getCdnFileHashes(fileToken: Buffer, offset: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.FileHash]>) {
static func getCdnFileHashes(fileToken: Buffer, offset: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.FileHash]>) {
let buffer = Buffer()
buffer.appendInt32(1302676017)
buffer.appendInt32(-1847836879)
serializeBytes(fileToken, buffer: buffer, boxed: false)
serializeInt32(offset, buffer: buffer, boxed: false)
serializeInt64(offset, buffer: buffer, boxed: false)
return (FunctionDescription(name: "upload.getCdnFileHashes", parameters: [("fileToken", String(describing: fileToken)), ("offset", String(describing: offset))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> [Api.FileHash]? in
let reader = BufferReader(buffer)
var result: [Api.FileHash]?
@ -7204,12 +7204,12 @@ public extension Api.functions.upload {
}
}
public extension Api.functions.upload {
static func getFile(flags: Int32, location: Api.InputFileLocation, offset: Int32, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.upload.File>) {
static func getFile(flags: Int32, location: Api.InputFileLocation, offset: Int64, limit: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.upload.File>) {
let buffer = Buffer()
buffer.appendInt32(-1319462148)
buffer.appendInt32(-1101843010)
serializeInt32(flags, buffer: buffer, boxed: false)
location.serialize(buffer, true)
serializeInt32(offset, buffer: buffer, boxed: false)
serializeInt64(offset, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
return (FunctionDescription(name: "upload.getFile", parameters: [("flags", String(describing: flags)), ("location", String(describing: location)), ("offset", String(describing: offset)), ("limit", String(describing: limit))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.upload.File? in
let reader = BufferReader(buffer)

View file

@ -1074,14 +1074,14 @@ public extension Api {
}
public extension Api {
enum Document: TypeConstructorDescription {
case document(flags: Int32, id: Int64, accessHash: Int64, fileReference: Buffer, date: Int32, mimeType: String, size: Int32, thumbs: [Api.PhotoSize]?, videoThumbs: [Api.VideoSize]?, dcId: Int32, attributes: [Api.DocumentAttribute])
case document(flags: Int32, id: Int64, accessHash: Int64, fileReference: Buffer, date: Int32, mimeType: String, size: Int64, thumbs: [Api.PhotoSize]?, videoThumbs: [Api.VideoSize]?, dcId: Int32, attributes: [Api.DocumentAttribute])
case documentEmpty(id: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .document(let flags, let id, let accessHash, let fileReference, let date, let mimeType, let size, let thumbs, let videoThumbs, let dcId, let attributes):
if boxed {
buffer.appendInt32(512177195)
buffer.appendInt32(-1881881384)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(id, buffer: buffer, boxed: false)
@ -1089,7 +1089,7 @@ public extension Api {
serializeBytes(fileReference, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
serializeString(mimeType, buffer: buffer, boxed: false)
serializeInt32(size, buffer: buffer, boxed: false)
serializeInt64(size, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(thumbs!.count))
for item in thumbs! {
@ -1138,8 +1138,8 @@ public extension Api {
_5 = reader.readInt32()
var _6: String?
_6 = parseString(reader)
var _7: Int32?
_7 = reader.readInt32()
var _7: Int64?
_7 = reader.readInt64()
var _8: [Api.PhotoSize]?
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.PhotoSize.self)

View file

@ -390,18 +390,18 @@ public extension Api {
}
public extension Api {
enum EncryptedFile: TypeConstructorDescription {
case encryptedFile(id: Int64, accessHash: Int64, size: Int32, dcId: Int32, keyFingerprint: Int32)
case encryptedFile(id: Int64, accessHash: Int64, size: Int64, dcId: Int32, keyFingerprint: Int32)
case encryptedFileEmpty
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .encryptedFile(let id, let accessHash, let size, let dcId, let keyFingerprint):
if boxed {
buffer.appendInt32(1248893260)
buffer.appendInt32(-1476358952)
}
serializeInt64(id, buffer: buffer, boxed: false)
serializeInt64(accessHash, buffer: buffer, boxed: false)
serializeInt32(size, buffer: buffer, boxed: false)
serializeInt64(size, buffer: buffer, boxed: false)
serializeInt32(dcId, buffer: buffer, boxed: false)
serializeInt32(keyFingerprint, buffer: buffer, boxed: false)
break
@ -428,8 +428,8 @@ public extension Api {
_1 = reader.readInt64()
var _2: Int64?
_2 = reader.readInt64()
var _3: Int32?
_3 = reader.readInt32()
var _3: Int64?
_3 = reader.readInt64()
var _4: Int32?
_4 = reader.readInt32()
var _5: Int32?
@ -664,15 +664,15 @@ public extension Api {
}
public extension Api {
enum FileHash: TypeConstructorDescription {
case fileHash(offset: Int32, limit: Int32, hash: Buffer)
case fileHash(offset: Int64, limit: Int32, hash: Buffer)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .fileHash(let offset, let limit, let hash):
if boxed {
buffer.appendInt32(1648543603)
buffer.appendInt32(-207944868)
}
serializeInt32(offset, buffer: buffer, boxed: false)
serializeInt64(offset, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
serializeBytes(hash, buffer: buffer, boxed: false)
break
@ -687,8 +687,8 @@ public extension Api {
}
public static func parse_fileHash(_ reader: BufferReader) -> FileHash? {
var _1: Int32?
_1 = reader.readInt32()
var _1: Int64?
_1 = reader.readInt64()
var _2: Int32?
_2 = reader.readInt32()
var _3: Buffer?

View file

@ -661,11 +661,11 @@ public enum AccountNetworkState: Equatable {
}
public final class AccountAuxiliaryMethods {
public let fetchResource: (Account, MediaResource, Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>?
public let fetchResource: (Account, MediaResource, Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>?
public let fetchResourceMediaReferenceHash: (MediaResource) -> Signal<Data?, NoError>
public let prepareSecretThumbnailData: (MediaResourceData) -> (PixelDimensions, Data)?
public init(fetchResource: @escaping (Account, MediaResource, Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>?, fetchResourceMediaReferenceHash: @escaping (MediaResource) -> Signal<Data?, NoError>, prepareSecretThumbnailData: @escaping (MediaResourceData) -> (PixelDimensions, Data)?) {
public init(fetchResource: @escaping (Account, MediaResource, Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>?, fetchResourceMediaReferenceHash: @escaping (MediaResource) -> Signal<Data?, NoError>, prepareSecretThumbnailData: @escaping (MediaResourceData) -> (PixelDimensions, Data)?) {
self.fetchResource = fetchResource
self.fetchResourceMediaReferenceHash = fetchResourceMediaReferenceHash
self.prepareSecretThumbnailData = prepareSecretThumbnailData

View file

@ -1,7 +1,7 @@
import Foundation
extension SecretChatFileReference {
func resource(key: SecretFileEncryptionKey, decryptedSize: Int32) -> SecretFileMediaResource {
func resource(key: SecretFileEncryptionKey, decryptedSize: Int64) -> SecretFileMediaResource {
return SecretFileMediaResource(fileId: self.id, accessHash: self.accessHash, containerSize: self.size, decryptedSize: decryptedSize, datacenterId: Int(self.datacenterId), key: key)
}
}

View file

@ -164,7 +164,7 @@ func telegramMediaFileFromApiDocument(_ document: Api.Document) -> TelegramMedia
}
}
return TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: Int(size), fileReference: fileReference.makeData(), fileName: fileNameFromFileAttributes(parsedAttributes)), previewRepresentations: previewRepresentations, videoThumbnails: videoThumbnails, immediateThumbnailData: immediateThumbnail, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
return TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: size, fileReference: fileReference.makeData(), fileName: fileNameFromFileAttributes(parsedAttributes)), previewRepresentations: previewRepresentations, videoThumbnails: videoThumbnails, immediateThumbnailData: immediateThumbnail, mimeType: mimeType, size: size, attributes: parsedAttributes)
case .documentEmpty:
return nil
}

View file

@ -12,11 +12,11 @@ func telegramMediaImageRepresentationsFromApiSizes(datacenterId: Int32, photoId:
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: nil, fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
case let .photoSize(type, w, h, size):
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int(size), fileReference: fileReference)
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(size), fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
case let .photoSizeProgressive(type, w, h, sizes):
if !sizes.isEmpty {
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int(sizes[sizes.count - 1]), fileReference: fileReference)
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(sizes[sizes.count - 1]), fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil))
}
case let .photoStrippedSize(_, data):
@ -46,7 +46,7 @@ func telegramMediaImageFromApiPhoto(_ photo: Api.Photo) -> TelegramMediaImage? {
switch size {
case let .videoSize(_, type, w, h, size, videoStartTs):
let resource: TelegramMediaResource
resource = CloudPhotoSizeMediaResource(datacenterId: dcId, photoId: id, accessHash: accessHash, sizeSpec: type, size: Int(size), fileReference: fileReference.makeData())
resource = CloudPhotoSizeMediaResource(datacenterId: dcId, photoId: id, accessHash: accessHash, sizeSpec: type, size: Int64(size), fileReference: fileReference.makeData())
videoRepresentations.append(TelegramMediaImage.VideoRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, startTimestamp: videoStartTs))
}

View file

@ -7,9 +7,9 @@ extension TelegramMediaWebFile {
convenience init(_ document: Api.WebDocument) {
switch document {
case let .webDocument(url, accessHash, size, mimeType, attributes):
self.init(resource: WebFileReferenceMediaResource(url: url, size: size, accessHash: accessHash), mimeType: mimeType, size: size, attributes: telegramMediaFileAttributesFromApiAttributes(attributes))
self.init(resource: WebFileReferenceMediaResource(url: url, size: Int64(size), accessHash: accessHash), mimeType: mimeType, size: size, attributes: telegramMediaFileAttributesFromApiAttributes(attributes))
case let .webDocumentNoProxy(url, size, mimeType, attributes):
self.init(resource: HttpReferenceMediaResource(url: url, size: Int(size)), mimeType: mimeType, size: size, attributes: telegramMediaFileAttributesFromApiAttributes(attributes))
self.init(resource: HttpReferenceMediaResource(url: url, size: Int64(size)), mimeType: mimeType, size: size, attributes: telegramMediaFileAttributesFromApiAttributes(attributes))
}
}
}

View file

@ -235,7 +235,7 @@ class Download: NSObject, MTRequestMessageServiceDelegate {
} |> retryRequest
}
func part(location: Api.InputFileLocation, offset: Int, length: Int) -> Signal<Data, NoError> {
func part(location: Api.InputFileLocation, offset: Int64, length: Int) -> Signal<Data, NoError> {
return Signal<Data, MTRpcError> { subscriber in
let request = MTRequest()
@ -244,7 +244,7 @@ class Download: NSObject, MTRequestMessageServiceDelegate {
updatedLength += 1
}
let data = Api.functions.upload.getFile(flags: 0, location: location, offset: Int32(offset), limit: Int32(updatedLength))
let data = Api.functions.upload.getFile(flags: 0, location: location, offset: offset, limit: Int32(updatedLength))
request.setPayload(data.1.makeData() as Data, metadata: WrappedRequestMetadata(metadata: WrappedFunctionDescription(data.0), tag: nil), shortMetadata: WrappedRequestShortMetadata(shortMetadata: WrappedShortFunctionDescription(data.0)), responseParser: { response in
if let result = data.2.parse(Buffer(data: response)) {

View file

@ -10,7 +10,7 @@ public func fetchHttpResource(url: String) -> Signal<MediaResourceDataFetchResul
subscriber.putNext(.reset)
let disposable = signal.start(next: { next in
if let response = next as? MTHttpResponse {
let fetchResult: MediaResourceDataFetchResult = .dataPart(resourceOffset: 0, data: response.data, range: 0 ..< response.data.count, complete: true)
let fetchResult: MediaResourceDataFetchResult = .dataPart(resourceOffset: 0, data: response.data, range: 0 ..< Int64(response.data.count), complete: true)
subscriber.putNext(fetchResult)
subscriber.putCompletion()
} else {

View file

@ -25,11 +25,11 @@ final class TelegramCloudMediaResourceFetchInfo: MediaResourceFetchInfo {
}
}
public func fetchedMediaResource(mediaBox: MediaBox, reference: MediaResourceReference, range: (Range<Int>, MediaBoxFetchPriority)? = nil, statsCategory: MediaResourceStatsCategory = .generic, reportResultStatus: Bool = false, preferBackgroundReferenceRevalidation: Bool = false, continueInBackground: Bool = false) -> Signal<FetchResourceSourceType, FetchResourceError> {
public func fetchedMediaResource(mediaBox: MediaBox, reference: MediaResourceReference, range: (Range<Int64>, MediaBoxFetchPriority)? = nil, statsCategory: MediaResourceStatsCategory = .generic, reportResultStatus: Bool = false, preferBackgroundReferenceRevalidation: Bool = false, continueInBackground: Bool = false) -> Signal<FetchResourceSourceType, FetchResourceError> {
return fetchedMediaResource(mediaBox: mediaBox, reference: reference, ranges: range.flatMap({ [$0] }), statsCategory: statsCategory, reportResultStatus: reportResultStatus, preferBackgroundReferenceRevalidation: preferBackgroundReferenceRevalidation, continueInBackground: continueInBackground)
}
public func fetchedMediaResource(mediaBox: MediaBox, reference: MediaResourceReference, ranges: [(Range<Int>, MediaBoxFetchPriority)]?, statsCategory: MediaResourceStatsCategory = .generic, reportResultStatus: Bool = false, preferBackgroundReferenceRevalidation: Bool = false, continueInBackground: Bool = false) -> Signal<FetchResourceSourceType, FetchResourceError> {
public func fetchedMediaResource(mediaBox: MediaBox, reference: MediaResourceReference, ranges: [(Range<Int64>, MediaBoxFetchPriority)]?, statsCategory: MediaResourceStatsCategory = .generic, reportResultStatus: Bool = false, preferBackgroundReferenceRevalidation: Bool = false, continueInBackground: Bool = false) -> Signal<FetchResourceSourceType, FetchResourceError> {
var isRandomAccessAllowed = true
switch reference {
case let .media(media, _):

View file

@ -4,17 +4,28 @@ import SwiftSignalKit
import TelegramApi
import MtProtoKit
private extension Range where Bound == Int64 {
func asIntRange() -> Range<Int> {
return Int(self.lowerBound) ..< Int(self.upperBound)
}
}
private extension Range where Bound == Int {
func asInt64Range() -> Range<Int64> {
return Int64(self.lowerBound) ..< Int64(self.upperBound)
}
}
private typealias SignalKitTimer = SwiftSignalKit.Timer
private final class MultipartDownloadState {
let aesKey: Data
var aesIv: Data
let decryptedSize: Int32?
let decryptedSize: Int64?
var currentSize: Int32 = 0
var currentSize: Int64 = 0
init(encryptionKey: SecretFileEncryptionKey?, decryptedSize: Int32?) {
init(encryptionKey: SecretFileEncryptionKey?, decryptedSize: Int64?) {
if let encryptionKey = encryptionKey {
self.aesKey = encryptionKey.aesKey
self.aesIv = encryptionKey.aesIv
@ -25,13 +36,13 @@ private final class MultipartDownloadState {
self.decryptedSize = decryptedSize
}
func transform(offset: Int, data: Data) -> Data {
func transform(offset: Int64, data: Data) -> Data {
if self.aesKey.count != 0 {
var decryptedData = data
assert(decryptedSize != nil)
assert(decryptedData.count % 16 == 0)
let decryptedDataCount = decryptedData.count
assert(offset == Int(self.currentSize))
assert(offset == self.currentSize)
decryptedData.withUnsafeMutableBytes { rawBytes -> Void in
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
self.aesIv.withUnsafeMutableBytes { rawIv -> Void in
@ -39,10 +50,10 @@ private final class MultipartDownloadState {
MTAesDecryptBytesInplaceAndModifyIv(bytes, decryptedDataCount, self.aesKey, iv)
}
}
if self.currentSize + Int32(decryptedData.count) > self.decryptedSize! {
if self.currentSize + Int64(decryptedData.count) > self.decryptedSize! {
decryptedData.count = Int(self.decryptedSize! - self.currentSize)
}
self.currentSize += Int32(decryptedData.count)
self.currentSize += Int64(decryptedData.count)
return decryptedData
} else {
return data
@ -52,7 +63,7 @@ private final class MultipartDownloadState {
private enum MultipartFetchDownloadError {
case generic
case switchToCdn(id: Int32, token: Data, key: Data, iv: Data, partHashes: [Int32: Data])
case switchToCdn(id: Int32, token: Data, key: Data, iv: Data, partHashes: [Int64: Data])
case reuploadToCdn(masterDatacenterId: Int32, token: Data)
case revalidateMediaReference
case hashesMissing
@ -96,7 +107,7 @@ private struct DownloadWrapper {
}
}
private func roundUp(_ value: Int, to multiple: Int) -> Int {
private func roundUp(_ value: Int64, to multiple: Int64) -> Int64 {
if multiple == 0 {
return value
}
@ -109,15 +120,15 @@ private func roundUp(_ value: Int, to multiple: Int) -> Int {
return value + multiple - remainder
}
private let dataHashLength: Int32 = 128 * 1024
private let dataHashLength: Int64 = 128 * 1024
private final class MultipartCdnHashSource {
private final class ClusterContext {
final class Subscriber {
let completion: ([Int32: Data]) -> Void
let completion: ([Int64: Data]) -> Void
let error: (MultipartFetchDownloadError) -> Void
init(completion: @escaping ([Int32: Data]) -> Void, error: @escaping (MultipartFetchDownloadError) -> Void) {
init(completion: @escaping ([Int64: Data]) -> Void, error: @escaping (MultipartFetchDownloadError) -> Void) {
self.completion = completion
self.error = error
}
@ -126,7 +137,7 @@ private final class MultipartCdnHashSource {
let disposable: Disposable
let subscribers = Bag<Subscriber>()
var result: [Int32: Data]?
var result: [Int64: Data]?
var error: MultipartFetchDownloadError?
init(disposable: Disposable) {
@ -144,153 +155,22 @@ private final class MultipartCdnHashSource {
private let masterDownload: DownloadWrapper
private let continueInBackground: Bool
private var clusterContexts: [Int32: ClusterContext] = [:]
private var clusterContexts: [Int64: ClusterContext] = [:]
/*private var knownUpperBound: Int32
private var hashes: [Int32: Data] = [:]
private var requestOffsetAndDisposable: (Int32, Disposable)?
private var requestedUpperBound: Int32?
private var subscribers = Bag<(Int32, Int32, ([Int32: Data]) -> Void)>()*/
init(queue: Queue, fileToken: Data, hashes: [Int32: Data], masterDownload: DownloadWrapper, continueInBackground: Bool) {
init(queue: Queue, fileToken: Data, hashes: [Int64: Data], masterDownload: DownloadWrapper, continueInBackground: Bool) {
assert(queue.isCurrent())
self.queue = queue
self.fileToken = fileToken
self.masterDownload = masterDownload
self.continueInBackground = continueInBackground
/*let knownUpperBound: Int32 = 0
self.knownUpperBound = knownUpperBound*/
}
deinit {
assert(self.queue.isCurrent())
//self.requestOffsetAndDisposable?.1.dispose()
}
/*private func take(offset: Int32, limit: Int32) -> [Int32: Data]? {
assert(offset % dataHashLength == 0)
assert(limit % dataHashLength == 0)
var result: [Int32: Data] = [:]
var localOffset: Int32 = 0
while localOffset < limit {
if let hash = self.hashes[offset + localOffset] {
result[offset + localOffset] = hash
} else {
return nil
}
localOffset += dataHashLength
}
return result
}*/
/*func get(offset: Int32, limit: Int32) -> Signal<[Int32: Data], MultipartFetchDownloadError> {
assert(self.queue.isCurrent())
let queue = self.queue
return Signal { [weak self] subscriber in
let disposable = MetaDisposable()
queue.async {
if let strongSelf = self {
if let result = strongSelf.take(offset: offset, limit: limit) {
subscriber.putNext(result)
subscriber.putCompletion()
} else {
let index = strongSelf.subscribers.add((offset, limit, { result in
subscriber.putNext(result)
subscriber.putCompletion()
}))
disposable.set(ActionDisposable {
queue.async {
if let strongSelf = self {
strongSelf.subscribers.remove(index)
}
}
})
if let requestedUpperBound = strongSelf.requestedUpperBound {
strongSelf.requestedUpperBound = max(requestedUpperBound, offset + limit)
} else {
strongSelf.requestedUpperBound = offset + limit
}
if strongSelf.requestOffsetAndDisposable == nil {
strongSelf.requestMore()
} else {
if let requestedUpperBound = strongSelf.requestedUpperBound {
strongSelf.requestedUpperBound = max(requestedUpperBound, offset + limit)
} else {
strongSelf.requestedUpperBound = offset + limit
}
}
}
}
}
return disposable
}
}
private func requestMore() {
assert(self.queue.isCurrent())
let requestOffset = self.knownUpperBound
let disposable = MetaDisposable()
self.requestOffsetAndDisposable = (requestOffset, disposable)
let queue = self.queue
let fileToken = self.fileToken
disposable.set((self.masterDownload.request(Api.functions.upload.getCdnFileHashes(fileToken: Buffer(data: fileToken), offset: requestOffset), tag: nil, continueInBackground: self.continueInBackground)
|> map { partHashes -> [Int32: Data] in
var parsedPartHashes: [Int32: Data] = [:]
for part in partHashes {
switch part {
case let .fileHash(offset, limit, bytes):
assert(limit == 128 * 1024)
parsedPartHashes[offset] = bytes.makeData()
}
}
return parsedPartHashes
}
|> `catch` { _ -> Signal<[Int32: Data], NoError> in
return .single([:])
} |> deliverOn(queue)).start(next: { [weak self] result in
if let strongSelf = self {
if strongSelf.requestOffsetAndDisposable?.0 == requestOffset {
strongSelf.requestOffsetAndDisposable = nil
for (hashOffset, hashData) in result {
assert(hashOffset % dataHashLength == 0)
strongSelf.knownUpperBound = max(strongSelf.knownUpperBound, hashOffset + dataHashLength)
strongSelf.hashes[hashOffset] = hashData
}
for (index, item) in strongSelf.subscribers.copyItemsWithIndices() {
let (offset, limit, subscriber) = item
if let data = strongSelf.take(offset: offset, limit: limit) {
strongSelf.subscribers.remove(index)
subscriber(data)
}
}
if let requestedUpperBound = strongSelf.requestedUpperBound, requestedUpperBound > strongSelf.knownUpperBound {
strongSelf.requestMore()
}
} else {
//assertionFailure()
}
}
}))
}*/
func getCluster(offset: Int32, completion: @escaping ([Int32: Data]) -> Void, error: @escaping (MultipartFetchDownloadError) -> Void) -> Disposable {
func getCluster(offset: Int64, completion: @escaping ([Int64: Data]) -> Void, error: @escaping (MultipartFetchDownloadError) -> Void) -> Disposable {
precondition(offset % (1 * 1024 * 1024) == 0)
let clusterContext: ClusterContext
@ -302,8 +182,8 @@ private final class MultipartCdnHashSource {
self.clusterContexts[offset] = clusterContext
disposable.set((self.masterDownload.request(Api.functions.upload.getCdnFileHashes(fileToken: Buffer(data: self.fileToken), offset: offset), tag: nil, continueInBackground: self.continueInBackground)
|> map { partHashes -> [Int32: Data] in
var parsedPartHashes: [Int32: Data] = [:]
|> map { partHashes -> [Int64: Data] in
var parsedPartHashes: [Int64: Data] = [:]
for part in partHashes {
switch part {
case let .fileHash(offset, limit, bytes):
@ -359,7 +239,7 @@ private final class MultipartCdnHashSource {
}
}
private func cluster(offset: Int32) -> Signal<[Int32: Data], MultipartFetchDownloadError> {
private func cluster(offset: Int64) -> Signal<[Int64: Data], MultipartFetchDownloadError> {
let queue = self.queue
return Signal { [weak self] subscriber in
let disposable = MetaDisposable()
@ -382,11 +262,11 @@ private final class MultipartCdnHashSource {
}
}
func get(offset: Int32, limit: Int32) -> Signal<[Int32: Data], MultipartFetchDownloadError> {
func get(offset: Int64, limit: Int64) -> Signal<[Int64: Data], MultipartFetchDownloadError> {
precondition(offset % dataHashLength == 0)
precondition((offset + limit) % dataHashLength == 0)
var clusterOffsets = Set<Int32>()
var clusterOffsets = Set<Int64>()
for partOffset in stride(from: offset, to: offset + limit, by: Int(dataHashLength)) {
clusterOffsets.insert(partOffset - (partOffset % (1 * 1024 * 1024)))
}
@ -394,8 +274,8 @@ private final class MultipartCdnHashSource {
return combineLatest(clusterOffsets.map { clusterOffset in
return self.cluster(offset: clusterOffset)
})
|> mapToSignal { clusterResults -> Signal<[Int32: Data], MultipartFetchDownloadError> in
var result: [Int32: Data] = [:]
|> mapToSignal { clusterResults -> Signal<[Int64: Data], MultipartFetchDownloadError> in
var result: [Int64: Data] = [:]
for partOffset in stride(from: offset, to: offset + limit, by: Int(dataHashLength)) {
var found = false
@ -420,7 +300,7 @@ private enum MultipartFetchSource {
case master(location: MultipartFetchMasterLocation, download: DownloadWrapper)
case cdn(masterDatacenterId: Int32, fileToken: Data, key: Data, iv: Data, download: DownloadWrapper, masterDownload: DownloadWrapper, hashSource: MultipartCdnHashSource)
func request(offset: Int32, limit: Int32, tag: MediaResourceFetchTag?, resource: TelegramMediaResource, resourceReference: FetchResourceReference, fileReference: Data?, continueInBackground: Bool) -> Signal<Data, MultipartFetchDownloadError> {
func request(offset: Int64, limit: Int64, tag: MediaResourceFetchTag?, resource: TelegramMediaResource, resourceReference: FetchResourceReference, fileReference: Data?, continueInBackground: Bool) -> Signal<Data, MultipartFetchDownloadError> {
var resourceReferenceValue: MediaResourceReference?
switch resourceReference {
case .forceRevalidate:
@ -462,7 +342,7 @@ private enum MultipartFetchSource {
}
return .single(resultData)
case let .fileCdnRedirect(dcId, fileToken, encryptionKey, encryptionIv, partHashes):
var parsedPartHashes: [Int32: Data] = [:]
var parsedPartHashes: [Int64: Data] = [:]
for part in partHashes {
switch part {
case let .fileHash(offset, limit, bytes):
@ -475,7 +355,7 @@ private enum MultipartFetchSource {
}
}
case let .web(_, location):
return download.request(Api.functions.upload.getWebFile(location: location, offset: offset, limit: Int32(limit)), tag: tag, continueInBackground: continueInBackground)
return download.request(Api.functions.upload.getWebFile(location: location, offset: Int32(offset), limit: Int32(limit)), tag: tag, continueInBackground: continueInBackground)
|> mapError { error -> MultipartFetchDownloadError in
return .generic
}
@ -491,7 +371,7 @@ private enum MultipartFetchSource {
}
}
case let .cdn(masterDatacenterId, fileToken, key, iv, download, _, hashSource):
var updatedLength = roundUp(Int(limit), to: 4096)
var updatedLength = roundUp(Int64(limit), to: 4096)
while updatedLength % 4096 != 0 || 1048576 % updatedLength != 0 {
updatedLength += 1
}
@ -512,7 +392,7 @@ private enum MultipartFetchSource {
let partIvCount = partIv.count
partIv.withUnsafeMutableBytes { rawBytes -> Void in
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
var ivOffset: Int32 = (offset / 16).bigEndian
var ivOffset: Int64 = (offset / 16).bigEndian
memcpy(bytes.advanced(by: partIvCount - 4), &ivOffset, 4)
}
return .single(MTAesCtrDecrypt(bytes.makeData(), key, partIv)!)
@ -521,23 +401,23 @@ private enum MultipartFetchSource {
}
return combineLatest(part, hashSource.get(offset: offset, limit: limit))
|> mapToSignal { partData, hashData -> Signal<Data, MultipartFetchDownloadError> in
var localOffset = 0
while localOffset < partData.count {
let dataToHash = partData.subdata(in: localOffset ..< min(partData.count, localOffset + Int(dataHashLength)))
if let hash = hashData[offset + Int32(localOffset)] {
let localHash = MTSha256(dataToHash)
if localHash != hash {
return .fail(.generic)
}
} else {
|> mapToSignal { partData, hashData -> Signal<Data, MultipartFetchDownloadError> in
var localOffset: Int64 = 0
while localOffset < partData.count {
let dataToHash = partData.subdata(in: Int(localOffset) ..< min(partData.count, Int(localOffset + Int64(dataHashLength))))
if let hash = hashData[offset + localOffset] {
let localHash = MTSha256(dataToHash)
if localHash != hash {
return .fail(.generic)
}
localOffset += Int(dataHashLength)
} else {
return .fail(.generic)
}
return .single(partData)
localOffset += Int64(dataHashLength)
}
return .single(partData)
}
}
}
}
@ -550,8 +430,8 @@ private enum FetchResourceReference {
private final class MultipartFetchManager {
let parallelParts: Int
let defaultPartSize: Int
var partAlignment = 4 * 1024
let defaultPartSize: Int64
var partAlignment: Int64 = 4 * 1024
var resource: TelegramMediaResource
var resourceReference: FetchResourceReference
@ -561,26 +441,26 @@ private final class MultipartFetchManager {
let queue = Queue()
var currentIntervals: [(Range<Int>, MediaBoxFetchPriority)]?
var currentIntervals: [(Range<Int64>, MediaBoxFetchPriority)]?
var currentFilledRanges = IndexSet()
var completeSize: Int?
var completeSize: Int64?
var completeSizeReported = false
let postbox: Postbox
let network: Network
let revalidationContext: MediaReferenceRevalidationContext?
let continueInBackground: Bool
let partReady: (Int, Data) -> Void
let reportCompleteSize: (Int) -> Void
let partReady: (Int64, Data) -> Void
let reportCompleteSize: (Int64) -> Void
private let useMainConnection: Bool
private var source: MultipartFetchSource
var fetchingParts: [Int: (Int, Disposable)] = [:]
var fetchingParts: [Int64: (Int64, Disposable)] = [:]
var nextFetchingPartId = 0
var fetchedParts: [Int: (Int, Data)] = [:]
var cachedPartHashes: [Int: Data] = [:]
var fetchedParts: [Int64: (Int64, Data)] = [:]
var cachedPartHashes: [Int64: Data] = [:]
var reuploadingToCdn = false
let reuploadToCdnDisposable = MetaDisposable()
@ -593,7 +473,7 @@ private final class MultipartFetchManager {
var rangesDisposable: Disposable?
init(resource: TelegramMediaResource, parameters: MediaResourceFetchParameters?, size: Int?, intervals: Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, encryptionKey: SecretFileEncryptionKey?, decryptedSize: Int32?, location: MultipartFetchMasterLocation, postbox: Postbox, network: Network, revalidationContext: MediaReferenceRevalidationContext?, partReady: @escaping (Int, Data) -> Void, reportCompleteSize: @escaping (Int) -> Void, useMainConnection: Bool) {
init(resource: TelegramMediaResource, parameters: MediaResourceFetchParameters?, size: Int64?, intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, encryptionKey: SecretFileEncryptionKey?, decryptedSize: Int64?, location: MultipartFetchMasterLocation, postbox: Postbox, network: Network, revalidationContext: MediaReferenceRevalidationContext?, partReady: @escaping (Int64, Data) -> Void, reportCompleteSize: @escaping (Int64) -> Void, useMainConnection: Bool) {
self.resource = resource
self.parameters = parameters
self.consumerId = Int64.random(in: Int64.min ... Int64.max)
@ -698,8 +578,8 @@ private final class MultipartFetchManager {
let isSingleContiguousRange = currentIntervals.count == 1
for offset in self.fetchedParts.keys.sorted() {
if let (_, data) = self.fetchedParts[offset] {
let partRange = offset ..< (offset + data.count)
removeFromFetchIntervals.insert(integersIn: partRange)
let partRange = offset ..< (offset + Int64(data.count))
removeFromFetchIntervals.insert(integersIn: Int(partRange.lowerBound) ..< Int(partRange.upperBound))
var hasEarlierFetchingPart = false
if isSingleContiguousRange {
@ -712,7 +592,7 @@ private final class MultipartFetchManager {
}
if !hasEarlierFetchingPart {
self.currentFilledRanges.insert(integersIn: partRange)
self.currentFilledRanges.insert(integersIn: Int(partRange.lowerBound) ..< Int(partRange.upperBound))
self.fetchedParts.removeValue(forKey: offset)
self.partReady(offset, self.state.transform(offset: offset, data: data))
}
@ -720,21 +600,21 @@ private final class MultipartFetchManager {
}
for (offset, (size, _)) in self.fetchingParts {
removeFromFetchIntervals.insert(integersIn: offset ..< (offset + size))
removeFromFetchIntervals.insert(integersIn: Int(offset) ..< Int(offset + size))
}
if let completeSize = self.completeSize {
self.currentFilledRanges.insert(integersIn: completeSize ..< Int.max)
removeFromFetchIntervals.insert(integersIn: completeSize ..< Int.max)
self.currentFilledRanges.insert(integersIn: Int(completeSize) ..< Int.max)
removeFromFetchIntervals.insert(integersIn: Int(completeSize) ..< Int.max)
}
var intervalsToFetch: [(Range<Int>, MediaBoxFetchPriority)] = []
var intervalsToFetch: [(Range<Int64>, MediaBoxFetchPriority)] = []
for (interval, priority) in currentIntervals {
var intervalIndexSet = IndexSet(integersIn: interval)
var intervalIndexSet = IndexSet(integersIn: Int(interval.lowerBound) ..< Int(interval.upperBound))
intervalIndexSet.subtract(removeFromFetchIntervals)
for cleanInterval in intervalIndexSet.rangeView {
assert(!cleanInterval.isEmpty)
intervalsToFetch.append((cleanInterval, priority))
intervalsToFetch.append((Int64(cleanInterval.lowerBound) ..< Int64(cleanInterval.upperBound), priority))
}
}
@ -743,7 +623,7 @@ private final class MultipartFetchManager {
self.completeSizeReported = true
assert(self.fetchedParts.isEmpty)
if let decryptedSize = self.state.decryptedSize {
self.reportCompleteSize(Int(decryptedSize))
self.reportCompleteSize(decryptedSize)
} else {
self.reportCompleteSize(completeSize)
}
@ -770,8 +650,8 @@ private final class MultipartFetchManager {
}
self.nextFetchingPartId += 1
let (firstInterval, priority) = intervalsToFetch[currentIntervalIndex]
var downloadRange: Range<Int> = firstInterval.lowerBound ..< min(firstInterval.lowerBound + self.defaultPartSize, firstInterval.upperBound)
let rawRange: Range<Int> = downloadRange
var downloadRange: Range<Int64> = firstInterval.lowerBound ..< min(firstInterval.lowerBound + self.defaultPartSize, firstInterval.upperBound)
let rawRange: Range<Int64> = downloadRange
if downloadRange.lowerBound % self.partAlignment != 0 {
let previousBoundary = (downloadRange.lowerBound / self.partAlignment) * self.partAlignment
downloadRange = previousBoundary ..< downloadRange.upperBound
@ -788,26 +668,26 @@ private final class MultipartFetchManager {
downloadRange = downloadRange.lowerBound ..< (downloadRange.upperBound - 1)
}
var intervalIndexSet = IndexSet(integersIn: intervalsToFetch[currentIntervalIndex].0)
intervalIndexSet.remove(integersIn: downloadRange)
var intervalIndexSet = IndexSet(integersIn: intervalsToFetch[currentIntervalIndex].0.asIntRange())
intervalIndexSet.remove(integersIn: downloadRange.asIntRange())
intervalsToFetch.remove(at: currentIntervalIndex)
var insertIndex = currentIntervalIndex
for interval in intervalIndexSet.rangeView {
intervalsToFetch.insert((interval, priority), at: insertIndex)
intervalsToFetch.insert((interval.asInt64Range(), priority), at: insertIndex)
insertIndex += 1
}
let part = self.source.request(offset: Int32(downloadRange.lowerBound), limit: Int32(downloadRange.count), tag: self.parameters?.tag, resource: self.resource, resourceReference: self.resourceReference, fileReference: self.fileReference, continueInBackground: self.continueInBackground)
let part = self.source.request(offset: Int64(downloadRange.lowerBound), limit: Int64(downloadRange.count), tag: self.parameters?.tag, resource: self.resource, resourceReference: self.resourceReference, fileReference: self.fileReference, continueInBackground: self.continueInBackground)
|> deliverOn(self.queue)
let partDisposable = MetaDisposable()
self.fetchingParts[downloadRange.lowerBound] = (downloadRange.count, partDisposable)
self.fetchingParts[downloadRange.lowerBound] = (Int64(downloadRange.count), partDisposable)
partDisposable.set(part.start(next: { [weak self] data in
guard let strongSelf = self else {
return
}
if data.count < downloadRange.count {
strongSelf.completeSize = downloadRange.lowerBound + data.count
strongSelf.completeSize = downloadRange.lowerBound + Int64(data.count)
}
let _ = strongSelf.fetchingParts.removeValue(forKey: downloadRange.lowerBound)
strongSelf.fetchedParts[downloadRange.lowerBound] = (rawRange.lowerBound, data)
@ -849,7 +729,7 @@ private final class MultipartFetchManager {
case let .switchToCdn(id, token, key, iv, partHashes):
switch strongSelf.source {
case let .master(location, download):
strongSelf.partAlignment = Int(dataHashLength)
strongSelf.partAlignment = dataHashLength
strongSelf.source = .cdn(masterDatacenterId: location.datacenterId, fileToken: token, key: key, iv: iv, download: DownloadWrapper(consumerId: strongSelf.consumerId, datacenterId: id, isCdn: true, network: strongSelf.network, useMainConnection: strongSelf.useMainConnection), masterDownload: download, hashSource: MultipartCdnHashSource(queue: strongSelf.queue, fileToken: token, hashes: partHashes, masterDownload: download, continueInBackground: strongSelf.continueInBackground))
strongSelf.checkState()
case .cdn, .none:
@ -882,7 +762,7 @@ private final class MultipartFetchManager {
}
}
public func standaloneMultipartFetch(postbox: Postbox, network: Network, resource: TelegramMediaResource, datacenterId: Int, size: Int?, intervals: Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?, encryptionKey: SecretFileEncryptionKey? = nil, decryptedSize: Int32? = nil, continueInBackground: Bool = false, useMainConnection: Bool = false) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
public func standaloneMultipartFetch(postbox: Postbox, network: Network, resource: TelegramMediaResource, datacenterId: Int, size: Int64?, intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?, encryptionKey: SecretFileEncryptionKey? = nil, decryptedSize: Int32? = nil, continueInBackground: Bool = false, useMainConnection: Bool = false) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
return multipartFetch(
postbox: postbox,
network: network,
@ -904,7 +784,7 @@ public func resourceFetchInfo(resource: TelegramMediaResource) -> MediaResourceF
)
}
func multipartFetch(postbox: Postbox, network: Network, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext?, resource: TelegramMediaResource, datacenterId: Int, size: Int?, intervals: Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?, encryptionKey: SecretFileEncryptionKey? = nil, decryptedSize: Int32? = nil, continueInBackground: Bool = false, useMainConnection: Bool = false) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
func multipartFetch(postbox: Postbox, network: Network, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext?, resource: TelegramMediaResource, datacenterId: Int, size: Int64?, intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?, encryptionKey: SecretFileEncryptionKey? = nil, decryptedSize: Int64? = nil, continueInBackground: Bool = false, useMainConnection: Bool = false) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
return Signal { subscriber in
let location: MultipartFetchMasterLocation
if let resource = resource as? WebFileReferenceMediaResource {
@ -958,7 +838,7 @@ func multipartFetch(postbox: Postbox, network: Network, mediaReferenceRevalidati
}
let manager = MultipartFetchManager(resource: resource, parameters: parameters, size: size, intervals: intervals, encryptionKey: encryptionKey, decryptedSize: decryptedSize, location: location, postbox: postbox, network: network, revalidationContext: mediaReferenceRevalidationContext, partReady: { dataOffset, data in
subscriber.putNext(.dataPart(resourceOffset: dataOffset, data: data, range: 0 ..< data.count, complete: false))
subscriber.putNext(.dataPart(resourceOffset: dataOffset, data: data, range: 0 ..< Int64(data.count), complete: false))
}, reportCompleteSize: { size in
subscriber.putNext(.resourceSizeUpdated(size))
subscriber.putCompletion()

View file

@ -27,7 +27,7 @@ private func md5(_ data: Data) -> Data {
private final class MultipartUploadState {
let aesKey: Data
var aesIv: Data
var effectiveSize: Int = 0
var effectiveSize: Int64 = 0
init(encryptionKey: SecretFileEncryptionKey?) {
if let encryptionKey = encryptionKey {
@ -41,7 +41,7 @@ private final class MultipartUploadState {
func transformHeader(data: Data) -> Data {
assert(self.aesKey.isEmpty)
self.effectiveSize += data.count
self.effectiveSize += Int64(data.count)
return data
}
@ -66,15 +66,15 @@ private final class MultipartUploadState {
MTAesEncryptBytesInplaceAndModifyIv(bytes, encryptedDataCount, self.aesKey, iv)
}
}
self.effectiveSize += encryptedData.count
self.effectiveSize += Int64(encryptedData.count)
return encryptedData
} else {
self.effectiveSize += data.count
self.effectiveSize += Int64(data.count)
return data
}
}
func finalize() -> Int {
func finalize() -> Int64 {
return self.effectiveSize
}
}
@ -83,7 +83,7 @@ private struct MultipartIntermediateResult {
let id: Int64
let partCount: Int32
let md5Digest: String
let size: Int32
let size: Int64
let bigTotalParts: Int?
}
@ -91,20 +91,20 @@ private enum MultipartUploadData {
case resourceData(MediaResourceData)
case data(Data)
var size: Int {
var size: Int64 {
switch self {
case let .resourceData(data):
return data.size
case let .data(data):
return data.count
case let .resourceData(data):
return data.size
case let .data(data):
return Int64(data.count)
}
}
var complete: Bool {
switch self {
case let .resourceData(data):
return data.complete
case .data:
return true
case let .resourceData(data):
return data.complete
case .data:
return true
}
}
}
@ -117,7 +117,7 @@ private enum HeaderPartState {
private final class MultipartUploadManager {
let parallelParts: Int
var defaultPartSize: Int
var defaultPartSize: Int64
var bigTotalParts: Int?
var bigParts: Bool
private let forceNoBigParts: Bool
@ -128,13 +128,13 @@ private final class MultipartUploadManager {
let dataSignal: Signal<MultipartUploadData, NoError>
var committedOffset: Int
var committedOffset: Int64
let uploadPart: (UploadPart) -> Signal<Void, UploadPartError>
let progress: (Float) -> Void
let completed: (MultipartIntermediateResult?) -> Void
var uploadingParts: [Int: (Int, Disposable)] = [:]
var uploadedParts: [Int: Int] = [:]
var uploadingParts: [Int64: (Int64, Disposable)] = [:]
var uploadedParts: [Int64: Int64] = [:]
let dataDisposable = MetaDisposable()
var resourceData: MultipartUploadData?
@ -143,7 +143,7 @@ private final class MultipartUploadManager {
let state: MultipartUploadState
init(headerSize: Int32, data: Signal<MultipartUploadData, NoError>, encryptionKey: SecretFileEncryptionKey?, hintFileSize: Int?, hintFileIsLarge: Bool, forceNoBigParts: Bool, useLargerParts: Bool, increaseParallelParts: Bool, uploadPart: @escaping (UploadPart) -> Signal<Void, UploadPartError>, progress: @escaping (Float) -> Void, completed: @escaping (MultipartIntermediateResult?) -> Void) {
init(headerSize: Int32, data: Signal<MultipartUploadData, NoError>, encryptionKey: SecretFileEncryptionKey?, hintFileSize: Int64?, hintFileIsLarge: Bool, forceNoBigParts: Bool, useLargerParts: Bool, increaseParallelParts: Bool, uploadPart: @escaping (UploadPart) -> Signal<Void, UploadPartError>, progress: @escaping (Float) -> Void, completed: @escaping (MultipartIntermediateResult?) -> Void) {
self.dataSignal = data
var fileId: Int64 = 0
@ -174,7 +174,7 @@ private final class MultipartUploadManager {
if let hintFileSize = hintFileSize, hintFileSize > 10 * 1024 * 1024, !forceNoBigParts {
self.defaultPartSize = 512 * 1024
self.bigTotalParts = (hintFileSize / self.defaultPartSize) + (hintFileSize % self.defaultPartSize == 0 ? 0 : 1)
self.bigTotalParts = Int((hintFileSize / self.defaultPartSize) + (hintFileSize % self.defaultPartSize == 0 ? 0 : 1))
self.bigParts = true
} else if hintFileIsLarge, !forceNoBigParts {
self.defaultPartSize = 512 * 1024
@ -216,7 +216,7 @@ private final class MultipartUploadManager {
if self.committedOffset == 0 && self.uploadedParts.isEmpty && self.uploadingParts.isEmpty {
if resourceData.size > 10 * 1024 * 1024, !self.forceNoBigParts {
self.defaultPartSize = 512 * 1024
self.bigTotalParts = (resourceData.size / self.defaultPartSize) + (resourceData.size % self.defaultPartSize == 0 ? 0 : 1)
self.bigTotalParts = Int(resourceData.size / self.defaultPartSize) + (resourceData.size % self.defaultPartSize == 0 ? 0 : 1)
self.bigParts = true
} else {
self.bigParts = false
@ -252,13 +252,13 @@ private final class MultipartUploadManager {
let effectivePartCount = Int32(effectiveSize / self.defaultPartSize + (effectiveSize % self.defaultPartSize == 0 ? 0 : 1))
var currentBigTotalParts = self.bigTotalParts
if self.bigParts {
currentBigTotalParts = (resourceData.size / self.defaultPartSize) + (resourceData.size % self.defaultPartSize == 0 ? 0 : 1)
currentBigTotalParts = Int(resourceData.size / self.defaultPartSize) + (resourceData.size % self.defaultPartSize == 0 ? 0 : 1)
}
self.completed(MultipartIntermediateResult(id: self.fileId, partCount: effectivePartCount, md5Digest: "", size: Int32(resourceData.size), bigTotalParts: currentBigTotalParts))
self.completed(MultipartIntermediateResult(id: self.fileId, partCount: effectivePartCount, md5Digest: "", size: resourceData.size, bigTotalParts: currentBigTotalParts))
case .notStarted:
let partOffset = 0
let partOffset: Int64 = 0
let partSize = min(resourceData.size - partOffset, self.defaultPartSize)
let partIndex = partOffset / self.defaultPartSize
let partIndex = Int(partOffset / self.defaultPartSize)
let fileData: Data?
switch resourceData {
case let .resourceData(data):
@ -267,11 +267,11 @@ private final class MultipartUploadManager {
fileData = data
}
if let fileData = fileData {
let partData = self.state.transformHeader(data: fileData.subdata(in: partOffset ..< (partOffset + partSize)))
let partData = self.state.transformHeader(data: fileData.subdata(in: Int(partOffset) ..< Int(partOffset + partSize)))
var currentBigTotalParts: Int? = nil
if self.bigParts {
let totalParts = (resourceData.size / self.defaultPartSize) + (resourceData.size % self.defaultPartSize == 0 ? 0 : 1)
currentBigTotalParts = totalParts
currentBigTotalParts = Int(totalParts)
}
self.headerPartState = .uploading
let part = self.uploadPart(UploadPart(fileId: self.fileId, index: partIndex, data: partData, bigTotalParts: currentBigTotalParts, bigPart: self.bigParts))
@ -312,13 +312,13 @@ private final class MultipartUploadManager {
let partSize = min(resourceData.size - partOffset, self.defaultPartSize)
if nextOffset < resourceData.size && partSize > 0 && (resourceData.complete || partSize == self.defaultPartSize) {
let partIndex = partOffset / self.defaultPartSize
let partIndex = Int(partOffset / self.defaultPartSize)
let partData: Data?
switch resourceData {
case let .resourceData(data):
if let file = ManagedFile(queue: nil, path: data.path, mode: .read) {
file.seek(position: Int64(partOffset))
let data = file.readData(count: partSize)
let data = file.readData(count: Int(partSize))
if data.count == partSize {
partData = data
} else {
@ -329,7 +329,7 @@ private final class MultipartUploadManager {
}
case let .data(data):
if data.count >= partOffset + partSize {
partData = data.subdata(in: partOffset ..< (partOffset + partSize))
partData = data.subdata(in: Int(partOffset) ..< Int(partOffset + partSize))
} else {
partData = nil
}
@ -338,7 +338,7 @@ private final class MultipartUploadManager {
let partData = self.state.transform(data: partData)
var currentBigTotalParts = self.bigTotalParts
if self.bigParts && resourceData.complete && partOffset + partSize == resourceData.size {
currentBigTotalParts = (resourceData.size / self.defaultPartSize) + (resourceData.size % self.defaultPartSize == 0 ? 0 : 1)
currentBigTotalParts = Int(resourceData.size / self.defaultPartSize) + (resourceData.size % self.defaultPartSize == 0 ? 0 : 1)
}
let part = self.uploadPart(UploadPart(fileId: self.fileId, index: partIndex, data: partData, bigTotalParts: currentBigTotalParts, bigPart: self.bigParts))
|> deliverOn(self.queue)
@ -376,7 +376,7 @@ private final class MultipartUploadManager {
enum MultipartUploadResult {
case progress(Float)
case inputFile(Api.InputFile)
case inputSecretFile(Api.InputEncryptedFile, Int32, SecretFileEncryptionKey)
case inputSecretFile(Api.InputEncryptedFile, Int64, SecretFileEncryptionKey)
}
public enum MultipartUploadSource {
@ -390,7 +390,7 @@ enum MultipartUploadError {
case generic
}
func multipartUpload(network: Network, postbox: Postbox, source: MultipartUploadSource, encrypt: Bool, tag: MediaResourceFetchTag?, hintFileSize: Int?, hintFileIsLarge: Bool, forceNoBigParts: Bool, useLargerParts: Bool = false, increaseParallelParts: Bool = false, useMultiplexedRequests: Bool = true, useCompression: Bool = false) -> Signal<MultipartUploadResult, MultipartUploadError> {
func multipartUpload(network: Network, postbox: Postbox, source: MultipartUploadSource, encrypt: Bool, tag: MediaResourceFetchTag?, hintFileSize: Int64?, hintFileIsLarge: Bool, forceNoBigParts: Bool, useLargerParts: Bool = false, increaseParallelParts: Bool = false, useMultiplexedRequests: Bool = true, useCompression: Bool = false) -> Signal<MultipartUploadResult, MultipartUploadError> {
enum UploadInterface {
case download(Download)
case multiplexed(manager: MultiplexedRequestManager, datacenterId: Int, consumerId: Int64)

View file

@ -9,7 +9,7 @@ enum PendingMessageUploadedContent {
case media(Api.InputMedia, String)
case forward(ForwardSourceInfoAttribute)
case chatContextResult(OutgoingChatContextResultMessageAttribute)
case secretMedia(Api.InputEncryptedFile, Int32, SecretFileEncryptionKey)
case secretMedia(Api.InputEncryptedFile, Int64, SecretFileEncryptionKey)
case messageScreenshot
}
@ -610,11 +610,11 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
}
var hintFileIsLarge = false
var hintSize: Int?
var hintSize: Int64?
if let size = file.size {
hintSize = size
} else if let resource = file.resource as? LocalFileReferenceMediaResource, let size = resource.size {
hintSize = Int(size)
hintSize = size
}
loop: for attribute in file.attributes {

View file

@ -165,7 +165,7 @@ private func uploadedImage(account: Account, data: Data) -> Signal<UploadMediaEv
}
private func uploadedFile(account: Account, data: Data, mimeType: String, attributes: [TelegramMediaFileAttribute]) -> Signal<UploadMediaEvent, PendingMessageUploadError> {
return multipartUpload(network: account.network, postbox: account.postbox, source: .data(data), encrypt: false, tag: TelegramMediaResourceFetchTag(statsCategory: statsCategoryForFileWithAttributes(attributes)), hintFileSize: data.count, hintFileIsLarge: false, forceNoBigParts: false)
return multipartUpload(network: account.network, postbox: account.postbox, source: .data(data), encrypt: false, tag: TelegramMediaResourceFetchTag(statsCategory: statsCategoryForFileWithAttributes(attributes)), hintFileSize: Int64(data.count), hintFileIsLarge: false, forceNoBigParts: false)
|> mapError { _ -> PendingMessageUploadError in return .generic }
|> map { next -> UploadMediaEvent in
switch next {

View file

@ -101,7 +101,7 @@ public func standaloneUploadedImage(account: Account, peerId: PeerId, text: Stri
|> mapToSignal { result -> Signal<StandaloneUploadMediaEvent, StandaloneUploadMediaError> in
switch result {
case let .encryptedFile(id, accessHash, size, dcId, _):
return .single(.result(.media(.standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: Int32(data.count), datacenterId: Int(dcId), key: key), progressiveSizes: [], immediateThumbnailData: nil)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])))))
return .single(.result(.media(.standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: Int64(data.count), datacenterId: Int(dcId), key: key), progressiveSizes: [], immediateThumbnailData: nil)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])))))
case .encryptedFileEmpty:
return .fail(.generic)
}
@ -194,7 +194,7 @@ public func standaloneUploadedFile(account: Account, peerId: PeerId, text: Strin
|> mapToSignal { result -> Signal<StandaloneUploadMediaEvent, StandaloneUploadMediaError> in
switch result {
case let .encryptedFile(id, accessHash, size, dcId, _):
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: size, datacenterId: Int(dcId), key: key), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: attributes)
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: size, datacenterId: Int(dcId), key: key), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: size, attributes: attributes)
return .single(.result(.media(.standalone(media: media))))
case .encryptedFileEmpty:

View file

@ -22,7 +22,7 @@ extension AutodownloadPresetSettings {
init(apiAutodownloadSettings: Api.AutoDownloadSettings) {
switch apiAutodownloadSettings {
case let .autoDownloadSettings(flags, photoSizeMax, videoSizeMax, fileSizeMax, videoUploadMaxbitrate):
self.init(disabled: (flags & (1 << 0)) != 0, photoSizeMax: photoSizeMax, videoSizeMax: videoSizeMax, fileSizeMax: fileSizeMax, preloadLargeVideo: (flags & (1 << 1)) != 0, lessDataForPhoneCalls: (flags & (1 << 3)) != 0, videoUploadMaxbitrate: videoUploadMaxbitrate)
self.init(disabled: (flags & (1 << 0)) != 0, photoSizeMax: Int64(photoSizeMax), videoSizeMax: videoSizeMax, fileSizeMax: fileSizeMax, preloadLargeVideo: (flags & (1 << 1)) != 0, lessDataForPhoneCalls: (flags & (1 << 3)) != 0, videoUploadMaxbitrate: videoUploadMaxbitrate)
}
}
}
@ -47,6 +47,6 @@ func apiAutodownloadPresetSettings(_ autodownloadPresetSettings: AutodownloadPre
if autodownloadPresetSettings.lessDataForPhoneCalls {
flags |= (1 << 3)
}
return .autoDownloadSettings(flags: flags, photoSizeMax: autodownloadPresetSettings.photoSizeMax, videoSizeMax: autodownloadPresetSettings.videoSizeMax, fileSizeMax: autodownloadPresetSettings.fileSizeMax, videoUploadMaxbitrate: autodownloadPresetSettings.videoUploadMaxbitrate)
return .autoDownloadSettings(flags: flags, photoSizeMax: Int32(autodownloadPresetSettings.photoSizeMax), videoSizeMax: autodownloadPresetSettings.videoSizeMax, fileSizeMax: autodownloadPresetSettings.fileSizeMax, videoUploadMaxbitrate: autodownloadPresetSettings.videoUploadMaxbitrate)
}

View file

@ -217,6 +217,7 @@ public enum CallSessionConnection: Equatable {
public let id: Int64
public let ip: String
public let ipv6: String
public let isTcp: Bool
public let port: Int32
public let peerTag: Data
@ -224,12 +225,14 @@ public enum CallSessionConnection: Equatable {
id: Int64,
ip: String,
ipv6: String,
isTcp: Bool,
port: Int32,
peerTag: Data
) {
self.id = id
self.ip = ip
self.ipv6 = ipv6
self.isTcp = isTcp
self.port = port
self.peerTag = peerTag
}
@ -272,8 +275,9 @@ public enum CallSessionConnection: Equatable {
private func parseConnection(_ apiConnection: Api.PhoneConnection) -> CallSessionConnection {
switch apiConnection {
case let .phoneConnection(id, ip, ipv6, port, peerTag):
return .reflector(CallSessionConnection.Reflector(id: id, ip: ip, ipv6: ipv6, port: port, peerTag: peerTag.makeData()))
case let .phoneConnection(flags, id, ip, ipv6, port, peerTag):
let isTcp = (flags & (1 << 0)) != 0
return .reflector(CallSessionConnection.Reflector(id: id, ip: ip, ipv6: ipv6, isTcp: isTcp, port: port, peerTag: peerTag.makeData()))
case let .phoneConnectionWebrtc(flags, id, ip, ipv6, port, username, password):
return .webRtcReflector(CallSessionConnection.WebRtcReflector(
id: id,

View file

@ -22,7 +22,7 @@ private final class MediaResourceDataCopyFile : MediaResourceDataFetchCopyLocalI
}
}
public func fetchCloudMediaLocation(account: Account, resource: TelegramMediaResource, datacenterId: Int, size: Int?, intervals: Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
public func fetchCloudMediaLocation(account: Account, resource: TelegramMediaResource, datacenterId: Int, size: Int64?, intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
return multipartFetch(postbox: account.postbox, network: account.network, mediaReferenceRevalidationContext: account.mediaReferenceRevalidationContext, resource: resource, datacenterId: datacenterId, size: size, intervals: intervals, parameters: parameters)
}
@ -39,7 +39,7 @@ private func fetchLocalFileResource(path: String, move: Bool) -> Signal<MediaRes
}
}
func fetchResource(account: Account, resource: MediaResource, intervals: Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>? {
func fetchResource(account: Account, resource: MediaResource, intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError>? {
if let _ = resource as? EmptyMediaResource {
return .single(.reset)
|> then(.never())

View file

@ -4,6 +4,6 @@ import SwiftSignalKit
import MtProtoKit
func fetchSecretFileResource(account: Account, resource: SecretFileMediaResource, intervals: Signal<[(Range<Int>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
func fetchSecretFileResource(account: Account, resource: SecretFileMediaResource, intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
return multipartFetch(postbox: account.postbox, network: account.network, mediaReferenceRevalidationContext: account.mediaReferenceRevalidationContext, resource: resource, datacenterId: resource.datacenterId, size: resource.size, intervals: intervals, parameters: parameters, encryptionKey: resource.key, decryptedSize: resource.decryptedSize)
}

View file

@ -825,7 +825,7 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g
arc4random_buf(randomBytesData, 15)
let randomBytes = Buffer(memory: randomBytesData, size: 15, capacity: 15, freeWhenDone: true)
let decryptedMedia = SecretApi8.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: thumb, thumbW: thumbW, thumbH: thumbH, w: Int32(largestRepresentation.dimensions.width), h: Int32(largestRepresentation.dimensions.height), size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv))
let decryptedMedia = SecretApi8.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: thumb, thumbW: thumbW, thumbH: thumbH, w: Int32(largestRepresentation.dimensions.width), h: Int32(largestRepresentation.dimensions.height), size: Int32(uploadedFile.size), key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv))
return .layer8(.decryptedMessage(randomId: globallyUniqueId, randomBytes: randomBytes, message: message.text, media: decryptedMedia))
case .layer46:
@ -835,7 +835,7 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g
if let _ = viaBotName {
flags |= (1 << 11)
}
let decryptedMedia = SecretApi46.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: thumb, thumbW: thumbW, thumbH: thumbH, w: Int32(largestRepresentation.dimensions.width), h: Int32(largestRepresentation.dimensions.height), size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), caption: "")
let decryptedMedia = SecretApi46.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: thumb, thumbW: thumbW, thumbH: thumbH, w: Int32(largestRepresentation.dimensions.width), h: Int32(largestRepresentation.dimensions.height), size: Int32(uploadedFile.size), key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), caption: "")
flags |= (1 << 9)
return .layer46(.decryptedMessage(flags: flags, randomId: globallyUniqueId, ttl: messageAutoremoveTimeout, message: message.text, media: decryptedMedia, entities: nil, viaBotName: viaBotName, replyToRandomId: replyGlobalId))
case .layer73:
@ -849,7 +849,7 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g
if let _ = decryptedEntites {
flags |= (1 << 7)
}
let decryptedMedia = SecretApi73.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: thumb, thumbW: thumbW, thumbH: thumbH, w: Int32(largestRepresentation.dimensions.width), h: Int32(largestRepresentation.dimensions.height), size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), caption: "")
let decryptedMedia = SecretApi73.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: thumb, thumbW: thumbW, thumbH: thumbH, w: Int32(largestRepresentation.dimensions.width), h: Int32(largestRepresentation.dimensions.height), size: Int32(uploadedFile.size), key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), caption: "")
flags |= (1 << 9)
if message.groupingKey != nil {
flags |= (1 << 17)
@ -866,7 +866,7 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g
if let _ = decryptedEntites {
flags |= (1 << 7)
}
let decryptedMedia = SecretApi101.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: thumb, thumbW: thumbW, thumbH: thumbH, w: Int32(largestRepresentation.dimensions.width), h: Int32(largestRepresentation.dimensions.height), size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), caption: "")
let decryptedMedia = SecretApi101.DecryptedMessageMedia.decryptedMessageMediaPhoto(thumb: thumb, thumbW: thumbW, thumbH: thumbH, w: Int32(largestRepresentation.dimensions.width), h: Int32(largestRepresentation.dimensions.height), size: Int32(uploadedFile.size), key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), caption: "")
flags |= (1 << 9)
if message.groupingKey != nil {
flags |= (1 << 17)
@ -894,7 +894,7 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g
arc4random_buf(randomBytesData, 15)
let randomBytes = Buffer(memory: randomBytesData, size: 15, capacity: 15, freeWhenDone: true)
let decryptedMedia = SecretApi8.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: thumb, thumbW: thumbW, thumbH: thumbH, fileName: file.fileName ?? "file", mimeType: file.mimeType, size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv))
let decryptedMedia = SecretApi8.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: thumb, thumbW: thumbW, thumbH: thumbH, fileName: file.fileName ?? "file", mimeType: file.mimeType, size: Int32(uploadedFile.size), key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv))
return .layer8(.decryptedMessage(randomId: globallyUniqueId, randomBytes: randomBytes, message: message.text, media: decryptedMedia))
}
@ -913,9 +913,9 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g
}
if let voiceDuration = voiceDuration {
decryptedMedia = SecretApi46.DecryptedMessageMedia.decryptedMessageMediaAudio(duration: voiceDuration, mimeType: file.mimeType, size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv))
decryptedMedia = SecretApi46.DecryptedMessageMedia.decryptedMessageMediaAudio(duration: voiceDuration, mimeType: file.mimeType, size: Int32(uploadedFile.size), key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv))
} else {
decryptedMedia = SecretApi46.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: thumb, thumbW: thumbW, thumbH: thumbH, mimeType: file.mimeType, size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), attributes: decryptedAttributes46(file.attributes, transaction: transaction), caption: "")
decryptedMedia = SecretApi46.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: thumb, thumbW: thumbW, thumbH: thumbH, mimeType: file.mimeType, size: Int32(uploadedFile.size), key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), attributes: decryptedAttributes46(file.attributes, transaction: transaction), caption: "")
}
} else {
if let resource = file.resource as? CloudDocumentMediaResource, let size = file.size {
@ -943,7 +943,7 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g
var decryptedMedia: SecretApi73.DecryptedMessageMedia?
if let uploadedFile = uploadedFile {
decryptedMedia = SecretApi73.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: thumb, thumbW: thumbW, thumbH: thumbH, mimeType: file.mimeType, size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), attributes: decryptedAttributes73(file.attributes, transaction: transaction), caption: "")
decryptedMedia = SecretApi73.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: thumb, thumbW: thumbW, thumbH: thumbH, mimeType: file.mimeType, size: Int32(uploadedFile.size), key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), attributes: decryptedAttributes73(file.attributes, transaction: transaction), caption: "")
} else {
if let resource = file.resource as? CloudDocumentMediaResource, let size = file.size {
let thumb: SecretApi73.PhotoSize
@ -977,7 +977,7 @@ private func boxedDecryptedMessage(transaction: Transaction, message: Message, g
var decryptedMedia: SecretApi101.DecryptedMessageMedia?
if let uploadedFile = uploadedFile {
decryptedMedia = SecretApi101.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: thumb, thumbW: thumbW, thumbH: thumbH, mimeType: file.mimeType, size: uploadedFile.size, key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), attributes: decryptedAttributes101(file.attributes, transaction: transaction), caption: "")
decryptedMedia = SecretApi101.DecryptedMessageMedia.decryptedMessageMediaDocument(thumb: thumb, thumbW: thumbW, thumbH: thumbH, mimeType: file.mimeType, size: Int32(uploadedFile.size), key: Buffer(data: uploadedFile.key.aesKey), iv: Buffer(data: uploadedFile.key.aesIv), attributes: decryptedAttributes101(file.attributes, transaction: transaction), caption: "")
} else {
if let resource = file.resource as? CloudDocumentMediaResource, let size = file.size {
let thumb: SecretApi101.PhotoSize

View file

@ -56,7 +56,7 @@ private final class MessageMediaPreuploadManagerContext {
}))
}
func upload(network: Network, postbox: Postbox, source: MultipartUploadSource, encrypt: Bool, tag: MediaResourceFetchTag?, hintFileSize: Int?, hintFileIsLarge: Bool) -> Signal<MultipartUploadResult, MultipartUploadError> {
func upload(network: Network, postbox: Postbox, source: MultipartUploadSource, encrypt: Bool, tag: MediaResourceFetchTag?, hintFileSize: Int64?, hintFileIsLarge: Bool) -> Signal<MultipartUploadResult, MultipartUploadError> {
let queue = self.queue
return Signal { [weak self] subscriber in
if let strongSelf = self {
@ -118,7 +118,7 @@ final class MessageMediaPreuploadManager {
}
}
func upload(network: Network, postbox: Postbox, source: MultipartUploadSource, encrypt: Bool, tag: MediaResourceFetchTag?, hintFileSize: Int?, hintFileIsLarge: Bool) -> Signal<MultipartUploadResult, MultipartUploadError> {
func upload(network: Network, postbox: Postbox, source: MultipartUploadSource, encrypt: Bool, tag: MediaResourceFetchTag?, hintFileSize: Int64?, hintFileIsLarge: Bool) -> Signal<MultipartUploadResult, MultipartUploadError> {
return Signal<Signal<MultipartUploadResult, MultipartUploadError>, MultipartUploadError> { subscriber in
self.impl.with { context in
subscriber.putNext(context.upload(network: network, postbox: postbox, source: source, encrypt: encrypt, tag: tag, hintFileSize: hintFileSize, hintFileIsLarge: hintFileIsLarge))

View file

@ -699,13 +699,13 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
resources.append((resource, thumb.makeData()))
}
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), progressiveSizes: [], immediateThumbnailData: nil))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil))
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
parsedMedia.append(image)
}
case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv):
if let file = file {
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: [TelegramMediaFileAttribute.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: [TelegramMediaFileAttribute.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])
parsedMedia.append(fileMedia)
}
case let .decryptedMessageMediaDocument(thumb, thumbW, thumbH, mimeType, size, key, iv, attributes, caption):
@ -725,7 +725,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
resources.append((resource, thumb.makeData()))
}
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
parsedMedia.append(fileMedia)
}
case let .decryptedMessageMediaVideo(thumb, thumbW, thumbH, duration, mimeType, w, h, size, key, iv, caption):
@ -740,7 +740,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
resources.append((resource, thumb.makeData()))
}
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
parsedMedia.append(fileMedia)
}
case let .decryptedMessageMediaExternalDocument(id, accessHash, _, mimeType, size, thumb, dcId, attributes):
@ -755,7 +755,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .photoSize(_, location, w, h, size):
switch location {
case let .fileLocation(dcId, volumeId, localId, secret):
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil))
case .fileLocationUnavailable:
break
}
@ -763,7 +763,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
if bytes.size > 0 {
switch location {
case let .fileLocation(dcId, volumeId, localId, secret):
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: bytes.size, fileReference: nil)
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil)
resources.append((resource, bytes.makeData()))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
case .fileLocationUnavailable:
@ -773,7 +773,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
default:
break
}
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: Int(size), fileReference: nil, fileName: nil), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: Int64(size), fileReference: nil, fileName: nil), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
parsedMedia.append(fileMedia)
case let .decryptedMessageMediaWebPage(url):
parsedMedia.append(TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.LocalWebpage, id: Int64.random(in: Int64.min ... Int64.max)), content: .Pending(0, url)))
@ -901,13 +901,13 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
resources.append((resource, thumb.makeData()))
}
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), progressiveSizes: [], immediateThumbnailData: nil))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil))
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
parsedMedia.append(image)
}
case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv):
if let file = file {
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: [TelegramMediaFileAttribute.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: [TelegramMediaFileAttribute.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])
parsedMedia.append(fileMedia)
attributes.append(ConsumableContentMessageAttribute(consumed: false))
}
@ -928,7 +928,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
resources.append((resource, thumb.makeData()))
}
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
parsedMedia.append(fileMedia)
loop: for attr in parsedAttributes {
@ -959,7 +959,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
resources.append((resource, thumb.makeData()))
}
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
parsedMedia.append(fileMedia)
}
case let .decryptedMessageMediaExternalDocument(id, accessHash, _, mimeType, size, thumb, dcId, attributes):
@ -974,7 +974,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .photoSize(_, location, w, h, size):
switch location {
case let .fileLocation(dcId, volumeId, localId, secret):
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil))
case .fileLocationUnavailable:
break
}
@ -982,7 +982,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
if bytes.size > 0 {
switch location {
case let .fileLocation(dcId, volumeId, localId, secret):
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: bytes.size, fileReference: nil)
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil)
resources.append((resource, bytes.makeData()))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
case .fileLocationUnavailable:
@ -992,7 +992,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
default:
break
}
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: Int(size), fileReference: nil, fileName: nil), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: Int64(size), fileReference: nil, fileName: nil), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
parsedMedia.append(fileMedia)
case let .decryptedMessageMediaWebPage(url):
parsedMedia.append(TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.LocalWebpage, id: Int64.random(in: Int64.min ... Int64.max)), content: .Pending(0, url)))
@ -1139,13 +1139,13 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
resources.append((resource, thumb.makeData()))
}
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), progressiveSizes: [], immediateThumbnailData: nil))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil))
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
parsedMedia.append(image)
}
case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv):
if let file = file {
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: [TelegramMediaFileAttribute.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: [TelegramMediaFileAttribute.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])
parsedMedia.append(fileMedia)
attributes.append(ConsumableContentMessageAttribute(consumed: false))
}
@ -1166,7 +1166,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
resources.append((resource, thumb.makeData()))
}
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
parsedMedia.append(fileMedia)
loop: for attr in parsedAttributes {
@ -1197,7 +1197,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
resources.append((resource, thumb.makeData()))
}
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
parsedMedia.append(fileMedia)
}
case let .decryptedMessageMediaExternalDocument(id, accessHash, _, mimeType, size, thumb, dcId, attributes):
@ -1212,7 +1212,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .photoSize(_, location, w, h, size):
switch location {
case let .fileLocation(dcId, volumeId, localId, secret):
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil))
case .fileLocationUnavailable:
break
}
@ -1220,7 +1220,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
if bytes.size > 0 {
switch location {
case let .fileLocation(dcId, volumeId, localId, secret):
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: bytes.size, fileReference: nil)
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil)
resources.append((resource, bytes.makeData()))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil))
case .fileLocationUnavailable:
@ -1230,7 +1230,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
default:
break
}
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: Int(size), fileReference: nil, fileName: nil), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int(size), attributes: parsedAttributes)
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: Int64(size), fileReference: nil, fileName: nil), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
parsedMedia.append(fileMedia)
case let .decryptedMessageMediaWebPage(url):
parsedMedia.append(TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.LocalWebpage, id: Int64.random(in: Int64.min ... Int64.max)), content: .Pending(0, url)))

View file

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt {
return 142
return 143
}
public func parseMessage(_ data: Data!) -> Any! {

View file

@ -8,14 +8,14 @@ public enum AutodownloadPreset {
public struct AutodownloadPresetSettings: Codable {
public let disabled: Bool
public let photoSizeMax: Int32
public let videoSizeMax: Int32
public let fileSizeMax: Int32
public let photoSizeMax: Int64
public let videoSizeMax: Int64
public let fileSizeMax: Int64
public let preloadLargeVideo: Bool
public let lessDataForPhoneCalls: Bool
public let videoUploadMaxbitrate: Int32
public init(disabled: Bool, photoSizeMax: Int32, videoSizeMax: Int32, fileSizeMax: Int32, preloadLargeVideo: Bool, lessDataForPhoneCalls: Bool, videoUploadMaxbitrate: Int32) {
public init(disabled: Bool, photoSizeMax: Int64, videoSizeMax: Int64, fileSizeMax: Int64, preloadLargeVideo: Bool, lessDataForPhoneCalls: Bool, videoUploadMaxbitrate: Int32) {
self.disabled = disabled
self.photoSizeMax = photoSizeMax
self.videoSizeMax = videoSizeMax
@ -29,9 +29,22 @@ public struct AutodownloadPresetSettings: Codable {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.disabled = ((try? container.decode(Int32.self, forKey: "disabled")) ?? 0) != 0
self.photoSizeMax = (try? container.decode(Int32.self, forKey: "photoSizeMax")) ?? 0
self.videoSizeMax = (try? container.decode(Int32.self, forKey: "videoSizeMax")) ?? 0
self.fileSizeMax = (try? container.decode(Int32.self, forKey: "fileSizeMax")) ?? 0
if let photoSizeMax = try? container.decode(Int64.self, forKey: "photoSizeMax64") {
self.photoSizeMax = photoSizeMax
} else {
self.photoSizeMax = Int64((try? container.decode(Int32.self, forKey: "photoSizeMax")) ?? 0)
}
if let videoSizeMax = try? container.decode(Int64.self, forKey: "videoSizeMax64") {
self.videoSizeMax = videoSizeMax
} else {
self.videoSizeMax = Int64((try? container.decode(Int32.self, forKey: "videoSizeMax")) ?? 0)
}
if let fileSizeMax = try? container.decode(Int64.self, forKey: "fileSizeMax64") {
self.fileSizeMax = fileSizeMax
} else {
self.fileSizeMax = Int64((try? container.decode(Int32.self, forKey: "fileSizeMax")) ?? 0)
}
self.preloadLargeVideo = ((try? container.decode(Int32.self, forKey: "preloadLargeVideo")) ?? 0) != 0
self.lessDataForPhoneCalls = ((try? container.decode(Int32.self, forKey: "lessDataForPhoneCalls")) ?? 0) != 0
self.videoUploadMaxbitrate = (try? container.decode(Int32.self, forKey: "videoUploadMaxbitrate")) ?? 0
@ -41,9 +54,9 @@ public struct AutodownloadPresetSettings: Codable {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode((self.disabled ? 1 : 0) as Int32, forKey: "disabled")
try container.encode(self.photoSizeMax, forKey: "photoSizeMax")
try container.encode(self.videoSizeMax, forKey: "videoSizeMax")
try container.encode(self.fileSizeMax, forKey: "fileSizeMax")
try container.encode(self.photoSizeMax, forKey: "photoSizeMax64")
try container.encode(self.videoSizeMax, forKey: "videoSizeMax64")
try container.encode(self.fileSizeMax, forKey: "fileSizeMax64")
try container.encode((self.preloadLargeVideo ? 1 : 0) as Int32, forKey: "preloadLargeVideo")
try container.encode((self.lessDataForPhoneCalls ? 1 : 0) as Int32, forKey: "lessDataForPhoneCalls")
try container.encode(self.videoUploadMaxbitrate, forKey: "videoUploadMaxbitrate")
@ -58,7 +71,7 @@ public struct AutodownloadSettings: Codable {
public static var defaultSettings: AutodownloadSettings {
return AutodownloadSettings(
lowPreset: AutodownloadPresetSettings(disabled: false, photoSizeMax: 1 * 1024 * 1024, videoSizeMax: 0, fileSizeMax: 0, preloadLargeVideo: false, lessDataForPhoneCalls: true, videoUploadMaxbitrate: 0),
mediumPreset: AutodownloadPresetSettings(disabled: false, photoSizeMax: 1 * 1024 * 1024, videoSizeMax: Int32(2.5 * 1024 * 1024), fileSizeMax: 1 * 1024 * 1024, preloadLargeVideo: false, lessDataForPhoneCalls: false, videoUploadMaxbitrate: 0),
mediumPreset: AutodownloadPresetSettings(disabled: false, photoSizeMax: 1 * 1024 * 1024, videoSizeMax: Int64(2.5 * 1024 * 1024), fileSizeMax: 1 * 1024 * 1024, preloadLargeVideo: false, lessDataForPhoneCalls: false, videoUploadMaxbitrate: 0),
highPreset: AutodownloadPresetSettings(disabled: false, photoSizeMax: 1 * 1024 * 1024, videoSizeMax: 10 * 1024 * 1024, fileSizeMax: 3 * 1024 * 1024, preloadLargeVideo: false, lessDataForPhoneCalls: false, videoUploadMaxbitrate: 0))
}

View file

@ -24,14 +24,14 @@ public final class CloudFileMediaResource: TelegramMediaResource {
public let volumeId: Int64
public let localId: Int32
public let secret: Int64
public let size: Int?
public let size: Int64?
public let fileReference: Data?
public var id: MediaResourceId {
return MediaResourceId(CloudFileMediaResourceId(datacenterId: self.datacenterId, volumeId: self.volumeId, localId: self.localId, secret: self.secret).uniqueId)
}
public init(datacenterId: Int, volumeId: Int64, localId: Int32, secret: Int64, size: Int?, fileReference: Data?) {
public init(datacenterId: Int, volumeId: Int64, localId: Int32, secret: Int64, size: Int64?, fileReference: Data?) {
self.datacenterId = datacenterId
self.volumeId = volumeId
self.localId = localId
@ -45,8 +45,10 @@ public final class CloudFileMediaResource: TelegramMediaResource {
self.volumeId = decoder.decodeInt64ForKey("v", orElse: 0)
self.localId = decoder.decodeInt32ForKey("l", orElse: 0)
self.secret = decoder.decodeInt64ForKey("s", orElse: 0)
if let size = decoder.decodeOptionalInt32ForKey("n") {
self.size = Int(size)
if let size = decoder.decodeOptionalInt64ForKey("n64") {
self.size = size
} else if let size = decoder.decodeOptionalInt32ForKey("n") {
self.size = Int64(size)
} else {
self.size = nil
}
@ -59,9 +61,9 @@ public final class CloudFileMediaResource: TelegramMediaResource {
encoder.encodeInt32(self.localId, forKey: "l")
encoder.encodeInt64(self.secret, forKey: "s")
if let size = self.size {
encoder.encodeInt32(Int32(size), forKey: "n")
encoder.encodeInt64(size, forKey: "n64")
} else {
encoder.encodeNil(forKey: "n")
encoder.encodeNil(forKey: "n64")
}
if let fileReference = self.fileReference {
encoder.encodeBytes(MemoryBuffer(data: fileReference), forKey: "fr")
@ -100,14 +102,14 @@ public final class CloudPhotoSizeMediaResource: TelegramMediaResource {
public let photoId: Int64
public let accessHash: Int64
public let sizeSpec: String
public let size: Int?
public let size: Int64?
public let fileReference: Data?
public var id: MediaResourceId {
return MediaResourceId(CloudPhotoSizeMediaResourceId(datacenterId: Int32(self.datacenterId), photoId: self.photoId, sizeSpec: self.sizeSpec).uniqueId)
}
public init(datacenterId: Int32, photoId: Int64, accessHash: Int64, sizeSpec: String, size: Int?, fileReference: Data?) {
public init(datacenterId: Int32, photoId: Int64, accessHash: Int64, sizeSpec: String, size: Int64?, fileReference: Data?) {
self.datacenterId = Int(datacenterId)
self.photoId = photoId
self.accessHash = accessHash
@ -121,8 +123,10 @@ public final class CloudPhotoSizeMediaResource: TelegramMediaResource {
self.photoId = decoder.decodeInt64ForKey("i", orElse: 0)
self.accessHash = decoder.decodeInt64ForKey("h", orElse: 0)
self.sizeSpec = decoder.decodeStringForKey("s", orElse: "")
if let size = decoder.decodeOptionalInt32ForKey("n") {
self.size = Int(size)
if let size = decoder.decodeOptionalInt64ForKey("n64") {
self.size = size
} else if let size = decoder.decodeOptionalInt32ForKey("n") {
self.size = Int64(size)
} else {
self.size = nil
}
@ -135,9 +139,9 @@ public final class CloudPhotoSizeMediaResource: TelegramMediaResource {
encoder.encodeInt64(self.accessHash, forKey: "h")
encoder.encodeString(self.sizeSpec, forKey: "s")
if let size = self.size {
encoder.encodeInt32(Int32(size), forKey: "n")
encoder.encodeInt64(size, forKey: "n64")
} else {
encoder.encodeNil(forKey: "n")
encoder.encodeNil(forKey: "n64")
}
if let fileReference = self.fileReference {
encoder.encodeBytes(MemoryBuffer(data: fileReference), forKey: "fr")
@ -177,6 +181,9 @@ public final class CloudDocumentSizeMediaResource: TelegramMediaResource {
public let accessHash: Int64
public let sizeSpec: String
public let fileReference: Data?
public var size: Int64? {
return nil
}
public var id: MediaResourceId {
return MediaResourceId(CloudDocumentSizeMediaResourceId(datacenterId: Int32(self.datacenterId), documentId: self.documentId, sizeSpec: self.sizeSpec).uniqueId)
@ -254,6 +261,9 @@ public final class CloudPeerPhotoSizeMediaResource: TelegramMediaResource {
public let sizeSpec: CloudPeerPhotoSizeSpec
public let volumeId: Int64?
public let localId: Int32?
public var size: Int64? {
return nil
}
public var id: MediaResourceId {
return MediaResourceId(CloudPeerPhotoSizeMediaResourceId(datacenterId: Int32(self.datacenterId), photoId: self.photoId, sizeSpec: self.sizeSpec, volumeId: self.volumeId, localId: self.localId).uniqueId)
@ -331,6 +341,9 @@ public final class CloudStickerPackThumbnailMediaResource: TelegramMediaResource
public let thumbVersion: Int32?
public let volumeId: Int64?
public let localId: Int32?
public var size: Int64? {
return nil
}
public var id: MediaResourceId {
return MediaResourceId(CloudStickerPackThumbnailMediaResourceId(datacenterId: Int32(self.datacenterId), thumbVersion: self.thumbVersion, volumeId: self.volumeId, localId: self.localId).uniqueId)
@ -396,7 +409,7 @@ public final class CloudDocumentMediaResource: TelegramMediaResource {
public let datacenterId: Int
public let fileId: Int64
public let accessHash: Int64
public let size: Int?
public let size: Int64?
public let fileReference: Data?
public let fileName: String?
@ -404,7 +417,7 @@ public final class CloudDocumentMediaResource: TelegramMediaResource {
return MediaResourceId(CloudDocumentMediaResourceId(datacenterId: self.datacenterId, fileId: self.fileId).uniqueId)
}
public init(datacenterId: Int, fileId: Int64, accessHash: Int64, size: Int?, fileReference: Data?, fileName: String?) {
public init(datacenterId: Int, fileId: Int64, accessHash: Int64, size: Int64?, fileReference: Data?, fileName: String?) {
self.datacenterId = datacenterId
self.fileId = fileId
self.accessHash = accessHash
@ -417,8 +430,10 @@ public final class CloudDocumentMediaResource: TelegramMediaResource {
self.datacenterId = Int(decoder.decodeInt32ForKey("d", orElse: 0))
self.fileId = decoder.decodeInt64ForKey("f", orElse: 0)
self.accessHash = decoder.decodeInt64ForKey("a", orElse: 0)
if let size = decoder.decodeOptionalInt32ForKey("n") {
self.size = Int(size)
if let size = decoder.decodeOptionalInt64ForKey("n64") {
self.size = size
} else if let size = decoder.decodeOptionalInt32ForKey("n") {
self.size = Int64(size)
} else {
self.size = nil
}
@ -431,9 +446,9 @@ public final class CloudDocumentMediaResource: TelegramMediaResource {
encoder.encodeInt64(self.fileId, forKey: "f")
encoder.encodeInt64(self.accessHash, forKey: "a")
if let size = self.size {
encoder.encodeInt32(Int32(size), forKey: "n")
encoder.encodeInt64(size, forKey: "n64")
} else {
encoder.encodeNil(forKey: "n")
encoder.encodeNil(forKey: "n64")
}
if let fileReference = self.fileReference {
encoder.encodeBytes(MemoryBuffer(data: fileReference), forKey: "fr")
@ -466,11 +481,11 @@ public struct LocalFileMediaResourceId: Hashable, Equatable {
public class LocalFileMediaResource: TelegramMediaResource, Codable {
public let fileId: Int64
public let size: Int?
public let size: Int64?
public let isSecretRelated: Bool
public init(fileId: Int64, size: Int? = nil, isSecretRelated: Bool = false) {
public init(fileId: Int64, size: Int64? = nil, isSecretRelated: Bool = false) {
self.fileId = fileId
self.size = size
self.isSecretRelated = isSecretRelated
@ -479,8 +494,10 @@ public class LocalFileMediaResource: TelegramMediaResource, Codable {
public required init(decoder: PostboxDecoder) {
self.fileId = decoder.decodeInt64ForKey("f", orElse: 0)
self.isSecretRelated = decoder.decodeBoolForKey("sr", orElse: false)
if let size = decoder.decodeOptionalInt32ForKey("s") {
self.size = Int(size)
if let size = decoder.decodeOptionalInt64ForKey("s64") {
self.size = size
} else if let size = decoder.decodeOptionalInt32ForKey("s") {
self.size = Int64(size)
} else {
self.size = nil
}
@ -491,16 +508,20 @@ public class LocalFileMediaResource: TelegramMediaResource, Codable {
self.fileId = try container.decode(Int64.self, forKey: "f")
self.isSecretRelated = try container.decodeIfPresent(Bool.self, forKey: "sr") ?? false
self.size = (try container.decodeIfPresent(Int32.self, forKey: "s")).flatMap(Int.init)
if let size = try container.decodeIfPresent(Int64.self, forKey: "s64") {
self.size = size
} else {
self.size = (try container.decodeIfPresent(Int32.self, forKey: "s")).flatMap(Int64.init)
}
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt64(self.fileId, forKey: "f")
encoder.encodeBool(self.isSecretRelated, forKey: "sr")
if let size = self.size {
encoder.encodeInt32(Int32(size), forKey: "s")
encoder.encodeInt64(size, forKey: "s64")
} else {
encoder.encodeNil(forKey: "s")
encoder.encodeNil(forKey: "s64")
}
}
@ -509,7 +530,7 @@ public class LocalFileMediaResource: TelegramMediaResource, Codable {
try container.encode(self.fileId, forKey: "f")
try container.encode(self.isSecretRelated, forKey: "sr")
try container.encodeIfPresent(self.size.flatMap(Int32.init), forKey: "s")
try container.encodeIfPresent(self.size, forKey: "s64")
}
public var id: MediaResourceId {
@ -537,9 +558,9 @@ public class LocalFileReferenceMediaResource: TelegramMediaResource {
public let localFilePath: String
public let randomId: Int64
public let isUniquelyReferencedTemporaryFile: Bool
public let size: Int32?
public let size: Int64?
public init(localFilePath: String, randomId: Int64, isUniquelyReferencedTemporaryFile: Bool = false, size: Int32? = nil) {
public init(localFilePath: String, randomId: Int64, isUniquelyReferencedTemporaryFile: Bool = false, size: Int64? = nil) {
self.localFilePath = localFilePath
self.randomId = randomId
self.isUniquelyReferencedTemporaryFile = isUniquelyReferencedTemporaryFile
@ -550,7 +571,13 @@ public class LocalFileReferenceMediaResource: TelegramMediaResource {
self.localFilePath = decoder.decodeStringForKey("p", orElse: "")
self.randomId = decoder.decodeInt64ForKey("r", orElse: 0)
self.isUniquelyReferencedTemporaryFile = decoder.decodeInt32ForKey("t", orElse: 0) != 0
self.size = decoder.decodeOptionalInt32ForKey("s")
if let size = decoder.decodeOptionalInt64ForKey("s64") {
self.size = size
} else if let size = decoder.decodeOptionalInt32ForKey("s") {
self.size = Int64(size)
} else {
self.size = nil
}
}
public func encode(_ encoder: PostboxEncoder) {
@ -558,7 +585,7 @@ public class LocalFileReferenceMediaResource: TelegramMediaResource {
encoder.encodeInt64(self.randomId, forKey: "r")
encoder.encodeInt32(self.isUniquelyReferencedTemporaryFile ? 1 : 0, forKey: "t")
if let size = self.size {
encoder.encodeInt32(size, forKey: "s")
encoder.encodeInt64(size, forKey: "s64")
} else {
encoder.encodeNil(forKey: "s")
}
@ -587,17 +614,19 @@ public struct HttpReferenceMediaResourceId: Hashable, Equatable {
public final class HttpReferenceMediaResource: TelegramMediaResource {
public let url: String
public let size: Int?
public let size: Int64?
public init(url: String, size: Int?) {
public init(url: String, size: Int64?) {
self.url = url
self.size = size
}
public required init(decoder: PostboxDecoder) {
self.url = decoder.decodeStringForKey("u", orElse: "")
if let size = decoder.decodeOptionalInt32ForKey("s") {
self.size = Int(size)
if let size = decoder.decodeOptionalInt64ForKey("s64") {
self.size = size
} else if let size = decoder.decodeOptionalInt32ForKey("s") {
self.size = Int64(size)
} else {
self.size = nil
}
@ -606,9 +635,9 @@ public final class HttpReferenceMediaResource: TelegramMediaResource {
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeString(self.url, forKey: "u")
if let size = self.size {
encoder.encodeInt32(Int32(size), forKey: "s")
encoder.encodeInt64(size, forKey: "s64")
} else {
encoder.encodeNil(forKey: "s")
encoder.encodeNil(forKey: "s64")
}
}
@ -628,7 +657,7 @@ public final class HttpReferenceMediaResource: TelegramMediaResource {
public struct WebFileReferenceMediaResourceId: Hashable, Equatable {
public let url: String
public let accessHash: Int64
public let size: Int32
public let size: Int64
public var uniqueId: String {
return "proxy-\(persistentHash32(self.url))-\(size)-\(accessHash)"
@ -637,29 +666,36 @@ public struct WebFileReferenceMediaResourceId: Hashable, Equatable {
public final class WebFileReferenceMediaResource: TelegramMediaResource {
public let url: String
public let size: Int32
public let actualSize: Int64
public var size: Int64? {
return self.actualSize
}
public let accessHash: Int64
public init(url: String, size: Int32, accessHash: Int64) {
public init(url: String, size: Int64, accessHash: Int64) {
self.url = url
self.size = size
self.actualSize = size
self.accessHash = accessHash
}
public required init(decoder: PostboxDecoder) {
self.url = decoder.decodeStringForKey("u", orElse: "")
self.size = decoder.decodeInt32ForKey("s", orElse: 0)
if let size = decoder.decodeOptionalInt64ForKey("s64") {
self.actualSize = size
} else {
self.actualSize = Int64(decoder.decodeInt32ForKey("s", orElse: 0))
}
self.accessHash = decoder.decodeInt64ForKey("h", orElse: 0)
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeString(self.url, forKey: "u")
encoder.encodeInt32(self.size, forKey: "s")
encoder.encodeInt64(self.actualSize, forKey: "s64")
encoder.encodeInt64(self.accessHash, forKey: "h")
}
public var id: MediaResourceId {
return MediaResourceId(WebFileReferenceMediaResourceId(url: self.url, accessHash: accessHash, size: self.size).uniqueId)
return MediaResourceId(WebFileReferenceMediaResourceId(url: self.url, accessHash: accessHash, size: self.actualSize).uniqueId)
}
public func isEqual(to: MediaResource) -> Bool {
@ -689,15 +725,15 @@ public struct SecretFileMediaResourceId: Hashable, Equatable {
public final class SecretFileMediaResource: TelegramMediaResource {
public let fileId: Int64
public let accessHash: Int64
public var size: Int? {
return Int(self.decryptedSize)
public var size: Int64? {
return self.decryptedSize
}
public let containerSize: Int32
public let decryptedSize: Int32
public let containerSize: Int64
public let decryptedSize: Int64
public let datacenterId: Int
public let key: SecretFileEncryptionKey
public init(fileId: Int64, accessHash: Int64, containerSize: Int32, decryptedSize: Int32, datacenterId: Int, key: SecretFileEncryptionKey) {
public init(fileId: Int64, accessHash: Int64, containerSize: Int64, decryptedSize: Int64, datacenterId: Int, key: SecretFileEncryptionKey) {
self.fileId = fileId
self.accessHash = accessHash
self.containerSize = containerSize
@ -709,8 +745,17 @@ public final class SecretFileMediaResource: TelegramMediaResource {
public init(decoder: PostboxDecoder) {
self.fileId = decoder.decodeInt64ForKey("i", orElse: 0)
self.accessHash = decoder.decodeInt64ForKey("a", orElse: 0)
self.containerSize = decoder.decodeInt32ForKey("s", orElse: 0)
self.decryptedSize = decoder.decodeInt32ForKey("ds", orElse: 0)
if let containerSize = decoder.decodeOptionalInt64ForKey("s64") {
self.containerSize = containerSize
} else {
self.containerSize = Int64(decoder.decodeInt32ForKey("s", orElse: 0))
}
if let decryptedSize = decoder.decodeOptionalInt64ForKey("ds64") {
self.decryptedSize = decryptedSize
} else {
self.decryptedSize = Int64(decoder.decodeInt32ForKey("ds", orElse: 0))
}
self.datacenterId = Int(decoder.decodeInt32ForKey("d", orElse: 0))
self.key = decoder.decodeObjectForKey("k", decoder: { SecretFileEncryptionKey(decoder: $0) }) as! SecretFileEncryptionKey
}
@ -718,8 +763,8 @@ public final class SecretFileMediaResource: TelegramMediaResource {
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt64(self.fileId, forKey: "i")
encoder.encodeInt64(self.accessHash, forKey: "a")
encoder.encodeInt32(self.containerSize, forKey: "s")
encoder.encodeInt32(self.decryptedSize, forKey: "ds")
encoder.encodeInt64(self.containerSize, forKey: "s64")
encoder.encodeInt64(self.decryptedSize, forKey: "ds64")
encoder.encodeInt32(Int32(self.datacenterId), forKey: "d")
encoder.encodeObject(self.key, forKey: "k")
}
@ -766,6 +811,10 @@ public struct EmptyMediaResourceId {
}
public final class EmptyMediaResource: TelegramMediaResource {
public var size: Int64? {
return nil
}
public init() {
}
@ -801,6 +850,10 @@ public struct WallpaperDataResourceId {
}
public final class WallpaperDataResource: TelegramMediaResource {
public var size: Int64? {
return nil
}
public let slug: String
public init(slug: String) {

View file

@ -83,9 +83,9 @@ public final class RenderedRecentDownloadItem: Equatable {
public let timestamp: Int32
public let isSeen: Bool
public let resourceId: String
public let size: Int
public let size: Int64
public init(message: Message, timestamp: Int32, isSeen: Bool, resourceId: String, size: Int) {
public init(message: Message, timestamp: Int32, isSeen: Bool, resourceId: String, size: Int64) {
self.message = message
self.timestamp = timestamp
self.isSeen = isSeen
@ -135,7 +135,7 @@ public func recentDownloadItems(postbox: Postbox) -> Signal<[RenderedRecentDownl
continue
}
var size: Int?
var size: Int64?
for media in message.media {
if let result = findMediaResourceById(media: media, resourceId: MediaResourceId(item.resourceId)) {
size = result.size

View file

@ -3,11 +3,11 @@ import Postbox
public final class SecretChatFileReference: PostboxCoding {
public let id: Int64
public let accessHash: Int64
public let size: Int32
public let size: Int64
public let datacenterId: Int32
public let keyFingerprint: Int32
public init(id: Int64, accessHash: Int64, size: Int32, datacenterId: Int32, keyFingerprint: Int32) {
public init(id: Int64, accessHash: Int64, size: Int64, datacenterId: Int32, keyFingerprint: Int32) {
self.id = id
self.accessHash = accessHash
self.size = size
@ -18,7 +18,11 @@ public final class SecretChatFileReference: PostboxCoding {
public init(decoder: PostboxDecoder) {
self.id = decoder.decodeInt64ForKey("i", orElse: 0)
self.accessHash = decoder.decodeInt64ForKey("a", orElse: 0)
self.size = decoder.decodeInt32ForKey("s", orElse: 0)
if let size = decoder.decodeOptionalInt64ForKey("s64") {
self.size = size
} else {
self.size = Int64(decoder.decodeInt32ForKey("s", orElse: 0))
}
self.datacenterId = decoder.decodeInt32ForKey("d", orElse: 0)
self.keyFingerprint = decoder.decodeInt32ForKey("f", orElse: 0)
}
@ -26,7 +30,7 @@ public final class SecretChatFileReference: PostboxCoding {
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt64(self.id, forKey: "i")
encoder.encodeInt64(self.accessHash, forKey: "a")
encoder.encodeInt32(self.size, forKey: "s")
encoder.encodeInt64(self.size, forKey: "s64")
encoder.encodeInt32(self.datacenterId, forKey: "d")
encoder.encodeInt32(self.keyFingerprint, forKey: "f")
}

View file

@ -49,10 +49,10 @@ public enum SecretChatOutgoingFileReference: PostboxCoding {
public struct SecretChatOutgoingFile: PostboxCoding {
public let reference: SecretChatOutgoingFileReference
public let size: Int32
public let size: Int64
public let key: SecretFileEncryptionKey
public init(reference: SecretChatOutgoingFileReference, size: Int32, key: SecretFileEncryptionKey) {
public init(reference: SecretChatOutgoingFileReference, size: Int64, key: SecretFileEncryptionKey) {
self.reference = reference
self.size = size
self.key = key
@ -60,13 +60,17 @@ public struct SecretChatOutgoingFile: PostboxCoding {
public init(decoder: PostboxDecoder) {
self.reference = decoder.decodeObjectForKey("r", decoder: { SecretChatOutgoingFileReference(decoder: $0) }) as! SecretChatOutgoingFileReference
self.size = decoder.decodeInt32ForKey("s", orElse: 0)
if let size = decoder.decodeOptionalInt64ForKey("s64") {
self.size = size
} else {
self.size = Int64(decoder.decodeInt32ForKey("s", orElse: 0))
}
self.key = SecretFileEncryptionKey(aesKey: decoder.decodeBytesForKey("k")!.makeData(), aesIv: decoder.decodeBytesForKey("i")!.makeData())
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.reference, forKey: "r")
encoder.encodeInt32(self.size, forKey: "s")
encoder.encodeInt64(self.size, forKey: "s64")
encoder.encodeBytes(MemoryBuffer(data: self.key.aesKey), forKey: "k")
encoder.encodeBytes(MemoryBuffer(data: self.key.aesIv), forKey: "i")
}

View file

@ -28,8 +28,8 @@ public final class SecureFileMediaResource: TelegramMediaResource {
return Int(self.file.datacenterId)
}
public var size: Int? {
return Int(self.file.size)
public var size: Int64? {
return self.file.size
}
public init(file: SecureIdFileReference) {
@ -37,13 +37,19 @@ public final class SecureFileMediaResource: TelegramMediaResource {
}
public required init(decoder: PostboxDecoder) {
self.file = SecureIdFileReference(id: decoder.decodeInt64ForKey("f", orElse: 0), accessHash: decoder.decodeInt64ForKey("a", orElse: 0), size: decoder.decodeInt32ForKey("n", orElse: 0), datacenterId: decoder.decodeInt32ForKey("d", orElse: 0), timestamp: decoder.decodeInt32ForKey("t", orElse: 0), fileHash: decoder.decodeBytesForKey("h")?.makeData() ?? Data(), encryptedSecret: decoder.decodeBytesForKey("s")?.makeData() ?? Data())
let size: Int64
if let value = decoder.decodeOptionalInt64ForKey("n64") {
size = value
} else {
size = Int64(decoder.decodeInt32ForKey("n", orElse: 0))
}
self.file = SecureIdFileReference(id: decoder.decodeInt64ForKey("f", orElse: 0), accessHash: decoder.decodeInt64ForKey("a", orElse: 0), size: size, datacenterId: decoder.decodeInt32ForKey("d", orElse: 0), timestamp: decoder.decodeInt32ForKey("t", orElse: 0), fileHash: decoder.decodeBytesForKey("h")?.makeData() ?? Data(), encryptedSecret: decoder.decodeBytesForKey("s")?.makeData() ?? Data())
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt64(self.file.id, forKey: "f")
encoder.encodeInt64(self.file.accessHash, forKey: "a")
encoder.encodeInt32(self.file.size, forKey: "n")
encoder.encodeInt64(self.file.size, forKey: "n64")
encoder.encodeInt32(self.file.datacenterId, forKey: "d")
encoder.encodeInt32(self.file.timestamp, forKey: "t")
encoder.encodeBytes(MemoryBuffer(data: self.file.fileHash), forKey: "h")

View file

@ -4,13 +4,13 @@ import Postbox
public struct SecureIdFileReference: Equatable {
public let id: Int64
public let accessHash: Int64
public let size: Int32
public let size: Int64
public let datacenterId: Int32
public let timestamp: Int32
public let fileHash: Data
public let encryptedSecret: Data
public init(id: Int64, accessHash: Int64, size: Int32, datacenterId: Int32, timestamp: Int32, fileHash: Data, encryptedSecret: Data) {
public init(id: Int64, accessHash: Int64, size: Int64, datacenterId: Int32, timestamp: Int32, fileHash: Data, encryptedSecret: Data) {
self.id = id
self.accessHash = accessHash
self.size = size

View file

@ -307,7 +307,7 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
public let videoThumbnails: [TelegramMediaFile.VideoThumbnail]
public let immediateThumbnailData: Data?
public let mimeType: String
public let size: Int?
public let size: Int64?
public let attributes: [TelegramMediaFileAttribute]
public let peerIds: [PeerId] = []
@ -328,7 +328,7 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
return result.isEmpty ? nil : result
}
public init(fileId: MediaId, partialReference: PartialMediaReference?, resource: TelegramMediaResource, previewRepresentations: [TelegramMediaImageRepresentation], videoThumbnails: [TelegramMediaFile.VideoThumbnail], immediateThumbnailData: Data?, mimeType: String, size: Int?, attributes: [TelegramMediaFileAttribute]) {
public init(fileId: MediaId, partialReference: PartialMediaReference?, resource: TelegramMediaResource, previewRepresentations: [TelegramMediaImageRepresentation], videoThumbnails: [TelegramMediaFile.VideoThumbnail], immediateThumbnailData: Data?, mimeType: String, size: Int64?, attributes: [TelegramMediaFileAttribute]) {
self.fileId = fileId
self.partialReference = partialReference
self.resource = resource
@ -348,8 +348,10 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
self.videoThumbnails = decoder.decodeObjectArrayForKey("vr")
self.immediateThumbnailData = decoder.decodeDataForKey("itd")
self.mimeType = decoder.decodeStringForKey("mt", orElse: "")
if let size = decoder.decodeOptionalInt32ForKey("s") {
self.size = Int(size)
if let size = decoder.decodeOptionalInt64ForKey("s64") {
self.size = size
} else if let size = decoder.decodeOptionalInt32ForKey("s") {
self.size = Int64(size)
} else {
self.size = nil
}
@ -375,9 +377,9 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
}
encoder.encodeString(self.mimeType, forKey: "mt")
if let size = self.size {
encoder.encodeInt32(Int32(size), forKey: "s")
encoder.encodeInt64(size, forKey: "s64")
} else {
encoder.encodeNil(forKey: "s")
encoder.encodeNil(forKey: "s64")
}
encoder.encodeObjectArray(self.attributes, forKey: "at")
}
@ -622,7 +624,7 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
return TelegramMediaFile(fileId: self.fileId, partialReference: self.partialReference, resource: resource, previewRepresentations: self.previewRepresentations, videoThumbnails: self.videoThumbnails, immediateThumbnailData: self.immediateThumbnailData, mimeType: self.mimeType, size: self.size, attributes: self.attributes)
}
public func withUpdatedSize(_ size: Int?) -> TelegramMediaFile {
public func withUpdatedSize(_ size: Int64?) -> TelegramMediaFile {
return TelegramMediaFile(fileId: self.fileId, partialReference: self.partialReference, resource: self.resource, previewRepresentations: self.previewRepresentations, videoThumbnails: self.videoThumbnails, immediateThumbnailData: self.immediateThumbnailData, mimeType: self.mimeType, size: size, attributes: self.attributes)
}

View file

@ -300,7 +300,7 @@ public enum UploadNotificationSoundError {
}
func _internal_uploadNotificationSound(account: Account, title: String, data: Data) -> Signal<NotificationSoundList.NotificationSound, UploadNotificationSoundError> {
return multipartUpload(network: account.network, postbox: account.postbox, source: .data(data), encrypt: false, tag: nil, hintFileSize: data.count, hintFileIsLarge: false, forceNoBigParts: true, useLargerParts: false, increaseParallelParts: false, useMultiplexedRequests: false, useCompression: false)
return multipartUpload(network: account.network, postbox: account.postbox, source: .data(data), encrypt: false, tag: nil, hintFileSize: Int64(data.count), hintFileIsLarge: false, forceNoBigParts: true, useLargerParts: false, increaseParallelParts: false, useMultiplexedRequests: false, useCompression: false)
|> mapError { _ -> UploadNotificationSoundError in
return .generic
}

View file

@ -171,7 +171,7 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state
switch size {
case let .videoSize(_, type, w, h, size, videoStartTs):
let resource: TelegramMediaResource
resource = CloudPhotoSizeMediaResource(datacenterId: dcId, photoId: id, accessHash: accessHash, sizeSpec: type, size: Int(size), fileReference: fileReference.makeData())
resource = CloudPhotoSizeMediaResource(datacenterId: dcId, photoId: id, accessHash: accessHash, sizeSpec: type, size: Int64(size), fileReference: fileReference.makeData())
videoRepresentations.append(TelegramMediaImage.VideoRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, startTimestamp: videoStartTs))
}

View file

@ -45,12 +45,12 @@ public final class EngineMediaResource: Equatable {
public final class ResourceData {
public let path: String
public let availableSize: Int
public let availableSize: Int64
public let isComplete: Bool
public init(
path: String,
availableSize: Int,
availableSize: Int64,
isComplete: Bool
) {
self.path = path

View file

@ -1220,7 +1220,7 @@ public func defaultBuiltinWallpaper(data: BuiltinWallpaperData, colors: [UInt32]
datacenterId: data.datacenterId,
fileId: data.fileId,
accessHash: data.fileAccessHash,
size: data.fileSize,
size: Int64(data.fileSize),
fileReference: Data(),
fileName: "pattern.tgv"
),
@ -1241,7 +1241,7 @@ public func defaultBuiltinWallpaper(data: BuiltinWallpaperData, colors: [UInt32]
videoThumbnails: [],
immediateThumbnailData: nil,
mimeType: "application/x-tgwallpattern",
size: data.fileSize,
size: Int64(data.fileSize),
attributes: [
.ImageSize(size: PixelDimensions(width: 1440, height: 2960)),
.FileName(fileName: "pattern.tgv")

View file

@ -11509,7 +11509,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
attributes.append(.Audio(isVoice: false, duration: audioMetadata.duration, title: audioMetadata.title, performer: audioMetadata.performer, waveform: nil))
}
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: fileId), partialReference: nil, resource: ICloudFileResource(urlData: item.urlData, thumbnail: false), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: item.fileSize, attributes: attributes)
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: fileId), partialReference: nil, resource: ICloudFileResource(urlData: item.urlData, thumbnail: false), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(item.fileSize), attributes: attributes)
let message: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: file), replyToMessageId: replyMessageId, localGroupingKey: groupingKey, correlationId: nil)
messages.append(message)
}
@ -12655,7 +12655,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
fileAttributes.append(.Sticker(displayText: "", packReference: nil, maskData: nil))
fileAttributes.append(.ImageSize(size: PixelDimensions(size)))
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "image/webp", size: data.count, attributes: fileAttributes)
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "image/webp", size: Int64(data.count), attributes: fileAttributes)
let message = EnqueueMessage.message(text: "", attributes: [], mediaReference: .standalone(media: media), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
@ -12865,7 +12865,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
})
} else if let waveform = data.waveform {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max), size: data.compressedData.count)
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max), size: Int64(data.compressedData.count))
strongSelf.context.account.postbox.mediaBox.storeResourceData(resource.id, data: data.compressedData)
@ -12919,7 +12919,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}, usedCorrelationId ? correlationId : nil)
strongSelf.sendMessages([.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: data.compressedData.count, attributes: [.Audio(isVoice: true, duration: Int(data.duration), title: nil, performer: nil, waveform: waveformBuffer)])), replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: correlationId)])
strongSelf.sendMessages([.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(data.compressedData.count), attributes: [.Audio(isVoice: true, duration: Int(data.duration), title: nil, performer: nil, waveform: waveformBuffer)])), replyToMessageId: strongSelf.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: correlationId)])
strongSelf.recorderFeedback?.tap()
strongSelf.recorderFeedback = nil
@ -13014,7 +13014,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}, nil)
let messages: [EnqueueMessage] = [.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: recordedMediaPreview.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int(recordedMediaPreview.fileSize), attributes: [.Audio(isVoice: true, duration: Int(recordedMediaPreview.duration), title: nil, performer: nil, waveform: waveformBuffer)])), replyToMessageId: self.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil)]
let messages: [EnqueueMessage] = [.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: recordedMediaPreview.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(recordedMediaPreview.fileSize), attributes: [.Audio(isVoice: true, duration: Int(recordedMediaPreview.duration), title: nil, performer: nil, waveform: waveformBuffer)])), replyToMessageId: self.presentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil, correlationId: nil)]
let transformedMessages: [EnqueueMessage]
if let silentPosting = silentPosting {

View file

@ -25,6 +25,10 @@ public struct EmojiThumbnailResourceId {
public class EmojiThumbnailResource: TelegramMediaResource {
public let emoji: String
public var size: Int64? {
return nil
}
public init(emoji: String) {
self.emoji = emoji
}
@ -67,6 +71,10 @@ public class EmojiSpriteResource: TelegramMediaResource {
public let packId: UInt8
public let stickerId: UInt8
public var size: Int64? {
return nil
}
public init(packId: UInt8, stickerId: UInt8) {
self.packId = packId
self.stickerId = stickerId
@ -277,7 +285,7 @@ func fetchEmojiSpriteResource(account: Account, resource: EmojiSpriteResource) -
subscriber.putNext(.reset)
let fetch = fetchResource(sticker.file.resource, .single([(0 ..< Int.max, .default)]), nil)
let fetch = fetchResource(sticker.file.resource, .single([(0 ..< Int64.max, .default)]), nil)
let buffer = Atomic<Buffer>(value: Buffer())
let disposable = fetch.start(next: { result in
switch result {
@ -314,18 +322,18 @@ func fetchEmojiSpriteResource(account: Account, resource: EmojiSpriteResource) -
buffer.data.withUnsafeMutableBytes { rawBytes -> Void in
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
data.copyBytes(to: bytes, from: range)
data.copyBytes(to: bytes, from: Int(range.lowerBound) ..< Int(range.upperBound))
}
}
case let .dataPart(resourceOffset, data, range, _):
let _ = buffer.with { buffer in
if buffer.data.count < resourceOffset + range.count {
buffer.data.count = resourceOffset + range.count
if buffer.data.count < Int(resourceOffset) + range.count {
buffer.data.count = Int(resourceOffset) + range.count
}
buffer.data.withUnsafeMutableBytes { rawBytes -> Void in
let bytes = rawBytes.baseAddress!.assumingMemoryBound(to: UInt8.self)
data.copyBytes(to: bytes.advanced(by: resourceOffset), from: range)
data.copyBytes(to: bytes.advanced(by: Int(resourceOffset)), from: Int(range.lowerBound) ..< Int(range.upperBound))
}
}
}
@ -334,7 +342,7 @@ func fetchEmojiSpriteResource(account: Account, resource: EmojiSpriteResource) -
return WebP.convert(fromWebP: buffer.data)
}
if let image = image, let data = image.pngData() {
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< data.count, complete: true))
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< Int64(data.count), complete: true))
subscriber.putCompletion()
}
})

View file

@ -83,7 +83,7 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR
|> `catch` { error -> Signal<CachedMediaResourceRepresentationResult, NoError> in
switch error {
case let .moreDataNeeded(targetSize):
return account.postbox.mediaBox.resourceData(resource, size: size, in: 0 ..< min(size, targetSize))
return account.postbox.mediaBox.resourceData(resource, size: size, in: 0 ..< min(size, Int64(targetSize)))
|> mapToSignal { result ->
Signal<CachedMediaResourceRepresentationResult, NoError> in
let (data, _) = result
@ -149,7 +149,7 @@ public func fetchCachedResourceRepresentation(account: Account, resource: MediaR
return .never()
}
private func videoFirstFrameData(account: Account, resource: MediaResource, chunkSize: Int) -> Signal<CachedMediaResourceRepresentationResult, NoError> {
private func videoFirstFrameData(account: Account, resource: MediaResource, chunkSize: Int64) -> Signal<CachedMediaResourceRepresentationResult, NoError> {
if let size = resource.size {
return account.postbox.mediaBox.resourceData(resource, size: size, in: 0 ..< min(size, chunkSize))
|> mapToSignal { _ -> Signal<CachedMediaResourceRepresentationResult, NoError> in

View file

@ -257,7 +257,7 @@ public func fetchVideoLibraryMediaResource(account: Account, resource: VideoLibr
}
}
}
let updatedSize = Atomic<Int>(value: 0)
let updatedSize = Atomic<Int64>(value: 0)
let entityRenderer: LegacyPaintEntityRenderer? = adjustments.flatMap { adjustments in
if let paintingData = adjustments.paintingData, paintingData.hasAnimation {
return LegacyPaintEntityRenderer(account: account, adjustments: adjustments)
@ -269,10 +269,10 @@ public func fetchVideoLibraryMediaResource(account: Account, resource: VideoLibr
var value = stat()
if stat(path, &value) == 0 {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: [.mappedRead]) {
var range: Range<Int>?
var range: Range<Int64>?
let _ = updatedSize.modify { updatedSize in
range = updatedSize ..< Int(value.st_size)
return Int(value.st_size)
range = updatedSize ..< value.st_size
return value.st_size
}
//print("size = \(Int(value.st_size)), range: \(range!)")
subscriber.putNext(.dataPart(resourceOffset: range!.lowerBound, data: data, range: range!, complete: false))
@ -284,15 +284,15 @@ public func fetchVideoLibraryMediaResource(account: Account, resource: VideoLibr
var value = stat()
if stat(result.fileURL.path, &value) == 0 {
if let data = try? Data(contentsOf: result.fileURL, options: [.mappedRead]) {
var range: Range<Int>?
var range: Range<Int64>?
let _ = updatedSize.modify { updatedSize in
range = updatedSize ..< Int(value.st_size)
return Int(value.st_size)
range = updatedSize ..< value.st_size
return value.st_size
}
//print("finish size = \(Int(value.st_size)), range: \(range!)")
subscriber.putNext(.dataPart(resourceOffset: range!.lowerBound, data: data, range: range!, complete: false))
subscriber.putNext(.replaceHeader(data: data, range: 0 ..< 1024))
subscriber.putNext(.dataPart(resourceOffset: data.count, data: Data(), range: 0 ..< 0, complete: true))
subscriber.putNext(.dataPart(resourceOffset: Int64(data.count), data: Data(), range: 0 ..< 0, complete: true))
}
} else {
subscriber.putError(.generic)
@ -342,7 +342,7 @@ func fetchLocalFileVideoMediaResource(account: Account, resource: LocalFileVideo
adjustments = TGVideoEditAdjustments(dictionary: dict)
}
}
let updatedSize = Atomic<Int>(value: 0)
let updatedSize = Atomic<Int64>(value: 0)
let entityRenderer: LegacyPaintEntityRenderer? = adjustments.flatMap { adjustments in
if let paintingData = adjustments.paintingData, paintingData.hasAnimation {
return LegacyPaintEntityRenderer(account: account, adjustments: adjustments)
@ -370,10 +370,10 @@ func fetchLocalFileVideoMediaResource(account: Account, resource: LocalFileVideo
var value = stat()
if stat(path, &value) == 0 {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: [.mappedRead]) {
var range: Range<Int>?
var range: Range<Int64>?
let _ = updatedSize.modify { updatedSize in
range = updatedSize ..< Int(value.st_size)
return Int(value.st_size)
range = updatedSize ..< value.st_size
return value.st_size
}
//print("size = \(Int(value.st_size)), range: \(range!)")
subscriber.putNext(.dataPart(resourceOffset: range!.lowerBound, data: data, range: range!, complete: false))
@ -392,10 +392,10 @@ func fetchLocalFileVideoMediaResource(account: Account, resource: LocalFileVideo
var value = stat()
if stat(path, &value) == 0 {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: [.mappedRead]) {
var range: Range<Int>?
var range: Range<Int64>?
let _ = updatedSize.modify { updatedSize in
range = updatedSize ..< Int(value.st_size)
return Int(value.st_size)
range = updatedSize ..< Int64(value.st_size)
return value.st_size
}
//print("size = \(Int(value.st_size)), range: \(range!)")
subscriber.putNext(.dataPart(resourceOffset: range!.lowerBound, data: data, range: range!, complete: false))
@ -421,10 +421,10 @@ func fetchLocalFileVideoMediaResource(account: Account, resource: LocalFileVideo
// subscriber.putNext(.moveLocalFile(path: result.fileURL.path))
// }
if let data = try? Data(contentsOf: result.fileURL, options: [.mappedRead]) {
var range: Range<Int>?
var range: Range<Int64>?
let _ = updatedSize.modify { updatedSize in
range = updatedSize ..< Int(value.st_size)
return Int(value.st_size)
range = updatedSize ..< value.st_size
return value.st_size
}
//print("finish size = \(Int(value.st_size)), range: \(range!)")
subscriber.putNext(.dataPart(resourceOffset: range!.lowerBound, data: data, range: range!, complete: false))

View file

@ -28,6 +28,10 @@ public class ICloudFileResource: TelegramMediaResource {
public let urlData: String
public let thumbnail: Bool
public var size: Int64? {
return nil
}
public init(urlData: String, thumbnail: Bool) {
self.urlData = urlData
self.thumbnail = thumbnail

View file

@ -401,7 +401,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
strongSelf.currentFileReference = fileReference
if let size = fileReference.media.size {
strongSelf.scrubberNode.bufferingStatus = strongSelf.postbox.mediaBox.resourceRangesStatus(fileReference.media.resource)
|> map { ranges -> (IndexSet, Int) in
|> map { ranges -> (IndexSet, Int64) in
return (ranges, size)
}
} else {

View file

@ -84,10 +84,10 @@ private func extractTextFileHeader(path: String) -> String? {
return nil
}
let limit = 3000
let limit: Int64 = 3000
var data = file.readData(count: min(size, limit))
let additionalCapacity = min(10, max(0, size - data.count))
var data = file.readData(count: Int(min(size, limit)))
let additionalCapacity = min(10, max(0, Int(size) - data.count))
for alignment in 0 ... additionalCapacity {
if alignment != 0 {

View file

@ -31,7 +31,7 @@ public let telegramAccountAuxiliaryMethods = AccountAuxiliaryMethods(fetchResour
return Signal { subscriber in
subscriber.putNext(.reset)
if let data = try? Data(contentsOf: URL(fileURLWithPath: resource.path), options: .mappedRead) {
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< data.count, complete: true))
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< Int64(data.count), complete: true))
}
return EmptyDisposable
}
@ -44,7 +44,7 @@ public let telegramAccountAuxiliaryMethods = AccountAuxiliaryMethods(fetchResour
return Signal { subscriber in
subscriber.putNext(.reset)
if let data = try? Data(contentsOf: url, options: .mappedRead) {
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< data.count, complete: true))
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< Int64(data.count), complete: true))
}
return EmptyDisposable
@ -60,7 +60,7 @@ public let telegramAccountAuxiliaryMethods = AccountAuxiliaryMethods(fetchResour
return Signal { subscriber in
subscriber.putNext(.reset)
if let data = try? Data(contentsOf: url, options: .mappedRead) {
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< data.count, complete: true))
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< Int64(data.count), complete: true))
}
return EmptyDisposable
@ -75,7 +75,7 @@ public let telegramAccountAuxiliaryMethods = AccountAuxiliaryMethods(fetchResour
return Signal { subscriber in
subscriber.putNext(.reset)
if let data = try? Data(contentsOf: url, options: .mappedRead) {
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< data.count, complete: true))
subscriber.putNext(.dataPart(resourceOffset: 0, data: data, range: 0 ..< Int64(data.count), complete: true))
}
return EmptyDisposable

View file

@ -126,10 +126,10 @@ public struct MediaAutoDownloadCategory: Codable, Equatable {
public var otherPrivate: Bool
public var groups: Bool
public var channels: Bool
public var sizeLimit: Int32
public var sizeLimit: Int64
public var predownload: Bool
public init(contacts: Bool, otherPrivate: Bool, groups: Bool, channels: Bool, sizeLimit: Int32, predownload: Bool) {
public init(contacts: Bool, otherPrivate: Bool, groups: Bool, channels: Bool, sizeLimit: Int64, predownload: Bool) {
self.contacts = contacts
self.otherPrivate = otherPrivate
self.groups = groups
@ -145,7 +145,11 @@ public struct MediaAutoDownloadCategory: Codable, Equatable {
self.otherPrivate = try container.decode(Int32.self, forKey: "otherPrivate") != 0
self.groups = try container.decode(Int32.self, forKey: "groups") != 0
self.channels = try container.decode(Int32.self, forKey: "channels") != 0
self.sizeLimit = try container.decode(Int32.self, forKey: "size")
if let sizeLimit = try container.decodeIfPresent(Int64.self, forKey: "size64") {
self.sizeLimit = sizeLimit
} else {
self.sizeLimit = Int64(try container.decode(Int32.self, forKey: "size"))
}
self.predownload = try container.decode(Int32.self, forKey: "predownload") != 0
}
@ -156,7 +160,7 @@ public struct MediaAutoDownloadCategory: Codable, Equatable {
try container.encode((self.otherPrivate ? 1 : 0) as Int32, forKey: "otherPrivate")
try container.encode((self.groups ? 1 : 0) as Int32, forKey: "groups")
try container.encode((self.channels ? 1 : 0) as Int32, forKey: "channels")
try container.encode(self.sizeLimit, forKey: "size")
try container.encode(self.sizeLimit, forKey: "size64")
try container.encode((self.predownload ? 1 : 0) as Int32, forKey: "predownload")
}
}
@ -172,12 +176,12 @@ public struct MediaAutoDownloadSettings: Codable, Equatable {
public var downloadInBackground: Bool
public static var defaultSettings: MediaAutoDownloadSettings {
let mb: Int32 = 1024 * 1024
let mb: Int64 = 1024 * 1024
let presets = MediaAutoDownloadPresets(low: MediaAutoDownloadCategories(basePreset: .low, photo: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false),
video: MediaAutoDownloadCategory(contacts: false, otherPrivate: false, groups: false, channels: false, sizeLimit: 1 * mb, predownload: false),
file: MediaAutoDownloadCategory(contacts: false, otherPrivate: false, groups: false, channels: false, sizeLimit: 1 * mb, predownload: false)),
medium: MediaAutoDownloadCategories(basePreset: .medium, photo: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false),
video: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: Int32(2.5 * CGFloat(mb)), predownload: false),
video: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: Int64(2.5 * CGFloat(mb)), predownload: false),
file: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false)),
high: MediaAutoDownloadCategories(basePreset: .high, photo: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 1 * mb, predownload: false),
video: MediaAutoDownloadCategory(contacts: true, otherPrivate: true, groups: true, channels: true, sizeLimit: 10 * mb, predownload: true),

View file

@ -130,8 +130,8 @@ private final class NativeVideoContentNode: ASDisplayNode, UniversalVideoContent
}
}
private let _bufferingStatus = Promise<(IndexSet, Int)?>()
var bufferingStatus: Signal<(IndexSet, Int)?, NoError> {
private let _bufferingStatus = Promise<(IndexSet, Int64)?>()
var bufferingStatus: Signal<(IndexSet, Int64)?, NoError> {
return self._bufferingStatus.get()
}

View file

@ -132,8 +132,8 @@ private final class PlatformVideoContentNode: ASDisplayNode, UniversalVideoConte
return self._status.get()
}
private let _bufferingStatus = Promise<(IndexSet, Int)?>()
var bufferingStatus: Signal<(IndexSet, Int)?, NoError> {
private let _bufferingStatus = Promise<(IndexSet, Int64)?>()
var bufferingStatus: Signal<(IndexSet, Int64)?, NoError> {
return self._bufferingStatus.get()
}

View file

@ -50,8 +50,8 @@ private final class SystemVideoContentNode: ASDisplayNode, UniversalVideoContent
return self._status.get()
}
private let _bufferingStatus = Promise<(IndexSet, Int)?>()
var bufferingStatus: Signal<(IndexSet, Int)?, NoError> {
private let _bufferingStatus = Promise<(IndexSet, Int64)?>()
var bufferingStatus: Signal<(IndexSet, Int64)?, NoError> {
return self._bufferingStatus.get()
}

View file

@ -28,11 +28,11 @@ private final class UniversalVideoContentHolder {
var statusValue: MediaPlayerStatus?
var bufferingStatusDisposable: Disposable?
var bufferingStatusValue: (IndexSet, Int)?
var bufferingStatusValue: (IndexSet, Int64)?
var playbackCompletedIndex: Int?
init(content: UniversalVideoContent, contentNode: UniversalVideoContentNode & ASDisplayNode, statusUpdated: @escaping (MediaPlayerStatus?) -> Void, bufferingStatusUpdated: @escaping ((IndexSet, Int)?) -> Void, playbackCompleted: @escaping () -> Void) {
init(content: UniversalVideoContent, contentNode: UniversalVideoContentNode & ASDisplayNode, statusUpdated: @escaping (MediaPlayerStatus?) -> Void, bufferingStatusUpdated: @escaping ((IndexSet, Int64)?) -> Void, playbackCompleted: @escaping () -> Void) {
self.content = content
self.contentNode = contentNode
@ -131,7 +131,7 @@ private final class UniversalVideoContentHolder {
private final class UniversalVideoContentHolderCallbacks {
let playbackCompleted = Bag<() -> Void>()
let status = Bag<(MediaPlayerStatus?) -> Void>()
let bufferingStatus = Bag<((IndexSet, Int)?) -> Void>()
let bufferingStatus = Bag<((IndexSet, Int64)?) -> Void>()
var isEmpty: Bool {
return self.playbackCompleted.isEmpty && self.status.isEmpty && self.bufferingStatus.isEmpty
@ -278,7 +278,7 @@ public final class UniversalVideoManagerImpl: UniversalVideoManager {
} |> runOn(Queue.mainQueue())
}
public func bufferingStatusSignal(content: UniversalVideoContent) -> Signal<(IndexSet, Int)?, NoError> {
public func bufferingStatusSignal(content: UniversalVideoContent) -> Signal<(IndexSet, Int64)?, NoError> {
return Signal { subscriber in
var callbacks: UniversalVideoContentHolderCallbacks
if let current = self.holderCallbacks[content.id] {

View file

@ -50,8 +50,8 @@ final class WebEmbedVideoContentNode: ASDisplayNode, UniversalVideoContentNode {
return self._status.get()
}
private let _bufferingStatus = Promise<(IndexSet, Int)?>()
var bufferingStatus: Signal<(IndexSet, Int)?, NoError> {
private let _bufferingStatus = Promise<(IndexSet, Int64)?>()
var bufferingStatus: Signal<(IndexSet, Int64)?, NoError> {
return self._bufferingStatus.get()
}

View file

@ -401,6 +401,10 @@ public class YoutubeEmbedStoryboardMediaResource: TelegramMediaResource {
public let storyboardId: Int32
public let url: String
public var size: Int64? {
return nil
}
public init(videoId: String, storyboardId: Int32, url: String) {
self.videoId = videoId
self.storyboardId = storyboardId

View file

@ -9,7 +9,7 @@ import TgVoip
import TgVoipWebrtc
private let debugUseLegacyVersionForReflectors: Bool = {
#if DEBUG
#if DEBUG && false
return true
#else
return false
@ -81,10 +81,10 @@ private func callConnectionDescriptionsWebrtc(_ connection: CallSessionConnectio
}
var result: [OngoingCallConnectionDescriptionWebrtc] = []
if !reflector.ip.isEmpty {
result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, hasTcp: false, ip: reflector.ip, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag)))
result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, hasTcp: reflector.isTcp, ip: reflector.ip, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag)))
}
if !reflector.ipv6.isEmpty {
result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, hasTcp: false, ip: reflector.ipv6, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag)))
result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, hasTcp: reflector.isTcp, ip: reflector.ipv6, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag)))
}
return result
case let .webRtcReflector(reflector):
@ -743,6 +743,12 @@ public final class OngoingCallContext {
private var signalingConnectionManager: QueueLocalObject<CallSignalingConnectionManager>?
public static func versions(includeExperimental: Bool, includeReference: Bool) -> [(version: String, supportsVideo: Bool)] {
#if DEBUG
if "".isEmpty {
return [("5.0.0", true)]
}
#endif
if debugUseLegacyVersionForReflectors {
return [(OngoingCallThreadLocalContext.version(), true)]
} else {
@ -784,7 +790,7 @@ public final class OngoingCallContext {
var allowP2P = allowP2P
if debugUseLegacyVersionForReflectors {
useModernImplementation = true
version = "4.1.2"
version = "5.0.0"
allowP2P = false
} else {
useModernImplementation = version != OngoingCallThreadLocalContext.version()
@ -820,35 +826,53 @@ public final class OngoingCallContext {
reflectorIdMapping[reflectorIdList[i]] = UInt8(i + 1)
}
var signalingReflector: OngoingCallConnectionDescriptionWebrtc?
var processedConnections: [CallSessionConnection] = []
var filteredConnections: [OngoingCallConnectionDescriptionWebrtc] = []
for connection in unfilteredConnections {
connectionsLoop: for connection in unfilteredConnections {
if processedConnections.contains(connection) {
continue
}
processedConnections.append(connection)
filteredConnections.append(contentsOf: callConnectionDescriptionsWebrtc(connection, idMapping: reflectorIdMapping))
switch connection {
case let .reflector(reflector):
if reflector.isTcp {
if signalingReflector == nil {
signalingReflector = OngoingCallConnectionDescriptionWebrtc(reflectorId: 0, hasStun: false, hasTurn: true, hasTcp: true, ip: reflector.ip, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag))
}
continue connectionsLoop
}
case .webRtcReflector:
break
}
var webrtcConnections: [OngoingCallConnectionDescriptionWebrtc] = []
for connection in callConnectionDescriptionsWebrtc(connection, idMapping: reflectorIdMapping) {
webrtcConnections.append(connection)
}
filteredConnections.append(contentsOf: webrtcConnections)
}
for connection in filteredConnections {
if connection.username == "reflector" {
let peerTag = dataWithHexString(connection.password)
if #available(iOS 12.0, *) {
strongSelf.signalingConnectionManager = QueueLocalObject(queue: queue, generate: {
return CallSignalingConnectionManager(queue: queue, peerTag: peerTag, servers: [OngoingCallConnectionDescriptionWebrtc(reflectorId: 0, hasStun: false, hasTurn: true, hasTcp: true, ip: "91.108.12.1", port: 533, username: "reflector", password: connection.password)], dataReceived: { data in
guard let strongSelf = self else {
return
}
strongSelf.withContext { context in
if let context = context as? OngoingCallThreadLocalContextWebrtc {
context.addSignaling(data)
}
}
})
})
}
if let signalingReflector = signalingReflector {
if #available(iOS 12.0, *) {
let peerTag = dataWithHexString(signalingReflector.password)
break
strongSelf.signalingConnectionManager = QueueLocalObject(queue: queue, generate: {
return CallSignalingConnectionManager(queue: queue, peerTag: peerTag, servers: [signalingReflector], dataReceived: { data in
guard let strongSelf = self else {
return
}
strongSelf.withContext { context in
if let context = context as? OngoingCallThreadLocalContextWebrtc {
context.addSignaling(data)
}
}
})
})
}
}

@ -1 +1 @@
Subproject commit f3c148739bf0ad37a0882a7fcafcbc56969c4f8a
Subproject commit c741da4568b0971ed06d9ccdc7a94db566bb84a0

View file

@ -727,7 +727,7 @@ final class WatchAudioHandler: WatchRequestHandler {
replyMessageId = MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToMid)
}
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: data.count, attributes: [.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)]).start()
let _ = enqueueMessages(account: context.account, peerId: peerId, messages: [.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: Int64(data.count), attributes: [.Audio(isVoice: true, duration: Int(duration), title: nil, performer: nil, waveform: nil)])), replyToMessageId: replyMessageId, localGroupingKey: nil, correlationId: nil)]).start()
}
})
} else {