chiark / gitweb /
mask-map lookup seems to work
authorian <ian>
Thu, 25 Nov 2004 02:02:52 +0000 (02:02 +0000)
committerian <ian>
Thu, 25 Nov 2004 02:02:52 +0000 (02:02 +0000)
base/chiark-tcl.h
hbytes/hbytes.h
maskmap/maskmap.c

index 17a05942b84a6b69b887fc015309c55f944993cb..4b4f4e8210ecacf106d8a8671f5dc5a9ada13380 100644 (file)
@@ -66,7 +66,7 @@
  *               ulong VARNAME/VALUE         VALUE if bitfields2ul)
  *
  *  hbytes mask-map lookup MAP-VAR ADDRESS [DEFAULT]   => DATA
- *     error on missing default or if address too short
+ *     error on missing default or if any prefix longer than address
  *  hbytes mask-map amend MAP-VAR PREFIX PREFIX-LENGTH DATA
  *     a maskmap MAP is [list [list PREFIX PREFIX-LENGTH DATA]] sorted
  *     first by descending PREFIX-LENGTH and then by ascending PREFIX
@@ -86,6 +86,8 @@
  * HBYTES LENGTH MISMATCH              when blocks must be exactly same length
  * HBYTES SYNTAX                       supposed hex block had wrong syntax
  * HBYTES VALUE OVERFLOW               value to be conv'd to hex too big/long
+ * HBYTES MASKMAP NOMATCH              no addr/mask matches address for lookup
+ * HBYTES MASKMAP UNDERRUN             addr value for lookup is too short
  * HBYTES MASKMAP SYNTAX LLENGTH       value for mask-map entry not llength==3
  * HBYTES MASKMAP SYNTAX UNDERRUN      value for mask-map entry hex too short
  * HBYTES MASKMAP SYNTAX OVERRUN       actual mask-map entry hex too short
index 17a05942b84a6b69b887fc015309c55f944993cb..4b4f4e8210ecacf106d8a8671f5dc5a9ada13380 100644 (file)
@@ -66,7 +66,7 @@
  *               ulong VARNAME/VALUE         VALUE if bitfields2ul)
  *
  *  hbytes mask-map lookup MAP-VAR ADDRESS [DEFAULT]   => DATA
- *     error on missing default or if address too short
+ *     error on missing default or if any prefix longer than address
  *  hbytes mask-map amend MAP-VAR PREFIX PREFIX-LENGTH DATA
  *     a maskmap MAP is [list [list PREFIX PREFIX-LENGTH DATA]] sorted
  *     first by descending PREFIX-LENGTH and then by ascending PREFIX
@@ -86,6 +86,8 @@
  * HBYTES LENGTH MISMATCH              when blocks must be exactly same length
  * HBYTES SYNTAX                       supposed hex block had wrong syntax
  * HBYTES VALUE OVERFLOW               value to be conv'd to hex too big/long
+ * HBYTES MASKMAP NOMATCH              no addr/mask matches address for lookup
+ * HBYTES MASKMAP UNDERRUN             addr value for lookup is too short
  * HBYTES MASKMAP SYNTAX LLENGTH       value for mask-map entry not llength==3
  * HBYTES MASKMAP SYNTAX UNDERRUN      value for mask-map entry hex too short
  * HBYTES MASKMAP SYNTAX OVERRUN       actual mask-map entry hex too short
index 9c92810f0197c4a5d8aea6356ba72ba36e5bb2f5..f51dba4b19cf587690b170174a9c933dd36b6150 100644 (file)
@@ -171,11 +171,45 @@ int do_maskmap_amend(ClientData cd, Tcl_Interp *ip,
 }
 
 int do_maskmap_lookup(ClientData cd, Tcl_Interp *ip,
-                     Tcl_Obj *mapo, HBytes_Value addr, Tcl_Obj *def,
+                     Tcl_Obj *mapo, HBytes_Value addrhb, Tcl_Obj *def,
                      Tcl_Obj **result) {
-  /*MaskMap_Var *map= (void*)&mapo->internalRep;*/
-  *result= Tcl_NewIntObj(42);
-  return TCL_OK; /*fixme*/
+  MaskMap_Value *mm= (void*)&mapo->internalRep;
+  MaskMap_Entry *search;
+  const Byte *addr= hbytes_data(&addrhb);
+  int addrbytes= hbytes_len(&addrhb);
+  int i, directbytes, leftoverbits;
+
+  search= mm->entries;
+  if (!search || search->prefixlen==-1) goto not_found;
+
+  /* longest masks are first, so we can test this once */
+  if (addrbytes < prefix_bytes(search->prefixlen))
+    return staticerr(ip, "address shorter than mask(s) in map",
+                    "HBYTES MASKMAP UNDERRUN");
+
+  for (i=0;
+       i < mm->allocd && search->prefixlen != -1;
+       i++, search++) {
+    directbytes= search->prefixlen / 8;
+    if (memcmp(search->prefix, addr, directbytes)) continue;
+
+    leftoverbits= search->prefixlen % 8;
+    if (leftoverbits)
+      if ((addr[directbytes] & (0xffu << leftoverbits))
+         != search->prefix[directbytes])
+       continue;
+
+    /*found*/
+    *result= search->data;
+    return TCL_OK;
+  }
+
+ not_found:
+  if (!def)
+    return staticerr(ip, "address not found in mask-map",
+                    "HBYTES MASKMAP NOMATCH");
+  *result= def;
+  return TCL_OK;
 }
 
 /*---------- Tcl type and arg parsing functions ----------*/