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

ncd: NCDValue: keep an element count for lists. ncd/modules/list.c: use NCDValue_ListCount

ambrop7 15 лет назад
Родитель
Сommit
47e7c49030
3 измененных файлов с 48 добавлено и 41 удалено
  1. 17 11
      ncd/NCDValue.c
  2. 11 7
      ncd/NCDValue.h
  3. 20 23
      ncd/modules/list.c

+ 17 - 11
ncd/NCDValue.c

@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
 #include <stdarg.h>
 #include <stdarg.h>
+#include <inttypes.h>
 
 
 #include <misc/debug.h>
 #include <misc/debug.h>
 #include <misc/offset.h>
 #include <misc/offset.h>
@@ -140,6 +141,7 @@ char * NCDValue_StringValue (NCDValue *o)
 void NCDValue_InitList (NCDValue *o)
 void NCDValue_InitList (NCDValue *o)
 {
 {
     LinkedList2_Init(&o->list);
     LinkedList2_Init(&o->list);
+    o->list_count = 0;
     
     
     o->type = NCDVALUE_LIST;
     o->type = NCDVALUE_LIST;
 }
 }
@@ -150,30 +152,43 @@ int NCDValue_ListAppend (NCDValue *o, NCDValue v)
     value_assert(&v);
     value_assert(&v);
     ASSERT(o->type == NCDVALUE_LIST)
     ASSERT(o->type == NCDVALUE_LIST)
     
     
+    if (o->list_count == SIZE_MAX) {
+        return 0;
+    }
+    
     NCDListElement *e = malloc(sizeof(*e));
     NCDListElement *e = malloc(sizeof(*e));
     if (!e) {
     if (!e) {
         return 0;
         return 0;
     }
     }
     
     
     LinkedList2_Append(&o->list, &e->list_node);
     LinkedList2_Append(&o->list, &e->list_node);
+    o->list_count++;
     e->v = v;
     e->v = v;
     
     
     return 1;
     return 1;
 }
 }
 
 
-void NCDValue_ListAppendList (NCDValue *o, NCDValue l)
+int NCDValue_ListAppendList (NCDValue *o, NCDValue l)
 {
 {
     value_assert(o);
     value_assert(o);
     value_assert(&l);
     value_assert(&l);
     ASSERT(o->type == NCDVALUE_LIST)
     ASSERT(o->type == NCDVALUE_LIST)
     ASSERT(l.type == NCDVALUE_LIST)
     ASSERT(l.type == NCDVALUE_LIST)
     
     
+    if (l.list_count > SIZE_MAX - o->list_count) {
+        return 0;
+    }
+    
     LinkedList2Node *n;
     LinkedList2Node *n;
     while (n = LinkedList2_GetFirst(&l.list)) {
     while (n = LinkedList2_GetFirst(&l.list)) {
         NCDListElement *e = UPPER_OBJECT(n, NCDListElement, list_node);
         NCDListElement *e = UPPER_OBJECT(n, NCDListElement, list_node);
         LinkedList2_Remove(&l.list, &e->list_node);
         LinkedList2_Remove(&l.list, &e->list_node);
         LinkedList2_Append(&o->list, &e->list_node);
         LinkedList2_Append(&o->list, &e->list_node);
     }
     }
+    
+    o->list_count += l.list_count;
+    
+    return 1;
 }
 }
 
 
 size_t NCDValue_ListCount (NCDValue *o)
 size_t NCDValue_ListCount (NCDValue *o)
@@ -181,16 +196,7 @@ size_t NCDValue_ListCount (NCDValue *o)
     value_assert(o);
     value_assert(o);
     ASSERT(o->type == NCDVALUE_LIST)
     ASSERT(o->type == NCDVALUE_LIST)
     
     
-    size_t c = 0;
-    
-    LinkedList2Iterator it;
-    LinkedList2Iterator_InitForward(&it, &o->list);
-    LinkedList2Node *n;
-    while (n = LinkedList2Iterator_Next(&it)) {
-        c++;
-    }
-    
-    return c;
+    return o->list_count;
 }
 }
 
 
 NCDValue * NCDValue_ListFirst (NCDValue *o)
 NCDValue * NCDValue_ListFirst (NCDValue *o)

+ 11 - 7
ncd/NCDValue.h

@@ -25,6 +25,7 @@
 
 
 #include <stddef.h>
 #include <stddef.h>
 
 
+#include <misc/debug.h>
 #include <structure/LinkedList2.h>
 #include <structure/LinkedList2.h>
 
 
 #define NCDVALUE_STRING 1
 #define NCDVALUE_STRING 1
@@ -34,7 +35,10 @@ typedef struct {
     int type;
     int type;
     union {
     union {
         char *string;
         char *string;
-        LinkedList2 list;
+        struct {
+            LinkedList2 list;
+            size_t list_count;
+        };
     };
     };
 } NCDValue;
 } NCDValue;
 
 
@@ -43,20 +47,20 @@ typedef struct {
     NCDValue v;
     NCDValue v;
 } NCDListElement;
 } NCDListElement;
 
 
-int NCDValue_InitCopy (NCDValue *o, NCDValue *v);
+int NCDValue_InitCopy (NCDValue *o, NCDValue *v) WARN_UNUSED;
 void NCDValue_Free (NCDValue *o);
 void NCDValue_Free (NCDValue *o);
 int NCDValue_Type (NCDValue *o);
 int NCDValue_Type (NCDValue *o);
 
 
-int NCDValue_InitString (NCDValue *o, const char *str);
+int NCDValue_InitString (NCDValue *o, const char *str) WARN_UNUSED;
 char * NCDValue_StringValue (NCDValue *o);
 char * NCDValue_StringValue (NCDValue *o);
 
 
 void NCDValue_InitList (NCDValue *o);
 void NCDValue_InitList (NCDValue *o);
-int NCDValue_ListAppend (NCDValue *o, NCDValue v);
-void NCDValue_ListAppendList (NCDValue *o, NCDValue l);
+int NCDValue_ListAppend (NCDValue *o, NCDValue v) WARN_UNUSED;
+int NCDValue_ListAppendList (NCDValue *o, NCDValue l) WARN_UNUSED;
 size_t NCDValue_ListCount (NCDValue *o);
 size_t NCDValue_ListCount (NCDValue *o);
 NCDValue * NCDValue_ListFirst (NCDValue *o);
 NCDValue * NCDValue_ListFirst (NCDValue *o);
 NCDValue * NCDValue_ListNext (NCDValue *o, NCDValue *ev);
 NCDValue * NCDValue_ListNext (NCDValue *o, NCDValue *ev);
-int NCDValue_ListRead (NCDValue *o, int num, ...);
-int NCDValue_ListReadHead (NCDValue *o, int num, ...);
+int NCDValue_ListRead (NCDValue *o, int num, ...) WARN_UNUSED;
+int NCDValue_ListReadHead (NCDValue *o, int num, ...) WARN_UNUSED;
 
 
 #endif
 #endif

+ 20 - 23
ncd/modules/list.c

@@ -67,7 +67,7 @@ struct appendv_instance {
 
 
 struct length_instance {
 struct length_instance {
     NCDModuleInst *i;
     NCDModuleInst *i;
-    uint64_t length;
+    size_t length;
 };
 };
 
 
 struct get_instance {
 struct get_instance {
@@ -227,7 +227,11 @@ static void appendv_func_new (NCDModuleInst *i)
         ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitCopy failed");
         ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitCopy failed");
         goto fail1;
         goto fail1;
     }
     }
-    NCDValue_ListAppendList(&mo->list, l);
+    if (!NCDValue_ListAppendList(&mo->list, l)) {
+        ModuleLog(o->i, BLOG_ERROR, "NCDValue_ListAppendList failed");
+        NCDValue_Free(&l);
+        goto fail1;
+    }
     
     
     // signal up
     // signal up
     NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
     NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
@@ -274,17 +278,8 @@ static void length_func_new (NCDModuleInst *i)
     // get method object
     // get method object
     struct instance *mo = i->method_object->inst_user;
     struct instance *mo = i->method_object->inst_user;
     
     
-    // count elements
-    o->length = 0;
-    NCDValue *e = NCDValue_ListFirst(&mo->list);
-    while (e) {
-        if (o->length == UINT64_MAX) {
-            ModuleLog(o->i, BLOG_ERROR, "too many elements");
-            goto fail1;
-        }
-        o->length++;
-        e = NCDValue_ListNext(&mo->list, e);
-    }
+    // remember length
+    o->length = NCDValue_ListCount(&mo->list);
     
     
     // signal up
     // signal up
     NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
     NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
@@ -314,8 +309,8 @@ static int length_func_getvar (void *vo, const char *name, NCDValue *out)
     struct length_instance *o = vo;
     struct length_instance *o = vo;
     
     
     if (!strcmp(name, "")) {
     if (!strcmp(name, "")) {
-        char str[30];
-        snprintf(str, sizeof(str), "%"PRIu64, o->length);
+        char str[50];
+        snprintf(str, sizeof(str), "%"PRIuMAX, (uintmax_t)o->length);
         
         
         if (!NCDValue_InitString(out, str)) {
         if (!NCDValue_InitString(out, str)) {
             ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitString failed");
             ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitString failed");
@@ -351,8 +346,8 @@ static void get_func_new (NCDModuleInst *i)
         ModuleLog(o->i, BLOG_ERROR, "wrong type");
         ModuleLog(o->i, BLOG_ERROR, "wrong type");
         goto fail1;
         goto fail1;
     }
     }
-    uint64_t index;
-    if (sscanf(NCDValue_StringValue(index_arg), "%"SCNu64, &index) != 1) {
+    uintmax_t index;
+    if (sscanf(NCDValue_StringValue(index_arg), "%"SCNuMAX, &index) != 1) {
         ModuleLog(o->i, BLOG_ERROR, "wrong value");
         ModuleLog(o->i, BLOG_ERROR, "wrong value");
         goto fail1;
         goto fail1;
     }
     }
@@ -360,8 +355,14 @@ static void get_func_new (NCDModuleInst *i)
     // get method object
     // get method object
     struct instance *mo = i->method_object->inst_user;
     struct instance *mo = i->method_object->inst_user;
     
     
+    // check index
+    if (index >= NCDValue_ListCount(&mo->list)) {
+        ModuleLog(o->i, BLOG_ERROR, "no element at index %"PRIuMAX, index);
+        goto fail1;
+    }
+    
     // find requested element
     // find requested element
-    uint64_t pos = 0;
+    uintmax_t pos = 0;
     NCDValue *e = NCDValue_ListFirst(&mo->list);
     NCDValue *e = NCDValue_ListFirst(&mo->list);
     while (e) {
     while (e) {
         if (pos == index) {
         if (pos == index) {
@@ -370,11 +371,7 @@ static void get_func_new (NCDModuleInst *i)
         pos++;
         pos++;
         e = NCDValue_ListNext(&mo->list, e);
         e = NCDValue_ListNext(&mo->list, e);
     }
     }
-    
-    if (!e) {
-        ModuleLog(o->i, BLOG_ERROR, "no element at index %"PRIu64, index);
-        goto fail1;
-    }
+    ASSERT(e)
     
     
     // copy value
     // copy value
     if (!NCDValue_InitCopy(&o->value, e)) {
     if (!NCDValue_InitCopy(&o->value, e)) {