1#include <gtest/gtest.h>
2
3#include <engine/shared/compression.h>
4
5static const int DATA[] = {0, 1, -1, 32, 64, 256, -512, 12345, -123456, 1234567, 12345678, 123456789, 2147483647, (-2147483647 - 1)};
6static const int NUM = std::size(DATA);
7static const int SIZES[NUM] = {1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5};
8
9TEST(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
21TEST(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
37TEST(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
43TEST(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
53TEST(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
71TEST(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
78TEST(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