因此,我正在尝试“模仿”一种可以包含以下数据的文件格式:
0x64-0xFB(100-251):A single byte consisting of a value (byteval-100)
0xFC(252): A 'null' byte, I don't need anything with that
0xFD(253): An indicator that I need to 'read ahead', more information follows
0xFE(254): Another 'null' byte in this case
这些值都分组为 8 个字节的块,直到EOF
发生。
当一个0xFD
值出现时,我需要移动到下一个 8 字节块,并在那里读取一个值。读完这篇文章后,我需要移动到下一个字节(并跳过下一个块,因为我已经读过了)。对于这种情况,这将是一个 64 位浮点数(或双精度,就此而言)。这里有一个例子:
0x71 0x75 0xFD 0x6E 0x78 0x82 0x8C 0x72
0x00 0x00 0x00 0x00 0x00 0xC0 0x82 0x40
将是以下值(按顺序)
13 (0x71 - 100)
17 (0x75 - 100)
600.0 (the value of 0x0000000000C08240 in double, because of the 0xFD)
10 (0x6E - 100)
20 (0x78 - 100)
30 (0x82 - 100)
40 (0x8C - 100)
14 (0x72 - 100)
可能在一个块中0xFD
出现多次,表示后面的块都是double
块(所以,如果0xFD
出现两次,后面的两个块将是双块,需要“预读”)。
我已经尝试过对此进行编程,但我想不出一个可行的解决方案(这也有点效率)。我尝试制作一个“长值块”列表,当我进入一个长数据块时,我会跳过它。读取长数据块后,我还需要返回下一个“正常”数据。但是,这会带来各种技术难题。
我确信有一些简单的解决方案,但我无法理解它。
有人有什么想法吗?随意用伪代码或任何编程语言回答这个问题。我只需要如何处理这个问题的基本原则。
以下代码是我想出的(在 Javascript 中):
readNumber: function() {
opcode = this.getNextOpcode();
switch(opcode) {
case -1:
case 252:
return null;
case 253:
return this.readNextFloat(this.position);
case 255:
return null; //SYSMIS
default:
return opcode - this.header.bias;
}
},
getNextOpcode: function() {
if(_.contains(this.longdatablocks,this.getCurrentBlock())) {
gotoBlock(_.max(this.longdatablocks) + 1);
return this.rU8();
}
return this.rU8();
},
readNextFloat: function(position) {
this.gotoBlock(this.getnextBlock())
console.debug(this.position);
this.longdatablocks.push(this.getCurrentBlock());
retval = this.rF64();
this.position = position;
return retval;
},
但是,这并不能很好地处理它。不幸的是,多个0xFD
's 没有被覆盖。