Skip to content

Commit 943cb15

Browse files
authored
Add Codable and Equatable conformance to Header, and add count property to CPIOArchiveReader (#1)
1 parent 6d4f049 commit 943cb15

File tree

6 files changed

+116
-7
lines changed

6 files changed

+116
-7
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.0.2](https://github.com/LebJe/CPIOArchiveKit/releases/tag/0.0.2) - 2021-06-11
9+
10+
### Added
11+
12+
- `Header` now conforms to `Codable` and `Equatable`.
13+
- `CPIOArchiveReader` now has a `count` property.
14+
815
## [0.0.1](https://github.com/LebJe/CPIOArchiveKit/releases/tag/0.0.1) - 2021-05-16
916

1017
### Added

Package.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ let package = Package(
88
.macOS(.v10_15),
99
.iOS(.v13),
1010
.tvOS(.v12),
11-
.watchOS(.v7)
12-
]
13-
,products: [
11+
.watchOS(.v7),
12+
],
13+
products: [
1414
.library(
1515
name: "CPIOArchiveKit",
1616
targets: ["CPIOArchiveKit"]

Sources/CPIOArchiveKit/CPIOArchiveReader.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public struct CPIOArchiveReader {
2222
///
2323
public var headers: [Header] = []
2424

25+
/// The amount of files in this archive.
26+
public var count: Int { self.headers.count }
27+
2528
/// The initializer reads all the `cpio` headers in preparation for random access to the header's file contents later.
2629
///
2730
/// - Parameters:

Sources/CPIOArchiveKit/Checksum.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
/// (From [go-cpio's documentation](https://github.com/cavaliercoder/go-cpio/blob/925f9528c45e5b74f52963bd11f1988ad99a95a5/header.go#L60)).
1111
///
1212
/// Use `Checksum.init(bytes:)` to compute the checksum of a file you will add to the archive.
13-
public struct Checksum {
13+
public struct Checksum: Codable, Equatable {
1414
/// The sum of all the bytes in the file.
1515
public var sum: Int = 0
1616

1717
/// Compute the checksum of `bytes`.
1818
public init(bytes: [UInt8]) { bytes.forEach({ self.sum += Int($0 & 0xFF) }) }
19-
19+
2020
/// Set `self.sum` to a pre-computed checksum.
2121
public init(sum: Int) { self.sum = sum }
2222
}

Sources/CPIOArchiveKit/FileType.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
/// `FileType` specifies the type of file in an archive.
88
///
99
/// Documentation comments are taken from [FreeBSD's man pages](https://www.freebsd.org/cgi/man.cgi?query=cpio&sektion=5&manpath=FreeBSD+13.0-current).
10-
public enum FileType: UInt32 {
10+
public enum FileType: UInt32, Codable, Equatable {
1111
/// SUID bit.
1212
case setUID = 0o4000
1313

Sources/CPIOArchiveKit/Header.swift

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
///
99
/// This header is placed directly before the contents of a file in the archive to
1010
/// provide information such as the size of the file, the file's name, it's permissions, etc.
11-
public struct Header {
11+
public struct Header: Codable, Equatable {
1212
/// The file's name.
1313
public internal(set) var name: String
1414

@@ -94,4 +94,103 @@ public struct Header {
9494
self.rDev = rDev
9595
self.checksum = checksum
9696
}
97+
98+
public init(from decoder: Decoder) throws {
99+
let container = try decoder.container(keyedBy: CodingKeys.self)
100+
self.name = try container.decode(String.self, forKey: .name)
101+
self.userID = try container.decode(Int.self, forKey: .userID)
102+
self.groupID = try container.decode(Int.self, forKey: .groupID)
103+
self.mode = FileMode(rawValue: try container.decode(UInt32.self, forKey: .mode))
104+
self.modificationTime = try container.decode(Int.self, forKey: .modificationTime)
105+
self.inode = try container.decodeIfPresent(Int.self, forKey: .inode)
106+
self.links = try container.decode(Int.self, forKey: .links)
107+
108+
let devContainer = try container.nestedContainer(keyedBy: DevCodingKeys.self, forKey: .dev)
109+
self.dev.major = try devContainer.decodeIfPresent(Int.self, forKey: .major)
110+
self.dev.minor = try devContainer.decodeIfPresent(Int.self, forKey: .minor)
111+
112+
let rDevContainer = try container.nestedContainer(keyedBy: DevCodingKeys.self, forKey: .rDev)
113+
self.rDev.major = try rDevContainer.decode(Int.self, forKey: .major)
114+
self.rDev.minor = try rDevContainer.decode(Int.self, forKey: .minor)
115+
116+
if let sum = try container.decodeIfPresent(Int.self, forKey: .checksum) {
117+
self.checksum = Checksum(sum: sum)
118+
}
119+
}
120+
121+
public func encode(to encoder: Encoder) throws {
122+
var container = encoder.container(keyedBy: Self.CodingKeys.self)
123+
124+
if let major = self.dev.major, let minor = self.dev.minor {
125+
var devContainer = container.nestedContainer(keyedBy: DevCodingKeys.self, forKey: .dev)
126+
127+
try devContainer.encode(major, forKey: .major)
128+
try devContainer.encode(minor, forKey: .minor)
129+
} else {
130+
var devContainer = container.nestedContainer(keyedBy: DevCodingKeys.self, forKey: .dev)
131+
132+
try devContainer.encodeNil(forKey: .major)
133+
try devContainer.encodeNil(forKey: .minor)
134+
}
135+
136+
var rDevContainer = container.nestedContainer(keyedBy: DevCodingKeys.self, forKey: .rDev)
137+
138+
try rDevContainer.encode(self.rDev.major, forKey: .major)
139+
try rDevContainer.encode(self.rDev.minor, forKey: .minor)
140+
141+
try container.encode(self.name, forKey: .name)
142+
try container.encode(self.userID, forKey: .userID)
143+
try container.encode(self.groupID, forKey: .groupID)
144+
try container.encode(self.mode.rawValue, forKey: .mode)
145+
try container.encode(self.modificationTime, forKey: .modificationTime)
146+
if let inode = inode {
147+
try container.encode(inode, forKey: .inode)
148+
} else {
149+
try container.encodeNil(forKey: .inode)
150+
}
151+
152+
try container.encode(self.links, forKey: .links)
153+
if let c = self.checksum {
154+
try container.encode(c.sum, forKey: .checksum)
155+
} else {
156+
try container.encodeNil(forKey: .checksum)
157+
}
158+
}
159+
160+
public static func == (lhs: Header, rhs: Header) -> Bool {
161+
lhs.name == rhs.name &&
162+
lhs.userID == rhs.userID &&
163+
lhs.groupID == rhs.groupID &&
164+
lhs.mode == rhs.mode &&
165+
lhs.modificationTime == rhs.modificationTime &&
166+
lhs.inode == rhs.inode &&
167+
lhs.links == rhs.links &&
168+
lhs.linkName == rhs.linkName &&
169+
lhs.dev == rhs.dev &&
170+
lhs.rDev == rhs.rDev &&
171+
lhs.checksum == rhs.checksum &&
172+
lhs.size == rhs.size &&
173+
lhs.contentLocation == rhs.contentLocation &&
174+
lhs.nameSize == rhs.nameSize &&
175+
lhs.startingLocation == rhs.startingLocation &&
176+
lhs.endingLocation == rhs.endingLocation
177+
}
178+
179+
enum CodingKeys: String, CodingKey {
180+
case name,
181+
userID,
182+
groupID,
183+
mode,
184+
modificationTime,
185+
inode,
186+
links,
187+
checksum,
188+
dev,
189+
rDev
190+
}
191+
192+
enum DevCodingKeys: CodingKey {
193+
case major
194+
case minor
195+
}
97196
}

0 commit comments

Comments
 (0)