• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wuwen5 / hessian / 17882005206

20 Sep 2025 01:06PM UTC coverage: 70.892% (+1.5%) from 69.377%
17882005206

push

github

web-flow
refactor: code clean (#50)

* refactor: code clean

* refactor: code clean,remove hessian1 code

* refactor: fix HessianDebugState

1780 of 2691 branches covered (66.15%)

Branch coverage included in aggregate %.

4226 of 5781 relevant lines covered (73.1%)

3.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.12
hessian2-codec/src/main/java/io/github/wuwen5/hessian/io/HessianDebugState.java
1
/*
2
 * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
3
 *
4
 * The Apache Software License, Version 1.1
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 *
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in
15
 *    the documentation and/or other materials provided with the
16
 *    distribution.
17
 *
18
 * 3. The end-user documentation included with the redistribution, if
19
 *    any, must include the following acknowlegement:
20
 *       "This product includes software developed by the
21
 *        Caucho Technology (http://www.caucho.com/)."
22
 *    Alternately, this acknowlegement may appear in the software itself,
23
 *    if and wherever such third-party acknowlegements normally appear.
24
 *
25
 * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
26
 *    endorse or promote products derived from this software without prior
27
 *    written permission. For written permission, please contact
28
 *    info@caucho.com.
29
 *
30
 * 5. Products derived from this software may not be called "Resin"
31
 *    nor may "Resin" appear in their names without prior written
32
 *    permission of Caucho Technology.
33
 *
34
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37
 * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45
 *
46
 * @author Scott Ferguson
47
 */
48

49
package io.github.wuwen5.hessian.io;
50

51
import java.io.PrintWriter;
52
import java.util.ArrayList;
53
import java.util.List;
54
import lombok.Getter;
55
import lombok.Setter;
56
import lombok.extern.slf4j.Slf4j;
57

58
/**
59
 * Debugging input stream for Hessian requests.
60
 */
61
@Slf4j
4✔
62
public class HessianDebugState implements Hessian2Constants {
63

64
    private final PrintWriter dbg;
65

66
    private State state;
67

68
    private final List<ObjectDef> objectDefList = new ArrayList<>();
5✔
69

70
    private final ArrayList<String> typeDefList = new ArrayList<>();
5✔
71

72
    private int refId;
73
    private boolean isNewline = true;
3✔
74
    private boolean isObject = false;
3✔
75
    private int column;
76

77
    @Getter
3✔
78
    @Setter
79
    private int depth = 0;
80

81
    /**
82
     * Creates an uninitialized Hessian input stream.
83
     */
84
    public HessianDebugState(PrintWriter dbg) {
2✔
85
        this.dbg = dbg;
3✔
86

87
        state = new InitialState();
6✔
88
    }
1✔
89

90
    public void startTop2() {
91
        state = new Top2State();
6✔
92
    }
1✔
93

94
    public void startStreaming() {
95
        state = new StreamingState(new InitialState(), false);
11✔
96
    }
1✔
97

98
    /**
99
     * Reads a character.
100
     */
101
    public void next(int ch) {
102
        state = state.next(ch);
6✔
103
    }
1✔
104

105
    void println() {
106
        if (!isNewline) {
3✔
107
            dbg.println();
3✔
108
            dbg.flush();
3✔
109
        }
110

111
        isNewline = true;
3✔
112
        column = 0;
3✔
113
    }
1✔
114

115
    abstract class State {
116
        State next;
117

118
        State() {}
6✔
119

120
        State(State next) {
5✔
121
            this.next = next;
3✔
122
        }
1✔
123

124
        abstract State next(int ch);
125

126
        @SuppressWarnings("unused")
127
        boolean isShift(Object value) {
128
            return false;
2✔
129
        }
130

131
        @SuppressWarnings("unused")
132
        State shift(Object value) {
133
            return this;
×
134
        }
135

136
        int depth() {
137
            if (next != null) {
3✔
138
                return next.depth();
4✔
139
            } else {
140
                return HessianDebugState.this.getDepth();
4✔
141
            }
142
        }
143

144
        void printIndent(int depth) {
145
            if (isNewline) {
4✔
146
                for (int i = column; i < depth() + depth; i++) {
12✔
147
                    dbg.print(" ");
5✔
148
                    column++;
7✔
149
                }
150
            }
151
        }
1✔
152

153
        void print(String string) {
154
            print(0, string);
4✔
155
        }
1✔
156

157
        void print(int depth, String string) {
158
            printIndent(depth);
3✔
159

160
            dbg.print(string);
5✔
161
            isNewline = false;
4✔
162
            isObject = false;
4✔
163

164
            int p = string.lastIndexOf('\n');
4✔
165
            if (p > 0) {
2!
166
                column = string.length() - p - 1;
×
167
            } else {
168
                column += string.length();
8✔
169
            }
170
        }
1✔
171

172
        void println(String string) {
173
            println(0, string);
4✔
174
        }
1✔
175

176
        void println(int depth, String string) {
177
            printIndent(depth);
3✔
178

179
            dbg.println(string);
5✔
180
            dbg.flush();
4✔
181
            isNewline = true;
4✔
182
            isObject = false;
4✔
183
            column = 0;
4✔
184
        }
1✔
185

186
        void println() {
187
            if (!isNewline) {
4✔
188
                dbg.println();
4✔
189
                dbg.flush();
4✔
190
            }
191

192
            isNewline = true;
4✔
193
            isObject = false;
4✔
194
            column = 0;
4✔
195
        }
1✔
196

197
        void printObject(String string) {
198
            if (isObject) {
4✔
199
                println();
2✔
200
            }
201

202
            printIndent(0);
3✔
203

204
            dbg.print(string);
5✔
205
            dbg.flush();
4✔
206

207
            column += string.length();
8✔
208

209
            isNewline = false;
4✔
210
            isObject = true;
4✔
211
        }
1✔
212

213
        protected State nextObject(int ch) {
214
            switch (ch) {
2!
215
                case -1:
216
                    println();
2✔
217
                    return this;
2✔
218

219
                case 'N':
220
                    if (isShift(null)) {
4!
221
                        return shift(null);
×
222
                    } else {
223
                        printObject("null");
3✔
224
                        return this;
2✔
225
                    }
226

227
                case 'T':
228
                    if (isShift(Boolean.TRUE)) {
4!
229
                        return shift(Boolean.TRUE);
×
230
                    } else {
231
                        printObject("true");
3✔
232
                        return this;
2✔
233
                    }
234

235
                case 'F':
236
                    if (isShift(Boolean.FALSE)) {
4!
237
                        return shift(Boolean.FALSE);
×
238
                    } else {
239
                        printObject("false");
3✔
240
                        return this;
2✔
241
                    }
242

243
                case 0x80:
244
                case 0x81:
245
                case 0x82:
246
                case 0x83:
247
                case 0x84:
248
                case 0x85:
249
                case 0x86:
250
                case 0x87:
251
                case 0x88:
252
                case 0x89:
253
                case 0x8a:
254
                case 0x8b:
255
                case 0x8c:
256
                case 0x8d:
257
                case 0x8e:
258
                case 0x8f:
259

260
                case 0x90:
261
                case 0x91:
262
                case 0x92:
263
                case 0x93:
264
                case 0x94:
265
                case 0x95:
266
                case 0x96:
267
                case 0x97:
268
                case 0x98:
269
                case 0x99:
270
                case 0x9a:
271
                case 0x9b:
272
                case 0x9c:
273
                case 0x9d:
274
                case 0x9e:
275
                case 0x9f:
276

277
                case 0xa0:
278
                case 0xa1:
279
                case 0xa2:
280
                case 0xa3:
281
                case 0xa4:
282
                case 0xa5:
283
                case 0xa6:
284
                case 0xa7:
285
                case 0xa8:
286
                case 0xa9:
287
                case 0xaa:
288
                case 0xab:
289
                case 0xac:
290
                case 0xad:
291
                case 0xae:
292
                case 0xaf:
293

294
                case 0xb0:
295
                case 0xb1:
296
                case 0xb2:
297
                case 0xb3:
298
                case 0xb4:
299
                case 0xb5:
300
                case 0xb6:
301
                case 0xb7:
302
                case 0xb8:
303
                case 0xb9:
304
                case 0xba:
305
                case 0xbb:
306
                case 0xbc:
307
                case 0xbd:
308
                case 0xbe:
309
                case 0xbf: {
310
                    Integer value = ch - 0x90;
5✔
311

312
                    if (isShift(value)) {
4✔
313
                        return shift(value);
4✔
314
                    } else {
315
                        printObject(value.toString());
4✔
316
                        return this;
2✔
317
                    }
318
                }
319

320
                case 0xc0:
321
                case 0xc1:
322
                case 0xc2:
323
                case 0xc3:
324
                case 0xc4:
325
                case 0xc5:
326
                case 0xc6:
327
                case 0xc7:
328
                case 0xc8:
329
                case 0xc9:
330
                case 0xca:
331
                case 0xcb:
332
                case 0xcc:
333
                case 0xcd:
334
                case 0xce:
335
                case 0xcf:
336
                    return new IntegerState(this, "int", ch - 0xc8, 3);
12✔
337

338
                case 0xd0:
339
                case 0xd1:
340
                case 0xd2:
341
                case 0xd3:
342
                case 0xd4:
343
                case 0xd5:
344
                case 0xd6:
345
                case 0xd7:
346
                    return new IntegerState(this, "int", ch - 0xd4, 2);
12✔
347

348
                case 'I':
349
                    return new IntegerState(this, "int");
8✔
350

351
                case 0xd8:
352
                case 0xd9:
353
                case 0xda:
354
                case 0xdb:
355
                case 0xdc:
356
                case 0xdd:
357
                case 0xde:
358
                case 0xdf:
359
                case 0xe0:
360
                case 0xe1:
361
                case 0xe2:
362
                case 0xe3:
363
                case 0xe4:
364
                case 0xe5:
365
                case 0xe6:
366
                case 0xe7:
367
                case 0xe8:
368
                case 0xe9:
369
                case 0xea:
370
                case 0xeb:
371
                case 0xec:
372
                case 0xed:
373
                case 0xee:
374
                case 0xef: {
375
                    Long value = (long) (ch - 0xe0);
6✔
376

377
                    if (isShift(value)) {
4!
378
                        return shift(value);
×
379
                    } else {
380
                        printObject(value + "L");
4✔
381
                        return this;
2✔
382
                    }
383
                }
384

385
                case 0xf0:
386
                case 0xf1:
387
                case 0xf2:
388
                case 0xf3:
389
                case 0xf4:
390
                case 0xf5:
391
                case 0xf6:
392
                case 0xf7:
393
                case 0xf8:
394
                case 0xf9:
395
                case 0xfa:
396
                case 0xfb:
397
                case 0xfc:
398
                case 0xfd:
399
                case 0xfe:
400
                case 0xff:
401
                    return new LongState(this, "long", (long) ch - 0xf8, 7);
13✔
402

403
                case 0x38:
404
                case 0x39:
405
                case 0x3a:
406
                case 0x3b:
407
                case 0x3c:
408
                case 0x3d:
409
                case 0x3e:
410
                case 0x3f:
411
                    return new LongState(this, "long", (long) ch - 0x3c, 6);
13✔
412

413
                case BC_LONG_INT:
414
                    return new LongState(this, "long", 0, 4);
10✔
415

416
                case 'L':
417
                    return new LongState(this, "long");
8✔
418

419
                case 0x5b:
420
                case 0x5c: {
421
                    Double value = (double) (ch - 0x5b);
6✔
422

423
                    if (isShift(value)) {
4!
424
                        return shift(value);
×
425
                    } else {
426
                        printObject(value.toString());
4✔
427
                        return this;
2✔
428
                    }
429
                }
430

431
                case 0x5d:
432
                    return new DoubleIntegerState(this, 3);
8✔
433

434
                case 0x5e:
435
                    return new DoubleIntegerState(this, 2);
8✔
436

437
                case 0x5f:
438
                    return new MillsState(this);
7✔
439

440
                case 'D':
441
                    return new DoubleState(this);
7✔
442

443
                case 'Q':
444
                    return new RefState(this);
7✔
445

446
                case BC_DATE:
447
                    return new DateState(this);
7✔
448

449
                case BC_DATE_MINUTE:
450
                    return new DateState(this, true);
8✔
451

452
                case 0x00: {
453
                    String value = "\"\"";
2✔
454

455
                    if (isShift(value)) return shift(value);
4!
456
                    else {
457
                        printObject(value);
3✔
458
                        return this;
2✔
459
                    }
460
                }
461

462
                case 0x01:
463
                case 0x02:
464
                case 0x03:
465
                case 0x04:
466
                case 0x05:
467
                case 0x06:
468
                case 0x07:
469
                case 0x08:
470
                case 0x09:
471
                case 0x0a:
472
                case 0x0b:
473
                case 0x0c:
474
                case 0x0d:
475
                case 0x0e:
476
                case 0x0f:
477

478
                case 0x10:
479
                case 0x11:
480
                case 0x12:
481
                case 0x13:
482
                case 0x14:
483
                case 0x15:
484
                case 0x16:
485
                case 0x17:
486
                case 0x18:
487
                case 0x19:
488
                case 0x1a:
489
                case 0x1b:
490
                case 0x1c:
491
                case 0x1d:
492
                case 0x1e:
493
                case 0x1f:
494
                    return new StringState(this, 'S', ch);
9✔
495

496
                case 0x30:
497
                case 0x31:
498
                case 0x32:
499
                case 0x33:
500
                    return new StringState(this, 'S', ch - 0x30, true);
12✔
501

502
                case 'R':
503
                    return new StringState(this, 'S', false);
9✔
504

505
                case 'S':
506
                    return new StringState(this, 'S', true);
9✔
507

508
                case 0x20: {
509
                    String value = "binary(0)";
2✔
510

511
                    if (isShift(value)) {
4!
512
                        return shift(value);
×
513
                    } else {
514
                        printObject(value);
3✔
515
                        return this;
2✔
516
                    }
517
                }
518

519
                case 0x21:
520
                case 0x22:
521
                case 0x23:
522
                case 0x24:
523
                case 0x25:
524
                case 0x26:
525
                case 0x27:
526
                case 0x28:
527
                case 0x29:
528
                case 0x2a:
529
                case 0x2b:
530
                case 0x2c:
531
                case 0x2d:
532
                case 0x2e:
533
                case 0x2f:
534
                    return new BinaryState(this, 'B', ch - 0x20);
11✔
535

536
                case 0x34:
537
                case 0x35:
538
                case 0x36:
539
                case 0x37:
540
                    return new BinaryState(this, 'B', ch - 0x34, true);
12✔
541

542
                case 'A':
543
                    return new BinaryState(this, 'B', false);
9✔
544

545
                case 'B':
546
                    return new BinaryState(this, 'B', true);
9✔
547

548
                case 'M':
549
                    return new MapState(this, refId++);
15✔
550

551
                case 'H':
552
                    return new MapState(this, refId++, false);
16✔
553

554
                case BC_LIST_VARIABLE:
555
                    return new ListState(this, refId++, true);
16✔
556

557
                case BC_LIST_VARIABLE_UNTYPED:
558
                    return new ListState(this, refId++, false);
16✔
559

560
                case BC_LIST_FIXED:
561
                    return new CompactListState(this, refId++, true);
16✔
562

563
                case BC_LIST_FIXED_UNTYPED:
564
                    return new CompactListState(this, refId++, false);
16✔
565

566
                case 0x70:
567
                case 0x71:
568
                case 0x72:
569
                case 0x73:
570
                case 0x74:
571
                case 0x75:
572
                case 0x76:
573
                case 0x77:
574
                    return new CompactListState(this, refId++, true, ch - 0x70);
19✔
575

576
                case 0x78:
577
                case 0x79:
578
                case 0x7a:
579
                case 0x7b:
580
                case 0x7c:
581
                case 0x7d:
582
                case 0x7e:
583
                case 0x7f:
584
                    return new CompactListState(this, refId++, false, ch - 0x78);
19✔
585

586
                case 'C':
587
                    return new ObjectDefState(this);
7✔
588

589
                case 0x60:
590
                case 0x61:
591
                case 0x62:
592
                case 0x63:
593
                case 0x64:
594
                case 0x65:
595
                case 0x66:
596
                case 0x67:
597
                case 0x68:
598
                case 0x69:
599
                case 0x6a:
600
                case 0x6b:
601
                case 0x6c:
602
                case 0x6d:
603
                case 0x6e:
604
                case 0x6f:
605
                    return new ObjectState(this, refId++, ch - 0x60);
18✔
606

607
                case 'O':
608
                    return new ObjectState(this, refId++);
15✔
609

610
                default:
611
                    return this;
×
612
            }
613
        }
614
    }
615

616
    class InitialState extends State {
7✔
617
        @Override
618
        State next(int ch) {
619
            return nextObject(ch);
4✔
620
        }
621
    }
622

623
    class Top2State extends State {
7✔
624
        @Override
625
        State next(int ch) {
626
            super.println();
2✔
627

628
            if (ch == 'R') {
3✔
629
                return new Reply2State(this);
7✔
630
            } else if (ch == 'C') {
3✔
631
                return new Call2State(this);
7✔
632
            } else if (ch == 'H') {
3✔
633
                return new Hessian2State(this);
7✔
634
            } else if (ch == 'r') {
3✔
635
                throw new IllegalStateException("unexpected 'r' in top2 state");
5✔
636
            } else if (ch == 'c') {
3✔
637
                throw new IllegalStateException("unexpected 'c' in top2 state");
5✔
638
            } else {
639
                return nextObject(ch);
4✔
640
            }
641
        }
642
    }
643

644
    class IntegerState extends State {
645
        String typeCode;
646

647
        int length;
648
        int value;
649

650
        IntegerState(State next, String typeCode) {
3✔
651
            super(next);
4✔
652

653
            this.typeCode = typeCode;
3✔
654
        }
1✔
655

656
        IntegerState(State next, String typeCode, int value, int length) {
3✔
657
            super(next);
4✔
658

659
            this.typeCode = typeCode;
3✔
660

661
            this.value = value;
3✔
662
            this.length = length;
3✔
663
        }
1✔
664

665
        @Override
666
        State next(int ch) {
667
            value = 256 * value + (ch & 0xff);
10✔
668

669
            if (++length == 4) {
9✔
670

671
                if (next.isShift(value)) {
7✔
672
                    return next.shift(value);
7✔
673
                } else {
674
                    printObject(String.valueOf(value));
5✔
675

676
                    return next;
3✔
677
                }
678
            } else {
679
                return this;
2✔
680
            }
681
        }
682
    }
683

684
    class LongState extends State {
685
        String typeCode;
686

687
        int length;
688
        long value;
689

690
        LongState(State next, String typeCode) {
3✔
691
            super(next);
4✔
692

693
            this.typeCode = typeCode;
3✔
694
        }
1✔
695

696
        LongState(State next, String typeCode, long value, int length) {
3✔
697
            super(next);
4✔
698

699
            this.typeCode = typeCode;
3✔
700

701
            this.value = value;
3✔
702
            this.length = length;
3✔
703
        }
1✔
704

705
        @Override
706
        State next(int ch) {
707
            value = 256 * value + (ch & 0xff);
11✔
708

709
            if (++length == 8) {
9✔
710

711
                if (next.isShift(value)) {
7!
712
                    return next.shift(value);
×
713
                } else {
714
                    printObject(value + "L");
5✔
715

716
                    return next;
3✔
717
                }
718
            } else {
719
                return this;
2✔
720
            }
721
        }
722
    }
723

724
    class DoubleIntegerState extends State {
725
        int length;
726
        int value;
727
        boolean isFirst = true;
3✔
728

729
        DoubleIntegerState(State next, int length) {
3✔
730
            super(next);
4✔
731

732
            this.length = length;
3✔
733
        }
1✔
734

735
        @Override
736
        State next(int ch) {
737
            if (isFirst) {
3✔
738
                value = (byte) ch;
5✔
739
            } else {
740
                value = 256 * value + (ch & 0xff);
10✔
741
            }
742

743
            isFirst = false;
3✔
744

745
            if (++length == 4) {
9✔
746

747
                if (next.isShift(value)) {
7!
748
                    return next.shift(value);
×
749
                } else {
750
                    printObject(String.valueOf(value));
5✔
751

752
                    return next;
3✔
753
                }
754
            } else {
755
                return this;
2✔
756
            }
757
        }
758
    }
759

760
    class RefState extends State {
761

762
        RefState(State next) {
3✔
763
            super(next);
4✔
764
        }
1✔
765

766
        @Override
767
        boolean isShift(Object o) {
768
            return true;
2✔
769
        }
770

771
        @Override
772
        State shift(Object o) {
773
            super.println("ref #" + o);
5✔
774

775
            return next;
3✔
776
        }
777

778
        @Override
779
        State next(int ch) {
780
            return nextObject(ch);
4✔
781
        }
782
    }
783

784
    class DateState extends State {
785
        int length;
786
        long value;
787
        boolean isMinute;
788

789
        DateState(State next) {
3✔
790
            super(next);
4✔
791
        }
1✔
792

793
        DateState(State next, boolean isMinute) {
3✔
794
            super(next);
4✔
795

796
            length = 4;
3✔
797
            this.isMinute = isMinute;
3✔
798
        }
1✔
799

800
        @Override
801
        State next(int ch) {
802
            value = 256 * value + (ch & 0xff);
11✔
803

804
            if (++length == 8) {
9✔
805
                java.util.Date d;
806

807
                if (isMinute) {
3✔
808
                    d = new java.util.Date(this.value * 60000L);
9✔
809
                } else {
810
                    d = new java.util.Date(this.value);
6✔
811
                }
812

813
                if (next.isShift(d)) {
5!
814
                    return next.shift(d);
×
815
                } else {
816
                    printObject(d.toString());
4✔
817

818
                    return next;
3✔
819
                }
820
            } else {
821
                return this;
2✔
822
            }
823
        }
824
    }
825

826
    class DoubleState extends State {
827
        int length;
828
        long value;
829

830
        DoubleState(State next) {
3✔
831
            super(next);
4✔
832
        }
1✔
833

834
        @Override
835
        State next(int ch) {
836
            value = 256 * value + (ch & 0xff);
11✔
837

838
            if (++length == 8) {
9✔
839
                Double v = Double.longBitsToDouble(this.value);
5✔
840

841
                if (next.isShift(v)) {
5!
842
                    return next.shift(v);
×
843
                } else {
844
                    printObject(v.toString());
4✔
845

846
                    return next;
3✔
847
                }
848
            } else {
849
                return this;
2✔
850
            }
851
        }
852
    }
853

854
    class MillsState extends State {
855
        int length;
856
        int value;
857

858
        MillsState(State next) {
3✔
859
            super(next);
4✔
860
        }
1✔
861

862
        @Override
863
        State next(int ch) {
864
            value = 256 * value + (ch & 0xff);
10✔
865

866
            if (++length == 4) {
9✔
867
                Double v = 0.001 * this.value;
7✔
868

869
                if (next.isShift(v)) {
5!
870
                    return next.shift(v);
×
871
                } else {
872
                    printObject(v.toString());
4✔
873

874
                    return next;
3✔
875
                }
876
            } else {
877
                return this;
2✔
878
            }
879
        }
880
    }
881

882
    class StringState extends State {
883
        private static final int TOP = 0;
884
        private static final int UTF_2_1 = 1;
885
        private static final int UTF_3_1 = 2;
886
        private static final int UTF_3_2 = 3;
887

888
        char typeCode;
889

890
        StringBuilder value = new StringBuilder();
15✔
891
        int lengthIndex;
892
        int length;
893
        boolean isLastChunk;
894

895
        int utfState;
896
        char ch;
897

898
        StringState(State next, char typeCode, boolean isLastChunk) {
3✔
899
            super(next);
4✔
900

901
            this.typeCode = typeCode;
3✔
902
            this.isLastChunk = isLastChunk;
3✔
903
        }
1✔
904

905
        StringState(State next, char typeCode, int length) {
3✔
906
            super(next);
4✔
907

908
            this.typeCode = typeCode;
3✔
909
            isLastChunk = true;
3✔
910
            this.length = length;
3✔
911
            lengthIndex = 2;
3✔
912
        }
1✔
913

914
        StringState(State next, char typeCode, int length, boolean isLastChunk) {
3✔
915
            super(next);
4✔
916

917
            this.typeCode = typeCode;
3✔
918
            this.isLastChunk = isLastChunk;
3✔
919
            this.length = length;
3✔
920
            lengthIndex = 1;
3✔
921
        }
1✔
922

923
        @Override
924
        State next(int ch) {
925
            if (lengthIndex < 2) {
4✔
926
                length = 256 * length + (ch & 0xff);
10✔
927

928
                if (++lengthIndex == 2 && length == 0 && isLastChunk) {
12!
929
                    if (next.isShift(value.toString())) {
×
930
                        return next.shift(value.toString());
×
931
                    } else {
932
                        printObject("\"" + value + "\"");
×
933
                        return next;
×
934
                    }
935
                } else {
936
                    return this;
2✔
937
                }
938
            } else if (length == 0) {
3✔
939
                if (ch == 's' || ch == 'x') {
6!
940
                    isLastChunk = false;
×
941
                    lengthIndex = 0;
×
942
                    return this;
×
943
                } else if (ch == 'S' || ch == 'X') {
3!
944
                    isLastChunk = true;
3✔
945
                    lengthIndex = 0;
3✔
946
                    return this;
2✔
947
                } else if (ch == 0x00) {
×
948
                    if (next.isShift(value.toString())) {
×
949
                        return next.shift(value.toString());
×
950
                    } else {
951
                        printObject("\"" + value + "\"");
×
952
                        return next;
×
953
                    }
954
                } else if (0x00 <= ch && ch < 0x20) {
×
955
                    isLastChunk = true;
×
956
                    lengthIndex = 2;
×
957
                    length = ch & 0xff;
×
958
                    return this;
×
959
                } else if (0x30 <= ch && ch < 0x34) {
×
960
                    isLastChunk = true;
×
961
                    lengthIndex = 1;
×
962
                    length = (ch - 0x30);
×
963
                    return this;
×
964
                } else {
965
                    super.println(this + " " + (char) ch + ": unexpected character");
×
966
                    return next;
×
967
                }
968
            }
969

970
            switch (utfState) {
3!
971
                case TOP:
972
                    if (ch < 0x80) {
3✔
973
                        length--;
6✔
974

975
                        value.append((char) ch);
7✔
976
                    } else if (ch < 0xe0) {
3✔
977
                        this.ch = (char) ((ch & 0x1f) << 6);
8✔
978
                        utfState = UTF_2_1;
4✔
979
                    } else {
980
                        this.ch = (char) ((ch & 0xf) << 12);
8✔
981
                        utfState = UTF_3_1;
3✔
982
                    }
983
                    break;
1✔
984

985
                case UTF_2_1:
986
                case UTF_3_2:
987
                    this.ch += ch & 0x3f;
9✔
988
                    value.append(this.ch);
6✔
989
                    length--;
6✔
990
                    utfState = TOP;
3✔
991
                    break;
1✔
992

993
                case UTF_3_1:
994
                    this.ch += (char) ((ch & 0x3f) << 6);
12✔
995
                    utfState = UTF_3_2;
3✔
996
                    break;
1✔
997
                default:
998
                    break;
999
            }
1000

1001
            if (length == 0 && isLastChunk) {
6✔
1002
                if (next.isShift(value.toString())) {
7✔
1003
                    return next.shift(value.toString());
7✔
1004
                } else {
1005
                    printObject("\"" + value + "\"");
6✔
1006

1007
                    return next;
3✔
1008
                }
1009
            } else {
1010
                return this;
2✔
1011
            }
1012
        }
1013
    }
1014

1015
    class BinaryState extends State {
1016
        char typeCode;
1017

1018
        int totalLength;
1019

1020
        int lengthIndex;
1021
        int length;
1022
        boolean isLastChunk;
1023

1024
        BinaryState(State next, char typeCode, boolean isLastChunk) {
3✔
1025
            super(next);
4✔
1026

1027
            this.typeCode = typeCode;
3✔
1028
            this.isLastChunk = isLastChunk;
3✔
1029
        }
1✔
1030

1031
        BinaryState(State next, char typeCode, int length) {
3✔
1032
            super(next);
4✔
1033

1034
            this.typeCode = typeCode;
3✔
1035
            isLastChunk = true;
3✔
1036
            this.length = length;
3✔
1037
            lengthIndex = 2;
3✔
1038
        }
1✔
1039

1040
        BinaryState(State next, char typeCode, int length, boolean isLastChunk) {
3✔
1041
            super(next);
4✔
1042

1043
            this.typeCode = typeCode;
3✔
1044
            this.isLastChunk = isLastChunk;
3✔
1045
            this.length = length;
3✔
1046
            lengthIndex = 1;
3✔
1047
        }
1✔
1048

1049
        @Override
1050
        State next(int ch) {
1051
            if (lengthIndex < 2) {
4✔
1052
                length = 256 * length + (ch & 0xff);
10✔
1053

1054
                if (++lengthIndex == 2 && length == 0 && isLastChunk) {
12!
1055
                    String value = getBinaryValue();
×
1056

1057
                    if (next.isShift(value)) {
×
1058
                        return next.shift(value);
×
1059
                    } else {
1060
                        printObject(value);
×
1061
                        return next;
×
1062
                    }
1063
                } else {
1064
                    return this;
2✔
1065
                }
1066
            } else if (length == 0) {
3✔
1067
                if (ch == 'b' || ch == 'A') {
6!
1068
                    isLastChunk = false;
3✔
1069
                    lengthIndex = 0;
3✔
1070
                    return this;
2✔
1071
                } else if (ch == 'B') {
3✔
1072
                    isLastChunk = true;
3✔
1073
                    lengthIndex = 0;
3✔
1074
                    return this;
2✔
1075
                } else if (ch == 0x20) {
3!
1076
                    String value = getBinaryValue();
3✔
1077

1078
                    if (next.isShift(value)) {
5!
1079
                        return next.shift(value);
×
1080
                    } else {
1081
                        printObject(value);
3✔
1082
                        return next;
3✔
1083
                    }
1084
                } else if (0x20 <= ch && ch < 0x30) {
×
1085
                    isLastChunk = true;
×
1086
                    lengthIndex = 2;
×
1087
                    length = (ch & 0xff) - 0x20;
×
1088
                    return this;
×
1089
                } else {
1090
                    super.println(this + " 0x" + Integer.toHexString(ch) + " " + (char) ch + ": unexpected character");
×
1091
                    return next;
×
1092
                }
1093
            }
1094

1095
            length--;
6✔
1096
            totalLength++;
6✔
1097

1098
            if (length == 0 && isLastChunk) {
6✔
1099
                String value = getBinaryValue();
3✔
1100

1101
                if (next.isShift(value)) {
5!
1102
                    return next.shift(value);
×
1103
                } else {
1104
                    printObject(value);
3✔
1105

1106
                    return next;
3✔
1107
                }
1108
            } else {
1109
                return this;
2✔
1110
            }
1111
        }
1112

1113
        private String getBinaryValue() {
1114
            return "binary(" + totalLength + ")";
4✔
1115
        }
1116
    }
1117

1118
    class MapState extends State {
1119
        private static final int TYPE = 0;
1120
        private static final int KEY = 1;
1121
        private static final int VALUE = 2;
1122

1123
        private final int refId;
1124

1125
        private int state;
1126
        private int valueDepth;
1127
        private boolean hasData;
1128

1129
        MapState(State next, int refId) {
3✔
1130
            super(next);
4✔
1131

1132
            this.refId = refId;
3✔
1133
            state = TYPE;
3✔
1134
        }
1✔
1135

1136
        MapState(State next, int refId, boolean isType) {
3✔
1137
            super(next);
4✔
1138

1139
            this.refId = refId;
3✔
1140

1141
            if (isType) state = TYPE;
2!
1142
            else {
1143
                printObject("map (#" + this.refId + ")");
5✔
1144
                state = VALUE;
3✔
1145
            }
1146
        }
1✔
1147

1148
        @Override
1149
        boolean isShift(Object value) {
1150
            return state == TYPE;
7✔
1151
        }
1152

1153
        @Override
1154
        State shift(Object type) {
1155
            if (state == TYPE) {
3!
1156
                if (type instanceof String) {
3!
1157
                    typeDefList.add((String) type);
8✔
1158
                } else if (type instanceof Integer) {
×
1159
                    int iValue = (Integer) type;
×
1160

1161
                    if (iValue >= 0 && iValue < typeDefList.size()) type = typeDefList.get(iValue);
×
1162
                }
1163

1164
                printObject("map " + type + " (#" + refId + ")");
7✔
1165

1166
                state = VALUE;
3✔
1167

1168
                return this;
2✔
1169
            } else {
1170
                printObject(this + " unknown shift state= " + state + " type=" + type);
×
1171

1172
                return this;
×
1173
            }
1174
        }
1175

1176
        @Override
1177
        int depth() {
1178
            if (state == TYPE) {
3✔
1179
                return next.depth();
4✔
1180
            } else if (state == KEY) {
4✔
1181
                return next.depth() + 2;
6✔
1182
            } else {
1183
                return valueDepth;
3✔
1184
            }
1185
        }
1186

1187
        @Override
1188
        State next(int ch) {
1189
            switch (state) {
3!
1190
                case TYPE:
1191
                    return nextObject(ch);
4✔
1192

1193
                case VALUE:
1194
                    if (ch == 'Z') {
3✔
1195
                        if (hasData) {
3✔
1196
                            super.println();
2✔
1197
                        }
1198

1199
                        return next;
3✔
1200
                    } else {
1201
                        if (hasData) {
3✔
1202
                            super.println();
2✔
1203
                        }
1204

1205
                        hasData = true;
3✔
1206
                        state = KEY;
3✔
1207

1208
                        return nextObject(ch);
4✔
1209
                    }
1210

1211
                case KEY:
1212
                    print(" => ");
3✔
1213
                    isObject = false;
4✔
1214
                    valueDepth = column;
5✔
1215

1216
                    state = VALUE;
3✔
1217

1218
                    return nextObject(ch);
4✔
1219

1220
                default:
1221
                    throw new IllegalStateException();
×
1222
            }
1223
        }
1224
    }
1225

1226
    class ObjectDefState extends State {
1227
        private static final int STATE_TYPE = 1;
1228
        private static final int STATE_COUNT = 2;
1229
        private static final int STATE_FIELD = 3;
1230

1231
        private int state;
1232
        private int count;
1233

1234
        private final List<String> fields = new ArrayList<>();
5✔
1235

1236
        ObjectDefState(State next) {
3✔
1237
            super(next);
4✔
1238

1239
            state = STATE_TYPE;
3✔
1240
        }
1✔
1241

1242
        @Override
1243
        boolean isShift(Object value) {
1244
            return true;
2✔
1245
        }
1246

1247
        @Override
1248
        State shift(Object object) {
1249
            if (state == STATE_TYPE) {
4✔
1250
                String type = (String) object;
3✔
1251

1252
                print("/* defun " + type + " [");
4✔
1253

1254
                objectDefList.add(new ObjectDef(type, fields));
11✔
1255

1256
                state = STATE_COUNT;
3✔
1257
            } else if (state == STATE_COUNT) {
5✔
1258
                count = (Integer) object;
5✔
1259

1260
                state = STATE_FIELD;
4✔
1261
            } else if (state == STATE_FIELD) {
4!
1262
                String field = (String) object;
3✔
1263

1264
                count--;
6✔
1265

1266
                fields.add(field);
5✔
1267

1268
                if (fields.size() == 1) {
5✔
1269
                    print(field);
4✔
1270
                } else {
1271
                    print(", " + field);
4✔
1272
                }
1273
            } else {
1✔
1274
                throw new UnsupportedOperationException();
×
1275
            }
1276

1277
            return this;
2✔
1278
        }
1279

1280
        @Override
1281
        int depth() {
1282
            if (state <= STATE_TYPE) {
4!
1283
                return next.depth();
4✔
1284
            } else {
1285
                return next.depth() + 2;
×
1286
            }
1287
        }
1288

1289
        @Override
1290
        State next(int ch) {
1291
            switch (state) {
3!
1292
                case STATE_TYPE:
1293

1294
                case STATE_COUNT:
1295
                    return nextObject(ch);
4✔
1296

1297
                case STATE_FIELD:
1298
                    if (count == 0) {
3✔
1299
                        super.println("] */");
3✔
1300
                        next.printIndent(0);
4✔
1301

1302
                        return next.nextObject(ch);
5✔
1303
                    } else {
1304
                        return nextObject(ch);
4✔
1305
                    }
1306

1307
                default:
1308
                    throw new IllegalStateException();
×
1309
            }
1310
        }
1311
    }
1312

1313
    class ObjectState extends State {
1314
        private static final int TYPE = 0;
1315
        private static final int FIELD = 1;
1316

1317
        private final int refId;
1318

1319
        private int state;
1320
        private ObjectDef def;
1321
        private int count;
1322
        private int fieldDepth;
1323

1324
        ObjectState(State next, int refId) {
3✔
1325
            super(next);
4✔
1326

1327
            this.refId = refId;
3✔
1328
            state = TYPE;
3✔
1329
        }
1✔
1330

1331
        ObjectState(State next, int refId, int def) {
3✔
1332
            super(next);
4✔
1333

1334
            this.refId = refId;
3✔
1335
            state = FIELD;
3✔
1336

1337
            if (def < 0 || objectDefList.size() <= def) {
7!
1338
                log.warn("{} {} is an unknown object type", this, def);
6✔
1339

1340
                super.println(this + " object unknown  (#" + this.refId + ")");
7✔
1341
                return;
1✔
1342
            }
1343

1344
            this.def = objectDefList.get(def);
7✔
1345

1346
            if (isObject) {
3✔
1347
                super.println();
2✔
1348
            }
1349

1350
            super.println("object " + this.def.getType() + " (#" + this.refId + ")");
8✔
1351
        }
1✔
1352

1353
        @Override
1354
        boolean isShift(Object value) {
1355
            return state == TYPE;
7✔
1356
        }
1357

1358
        @Override
1359
        State shift(Object object) {
1360
            if (state == TYPE) {
3!
1361

1362
                this.def = objectDefList.get((Integer) object);
10✔
1363

1364
                super.println("object " + this.def.getType() + " (#" + refId + ")");
8✔
1365

1366
                state = FIELD;
3✔
1367

1368
                if (this.def.getFields().isEmpty()) {
5!
1369
                    return next;
3✔
1370
                }
1371
            }
1372

1373
            return this;
×
1374
        }
1375

1376
        @Override
1377
        int depth() {
1378
            if (state <= TYPE) {
3✔
1379
                return next.depth();
4✔
1380
            } else {
1381
                return fieldDepth;
3✔
1382
            }
1383
        }
1384

1385
        @Override
1386
        State next(int ch) {
1387
            switch (state) {
3!
1388
                case TYPE:
1389
                    return nextObject(ch);
4✔
1390

1391
                case FIELD:
1392
                    if (def == null || def.getFields().size() <= count) {
10✔
1393
                        return next.next(ch);
5✔
1394
                    }
1395

1396
                    fieldDepth = next.depth() + 2;
7✔
1397
                    super.println();
2✔
1398
                    print(def.getFields().get(count++) + ": ");
15✔
1399

1400
                    fieldDepth = column;
5✔
1401

1402
                    isObject = false;
4✔
1403
                    return nextObject(ch);
4✔
1404

1405
                default:
1406
                    throw new IllegalStateException();
×
1407
            }
1408
        }
1409
    }
1410

1411
    class ListState extends State {
1412
        private static final int TYPE = 0;
1413
        private static final int LENGTH = 1;
1414
        private static final int VALUE = 2;
1415

1416
        private final int refId;
1417

1418
        private int state;
1419
        private int count;
1420
        private int valueDepth;
1421

1422
        ListState(State next, int refId, boolean isType) {
3✔
1423
            super(next);
4✔
1424

1425
            this.refId = refId;
3✔
1426

1427
            if (isType) {
2✔
1428
                state = TYPE;
4✔
1429
            } else {
1430
                printObject("list (#" + this.refId + ")");
5✔
1431
                state = VALUE;
3✔
1432
            }
1433
        }
1✔
1434

1435
        @Override
1436
        boolean isShift(Object value) {
1437
            return state == TYPE || state == LENGTH;
11!
1438
        }
1439

1440
        @Override
1441
        State shift(Object object) {
1442
            if (state == TYPE) {
3!
1443
                Object type = object;
2✔
1444

1445
                if (type instanceof String) {
3!
1446
                    typeDefList.add((String) type);
8✔
1447
                } else if (object instanceof Integer) {
×
1448
                    int index = (Integer) object;
×
1449

1450
                    if (index >= 0 && index < typeDefList.size()) {
×
1451
                        type = typeDefList.get(index);
×
1452
                    } else {
1453
                        type = "type-unknown(" + index + ")";
×
1454
                    }
1455
                }
1456

1457
                printObject("list " + type + "(#" + refId + ")");
7✔
1458

1459
                state = VALUE;
3✔
1460

1461
                return this;
2✔
1462
            } else if (state == LENGTH) {
×
1463
                state = VALUE;
×
1464

1465
                return this;
×
1466
            } else {
1467
                return this;
×
1468
            }
1469
        }
1470

1471
        @Override
1472
        int depth() {
1473
            if (state <= LENGTH) {
4✔
1474
                return next.depth();
4✔
1475
            } else if (state == VALUE) {
4!
1476
                return valueDepth;
3✔
1477
            } else {
1478
                return next.depth() + 2;
×
1479
            }
1480
        }
1481

1482
        @Override
1483
        State next(int ch) {
1484
            switch (state) {
3!
1485
                case TYPE:
1486
                    return nextObject(ch);
4✔
1487

1488
                case VALUE:
1489
                    if (ch == 'Z') {
3✔
1490
                        if (count > 0) {
3!
1491
                            super.println();
2✔
1492
                        }
1493

1494
                        return next;
3✔
1495
                    } else {
1496
                        valueDepth = next.depth() + 2;
7✔
1497
                        super.println();
2✔
1498
                        printObject(count++ + ": ");
10✔
1499
                        valueDepth = column;
5✔
1500
                        isObject = false;
4✔
1501

1502
                        return nextObject(ch);
4✔
1503
                    }
1504

1505
                default:
1506
                    throw new IllegalStateException();
×
1507
            }
1508
        }
1509
    }
1510

1511
    class CompactListState extends State {
1512
        private static final int STATE_TYPE = 0;
1513
        private static final int STATE_LENGTH = 1;
1514
        private static final int STATE_VALUE = 2;
1515

1516
        private final int refId;
1517

1518
        private final boolean isTyped;
1519
        private boolean isLength;
1520

1521
        private int state;
1522
        private int length;
1523
        private int count;
1524
        private int valueDepth;
1525

1526
        CompactListState(State next, int refId, boolean isTyped) {
3✔
1527
            super(next);
4✔
1528

1529
            this.isTyped = isTyped;
3✔
1530
            this.refId = refId;
3✔
1531

1532
            if (isTyped) {
2✔
1533
                state = STATE_TYPE;
4✔
1534
            } else {
1535
                state = STATE_LENGTH;
3✔
1536
            }
1537
        }
1✔
1538

1539
        CompactListState(State next, int refId, boolean isTyped, int length) {
3✔
1540
            super(next);
4✔
1541

1542
            this.isTyped = isTyped;
3✔
1543
            this.refId = refId;
3✔
1544
            this.length = length;
3✔
1545

1546
            isLength = true;
3✔
1547

1548
            if (isTyped) {
2✔
1549
                state = STATE_TYPE;
4✔
1550
            } else {
1551
                printObject("list (#" + this.refId + ")");
5✔
1552

1553
                state = STATE_VALUE;
3✔
1554
            }
1555
        }
1✔
1556

1557
        @Override
1558
        boolean isShift(Object value) {
1559
            return state == STATE_TYPE || state == STATE_LENGTH;
11✔
1560
        }
1561

1562
        @Override
1563
        State shift(Object object) {
1564
            if (state == STATE_TYPE) {
3✔
1565
                Object type = object;
2✔
1566

1567
                if (object instanceof Integer) {
3✔
1568
                    int index = (Integer) object;
4✔
1569

1570
                    if (index >= 0 && index < typeDefList.size()) {
8!
1571
                        type = typeDefList.get(index);
7✔
1572
                    } else {
1573
                        type = "type-unknown(" + index + ")";
×
1574
                    }
1575
                } else if (object instanceof String) {
4!
1576
                    typeDefList.add((String) object);
7✔
1577
                }
1578

1579
                printObject("list " + type + " (#" + refId + ")");
7✔
1580

1581
                if (isLength) {
3✔
1582
                    state = STATE_VALUE;
3✔
1583

1584
                    if (length == 0) {
3✔
1585
                        return next;
3✔
1586
                    }
1587
                } else {
1588
                    state = STATE_LENGTH;
3✔
1589
                }
1590

1591
                return this;
2✔
1592
            } else if (state == STATE_LENGTH) {
4!
1593
                length = (Integer) object;
5✔
1594

1595
                if (!isTyped) {
3✔
1596
                    printObject("list (#" + refId + ")");
5✔
1597
                }
1598

1599
                state = STATE_VALUE;
3✔
1600

1601
                if (length == 0) {
3!
1602
                    return next;
×
1603
                } else {
1604
                    return this;
2✔
1605
                }
1606
            } else {
1607
                return this;
×
1608
            }
1609
        }
1610

1611
        @Override
1612
        int depth() {
1613
            if (state <= STATE_LENGTH) {
4✔
1614
                return next.depth();
4✔
1615
            } else if (state == STATE_VALUE) {
4!
1616
                return valueDepth;
3✔
1617
            } else {
1618
                return next.depth() + 2;
×
1619
            }
1620
        }
1621

1622
        @Override
1623
        State next(int ch) {
1624
            switch (state) {
3!
1625
                case STATE_TYPE:
1626

1627
                case STATE_LENGTH:
1628
                    return nextObject(ch);
4✔
1629

1630
                case STATE_VALUE:
1631
                    if (length <= count) {
5✔
1632
                        return next.next(ch);
5✔
1633
                    } else {
1634
                        valueDepth = next.depth() + 2;
7✔
1635
                        super.println();
2✔
1636
                        printObject(count++ + ": ");
10✔
1637
                        valueDepth = column;
5✔
1638
                        isObject = false;
4✔
1639

1640
                        return nextObject(ch);
4✔
1641
                    }
1642

1643
                default:
1644
                    throw new IllegalStateException();
×
1645
            }
1646
        }
1647
    }
1648

1649
    class Hessian2State extends State {
1650
        private static final int STATE_MAJOR = 0;
1651
        private static final int STATE_MINOR = 1;
1652

1653
        private int state;
1654
        private int major;
1655
        private int minor;
1656

1657
        Hessian2State(State next) {
3✔
1658
            super(next);
4✔
1659
        }
1✔
1660

1661
        @Override
1662
        int depth() {
1663
            return next.depth() + 2;
6✔
1664
        }
1665

1666
        @Override
1667
        State next(int ch) {
1668
            switch (state) {
3!
1669
                case STATE_MAJOR:
1670
                    major = ch;
3✔
1671
                    state = STATE_MINOR;
3✔
1672
                    return this;
2✔
1673

1674
                case STATE_MINOR:
1675
                    minor = ch;
3✔
1676
                    super.println(-2, "Hessian " + major + "." + minor);
8✔
1677
                    return next;
3✔
1678

1679
                default:
1680
                    throw new IllegalStateException();
×
1681
            }
1682
        }
1683
    }
1684

1685
    class Call2State extends State {
1686
        private static final int STATE_METHOD = 0;
1687
        private static final int STATE_COUNT = 1;
1688
        private static final int STATE_ARG = 2;
1689

1690
        private int state = STATE_METHOD;
3✔
1691
        private int i;
1692
        private int count;
1693

1694
        Call2State(State next) {
3✔
1695
            super(next);
4✔
1696
        }
1✔
1697

1698
        @Override
1699
        int depth() {
1700
            return next.depth() + 5;
6✔
1701
        }
1702

1703
        @Override
1704
        boolean isShift(Object value) {
1705
            return state != STATE_ARG;
8✔
1706
        }
1707

1708
        @Override
1709
        State shift(Object object) {
1710
            if (state == STATE_METHOD) {
3✔
1711
                super.println(-5, "Call " + object);
6✔
1712

1713
                state = STATE_COUNT;
3✔
1714
                return this;
2✔
1715
            } else if (state == STATE_COUNT) {
4!
1716

1717
                this.count = (Integer) object;
5✔
1718

1719
                state = STATE_ARG;
3✔
1720

1721
                if (this.count == 0) {
3✔
1722
                    return next;
3✔
1723
                } else {
1724
                    return this;
2✔
1725
                }
1726
            } else {
1727
                return this;
×
1728
            }
1729
        }
1730

1731
        @Override
1732
        State next(int ch) {
1733
            switch (state) {
3!
1734
                case STATE_COUNT:
1735

1736
                case STATE_METHOD:
1737
                    return nextObject(ch);
4✔
1738

1739
                case STATE_ARG:
1740
                    if (count <= i) {
5✔
1741
                        super.println();
2✔
1742
                        return next.next(ch);
5✔
1743
                    } else {
1744
                        super.println();
2✔
1745
                        print(-3, i++ + ": ");
11✔
1746

1747
                        return nextObject(ch);
4✔
1748
                    }
1749

1750
                default:
1751
                    throw new IllegalStateException();
×
1752
            }
1753
        }
1754
    }
1755

1756
    class Reply2State extends State {
1757
        Reply2State(State next) {
3✔
1758
            super(next);
4✔
1759

1760
            super.println(-2, "Reply");
4✔
1761
        }
1✔
1762

1763
        @Override
1764
        int depth() {
1765
            return next.depth() + 2;
6✔
1766
        }
1767

1768
        @Override
1769
        State next(int ch) {
1770
            if (ch < 0) {
2✔
1771
                super.println();
2✔
1772
                return next;
3✔
1773
            } else {
1774
                return nextObject(ch);
4✔
1775
            }
1776
        }
1777
    }
1778

1779
    class StreamingState extends State {
1780
        private long length;
1781
        private int metaLength;
1782
        private boolean isLast;
1783
        private boolean isFirst = true;
3✔
1784

1785
        private boolean isLengthState;
1786

1787
        private State childState;
1788

1789
        StreamingState(State next, boolean isLast) {
3✔
1790
            super(next);
4✔
1791

1792
            this.isLast = isLast;
3✔
1793
            childState = new InitialState();
6✔
1794
        }
1✔
1795

1796
        @Override
1797
        State next(int ch) {
1798
            if (metaLength > 0) {
3!
1799
                length = 256 * length + ch;
×
1800
                metaLength--;
×
1801

1802
                if (metaLength == 0 && isFirst) {
×
1803
                    if (isLast) {
×
1804
                        super.println(-1, "--- packet-start(" + length + ")");
×
1805
                    } else {
1806
                        super.println(-1, "--- packet-start(fragment)");
×
1807
                    }
1808
                    isFirst = false;
×
1809
                }
1810

1811
                return this;
×
1812
            }
1813

1814
            if (length > 0) {
5✔
1815
                length--;
6✔
1816
                childState = childState.next(ch);
6✔
1817

1818
                return this;
2✔
1819
            }
1820

1821
            if (!isLengthState) {
3✔
1822
                isLengthState = true;
3✔
1823

1824
                if (isLast) {
3!
1825
                    super.println(-1, "");
×
1826
                    super.println(-1, "--- packet-end");
×
1827
                    refId = 0;
×
1828

1829
                    isFirst = true;
×
1830
                }
1831

1832
                isLast = (ch & 0x80) == 0x00;
8!
1833
                isLengthState = true;
4✔
1834
            } else {
1835
                isLengthState = false;
3✔
1836
                length = (ch & 0x7f);
6✔
1837

1838
                if (length == 0x7e) {
5!
1839
                    length = 0;
×
1840
                    metaLength = 2;
×
1841
                } else if (length == 0x7f) {
5!
1842
                    length = 0;
×
1843
                    metaLength = 8;
×
1844
                } else {
1845
                    if (isFirst) {
3!
1846
                        if (isLast) {
3!
1847
                            super.println(-1, "--- packet-start(" + length + ")");
7✔
1848
                        } else {
1849
                            super.println(-1, "--- packet-start(fragment)");
×
1850
                        }
1851
                        isFirst = false;
3✔
1852
                    }
1853
                }
1854
            }
1855

1856
            return this;
2✔
1857
        }
1858
    }
1859

1860
    static class ObjectDef {
1861
        private final String type;
1862
        private final List<String> fields;
1863

1864
        ObjectDef(String type, List<String> fields) {
2✔
1865
            this.type = type;
3✔
1866
            this.fields = fields;
3✔
1867
        }
1✔
1868

1869
        String getType() {
1870
            return type;
3✔
1871
        }
1872

1873
        List<String> getFields() {
1874
            return fields;
3✔
1875
        }
1876
    }
1877
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc