【发布时间】:2015-07-28 12:20:31
【问题描述】:
你好 javascript 大师,
我正在尝试使用 javascript 生成一个基于 protobuf 的文件,该文件具有以下结构:
消息大小 | probuff字节|消息大小 | protobuff字节..等
我的想法是我在一个文件中附加多个 protobuf 消息,稍后通过读取消息大小(4 字节整数)来处理它,然后通过读取相应的以下字节来重建 pb 消息,然后解码每个带有 protobuf 的消息。
我已经在 Objective-C 中进行了编码/解码,但我正在努力使用 javascript 做同样的事情。由于代码不言自明,因此在每次迭代中使用 Objc(使用 pod 'ProtocolBuffers', '~> 1.9.8')如下所示:
//configure protobuff, then build.
DataOperationPB * dataOp = [dataOperationBuilder build];
//get its NSData representation
NSData * varBlob = [dataOp data]; //byte string
unsigned int size = (unsigned int)[dataOp serializedSize];
[variablesBlobContainer appendData:[NSMutableData dataWithBytes:&size length:sizeof(size)]];
[variablesBlobContainer appendData:varBlob];
//then we can easily write this to a file with:
[variablesBlobContainer writeToFile:fileNameWithPath atomically:YES]
如此简单;如果我打开生成的文件,并说第一个 protobuffer 消息的大小为 250,则可以正确看到文件中的初始数据:
以 HEX 格式查看文件的前 4 个字节(偏移量 0):
FA 00 00 00
作为 INT (LITTLE ENDIAN):
250
按预期工作。如果您对这种语言更熟悉,我也可以使用 python 进行解码(为简洁起见,删除了断言):
file = open(currentPbdFile, 'r')
msgSize = file.read(4)
msg_len = struct.unpack('<L',msgSize)[0]
while msg_len > 0:
bufferVar = file.read(msg_len)
dataOpList.append(DataOperation(bufferVar))
msgSize = file.read(4)
if(msgSize == ''):
break
msg_len = struct.unpack('<L', msgSize)[0]
现在,在尝试使用 javascript 进行相同操作时,我遇到了困难。我的一项尝试是(使用protobuf.js 对消息进行编码):
var ProtoBuf = dcodeIO.ProtoBuf;
var builder = ProtoBuf.loadProtoFile("DataOperationPB.proto");
var ByteBuffer = dcodeIO.ByteBuffer;
var byteBuffer = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
var data = new DataOperationPB({
//(omitted code for setting pb message values)
});
然后在循环中构建消息并附加数据:
byteBuffer.append(new ByteBuffer().writeInt32(data.calculate()));
byteBuffer.append(data.encode()); //the protobuff data itself
稍后我将数据作为 url 下载按钮提供:
var data = new Blob([new DataView(byteBuffer.toArrayBuffer())], {type: 'application/octet-stream'});
从角度:
this.url = ($window.URL || $window.webkitURL).createObjectURL(data);
当我打开下载的 29 长 protobuff 消息的文件时,前四个字节如下所示:
28 01 38 04
这是完全错误的。
进一步挖掘,我注意到protobuf.js 使用他们自己的 ArrayBuffers 实现(称为ByteBuffer.js),当在浏览器中运行 Javascript 时,它又使用普通的 ArrayBuffers。我不是JS的资深人士,有人可以指出完成上述工作的方向吗?提前感谢您的帮助。
【问题讨论】:
标签: javascript angularjs protocol-buffers arraybuffer