Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update bitstring & test #67

Merged
merged 21 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"configurations": [

xlc marked this conversation as resolved.
Show resolved Hide resolved
{
"type": "lldb",
"request": "launch",
Expand Down
89 changes: 89 additions & 0 deletions Utils/Sources/Utils/FixSizeBitstring.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import Foundation
import ScaleCodec

// TODO: add tests
public struct FixSizeBitstring<T: ReadInt>: Hashable, Sendable {
MacOMNI marked this conversation as resolved.
Show resolved Hide resolved
/// Byte storage for bits.
public private(set) var bytes: Data
public private(set) var length: Int
/// Initialize with byte data storage.
/// - Parameter bytes: Byte storage for bits.
public init?(config: T.TConfig, bytes: Data) {
let length = T.read(config: config)
guard length == bytes.count else {
xlc marked this conversation as resolved.
Show resolved Hide resolved
return nil
}
self.bytes = bytes
self.length = length
}

/// Initialize with byte data storage.
/// - Parameter bytes: Byte storage for bits.
public init(bytes: Data, length: Int) {
self.length = length
self.bytes = bytes
}

MacOMNI marked this conversation as resolved.
Show resolved Hide resolved
private func at(unchecked index: Int) -> Bool {
let byteIndex = index >> 3
let bitIndex = 7 - index % 8
return (bytes[byteIndex] & (1 << bitIndex)) != 0
}

/// Formats the bitstring in binary digits.
public var binaryString: String {
var s = ""
let length: Int = bytes.count * 8
MacOMNI marked this conversation as resolved.
Show resolved Hide resolved
for i in 0 ..< length {
s.append(at(unchecked: i) ? "1" : "0")
}
return s
}

public var description: String { binaryString }
}

extension FixSizeBitstring: Comparable {
public static func < (lhs: Self, rhs: Self) -> Bool {
guard lhs.bytes.count == rhs.bytes.count else {
return lhs.bytes.count < rhs.bytes.count
}
for (l, r) in zip(lhs.bytes, rhs.bytes) where l != r {
return l < r
}
return false
}
}

extension FixSizeBitstring: Equatable {
/**
Checks for equality
- parameter lhs: bitstring
- parameter rhs: bitstring
- returns true if the bitstrings are equal, false otherwise
*/
public static func == (lhs: FixSizeBitstring, rhs: FixSizeBitstring) -> Bool {
guard lhs.bytes.count == rhs.bytes.count else {
return false
}
return lhs.bytes == rhs.bytes
MacOMNI marked this conversation as resolved.
Show resolved Hide resolved
}
}

extension FixSizeBitstring {
public init<D: ScaleCodec.Decoder>(
config: T.TConfig,
from decoder: inout D,
decodeItem _: @escaping (inout D) throws -> T
) throws {
let length = T.read(config: config)
try self.init(bytes: decoder.decode(Data.self, .fixed(UInt(length))), length: length)
}
}
MacOMNI marked this conversation as resolved.
Show resolved Hide resolved

extension FixSizeBitstring where T: ScaleCodec.Decodable {
public init(config: T.TConfig, from decoder: inout some ScaleCodec.Decoder) throws {
let length = T.read(config: config)
try self.init(bytes: decoder.decode(Data.self, .fixed(UInt(length))), length: length)
xlc marked this conversation as resolved.
Show resolved Hide resolved
}
}
Loading