2016-08-08 35 views
12

Mam protobuf v2 in Swift i próbuję dołączyć do innego protobuf. To jest to, co usiłuję:Jak dołączyć bufory protokołów w 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 

Wydaje mi się jakbym uszkodzenie danych, bo ten błąd podczas czytania go z powrotem:

malloc: *** mach_vm_map(size=2749415424) failed (error code=3) 
*** error: can't allocate region 
*** set a breakpoint in malloc_error_break to debug 

Być może to moje czytanie powrotem wartości jest nieprawidłowa, tutaj jest to, co robię, aby przeczytać dołączone dane z pamięci:

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 
    } 
    } 
} 

I tu jest moje przesłanie protobuf:

syntax = "proto2"; 

message MyProtoBuf { 
    optional uint64 epochMillis = 1; 
    optional uint32 value = 2; 
} 

Jaki jest poprawny sposób dołączania danych do istniejącego protobuf zamiast konieczności analizowania elementów tablicy jeden po drugim, dołączanie protobuf, a następnie przekształcanie całej tablicy z powrotem na bajty?

+0

Może brakuje mi ogranicznika? – TruMan1

Odpowiedz

5

Twoja część do czytania jest w porządku. brakuje ograniczników podczas łączenia obiektów proto. najpierw obliczyć i dodać ogranicznik do strumienia, a następnie do obiektu proto. następnie zrób to dla każdego obiektu 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

Dziękuję, że zadziałało !! Dodanie rozmiaru bajtów jako przedrostka ogranicznika było kluczowe. – TruMan1