Allow reading and writing of empty header maps
This commit is contained in:
parent
1f3a874c98
commit
f72f8d839e
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue