1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
package invalid.lena.scrcpy;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
public class WireTest {
@Test
public void readFullyRejectsZeroProgress() throws Exception {
InputStream in = new InputStream() {
@Override public int read() { return 0; }
@Override public int read(byte[] b, int off, int len) { return 0; }
};
try {
Wire.readFully(in, new byte[1]);
fail("zero-progress input accepted");
} catch (IOException expected) {
assertTrue(expected.getMessage().contains("no progress"));
}
}
@Test
public void be32RoundTrip() {
byte[] b = new byte[4];
int[] cases = {0, 1, -1, 0x7fffffff, 0x80000000, 0x12345678};
for (int v : cases) {
Wire.writeBe32(b, 0, v);
assertEquals(v, Wire.readBe32(b, 0));
}
}
@Test
public void be32Layout() {
byte[] b = new byte[4];
Wire.writeBe32(b, 0, 0x12345678);
assertArrayEquals(new byte[]{0x12, 0x34, 0x56, 0x78}, b);
}
@Test
public void be64RoundTrip() {
byte[] b = new byte[8];
long[] cases = {0L, 1L, -1L, Long.MAX_VALUE, Long.MIN_VALUE, 0x0123456789abcdefL};
for (long v : cases) {
Wire.writeBe64(b, 0, v);
assertEquals(v, Wire.readBe64(b, 0));
}
}
@Test
public void le32RoundTrip() {
byte[] b = new byte[4];
int[] cases = {0, 1, -1, 0x7fffffff, 0x80000000, 0x12345678};
for (int v : cases) {
Wire.writeLe32(b, 0, v);
assertEquals(v, Wire.readLe32(b, 0));
}
}
@Test
public void le32Layout() {
byte[] b = new byte[4];
Wire.writeLe32(b, 0, 0x12345678);
assertArrayEquals(new byte[]{0x78, 0x56, 0x34, 0x12}, b);
}
@Test
public void readFullyShortStreamThrows() throws Exception {
ByteArrayInputStream in = new ByteArrayInputStream(new byte[3]);
byte[] buf = new byte[8];
try {
Wire.readFully(in, buf);
fail("expected EOFException");
} catch (EOFException ignored) {
// expected
}
}
// Derive the id the way scrcpy's Codec enums do: the ASCII name, right
// aligned in a big-endian uint32, NUL-padded on the left. Deriving it
// from the name is the whole point - the previous version of this test
// asserted the constants against hand-copied literals, so it passed
// while CODEC_AV1 held 'av01' instead of '\0av1' and AV1 could never
// negotiate.
private static int idOf(String name) {
if (name.length() > 4) throw new IllegalArgumentException(name);
int v = 0;
for (int i = 0; i < 4 - name.length(); i++) v <<= 8;
for (int i = 0; i < name.length(); i++) v = (v << 8) | name.charAt(i);
return v;
}
@Test
public void fourccConstantsMatchScrcpy() {
// Names as spelled in scrcpy's VideoCodec / AudioCodec enums.
assertEquals(idOf("h264"), Wire.CODEC_H264);
assertEquals(idOf("h265"), Wire.CODEC_H265);
assertEquals(idOf("av1"), Wire.CODEC_AV1);
assertEquals(idOf("opus"), Wire.CODEC_OPUS);
assertEquals(idOf("raw"), Wire.CODEC_RAW);
}
@Test
public void fourccNameRoundTripsEveryCodec() {
assertEquals("h264", Wire.fourccName(Wire.CODEC_H264));
assertEquals("h265", Wire.fourccName(Wire.CODEC_H265));
assertEquals("av1", Wire.fourccName(Wire.CODEC_AV1));
assertEquals("opus", Wire.fourccName(Wire.CODEC_OPUS));
assertEquals("raw", Wire.fourccName(Wire.CODEC_RAW));
// Left-NUL padding is the rule, not a special case for raw.
assertEquals("aac", Wire.fourccName(0x00_61_61_63));
}
}
|