2016-08-08 21 views
12

我有一個protobuf v2 in Swift,我試圖將它附加到另一個protobuf。這就是我想:如何在Swift中添加協議緩衝區?

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($0.date.epochMilliseconds) 
     .setValue($0.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,然後將整個數組轉換回字節?

+0

也許我缺少一個分隔符? – TruMan1

回答

5

你的閱讀部分沒問題。鏈接原始對象時缺少分隔符。首先計算並添加分隔符到流然後proto對象。然後爲每個原始對象執行此操作。

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($0.date.epochMilliseconds) 
     .setValue($0.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 
+0

謝謝你的工作!添加字節大小作爲分隔符的前綴是關鍵。 – TruMan1