1 | #include <gtest/gtest.h> |
2 | |
3 | #include <engine/shared/compression.h> |
4 | |
5 | static const int DATA[] = {0, 1, -1, 32, 64, 256, -512, 12345, -123456, 1234567, 12345678, 123456789, 2147483647, (-2147483647 - 1)}; |
6 | static const int NUM = std::size(DATA); |
7 | static const int SIZES[NUM] = {1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5}; |
8 | |
9 | TEST(CVariableInt, RoundtripPackUnpack) |
10 | { |
11 | for(int i = 0; i < NUM; i++) |
12 | { |
13 | unsigned char aPacked[CVariableInt::MAX_BYTES_PACKED]; |
14 | int Result; |
15 | EXPECT_EQ(CVariableInt::Pack(aPacked, DATA[i], sizeof(aPacked)) - aPacked, (ptrdiff_t)SIZES[i]); |
16 | EXPECT_EQ(CVariableInt::Unpack(aPacked, &Result, sizeof(aPacked)) - aPacked, (ptrdiff_t)SIZES[i]); |
17 | EXPECT_EQ(Result, DATA[i]); |
18 | } |
19 | } |
20 | |
21 | TEST(CVariableInt, UnpackInvalid) |
22 | { |
23 | unsigned char aPacked[CVariableInt::MAX_BYTES_PACKED]; |
24 | for(auto &Byte : aPacked) |
25 | Byte = 0xFF; |
26 | |
27 | int Result; |
28 | EXPECT_EQ(CVariableInt::Unpack(aPacked, &Result, sizeof(aPacked)) - aPacked, (ptrdiff_t)CVariableInt::MAX_BYTES_PACKED); |
29 | EXPECT_EQ(Result, (-2147483647 - 1)); |
30 | |
31 | aPacked[0] &= ~0x40; // unset sign bit |
32 | |
33 | EXPECT_EQ(CVariableInt::Unpack(aPacked, &Result, sizeof(aPacked)) - aPacked, (ptrdiff_t)CVariableInt::MAX_BYTES_PACKED); |
34 | EXPECT_EQ(Result, 2147483647); |
35 | } |
36 | |
37 | TEST(CVariableInt, PackBufferTooSmall) |
38 | { |
39 | unsigned char aPacked[CVariableInt::MAX_BYTES_PACKED / 2]; // too small |
40 | EXPECT_EQ(CVariableInt::Pack(aPacked, 2147483647, sizeof(aPacked)), (const unsigned char *)0x0); |
41 | } |
42 | |
43 | TEST(CVariableInt, UnpackBufferTooSmall) |
44 | { |
45 | unsigned char aPacked[CVariableInt::MAX_BYTES_PACKED / 2]; |
46 | for(auto &Byte : aPacked) |
47 | Byte = 0xFF; // extended bits are set, but buffer ends too early |
48 | |
49 | int UnusedResult; |
50 | EXPECT_EQ(CVariableInt::Unpack(aPacked, &UnusedResult, sizeof(aPacked)), (const unsigned char *)0x0); |
51 | } |
52 | |
53 | TEST(CVariableInt, RoundtripCompressDecompress) |
54 | { |
55 | unsigned char aCompressed[NUM * CVariableInt::MAX_BYTES_PACKED]; |
56 | int aDecompressed[NUM]; |
57 | long ExpectedCompressedSize = 0; |
58 | for(auto Size : SIZES) |
59 | ExpectedCompressedSize += Size; |
60 | |
61 | long CompressedSize = CVariableInt::Compress(pSrc: DATA, SrcSize: sizeof(DATA), pDst: aCompressed, DstSize: sizeof(aCompressed)); |
62 | ASSERT_EQ(CompressedSize, ExpectedCompressedSize); |
63 | long DecompressedSize = CVariableInt::Decompress(pSrc: aCompressed, SrcSize: ExpectedCompressedSize, pDst: aDecompressed, DstSize: sizeof(aDecompressed)); |
64 | ASSERT_EQ(DecompressedSize, sizeof(DATA)); |
65 | for(int i = 0; i < NUM; i++) |
66 | { |
67 | EXPECT_EQ(aDecompressed[i], DATA[i]); |
68 | } |
69 | } |
70 | |
71 | TEST(CVariableInt, CompressBufferTooSmall) |
72 | { |
73 | unsigned char aCompressed[NUM]; // too small |
74 | long CompressedSize = CVariableInt::Compress(pSrc: DATA, SrcSize: sizeof(DATA), pDst: aCompressed, DstSize: sizeof(aCompressed)); |
75 | ASSERT_EQ(CompressedSize, -1); |
76 | } |
77 | |
78 | TEST(CVariableInt, DecompressBufferTooSmall) |
79 | { |
80 | unsigned char aCompressed[] = {0x00, 0x01, 0x40, 0x20, 0x80, 0x01, 0x80, 0x04, 0xFF, 0x07, 0xB9, 0xC0, 0x01}; |
81 | int aUncompressed[4]; // too small |
82 | long CompressedSize = CVariableInt::Decompress(pSrc: aCompressed, SrcSize: sizeof(aCompressed), pDst: aUncompressed, DstSize: sizeof(aUncompressed)); |
83 | ASSERT_EQ(CompressedSize, -1); |
84 | } |
85 | |