Commit 9d2612e25fa9c736bdebe2fa6425889221edea3f

Thomas de Grivel 2024-12-09T10:57:59

serialize

diff --git a/.ikc3_history b/.ikc3_history
index be370d5..b11d533 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,15 +1,3 @@
-type(1234567890123456789)
-type(123456789012345678901234)
-type(123456789012345678901234/2)
-123456789012345678901234/2
-123456789012345678901234/2 * 0.1
-(123456789012345678901234/2) * 0.1
-(F128) 123456789012345678901234/2 * 0.1
-List.to_array
-0 - 2
-Tuple[]
-type(Tuple[])
-type((Tuple[]) {{1, 2, 3}})
 type((Tuple[]) {1, 2, 3})
 [1][0]
 ([1])[0]
@@ -97,3 +85,15 @@ quote t = Thread.new(fn () { puts("ok") })
 List.count(10)
 List.map(List.count(10), fn (x) { {x, x} })
 List.map(List.count(10), fn (x) { %{id: x} })
+s = Serialize.new()
+Serialize.tag(s, 123)
+s = Serialize.new()
+Serialize.tag(s, 123)
+s = Serialize.new()
+Serialize.tag(s, 123)
+Serialize.to_str(s)
+'U+123'
+'U+123'
+Serialize.tag(s, 66)
+Serialize.to_str(s)
+Serialize.delete(s)
diff --git a/lib/kc3/0.1/serialize.kc3 b/lib/kc3/0.1/serialize.kc3
index 2322ea8..28633cd 100644
--- a/lib/kc3/0.1/serialize.kc3
+++ b/lib/kc3/0.1/serialize.kc3
@@ -6,4 +6,6 @@ defmodule Serialize do
 
   def tag = cfn Bool "kc3_serialize_tag" (Ptr, Tag)
 
+  def to_str = cfn Str "kc3_serialize_to_str" (Ptr, Result)
+
 end
diff --git a/libkc3/callable.c b/libkc3/callable.c
index a089aec..102e474 100644
--- a/libkc3/callable.c
+++ b/libkc3/callable.c
@@ -16,12 +16,13 @@
 #include "callable.h"
 #include "cfn.h"
 #include "fn.h"
+#include "mutex.h"
 #include "tag.h"
 
 void callable_delete (s_callable *callable)
 {
   assert(callable);
-  /* FIXME: lock callable lock. */
+  mutex_lock(&callable->mutex);
   if (callable->reference_count <= 0)
     goto clean;
   if (--callable->reference_count > 0)
@@ -31,12 +32,12 @@ void callable_delete (s_callable *callable)
   case CALLABLE_FN:  fn_clean(&callable->data.fn);   break;
   case CALLABLE_VOID:                                break;
   }
-  /* FIXME: unlock callable lock. */
+  mutex_unlock(&callable->mutex);
+  mutex_clean(&callable->mutex);
   free(callable);
   return;
  clean:
-  /* FIXME: unlock callable lock. */
-  return;
+  mutex_unlock(&callable->mutex);
 }
 
 s_callable * callable_new (void)
@@ -44,6 +45,7 @@ s_callable * callable_new (void)
   s_callable *callable;
   if (! (callable = alloc(sizeof(s_callable))))
     return NULL;
+  mutex_init(&callable->mutex);
   return callable;
 }
 
@@ -75,8 +77,14 @@ s_callable * callable_new_copy (s_callable *src)
 s_callable * callable_new_ref (s_callable *callable)
 {
   assert(callable);
-  assert(callable->reference_count > 0);
+  mutex_lock(&callable->mutex);
+  if (callable->reference_count <= 0) {
+    err_puts("callable_new_ref: reference count <= 0");
+    assert(! "callable_new_ref: reference count <= 0");
+    abort();
+  }
   callable->reference_count++;
+  mutex_unlock(&callable->mutex);
   return callable;
 }
 
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index bc6f6e3..fc9e7b1 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -550,6 +550,18 @@ s_list ** kc3_search_modules (s_list **dest)
   return env_search_modules(g_kc3_env, dest);
 }
 
+void kc3_serialize_delete (s_serialize **serialize)
+{
+  serialize_delete(*serialize);
+}
+
+s_serialize ** kc3_serialize_new (s_serialize **serialize)
+{
+  assert(serialize);
+  *serialize = serialize_new();
+  return serialize;
+}
+
 bool kc3_serialize_tag (s_serialize **serialize, const s_tag *tag)
 {
   if (! serialize_tag(*serialize, tag))
@@ -557,6 +569,11 @@ bool kc3_serialize_tag (s_serialize **serialize, const s_tag *tag)
   return true;
 }
 
+s_str * kc3_serialize_to_str (s_serialize **serialize, s_str *dest)
+{
+  return serialize_to_str(*serialize, dest);
+}
+
 s_list ** kc3_stacktrace (s_list **dest)
 {
   return env_stacktrace(g_kc3_env, dest);
diff --git a/libkc3/serialize.c b/libkc3/serialize.c
index 873b6de..db91924 100644
--- a/libkc3/serialize.c
+++ b/libkc3/serialize.c
@@ -31,7 +31,8 @@ DEF_SERIALIZE(bool)
 void serialize_clean (s_serialize *serialize)
 {
   assert(serialize);
-  (void) serialize;
+  buf_clean(&serialize->buf);
+  buf_clean(&serialize->heap);
 }
 
 void serialize_delete (s_serialize *serialize)
@@ -40,13 +41,24 @@ void serialize_delete (s_serialize *serialize)
   free(serialize);
 }
 
+s_serialize * serialize_character (s_serialize *serialize,
+                                   character c)
+{
+  return serialize_u32(serialize, c);
+}
+
 s_serialize * serialize_init (s_serialize *serialize)
 {
   s_serialize tmp = {0};
+  buf_init_alloc(&tmp.heap, 1024024);
+  buf_init_alloc(&tmp.buf, 1024024);
   *serialize = tmp;
   return serialize;
 }
 
+s_serialize * serialize_list (s_serialize *serialize,
+                              const s_list *list);
+
 s_serialize * serialize_new (void)
 {
   s_serialize *serialize;
@@ -56,40 +68,63 @@ s_serialize * serialize_new (void)
   return serialize;
 }
 
-s_str * serialize_to_buf (const s_serialize *serialize, s_buf *buf);
-
-s_str * serialize_to_str (const s_serialize *serialize, s_str *dest);
-
-s_serialize * serialize_bool (s_serialize *serialize, bool b);
+DEF_SERIALIZE(s8)
+DEF_SERIALIZE(s16)
+DEF_SERIALIZE(s32)
+DEF_SERIALIZE(s64)
 
-s_serialize * serialize_character (s_serialize *serialize,
-                                   character c);
+s_serialize * serialize_str (s_serialize *serialize, const s_str *src)
+{
+  sw r;
+  assert(serialize);
+  assert(src);
+  if (! serialize_u32(serialize, src->size))
+    return NULL;
+  if ((r = buf_write(&serialize->buf, src->ptr.pchar, src->size)) <= 0)
+    return NULL;
+  return serialize;
+}
 
-s_serialize * serialize_list (s_serialize *serialize,
-                              const s_list *list);
+DEF_SERIALIZE(sw)
 
 s_serialize * serialize_tag (s_serialize *serialize, const s_tag *tag)
 {
   switch (tag->type){
-  case TAG_U8: return serialize_u8(serialize, tag->data.u8);
-  default:     break;
+  case TAG_BOOL: return serialize_bool(serialize, tag->data.bool);
+  case TAG_CHARACTER:
+    return serialize_character(serialize, tag->data.character);
+  case TAG_S8:   return serialize_s8(serialize, tag->data.s8);
+  case TAG_S16:  return serialize_s16(serialize, tag->data.s16);
+  case TAG_S32:  return serialize_s32(serialize, tag->data.s32);
+  case TAG_S64:  return serialize_s64(serialize, tag->data.s64);
+  case TAG_STR:  return serialize_str(serialize, &tag->data.str);
+  case TAG_SW:   return serialize_sw(serialize, tag->data.sw);
+  case TAG_U8:   return serialize_u8(serialize, tag->data.u8);
+  case TAG_U16:  return serialize_u16(serialize, tag->data.u16);
+  case TAG_U32:  return serialize_u32(serialize, tag->data.u32);
+  case TAG_U64:  return serialize_u64(serialize, tag->data.u64);
+  case TAG_UW:   return serialize_uw(serialize, tag->data.uw);
+  default:       break;
   }
   err_puts("serialize_tag: not implemented");
   assert(! "serialize_tag: not implemented");
   return NULL;
 }
 
-s_serialize * serialize_tuple (s_serialize *serialize,
-                               const s_tuple *tuple);
+sw serialize_to_buf (s_serialize *serialize, s_buf *buf)
+{
+  return buf_xfer(&serialize->buf, buf,
+                  serialize->buf.wpos - serialize->buf.rpos);
+}
 
-DEF_SERIALIZE(s8)
-DEF_SERIALIZE(s16)
-DEF_SERIALIZE(s32)
-DEF_SERIALIZE(s64)
+s_str * serialize_to_str (s_serialize *serialize, s_str *dest)
+{
+  return buf_read_to_str(&serialize->buf, dest);
+}
 
-s_serialize * serialize_str (s_serialize *serialize, const s_str *str);
+s_serialize * serialize_tuple (s_serialize *serialize,
+                               const s_tuple *tuple);
 
-DEF_SERIALIZE(sw)
 DEF_SERIALIZE(u8)
 DEF_SERIALIZE(u16)
 DEF_SERIALIZE(u32)
diff --git a/libkc3/serialize.h b/libkc3/serialize.h
index 7b4f0cb..40d5403 100644
--- a/libkc3/serialize.h
+++ b/libkc3/serialize.h
@@ -30,9 +30,9 @@
 void          serialize_clean (s_serialize *serialize);
 s_serialize * serialize_init (s_serialize *serialize);
 
-/* Observers. */
-s_str * serialize_to_buf (const s_serialize *serialize, s_buf *buf);
-s_str * serialize_to_str (const s_serialize *serialize, s_str *dest);
+/* Heap-allocation functions, call serialize_delete after use. */
+void          serialize_delete (s_serialize *serialize);
+s_serialize * serialize_new (void);
 
 /* Operators. */
 PROTO_SERIALIZE(bool);
@@ -41,6 +41,10 @@ s_serialize * serialize_list (s_serialize *serialize,
                               const s_list *list);
 s_serialize * serialize_tag (s_serialize *serialize,
                              const s_tag *tag);
+sw            serialize_to_buf (s_serialize *serialize,
+                                s_buf *buf);
+s_str *       serialize_to_str (s_serialize *serialize,
+                                s_str *dest);
 s_serialize * serialize_tuple (s_serialize *serialize,
                                const s_tuple *tuple);
 PROTO_SERIALIZE(s8);
diff --git a/libkc3/types.h b/libkc3/types.h
index 27597b5..d0d0c85 100644
--- a/libkc3/types.h
+++ b/libkc3/types.h
@@ -454,7 +454,7 @@ struct integer {
 
 struct str {
   u_ptr_w free;        /**< Pointer to free or NULL. */
-  uw      size;        /**< Size in bytes. */
+  u32     size;        /**< Size in bytes. */
   u_ptr   ptr;         /**< Pointer to memory. */
 };
 
@@ -561,6 +561,7 @@ struct callable {
   e_callable_type type;
   sw reference_count;
   u_callable_data data;
+  s_mutex mutex;
 };
 
 union tag_data {