Allow reading and writing of empty header maps

This commit is contained in:
Milen Dzhumerov 2017-08-22 20:32:01 +01:00
parent 1f3a874c98
commit f72f8d839e
5 changed files with 17 additions and 16 deletions

View File

@ -277,17 +277,17 @@ func parseHeaderMap(data: Data) throws -> DataHeaderParseResult {
found: reseredValue)
}
guard bucketCount.isPowerOf2 else {
guard bucketCount == 0 || bucketCount.isPowerOf2 else {
throw HeaderMapParseError.bucketCountNotPowerOf2(found: bucketCount)
}
guard Int(stringSectionOffset) < data.count else {
guard Int(stringSectionOffset) <= data.count else {
throw HeaderMapParseError.outOfBoundsStringSectionOffset
}
let bucketsSectionSize = Int(bucketCount) * BinaryHeaderMap.Bucket.packedSize
let headerAndBucketsSectionSize = H.packedSize + bucketsSectionSize
guard headerAndBucketsSectionSize < data.count else {
guard headerAndBucketsSectionSize <= data.count else {
throw HeaderMapParseError.bucketsSectionOverflow
}

View File

@ -39,7 +39,6 @@ public enum HeaderMapParseError: LocalizedError {
public enum HeaderMapCreateError: LocalizedError {
case invalidStringSectionOffset
case noEntries
case stringWithoutOffsetInTable
case hashTableFull
case unhashableKey
@ -82,8 +81,6 @@ extension HeaderMapCreateError {
switch self {
case .invalidStringSectionOffset:
return "The string section offset is invalid"
case .noEntries:
return "Header map needs to contain at least one entry"
case .stringWithoutOffsetInTable:
return "String not present in string section"
case .hashTableFull:

View File

@ -25,10 +25,6 @@ import Foundation
func makeHeaderMapBinaryData(
withEntries unsafeEntries: [HeaderMap.Entry]) throws -> Data {
guard unsafeEntries.count > 0 else {
throw HeaderMapCreateError.noEntries
}
let safeEntries = sanitize(headerEntries: unsafeEntries)
let allStrings = Set(safeEntries.flatMap { [$0.key, $0.prefix, $0.suffix] })
let stringSection = try makeStringSection(allStrings: allStrings)
@ -81,9 +77,12 @@ fileprivate func makeStringSection(
allStrings: Set<String>) throws -> StringSection {
var buffer = Data()
buffer.append(UInt8(BinaryHeaderMap.StringSectionOffset.Reserved))
var offsets = Dictionary<String, BinaryHeaderMap.StringSectionOffset>()
if !allStrings.isEmpty {
buffer.append(UInt8(BinaryHeaderMap.StringSectionOffset.Reserved))
}
for string in allStrings {
guard let stringBytes = string.data(using: BinaryHeaderMap.StringEncoding) else {
throw HeaderMapError.unencodableString
@ -134,8 +133,6 @@ fileprivate func makeBucketSection(
forEntries entries: [HeaderMap.Entry],
stringSection: StringSection) throws -> BucketSection {
assert(entries.count > 0)
let bucketCount = numberOfBuckets(forEntryCount: entries.count)
var bytes = Data(count: bucketCount * BinaryHeaderMap.Bucket.packedSize)
try bytes.withUnsafeMutableBytes {
@ -188,8 +185,6 @@ fileprivate func makeBucketSection(
}
fileprivate func numberOfBuckets(forEntryCount entryCount: Int) -> Int {
assert(entryCount > 0)
let minimumSlots = Int(ceil(Double(entryCount) * (1.0 / 0.7)))
var bucketCount = 1
while bucketCount < minimumSlots {

View File

@ -36,7 +36,8 @@ func addPrintCommand(to group: Group) {
let output = try FilePrintCommand.perform(
input: FilePrintCommand.Input(headerMapFile: url, argumentPath: file)
)
Swift.print(output.text)
let text = output.text.isEmpty ? "Empty header map" : output.text
Swift.print(text)
} catch (let error) {
Swift.print(error.localizedDescription)
exit(ToolReturnCode.failure.rawValue)

View File

@ -129,5 +129,13 @@ class HeaderMapTests: XCTestCase {
let decodedEntries = hmap.makeJSONHeaderMap().entries
XCTAssertEqual(entries, decodedEntries)
}
func testEmptyHeaderMap() throws {
let hmapBinaryData = try HeaderMap.makeBinary(withEntries: [])
XCTAssertNotNil(hmapBinaryData)
let hmap = try HeaderMap(data: hmapBinaryData)
let hmapEntries = Set<HeaderMap.Entry>(hmap.makeEntryList())
XCTAssertEqual(Set(), hmapEntries)
}
}