1+ package org .utbot .examples ;
2+
3+ /**
4+ * A dynamically extensible vector of bytes. This class is roughly equivalent to
5+ * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
6+ *
7+ * @author Eric Bruneton
8+ */
9+ public class ByteVector {
10+
11+ /**
12+ * The content of this vector.
13+ */
14+ public byte [] data ;
15+
16+ /**
17+ * Actual number of bytes in this vector.
18+ */
19+ public int length ;
20+
21+ /**
22+ * Constructs a new {@link ByteVector ByteVector} with a default initial size.
23+ */
24+ public ByteVector () {
25+ data = new byte [64 ];
26+ }
27+
28+ /**
29+ * Constructs a new {@link ByteVector ByteVector} with the given initial size.
30+ *
31+ * @param initialSize the initial size of the byte vector to be constructed.
32+ */
33+ public ByteVector (final int initialSize ) {
34+ data = new byte [initialSize ];
35+ }
36+
37+ /**
38+ * Puts a byte into this byte vector. The byte vector is automatically enlarged
39+ * if necessary.
40+ *
41+ * @param b a byte.
42+ * @return this byte vector.
43+ */
44+ public ByteVector putByte (final int b ) {
45+ int length = this .length ;
46+ if (length + 1 > data .length ) {
47+ enlarge (1 );
48+ }
49+ data [length ++] = (byte ) b ;
50+ this .length = length ;
51+ return this ;
52+ }
53+
54+ /**
55+ * Puts two bytes into this byte vector. The byte vector is automatically
56+ * enlarged if necessary.
57+ *
58+ * @param b1 a byte.
59+ * @param b2 another byte.
60+ * @return this byte vector.
61+ */
62+ ByteVector put11 (final int b1 , final int b2 ) {
63+ int length = this .length ;
64+ if (length + 2 > data .length ) {
65+ enlarge (2 );
66+ }
67+ final byte [] data = this .data ;
68+ data [length ++] = (byte ) b1 ;
69+ data [length ++] = (byte ) b2 ;
70+ this .length = length ;
71+ return this ;
72+ }
73+
74+ /**
75+ * Puts a short into this byte vector. The byte vector is automatically enlarged
76+ * if necessary.
77+ *
78+ * @param s a short.
79+ * @return this byte vector.
80+ */
81+ public ByteVector putShort (final int s ) {
82+ int length = this .length ;
83+ if (length + 2 > data .length ) {
84+ enlarge (2 );
85+ }
86+ final byte [] data = this .data ;
87+ data [length ++] = (byte ) (s >>> 8 );
88+ data [length ++] = (byte ) s ;
89+ this .length = length ;
90+ return this ;
91+ }
92+
93+ /**
94+ * Puts a byte and a short into this byte vector. The byte vector is
95+ * automatically enlarged if necessary.
96+ *
97+ * @param b a byte.
98+ * @param s a short.
99+ * @return this byte vector.
100+ */
101+ public ByteVector put12 (final int b , final int s ) {
102+ int length = this .length ;
103+ if (length + 3 > data .length ) {
104+ enlarge (3 );
105+ }
106+ final byte [] data = this .data ;
107+ data [length ++] = (byte ) b ;
108+ data [length ++] = (byte ) (s >>> 8 );
109+ data [length ++] = (byte ) s ;
110+ this .length = length ;
111+ return this ;
112+ }
113+
114+ /**
115+ * Puts an int into this byte vector. The byte vector is automatically enlarged
116+ * if necessary.
117+ *
118+ * @param i an int.
119+ * @return this byte vector.
120+ */
121+ public ByteVector putInt (final int i ) {
122+ int length = this .length ;
123+ if (length + 4 > data .length ) {
124+ enlarge (4 );
125+ }
126+ final byte [] data = this .data ;
127+ data [length ++] = (byte ) (i >>> 24 );
128+ data [length ++] = (byte ) (i >>> 16 );
129+ data [length ++] = (byte ) (i >>> 8 );
130+ data [length ++] = (byte ) i ;
131+ this .length = length ;
132+ return this ;
133+ }
134+
135+ /**
136+ * Puts an UTF8 string into this byte vector. The byte vector is automatically
137+ * enlarged if necessary.
138+ *
139+ * @param s a String.
140+ * @return this byte vector.
141+ */
142+ public ByteVector putUTF8 (final String s ) {
143+ final int charLength = s .length ();
144+ int len = length ;
145+ if (len + 2 + charLength > data .length ) {
146+ enlarge (2 + charLength );
147+ }
148+ final byte [] data = this .data ;
149+ // optimistic algorithm: instead of computing the byte length and then
150+ // serializing the string (which requires two loops), we assume the byte
151+ // length is equal to char length (which is the most frequent case), and
152+ // we start serializing the string right away. During the serialization,
153+ // if we find that this assumption is wrong, we continue with the
154+ // general method.
155+ data [len ++] = (byte ) (charLength >>> 8 );
156+ data [len ++] = (byte ) charLength ;
157+ for (int i = 0 ; i < charLength ; ++i ) {
158+ final char c = s .charAt (i );
159+ if ((c >= '\001' && c <= '\177' ) || (c >= '\u4E00' && c <= '\u9FFF' )) {
160+ data [len ++] = (byte ) c ;
161+ } else {
162+ throw new UnsupportedOperationException ();
163+ }
164+ }
165+ length = len ;
166+ return this ;
167+ }
168+
169+ /**
170+ * Puts an array of bytes into this byte vector. The byte vector is
171+ * automatically enlarged if necessary.
172+ *
173+ * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt> null
174+ * bytes into this byte vector.
175+ * @param off index of the fist byte of b that must be copied.
176+ * @param len number of bytes of b that must be copied.
177+ * @return this byte vector.
178+ */
179+ public ByteVector putByteArray (final byte [] b , final int off , final int len ) {
180+ if (length + len > data .length ) {
181+ enlarge (len );
182+ }
183+ if (b != null ) {
184+ System .arraycopy (b , off , data , length , len );
185+ }
186+ length += len ;
187+ return this ;
188+ }
189+
190+ /**
191+ * Enlarge this byte vector so that it can receive n more bytes.
192+ *
193+ * @param size number of additional bytes that this byte vector should be able
194+ * to receive.
195+ */
196+ private void enlarge (final int size ) {
197+ final int length1 = 2 * data .length ;
198+ final int length2 = length + size ;
199+ final byte [] newData = new byte [length1 > length2 ? length1 : length2 ];
200+ System .arraycopy (data , 0 , newData , 0 , length );
201+ data = newData ;
202+ }
203+ }
0 commit comments