ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/branches/udr/client/FBOutputBlock.pas
(Generate patch)

Comparing:
ibx/trunk/fbintf/client/FBOutputBlock.pas (file contents), Revision 56 by tony, Mon Mar 6 10:20:02 2017 UTC vs.
ibx/branches/journaling/fbintf/client/FBOutputBlock.pas (file contents), Revision 362 by tony, Tue Dec 7 13:27:39 2021 UTC

# Line 46 | Line 46 | uses
46  
47   const
48    DefaultBufferSize = 32000;
49 <  DBInfoDefaultBufferSize = 512;
49 >  DBInfoDefaultBufferSize = DefaultBufferSize; {allow for database page}
50  
51   type
52 <  TItemDataType = (dtString, dtString2, dtByte, dtBytes, dtInteger, dtIntegerFixed, dtnone,
53 <    dtList,dtSpecial);
52 >  TItemDataType = (dtString, dtString2, dtByte, dtBytes, dtInteger, dtIntegerFixed,
53 >    dtTinyInteger, dtShortIntFixed, dtnone, dtList, dtSpecial, dtDateTime, dtOctetString);
54  
55    POutputBlockItemData = ^TOutputBlockItemData;
56    TOutputBlockItemData = record
# Line 73 | Line 73 | type
73      FBuffer: PByte;
74      FBufSize: integer;
75      FBufferParsed: boolean;
76 +    FFirebirdClientAPI: TFBClientAPI;
77      procedure ParseBuffer;
78      {$IFDEF DEBUGOUTPUTBLOCK}
79      procedure FormattedPrint(const aItems: array of POutputBlockItemData;
80        Indent: AnsiString);
81      {$ENDIF}
81    procedure PrintBuf;
82    protected
83      FIntegerType: TItemDataType;
84      FError: boolean;
# Line 86 | Line 86 | type
86      FItems: array of POutputBlockItemData;
87      procedure DoParseBuffer; virtual; abstract;
88      function AddItem(BufPtr: PByte): POutputBlockItemData;
89 <    function AddIntegerItem(BufPtr: PByte): POutputBlockItemData;
89 >    function AddIntegerItem(BufPtr: PByte; IntType: TItemDataType): POutputBlockItemData; overload;
90 >    function AddIntegerItem(BufPtr: PByte): POutputBlockItemData; overload;
91      function AddStringItem(BufPtr: PByte): POutputBlockItemData;
92      function AddShortStringItem(BufPtr: PByte): POutputBlockItemData;
93      function AddByteItem(BufPtr: PByte): POutputBlockItemData;
94      function AddBytesItem(BufPtr: PByte): POutputBlockItemData;
95      function AddListItem(BufPtr: PByte): POutputBlockItemData; virtual;
96      function AddSpecialItem(BufPtr: PByte): POutputBlockItemData; virtual;
97 +    function AddDateTimeItem(BufPtr: PByte): POutputBlockItemData;
98 +    function AddOctetString(BufPtr: PByte): POutputBlockItemData;
99    public
100 <    constructor Create(aSize: integer = DefaultBufferSize);
100 >    constructor Create(api: TFBClientAPI; aSize: integer = DefaultBufferSize);
101      destructor Destroy; override;
102      function Buffer: PByte;
103      function getBufSize: integer;
# Line 103 | Line 106 | type
106      function GetCount: integer;
107      function GetItem(index: integer): POutputBlockItemData;
108      function Find(ItemType: byte): POutputBlockItemData;
109 +    procedure PrintBuf;
110      property Count: integer read GetCount;
111      property Items[index: integer]: POutputBlockItemData read getItem; default;
112    end;
# Line 115 | Line 119 | type
119      FOwnerIntf: IUnknown;
120      FItemData: POutputBlockItemData;
121    protected
122 +    FFirebirdClientAPI: TFBClientAPI;
123      function GetItem(index: integer): POutputBlockItemData;
124      function Find(ItemType: byte): POutputBlockItemData;
125      procedure SetString(out S: AnsiString; Buf: PByte; Len: integer;
# Line 128 | Line 133 | type
133      function getItemType: byte;
134      function getSize: integer;
135      procedure getRawBytes(var Buffer);
136 <    function getAsInteger: integer;
136 >    function getAsInteger: int64;
137      function getParamType: byte;
138      function getAsString: AnsiString;
139      function getAsByte: byte;
140      function getAsBytes: TByteArray;
141 +    function getAsDateTime: TDateTime;
142      function CopyTo(stream: TStream; count: integer): integer;
143    end;
144  
# Line 179 | Line 185 | type
185      procedure DecodeVersionString(var Version: byte; var VersionString: AnsiString);
186      procedure DecodeUserNames(UserNames: TStrings);
187      function getOperationCounts: TDBOperationCounts;
188 < end;
188 >  end;
189  
190    { TDBInformation }
191  
# Line 188 | Line 194 | type
194      function AddSpecialItem(BufPtr: PByte): POutputBlockItemData; override;
195      procedure DoParseBuffer; override;
196    public
197 <    constructor Create(aSize: integer=DBInfoDefaultBufferSize);
197 >    constructor Create(api: TFBClientAPI; aSize: integer = DefaultBufferSize);
198 >  {$IFNDEF FPC}
199 >    function Find(ItemType: byte): IDBInfoItem;
200 >  {$ENDIF}
201    end;
202  
203    { TServiceQueryResultItem }
# Line 203 | Line 212 | type
212      function AddListItem(BufPtr: PByte): POutputBlockItemData; override;
213      function AddSpecialItem(BufPtr: PByte): POutputBlockItemData; override;
214      procedure DoParseBuffer; override;
215 +  {$IFNDEF FPC}
216 +  public
217 +    function Find(ItemType: byte): IServiceQueryResultItem;
218 +  {$ENDIF}
219    end;
220  
221  
# Line 213 | Line 226 | type
226      function getItemType: byte;
227      function getSize: integer;
228      function getAsString: AnsiString;
229 <    function getAsInteger: integer;
229 >    function getAsInteger: int64;
230    end;
231  
232    ISQLInfoItem = interface(ISQLInfoSubItem)
# Line 249 | Line 262 | type
262      function AddListItem(BufPtr: PByte): POutputBlockItemData; override;
263      procedure DoParseBuffer; override;
264    public
265 <    constructor Create(aSize: integer = 1024);
265 >    constructor Create(api: TFBClientAPI; aSize: integer= DefaultBufferSize);
266    end;
267  
268    IBlobInfoItem = interface
# Line 257 | Line 270 | type
270       function getItemType: byte;
271       function getSize: integer;
272       function getAsString: AnsiString;
273 <     function getAsInteger: integer;
273 >     function getAsInteger: int64;
274     end;
275  
276    IBlobInfo = interface
# Line 285 | Line 298 | type
298    protected
299      procedure DoParseBuffer; override;
300    public
301 <    constructor Create(aSize: integer=DBInfoDefaultBufferSize);
301 >    constructor Create(api: TFBClientAPI; aSize: integer = DefaultBufferSize);
302    end;
303  
304   implementation
305  
306   uses FBMessages {$IFNDEF FPC}, TypInfo {$ENDIF};
307  
308 + function BufToStr(P: PByte; Len: integer):AnsiString;
309 + begin
310 +  SetLength(Result,Len);
311 +  Move(P^,Result[1],Len);
312 + end;
313 +
314   {$IFDEF FPC}
315   { TOutputBlockItemGroup }
316  
# Line 322 | Line 341 | function TCustomOutputBlock<_TItem,_IIte
341   var P: POutputBlockItemData;
342   begin
343    P := inherited Find(ItemType);
344 <  Result := _TItem.Create(self,P)
344 >  if P = nil then
345 >    Result := nil
346 >  else
347 >    Result := _TItem.Create(self,P)
348   end;
349  
350   {$ELSE}
# Line 344 | Line 366 | var P: POutputBlockItemData;
366      Obj: TOutputBlockItem;
367   begin
368    P := inherited Find(ItemType);
369 <  Obj := TOutputBlockItemClass(_TItem).Create(self.Owner,P);
370 <  if Obj.QueryInterface(GetTypeData(TypeInfo(_IItem))^.Guid,Result) <> 0 then
371 <    IBError(ibxeInterfaceNotSupported,[GuidToString(GetTypeData(TypeInfo(_IItem))^.Guid)]);
369 >  if P = nil then
370 >    Result := Default(_IITEM)
371 >  else
372 >  begin
373 >    Obj := TOutputBlockItemClass(_TItem).Create(self.Owner,P);
374 >    if Obj.QueryInterface(GetTypeData(TypeInfo(_IItem))^.Guid,Result) <> 0 then
375 >      IBError(ibxeInterfaceNotSupported,[GuidToString(GetTypeData(TypeInfo(_IItem))^.Guid)]);
376 >  end;
377   end;
378  
379   { TCustomOutputBlock }
# Line 385 | Line 412 | begin
412    if (index >= 0) and (index < Length(FItemData^.FSubItems)) then
413      Result := FItemData^.FSubItems[index]
414    else
415 <  with FirebirdClientAPI do
415 >  with FFirebirdClientAPI do
416      IBError(ibxeOutputBlockIndexError,[index]);
417   end;
418  
# Line 406 | Line 433 | end;
433   procedure TOutputBlockItem.SetString(out S: AnsiString; Buf: PByte;
434    Len: integer; CodePage: TSystemCodePage);
435   var rs: RawByteString;
436 +    i: integer;
437   begin
438 <  system.SetString(rs,PAnsiChar(Buf),len);
438 >  {There seems to be a memory manager problem with SetString that can cause
439 >   an unhandled exception at the end of a program if it is used to set the
440 >   string. Safer to copy characters one by one. Note that Setlength does
441 >   not work around the bug either.}
442 >  rs := '';
443 >  for i := 0 to len-1 do
444 >    rs := rs + PAnsiChar(buf+i)^;
445 > //  system.SetString(rs,PAnsiChar(Buf),len);
446    SetCodePage(rs,CodePage,false);
447    S := rs;
448   end;
# Line 418 | Line 453 | begin
453    inherited Create;
454    FOwner := AOwner;
455    FOwnerIntf := AOwner;
456 +  FFirebirdClientAPI := AOwner.FFirebirdClientAPI;
457    FItemData := Data;
458   end;
459  
# Line 428 | Line 464 | end;
464  
465   function TOutputBlockItem.getSize: integer;
466   begin
467 <  Result := FItemData^.FDataLength;
467 >  if FItemData = nil then
468 >    Result := 0
469 >  else
470 >    Result := FItemData^.FDataLength;
471   end;
472  
473   procedure TOutputBlockItem.getRawBytes(var Buffer);
# Line 437 | Line 476 | begin
476      Move(FBufPtr^,Buffer,FDatalength);
477   end;
478  
479 < function TOutputBlockItem.getAsInteger: integer;
479 > function TOutputBlockItem.getAsInteger: int64;
480   var len: integer;
481   begin
482    with FItemData^ do
483    case FDataType of
484    dtIntegerFixed:
485 <    with FirebirdClientAPI do
485 >    with FFirebirdClientAPI do
486        Result := DecodeInteger(FBufPtr+1,4);
487  
488 +  dtShortIntFixed:
489 +    with FFirebirdClientAPI do
490 +      Result := DecodeInteger(FBufPtr+1,2);
491 +
492 +  dtTinyInteger:
493 +    with FFirebirdClientAPI do
494 +    begin
495 +      len := DecodeInteger(FBufPtr+1,1);
496 +      Result := DecodeInteger(FBufPtr+2,len);
497 +    end;
498 +
499    dtByte,
500    dtInteger:
501 <    with FirebirdClientAPI do
501 >    with FFirebirdClientAPI do
502      begin
503        len := DecodeInteger(FBufPtr+1,2);
504        Result := DecodeInteger(FBufPtr+3,len);
# Line 469 | Line 519 | begin
519    Result := '';
520    with FItemData^ do
521    case FDataType of
522 +  dtIntegerFixed,
523    dtInteger:
524      Result := IntToStr(getAsInteger);
525    dtByte:
# Line 480 | Line 531 | begin
531      end;
532    dtString2:
533      begin
534 <      with FirebirdClientAPI do
534 >      with FFirebirdClientAPI do
535          len := DecodeInteger(FBufPtr+1,2);
536        SetString(Result,FBufPtr+3,len,CP_ACP);
537      end;
538 +  dtOctetString:
539 +    begin
540 +      with FFirebirdClientAPI do
541 +        len := DecodeInteger(FBufPtr+1,2);
542 +      SetString(Result,FBufPtr+3,len,CP_NONE);
543 +    end;
544    else
545      IBError(ibxeOutputBlockTypeError,[nil]);
546    end;
# Line 517 | Line 574 | begin
574      IBError(ibxeOutputBlockTypeError,[nil]);
575   end;
576  
577 + function TOutputBlockItem.getAsDateTime: TDateTime;
578 + var aDate: integer;
579 +    aTime: integer;
580 + begin
581 +  with FItemData^, FFirebirdClientAPI do
582 +  if FDataType = dtDateTime then
583 +  begin
584 +    aDate := DecodeInteger(FBufPtr+3,4);
585 +    aTime := DecodeInteger(FBufPtr+7,4);
586 +    Result := SQLDecodeDate(@aDate) + SQLDecodeTime(@aTime)
587 +  end
588 +  else
589 +    IBError(ibxeOutputBlockTypeError,[nil]);
590 + end;
591 +
592 +
593   function TOutputBlockItem.CopyTo(stream: TStream; count: integer): integer;
594   var len: integer;
595   begin
# Line 532 | Line 605 | begin
605        end;
606      dtString2:
607        begin
608 <        with FirebirdClientAPI do
608 >        with FFirebirdClientAPI do
609            len := DecodeInteger(FBufPtr+1,2);
610          if (count > 0) and (count < len) then len := count;
611          Result := stream.Write((FBufPtr+3)^,len);
# Line 575 | Line 648 | begin
648    end;
649   end;
650  
651 < function TOutputBlock.AddIntegerItem(BufPtr: PByte): POutputBlockItemData;
651 > function TOutputBlock.AddIntegerItem(BufPtr: PByte; IntType: TItemDataType
652 >  ): POutputBlockItemData;
653   begin
654    new(Result);
655    with Result^ do
656    begin
657 <    FDataType := FIntegerType;
657 >    FDataType := IntType;
658      FBufPtr := BufPtr;
659 <    if FDataType = dtIntegerFixed then
660 <    begin
661 <      FDataLength := 4;
662 <      FSize := 5;
663 <    end
664 <    else
665 <    begin
666 <      with FirebirdClientAPI do
667 <        FDataLength := DecodeInteger(FBufPtr+1, 2);
668 <      FSize := FDataLength + 3;
659 >    case FDataType of
660 >      dtIntegerFixed:
661 >      begin
662 >        FDataLength := 4;
663 >        FSize := 5;
664 >      end;
665 >
666 >      dtShortIntFixed:
667 >      begin
668 >        FDataLength := 2;
669 >        FSize := 3;
670 >      end;
671 >
672 >      dtTinyInteger:
673 >      begin
674 >        with FFirebirdClientAPI do
675 >          FDataLength := DecodeInteger(FBufPtr+1, 1);
676 >        FSize := FDataLength + 2;
677 >      end;
678 >
679 >      else
680 >      begin
681 >        with FFirebirdClientAPI do
682 >          FDataLength := DecodeInteger(FBufPtr+1, 2);
683 >        FSize := FDataLength + 3;
684 >      end;
685      end;
686      SetLength(FSubItems,0);
687    end;
688   end;
689  
690 + function TOutputBlock.AddIntegerItem(BufPtr: PByte): POutputBlockItemData;
691 + begin
692 +  Result := AddIntegerItem(BufPtr,FIntegerType);
693 + end;
694 +
695   function TOutputBlock.AddStringItem(BufPtr: PByte): POutputBlockItemData;
696   begin
697    new(Result);
# Line 604 | Line 699 | begin
699    begin
700      FDataType := dtString2;
701      FBufPtr := BufPtr;
702 <    with FirebirdClientAPI do
702 >    with FFirebirdClientAPI do
703        FDataLength := DecodeInteger(FBufPtr+1, 2);
704      FSize := FDataLength + 3;
705      SetLength(FSubItems,0);
# Line 644 | Line 739 | begin
739    begin
740      FDataType := dtBytes;
741      FBufPtr := BufPtr;
742 <    with FirebirdClientAPI do
742 >    with FFirebirdClientAPI do
743        FDataLength := DecodeInteger(FBufPtr+1, 2);
744      FSize := FDataLength + 3;
745      SetLength(FSubItems,0);
# Line 677 | Line 772 | begin
772    end;
773   end;
774  
775 < constructor TOutputBlock.Create(aSize: integer);
775 > function TOutputBlock.AddDateTimeItem(BufPtr: PByte): POutputBlockItemData;
776 > begin
777 >  new(Result);
778 >  with Result^ do
779 >  begin
780 >    FDataType := dtDateTime;
781 >    FBufPtr := BufPtr;
782 >    with FFirebirdClientAPI do
783 >      FDataLength := DecodeInteger(FBufPtr+1, 2);
784 >    FSize := FDataLength + 3;
785 >    SetLength(FSubItems,0);
786 >  end;
787 > end;
788 >
789 > function TOutputBlock.AddOctetString(BufPtr: PByte): POutputBlockItemData;
790 > begin
791 >  new(Result);
792 >  with Result^ do
793 >  begin
794 >    FDataType := dtOctetString;
795 >    FBufPtr := BufPtr;
796 >    with FFirebirdClientAPI do
797 >      FDataLength := DecodeInteger(FBufPtr+1, 2);
798 >    FSize := FDataLength + 3;
799 >    SetLength(FSubItems,0);
800 >  end;
801 > end;
802 >
803 > constructor TOutputBlock.Create(api: TFBClientAPI; aSize: integer);
804   begin
805    inherited Create;
806 +  FFirebirdClientAPI := api;
807    FBufSize := aSize;
808    GetMem(FBuffer,aSize);
809    if FBuffer = nil then
# Line 694 | Line 818 | var i, j: integer;
818   begin
819    for i := 0 to length(FItems) - 1 do
820    begin
821 <    for j := 0 to Length(FItems[i]^.FSubItems) -1 do
822 <      dispose(FItems[i]^.FSubItems[j]);
823 <    dispose(FItems[i]);
821 >    if FItems[i] <> nil then
822 >    begin
823 >      for j := 0 to Length(FItems[i]^.FSubItems) -1 do
824 >        if FItems[i]^.FSubItems[j] <> nil then
825 >          dispose(FItems[i]^.FSubItems[j]);
826 >      dispose(FItems[i]);
827 >    end;
828    end;
829    FreeMem(FBuffer);
830    inherited Destroy;
# Line 772 | Line 900 | begin
900      else
901        begin
902          item := TOutputBlockItem.Create(self,(aItems[i]));
903 <        writeln(Indent,'ItemType = ',byte(FBufPtr^),' Value = ',(item as TOutputBlockItem).GetAsString);
903 >        try
904 >          writeln(Indent,'ItemType = ',byte(FBufPtr^),' Value = ',(item as TOutputBlockItem).GetAsString);
905 >        except
906 >          writeln(Indent,'Unknown ItemType = ',byte(FBufPtr^));
907 >        end;
908        end;
909      end;
910    end;
# Line 785 | Line 917 | begin
917    write(classname,': ');
918    for i := 0 to getBufSize - 1 do
919    begin
920 +    if byte(FBuffer[i]) = $FF then break;
921      write(Format('%x ',[byte(Buffer[i])]));
922 <    if byte(FBuffer[i]) = isc_info_end then break;
922 > //    if byte(FBuffer[i]) = isc_info_end then break;
923 >  end;
924 >  writeln;
925 >  for i := 0 to getBufSize - 1 do
926 >  begin
927 >    if byte(FBuffer[i]) = $FF then break;
928 >    if chr(FBuffer[i]) in [' '..'~'] then
929 >      write(chr(Buffer[i]))
930 >    else
931 >      write('.');
932 > //    if byte(FBuffer[i]) = isc_info_end then break;
933    end;
934    writeln;
935   end;
# Line 862 | Line 1005 | begin
1005      SetLength(Result,TableCounts);
1006      P := FBufPtr + 3;
1007      for i := 0 to TableCounts -1 do
1008 <    with FirebirdClientAPI do
1008 >    with FFirebirdClientAPI do
1009      begin
1010        Result[i].TableID := DecodeInteger(P,2);
1011        Inc(P,2);
# Line 881 | Line 1024 | begin
1024    Result := inherited AddSpecialItem(BufPtr);
1025    with Result^ do
1026    begin
1027 <    with FirebirdClientAPI do
1027 >    with FFirebirdClientAPI do
1028        FDataLength := DecodeInteger(FBufPtr+1,2);
1029      FSize := FDataLength + 3;
1030    end;
# Line 898 | Line 1041 | begin
1041    begin
1042      SetLength(FItems,index+1);
1043      case byte(P^) of
1044 +    isc_info_db_read_only,
1045      isc_info_no_reserve,
1046      isc_info_allocation,
1047      isc_info_ods_minor_version,
# Line 912 | Line 1056 | begin
1056      isc_info_fetches,
1057      isc_info_marks,
1058      isc_info_reads,
1059 <    isc_info_writes:
1059 >    isc_info_writes,
1060 >    isc_info_active_tran_count,
1061 >    fb_info_pages_used,
1062 >    fb_info_pages_free,
1063 >    fb_info_conn_flags:
1064        FItems[index] := AddIntegerItem(P);
1065  
1066      isc_info_implementation,
1067      isc_info_base_level:
1068        FItems[index] := AddBytesItem(P);
1069  
1070 +    isc_info_creation_date:
1071 +      FItems[index] := AddDateTimeItem(P);
1072 +
1073 +    fb_info_page_contents:
1074 +      FItems[index] := AddOctetString(P);
1075 +
1076 +    fb_info_crypt_key:
1077 +      FItems[index] := AddStringItem(P);
1078 +
1079      isc_info_db_id,
1080      isc_info_version,
1081      isc_info_backout_count,
# Line 940 | Line 1097 | begin
1097    end;
1098   end;
1099  
1100 < constructor TDBInformation.Create(aSize: integer);
1100 > {$IFNDEF FPC}
1101 > function TDBInformation.Find(ItemType: byte): IDBInfoItem;
1102   begin
1103 <  inherited Create(aSize);
1103 >  Result := inherited Find(ItemType);
1104 >  if Result.GetSize = 0 then
1105 >    Result := nil;
1106 > end;
1107 > {$ENDIF}
1108 >
1109 > constructor TDBInformation.Create(api: TFBClientAPI; aSize: integer);
1110 > begin
1111 >  inherited Create(api,aSize);
1112    FIntegerType := dtInteger;
1113   end;
1114  
# Line 959 | Line 1125 | begin
1125    group := byte(BufPtr^);
1126    if group in [isc_info_svc_get_users,isc_info_svc_limbo_trans] then
1127    begin
1128 <    with FirebirdClientAPI do
1128 >    with FFirebirdClientAPI do
1129         Result^.FSize := DecodeInteger(P,2) + 3;
1130      Inc(P,2);
1131    end;
# Line 968 | Line 1134 | begin
1134      while (P < FBufPtr + FSize) and (P^ <> isc_info_flag_end) do
1135      begin
1136        SetLength(FSubItems,i+1);
1137 +      FSubItems[i] := nil;
1138        case group of
1139        isc_info_svc_svr_db_info:
1140          case integer(P^) of
# Line 979 | Line 1146 | begin
1146              FSubItems[i] := AddStringItem(P);
1147  
1148            else
1149 <            IBError(ibxeOutputParsingError, [integer(P^)]);
1149 >            IBError(ibxeOutputParsingError, [integer(P^),BufToStr(P,FSize - (P-FBufPtr))]);
1150            end;
1151  
1152        isc_info_svc_get_license:
# Line 988 | Line 1155 | begin
1155          isc_spb_lic_key:
1156            FSubItems[i] := AddIntegerItem(P);
1157          else
1158 <          IBError(ibxeOutputParsingError, [integer(P^)]);
1158 >          IBError(ibxeOutputParsingError, [integer(P^),BufToStr(P,FSize - (P-FBufPtr))]);
1159          end;
1160  
1161        isc_info_svc_limbo_trans:
# Line 1007 | Line 1174 | begin
1174         isc_spb_tra_state:
1175           FSubItems[i] := AddByteItem(P);
1176         else
1177 <         IBError(ibxeOutputParsingError, [integer(P^)]);
1177 >         IBError(ibxeOutputParsingError, [integer(P^),BufToStr(P,FSize - (P-FBufPtr))]);
1178         end;
1179  
1180        isc_info_svc_get_users:
1181          case integer(P^) of
1182 +        isc_spb_sec_admin,
1183          isc_spb_sec_userid,
1184          isc_spb_sec_groupid:
1185            FSubItems[i] := AddIntegerItem(P);
# Line 1024 | Line 1192 | begin
1192            FSubItems[i] := AddStringItem(P);
1193  
1194          else
1195 <          IBError(ibxeOutputParsingError, [integer(P^)]);
1195 >          IBError(ibxeOutputParsingError, [integer(P^),BufToStr(P,FSize - (P-FBufPtr))]);
1196          end;
1197  
1198        end;
# Line 1052 | Line 1220 | begin
1220    Result := inherited AddSpecialItem(BufPtr);
1221    with Result^ do
1222    begin
1223 <    with FirebirdClientAPI do
1223 >    with FFirebirdClientAPI do
1224        FDataLength := DecodeInteger(FBufPtr+1, 2);
1225  
1226      P := FBufPtr + 3; {skip length bytes}
# Line 1075 | Line 1243 | begin
1243    while  (P < Buffer + getBufSize) and (P^ <> isc_info_end) do
1244    begin
1245      SetLength(FItems,i+1);
1246 +    FItems[i] := nil;
1247      case integer(P^) of
1248      isc_info_svc_line,
1249      isc_info_svc_get_env,
# Line 1109 | Line 1278 | begin
1278  
1279  
1280      else
1281 <       IBError(ibxeOutputParsingError, [integer(P^)]);
1281 >       IBError(ibxeOutputParsingError, [integer(P^),BufToStr(P,getBufSize - (P-Buffer))]);
1282      end;
1283      P := P + FItems[i]^.FSize;
1284      Inc(i);
1285    end;
1286   end;
1287  
1288 + {$IFNDEF FPC}
1289 + function TServiceQueryResults.Find(ItemType: byte): IServiceQueryResultItem;
1290 + begin
1291 +  Result := inherited Find(ItemType);
1292 +  if Result.GetSize = 0 then
1293 +    Result := nil;
1294 + end;
1295 + {$ENDIF}
1296 +
1297   { TSQLInfoResultsBuffer }
1298  
1299   function TSQLInfoResultsBuffer.AddListItem(BufPtr: PByte): POutputBlockItemData;
# Line 1128 | Line 1306 | begin
1306  
1307    if byte(BufPtr^) = isc_info_sql_records then
1308    begin
1309 <    with FirebirdClientAPI do
1309 >    with FFirebirdClientAPI do
1310        Result^.FSize := DecodeInteger(P,2) + 3;
1311      Inc(P,2);
1312      with Result^ do
# Line 1204 | Line 1382 | begin
1382    end;
1383   end;
1384  
1385 < constructor TSQLInfoResultsBuffer.Create(aSize: integer);
1385 > constructor TSQLInfoResultsBuffer.Create(api: TFBClientAPI; aSize: integer);
1386   begin
1387 <  inherited Create(aSize);
1387 >  inherited Create(api,aSize);
1388    FIntegerType := dtInteger;
1389   end;
1390  
# Line 1236 | Line 1414 | begin
1414    end;
1415   end;
1416  
1417 < constructor TBlobInfo.Create(aSize: integer);
1417 > constructor TBlobInfo.Create(api: TFBClientAPI; aSize: integer);
1418   begin
1419 <  inherited Create(aSize);
1419 >  inherited Create(api,aSize);
1420    FIntegerType := dtInteger;
1421   end;
1422  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines