commit a09362ba95ef5581dc5fcc05384d61ed3f662c15
Author: lash <dev@holbrook.no>
Date: Mon, 15 Apr 2024 18:12:37 +0100
Initial commit
Diffstat:
10 files changed, 303 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,3 @@
+*.o
+*.testbin
+*.so
diff --git a/Makefile b/Makefile
@@ -0,0 +1,12 @@
+all: src
+
+src:
+ make -C src
+
+test: src
+ make -C src test
+
+clean:
+ make -C src clean
+
+.PHONY: clean
diff --git a/src/Makefile b/src/Makefile
@@ -0,0 +1,23 @@
+OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
+CFLAGS += -Wall -Werror
+
+all: $(OBJS)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+clean:
+ make -C tests clean
+ rm -vf *.o
+
+test: all
+ make -C tests test
+
+
+shared: strip.so.o endian.so.o
+ $(CC) $(CFLAGS) -c strip.c -o strip.so.o -fpic
+ $(CC) $(CFLAGS) -c endian.c -o endian.so.o -fpic
+ $(CC) $(CFLAGS) -shared -o liblash.so $^
+
+
+.PHONY: clean
diff --git a/src/endian.c b/src/endian.c
@@ -0,0 +1,48 @@
+#include "endian.h"
+
+int is_le() {
+ unsigned short s = 42;
+ return *((unsigned char*)&s) == 42;
+}
+
+
+void flip_endian(int l, void *v) {
+ int i;
+ char t;
+ char *ne;
+ char *p;
+
+ p = (char*)v;
+ ne = p+(l-1);
+ for (i = 0; i < l/2; i++) {
+ t = *(p+i);
+ *(p+i) = *(ne-i);
+ *(ne-i) = t;
+ }
+}
+
+// convert unsigned integer to little-endian representation
+int to_endian(char direction, int l, void *n) {
+ union le un;
+
+ if (l == 1 || is_le() == direction) {
+ return 0;
+ }
+ switch(l) {
+ case sizeof(long long):
+ un.ll = (long long*)n;
+ break;
+ case sizeof(int):
+ un.i = (int*)n;
+ break;
+ case sizeof(short):
+ un.s = (short*)n;
+ break;
+ default:
+ return 1;
+ }
+ flip_endian(l, un.c);
+
+ return 0;
+}
+
diff --git a/src/endian.h b/src/endian.h
@@ -0,0 +1,48 @@
+#ifndef LASH_ENDIAN_H_
+#define LASH_ENDIAN_H_
+
+#define TO_ENDIAN_BIG 0
+#define TO_ENDIAN_LITTLE 1
+
+/**
+ *
+ * \brief Encapsulats all suppoerted integer lengths for endian conversion.
+ *
+ */
+union le {
+ short *s;
+ int *i;
+ long long *ll;
+ unsigned char *c;
+};
+
+//int le(int l, void *n);
+/*
+ * Return true (1) if system is little-endian.
+ */
+int is_le();
+/**
+ * Convert to specified endian order.
+ *
+ * The integer data in \c n is changed in-place.
+ *
+ * If \c direction is same as system endianness, or \c l==1, no action is taken.
+ *
+ * \param direction 0 for big-endian, 1 for little-endian.
+ * \param l Length of integer \c n in bytes.
+ * \param n Integer data.
+ * \return 1 if \c l is invalid byte size, 0 (success) otherwise.
+ *
+ */
+int to_endian(char direction, int l, void *n);
+/**
+ * Change endian order of given number.
+ *
+ * The integer data in \c n is changed in-place.
+ *
+ * \param l Length of integer \c in bytes.
+ * \param v Integer data
+ */
+void flip_endian(int l, void *v);
+
+#endif // LASH_ENDIAN_H_
diff --git a/src/strip.c b/src/strip.c
@@ -0,0 +1,21 @@
+#include <stddef.h>
+
+
+char* zerostrip_be(char *value, size_t *len) {
+ int i;
+ char *p;
+
+ p = value;
+ for (i = 0; i < *len; i++) {
+ if (*p & 0xff) {
+ break;
+ }
+ p++;
+ }
+ *len -= i;
+ if (!*len) {
+ *len = 1;
+ p--;
+ }
+ return p;
+}
diff --git a/src/strip.h b/src/strip.h
@@ -0,0 +1,6 @@
+#ifndef LASH_BYTES_H_
+#define LASH_BYTES_H_
+
+char* zerostrip_be(char *value, size_t *len);
+
+#endif
diff --git a/src/tests/Makefile b/src/tests/Makefile
@@ -0,0 +1,20 @@
+TESTS := $(patsubst %.c,%.testbin,$(wildcard *.c))
+LINKOBJS := $(wildcard ../*.o)
+INCLUDES := -I..
+CFLAGS += $(INCLUDES) -g3 -Wall
+
+all: $(TESTS)
+
+%.testbin: %.c
+ $(CC) $(CFLAGS) $< -o $@ $(LINKOBJS)
+ ./$@
+
+#test_run: $(wildcard out_*)
+# for f in $^; do ./$$f; done
+
+test: all
+
+clean:
+ rm -vf *.testbin
+
+.PHONY: clean
diff --git a/src/tests/test_endian.c b/src/tests/test_endian.c
@@ -0,0 +1,62 @@
+#include <string.h>
+#include <stdio.h>
+
+#include "endian.h"
+
+
+int main() {
+ int r;
+ int i;
+ char left[] = { 0x02, 0x13, 0x24, 0x35};
+ char right[] = { 0x35, 0x24, 0x13, 0x02};
+ unsigned char tmp[4];
+
+ memcpy(tmp, left, 4);
+
+ // four byte flip
+ flip_endian(4, tmp);
+ for (i = 0; i < 4; i++) {
+ if (tmp[i] != *(right+i)) {
+ return 1;
+ }
+ }
+
+ // two byte flip
+ memcpy(tmp, left, 2);
+ flip_endian(2, tmp);
+ for (i = 0; i < 4; i++) {
+ if (tmp[i] != *(right+2+i)) {
+ return 1;
+ }
+ }
+
+ // single byte flip
+ tmp[0] = 0x2a;
+ flip_endian(1, tmp);
+ tmp[0] = 0x2a;
+
+
+ // check explicit endian convert
+ if (is_le()) {
+ memcpy(tmp, left, 4);
+ } else {
+ memcpy(tmp, right, 4);
+ }
+ r = to_endian(0, 4, (void*)tmp);
+ if (r) {
+ return 1;
+ }
+ for (i = 0; i < 4; i++) {
+ if (tmp[i] != *(right+i)) {
+ return 1;
+ }
+ }
+
+ // check invalid length
+ r = to_endian(0, 3, (void*)tmp);
+ if (!r) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/src/tests/test_strip.c b/src/tests/test_strip.c
@@ -0,0 +1,60 @@
+#include <stddef.h>
+#include <stdio.h>
+
+#include "strip.h"
+
+int main() {
+ size_t l = 4;
+ char be_int_semi[4] = {0x00, 0x00, 0x02, 0x9f};
+ char be_int_full[4] = {0x40, 0x00, 0x02, 0x9f};
+ char be_int_zero[4] = {0x00, 0x00, 0x00, 0x00};
+ char be_int_mini[1] = {0x2a};
+ char be_int_mini_zero[1] = {0x00};
+ char *r;
+
+ r = zerostrip_be((char*)be_int_semi, &l);
+ if (l != 2) {
+ return 1;
+ }
+ if (*r != 0x02) {
+ return 1;
+ }
+
+ l = 4;
+ r = zerostrip_be((char*)be_int_full, &l);
+ if (l != 4) {
+ return 1;
+ }
+ if (*r != 0x40) {
+ return 1;
+ }
+
+ l = 4;
+ r = zerostrip_be((char*)be_int_zero, &l);
+ if (l != 1) {
+ return 1;
+ }
+ if (*r != 0x00) {
+ return 1;
+ }
+
+ l = 1;
+ r = zerostrip_be((char*)be_int_mini, &l);
+ if (l != 1) {
+ return 1;
+ }
+ if (*r != 0x2a) {
+ return 1;
+ }
+
+ l = 1;
+ r = zerostrip_be((char*)be_int_mini_zero, &l);
+ if (l != 1) {
+ return 1;
+ }
+ if (*r != 0x00) {
+ return 1;
+ }
+
+ return 0;
+}