posint morphisms in C
This commit is contained in:
commit
06227a2731
4 changed files with 174 additions and 0 deletions
11
morphisms/Makefile
Normal file
11
morphisms/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
|||
TARGETS=lib/posint.so
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
lib/%.so: src/%.c
|
||||
gcc -shared -o $@ -fPIC $<
|
||||
|
||||
clean:
|
||||
rm $(TARGETS)
|
||||
|
||||
.PHONY: all clean
|
36
morphisms/posint.morphism-base
Normal file
36
morphisms/posint.morphism-base
Normal file
|
@ -0,0 +1,36 @@
|
|||
morph_digit_as_char_to_uint8 (Radix:ℤ_16)
|
||||
<Digit Radix> ~ Char ~ Ascii ~ Byte
|
||||
--> <Digit Radix> ~ x86.UInt8 ~ Byte
|
||||
@lib/posint.so:src/posint.c
|
||||
|
||||
morph_digit_as_uint8_to_char (Radix:ℤ_16)
|
||||
<Digit Radix> ~ x86.UInt8 ~ Byte
|
||||
--> <Digit Radix> ~ Char ~ Ascii ~ Byte
|
||||
@lib/posint.so:src/posint.c
|
||||
|
||||
morph_posint_radix (SrcRadix:ℤ, DstRadix:ℤ)
|
||||
ℕ
|
||||
~ <PosInt SrcRadix LittleEndian>
|
||||
~ [~<LengthPrefix x86.UInt64> <Digit SrcRadix>~x86.UInt64]
|
||||
--> ℕ
|
||||
~ <PosInt DstRadix LittleEndian>
|
||||
~ [~<LengthPrefix x86.UInt64> <Digit DstRadix>~x86.UInt64]
|
||||
@lib/posint.so:src/posint.c
|
||||
|
||||
morph_posint_endianness (Radix:ℤ)
|
||||
ℕ
|
||||
~ <PosInt Radix LittleEndian>
|
||||
~ [~<LengthPrefix x86.UInt64> <Digit Radix> ~ x86.UInt64]
|
||||
--> ℕ
|
||||
~ <PosInt Radix BigEndian>
|
||||
~ [~<LengthPrefix x86.UInt64> <Digit Radix> ~ x86.UInt64]
|
||||
@lib/posint.so:src/posint.c
|
||||
|
||||
morph_posint_endianness (Radix:ℤ)
|
||||
ℕ
|
||||
~ <PosInt Radix BigEndian>
|
||||
~ [~<LengthPrefix x86.UInt64> <Digit Radix> ~ x86.UInt64]
|
||||
--> ℕ
|
||||
~ <PosInt Radix LittleEndian>
|
||||
~ [~<LengthPrefix x86.UInt64> <Digit Radix> ~ x86.UInt64]
|
||||
@lib/posint.so:src/posint.c
|
42
morphisms/src/length_prefix_array.c
Normal file
42
morphisms/src/length_prefix_array.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
#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");
|
||||
}
|
85
morphisms/src/posint.c
Normal file
85
morphisms/src/posint.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include <stdint.h>
|
||||
#include "length_prefix_array.c"
|
||||
|
||||
int morph_digit_as_char_to_uint8(
|
||||
char const * restrict src,
|
||||
uint8_t * restrict dst
|
||||
) {
|
||||
if( *src >= '0' && *src <= '9' )
|
||||
*dst = *src - '0';
|
||||
else if( *src >= 'a' && *src <= 'f')
|
||||
*dst = 0xa + *src - 'a';
|
||||
else if( *src >= 'A' && *src <= 'F')
|
||||
*dst = 0xa + *src - 'A';
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int morph_digit_as_char_to_uint64(
|
||||
char const * restrict src,
|
||||
uint64_t * restrict dst
|
||||
) {
|
||||
if( *src >= '0' && *src <= '9' )
|
||||
*dst = *src - '0';
|
||||
else if( *src >= 'a' && *src <= 'f')
|
||||
*dst = 0xa + *src - 'a';
|
||||
else if( *src >= 'A' && *src <= 'F')
|
||||
*dst = 0xa + *src - 'A';
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int morph_digit_as_uint8_to_char(
|
||||
uint8_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(
|
||||
uint64_t const radix,
|
||||
|
||||
struct LengthPrefixUInt64Array const * restrict src,
|
||||
struct LengthPrefixUInt64Array * restrict dst
|
||||
) {
|
||||
return length_prefix_uint64_array_reverse( src, dst );
|
||||
}
|
||||
|
||||
/* morph radix in little endian
|
||||
*/
|
||||
int morph_posint_radix(
|
||||
uint64_t const src_radix,
|
||||
uint64_t const dst_radix,
|
||||
|
||||
struct LengthPrefixUInt64Array const * restrict src,
|
||||
struct LengthPrefixUInt64Array * restrict dst
|
||||
) {
|
||||
uint64_t value = 0;
|
||||
|
||||
for( uint64_t i = 0; i < src->len; ++i ) {
|
||||
value *= src_radix;
|
||||
value += src->items[src->len - i - 1];
|
||||
}
|
||||
|
||||
length_prefix_uint64_array_clear( dst );
|
||||
|
||||
while( value > 0 ) {
|
||||
length_prefix_uint64_array_push( dst, value % dst_radix );
|
||||
value /= dst_radix;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue