MetadataStruct moved to its own module.
Signed-off-by: Adam Rocska <adam.rocska@adams.solutions>
This commit is contained in:
parent
5db534cb55
commit
3b80256856
|
@ -35,7 +35,7 @@ let package = Package(
|
|||
|
||||
.target(
|
||||
name: "MaxMindDBReader",
|
||||
dependencies: ["Index", "MaxMindDecoder"],
|
||||
dependencies: ["Index", "Metadata", "MaxMindDecoder"],
|
||||
path: "Sources/MaxMindDBReader"
|
||||
),
|
||||
.target(
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Foundation
|
||||
import MaxMindDecoder
|
||||
import Index
|
||||
import Metadata
|
||||
|
||||
public class InMemoryReader {
|
||||
|
||||
|
@ -10,7 +11,7 @@ public class InMemoryReader {
|
|||
|
||||
private let databaseContent: Data
|
||||
private let indexRange: Range<Data.Index>
|
||||
let metadata: MetadataStruct
|
||||
let metadata: Metadata
|
||||
|
||||
public init(data: Data) throws {
|
||||
databaseContent = data
|
||||
|
@ -30,7 +31,7 @@ public class InMemoryReader {
|
|||
upper: databaseContent.endIndex
|
||||
))
|
||||
let rawMetadata = databaseContent.subdata(in: metadataRange)
|
||||
guard let metadata = MetadataStruct(rawMetadata) else {
|
||||
guard let metadata = Metadata(rawMetadata) else {
|
||||
throw ReaderError.corruptMetadata
|
||||
}
|
||||
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
import Foundation
|
||||
import MaxMindDecoder
|
||||
|
||||
struct MetadataStruct {
|
||||
let nodeCount: UInt32
|
||||
let recordSize: UInt16
|
||||
let ipVersion: UInt16
|
||||
let databaseType: String
|
||||
let languages: [String]
|
||||
let binaryFormatMajorVersion: UInt16
|
||||
let binaryFormatMinorVersion: UInt16
|
||||
let buildEpoch: UInt64
|
||||
let description: [String: String]
|
||||
var nodeByteSize: UInt16 { get { return recordSize / 4 } }
|
||||
var searchTreeSize: UInt64 { get { return UInt64(nodeCount * UInt32(nodeByteSize)) } }
|
||||
|
||||
init?(_ iterator: MaxMindIterator) {
|
||||
guard let mapControlByte = iterator.next() else { return nil }
|
||||
if mapControlByte.type != .map { return nil }
|
||||
let decoder = MaxMindDecoder(inputEndianness: .big)
|
||||
|
||||
let decoded: [String: Any] = decoder.decode(iterator, size: Int(mapControlByte.payloadSize))
|
||||
|
||||
guard let nodeCount = decoded["node_count"] as? UInt32 else { return nil }
|
||||
guard let recordSize = decoded["record_size"] as? UInt16 else { return nil }
|
||||
guard let ipVersion = decoded["ip_version"] as? UInt16 else { return nil }
|
||||
guard let databaseType = decoded["database_type"] as? String else { return nil }
|
||||
guard let languages = decoded["languages"] as? [String] else { return nil }
|
||||
guard let majorVersion = decoded["binary_format_major_version"] as? UInt16 else { return nil }
|
||||
guard let minorVersion = decoded["binary_format_minor_version"] as? UInt16 else { return nil }
|
||||
guard let buildEpoch = decoded["build_epoch"] as? UInt64 else { return nil }
|
||||
guard let description = decoded["description"] as? [String: String] else { return nil }
|
||||
|
||||
self.nodeCount = nodeCount
|
||||
self.recordSize = recordSize
|
||||
self.ipVersion = ipVersion
|
||||
self.databaseType = databaseType
|
||||
self.languages = languages
|
||||
self.binaryFormatMajorVersion = majorVersion
|
||||
self.binaryFormatMinorVersion = minorVersion
|
||||
self.buildEpoch = buildEpoch
|
||||
self.description = description
|
||||
}
|
||||
|
||||
init?(_ data: Data) {
|
||||
guard let iterator = MaxMindIterator(data) else { return nil }
|
||||
self.init(iterator)
|
||||
}
|
||||
}
|
|
@ -1,17 +1,49 @@
|
|||
import Foundation
|
||||
import MaxMindDecoder
|
||||
|
||||
public protocol Metadata {
|
||||
public struct Metadata {
|
||||
public let nodeCount: UInt32
|
||||
public let recordSize: UInt16
|
||||
public let ipVersion: UInt16
|
||||
public let databaseType: String
|
||||
public let languages: [String]
|
||||
public let binaryFormatMajorVersion: UInt16
|
||||
public let binaryFormatMinorVersion: UInt16
|
||||
public let buildEpoch: UInt64
|
||||
public let description: [String: String]
|
||||
public var nodeByteSize: UInt16 { get { return recordSize / 4 } }
|
||||
public var searchTreeSize: UInt64 { get { return UInt64(nodeCount * UInt32(nodeByteSize)) } }
|
||||
|
||||
var nodeCount: UInt32 { get }
|
||||
var recordSize: UInt16 { get }
|
||||
var ipVersion: UInt16 { get }
|
||||
var databaseType: String { get }
|
||||
var languages: [String] { get }
|
||||
var binaryFormatMajorVersion: UInt16 { get }
|
||||
var binaryFormatMinorVersion: UInt16 { get }
|
||||
var buildEpoch: UInt64 { get }
|
||||
var description: [String:String] { get }
|
||||
var nodeByteSize: UInt16 { get }
|
||||
var searchTreeSize: UInt64 { get }
|
||||
public init?(_ iterator: MaxMindIterator) {
|
||||
guard let mapControlByte = iterator.next() else { return nil }
|
||||
if mapControlByte.type != .map { return nil }
|
||||
let decoder = MaxMindDecoder(inputEndianness: .big)
|
||||
|
||||
let decoded: [String: Any] = decoder.decode(iterator, size: Int(mapControlByte.payloadSize))
|
||||
|
||||
guard let nodeCount = decoded["node_count"] as? UInt32 else { return nil }
|
||||
guard let recordSize = decoded["record_size"] as? UInt16 else { return nil }
|
||||
guard let ipVersion = decoded["ip_version"] as? UInt16 else { return nil }
|
||||
guard let databaseType = decoded["database_type"] as? String else { return nil }
|
||||
guard let languages = decoded["languages"] as? [String] else { return nil }
|
||||
guard let majorVersion = decoded["binary_format_major_version"] as? UInt16 else { return nil }
|
||||
guard let minorVersion = decoded["binary_format_minor_version"] as? UInt16 else { return nil }
|
||||
guard let buildEpoch = decoded["build_epoch"] as? UInt64 else { return nil }
|
||||
guard let description = decoded["description"] as? [String: String] else { return nil }
|
||||
|
||||
self.nodeCount = nodeCount
|
||||
self.recordSize = recordSize
|
||||
self.ipVersion = ipVersion
|
||||
self.databaseType = databaseType
|
||||
self.languages = languages
|
||||
self.binaryFormatMajorVersion = majorVersion
|
||||
self.binaryFormatMinorVersion = minorVersion
|
||||
self.buildEpoch = buildEpoch
|
||||
self.description = description
|
||||
}
|
||||
|
||||
public init?(_ data: Data) {
|
||||
guard let iterator = MaxMindIterator(data) else { return nil }
|
||||
self.init(iterator)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
@testable import MaxMindDBReader
|
||||
@testable import Metadata
|
||||
import MaxMindDecoder
|
||||
|
||||
class MetadataStructTest: XCTestCase {
|
||||
class MetadataTest: XCTestCase {
|
||||
|
||||
private func assertCalculatedValues(
|
||||
_ metadata: MetadataStruct,
|
||||
_ metadata: Metadata,
|
||||
file: StaticString = #file,
|
||||
line: UInt = #line
|
||||
) {
|
||||
|
@ -17,21 +17,21 @@ class MetadataStructTest: XCTestCase {
|
|||
}
|
||||
|
||||
func testInit_nilIfCantCreateIterator() {
|
||||
XCTAssertNil(MetadataStruct(Data()))
|
||||
XCTAssertNil(Metadata(Data()))
|
||||
}
|
||||
|
||||
func testInit_nilIfCantFetchFirstControlByte() {
|
||||
let data = Data([0b0000_1111])
|
||||
XCTAssertNil(MetadataStruct(data))
|
||||
XCTAssertNil(Metadata(data))
|
||||
}
|
||||
|
||||
func testInit_nilIfFirstControlByteIsNotMap() {
|
||||
let data = Data([0b0010_1111])
|
||||
XCTAssertNil(MetadataStruct(data))
|
||||
XCTAssertNil(Metadata(data))
|
||||
}
|
||||
|
||||
func testInit_withBinary() {
|
||||
guard let metadata = MetadataStruct(binaryMetaData) else {
|
||||
guard let metadata = Metadata(binaryMetaData) else {
|
||||
XCTFail("Input binary is valid. Should have constructed a proper struct.")
|
||||
return
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class MetadataStructTest: XCTestCase {
|
|||
XCTFail("Input binary is valid. Should have constructed a proper MaxMindIterator.")
|
||||
return
|
||||
}
|
||||
guard let metadata = MetadataStruct(iterator) else {
|
||||
guard let metadata = Metadata(iterator) else {
|
||||
XCTFail("Input binary is valid. Should have constructed a proper struct.")
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue