Skip to content

Commit

Permalink
Use withContiguousStorageIfAvailable for String encoding in BinaryEnc…
Browse files Browse the repository at this point in the history
…oder

Resolves issue #919
  • Loading branch information
RLovelett authored and thomasvl committed Feb 14, 2020
1 parent ce43667 commit a1e28b9
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions Sources/SwiftProtobuf/BinaryEncoder.swift
Expand Up @@ -39,12 +39,14 @@ internal struct BinaryEncoder {
}
}

private mutating func append(contentsOf bufferPointer: UnsafeRawBufferPointer) {
@discardableResult
private mutating func append(contentsOf bufferPointer: UnsafeRawBufferPointer) -> Int {
let count = bufferPointer.count
if let baseAddress = bufferPointer.baseAddress, count > 0 {
memcpy(pointer, baseAddress, count)
}
pointer = pointer.advanced(by: count)
return count
}

func distance(pointer: UnsafeMutableRawPointer) -> Int {
Expand Down Expand Up @@ -125,11 +127,19 @@ internal struct BinaryEncoder {

// Write a string field, including the leading index/tag value.
mutating func putStringValue(value: String) {
let count = value.utf8.count
putVarInt(value: count)
for b in value.utf8 {
pointer.storeBytes(of: b, as: UInt8.self)
pointer = pointer.advanced(by: 1)
// If the String does not support an internal representation in a form
// of contiguous storage, body is not called and nil is returned.
let isAvailable = value.utf8.withContiguousStorageIfAvailable { (body: UnsafeBufferPointer<UInt8>) -> Int in
putVarInt(value: body.count)
return append(contentsOf: UnsafeRawBufferPointer(body))
}
if isAvailable == nil {
let count = value.utf8.count
putVarInt(value: count)
for b in value.utf8 {
pointer.storeBytes(of: b, as: UInt8.self)
pointer = pointer.advanced(by: 1)
}
}
}

Expand Down

0 comments on commit a1e28b9

Please sign in to comment.