diff --git a/morphisms/Makefile b/morphisms/Makefile index 4eb2d4d..2394a86 100644 --- a/morphisms/Makefile +++ b/morphisms/Makefile @@ -1,9 +1,13 @@ -TARGETS=lib/posint.so +LIB_DIR=$(shell pwd)/lib +TARGETS=lib/libmorph_length_prefix.so lib/libmorph_posint.so test all: $(TARGETS) -lib/%.so: src/%.c - gcc -shared -o $@ -fPIC $< +lib/libmorph_%.so: src/%.c + $(CC) -O3 -shared -o $@ -fPIC -Iinclude $< + +test: test.c lib/libmorph_length_prefix.so lib/libmorph_posint.so + $(CC) -O3 -L$(LIB_DIR) -o $@ -Iinclude $< -llength_prefix -lposint clean: rm $(TARGETS) diff --git a/morphisms/include/morphisms/length_prefix.h b/morphisms/include/morphisms/length_prefix.h new file mode 100644 index 0000000..1ce7346 --- /dev/null +++ b/morphisms/include/morphisms/length_prefix.h @@ -0,0 +1,61 @@ +#pragma once +#include <stdint.h> + +/* UInt8 */ + +struct LengthPrefixUInt8Array { + uint64_t len; + uint8_t items[]; +}; + +void length_prefix_uint8_array_clear( + struct LengthPrefixUInt8Array * data +); +void length_prefix_uint8_array_push( + struct LengthPrefixUInt8Array * data, + uint8_t value +); +int length_prefix_uint8_array_reverse( + struct LengthPrefixUInt8Array const * restrict src, + struct LengthPrefixUInt8Array * restrict dst +); +void length_prefix_uint8_array_dump( + struct LengthPrefixUInt8Array const * data +); + + +/* UInt64 */ + +struct LengthPrefixUInt64Array { + uint64_t len; + uint64_t items[]; +}; + +void length_prefix_uint64_array_clear( + struct LengthPrefixUInt64Array * data +); +void length_prefix_uint64_array_push( + struct LengthPrefixUInt64Array * data, + uint64_t value +); +int length_prefix_uint64_array_reverse( + struct LengthPrefixUInt64Array const * restrict src, + struct LengthPrefixUInt64Array * restrict dst +); +void length_prefix_uint64_array_dump( + struct LengthPrefixUInt64Array const * data +); + + +/* + * Morphisms + */ + +int morph_string_as_nullterm_to_length_prefix( + char const * restrict src, + struct LengthPrefixUInt8Array * restrict dst +); +int morph_string_as_length_prefix_to_nullterm( + struct LengthPrefixUInt8Array const * restrict src, + char * restrict dst +); diff --git a/morphisms/include/morphisms/posint.h b/morphisms/include/morphisms/posint.h new file mode 100644 index 0000000..08568a6 --- /dev/null +++ b/morphisms/include/morphisms/posint.h @@ -0,0 +1,34 @@ +#pragma once +#include <stdint.h> +#include <morphisms/length_prefix.h> + +int morph_digit_as_char_to_uint8( + char const * restrict src, + uint8_t * restrict dst +); +int morph_digit_as_char_to_uint64( + char const * restrict src, + uint64_t * restrict dst +); +int morph_digit_as_uint8_to_char( + uint8_t const * restrict src, + char * restrict dst +); +int morph_digit_as_uint64_to_char( + uint64_t const * restrict src, + char * restrict dst +); + +int morph_posint_endianness( + uint64_t const radix, + + struct LengthPrefixUInt64Array const * restrict src, + struct LengthPrefixUInt64Array * restrict dst +); +int morph_posint_radix( + uint64_t const src_radix, + uint64_t const dst_radix, + + struct LengthPrefixUInt64Array const * restrict src, + struct LengthPrefixUInt64Array * restrict dst +); diff --git a/morphisms/length_prefix.morphism-base b/morphisms/length_prefix.morphism-base new file mode 100644 index 0000000..7a74e26 --- /dev/null +++ b/morphisms/length_prefix.morphism-base @@ -0,0 +1,9 @@ +morph_string_as_nullterm_to_length_prefix () + [~<ValueDelim '\0'> Char ~ Ascii] +--> [~<LengthPrefix x86.UInt64> Char ~ Ascii] +@lib/array.so:src/array.c + +morph_string_as_length_prefix_to_nullterm () + [~<LengthPrefix x86.UInt64> Char ~ Ascii] +--> [~<ValueDelim '\0'> Char ~ Ascii] +@lib/array.so:src/array.c diff --git a/morphisms/src/length_prefix.c b/morphisms/src/length_prefix.c new file mode 100644 index 0000000..cd29532 --- /dev/null +++ b/morphisms/src/length_prefix.c @@ -0,0 +1,102 @@ +#include <stdio.h> +#include <stdint.h> + +#include <morphisms/length_prefix.h> + +void length_prefix_uint64_array_clear( + struct LengthPrefixUInt64Array * data +) { + data->len = 0; +} + +void length_prefix_uint64_array_push( + struct LengthPrefixUInt64Array * data, + uint64_t value +) { + data->items[ data->len ] = value; + data->len += 1; +} + +int length_prefix_uint64_array_reverse( + struct LengthPrefixUInt64Array const * restrict src, + struct LengthPrefixUInt64Array * restrict dst +) { + dst->len = src->len; + for(uint64_t i = 0; i < src->len; ++i) { + dst->items[i] = src->items[src->len - i - 1]; + } + return 0; +} + +void length_prefix_uint64_array_dump( + struct LengthPrefixUInt64Array const * data +) { + printf("Len = %d, [", data->len); + for( uint64_t i = 0; i < data->len; ++i ) { + printf("%d; ", data->items[i]); + } + printf("]\n"); +} + + + + +void length_prefix_uint8_array_clear( + struct LengthPrefixUInt8Array * data +) { + data->len = 0; +} + +void length_prefix_uint8_array_push( + struct LengthPrefixUInt8Array * data, + uint8_t value +) { + data->items[ data->len ] = value; + data->len += 1; +} + +int length_prefix_uint8_array_reverse( + struct LengthPrefixUInt8Array const * restrict src, + struct LengthPrefixUInt8Array * restrict dst +) { + dst->len = src->len; + for(uint64_t i = 0; i < src->len; ++i) { + dst->items[i] = src->items[src->len - i - 1]; + } + return 0; +} + +void length_prefix_uint8_array_dump( + struct LengthPrefixUInt8Array const * data +) { + printf("Len = %d, [", data->len); + for( uint64_t i = 0; i < data->len; ++i ) { + printf("%d; ", data->items[i]); + } + printf("]\n"); +} + +int morph_string_as_nullterm_to_length_prefix( + char const * restrict src, + struct LengthPrefixUInt8Array * restrict dst +) { + length_prefix_uint8_array_clear(dst); + while( *src ) { + length_prefix_uint8_array_push(dst, *src); + src++; + } + + return 0; +} + +int morph_string_as_length_prefix_to_nullterm( + struct LengthPrefixUInt8Array const * restrict src, + char * restrict dst +) { + for( uint64_t i = 0; i < src->len; ++i ) { + *dst ++ = src->items[i]; + } + *dst = '\0'; + + return 0; +} diff --git a/morphisms/src/length_prefix_array.c b/morphisms/src/length_prefix_array.c deleted file mode 100644 index 4f908e6..0000000 --- a/morphisms/src/length_prefix_array.c +++ /dev/null @@ -1,42 +0,0 @@ -#include <stdio.h> -#include <stdint.h> - -struct LengthPrefixUInt64Array { - uint64_t len; - uint64_t items[]; -}; - -void length_prefix_uint64_array_clear( - struct LengthPrefixUInt64Array * data -) { - data->len = 0; -} - -void length_prefix_uint64_array_push( - struct LengthPrefixUInt64Array * data, - uint64_t value -) { - data->items[ data->len ] = value; - data->len += 1; -} - -int length_prefix_uint64_array_reverse( - struct LengthPrefixUInt64Array const * restrict src, - struct LengthPrefixUInt64Array * restrict dst -) { - dst->len = src->len; - for(uint64_t i = 0; i < src->len; ++i) { - dst->items[i] = src->items[src->len - i - 1]; - } - return 0; -} - -void length_prefix_uint64_array_dump( - struct LengthPrefixUInt64Array const * data -) { - printf("Len = %d, [", data->len); - for( uint64_t i = 0; i < data->len; ++i ) { - printf("%d; ", data->items[i]); - } - printf("]\n"); -} diff --git a/morphisms/src/posint.c b/morphisms/src/posint.c index 5d25f20..cc35955 100644 --- a/morphisms/src/posint.c +++ b/morphisms/src/posint.c @@ -1,5 +1,5 @@ #include <stdint.h> -#include "length_prefix_array.c" +#include <morphisms/length_prefix.h> int morph_digit_as_char_to_uint8( char const * restrict src, @@ -47,6 +47,20 @@ int morph_digit_as_uint8_to_char( return 0; } +int morph_digit_as_uint64_to_char( + uint64_t const * restrict src, + char * restrict dst +) { + if ( *src < 10 ) + *dst = *src + '0'; + else if( *dst < 16 ) + *dst = *src - 0xa + 'a'; + else + return -1; + + return 0; +} + /* switches endianness by reversing the digit sequence */ int morph_posint_endianness( diff --git a/morphisms/test.c b/morphisms/test.c new file mode 100644 index 0000000..8fe26b7 --- /dev/null +++ b/morphisms/test.c @@ -0,0 +1,60 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <morphisms/length_prefix.h> +#include <morphisms/posint.h> + +int main( int argc, char * argv[] ) { + char * int1 = malloc(4096); + struct LengthPrefixUInt8Array * int2 = malloc(4096); + struct LengthPrefixUInt64Array * int3 = malloc(4096); + struct LengthPrefixUInt64Array * int4 = malloc(4096); + struct LengthPrefixUInt64Array * int5 = malloc(4096); + struct LengthPrefixUInt64Array * int6 = malloc(4096); + struct LengthPrefixUInt8Array * int7 = malloc(4096); + char * int8 = malloc(4096); + + // ℕ ~ <PosInt 10 BigEndian> ~ [~<ValueDelim '\0'> <Digit 10> ~ Char ~ Ascii] + scanf("%s", int1); + + // morph to + // ℕ ~ <PosInt 10 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ Char ~ Ascii] + morph_string_as_nullterm_to_length_prefix( int1, int2 ); + + // morph to + // ℕ ~ <PosInt 10 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ ℤ_10 ~ x86.UInt64] + int3->len = int2->len; + for( uint64_t i = 0; i < int2->len; ++i ) + morph_digit_as_char_to_uint64( &int2->items[i], &int3->items[i] ); + + // morph to + // ℕ ~ <PosInt 10 LittleEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ ℤ_10 ~ x86.UInt64] + morph_posint_endianness( 10, int3, int4 ); + + // morph to + // ℕ ~ <PosInt 16 LittleEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ ℤ_16 ~ x86.UInt64] + morph_posint_radix( + 10, + 16, + int4, + int5 + ); + + // morph to + // ℕ ~ <PosInt 16 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ ℤ_16 ~ x86.UInt64] + morph_posint_endianness( 10, int5, int6 ); + + // morph to + // ℕ ~ <PosInt 16 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ Char ~ Ascii] + int7->len = int6->len; + for( uint64_t i = 0; i < int6->len; ++i ) + morph_digit_as_uint64_to_char( &int6->items[i], &int7->items[i] ); + + // morph to + // ℕ ~ <PosInt 16 BigEndian> ~ [~<ValueDelim '\0'> <Digit 16> ~ Char ~ Ascii] + morph_string_as_length_prefix_to_nullterm( int7, int8 ); + + printf("%s\n", int8); + + return 0; +}