コード例 #1
0
ファイル: bc_emit.c プロジェクト: kolab-groupware/cyrus-imapd
/* emit the bytecode for a test.  returns -1 on failure or size of
 * emitted bytecode on success */
static int bc_test_emit(int fd, int *codep, bytecode_info_t *bc)
{
    int opcode;
    int wrote=0;/* Relative offset to account for interleaved strings */

    int ret; /* Temporary Return Value Variable */

    /* Output this opcode */
    opcode = bc->data[(*codep)++].op;
    if(write_int(fd, opcode) == -1)
        return -1;
    wrote += sizeof(int);

    switch(opcode) {
    case BC_TRUE:
    case BC_FALSE:
        /* No parameter opcodes */
        break;

    case BC_NOT:
    {
        /* Single parameter: another test */
        ret = bc_test_emit(fd, codep, bc);
        if(ret < 0)
            return -1;
        else
            wrote+=ret;
        break;
    }

    case BC_ALLOF:
    case BC_ANYOF:
        /*where we jump to?*/
        /* Just drop a testlist */
        ret = bc_testlist_emit(fd, codep, bc);
        if(ret < 0)
            return -1;
        else
            wrote+=ret;
        break;

    case BC_SIZE:
        /* Drop tag and number */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        if(write_int(fd, bc->data[(*codep)+1].value) == -1)
            return -1;

        wrote += 2 * sizeof(int);
        (*codep) += 2;
        break;

    case BC_EXISTS:
    {
        int ret;
        ret = bc_stringlist_emit(fd, codep, bc);
        if(ret < 0) return -1;
        wrote += ret;
        break;
    }

    case BC_HEADER:
    case BC_HASFLAG:
    {
        int ret;
        if (BC_HEADER == opcode) {
        /* drop index */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        }
        /* Drop match type */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*now drop relation*/
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*drop comparator */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /* Now drop haystacks */
        ret = bc_stringlist_emit(fd, codep, bc);
        if(ret < 0) return -1;
        wrote+=ret;
        /* Now drop needles */
        ret = bc_stringlist_emit(fd, codep, bc);
        if(ret < 0) return -1;
        wrote+=ret;
        break;
    }

    case BC_ADDRESS:
        /* drop index */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;

        /* fall-through */
    case BC_ENVELOPE:
    {
        int ret;
        /* Drop match type */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*drop comparator */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*now drop relation*/
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*now drop address part*/
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /* Now drop headers */
        ret = bc_stringlist_emit(fd, codep, bc);
        if(ret < 0) return -1;
        wrote+=ret;
        /* Now drop data */
        ret = bc_stringlist_emit(fd, codep, bc);
        if(ret < 0) return -1;
        wrote+=ret;
        break;
    }

    case BC_BODY:
    {
        int ret;
        /* Drop match type */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*drop comparator */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*now drop relation*/
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*now drop transform*/
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*now drop offset*/
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;
        /*now drop content-types*/
        ret = bc_stringlist_emit(fd, codep, bc);
        if(ret < 0) return -1;
        wrote+=ret;
        /* Now drop data */
        ret = bc_stringlist_emit(fd, codep, bc);
        if(ret < 0) return -1;
        wrote+=ret;
        break;
    }

    case BC_DATE:
    case BC_CURRENTDATE:
    {
        int ret;
        int datalen;
        int tmp;

        /* drop index */
        if(BC_DATE == opcode) {
                if(write_int(fd, bc->data[(*codep)].value) == -1)
                    return -1;
                wrote += sizeof(int);
                (*codep)++;
        }

        /* drop zone tag */
        tmp = bc->data[(*codep)].value;
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;

        /* drop timezone offset */
        if (tmp == B_TIMEZONE) {
                if(write_int(fd, bc->data[(*codep)].value) == -1)
                    return -1;
                wrote += sizeof(int);
                (*codep)++;
        }

        /* drop match type */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;

        /* drop relation */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;

        /* drop comparator */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;

        /* drop date-part */
        if(write_int(fd, bc->data[(*codep)].value) == -1)
            return -1;
        wrote += sizeof(int);
        (*codep)++;

        if (BC_DATE == opcode) {
                /* drop header-name */
                datalen = bc->data[(*codep)++].len;

                if(write_int(fd, datalen) == -1) return -1;
                wrote += sizeof(int);

                if(write(fd, bc->data[(*codep)++].str, datalen) == -1) return -1;
                wrote += datalen;

                ret = align_string(fd,datalen);
                if(ret == -1) return -1;

                wrote+=ret;
        }

        /* drop keywords */
        ret = bc_stringlist_emit(fd, codep, bc);
        if(ret < 0) return -1;
        wrote+=ret;

        break;
    }

    default:
        /* Unknown testcode? */
        return -1;
    }
    return wrote;
}
コード例 #2
0
ファイル: bc_emit.c プロジェクト: ajwans/cyrus-imapd
/* emit the bytecode for a test.  returns -1 on failure or size of
 * emitted bytecode on success */
static int bc_test_emit(int fd, int *codep, bytecode_info_t *bc) 
{
    int wrote=0;/* Relative offset to account for interleaved strings */
    
    
    int ret; /* Temporary Return Value Variable */
    
    /* Output this opcode */
    if(write_int(fd, bc->data[(*codep)].op) == -1)
	return -1;
    wrote += sizeof(int);
    
    switch(bc->data[(*codep)++].op) {
    case BC_TRUE:
    case BC_FALSE:
	/* No parameter opcodes */
	break;
	
    case BC_NOT:
    {
	/* Single parameter: another test */
	ret = bc_test_emit(fd, codep, bc);
	if(ret < 0)
	    return -1;
	else
	    wrote+=ret;
	break;
    }
    
    case BC_ALLOF:
    case BC_ANYOF:
	/*where we jump to?*/
	/* Just drop a testlist */
	ret = bc_testlist_emit(fd, codep, bc);
	if(ret < 0)
	    return -1;
	else
	    wrote+=ret;
	break;
	
    case BC_SIZE:
	/* Drop tag and number */
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	if(write_int(fd, bc->data[(*codep)+1].value) == -1)
	    return -1;
	
	wrote += 2 * sizeof(int);
	(*codep) += 2;
	break;
	
    case BC_EXISTS:
    {
	int ret;
	ret = bc_stringlist_emit(fd, codep, bc);
	if(ret < 0) return -1;
	wrote += ret;
	break;
    }
    
    case BC_HEADER:
    {
	int ret;
	/* Drop match type */
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/*drop comparator */
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;    
	/*now drop relation*/
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/* Now drop headers */
	ret = bc_stringlist_emit(fd, codep, bc);
	if(ret < 0) return -1;
	wrote+=ret;
	/* Now drop data */
	ret = bc_stringlist_emit(fd, codep, bc);
	if(ret < 0) return -1;
	wrote+=ret;
	break;
    }
    
    case BC_ADDRESS:
    case BC_ENVELOPE:
    {
	int ret;
	/* Drop match type */
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/*drop comparator */
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/*now drop relation*/
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/*now drop address part*/
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/* Now drop headers */
	ret = bc_stringlist_emit(fd, codep, bc);
	if(ret < 0) return -1;
	wrote+=ret;
	/* Now drop data */
	ret = bc_stringlist_emit(fd, codep, bc);
	if(ret < 0) return -1;
	wrote+=ret;
	break;
    }
    
    case BC_BODY:
    {
	int ret;
	/* Drop match type */
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/*drop comparator */
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/*now drop relation*/
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/*now drop transform*/
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/*now drop offset*/
	if(write_int(fd, bc->data[(*codep)].value) == -1)
	    return -1;
	wrote += sizeof(int);
	(*codep)++;
	/*now drop content-types*/
	ret = bc_stringlist_emit(fd, codep, bc);
	if(ret < 0) return -1;
	wrote+=ret;
	/* Now drop data */
	ret = bc_stringlist_emit(fd, codep, bc);
	if(ret < 0) return -1;
	wrote+=ret;
	break;
    }
    
    default:
	/* Unknown testcode? */
	return -1;
    }
    return wrote;
}