-int pat_maskmapv(Tcl_Interp *ip, Tcl_Obj *var, MaskMap_Var *agg) {
- int rc;
- rc= pat_somethingv(ip,var,&agg->sth,&maskmap_type); if (rc) return rc;
- agg->mm= (void*)&agg->sth.obj->internalRep;
- return TCL_OK;
-}
-
-static void maskmap_t_free(Tcl_Obj *o) {
- MaskMap_Value *mm= (void*)&o->internalRep;
- MaskMap_Entry *mme;
- int i;
-
- for (i=0, mme=mm->entries; i<mm->used; i++, mme++) {
- if (mme->prefixlen==-1) break;
- mme_free(mme);
- }
-}
-
-static void maskmap_t_dup(Tcl_Obj *sob, Tcl_Obj *dob) {
- MaskMap_Value *sm= (void*)&sob->internalRep;
- MaskMap_Value *dm= (void*)&dob->internalRep;
- MaskMap_Entry *sme, *dme;
- int i, nbytes;
-
- assert(sob->typePtr == &maskmap_type);
- objfreeir(dob);
-
- mm_init(dm);
- mm_reallocentries(dm,sm->used);
- dm->used= sm->used;
- for (i=0, sme=sm->entries, dme=dm->entries;
- i < dm->used;
- i++, sme++, dme++) {
- *dme= *sme;
- nbytes= prefix_bytes(sme->prefixlen);
- dme->prefix= TALLOC(nbytes); assert(dme->prefix);
- memcpy(dme->prefix, sme->prefix, nbytes);
- Tcl_IncrRefCount(dme->data);
- }
- dob->typePtr= &maskmap_type;
-}
-
-static void maskmap_t_ustr(Tcl_Obj *so) {
- MaskMap_Value *sm= (void*)&so->internalRep;
- Tcl_Obj **mainlobjsl, *mainobj;
- int i;
-
- assert(so->typePtr == &maskmap_type);
- mainlobjsl= TALLOC(sizeof(*mainlobjsl) * sm->used); assert(mainlobjsl);
-
- for (i=0; i<sm->used; 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(0, 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(sm->used,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 rc, len, eol, i;
- MaskMap_Value mm;
- MaskMap_Entry *mme;
- Tcl_Obj *eo, *prefixo, *prefixleno;
-
- mm_init(&mm);
-
- rc= Tcl_ListObjLength(ip,o,&len); if (rc) goto x_rc;
- mm_reallocentries(&mm, len);
-
- for (i=0, mme=mm.entries; i < len; i++, mme++) {
- 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",
- "HBYTES MASKMAP SYNTAX LLENGTH");
- goto x_rc;
- }
- rc= Tcl_ListObjIndex(ip,eo,0,&prefixo); if (rc) goto x_rc;
- rc= Tcl_ListObjIndex(ip,eo,1,&prefixleno); if (rc) goto x_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(ip, mme, prefixo, prefixleno, 1);
- if (rc) goto x_rc;
-
- mm->used++;
-
- if (i>0) {
- if (mme_ordercompare(mme-1, mme) <= 0) {
- rc= staticerr(ip, "mask-map entries out of order",
- "HBYTES MASKMAP SYNTAX 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:
- for (mme=mm.entries, i=0; i<mm.used; i++, mme++)
- mme_free(mme);
- TFREE(mm.entries);
- return rc;
-}
-
-Tcl_ObjType maskmap_type = {
- "mask-map",
- maskmap_t_free, maskmap_t_dup, maskmap_t_ustr, maskmap_t_sfa
-};