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

hazendaz / jmockit1 / 496

15 Nov 2025 05:33PM UTC coverage: 72.192% (-0.008%) from 72.2%
496

push

github

web-flow
Merge pull request #412 from hazendaz/renovate/major-spring-core

Update spring core to v7 (major)

5677 of 8360 branches covered (67.91%)

Branch coverage included in aggregate %.

11922 of 16018 relevant lines covered (74.43%)

0.74 hits per line

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

56.6
/main/src/main/java/mockit/asm/util/ByteVector.java
1
/*
2
 * MIT License
3
 * Copyright (c) 2006-2025 JMockit developers
4
 * See LICENSE file for full license text.
5
 */
6
package mockit.asm.util;
7

8
import edu.umd.cs.findbugs.annotations.NonNull;
9

10
import org.checkerframework.checker.index.qual.NonNegative;
11

12
/**
13
 * A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream on top of a
14
 * ByteArrayOutputStream, but is more efficient.
15
 */
16
@SuppressWarnings({ "NumericCastThatLosesPrecision", "CharUsedInArithmeticContext" })
17
public final class ByteVector {
18
    /**
19
     * The content of this vector.
20
     */
21
    @NonNull
22
    private byte[] data;
23

24
    /**
25
     * Actual number of bytes in this vector.
26
     */
27
    @NonNegative
28
    private int length;
29

30
    /**
31
     * Constructs a new ByteVector with a default initial size.
32
     */
33
    public ByteVector() {
1✔
34
        data = new byte[64];
1✔
35
    }
1✔
36

37
    /**
38
     * Constructs a new ByteVector with the given initial size.
39
     */
40
    public ByteVector(@NonNegative int initialSize) {
1✔
41
        data = new byte[initialSize];
1✔
42
    }
1✔
43

44
    /**
45
     * Returns the byte {@link #data}.
46
     */
47
    @NonNull
48
    public byte[] getData() {
49
        return data;
1✔
50
    }
51

52
    /**
53
     * Returns the {@link #length} of this vector, in bytes.
54
     */
55
    @NonNegative
56
    public int getLength() {
57
        return length;
1✔
58
    }
59

60
    /**
61
     * Sets the {@link #length} of this vector, in bytes.
62
     */
63
    public void setLength(@NonNegative int length) {
64
        this.length = length;
1✔
65
    }
1✔
66

67
    /**
68
     * Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary.
69
     *
70
     * @return this byte vector
71
     */
72
    @NonNull
73
    public ByteVector putByte(int b) {
74
        int len = getLengthEnlargingIfNeeded(1);
1✔
75
        data[len] = (byte) b;
1✔
76
        len++;
1✔
77
        length = len;
1✔
78
        return this;
1✔
79
    }
80

81
    @NonNegative
82
    private int getLengthEnlargingIfNeeded(@NonNegative int bytesToAdd) {
83
        int len = length;
1✔
84

85
        if (len + bytesToAdd > data.length) {
1✔
86
            enlarge(bytesToAdd);
1✔
87
        }
88

89
        return len;
1✔
90
    }
91

92
    /**
93
     * Enlarge this byte vector so that it can receive n more bytes.
94
     *
95
     * @param size
96
     *            number of additional bytes that this byte vector should be able to receive
97
     */
98
    private void enlarge(@NonNegative int size) {
99
        int length1 = 2 * data.length;
1✔
100
        int length2 = length + size;
1✔
101
        byte[] newData = new byte[length1 > length2 ? length1 : length2];
1✔
102
        System.arraycopy(data, 0, newData, 0, length);
1✔
103
        data = newData;
1✔
104
    }
1✔
105

106
    /**
107
     * Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary.
108
     *
109
     * @return this byte vector
110
     */
111
    @NonNull
112
    public ByteVector put11(int b1, int b2) {
113
        int len = getLengthEnlargingIfNeeded(2);
1✔
114
        byte[] bytes = data;
1✔
115
        bytes[len] = (byte) b1;
1✔
116
        len++;
1✔
117
        bytes[len] = (byte) b2;
1✔
118
        len++;
1✔
119
        length = len;
1✔
120
        return this;
1✔
121
    }
122

123
    /**
124
     * Puts a short into this byte vector. The byte vector is automatically enlarged if necessary.
125
     *
126
     * @return this byte vector
127
     */
128
    @NonNull
129
    public ByteVector putShort(int s) {
130
        return put11(s >>> 8, s);
1✔
131
    }
132

133
    /**
134
     * Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if necessary.
135
     *
136
     * @return this byte vector
137
     */
138
    @NonNull
139
    public ByteVector put12(int b, int s) {
140
        int len = getLengthEnlargingIfNeeded(3);
1✔
141
        byte[] bytes = data;
1✔
142
        bytes[len] = (byte) b;
1✔
143
        len++;
1✔
144
        bytes[len] = (byte) (s >>> 8);
1✔
145
        len++;
1✔
146
        bytes[len] = (byte) s;
1✔
147
        len++;
1✔
148
        length = len;
1✔
149
        return this;
1✔
150
    }
151

152
    /**
153
     * Puts an int into this byte vector. The byte vector is automatically enlarged if necessary.
154
     *
155
     * @return this byte vector
156
     */
157
    @NonNull
158
    public ByteVector putInt(int i) {
159
        int len = getLengthEnlargingIfNeeded(4);
1✔
160
        byte[] bytes = data;
1✔
161
        bytes[len] = (byte) (i >>> 24);
1✔
162
        len++;
1✔
163
        bytes[len] = (byte) (i >>> 16);
1✔
164
        len++;
1✔
165
        bytes[len] = (byte) (i >>> 8);
1✔
166
        len++;
1✔
167
        bytes[len] = (byte) i;
1✔
168
        len++;
1✔
169
        length = len;
1✔
170
        return this;
1✔
171
    }
172

173
    /**
174
     * Puts a long into this byte vector. The byte vector is automatically enlarged if necessary.
175
     */
176
    public void putLong(long l) {
177
        int i1 = (int) (l >>> 32);
×
178
        int i2 = (int) l;
×
179
        putInt(i1);
×
180
        putInt(i2);
×
181
    }
×
182

183
    /**
184
     * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary.
185
     *
186
     * @param utf8String
187
     *            a String whose UTF8 encoded length must be less than 65536
188
     */
189
    public void putUTF8(@NonNull String utf8String) {
190
        int charLength = utf8String.length();
1✔
191

192
        if (charLength > 65535) {
1!
193
            throw new IllegalArgumentException("String too long: " + charLength);
×
194
        }
195

196
        int len = getLengthEnlargingIfNeeded(2 + charLength);
1✔
197
        byte[] characters = data;
1✔
198

199
        // Optimistic algorithm: instead of computing the byte length and then serializing the string (which requires
200
        // two loops), we assume the byte length is equal to char length (which is the most frequent case), and we start
201
        // serializing the string right away.
202
        // During the serialization, if we find that this assumption is wrong, we continue with the general method.
203
        characters[len] = (byte) (charLength >>> 8);
1✔
204
        len++;
1✔
205
        characters[len] = (byte) charLength;
1✔
206
        len++;
1✔
207

208
        for (int i = 0; i < charLength; i++) {
1✔
209
            char c = utf8String.charAt(i);
1✔
210

211
            if (c >= '\001' && c <= '\177') {
1!
212
                characters[len] = (byte) c;
1✔
213
                len++;
1✔
214
            } else {
215
                length = len;
×
216
                encodeUTF8(utf8String, i);
×
217
            }
218
        }
219

220
        length = len;
1✔
221
    }
1✔
222

223
    /**
224
     * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if necessary. The string
225
     * length is encoded in two bytes before the encoded characters, if there is space for that (i.e. if this.length - i
226
     * - 2 >= 0).
227
     *
228
     * @param utf8String
229
     *            the String to encode
230
     * @param startIndex
231
     *            the index of the first character to encode. The previous characters are supposed to have already been
232
     *            encoded, using only one byte per character.
233
     */
234
    private void encodeUTF8(@NonNull String utf8String, @NonNegative int startIndex) {
235
        int byteLength = computeByteLength(utf8String, startIndex);
×
236

237
        if (byteLength > 65535) {
×
238
            throw new IllegalArgumentException("String too long for UTF8 encoding: " + byteLength);
×
239
        }
240

241
        int start = length - startIndex - 2;
×
242

243
        if (start >= 0) {
×
244
            data[start] = (byte) (byteLength >>> 8);
×
245
            data[start + 1] = (byte) byteLength;
×
246
        }
247

248
        if (length + byteLength - startIndex > data.length) {
×
249
            enlarge(byteLength - startIndex);
×
250
        }
251

252
        putEncodedCharacters(utf8String, startIndex);
×
253
    }
×
254

255
    @NonNegative
256
    private static int computeByteLength(@NonNull String utf8String, @NonNegative int startIndex) {
257
        int byteLength = startIndex;
×
258

259
        for (int i = startIndex, n = utf8String.length(); i < n; i++) {
×
260
            char c = utf8String.charAt(i);
×
261

262
            if (c >= '\001' && c <= '\177') {
×
263
                byteLength++;
×
264
            } else if (c > '\u07FF') {
×
265
                byteLength += 3;
×
266
            } else {
267
                byteLength += 2;
×
268
            }
269
        }
270

271
        return byteLength;
×
272
    }
273

274
    private void putEncodedCharacters(@NonNull String utf8String, @NonNegative int startIndex) {
275
        byte[] characters = data;
×
276
        int len = length;
×
277

278
        for (int i = startIndex, n = utf8String.length(); i < n; i++) {
×
279
            char c = utf8String.charAt(i);
×
280

281
            if (c >= '\001' && c <= '\177') {
×
282
                characters[len] = (byte) c;
×
283
            } else {
284
                if (c > '\u07FF') {
×
285
                    characters[len] = (byte) (0xE0 | c >> 12 & 0xF);
×
286
                    len++;
×
287
                    characters[len] = (byte) (0x80 | c >> 6 & 0x3F);
×
288
                } else {
289
                    characters[len] = (byte) (0xC0 | c >> 6 & 0x1F);
×
290
                }
291
                len++;
×
292

293
                characters[len] = (byte) (0x80 | c & 0x3F);
×
294
            }
295
            len++;
×
296
        }
297

298
        length = len;
×
299
    }
×
300

301
    /**
302
     * Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if necessary.
303
     *
304
     * @param bytes
305
     *            an array of bytes
306
     * @param offset
307
     *            index of the first byte of code that must be copied
308
     * @param numBytes
309
     *            number of bytes of code that must be copied
310
     */
311
    public void putByteArray(@NonNull byte[] bytes, @NonNegative int offset, @NonNegative int numBytes) {
312
        int len = getLengthEnlargingIfNeeded(numBytes);
1✔
313
        System.arraycopy(bytes, offset, data, len, numBytes);
1✔
314
        length += numBytes;
1✔
315
    }
1✔
316

317
    public void putByteVector(@NonNull ByteVector another) {
318
        putByteArray(another.data, 0, another.length);
1✔
319
    }
1✔
320

321
    public void roundUpLength() {
322
        int newLength = (4 - length % 4) % 4;
1✔
323
        getLengthEnlargingIfNeeded(newLength);
1✔
324
        length += newLength;
1✔
325
    }
1✔
326
}
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