<commit_before>//
//  RDGCDServerResourceResponse.swift
//  R2Streamer
//
//  Created by <NAME> on 13/01/2017.
//  Copyright © 2017 Readium. All rights reserved.
//

import GCDWebServers


enum RDWebServerResponseError: Error {
    case streamFailed
    case invalidRange
}


open class RDWebServerResourceResponse: GCDWebServerFileResponse {
    
    var inputStream: SeekableInputStream
    var range: Range<UInt64>
    var totalNumberOfBytesRead: UInt64 = 0
    var buffer:Array<UInt8>
    let bufferSize = 32 * 1024
    
    init(inputStream: SeekableInputStream, range: NSRange?, contentType: String) {
        buffer = Array<UInt8>(repeating: 0, count: bufferSize)
        self.inputStream = inputStream
        
        let totalLength = inputStream.length
        if let r = range {
            NSLog("Request range \(r.location)-\(r.length)")
            
            if r.location == Int.max {
                let l = min(UInt64(r.length), totalLength)
                self.range = Range<UInt64>(uncheckedBounds: (lower: totalLength - l, upper: totalLength))
            } else if r.location < 0 {
                // TODO: negative range location
                // The whole data for now
                self.range = Range<UInt64>(uncheckedBounds: (lower: 0, upper: totalLength))
            } else {
                let o = min(UInt64(r.location), totalLength)
                let l = (r.length == -1) ? totalLength : min(UInt64(r.length), totalLength)
                self.range = Range<UInt64>(uncheckedBounds: (lower: o, upper: o + l))
            }
            
            
        } else {
            self.range = Range<UInt64>(uncheckedBounds: (lower: 0, upper: totalLength))
        }
        
        super.init()
        
        if range != nil {
            statusCode = 206
            
            let lower = self.range.lowerBound
            let upper = self.range.upperBound - 1
            setValue("bytes \(lower)-\(upper)/\(totalLength)", forAdditionalHeader: "Content-Range")
            setValue("bytes", forAdditionalHeader: "Accept-Ranges")
        } else {
            statusCode = 200
        }

        self.contentType = contentType
        contentLength = UInt(self.range.count)
        
        // TODO: lastModifiedDate = ...
        // TODO: setValue("", forAdditionalHeader: "Cache-Control")
    }
    <commit_msg>Fix bug with range request with length=-1<commit_after>//
//  RDGCDServerResourceResponse.swift
//  R2Streamer
//
//  Created by <NAME> on 13/01/2017.
//  Copyright © 2017 Readium. All rights reserved.
//

import GCDWebServers


enum RDWebServerResponseError: Error {
    case streamFailed
    case invalidRange
}


open class RDWebServerResourceResponse: GCDWebServerFileResponse {
    
    var inputStream: SeekableInputStream
    var range: Range<UInt64>
    var totalNumberOfBytesRead: UInt64 = 0
    var buffer:Array<UInt8>
    let bufferSize = 32 * 1024
    
    init(inputStream: SeekableInputStream, range: NSRange?, contentType: String) {
        buffer = Array<UInt8>(repeating: 0, count: bufferSize)
        self.inputStream = inputStream
        
        let totalLength = inputStream.length
        if let r = range {
            NSLog("Request range \(r.location)-\(r.length)")
            
            if r.location == Int.max {
                let l = min(UInt64(r.length), totalLength)
                self.range = Range<UInt64>(uncheckedBounds: (lower: totalLength - l, upper: totalLength))
            } else if r.location < 0 {
                // TODO: negative range location
                // The whole data for now
                self.range = Range<UInt64>(uncheckedBounds: (lower: 0, upper: totalLength))
            } else {
                let o = min(UInt64(r.location), totalLength)
                let l = (r.length == -1) ? (totalLength - o) : min(UInt64(r.length), totalLength - o)
                self.range = Range<UInt64>(uncheckedBounds: (lower: o, upper: o + l))
            }
            
            
        } else {
            self.range = Range<UInt64>(uncheckedBounds: (lower: 0, upper: totalLength))
        }
        
        super.init()
        
        if range != nil {
            statusCode = 206
            
            let lower = self.range.lowerBound
            let upper = self.range.upperBound - 1
            setValue("bytes \(lower)-\(upper)/\(totalLength)", forAdditionalHeader: "Content-Range")
            setValue("bytes", forAdditionalHeader: "Accept-Ranges")
        } else {
            statusCode = 200
        }

        self.contentType = contentType
        contentLength = UInt(self.range.count)
        
        // TODO: lastModifiedDate = ...
        // TODO: setValue("", forAdditionalHeader: "Cache-Control")
    }
    
{'fraction_non_alphanumeric': 0.1067675493905002, 'fraction_numerical': 0.022068095838587643, 'mean_word_length': 1.8807506053268765, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7313223', 'n_tokens_mistral': 1415, 'n_tokens_neox': 1302, 'n_words': 326}