Also added tests for big-endian-conversion functions.
set(SimpleArchiver_SOURCES
src/main.c
src/parser.c
+ src/helpers.c
src/data_structures/linked_list.c
src/data_structures/hash_map.c
src/data_structures/priority_heap.c
add_executable(test_simplearchiver
src/test.c
src/parser.c
+ src/helpers.c
)
SOURCES = \
../src/main.c \
../src/parser.c \
+ ../src/helpers.c \
../src/algorithms/linear_congruential_gen.c \
../src/data_structures/linked_list.c \
../src/data_structures/hash_map.c \
HEADERS = \
../src/parser.h \
../src/parser_internal.h \
+ ../src/helpers.h \
../src/algorithms/linear_congruential_gen.h \
../src/data_structures/linked_list.h \
../src/data_structures/hash_map.h \
--- /dev/null
+/*
+ * Copyright 2024 Stephen Seo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * `helpers.c` is the source for helpful/utility functions.
+ */
+
+#include "helpers.h"
+
+int simple_archiver_helper_is_big_endian(void) {
+ union {
+ unsigned int i;
+ char c[4];
+ } bint = {0x01020304};
+
+ return bint.c[0] == 1 ? 1 : 0;
+}
+
+void simple_archiver_helper_16_bit_be(unsigned short *value) {
+ if (simple_archiver_helper_is_big_endian() == 0) {
+ unsigned char c = ((unsigned char *)value)[0];
+ ((unsigned char *)value)[0] = ((unsigned char *)value)[1];
+ ((unsigned char *)value)[1] = c;
+ }
+}
+
+void simple_archiver_helper_32_bit_be(unsigned int *value) {
+ if (simple_archiver_helper_is_big_endian() == 0) {
+ for (unsigned int i = 0; i < 2; ++i) {
+ unsigned char c = ((unsigned char *)value)[i];
+ ((unsigned char *)value)[i] = ((unsigned char *)value)[3 - i];
+ ((unsigned char *)value)[3 - i] = c;
+ }
+ }
+}
+
+void simple_archiver_helper_64_bit_be(unsigned long long *value) {
+ if (simple_archiver_helper_is_big_endian() == 0) {
+ for (unsigned int i = 0; i < 4; ++i) {
+ unsigned char c = ((unsigned char *)value)[i];
+ ((unsigned char *)value)[i] = ((unsigned char *)value)[7 - i];
+ ((unsigned char *)value)[7 - i] = c;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright 2024 Stephen Seo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * `helpers.h` is the header for helpful/utility functions.
+ */
+
+#ifndef SEODISPARATE_COM_SIMPLE_ARCHIVER_HELPERS_H_
+#define SEODISPARATE_COM_SIMPLE_ARCHIVER_HELPERS_H_
+
+/// Returns non-zero if this system is big-endian.
+int simple_archiver_helper_is_big_endian(void);
+
+/// Swaps value from/to big-endian. Nop on big-endian systems.
+void simple_archiver_helper_16_bit_be(unsigned short *value);
+
+/// Swaps value from/to big-endian. Nop on big-endian systems.
+void simple_archiver_helper_32_bit_be(unsigned int *value);
+
+/// Swaps value from/to big-endian. Nop on big-endian systems.
+void simple_archiver_helper_64_bit_be(unsigned long long *value);
+
+#endif
#include <stdlib.h>
#include <string.h>
+#include "helpers.h"
#include "parser_internal.h"
static int checks_checked = 0;
simple_archiver_free_parsed(&parsed);
}
+ // Test helpers.
+ {
+ // Only if system is little-endian.
+ if (simple_archiver_helper_is_big_endian() == 0) {
+ unsigned short u16 = 0x0102;
+ CHECK_TRUE(((unsigned char *)&u16)[0] == 2);
+ CHECK_TRUE(((unsigned char *)&u16)[1] == 1);
+ simple_archiver_helper_16_bit_be(&u16);
+ CHECK_TRUE(((unsigned char *)&u16)[0] == 1);
+ CHECK_TRUE(((unsigned char *)&u16)[1] == 2);
+ simple_archiver_helper_16_bit_be(&u16);
+ CHECK_TRUE(((unsigned char *)&u16)[0] == 2);
+ CHECK_TRUE(((unsigned char *)&u16)[1] == 1);
+
+ unsigned int u32 = 0x01020304;
+ CHECK_TRUE(((unsigned char *)&u32)[0] == 4);
+ CHECK_TRUE(((unsigned char *)&u32)[1] == 3);
+ CHECK_TRUE(((unsigned char *)&u32)[2] == 2);
+ CHECK_TRUE(((unsigned char *)&u32)[3] == 1);
+ simple_archiver_helper_32_bit_be(&u32);
+ CHECK_TRUE(((unsigned char *)&u32)[0] == 1);
+ CHECK_TRUE(((unsigned char *)&u32)[1] == 2);
+ CHECK_TRUE(((unsigned char *)&u32)[2] == 3);
+ CHECK_TRUE(((unsigned char *)&u32)[3] == 4);
+ simple_archiver_helper_32_bit_be(&u32);
+ CHECK_TRUE(((unsigned char *)&u32)[0] == 4);
+ CHECK_TRUE(((unsigned char *)&u32)[1] == 3);
+ CHECK_TRUE(((unsigned char *)&u32)[2] == 2);
+ CHECK_TRUE(((unsigned char *)&u32)[3] == 1);
+
+ unsigned long long u64 = 0x010203040a0b0c0d;
+ CHECK_TRUE(((unsigned char *)&u64)[0] == 0xd);
+ CHECK_TRUE(((unsigned char *)&u64)[1] == 0xc);
+ CHECK_TRUE(((unsigned char *)&u64)[2] == 0xb);
+ CHECK_TRUE(((unsigned char *)&u64)[3] == 0xa);
+ CHECK_TRUE(((unsigned char *)&u64)[4] == 0x4);
+ CHECK_TRUE(((unsigned char *)&u64)[5] == 0x3);
+ CHECK_TRUE(((unsigned char *)&u64)[6] == 0x2);
+ CHECK_TRUE(((unsigned char *)&u64)[7] == 0x1);
+ simple_archiver_helper_64_bit_be(&u64);
+ CHECK_TRUE(((unsigned char *)&u64)[0] == 0x1);
+ CHECK_TRUE(((unsigned char *)&u64)[1] == 0x2);
+ CHECK_TRUE(((unsigned char *)&u64)[2] == 0x3);
+ CHECK_TRUE(((unsigned char *)&u64)[3] == 0x4);
+ CHECK_TRUE(((unsigned char *)&u64)[4] == 0xa);
+ CHECK_TRUE(((unsigned char *)&u64)[5] == 0xb);
+ CHECK_TRUE(((unsigned char *)&u64)[6] == 0xc);
+ CHECK_TRUE(((unsigned char *)&u64)[7] == 0xd);
+ simple_archiver_helper_64_bit_be(&u64);
+ CHECK_TRUE(((unsigned char *)&u64)[0] == 0xd);
+ CHECK_TRUE(((unsigned char *)&u64)[1] == 0xc);
+ CHECK_TRUE(((unsigned char *)&u64)[2] == 0xb);
+ CHECK_TRUE(((unsigned char *)&u64)[3] == 0xa);
+ CHECK_TRUE(((unsigned char *)&u64)[4] == 0x4);
+ CHECK_TRUE(((unsigned char *)&u64)[5] == 0x3);
+ CHECK_TRUE(((unsigned char *)&u64)[6] == 0x2);
+ CHECK_TRUE(((unsigned char *)&u64)[7] == 0x1);
+ }
+ }
+
printf("Checks checked: %u\n", checks_checked);
printf("Checks passed: %u\n", checks_passed);
return checks_passed == checks_checked ? 0 : 1;