Răsfoiți Sursa

ncd: NCDVal: add NCDVal_MapGetValue()

ambrop7 13 ani în urmă
părinte
comite
9b6c186ef0
3 a modificat fișierele cu 44 adăugiri și 3 ștergeri
  1. 6 0
      examples/ncdval_test.c
  2. 31 3
      ncd/NCDVal.c
  3. 7 0
      ncd/NCDVal.h

+ 6 - 0
examples/ncdval_test.c

@@ -136,6 +136,10 @@ int main ()
     FORCE( NCDVal_MapInsert(m1, k1, v1) )
     FORCE( NCDVal_MapInsert(m1, k1, v1) )
     FORCE( NCDVal_MapInsert(m1, k2, v2) )
     FORCE( NCDVal_MapInsert(m1, k2, v2) )
     
     
+    ASSERT( NCDVal_MapGetValue(m1, "K1").idx == v1.idx )
+    ASSERT( NCDVal_MapGetValue(m1, "K2").idx == v2.idx )
+    ASSERT( NCDVal_IsInvalid(NCDVal_MapGetValue(m1, "K3")) )
+    
     NCDValRef ids1 = NCDVal_NewIdString(&mem, NCD_STRING_ARG1, &string_index);
     NCDValRef ids1 = NCDVal_NewIdString(&mem, NCD_STRING_ARG1, &string_index);
     FORCE( !NCDVal_IsInvalid(ids1) )
     FORCE( !NCDVal_IsInvalid(ids1) )
     ASSERT( !memcmp(NCDVal_StringData(ids1), "_arg1", 5) )
     ASSERT( !memcmp(NCDVal_StringData(ids1), "_arg1", 5) )
@@ -156,6 +160,8 @@ int main ()
     
     
     FORCE( NCDVal_MapInsert(m1, ids1, ids2) )
     FORCE( NCDVal_MapInsert(m1, ids1, ids2) )
     
     
+    ASSERT( NCDVal_MapGetValue(m1, "_arg1").idx == ids2.idx )
+    
     print_value(m1, 0);
     print_value(m1, 0);
     
     
     NCDValRef copy = NCDVal_NewCopy(&mem, m1);
     NCDValRef copy = NCDVal_NewCopy(&mem, m1);

+ 31 - 3
ncd/NCDVal.c

@@ -178,9 +178,8 @@ static void NCDVal__AssertValOnly (NCDValMem *mem, NCDVal__idx idx)
             ASSERT(idx + sizeof(struct NCDVal__externalstring) <= mem->used)
             ASSERT(idx + sizeof(struct NCDVal__externalstring) <= mem->used)
             struct NCDVal__externalstring *exs_e = NCDValMem__BufAt(mem, idx);
             struct NCDVal__externalstring *exs_e = NCDValMem__BufAt(mem, idx);
             ASSERT(exs_e->data)
             ASSERT(exs_e->data)
-            ASSERT(exs_e->ref.next >= -1)
-            ASSERT(exs_e->ref.next < mem->used)
-            ASSERT(exs_e->ref.target)
+            ASSERT(!exs_e->ref.target || exs_e->ref.next >= -1)
+            ASSERT(!exs_e->ref.target || exs_e->ref.next < mem->used)
         } break;
         } break;
         default: ASSERT(0);
         default: ASSERT(0);
     }
     }
@@ -426,6 +425,7 @@ NCDValRef NCDVal_NewCopy (NCDValMem *mem, NCDValRef val)
         
         
         case EXTERNALSTRING_TYPE: {
         case EXTERNALSTRING_TYPE: {
             struct NCDVal__externalstring *exs_e = ptr;
             struct NCDVal__externalstring *exs_e = ptr;
+            ASSERT(exs_e->ref.target)
             
             
             return NCDVal_NewExternalString(mem, exs_e->data, exs_e->length, exs_e->ref.target);
             return NCDVal_NewExternalString(mem, exs_e->data, exs_e->length, exs_e->ref.target);
         } break;
         } break;
@@ -883,6 +883,7 @@ NCDRefTarget * NCDVal_ExternalStringTarget (NCDValRef externalstring)
     ASSERT(NCDVal_IsExternalString(externalstring))
     ASSERT(NCDVal_IsExternalString(externalstring))
     
     
     struct NCDVal__externalstring *exs_e = NCDValMem__BufAt(externalstring.mem, externalstring.idx);
     struct NCDVal__externalstring *exs_e = NCDValMem__BufAt(externalstring.mem, externalstring.idx);
+    ASSERT(exs_e->ref.target)
     return exs_e->ref.target;
     return exs_e->ref.target;
 }
 }
 
 
@@ -1226,6 +1227,33 @@ NCDValMapElem NCDVal_MapFindKey (NCDValRef map, NCDValRef key)
     return NCDVal__MapElem(ref.link);
     return NCDVal__MapElem(ref.link);
 }
 }
 
 
+NCDValRef NCDVal_MapGetValue (NCDValRef map, const char *key_str)
+{
+    ASSERT(NCDVal_IsMap(map))
+    ASSERT(key_str)
+    
+    NCDValMem mem;
+    mem.buf = NULL;
+    mem.size = NCDVAL_FASTBUF_SIZE;
+    mem.used = sizeof(struct NCDVal__externalstring);
+    mem.first_ref = -1;
+    
+    struct NCDVal__externalstring *exs_e = (void *)mem.fastbuf;
+    exs_e->type = EXTERNALSTRING_TYPE;
+    exs_e->data = key_str;
+    exs_e->length = strlen(key_str);
+    exs_e->ref.target = NULL;
+    
+    NCDValRef key = NCDVal__Ref(&mem, 0);
+    
+    NCDValMapElem elem = NCDVal_MapFindKey(map, key);
+    if (NCDVal_MapElemInvalid(elem)) {
+        return NCDVal_NewInvalid();
+    }
+    
+    return NCDVal_MapElemVal(map, elem);
+}
+
 static void replaceprog_build_recurser (NCDValMem *mem, NCDVal__idx idx, size_t *out_num_instr, NCDValReplaceProg *prog)
 static void replaceprog_build_recurser (NCDValMem *mem, NCDVal__idx idx, size_t *out_num_instr, NCDValReplaceProg *prog)
 {
 {
     ASSERT(idx >= 0)
     ASSERT(idx >= 0)

+ 7 - 0
ncd/NCDVal.h

@@ -623,6 +623,13 @@ NCDValRef NCDVal_MapElemVal (NCDValRef map, NCDValMapElem me);
  */
  */
 NCDValMapElem NCDVal_MapFindKey (NCDValRef map, NCDValRef key);
 NCDValMapElem NCDVal_MapFindKey (NCDValRef map, NCDValRef key);
 
 
+/**
+ * Retrieves the value reference to the value of the map entry whose key is a
+ * string value equal to the given null-terminated string. If there is no such
+ * entry, returns an invalid value reference.
+ */
+NCDValRef NCDVal_MapGetValue (NCDValRef map, const char *key_str);
+
 /**
 /**
  * Builds a placeholder replacement program, which is a list of instructions for
  * Builds a placeholder replacement program, which is a list of instructions for
  * efficiently replacing placeholders in identical values in identical memory
  * efficiently replacing placeholders in identical values in identical memory