Add helpers for conversion to/from big-endian
All checks were successful
Run Unit Tests / build-and-run-unit-tests (push) Successful in 3s

Also added tests for big-endian-conversion functions.
This commit is contained in:
Stephen Seo 2024-07-02 14:25:01 +09:00
parent eb1f09b551
commit 69051a6c24
5 changed files with 155 additions and 0 deletions

View file

@ -6,6 +6,7 @@ set(SimpleArchiver_VERSION 1.0)
set(SimpleArchiver_SOURCES set(SimpleArchiver_SOURCES
src/main.c src/main.c
src/parser.c src/parser.c
src/helpers.c
src/data_structures/linked_list.c src/data_structures/linked_list.c
src/data_structures/hash_map.c src/data_structures/hash_map.c
src/data_structures/priority_heap.c src/data_structures/priority_heap.c
@ -37,4 +38,5 @@ add_executable(test_datastructures
add_executable(test_simplearchiver add_executable(test_simplearchiver
src/test.c src/test.c
src/parser.c src/parser.c
src/helpers.c
) )

View file

@ -6,6 +6,7 @@ OUTDIR = out
SOURCES = \ SOURCES = \
../src/main.c \ ../src/main.c \
../src/parser.c \ ../src/parser.c \
../src/helpers.c \
../src/algorithms/linear_congruential_gen.c \ ../src/algorithms/linear_congruential_gen.c \
../src/data_structures/linked_list.c \ ../src/data_structures/linked_list.c \
../src/data_structures/hash_map.c \ ../src/data_structures/hash_map.c \
@ -14,6 +15,7 @@ SOURCES = \
HEADERS = \ HEADERS = \
../src/parser.h \ ../src/parser.h \
../src/parser_internal.h \ ../src/parser_internal.h \
../src/helpers.h \
../src/algorithms/linear_congruential_gen.h \ ../src/algorithms/linear_congruential_gen.h \
../src/data_structures/linked_list.h \ ../src/data_structures/linked_list.h \
../src/data_structures/hash_map.h \ ../src/data_structures/hash_map.h \

56
src/helpers.c Normal file
View file

@ -0,0 +1,56 @@
/*
* 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;
}
}
}

34
src/helpers.h Normal file
View file

@ -0,0 +1,34 @@
/*
* 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

View file

@ -20,6 +20,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "helpers.h"
#include "parser_internal.h" #include "parser_internal.h"
static int checks_checked = 0; static int checks_checked = 0;
@ -109,6 +110,66 @@ int main(void) {
simple_archiver_free_parsed(&parsed); 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 checked: %u\n", checks_checked);
printf("Checks passed: %u\n", checks_passed); printf("Checks passed: %u\n", checks_passed);
return checks_passed == checks_checked ? 0 : 1; return checks_passed == checks_checked ? 0 : 1;