Skip to content

Commit

Permalink
Improve Foundationless (#4)
Browse files Browse the repository at this point in the history
- Added three new options to Foundationless.
- Added support for changing the amount of characters/bytes printed, whether to print in binary of hexadecimal, and changing the line width in Foundationless.

* Use Swift 5.4 on Windows CI
  • Loading branch information
LebJe authored May 2, 2021
1 parent 9305112 commit 13b5d94
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 30 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/buildAndTest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: seanmiddleditch/gha-setup-vsdevenv@master
- name: Install swift-DEVELOPMENT-SNAPSHOT-2021-01-27-a
run: Install-Binary -Url "https://swift.org/builds/development/windows10/swift-DEVELOPMENT-SNAPSHOT-2021-01-27-a/swift-DEVELOPMENT-SNAPSHOT-2021-01-27-a-windows10.exe" -Name "installer.exe" -ArgumentList ("-q")
- name: Install swift-5.4-RELEASE
run: Install-Binary -Url "https://swift.org/builds/swift-5.4-release/windows10/swift-5.4-RELEASE/swift-5.4-RELEASE-windows10.exe" -Name "installer.exe" -ArgumentList ("-q")
- name: Set Environment Variables
run: |
echo "SDKROOT=C:\Library\Developer\Platforms\Windows.platform\Developer\SDKs\Windows.sdk" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]()

### Added

- Added three new options to Foundationless.
- Added support for changing the amount of characters/bytes printed, whether to print in binary of hexadecimal, and changing the line width in Foundationless.

### Fixed

- Fixed a bug that occurred when parsing a file in an archive that contained a `\n` after it's content.
Expand Down
163 changes: 136 additions & 27 deletions Examples/Foundationless/Sources/Foundationless/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,43 @@

import ArArchiveKit

// MARK: - Extensions

// From: https://www.hackingwithswift.com/example-code/language/how-to-split-an-array-into-chunks
extension Array {
func chunked(into size: Int) -> [[Element]] {
stride(from: 0, to: self.count, by: size).map {
Array(self[$0..<Swift.min($0 + size, self.count)])
}
}
}

// MARK: - Exit Codes and Errors

enum ExitCode: Int32 {
case invalidArgument = 1
case arParserError = 2
case otherError = 3
}

enum FoundationlessEror: Error {
case indexOutOfRange
}

// MARK: - Arguments

enum Format: String {
case binary, hexadecimal = "hex"
}

var shouldPrintFile = false
var printInBinary = false
var width: Int = 30
var amountOfBytes = -1
var format: Format = .hexadecimal

// MARK: - Argument Parsing

func parseHelpFlag(_ s: String) -> Bool {
switch s {
case "-h": return true
Expand All @@ -33,15 +70,22 @@ Reads the archive at `file` prints information about each file in the archive.
-h, --help, -? Prints this message.
-p Print the contents of the files in the archive.
-b Print the binary representation of the files in the archive.
"""
USAGE: \(CommandLine.arguments[0]) [--help, -h, -?] [-p] [-b] [-w <value>] [-a <value>] <file>
var shouldPrintFile = false
var printInBinary = false
Reads the archive at `file` and prints information about each file in the archive.
-h, --help, -? Prints this message.
-p Print the contents of the files in the archive.
-b Print the binary representation of the files in the archive.
-w <value> (defalut: \(width)) The amount of characters shown horizontally when printing the contents of a file in binary or ASCII/Unicode.
-a <value> (default: \(amountOfBytes)) The amount of characters/bytes you want print from each file in the archive. Use \"-1\" (with the quotes) to print the full file. If the number is greater than the amount of bytes in the file, then it will equal the amount of bytes in the file.
-f <value> (default: \(format.rawValue)) The format you want the file to be printed in. you can choose either \(Format.binary.rawValue) or \(Format.hexadecimal.rawValue).
"""

func parseArgs() {
if CommandLine.arguments.count < 2 || parseHelpFlag(CommandLine.arguments[1]) {
print(usage)
exit(1)
exit(0)
}

if CommandLine.arguments.firstIndex(of: "-p") != nil {
Expand All @@ -51,45 +95,110 @@ func parseArgs() {
if CommandLine.arguments.firstIndex(of: "-b") != nil {
printInBinary = true
}

if let index = CommandLine.arguments.firstIndex(of: "-w") {
if let w = Int(CommandLine.arguments[index + 1]) {
width = w
} else {
print("\"\(CommandLine.arguments[index + 1])\" is not valid value for -w.")
exit(ExitCode.invalidArgument.rawValue)
}
}

if let index = CommandLine.arguments.firstIndex(of: "-a") {
if let a = Int(CommandLine.arguments[index + 1]) {
amountOfBytes = a
} else {
print("\"\(CommandLine.arguments[index + 1])\" is not valid value for -a.")
exit(ExitCode.invalidArgument.rawValue)
}
}

if let index = CommandLine.arguments.firstIndex(of: "-f") {
if let f = Format(rawValue: CommandLine.arguments[index + 1]) {
format = f
} else {
print("\"\(CommandLine.arguments[index + 1])\" is not valid value for -f.")
exit(ExitCode.invalidArgument.rawValue)
}
}
}

parseArgs()

let fd = open(CommandLine.arguments[1], O_RDONLY)
// MARK: - Main Code

func printContents(from bytes: [UInt8]) {
if printInBinary {
bytes
.chunked(into: width)
.forEach({
$0.forEach({ byte in
switch format {
case .binary:
print(String(byte, radix: 2), terminator: " ")
case .hexadecimal:
print("0x\(String(byte, radix: 16))", terminator: " ")
}
})

print()
})
} else {
print(String(bytes))
}
}

let size = Int(lseek(fd, 0, SEEK_END))
func main() throws {
let fd = open(CommandLine.arguments[1], O_RDONLY)

lseek(fd, 0, SEEK_SET)
let size = Int(lseek(fd, 0, SEEK_END))

let buf = UnsafeMutableRawBufferPointer.allocate(byteCount: size, alignment: MemoryLayout<UInt8>.alignment)
lseek(fd, 0, SEEK_SET)

read(fd, buf.baseAddress, buf.count)
let buf = UnsafeMutableRawBufferPointer.allocate(byteCount: size, alignment: MemoryLayout<UInt8>.alignment)

let bufferPointer = buf.bindMemory(to: UInt8.self)
read(fd, buf.baseAddress, buf.count)

let bytes = Array(bufferPointer)
let bufferPointer = buf.bindMemory(to: UInt8.self)

let reader = try ArArchiveReader(archive: bytes)
let bytes = Array(bufferPointer)

for (header, file) in reader {
print("---------------------------")
let reader = try ArArchiveReader(archive: bytes)

print("Name: " + header.name)
print("User ID: " + String(header.userID))
print("Group ID: " + String(header.groupID))
print("Mode (In Octal): " + String(header.mode, radix: 8))
print("File Size: " + String(header.size))
print("File Modification Time: " + String(header.modificationTime))
for (header, file) in reader {
print("---------------------------")

if shouldPrintFile {
print("Contents:\n")
print("Name: " + header.name)
print("User ID: " + String(header.userID))
print("Group ID: " + String(header.groupID))
print("Mode (In Octal): " + String(header.mode, radix: 8))
print("File Size: " + String(header.size))
print("File Modification Time: " + String(header.modificationTime))

if printInBinary {
file.forEach({ print($0) })
} else {
print(String(file))
if shouldPrintFile {
print("Contents:\n")
if amountOfBytes != -1 {
amountOfBytes = amountOfBytes > file.count ? file.count : amountOfBytes
printContents(from: Array(file[0..<amountOfBytes]))
} else {
printContents(from: file)
}
}
}

print("---------------------------")
}

print("---------------------------")
do {
try main()
} catch ArArchiveError.invalidHeader {
fputs("One of the headers in \"\(CommandLine.arguments[1])\" is invalid.", stderr)
exit(ExitCode.arParserError.rawValue)
} catch ArArchiveError.invalidArchive {
fputs("The archive \"\(CommandLine.arguments[1])\" is invalid.", stderr)
exit(ExitCode.arParserError.rawValue)
} catch {
fputs("An error occured: \(error)", stderr)
exit(ExitCode.otherError.rawValue)
}
1 change: 0 additions & 1 deletion Sources/ArArchiveKit/ArArchiveReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public struct ArArchiveReader {
///
/// - Parameters:
/// - archive: The bytes of the archive you want to read.
/// - variant: The format of the archive you want to read.
/// - Throws: `ArArchiveError`.
public init(archive: [UInt8]) throws {
if archive.isEmpty {
Expand Down

0 comments on commit 13b5d94

Please sign in to comment.