Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 4 split Data by other Data ([Uint8])

Tags:

swift

I'm pretty new to Swift and I'm looking for a method to split a Data datatype into smaller chunks by another Data. I cannot find any suitable method in the Apple documentation. Every method (split, filter, index...) work by passing just a UInt8, but I need to pass a [Uint8].

For example:

var data: Data = Data.init([0x00, 0x00, 0x00, 0x01, 0xAB, 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0xEE, 0xBB, 0x14, 0x24])
var separator: Data = Data.init([0x00, 0x00, 0x00, 0x01])

And I need to to something like data.split(separator: separator).

Is there any suitable method for doing this or should I just iterate over the entire buffer?

like image 426
Jorge Avatar asked Sep 10 '25 07:09

Jorge


1 Answers

I am not aware of a built-in method. A possible solution is to call range(of:) repeatedly to find all occurrences of the separator data, and append the chunks between the separators to an array:

extension Data {
    func split(separator: Data) -> [Data] {
        var chunks: [Data] = []
        var pos = startIndex
        // Find next occurrence of separator after current position:
        while let r = self[pos...].range(of: separator) {
            // Append if non-empty:
            if r.lowerBound > pos {
                chunks.append(self[pos..<r.lowerBound])
            }
            // Update current position:
            pos = r.upperBound
        }
        // Append final chunk, if non-empty:
        if pos < endIndex {
            chunks.append(self[pos..<endIndex])
        }
        return chunks
    }
}

Example:

let data = Data(bytes: [0x00, 0x00, 0x00, 0x01, 0xAB, 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0xEE, 0xBB, 0x14, 0x24])
let separator = Data(bytes: [0x00, 0x00, 0x00, 0x01])

let chunks = data.split(separator: separator)
for chunk in chunks {
    print(chunk as NSData)
}

Output:

<ab0203>
<eebb1424>
like image 93
Martin R Avatar answered Sep 13 '25 03:09

Martin R