chiark / gitweb /
some maskmap stuff;
authorian <ian>
Sun, 21 Nov 2004 22:05:32 +0000 (22:05 +0000)
committerian <ian>
Sun, 21 Nov 2004 22:05:32 +0000 (22:05 +0000)
base/hook.c
hbytes/hook.c
maskmap/maskmap.c

index e067c94..8ef140f 100644 (file)
@@ -421,6 +421,7 @@ int Hbytes_Init(Tcl_Interp *ip) {
   Tcl_RegisterObjType(&sockaddr_type);
   Tcl_RegisterObjType(&tabledataid_nearlytype);
   Tcl_RegisterObjType(&ulong_type);
+  Tcl_RegisterObjType(&maskmap_type);
 
   for (cmd=toplevel_commands;
        cmd->name;
index e067c94..8ef140f 100644 (file)
@@ -421,6 +421,7 @@ int Hbytes_Init(Tcl_Interp *ip) {
   Tcl_RegisterObjType(&sockaddr_type);
   Tcl_RegisterObjType(&tabledataid_nearlytype);
   Tcl_RegisterObjType(&ulong_type);
+  Tcl_RegisterObjType(&maskmap_type);
 
   for (cmd=toplevel_commands;
        cmd->name;
index 9968801..bb1e258 100644 (file)
@@ -34,10 +34,141 @@ int do_maskmap_lookup(ClientData cd, Tcl_Interp *ip,
   return TCL_OK;
 }
 
-static void maskmap_t_free(Tcl_Obj *o) { }
-static void maskmap_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { }
-static void maskmap_t_ustr(Tcl_Obj *o) { }
-static int maskmap_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) { return TCL_ERROR; }
+static int prefix_bytes (int prefixlen) {
+  return (prefixlen + 7)/8;
+}
+
+static void mme_init(MaskMap_Entry *mme) {
+  mme->prefix= 0;
+  mme->data= 0;
+}
+
+static int mm_count(const MaskMap_Value *mm) {
+  int i;
+  for (i=0; i<sm->allocd && sm->entries[i].prefixlen != -1; i++);
+  return i;
+}
+
+static void mm_allocentries(MaskMap_Value *mm, int len) {
+  int i;
+  mm->allocd= len;
+  mm->entries= Tcl_Alloc(sizeof(*mm->entries) * len);
+  assert(mm->entries);
+  for (i=0; i < len; i++)
+    mme_init(&mm->entries[i]);
+}
+  
+static void maskmap_t_free(Tcl_Obj *o) {
+  MaskMap_Value *mm= (void*)&o->internalRep;
+  for (i=0; i<mm.allocd; i++) {
+    if (i.prefixlen==-1) break;
+    mme_free(&mm.entries[i]);
+  }
+}
+
+static void maskmap_t_dup(Tcl_Obj *so, Tcl_Obj *do) {
+  MaskMap_Value *sm= (void*)&so->internalRep;
+  MaskMap_Value *dm= (void*)&do->internalRep;
+  int l, i, nbytes;
+
+  assert(so->typePtr == &maskmap_type);
+  objfreeir(do);
+  l= mm_count(&sm);
+
+  mm_allocentries(&dm,l);
+  for (i=0, sme=sm->entries, dme=dm->entries;
+       i<dm->allocd;
+       i++, sme++, dme++) {
+    *dme= *sme;
+    nbytes= prefix_bytes(sme->prefixlen);
+    dme->prefix= Tcl_Alloc(nbytes);  assert(dme->prefix);
+    memcpy(dme->prefix, sme->prefix, nbytes);
+    Tcl_IncrRefCount(dme->data);
+  }
+}
+
+static void maskmap_t_ustr(Tcl_Obj *so) {
+  MaskMap_Value *sm= (void*)&so->internalRep;
+  Tcl_Obj **mainlobjsl, *mainobj;
+  char *string;
+  int stringl;
+
+  assert(so->typePtr == &maskmap_type);
+  l= mm_count(sm);
+  mainlobjsl= Tcl_Alloc(sizeof(*mainobjsl) * l);  assert(mainlobjsl);
+
+  for (i=0; i<l; i++) {
+    MaskMap_Entry *sme= &sm->entries[i];
+    HBytes_Value hb;
+    Tcl_Obj *subl[3], *sublo;
+
+    hbytes_array(&hb, sme->prefix, prefix_bytes(sme->prefixlen));
+    subl[0]= ret_hb(ip, &hb);  assert(subl[0]);
+    subl[1]= Tcl_NewIntObj(sme->prefixlen);  assert(subl[1]);
+    subl[2]= sme->data;
+    
+    sublo= Tcl_NewListObj(3,subl);  assert(sublo);
+    mainlobjsl[i]= sublo;
+  }
+
+  mainobj= Tcl_NewListObj(l,mainlobjsl);  assert(mainobj);
+  so->bytes= Tcl_GetStringFromObj(mainobj, &so->length);  assert(so->bytes);
+  mainobj->bytes= 0; mainobj->length= 0; /* we stole it */
+}
+
+static int maskmap_t_sfa(Tcl_Interp *ip, Tcl_Obj *o) {
+  int len, eol;
+  MaskMap_Value mm;
+
+  mm.allocd= 0;
+  mm.entries= 0;
+  
+  rc= Tcl_ListObjLength(ip,o,&len);  if (rc) goto x_rc;
+  mm_allocentries(len);
+  
+  for (i=0; i<len; i++) {
+    rc= Tcl_ListObjIndex(ip,o,i,&eo);  if (rc) goto x_rc;
+    rc= Tcl_ListObjLength(ip,eo,&eol);  if (rc) goto x_rc;
+    if (eol != 3) {
+      rc= staticerr(ip, "mask-map entry length != 3");
+      goto x_rc;
+    }
+    rc= Tcl_ListObjIndex(ip,eo,0,&prefixo);  if (rc) goto rc;
+    rc= Tcl_ListObjIndex(ip,eo,1,&prefixleno);  if (rc) goto rc;
+    rc= Tcl_ListObjIndex(ip,eo,2,&mm.entries[i].data);  if (rc) goto x_rc;
+    Tcl_IncrRefCount(mm.entries[i].data);
+
+    rc= mme_parsekey(&mm.entries[i], prefixo, prefixleno, 1);
+    if (rc) goto rc;
+
+    if (i>0) {
+      if (mme_compare(&mm.entries[i-1], &mm.entries[i]) <= 0) {
+       rc= staticerr(ip, "mask-map entries out of order");
+       goto x_rc;
+      }
+    }
+  }
+
+  /* we commit now */
+  assert(sizeof(mm) <= sizeof(o.internalRep));
+  objfreeir(o);
+  memcpy(&o.internalRep, &mm, sizeof(mm));
+  o.typePtr= &maskmap_type;
+  return TCL_OK;
+
+x_rc:
+  if (mm.entries) {
+    for (i=0; i<len; i++)
+      mme_free(&mm.entries[i]);
+    Tcl_Free(mm.entries);
+  }
+  return rc;
+}
+
+    { free(mm.e
+  return rc;
+  rc= Tcl_ConvertToType(ip,o,
+}
 
 Tcl_ObjType maskmap_type = {
   "mask-map",