Ejemplo n.º 1
0
//dtree lookup
void *dtree_get(const dtree_dt_index *h,const char *str,dtree_flag_f filter)
{
    const dtree_dt_node *ret;
    const dtree_dt_node *fnode;
    
    if(!str || !h->head)
        return NULL;
    
    ret=dtree_get_node(h,str,DTREE_S_FLAG_NONE,0);
    
    if(ret)
    {
        if(filter)
        {
            fnode=dtree_get_flag(h,ret,filter,0);
            
            if(fnode)
                return fnode->payload;
        }
        else
            return ret->payload;
    }
    
    return NULL;
}
Ejemplo n.º 2
0
//searches for a token with regex
static const dtree_dt_node *dtree_search_node(const dtree_dt_index *h,const dtree_dt_node *n,const char *t,dtree_pos_f pos)
{
    unsigned int hash;
    dtree_flag_f rf,nf;
    packed_ptr pp;
    const dtree_dt_node *rflag;
    
    if(!n || !n->curr)
        return NULL;
    
    //bad match
    if(n->data!=*t && n->data!=(*t|0x20) && n->data!=DTREE_PATTERN_ANY)
        return NULL;
    
    t++;
    hash=dtree_hash_char(*t);
    
    //EOS
    if(!hash && *t!='0')
    {
        //only quit if strong with position
        if(dtree_get_flag(h,n,DTREE_DT_FLAG_STRONG,pos))
            return n;
        else if(!n->flags)
            return NULL;
    }
    
    pp=n->nodes[hash];
    rflag=DTREE_DT_GETPP(h,pp);
    
    if(pp)
        rflag=dtree_search_node(h,rflag,t,pos);
    else
        rflag=NULL;
    
    //wildcard
    if(!rflag)
    {
        hash=DTREE_HASH_ANY;
        
        pp=n->nodes[hash];
        rflag=DTREE_DT_GETPP(h,pp);
        
        if(pp)
            rflag=dtree_search_node(h,rflag,t,pos);
        else
            rflag=NULL;
        
        hash=dtree_hash_char(*t);
    }
    
    //n is lazy EOT or stronger match
    if((n->flags & DTREE_DT_FLAG_TOKEN) && ((!hash && *t!='0') || hash>=DTREE_HASH_SEP))
    {
        nf=dtree_get_flags(h,n,pos);
        rf=dtree_get_flags(h,rflag,pos);
        
        if(!rflag)
            rflag=n;
        else if((nf & DTREE_DT_FLAG_STRONG) && !(rf & DTREE_DT_FLAG_STRONG))
            rflag=n;
        else if(rf & DTREE_DT_FLAG_STRONG);
        else if((nf & DTREE_DT_FLAG_CHAIN) && !(nf & DTREE_DT_FLAG_BCHAIN) &&
                !(rf & DTREE_DT_FLAG_CHAIN) && !(rf & DTREE_DT_FLAG_BCHAIN))
            rflag=n;
        else if(rf & DTREE_DT_FLAG_CHAIN);
        else if((nf & DTREE_DT_FLAG_WEAK) && !(rf & DTREE_DT_FLAG_WEAK))
            rflag=n;
    }
    
    return rflag;
}
Ejemplo n.º 3
0
//classifies a string
const dclass_keyvalue *dclass_classify(const dclass_index *di,const char *str)
{
    int on=0;
    int valid;
    int bcvalid;
    int i;
    char buf[DTREE_DATA_BUFLEN];
    const char *p;
    const char *token="";
    packed_ptr pp;
    const dtree_dt_node *wnode=NULL;
    const dtree_dt_node *nnode=NULL;
    const dtree_dt_node *fbnode;
    const dtree_dt_node *fnode;
    const dtree_dt_index *h=&di->dti;
    const void *cnodes[DTREE_S_MAX_CHAIN]={NULL};
    
    if(!str || !h->head)
        return dclass_get_kverror(di);
    
    dtree_printd(DTREE_PRINT_CLASSIFY,"dtree_classify() UA: '%s'\n",str);
    
    for(p=str;*p;p++)
    {
        valid=0;
        
        if((*p>='a' && *p<='z') || (*p>='A' && *p<='Z') || (*p>='0' && *p<='9'))
        {
            //new token found
            if(!on)
            {
                token=p;
                on=1;
            }
            
            valid=1;
        }
        
        if((!valid || (!*(p+1))) && on)
        {
            //EOT found
            fbnode=dtree_get_node(h,token,0);
            
            dtree_printd(DTREE_PRINT_CLASSIFY,"dtree_classify() token:'%s' = '%s':%d\n",
                    token,fbnode?dtree_node_path(h,fbnode,buf):"",fbnode?(int)fbnode->flags:0);
            
            if(fbnode && dtree_get_flag(h,fbnode,DTREE_DT_FLAG_TOKEN))
            {
                if((fnode=dtree_get_flag(h,fbnode,DTREE_DT_FLAG_STRONG)))
                    return fnode->payload;
                else if((fnode=dtree_get_flag(h,fbnode,DTREE_DT_FLAG_WEAK)))
                {
                    i=DTREE_DC_DISTANCE(h,(char*)fnode->payload);
                    if(!wnode || (i>=0 && i<DTREE_DC_DISTANCE(h,(char*)wnode->payload)))
                        wnode=fnode;
                }
                else if((fnode=dtree_get_flag(h,fbnode,DTREE_DT_FLAG_NONE)))
                {
                    i=DTREE_DC_DISTANCE(h,(char*)fnode->payload);
                    if(!nnode || (i>=0 && i<DTREE_DC_DISTANCE(h,(char*)nnode->payload)))
                        nnode=fnode;
                }
                
                if((fnode=dtree_get_flag(h,fbnode,DTREE_DT_FLAG_CHAIN)))
                {
                    dtree_printd(DTREE_PRINT_CLASSIFY,"dtree_classify() pchain detected\n");
                    
                    pp=fnode->curr;

                    while(pp)
                    {
                        bcvalid=0;
                        
                        if(fnode->flags & DTREE_DT_FLAG_CHAIN && fnode->cparam)
                        {   
                            dtree_printd(DTREE_PRINT_CLASSIFY,"dtree_classify() looking for pchain %p\n",fnode->cparam);
                            for(i=0;i<DTREE_S_MAX_CHAIN && cnodes[i];i++)
                            {
                                //chain hit
                                if(cnodes[i]==fnode->cparam)
                                {
                                    if(fnode->flags & DTREE_DT_FLAG_BCHAIN)
                                        bcvalid=1;
                                    else
                                        return fnode->payload;
                                }
                            }
                        }
                        
                        if(fnode->flags & DTREE_DT_FLAG_BCHAIN && (bcvalid || !fnode->cparam))
                        {
                            for(i=0;i<DTREE_S_MAX_CHAIN;i++)
                            {
                                if(!cnodes[i])
                                {
                                    cnodes[i]=fnode->payload;
                                    dtree_printd(DTREE_PRINT_CLASSIFY,"dtree_classify() pchain added: %p('%d')\n",fnode->payload,i);
                                    break;
                                }
                            }
                        }
                        
                        pp=fnode->dup;
                        fnode=DTREE_DT_GETPP(h,pp);
                    }
                }
            }
            on=0;
        }
    }
    
    if(wnode)
        return wnode->payload;
    else if(nnode)
        return nnode->payload;
    
    return dclass_get_kverror(di);
}
Ejemplo n.º 4
0
//searches for a token with regex
static const dtree_dt_node *dtree_search_node(const dtree_dt_index *h,const dtree_dt_node *n,const char *t)
{
    int hash;
    flag_f rf,nf;
    packed_ptr pp;
    const dtree_dt_node *rflag;
    
    if(!n)
        return NULL;
    
    //bad match
    if(n->data!=*t && n->data!=(*t|0x20) && n->data!=DTREE_PATTERN_ANY)
        return NULL;
    
    t++;
    hash=dtree_hash_char(*t);
    
    //lazy EOT
    if((!hash && *t!='0') || hash>=DTREE_HASH_SEP)
    {
        //only quit if strong
        if(dtree_get_flag(h,n,DTREE_DT_FLAG_STRONG))
            return n;
        else if(!t && !n->flags)
            return NULL;
    }
    
    pp=n->nodes[hash];
    rflag=DTREE_DT_GETPP(h,pp);
    
    if(rflag && *t)
        rflag=dtree_search_node(h,rflag,t);
    
    //wildcard
    if(!rflag)
    {
        hash=dtree_hash_char(DTREE_PATTERN_ANY);
        
        pp=n->nodes[hash];
        rflag=DTREE_DT_GETPP(h,pp);
        
        if(rflag)
            rflag=dtree_search_node(h,rflag,t);
        
        hash=dtree_hash_char(*t);
    }
    
    //partial
    if(!rflag && (n->flags & DTREE_DT_FLAG_TOKEN) && (h->sflags & DTREE_S_FLAG_PARTIAL))
    {
        if(dtree_node_depth(h,n)>=DTREE_S_PART_TLEN)
            rflag=n;
    }
    
    //n is lazy EOT or stronger match
    if((n->flags & DTREE_DT_FLAG_TOKEN) && ((hash==0 && *t!='0') || hash>=DTREE_HASH_SEP))
    {
        nf=dtree_get_flags(h,n);
        rf=dtree_get_flags(h,rflag);
        
        if(!rflag)
            rflag=n;
        else if((nf & DTREE_DT_FLAG_STRONG) && !(rf & DTREE_DT_FLAG_STRONG))
            rflag=n;
        else if((rf & DTREE_DT_FLAG_STRONG));
        else if((nf & DTREE_DT_FLAG_CHAIN) && !(nf & DTREE_DT_FLAG_BCHAIN) &&
                !(rf & DTREE_DT_FLAG_CHAIN) && !(rf & DTREE_DT_FLAG_BCHAIN))
            rflag=n;
        else if((rf & DTREE_DT_FLAG_CHAIN));
        else if((nf & DTREE_DT_FLAG_WEAK))
            rflag=n;
    }
    
    return rflag;
}