<commit_before>// ImageDownloader.h
//
// Copyright (c) 2014–2015 Alamofire (http://alamofire.org)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import Alamofire
import UIKit

public class ImageDownloader {
    
    public typealias ImageDownloadSuccessHandler = (NSURLRequest?, NSHTTPURLResponse?, UIImage) -> Void
    public typealias ImageDownloadFailureHandler = (NSURLRequest?, NSHTTPURLResponse?, NSError?) -> Void
    
    public enum DownloadPrioritization {
        case FIFO, LIFO
    }
    
    // MARK: - Properties

    public let imageCache: ImageCache
    
    private let sessionManager: Alamofire.Manager
    
    private var queuedRequests: [Request]
    private let synchronizationQueue: dispatch_queue_t
    private let responseQueue: dispatch_queue_t
    private let downloadPrioritization: DownloadPrioritization
    
    private var activeRequestCount: Int
    private let maximumActiveDownloads: Int
    
    // MARK: - Initialization Methods
    
    public class var defaultInstance: ImageDownloader {
        struct Singleton {
            static let instance = ImageDownloader(configuration: ImageDownloader.defaultSessionConfiguration)
        }
        
        return Singleton.instance
    }
    
    public class var defaultSessionConfiguration: NSURLSessionConfiguration {
        let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
        
        configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders()
        configuration.HTTPShouldSetCookies = true // true by default
        configuration.HTTPShouldUsePipelining = true // risky change...
//        configuration.HTTPMaximumConnectionsPerHost = 4 on iOS or 6 on OSX
        
        configuration.requestCachePolicy = .UseProtocolCachePolicy // Let server decide
        configuration.allowsCellularAccess = true
        configuration.timeoutIntervalForRequest = 30 // default is 60
        
        return configuration
    }
    
    public init(
        configuration: NSURLSessionConfiguration? = nil,
        downloadPrioritization: DownloadPrioritization = .FIFO,
        maximumActiveDownloads: Int = 4,
        imageCache: ImageCache = AutoPurgingImageCache())
    {
        self.sessionManager = Alamofire.Manager(configuration: configuration)
        self.sessionManager.startRequestsImmediately = false
        
        self.downloadPrioritization = downloadPrioritization
        self.maximumActiveDownloads = maximumActiveDownloads
        self.imageCache = imageCache
        
        self.queuedRequests = []
        self.activeRequestCount = 0
        
        self.synchronizationQueue = {
            let name = String(format: "com.alamofire.imagedownloader.synchronizationqueue-%08%08", arc4random(), arc4random())<commit_msg>Added a defaultURLCache class method to the ImageDownloader with reasonable defaults.<commit_after>// ImageDownloader.h
//
// Copyright (c) 2014–2015 Alamofire (http://alamofire.org)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import Alamofire
import UIKit

public class ImageDownloader {
    
    public typealias ImageDownloadSuccessHandler = (NSURLRequest?, NSHTTPURLResponse?, UIImage) -> Void
    public typealias ImageDownloadFailureHandler = (NSURLRequest?, NSHTTPURLResponse?, NSError?) -> Void
    
    public enum DownloadPrioritization {
        case FIFO, LIFO
    }
    
    // MARK: - Properties

    public let imageCache: ImageCache
    
    private let sessionManager: Alamofire.Manager
    
    private var queuedRequests: [Request]
    private let synchronizationQueue: dispatch_queue_t
    private let responseQueue: dispatch_queue_t
    private let downloadPrioritization: DownloadPrioritization
    
    private var activeRequestCount: Int
    private let maximumActiveDownloads: Int
    
    // MARK: - Initialization Methods
    
    public class var defaultInstance: ImageDownloader {
        struct Singleton {
            static let instance = ImageDownloader(configuration: ImageDownloader.defaultURLSessionConfiguration())
        }
        
        return Singleton.instance
    }
    
    public class func defaultURLSessionConfiguration() -> NSURLSessionConfiguration {
        let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
        
        configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders()
        configuration.HTTPShouldSetCookies = true // true by default
        configuration.HTTPShouldUsePipelining = true // risky change...
//        configuration.HTTPMaximumConnectionsPerHost = 4 on iOS or 6 on OSX
        
        configuration.requestCachePolicy = .UseProtocolCachePolicy // Let server decide (should handle `willCache`)
        configuration.allowsCellularAccess = true
        configuration.timeoutIntervalForRequest = 30 // default is 60
        
        configuration.URLCache = ImageDownloader.defaultURLCache()
        
        return configuration
    }
    
    public class func defaultURLCache() -> NSURLCache {
        let URLCache = NSURLCache(
            memoryCapacity: 50 * 1024 * 1024, // 50 MB
            diskCapacity: 100 * 1024 * 1024, // 100 MB
            diskPath: "com.alamofire.imagedownloader"
        )
        
        return URLCache
    }
    
    public init(
        configuration: NSURLSessionConfiguration? = nil,
        downloadPrioritization: DownloadPrioritization = .FIFO,
        maximumActiveDownloads: Int = 4,
        imageCache: ImageCache = AutoPurgingImageCache())
    {
        self.sessionManager = Alamofire.Manager(configuration: configuration)
        self.sessionManager.startRequestsImmediately = false
        
        self.downloadPrioritization = downloadPrioritization
        self.maximumActiveDownloads = maximumActiveDownloads
        self.imageCache = imageCache
        
        self.queuedRequests = []
        self.activeRequestCount = 0
        
        self.synchronizationQueue = {
            let name = String(format: "com.alamofire.imagedownloader.synchronizationqueue-%08%08", arc4random(), arc4random())
{'fraction_non_alphanumeric': 0.0640582572204394, 'fraction_numerical': 0.008639842014317452, 'mean_word_length': 3.0986342943854326, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 41, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7432603', 'n_tokens_mistral': 2053, 'n_tokens_neox': 1935, 'n_words': 684}