如何在 Swift 中附加协议缓冲区?
How to append Protocol Buffers in Swift?
我有一个 protobuf v2 in Swift,我正在尝试将它附加到另一个 protobuf。这就是我正在尝试的:
let attachment = getAttachment(id: 987) //From cloud database
var protosData = NSMutableData(data: attachment)
items.forEach { //Some struct array of values
guard let proto = try? MyProtoBuf.Builder()
.setEpochMillis([=11=].date.epochMilliseconds)
.setValue([=11=].value)
.build() else { return }
protosData.appendData(proto.data())
}
saveAttachment(protosData) //Store to cloud
我好像在破坏数据,因为我在回读时遇到了这个错误:
malloc: *** mach_vm_map(size=2749415424) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
也许是我读回的值不正确,这是我从存储中读取附加数据的操作:
extension GeneratedMessageProtocol {
static func getStreamData(data: NSData) -> [Self] {
var messages = [Self]()
do {
let inStream = NSInputStream(data:data)
inStream.open()
defer { inStream.close() }
while inStream.hasBytesAvailable {
var sizeBuffer: [UInt8] = [0,0,0,0]
inStream.read(&sizeBuffer, maxLength: sizeBuffer.count)
let data = NSData(bytes: sizeBuffer, length: sizeBuffer.count)
let messageSize = data.uint32.littleEndian
var buffer = Array<UInt8>(count: Int(messageSize), repeatedValue: 0)
inStream.read(&buffer, maxLength: Int(messageSize))
let messageData = NSData(bytes: buffer, length:Int(messageSize))
messages.append(try self.parseFromData(messageData))
}
}
catch {
}
return messages
}
}
extension NSData {
var uint32: UInt32 {
get {
var number: UInt32 = 0
self.getBytes(&number, length: sizeof(UInt32))
return number
}
}
}
这是我的 protobuf 消息:
syntax = "proto2";
message MyProtoBuf {
optional uint64 epochMillis = 1;
optional uint32 value = 2;
}
将数据附加到现有 protobuf 而不是逐一解析数组项、附加 protobuf,然后将整个数组转换回字节的正确方法是什么?
你的阅读部分还可以。链接原型对象时缺少分隔符。首先计算并向流添加分隔符,然后向原型对象添加分隔符。然后为每个原型对象执行此操作。
let attachment = getAttachment(id: 987) //From cloud database
var arr: [UInt32] = [UInt32(attachment.length)] //Assuming attachment is NSData type
let delimiter = NSData(bytes: arr, length: arr.count * sizeof(UInt32))
let protosData = NSMutableData(data: delimiter)
protosData.appendData(attachment)
items.forEach { //Some struct array of values
guard let proto = try? MyProtoBuf.Builder()
.setEpochMillis([=10=].date.epochMilliseconds)
.setValue([=10=].value)
.build() else { return }
var array: [UInt32] = [UInt32(proto.data().length)]
let delimit = NSData(bytes: array, length: arr.count * sizeof(UInt32))
protosData.appendData(delimit)
protosData.appendData(proto.data())
}
saveAttachment(protosData) //Store to cloud
我有一个 protobuf v2 in Swift,我正在尝试将它附加到另一个 protobuf。这就是我正在尝试的:
let attachment = getAttachment(id: 987) //From cloud database
var protosData = NSMutableData(data: attachment)
items.forEach { //Some struct array of values
guard let proto = try? MyProtoBuf.Builder()
.setEpochMillis([=11=].date.epochMilliseconds)
.setValue([=11=].value)
.build() else { return }
protosData.appendData(proto.data())
}
saveAttachment(protosData) //Store to cloud
我好像在破坏数据,因为我在回读时遇到了这个错误:
malloc: *** mach_vm_map(size=2749415424) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
也许是我读回的值不正确,这是我从存储中读取附加数据的操作:
extension GeneratedMessageProtocol {
static func getStreamData(data: NSData) -> [Self] {
var messages = [Self]()
do {
let inStream = NSInputStream(data:data)
inStream.open()
defer { inStream.close() }
while inStream.hasBytesAvailable {
var sizeBuffer: [UInt8] = [0,0,0,0]
inStream.read(&sizeBuffer, maxLength: sizeBuffer.count)
let data = NSData(bytes: sizeBuffer, length: sizeBuffer.count)
let messageSize = data.uint32.littleEndian
var buffer = Array<UInt8>(count: Int(messageSize), repeatedValue: 0)
inStream.read(&buffer, maxLength: Int(messageSize))
let messageData = NSData(bytes: buffer, length:Int(messageSize))
messages.append(try self.parseFromData(messageData))
}
}
catch {
}
return messages
}
}
extension NSData {
var uint32: UInt32 {
get {
var number: UInt32 = 0
self.getBytes(&number, length: sizeof(UInt32))
return number
}
}
}
这是我的 protobuf 消息:
syntax = "proto2";
message MyProtoBuf {
optional uint64 epochMillis = 1;
optional uint32 value = 2;
}
将数据附加到现有 protobuf 而不是逐一解析数组项、附加 protobuf,然后将整个数组转换回字节的正确方法是什么?
你的阅读部分还可以。链接原型对象时缺少分隔符。首先计算并向流添加分隔符,然后向原型对象添加分隔符。然后为每个原型对象执行此操作。
let attachment = getAttachment(id: 987) //From cloud database
var arr: [UInt32] = [UInt32(attachment.length)] //Assuming attachment is NSData type
let delimiter = NSData(bytes: arr, length: arr.count * sizeof(UInt32))
let protosData = NSMutableData(data: delimiter)
protosData.appendData(attachment)
items.forEach { //Some struct array of values
guard let proto = try? MyProtoBuf.Builder()
.setEpochMillis([=10=].date.epochMilliseconds)
.setValue([=10=].value)
.build() else { return }
var array: [UInt32] = [UInt32(proto.data().length)]
let delimit = NSData(bytes: array, length: arr.count * sizeof(UInt32))
protosData.appendData(delimit)
protosData.appendData(proto.data())
}
saveAttachment(protosData) //Store to cloud