Seg参数:
liBinID : LongInt;
liAux : LongInt;
classID : TJPIPDatabinClass;
liCodestreamID: LongInt;
iOffset : Integer;
iLength : Integer;
arrData : TBytes;
isFinal : Boolean;
isEOR : Boolean;
isComplete : Boolean;
错误功能:
function TJPIPDataInputStream.readSegment: TJPIPDataSegment;
var
m : Integer;
id : LongInt;
seg : TJPIPDataSegment;
B : Byte;
begin
id:= readVBAS;
if id < 0 then
begin
Result:= nil;
Exit;
end;
seg:= TJPIPDataSegment.Create;
seg.liBinID:= id;
if vbasFstByte = 0 then
begin
seg.isEOR:= true;
seg.liBinID:= formMain.client.IOHandler.ReadByte;
if seg.liBinID < 0 then
ShowMessage('EOF reached before completing EOR message');
seg.iLength:= Integer(readVBAS);
end
else
begin
seg.isEOR:= false;
seg.liBinID:= seg.liBinID and (not LongInt($70 shl ((vbasLength - 1) * 7)));
seg.isFinal:= ((vbasFstByte and $10) <> 0);
m:= (vbasFstByte and $7F) shr 5;
if m = 0 then
ShowMessage('Invalid Bin-ID value format')
else if m >= 2 then
begin
classId:= readVBAS;
if m > 2 then
codestream:= readVBAS;
end;
seg.liCodestreamID:= codestream;
if classId = jpipdatabinclass.FPRECINCT_DATABIN.getStandardClassID then
seg.classID:= jpipdatabinclass.FPRECINCT_DATABIN
else if classId = jpipdatabinclass.FTILE_HEADER_DATABIN.getStandardClassID then
seg.classID:= jpipdatabinclass.FTILE_HEADER_DATABIN
else if classId = jpipdatabinclass.FTILE_DATABIN.getStandardClassID then
seg.classID:= jpipdatabinclass.FTILE_DATABIN
else if classId = jpipdatabinclass.FMAIN_HEADER_DATABIN.getStandardClassID then
seg.classID:= jpipdatabinclass.FMAIN_HEADER_DATABIN
else if classId = jpipdatabinclass.FMETA_DATABIN.getStandardClassID then
seg.classID:= jpipdatabinclass.FMETA_DATABIN;
if seg.classID = nil then
ShowMessage('Invalid databin classID');
seg.iOffset:= Integer(readVBAS);
seg.iLength:= Integer(readVBAS);
if (classId = EXTENDED_PRECINCT_DATA_BIN_CLASS) or (classId = EXTENDED_TILE_DATA_BIN_CLASS) then
seg.liAux:= readVBAS;
end;
if seg.iLength > 0 then
begin
if seg.arrData = nil then
SetLength(seg.arrData, seg.iLength);
if Length(seg.arrData) < seg.iLength then
SetLength(seg.arrData, seg.iLength);
formMain.client.IOHandler.ReadBytes(TIdBytes(seg.arrData), Length(seg.arrData));
// if inStream.read(seg.data, 0, seg.alength) <> seg.alength then
// ShowMessage('EOF reached before read' + IntToStr(seg.alength) + ' bytes');
end;
Result:= seg;
end;
arrData是TBytes;
iLength是整数;
iLength = 12;
arrData长度也是12。
我调试了它,输出长度为24.前12个元素为0,其他12个元素为真值。但是我无法理解,我将arrData的长度设置为12但是在读取之后,它返回arrData的长度为24。
编辑它总是给出我给出的x2长度。
答案 0 :(得分:2)
TIdIOHandler.ReadBytes()
默认包含AAppend
个可选参数{/ 1}}:
True
这意味着任何读取的字节都将附加到现有数组的末尾。由于您正在预先分配数组,因此它最终会变成两倍大小。
您需要:
删除预分配,让procedure ReadBytes(var VBuffer: TIdBytes; AByteCount: Integer; AAppend: Boolean = True);
为您分配数组:
ReadBytes()
保留预分配并将seg.arrData := nil;
if seg.iLength > 0 then
begin
formMain.client.IOHandler.ReadBytes(TIdBytes(seg.arrData), seg.iLength);
end;
设置为False,以便AAppend
填充现有内存而不是附加到其中:
ReadBytes()