2015-04-30 2 views
0

Seg Параметры:TIdTCPClient Read Bytes

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 Integer;

И iLength = 12;

Также длина arrData тоже 12.

Я отлаживал его, а длина вывода - 24. Первые 12 элементов равны 0, а остальные 12 элементов являются истинными значениями. Но я не мог понять, я задал длину arrData до 12, но после чтения он возвращает длину 24 arrData.

Редактировать всегда дает x2 длину того, что я даю.

+1

Пожалуйста, добавьте детали для объекта seg/Запись – whosrdaddy

+0

Я добавил дополнительную информацию. я отлаживаю и вижу, например, длину 12, но возвращает 24: / –

ответ

2

TIdIOHandler.ReadBytes() имеет дополнительный AAppend параметр, который True по умолчанию:

procedure ReadBytes(var VBuffer: TIdBytes; AByteCount: Integer; AAppend: Boolean = True); 

Это означает, что любые байты чтения будут добавляться в конец существующего массива. Поскольку вы предварительно выделяете массив, поэтому он в два раза превышает размер.

Вам нужно либо:

  1. удалить предварительно выделение и пусть ReadBytes() выделить массив для вас:

    seg.arrData := nil; 
    if seg.iLength > 0 then 
    begin 
        formMain.client.IOHandler.ReadBytes(TIdBytes(seg.arrData), seg.iLength); 
    end; 
    
  2. держать предварительное выделение и установите AAppend Ложь так ReadBytes() заполнит существующую память, а не добавит к ней:

    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; 
    
Смежные вопросы