2727import java .sql .SQLException ;
2828import java .util .Arrays ;
2929
30+ import static org .firebirdsql .gds .ISCConstants .isc_spb_version ;
3031import static org .firebirdsql .gds .JaybirdErrorCodes .jb_clumpletReaderUsageError ;
3132import static org .firebirdsql .gds .JaybirdErrorCodes .jb_invalidClumpletStructure ;
3233
@@ -49,18 +50,13 @@ public ClumpletReader(Kind kind, byte[] buffer) {
4950 }
5051
5152 public boolean isTagged () {
52- switch (kind ) {
53- case Tpb :
54- case Tagged :
55- case WideTagged :
56- case SpbAttach :
57- return true ;
58- }
59-
60- return false ;
53+ return kind .isTagged ();
6154 }
6255
6356 public int getBufferTag () throws SQLException {
57+ if (!isTagged ()) {
58+ throw usageMistake ("buffer is not tagged" );
59+ }
6460 switch (kind ) {
6561 case Tpb :
6662 case Tagged :
@@ -69,33 +65,16 @@ public int getBufferTag() throws SQLException {
6965 throw invalidStructure ("empty buffer" );
7066 }
7167 return buffer [0 ];
72- case SpbStart :
73- case UnTagged :
74- case WideUnTagged :
75- case SpbSendItems :
76- case SpbReceiveItems :
77- throw usageMistake ("buffer is not tagged" );
7868 case SpbAttach :
7969 if (buffer .length == 0 ) {
8070 throw invalidStructure ("empty buffer" );
81- }
82- switch (buffer [0 ]) {
83- case ISCConstants .isc_spb_version1 :
84- // This is old SPB format, it's almost like DPB -
85- // buffer's tag is the first byte.
86- return buffer [0 ];
87- case ISCConstants .isc_spb_version :
88- // Buffer's tag is the second byte
71+ }else if (buffer [0 ] == isc_spb_version ) {
8972 if (buffer .length == 1 ) {
90- throw invalidStructure ("buffer too short (1 byte) " );
73+ throw invalidStructure ("empty buffer " );
9174 }
9275 return buffer [1 ];
93- case ISCConstants .isc_spb_version3 :
94- // This is wide SPB attach format - buffer's tag is the first byte.
95- return buffer [0 ];
96- default :
97- throw invalidStructure ("spb in service attach should begin with isc_spb_version1 or isc_spb_version" );
9876 }
77+ return buffer [0 ];
9978 default :
10079 throw new SQLException ("Unexpected clumplet kind: " + kind );
10180 }
@@ -132,6 +111,7 @@ public ClumpletType getClumpletType(byte tag) throws SQLException {
132111 }
133112 return ClumpletType .StringSpb ;
134113 case SpbReceiveItems :
114+ case InfoItems :
135115 return ClumpletType .SingleTpb ;
136116 case SpbStart :
137117 switch (tag ) {
@@ -293,6 +273,15 @@ public ClumpletType getClumpletType(byte tag) throws SQLException {
293273 break ;
294274 }
295275 throw invalidStructure ("wrong spb state" );
276+ case InfoResponse :
277+ switch (tag ) {
278+ case ISCConstants .isc_info_end :
279+ case ISCConstants .isc_info_truncated :
280+ case ISCConstants .isc_info_flag_end :
281+ return ClumpletType .SingleTpb ;
282+ default :
283+ return ClumpletType .StringSpb ;
284+ }
296285 }
297286 throw invalidStructure ("unknown reason" );
298287 }
@@ -383,32 +372,26 @@ public int getClumpletSize(boolean wTag, boolean wLength, boolean wData) throws
383372 public void moveNext () throws SQLException {
384373 if (isEof ()) {
385374 return ; // no need to raise useless exceptions
375+ } else if (kind == Kind .InfoResponse ) {
376+ int clumpTag = getClumpTag ();
377+ // terminating clumplet
378+ if (clumpTag == ISCConstants .isc_info_end || clumpTag == ISCConstants .isc_info_truncated ) {
379+ position = getBufferLength ();
380+ return ;
381+ }
386382 }
387383 int cs = getClumpletSize (true , true , true );
388384 adjustSpbState ();
389385 position += cs ;
390386 }
391387
392- public void rewind () throws SQLException {
393- if (buffer == null || buffer . length == 0 ) {
388+ public void rewind () {
389+ if (buffer . length == 0 || ! isTagged () ) {
394390 position = 0 ;
395- spbState = 0 ;
396- return ;
397- }
398- switch (kind ) {
399- case UnTagged :
400- case WideUnTagged :
401- case SpbStart :
402- case SpbSendItems :
403- case SpbReceiveItems :
404- position = 0 ;
405- break ;
406- default :
407- if (kind == Kind .SpbAttach && getBufferLength () > 0 && buffer [0 ] != ISCConstants .isc_spb_version1 ) {
408- position = 2 ;
409- } else {
410- position = 1 ;
411- }
391+ } else if (kind == Kind .SpbAttach && getBufferLength () > 0 && buffer [0 ] == isc_spb_version ) {
392+ position = 2 ;
393+ } else {
394+ position = 1 ;
412395 }
413396 spbState = 0 ;
414397 }
@@ -537,9 +520,7 @@ public boolean isEof() {
537520 }
538521
539522 private int getBufferLength () {
540- if (buffer .length == 1 && kind != Kind .UnTagged && kind != Kind .SpbStart &&
541- kind != Kind .WideUnTagged && kind != Kind .SpbSendItems &&
542- kind != Kind .SpbReceiveItems ) {
523+ if (buffer .length == 1 && isTagged ()) {
543524 return 0 ;
544525 }
545526 return buffer .length ;
@@ -554,16 +535,30 @@ private static SQLException usageMistake(String message) {
554535 }
555536
556537 public enum Kind {
557- EndOfList ,
558- Tagged ,
559- UnTagged ,
560- SpbAttach ,
561- SpbStart ,
562- Tpb ,
563- WideTagged ,
564- WideUnTagged ,
565- SpbSendItems ,
566- SpbReceiveItems
538+
539+ Tagged (true ),
540+ UnTagged (false ),
541+ SpbAttach (true ),
542+ SpbStart (false ),
543+ Tpb (true ),
544+ WideTagged (true ),
545+ WideUnTagged (false ),
546+ SpbSendItems (false ),
547+ SpbReceiveItems (false ),
548+ InfoResponse (false ),
549+ InfoItems (false ),
550+ ;
551+
552+ private final boolean tagged ;
553+
554+ Kind (boolean tagged ) {
555+ this .tagged = tagged ;
556+ }
557+
558+ public boolean isTagged () {
559+ return tagged ;
560+ }
561+
567562 }
568563
569564 public enum ClumpletType {
0 commit comments