From f0948814b12d3d0f48e52f89dd30ec6d7160248e Mon Sep 17 00:00:00 2001 From: Oleg Andreev Date: Sat, 1 Apr 2023 21:44:19 +0200 Subject: [PATCH] BitString -> Bitstring --- Source/TonSwift/Address/ExternalAddress.swift | 6 ++-- .../{BitString.swift => Bitstring.swift} | 20 ++++++------- Source/TonSwift/Cells/Boc.swift | 8 ++--- Source/TonSwift/Cells/Builder.swift | 10 +++---- Source/TonSwift/Cells/Cell.swift | 30 +++++++++---------- Source/TonSwift/Cells/Dictionary.swift | 26 ++++++++-------- Source/TonSwift/Cells/Slice.swift | 14 ++++----- Tests/TonSwiftTests/Cells/BitStringTest.swift | 22 +++++++------- Tests/TonSwiftTests/Cells/CellTest.swift | 2 +- .../TonSwiftTests/Cells/DictionaryTest.swift | 6 ++-- 10 files changed, 72 insertions(+), 72 deletions(-) rename Source/TonSwift/Cells/{BitString.swift => Bitstring.swift} (94%) diff --git a/Source/TonSwift/Address/ExternalAddress.swift b/Source/TonSwift/Address/ExternalAddress.swift index cc7c0e4..3b2e68e 100644 --- a/Source/TonSwift/Address/ExternalAddress.swift +++ b/Source/TonSwift/Address/ExternalAddress.swift @@ -5,9 +5,9 @@ import Foundation /// addr_extern$01 len:(## 9) external_address:(bits len) = MsgAddressExt; /// ``` public struct ExternalAddress { - private(set) var value: BitString + private(set) var value: Bitstring - public init(value: BitString) { + public init(value: Bitstring) { self.value = value } @@ -16,7 +16,7 @@ public struct ExternalAddress { } public static func mock(seed: String) throws -> Self { - let value = BitString(data: Data(seed.utf8).sha256()) + let value = Bitstring(data: Data(seed.utf8).sha256()) return ExternalAddress(value: value) } } diff --git a/Source/TonSwift/Cells/BitString.swift b/Source/TonSwift/Cells/Bitstring.swift similarity index 94% rename from Source/TonSwift/Cells/BitString.swift rename to Source/TonSwift/Cells/Bitstring.swift index 36bdde9..2a104b6 100644 --- a/Source/TonSwift/Cells/BitString.swift +++ b/Source/TonSwift/Cells/Bitstring.swift @@ -1,8 +1,8 @@ import Foundation -public struct BitString: Hashable { +public struct Bitstring: Hashable { - public static let empty = BitString(data: .init(), unchecked: (offset: 0, length: 0)) + public static let empty = Bitstring(data: .init(), unchecked: (offset: 0, length: 0)) private let _offset: Int private let _length: Int @@ -111,15 +111,15 @@ public struct BitString: Hashable { - parameter length: length of the bitstring in bits - returns substring of bitstring */ - public func substring(offset: Int, length: Int) throws -> BitString { + public func substring(offset: Int, length: Int) throws -> Bitstring { // Corner case of empty string if length == 0 && offset == _length { - return BitString.empty + return Bitstring.empty } try checkOffset(offset: offset, length: length) - return BitString(data: _data, unchecked:(offset: _offset + offset, length: length)) + return Bitstring(data: _data, unchecked:(offset: _offset + offset, length: length)) } /// Returns a byte-aligned substring given the `offset` and `length` in bits (same as in `substring` method). @@ -148,7 +148,7 @@ public struct BitString: Hashable { } /// Drops first `n` bits from the bitstring. - public func dropFirst(_ n: Int) throws -> BitString { + public func dropFirst(_ n: Int) throws -> Bitstring { return try substring(offset: n, length: self.length - n) } @@ -193,7 +193,7 @@ public struct BitString: Hashable { } } - public func padLeft(_ n: Int = 0) -> BitString { + public func padLeft(_ n: Int = 0) -> Bitstring { let b = Builder(capacity: max(n, self.length)) for _ in self.length.. Bool { for i in 0.. Bool { + public static func == (lhs: Bitstring, rhs: Bitstring) -> Bool { if lhs._length != rhs._length { return false } diff --git a/Source/TonSwift/Cells/Boc.swift b/Source/TonSwift/Cells/Boc.swift index 6cd6953..3c933d1 100644 --- a/Source/TonSwift/Cells/Boc.swift +++ b/Source/TonSwift/Cells/Boc.swift @@ -83,12 +83,12 @@ func getRefsDescriptor(refs: [Cell], level: UInt32, type: CellType) -> UInt8 { return UInt8(refs.count) + typeFactor * 8 + UInt8(level) * 32 } -func getBitsDescriptor(bits: BitString) -> UInt8 { +func getBitsDescriptor(bits: Bitstring) -> UInt8 { let len = bits.length return UInt8(ceil(Double(len) / 8) + floor(Double(len) / 8)) } -func readCell(reader: Slice, sizeBytes: Int) throws -> (exotic: Bool, bits: BitString, refs: [UInt64]) { +func readCell(reader: Slice, sizeBytes: Int) throws -> (exotic: Bool, bits: Bitstring, refs: [UInt64]) { let d1 = try reader.loadUint(bits: 8) let refsCount = d1 % 8 let exotic = d1 & 8 != 0 @@ -97,7 +97,7 @@ func readCell(reader: Slice, sizeBytes: Int) throws -> (exotic: Bool, bits: BitS let dataBytesize = Int(ceil(Double(d2) / 2.0)) let paddingAdded = d2 % 2 != 0 - var bits = BitString.empty + var bits = Bitstring.empty if dataBytesize > 0 { if paddingAdded { bits = try reader.loadPaddedBits(bits: dataBytesize * 8) @@ -122,7 +122,7 @@ func deserializeBoc(src: Data) throws -> [Cell] { let boc = try Boc(data: src) let reader = Slice(data: boc.cellData) - var cells: [(bits: BitString, refs: [UInt64], exotic: Bool, result: Cell?)] = [] + var cells: [(bits: Bitstring, refs: [UInt64], exotic: Bool, result: Cell?)] = [] for _ in 0.. Cell { - let bits = BitString(data: _buffer, unchecked:(offset: 0, length: _length)) + let bits = Bitstring(data: _buffer, unchecked:(offset: 0, length: _length)) return try Cell(bits: bits, refs: refs) } @@ -55,8 +55,8 @@ public class Builder { } /// Converts builder into BitString - public func bitstring() -> BitString { - return BitString(data: _buffer, unchecked:(offset: 0, length: _length)) + public func bitstring() -> Bitstring { + return Bitstring(data: _buffer, unchecked:(offset: 0, length: _length)) } /// Converts to data if the bitstring contains a whole number of bytes. @@ -270,7 +270,7 @@ public class Builder { /// Writes bits from a bitstring @discardableResult - public func store(bits: BitString) throws -> Self { + public func store(bits: Bitstring) throws -> Self { for i in 0.. Self { + static func exotic(bits: Bitstring, refs: [Cell]) throws -> Self { let reader = Slice(bits: bits) let typeInt = try reader.preloadUint(bits: 8) @@ -290,7 +290,7 @@ fileprivate struct BasicCell: Hashable { } // Bits - var currentBits: BitString + var currentBits: Bitstring if hashI == hashIOffset { if !(levelI == 0 || type == .prunedBranch) { throw TonError.custom("Invalid") @@ -300,7 +300,7 @@ fileprivate struct BasicCell: Hashable { if !(levelI != 0 && type != .prunedBranch) { throw TonError.custom("Invalid: \(levelI), \(type)") } - currentBits = BitString(data: hashes[Int(hashI - hashIOffset) - 1], unchecked: (offset: 0, length: 256)) + currentBits = Bitstring(data: hashes[Int(hashI - hashIOffset) - 1], unchecked: (offset: 0, length: 256)) } // Depth @@ -355,7 +355,7 @@ fileprivate struct BasicCell: Hashable { } } -func getRepr(bits: BitString, refs: [Cell], level: UInt32, type: CellType) throws -> Data { +func getRepr(bits: Bitstring, refs: [Cell], level: UInt32, type: CellType) throws -> Data { // Allocate let bitsLen = (bits.length + 7) / 8 var repr = Data(count: 2 + bitsLen + (2 + 32) * refs.count) @@ -408,7 +408,7 @@ public struct ExoticPruned { public var pruned: [(depth: UInt32, hash: Data)] } -func exoticPruned(bits: BitString, refs: [Cell]) throws -> ExoticPruned { +func exoticPruned(bits: Bitstring, refs: [Cell]) throws -> ExoticPruned { let reader = Slice(bits: bits) let type = try reader.loadUint(bits: 8) @@ -458,7 +458,7 @@ func exoticPruned(bits: BitString, refs: [Cell]) throws -> ExoticPruned { return ExoticPruned(mask: mask.value, pruned: pruned) } -func resolvePruned(bits: BitString, refs: [Cell]) throws -> (type: CellType, depths: [UInt32], hashes: [Data], mask: LevelMask) { +func resolvePruned(bits: Bitstring, refs: [Cell]) throws -> (type: CellType, depths: [UInt32], hashes: [Data], mask: LevelMask) { let pruned = try exoticPruned(bits: bits, refs: refs) var depths = [UInt32]() var hashes = [Data]() @@ -471,7 +471,7 @@ func resolvePruned(bits: BitString, refs: [Cell]) throws -> (type: CellType, dep return (CellType.prunedBranch, depths, hashes, mask) } -func resolveMerkleProof(bits: BitString, refs: [Cell]) throws -> (type: CellType, depths: [UInt32], hashes: [Data], mask: LevelMask) { +func resolveMerkleProof(bits: Bitstring, refs: [Cell]) throws -> (type: CellType, depths: [UInt32], hashes: [Data], mask: LevelMask) { let _/*merkleProof*/ = try exoticMerkleProof(bits: bits, refs: refs) let depths = [UInt32]() let hashes = [Data]() @@ -480,7 +480,7 @@ func resolveMerkleProof(bits: BitString, refs: [Cell]) throws -> (type: CellType return (CellType.merkleProof, depths, hashes, mask) } -func resolveMerkleUpdate(bits: BitString, refs: [Cell]) throws -> (type: CellType, depths: [UInt32], hashes: [Data], mask: LevelMask) { +func resolveMerkleUpdate(bits: Bitstring, refs: [Cell]) throws -> (type: CellType, depths: [UInt32], hashes: [Data], mask: LevelMask) { let _/*merkleUpdate*/ = try exoticMerkleUpdate(bits: bits, refs: refs) let depths = [UInt32]() let hashes = [Data]() @@ -490,7 +490,7 @@ func resolveMerkleUpdate(bits: BitString, refs: [Cell]) throws -> (type: CellTyp } @discardableResult -func exoticMerkleUpdate(bits: BitString, refs: [Cell]) throws -> (proofDepth1: UInt32, proofDepth2: UInt32, proofHash1: Data, proofHash2: Data) { +func exoticMerkleUpdate(bits: Bitstring, refs: [Cell]) throws -> (proofDepth1: UInt32, proofDepth2: UInt32, proofHash1: Data, proofHash2: Data) { let reader = Slice(bits: bits) // type + hash + hash + depth + depth @@ -534,7 +534,7 @@ func exoticMerkleUpdate(bits: BitString, refs: [Cell]) throws -> (proofDepth1: U } @discardableResult -func exoticMerkleProof(bits: BitString, refs: [Cell]) throws -> (proofDepth: UInt32, proofHash: Data) { +func exoticMerkleProof(bits: Bitstring, refs: [Cell]) throws -> (proofDepth: UInt32, proofHash: Data) { let reader = Slice(bits: bits) // type + hash + depth diff --git a/Source/TonSwift/Cells/Dictionary.swift b/Source/TonSwift/Cells/Dictionary.swift index 944976f..ef2ba8b 100644 --- a/Source/TonSwift/Cells/Dictionary.swift +++ b/Source/TonSwift/Cells/Dictionary.swift @@ -114,7 +114,7 @@ public class DictionaryCoder where K.T: Hashable { } // Serialize keys - var paddedMap: [BitString: V.T] = [:] + var paddedMap: [Bitstring: V.T] = [:] for (k, v) in map { let b = Builder() try keyCoder.storeValue(k, to: b) @@ -187,21 +187,21 @@ enum Node { } class Edge { - let label: BitString + let label: Bitstring let node: Node - init(label: BitString, node: Node) { + init(label: Bitstring, node: Node) { self.label = label self.node = node } } /// Removes `n` bits from all the keys in a map -func removePrefixMap(_ src: [BitString: T], _ length: Int) -> [BitString: T] { +func removePrefixMap(_ src: [Bitstring: T], _ length: Int) -> [Bitstring: T] { if length == 0 { return src } - var res: [BitString: T] = [:] + var res: [Bitstring: T] = [:] for (k, d) in src { res[try! k.dropFirst(length)] = d } @@ -210,11 +210,11 @@ func removePrefixMap(_ src: [BitString: T], _ length: Int) -> [BitString: T] /// Splits the dictionary by the value of the first bit of the keys. 0-prefixed keys go into left map, 1-prefixed keys go into the right one. /// First bit is removed from the keys. -func forkMap(_ src: [BitString: T]) throws -> (left: [BitString: T], right: [BitString: T]) { +func forkMap(_ src: [Bitstring: T]) throws -> (left: [Bitstring: T], right: [Bitstring: T]) { try invariant(!src.isEmpty) - var left: [BitString: T] = [:] - var right: [BitString: T] = [:] + var left: [Bitstring: T] = [:] + var right: [Bitstring: T] = [:] for (k, d) in src { if k.at(unchecked: 0) == false { left[try! k.dropFirst(1)] = d @@ -228,7 +228,7 @@ func forkMap(_ src: [BitString: T]) throws -> (left: [BitString: T], right: [ return (left, right) } -func buildNode(_ src: [BitString: T]) throws -> Node { +func buildNode(_ src: [Bitstring: T]) throws -> Node { try invariant(!src.isEmpty) if src.count == 1 { return .leaf(value: src.values.first!) @@ -238,7 +238,7 @@ func buildNode(_ src: [BitString: T]) throws -> Node { } } -func buildEdge(_ src: [BitString: T]) throws -> Edge { +func buildEdge(_ src: [Bitstring: T]) throws -> Edge { try invariant(!src.isEmpty) let label = findCommonPrefix(src: Array(src.keys)) return Edge(label: label, node: try buildNode(removePrefixMap(src, label.length))) @@ -287,7 +287,7 @@ func buildEdge(_ src: [BitString: T]) throws -> Edge { /// cb.store_bits(label, len); /// } /// ``` -func writeLabel(src: BitString, keyLength: Int, to: Builder) throws { +func writeLabel(src: Bitstring, keyLength: Int, to: Builder) throws { let k = bitsForInt(keyLength) let n = src.length @@ -335,10 +335,10 @@ func writeEdge(src: Edge, keyLength: Int, valueCoder: V, to: Builder) t try writeNode(src: src.node, keyLength: keyLength - src.label.length, valueCoder: valueCoder, to: to) } -func findCommonPrefix(src: some Collection) -> BitString { +func findCommonPrefix(src: some Collection) -> Bitstring { // Corner cases if src.isEmpty { - return BitString() + return Bitstring() } if src.count == 1 { return src.first! diff --git a/Source/TonSwift/Cells/Slice.swift b/Source/TonSwift/Cells/Slice.swift index 8bc84c9..4ad6e73 100644 --- a/Source/TonSwift/Cells/Slice.swift +++ b/Source/TonSwift/Cells/Slice.swift @@ -5,7 +5,7 @@ import BigInt /// Once you have done reading and want to make sure all the data is consumed, call `endParse()`. public class Slice { - private var bitstring: BitString + private var bitstring: Bitstring private var offset: Int private var refs: [Cell] @@ -20,7 +20,7 @@ public class Slice { } /// Allows initializing with bitstring - public init(bits: BitString) { + public init(bits: Bitstring) { self.bitstring = bits self.offset = 0 self.refs = [] @@ -29,13 +29,13 @@ public class Slice { /// Initializes Slice with a byte buffer to read the bits from. /// This does not parse bag-of-cells. To parse BoC, see `Cell` API instead. public init(data: Data) { - self.bitstring = BitString(data: data) + self.bitstring = Bitstring(data: data) self.offset = 0 self.refs = [] } /// Unchecked initializer for cloning - private init(bitstring: BitString, offset: Int, refs: [Cell]) { + private init(bitstring: Bitstring, offset: Int, refs: [Cell]) { self.bitstring = bitstring self.offset = offset self.refs = refs @@ -229,14 +229,14 @@ public class Slice { } /// Loads the specified number of bits in a `BitString`. - public func loadBits(_ bits: Int) throws -> BitString { + public func loadBits(_ bits: Int) throws -> Bitstring { let r = try bitstring.substring(offset: offset, length: bits) offset += bits return r } /// Preloads the specified number of bits in a `BitString` without advancing the cursor. - public func preloadBits(_ bits: Int) throws -> BitString { + public func preloadBits(_ bits: Int) throws -> Bitstring { return try bitstring.substring(offset: offset, length: bits) } @@ -259,7 +259,7 @@ public class Slice { Load bit string that was padded to make it byte alligned. Used in BOC serialization - parameter bytes: number of bytes to read */ - func loadPaddedBits(bits: Int) throws -> BitString { + func loadPaddedBits(bits: Int) throws -> Bitstring { // Check that number of bits is byte alligned guard bits % 8 == 0 else { throw TonError.custom("Invalid number of bits") diff --git a/Tests/TonSwiftTests/Cells/BitStringTest.swift b/Tests/TonSwiftTests/Cells/BitStringTest.swift index a0960b0..0298bbf 100644 --- a/Tests/TonSwiftTests/Cells/BitStringTest.swift +++ b/Tests/TonSwiftTests/Cells/BitStringTest.swift @@ -5,7 +5,7 @@ final class BitStringTest: XCTestCase { func testBitString() throws { // should read bits - let bs = BitString(data: Data([0b10101010]), unchecked:(offset: 0, length: 8)) + let bs = Bitstring(data: Data([0b10101010]), unchecked:(offset: 0, length: 8)) XCTAssertTrue(try bs.at(0)) XCTAssertFalse(try bs.at(1)) XCTAssertTrue(try bs.at(2)) @@ -17,9 +17,9 @@ final class BitStringTest: XCTestCase { XCTAssertEqual(bs.toString(), "AA") // should equals - let a = BitString(data: Data([0b10101010]), unchecked:(offset: 0, length: 8)) - let b = BitString(data: Data([0b10101010]), unchecked:(offset: 0, length: 8)) - let c = BitString(data: Data([0, 0b10101010]), unchecked:(offset: 8, length: 8)) + let a = Bitstring(data: Data([0b10101010]), unchecked:(offset: 0, length: 8)) + let b = Bitstring(data: Data([0b10101010]), unchecked:(offset: 0, length: 8)) + let c = Bitstring(data: Data([0, 0b10101010]), unchecked:(offset: 8, length: 8)) XCTAssertEqual(a, b) XCTAssertEqual(b, a) XCTAssertEqual(a, c) @@ -29,15 +29,15 @@ final class BitStringTest: XCTestCase { XCTAssertEqual(c.toString(), "AA") // should format strings - XCTAssertEqual(try BitString(data: Data([0b00000000]), offset: 0, length: 1).toString(), "4_") - XCTAssertEqual(try BitString(data: Data([0b10000000]), offset: 0, length: 1).toString(), "C_") - XCTAssertEqual(try BitString(data: Data([0b11000000]), offset: 0, length: 2).toString(), "E_") - XCTAssertEqual(try BitString(data: Data([0b11100000]), offset: 0, length: 3).toString(), "F_") - XCTAssertEqual(try BitString(data: Data([0b11100000]), offset: 0, length: 4).toString(), "E") - XCTAssertEqual(try BitString(data: Data([0b11101000]), offset: 0, length: 5).toString(), "EC_") + XCTAssertEqual(try Bitstring(data: Data([0b00000000]), offset: 0, length: 1).toString(), "4_") + XCTAssertEqual(try Bitstring(data: Data([0b10000000]), offset: 0, length: 1).toString(), "C_") + XCTAssertEqual(try Bitstring(data: Data([0b11000000]), offset: 0, length: 2).toString(), "E_") + XCTAssertEqual(try Bitstring(data: Data([0b11100000]), offset: 0, length: 3).toString(), "F_") + XCTAssertEqual(try Bitstring(data: Data([0b11100000]), offset: 0, length: 4).toString(), "E") + XCTAssertEqual(try Bitstring(data: Data([0b11101000]), offset: 0, length: 5).toString(), "EC_") // should do subbuffers - let bs1 = BitString(data: Data([1, 2, 3, 4, 5, 6, 7, 8]), unchecked:(offset: 0, length: 64)) + let bs1 = Bitstring(data: Data([1, 2, 3, 4, 5, 6, 7, 8]), unchecked:(offset: 0, length: 64)) let bs2 = try bs1.subbuffer(offset: 0, length: 16) XCTAssertEqual(bs2!.count, 2) diff --git a/Tests/TonSwiftTests/Cells/CellTest.swift b/Tests/TonSwiftTests/Cells/CellTest.swift index bbb0205..9246cf7 100644 --- a/Tests/TonSwiftTests/Cells/CellTest.swift +++ b/Tests/TonSwiftTests/Cells/CellTest.swift @@ -7,7 +7,7 @@ final class CellTest: XCTestCase { // should construct let cell = Cell() XCTAssertEqual(cell.type, CellType.ordinary) - XCTAssertEqual(cell.bits, BitString(data: .init(), unchecked:(offset: 0, length: 0))) + XCTAssertEqual(cell.bits, Bitstring(data: .init(), unchecked:(offset: 0, length: 0))) XCTAssertEqual(cell.refs, []) } diff --git a/Tests/TonSwiftTests/Cells/DictionaryTest.swift b/Tests/TonSwiftTests/Cells/DictionaryTest.swift index 6af54bb..01c1a75 100644 --- a/Tests/TonSwiftTests/Cells/DictionaryTest.swift +++ b/Tests/TonSwiftTests/Cells/DictionaryTest.swift @@ -118,12 +118,12 @@ final class DictionaryTest: XCTestCase { return builder } - func int2bits(_ i: Int, bits: Int = 16) -> BitString { + func int2bits(_ i: Int, bits: Int = 16) -> Bitstring { return try! Builder().store(int: i, bits: bits).bitstring() } - func b(_ s: String) -> BitString { - return try! BitString(binaryString: s) + func b(_ s: String) -> Bitstring { + return try! Bitstring(binaryString: s) } private func builderFrom(_ src: String) throws -> Builder {