an efficient binary archive format
1#include "greatest.h"
2#include <string.h>
3
4#include "../include/bindle.h"
5
6TEST test_basic(void) {
7 const char *path = "test_c.bndl";
8 const char *name = "test.txt";
9 const char *data = "Hello from C!";
10
11 // Create and add data
12 Bindle *archive = bindle_create(path);
13 ASSERT(archive != NULL);
14
15 int success = bindle_add(archive, name, (unsigned char *)data, strlen(data),
16 BindleCompressNone);
17 ASSERT(success);
18
19 success = bindle_save(archive);
20 ASSERT(success);
21
22 // Read back
23 size_t len = 0;
24 const unsigned char *read_data =
25 bindle_read_uncompressed_direct(archive, name, &len);
26 ASSERT(read_data != NULL);
27 ASSERT_MEM_EQ(read_data, data, len);
28
29 // Check exists
30 ASSERT(bindle_exists(archive, name));
31 ASSERT_EQ(bindle_length(archive), 1);
32
33 ASSERT(bindle_save(archive));
34 bindle_close(archive);
35
36 PASS();
37}
38
39TEST test_writer_reader(void) {
40 const char *path = "test_c_stream.bndl";
41 const char *name = "streamed.txt";
42 const char *data = "Streaming from C!";
43
44 // Write
45 Bindle *archive = bindle_create(path);
46 ASSERT(archive != NULL);
47
48 BindleWriter *writer = bindle_writer_new(archive, name, BindleCompressNone);
49 ASSERT(writer != NULL);
50
51 int success =
52 bindle_writer_write(writer, (unsigned char *)data, strlen(data));
53 ASSERT(success);
54
55 success = bindle_writer_close(writer);
56 ASSERT(success);
57
58 bindle_save(archive);
59 bindle_close(archive);
60
61 // Read
62 archive = bindle_open(path);
63 ASSERT(archive != NULL);
64
65 BindleReader *reader = bindle_reader_new(archive, name);
66 ASSERT(reader != NULL);
67
68 unsigned char buffer[256];
69 long bytes_read = bindle_reader_read(reader, buffer, sizeof(buffer));
70 ASSERT_EQ(bytes_read, (long)strlen(data));
71 ASSERT_MEM_EQ(buffer, data, bytes_read);
72
73 ASSERT(bindle_reader_verify_crc32(reader));
74
75 bindle_reader_close(reader);
76
77 ASSERT(bindle_save(archive));
78 bindle_close(archive);
79
80 PASS();
81}
82
83TEST test_remove_vacuum(void) {
84 const char *path = "test_c_vacuum.bndl";
85
86 Bindle *archive = bindle_create(path);
87 ASSERT(archive != NULL);
88
89 // Add two entries
90 bindle_add(archive, "file1.txt", (unsigned char *)"Data 1", 6,
91 BindleCompressNone);
92 bindle_add(archive, "file2.txt", (unsigned char *)"Data 2", 6,
93 BindleCompressNone);
94 bindle_save(archive);
95
96 ASSERT_EQ(bindle_length(archive), 2);
97
98 // Remove one
99 ASSERT(bindle_remove(archive, "file1.txt"));
100 bindle_save(archive);
101
102 ASSERT_EQ(bindle_length(archive), 1);
103 ASSERT_FALSE(bindle_exists(archive, "file1.txt"));
104 ASSERT(bindle_exists(archive, "file2.txt"));
105
106 // Vacuum
107 ASSERT(bindle_vacuum(archive));
108 ASSERT_EQ(bindle_length(archive), 1);
109
110 bindle_close(archive);
111
112 PASS();
113}
114
115SUITE(c_api_suite) {
116 RUN_TEST(test_basic);
117 RUN_TEST(test_writer_reader);
118 RUN_TEST(test_remove_vacuum);
119}
120
121GREATEST_MAIN_DEFS();
122
123int main(int argc, char **argv) {
124 GREATEST_MAIN_BEGIN();
125 RUN_SUITE(c_api_suite);
126 GREATEST_MAIN_END();
127}