From 24b332c68257cb4c51f21ad2381c660b630a6826 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 19 Mar 2025 17:27:04 +0100
Subject: [PATCH 1/4] add morphism for unix-timestamp to iso8601

---
 morphisms/timepoint.morphism-base | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 morphisms/timepoint.morphism-base

diff --git a/morphisms/timepoint.morphism-base b/morphisms/timepoint.morphism-base
new file mode 100644
index 0000000..39f5822
--- /dev/null
+++ b/morphisms/timepoint.morphism-base
@@ -0,0 +1,15 @@
+```
+#include <time.h>
+```
+
+morph_unixtime_to_iso ()
+      TimePoint ~ <TimeSince UnixEpoch> ~ Duration ~ Seconds ~ ℝ ~ <QuantizedLinear 0 1 1> ~ ℕ ~ x86.UInt64
+-->   TimePoint ~ ISO8601 ~ <Seq~<ValueTerminated 0> Char~Ascii~x86.UInt8>
+```
+    time_t rawtime = (time_t)(*src);
+    struct tm *timeinfo = gmtime(&rawtime);
+    if (!timeinfo) return -1;
+
+    strftime((char*)dst, 20, "%Y-%m-%dT%H:%M:%SZ", timeinfo);
+    return 0;
+```

From f8725c0624afe32343bedb8421a47ade32dbbca2 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 19 Mar 2025 17:28:04 +0100
Subject: [PATCH 2/4] unicode morphisms: switch to 0 terminator instead of '\0'

---
 morphisms/unicode.morphism-base | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/morphisms/unicode.morphism-base b/morphisms/unicode.morphism-base
index db4b342..c8e8a87 100644
--- a/morphisms/unicode.morphism-base
+++ b/morphisms/unicode.morphism-base
@@ -3,7 +3,7 @@
 ```
 
 morph_string_as_ascii_to_utf8 ()
-     <Seq ~ <ValueTerminated '\0'>  Char~Ascii~x86.UInt8>
+     <Seq ~ <ValueTerminated 0>  Char~Ascii~x86.UInt8>
 -->  <Seq Char~Unicode>
     ~ UTF-8
     ~ <Seq~<ValueTerminated 0> x86.UInt8>
@@ -17,7 +17,7 @@ morph_string_as_utf8_to_ascii ()
     <Seq Char~Unicode>
     ~ UTF-8
     ~ <Seq~<ValueTerminated 0> x86.UInt8>
---> <Seq ~ <ValueTerminated '\0'>  Char~Ascii~x86.UInt8>
+--> <Seq ~ <ValueTerminated 0>  Char~Ascii~x86.UInt8>
 ```
     while( *src ) {
         if( *src < 128 ) {
@@ -32,7 +32,7 @@ morph_string_as_utf8_to_ascii ()
 ```
 
 morph_string_as_ascii_to_utf32 ()
-     <Seq ~ <ValueTerminated '\0'>  Char~Ascii~x86.UInt8>
+     <Seq ~ <ValueTerminated 0>  Char~Ascii~x86.UInt8>
 -->  <Seq Char~Unicode>
     ~ UTF-32LE
     ~ <Seq~<ValueTerminated 0> x86.UInt32>

From 17a1e499d8d2eb8372d029885aeb17226f58d92d Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 19 Mar 2025 17:28:26 +0100
Subject: [PATCH 3/4] add lenpfx to valsep morphism

---
 morphisms/value_delim.morphism-base | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/morphisms/value_delim.morphism-base b/morphisms/value_delim.morphism-base
index 1870ff7..cab2c32 100644
--- a/morphisms/value_delim.morphism-base
+++ b/morphisms/value_delim.morphism-base
@@ -69,3 +69,31 @@ morph_seqseq_as_valsep_to_lenpfx (T: Type, Delim: T, EscKey: T)
 
     return 0;
 ```
+
+morph_seqeq_as_lenpfx_to_valsep (T: Type, Delim: T, EscKey: T)
+    < Seq~<LengthPrefix x86.UInt64>
+        <Seq~<LengthPrefix x86.UInt64> T >
+        ~ <RefMut < Seq~<LengthPrefix x86.UInt64> T>>
+        ~ x86.Address
+        ~ x86.UInt64
+    >
+-->   < Seq <Seq T> >
+    ~ < ValueSep T Delim >
+    ~ < Seq~<LengthPrefix x86.UInt64> T >
+```
+    length_prefix_uint8_array_clear( dst );
+
+    for( uint64_t i = 0; i < src->len; ++i ) {
+        LengthPrefixUInt8Array * item = src->items[i];
+
+        for( uint64_t j = 0; j < item->len; ++j ) {
+            length_prefix_uint8_array_push( items->items[j] );
+        }
+
+        if( i+1 < src->len ) {
+            length_prefix_uint8_array_push( Delim );
+        }
+    }
+
+    return 0;
+```

From 4c7302c4a3f48678055528b037427e58eec44457 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Wed, 19 Mar 2025 17:28:54 +0100
Subject: [PATCH 4/4] digit morphisms: print message to stderr when digit is
 out of range

---
 morphisms/digit.morphism-base | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/morphisms/digit.morphism-base b/morphisms/digit.morphism-base
index 97d3bd9..8cc1597 100644
--- a/morphisms/digit.morphism-base
+++ b/morphisms/digit.morphism-base
@@ -12,8 +12,10 @@ morph_digit_as_char_to_uint8 (Radix:ℤ)
         *dst = 0xa + *src - 'a';
     else if( *src >= 'A' && *src <= 'F')
         *dst = 0xa + *src - 'A';
-    else
+    else {
+        fprintf(stderr, "invalid digit 0x%x\n", *src);
         return -1;
+    }
 
     if( *dst < Radix ) {
         return 0;
@@ -33,8 +35,10 @@ morph_digit_as_char_to_uint64 (Radix:ℤ)
         *dst = 0xa + *src - 'a';
     else if( *src >= 'A' && *src <= 'F')
         *dst = 0xa + *src - 'A';
-    else
+    else {
+        fprintf(stderr, "invalid digit 0x%x\n", *src);
         return -1;
+    }
 
     if( *dst < Radix ) {
         return 0;