Reputation: 711
Seg Parameters:
liBinID : LongInt;
liAux : LongInt;
classID : TJPIPDatabinClass;
liCodestreamID: LongInt;
iOffset : Integer;
iLength : Integer;
arrData : TBytes;
isFinal : Boolean;
isEOR : Boolean;
isComplete : Boolean;
error function:
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 is TBytes;
iLength is Integer;
And iLength = 12;
Also arrData length is 12 too.
I debugged it and output length is 24. First 12 elements are 0 and the other 12 elements are true values. But i couldn' t understand, i set the length of arrData to 12 but after read, it returns length 24 of arrData.
Edit it always give x2 length of what i give.
Upvotes: 0
Views: 2045
Reputation: 596226
TIdIOHandler.ReadBytes()
has an optional AAppend
parameter that is True
by default:
procedure ReadBytes(var VBuffer: TIdBytes; AByteCount: Integer; AAppend: Boolean = True);
That means any bytes read will be appended to the end of the existing array. Since you are pre-allocating the array, that is why it ends up being twice the size.
You need to either:
remove the pre-allocation and let ReadBytes()
allocate the array for you:
seg.arrData := nil;
if seg.iLength > 0 then
begin
formMain.client.IOHandler.ReadBytes(TIdBytes(seg.arrData), seg.iLength);
end;
keep the pre-allocation and set AAppend
to False so ReadBytes()
will fill the existing memory instead of appending to it:
seg.arrData := nil;
if seg.iLength > 0 then
begin
SetLength(seg.arrData, seg.iLength);
formMain.client.IOHandler.ReadBytes(TIdBytes(seg.arrData), seg.iLength, False);
end;
Upvotes: 2