Просмотр исходного кода

ncd: modules: value: pass through ID-strings instead of collapsing them to normal strings

ambrop7 13 лет назад
Родитель
Сommit
520ac5fc36
1 измененных файлов с 80 добавлено и 13 удалено
  1. 80 13
      ncd/modules/value.c

+ 80 - 13
ncd/modules/value.c

@@ -147,6 +147,7 @@
 #include <structure/IndexedList.h>
 #include <structure/SAvl.h>
 #include <ncd/NCDModule.h>
+#include <ncd/NCDStringIndex.h>
 #include <ncd/static_strings.h>
 #include <ncd/value_utils.h>
 
@@ -154,6 +155,8 @@
 
 #define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
 
+#define IDSTRING_TYPE (NCDVAL_STRING | (1 << 3))
+
 struct value;
 
 #include "value_maptree.h"
@@ -191,9 +194,13 @@ struct value {
     int type;
     union {
         struct {
-            uint8_t *string;
+            char *string;
             size_t length;
         } string;
+        struct {
+            NCD_string_id_t id;
+            NCDStringIndex *string_index;
+        } idstring;
         struct {
             IndexedList list_contents_il;
         } list;
@@ -206,7 +213,8 @@ struct value {
 static const char * get_type_str (int type);
 static void value_cleanup (struct value *v);
 static void value_delete (struct value *v);
-static struct value * value_init_string (NCDModuleInst *i, const uint8_t *str, size_t len);
+static struct value * value_init_string (NCDModuleInst *i, const char *str, size_t len);
+static struct value * value_init_idstring (NCDModuleInst *i, NCD_string_id_t id, NCDStringIndex *string_index);
 static struct value * value_init_list (NCDModuleInst *i);
 static size_t value_list_len (struct value *v);
 static struct value * value_list_at (struct value *v, size_t index);
@@ -243,7 +251,8 @@ static struct NCD_string_request strings[] = {
 static const char * get_type_str (int type)
 {
     switch (type) {
-        case NCDVAL_STRING: return "string";
+        case NCDVAL_STRING:
+        case IDSTRING_TYPE: return "string";
         case NCDVAL_LIST: return "list";
         case NCDVAL_MAP: return "map";
     }
@@ -262,6 +271,9 @@ static void value_cleanup (struct value *v)
             BFree(v->string.string);
         } break;
         
+        case IDSTRING_TYPE: {
+        } break;
+        
         case NCDVAL_LIST: {
             while (value_list_len(v) > 0) {
                 struct value *ev = value_list_at(v, 0);
@@ -310,6 +322,9 @@ static void value_delete (struct value *v)
             BFree(v->string.string);
         } break;
         
+        case IDSTRING_TYPE: {
+        } break;
+        
         case NCDVAL_LIST: {
             while (value_list_len(v) > 0) {
                 struct value *ev = value_list_at(v, 0);
@@ -330,7 +345,7 @@ static void value_delete (struct value *v)
     free(v);
 }
 
-static struct value * value_init_string (NCDModuleInst *i, const uint8_t *str, size_t len)
+static struct value * value_init_string (NCDModuleInst *i, const char *str, size_t len)
 {
     struct value *v = malloc(sizeof(*v));
     if (!v) {
@@ -359,6 +374,29 @@ fail0:
     return NULL;
 }
 
+static struct value * value_init_idstring (NCDModuleInst *i, NCD_string_id_t id, NCDStringIndex *string_index)
+{
+    ASSERT(string_index == i->params->iparams->string_index)
+    
+    struct value *v = malloc(sizeof(*v));
+    if (!v) {
+        ModuleLog(i, BLOG_ERROR, "malloc failed");
+        goto fail0;
+    }
+    
+    LinkedList0_Init(&v->refs_list);
+    v->parent = NULL;
+    v->type = IDSTRING_TYPE;
+    
+    v->idstring.id = id;
+    v->idstring.string_index = string_index;
+    
+    return v;
+    
+fail0:
+    return NULL;
+}
+
 static struct value * value_init_list (NCDModuleInst *i)
 {
     struct value *v = malloc(sizeof(*v));
@@ -533,7 +571,12 @@ static struct value * value_init_fromvalue (NCDModuleInst *i, NCDValRef value)
     
     switch (NCDVal_Type(value)) {
         case NCDVAL_STRING: {
-            if (!(v = value_init_string(i, (const uint8_t *)NCDVal_StringValue(value), NCDVal_StringLength(value)))) {
+            if (NCDVal_IsIdString(value)) {
+                v = value_init_idstring(i, NCDVal_IdStringId(value), NCDVal_IdStringStringIndex(value));
+            } else {
+                v = value_init_string(i, NCDVal_StringValue(value), NCDVal_StringLength(value));
+            }
+            if (!v) {
                 goto fail0;
             }
         } break;
@@ -611,13 +654,21 @@ static int value_to_value (NCDModuleInst *i, struct value *v, NCDValMem *mem, NC
     
     switch (v->type) {
         case NCDVAL_STRING: {
-            *out_value = NCDVal_NewStringBin(mem, v->string.string, v->string.length);
+            *out_value = NCDVal_NewStringBin(mem, (const uint8_t *)v->string.string, v->string.length);
             if (NCDVal_IsInvalid(*out_value)) {
                 ModuleLog(i, BLOG_ERROR, "NCDVal_NewStringBin failed");
                 goto fail;
             }
         } break;
         
+        case IDSTRING_TYPE: {
+            *out_value = NCDVal_NewIdString(mem, v->idstring.id, v->idstring.string_index);
+            if (NCDVal_IsInvalid(*out_value)) {
+                ModuleLog(i, BLOG_ERROR, "NCDVal_NewIdString failed");
+                goto fail;
+            }
+        } break;
+        
         case NCDVAL_LIST: {
             *out_value = NCDVal_NewList(mem, value_list_len(v));
             if (NCDVal_IsInvalid(*out_value)) {
@@ -675,7 +726,8 @@ static struct value * value_get (NCDModuleInst *i, struct value *v, NCDValRef wh
     ASSERT((NCDVal_Type(where), 1))
     
     switch (v->type) {
-        case NCDVAL_STRING: {
+        case NCDVAL_STRING:
+        case IDSTRING_TYPE: {
             if (!no_error) ModuleLog(i, BLOG_ERROR, "cannot resolve into a string");
             goto fail;
         } break;
@@ -745,7 +797,8 @@ static struct value * value_insert (NCDModuleInst *i, struct value *v, NCDValRef
     struct value *oldv = NULL;
     
     switch (v->type) {
-        case NCDVAL_STRING: {
+        case NCDVAL_STRING:
+        case IDSTRING_TYPE: {
             ModuleLog(i, BLOG_ERROR, "cannot insert into a string");
             goto fail1;
         } break;
@@ -826,7 +879,8 @@ static int value_remove (NCDModuleInst *i, struct value *v, NCDValRef where)
     ASSERT((NCDVal_Type(where), 1))
     
     switch (v->type) {
-        case NCDVAL_STRING: {
+        case NCDVAL_STRING:
+        case IDSTRING_TYPE: {
             ModuleLog(i, BLOG_ERROR, "cannot remove from a string");
             goto fail;
         } break;
@@ -972,6 +1026,9 @@ static int func_getvar2 (void *vo, NCD_string_id_t name, NCDValMem *mem, NCDValR
             case NCDVAL_STRING:
                 len = v->string.length;
                 break;
+            case IDSTRING_TYPE:
+                len = strlen(NCDStringIndex_Value(v->idstring.string_index, v->idstring.id));
+                break;
             default:
                 ASSERT(0);
         }
@@ -1422,20 +1479,30 @@ static void func_new_substr (void *vo, NCDModuleInst *i, const struct NCDModuleI
         goto fail0;
     }
     
-    if (mov->type != NCDVAL_STRING) {
+    if (mov->type != NCDVAL_STRING && mov->type != IDSTRING_TYPE) {
         ModuleLog(i, BLOG_ERROR, "value is not a string");
         goto fail0;
     }
     
-    if (start > mov->string.length) {
+    const char *string_data;
+    size_t string_len;
+    if (mov->type == IDSTRING_TYPE) {
+        string_data = NCDStringIndex_Value(mov->idstring.string_index, mov->idstring.id);
+        string_len = strlen(string_data);
+    } else {
+        string_data = mov->string.string;
+        string_len = mov->string.length;
+    }
+    
+    if (start > string_len) {
         ModuleLog(i, BLOG_ERROR, "start is out of range");
         goto fail0;
     }
     
-    size_t remain = mov->string.length - start;
+    size_t remain = string_len - start;
     size_t amount = length < remain ? length : remain;
     
-    struct value *v = value_init_string(i, mov->string.string + start, amount);
+    struct value *v = value_init_string(i, string_data + start, amount);
     if (!v) {
         goto fail0;
     }