예제 #1
0
파일: daoValue.c 프로젝트: wherby/dao
DaoTuple* DaoProcess_NewTuple( DaoProcess *self, int count )
{
	int i, N = abs( count );
	int M = self->factory->size;
	DaoValue **values = self->factory->items.pValue;
	DaoTuple *res = NULL;
	if( count < 0 ){
		if( M < N ) return NULL;
		res = DaoTuple_New( N );
		for(i=0; i<N; i++) DaoTuple_SetItem( res, values[M-N+i], i );
	}
	if( res == NULL ) res = DaoTuple_New( N );
	DaoProcess_CacheValue( self, (DaoValue*) res );
	return res;
}
예제 #2
0
int DaoProcess_Resume( DaoProcess *self, DaoValue *par[], int N, DaoProcess *ret )
{
	DaoType *tp;
	DaoVmCode *vmc;
	DaoTuple *tuple;
	if( self->status != DAO_PROCESS_SUSPENDED ) return 0;
	if( self->activeCode && self->activeCode->code == DVM_MCALL ){
		tp = self->activeTypes[ self->activeCode->c ];
		if( N == 1 ){
			DaoProcess_PutValue( self, par[0] );
		}else if( N ){ /* TODO */
			tuple = DaoTuple_New( N );
			tuple->ctype = tp;
			GC_IncRC( tuple->ctype );
			DaoProcess_MakeTuple( self, tuple, par, N );
			DaoProcess_PutValue( self, (DaoValue*) tuple );
		}
	}else if( N ){ /* TODO */
		DaoRoutine *rout = self->topFrame->routine;
		self->paramValues = self->stackValues + self->topFrame->stackBase;
		if( rout ) rout = DaoProcess_PassParams( self, rout, NULL, NULL, par, NULL, N, DVM_CALL );
		self->paramValues = self->stackValues + 1;
		if( rout == NULL ){
			DaoProcess_RaiseError( ret, NULL, "invalid parameters." );
			return 0;
		}
	}
	DaoProcess_Start( self );
	DaoProcess_PutValue( ret, self->stackValues[0] );
	return 1;
}
예제 #3
0
static void TEST_AssertEq( DaoProcess *proc, DaoValue* p[], int N )
{
	if ( DaoValue_ComparePro( p[0], p[1], proc ) != 0 ){
		DaoTuple *tup = DaoTuple_New( 2 );
		DaoTuple_SetItem( tup, p[0], 0 );
		DaoTuple_SetItem( tup, p[1], 1 );
		DaoProcess_RaiseException( proc, "Error::Test::AssertEqual", "", (DaoValue*)tup );
	}
}
예제 #4
0
static void TEST_AssertRange( DaoProcess *proc, DaoValue* p[], int N )
{
	if ( DaoValue_ComparePro( p[0], p[1]->xTuple.values[0], proc ) < 0 || DaoValue_ComparePro( p[0], p[1]->xTuple.values[1], proc ) > 0 ){
		DaoTuple *tup = DaoTuple_New( 2 );
		DaoTuple_SetItem( tup, p[0], 0 );
		DaoTuple_SetItem( tup, p[1], 1 );
		DaoProcess_RaiseException( proc, "Error::Test::AssertInRange", "", (DaoValue*)tup );
	}
}
예제 #5
0
파일: daoValue.c 프로젝트: daokoder/dao
static int DaoValue_TryCastTuple( DaoValue *src, DaoValue **dest, DaoType *tp )
{
	DaoTuple *tuple;
	DaoType **item_types = tp->args->items.pType;
	DaoType *totype = src->xTuple.ctype;
	DaoValue **data = src->xTuple.values;
	DMap *names = totype ? totype->mapNames : NULL;
	DNode *node, *search;
	daoint i, T = tp->args->size;
	int tm, eqs = 0;
	/*
	// Auto-cast tuple type, on the following conditions:
	// (1) the item values of "dest" must match exactly to the item types of "tp";
	// (2) "tp->mapNames" must contain "(*dest)->xTuple.ctype->mapNames";
	*/
	if( src->xTuple.ctype == NULL ){
		GC_IncRC( tp );
		src->xTuple.ctype = tp;
		return 1;
	}
	if( DaoType_MatchValue( tp, src, NULL ) < DAO_MT_SIM ) return 1; /* Redundant? */
	/*
	// Casting is not necessary if the tuple's field names are a superset of the
	// field names of the target type:
	*/
	if( tp->mapNames == NULL || tp->mapNames->size ==0 ) goto Finalize;
	if( names ){
		daoint count = 0;
		for(node=DMap_First(names); node; node=DMap_Next(names,node)){
			search = DMap_Find( tp->mapNames, node->key.pVoid );
			if( search && node->value.pInt != search->value.pInt ) return 0;
			count += search != NULL;
		}
		/* be superset of the field names of the target type: */
		if( count == tp->mapNames->size ) goto Finalize;
	}
Finalize:
	tuple = DaoTuple_New( T );
	for(i=0; i<T; i++){
		DaoType *it = item_types[i];
		if( it->tid == DAO_PAR_NAMED ) it = & it->aux->xType;
		DaoValue_Move( data[i], tuple->values+i, it );
	}
	GC_IncRC( tp );
	tuple->ctype = tp;
	GC_Assign( dest, tuple );
	return 1;
}
예제 #6
0
static DaoValue* DaoValue_DeepCopy( DaoValue *self )
{
	DNode *it;
	daoint i;
	if( self == NULL ) return NULL;
	if( self->type <= DAO_ENUM ) return self; /* simple types will be copied at use; */
	if( self->type == DAO_ARRAY ) return (DaoValue*) DaoArray_Copy( (DaoArray*) self );
	if( self->type == DAO_LIST ){
		DaoList *list = (DaoList*) self;
		DaoList *copy = DaoList_New();
		GC_ShiftRC( list->unitype, copy->unitype );
		copy->unitype = list->unitype;
		for(i=0; i<list->items.size; ++i){
			DaoValue *value = DaoValue_DeepCopy( list->items.items.pValue[i] );
			DaoList_Append( copy, value );
		}
		return (DaoValue*) copy;
	}else if( self->type == DAO_MAP ){
		DaoMap *map = (DaoMap*) self;
		DaoMap *copy = DaoMap_New( map->items->hashing );
		GC_ShiftRC( map->unitype, copy->unitype );
		copy->unitype = map->unitype;
		for(it=DMap_First(map->items); it; it=DMap_Next(map->items,it)){
			DaoValue *key = DaoValue_DeepCopy( it->key.pValue );
			DaoValue *value = DaoValue_DeepCopy( it->value.pValue );
			DaoMap_Insert( copy, key, value );
		}
		return (DaoValue*) copy;
	}else if( self->type == DAO_TUPLE ){
		DaoTuple *tuple = (DaoTuple*) self;
		DaoTuple *copy = DaoTuple_New( tuple->size );
		GC_ShiftRC( tuple->unitype, copy->unitype );
		copy->unitype = tuple->unitype;
		for(i=0; i<tuple->size; ++i){
			DaoValue *value = DaoValue_DeepCopy( tuple->items[i] );
			DaoTuple_SetItem( copy, value, i );
		}
		return (DaoValue*) copy;
	}
	return NULL;
}
예제 #7
0
static void PreparePostData( DaoProcess *proc, DaoMap *httpPOSTS, DaoMap *httpPOST, DaoMap *httpFILE )
{
    DString *fname;
    DString *buffer = DString_New();
    DaoValue *vk = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 );
    DaoValue *vv = (DaoValue*) DaoProcess_NewString( proc, NULL, 0 );
    DString *key = DaoString_Get( DaoValue_CastString( vk ) );
    DString *value = DaoString_Get( DaoValue_CastString( vv ) );
    char *content_length = getenv( "CONTENT_LENGTH" );
    char *content_type = getenv( "CONTENT_TYPE" );
    const char *boundary;
    char postbuf[1024];
    daoint postlen, boundarylen, len = 0;
    daoint pos, pos2, pos_rnrn, offset;

    if( content_length != NULL ) len = strtol( content_length, NULL, 10);
    if( len == 0 ) return;
    DString_SetSharing( buffer, 0 );
    if( content_type == NULL || strstr( content_type, "multipart/form-data" ) == NULL ) {
        postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
        while( postlen ) {
            DString_AppendBytes( buffer, postbuf, postlen );
            postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
        }
        ParseKeyValueString( proc, httpPOSTS, httpPOST, buffer->chars );
        DString_Delete( buffer );
        return;
    }
    boundary = strstr( content_type, "boundary=" ) + strlen( "boundary=" );
    boundarylen = strlen( boundary );

    fname = DString_New();
    buffer->size = 0;
    for(;;) {
        postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
        if( postlen == 0 && buffer->size < boundarylen ) break;

        DString_AppendBytes( buffer, postbuf, postlen );
        while( strstr( buffer->chars, "\r\n\r\n" ) == 0 && postlen != 0 ) {
            postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
            DString_AppendBytes( buffer, postbuf, postlen );
        }
        //printf( "###############\n%s\n", buffer->chars );

        key->size = 0;
        fname->size = 0;
        pos = DString_FindChars( buffer, "name=", 20 ); /* Skip: Content-Disposition: ; */
        pos2 = DString_FindChar( buffer, '\"', pos+6 );
        DString_SubString( buffer, key, pos + 6, pos2 - pos - 6 );

        pos_rnrn = DString_FindChars( buffer, "\r\n\r\n", pos2 );
        pos = DString_FindChars( buffer, "filename=", pos2 );
        if( pos != DAO_NULLPOS && pos < pos_rnrn ) {
            daoint pos3 = DString_FindChar( buffer, '\"', pos+10 );
            DString_SubString( buffer, fname, pos + 10, pos3 - pos - 10 );
        }

        buffer->size -= pos_rnrn + 4;
        memmove( buffer->chars, buffer->chars + pos_rnrn + 4, buffer->size );
        if( fname->size == 0 ) {
            offset = 0;
            while( (pos2 = DString_FindChars( buffer, boundary, offset )) == DAO_NULLPOS ) {
                offset = buffer->size - boundarylen;
                if( offset < 0 ) offset = 0;
                postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
                DString_AppendBytes( buffer, postbuf, postlen );
            }
            DString_SubString( buffer, value, 0, pos2 - 4 ); /* \r\n-- */
            DaoMap_Insert( httpPOST, (DaoValue*) vk, (DaoValue*) vv );
            buffer->size -= pos2 + boundarylen;
            memmove( buffer->chars, buffer->chars + pos2 + boundarylen, buffer->size );
        } else {
            DaoInteger isize = {DAO_INTEGER,0,0,0,0,0};
            DaoFileStream *stream = _DaoFileStream_New();
            DaoTuple *tuple = DaoTuple_New(3);
            FILE *file = tmpfile();

            DaoString_Set( (DaoString*) vv, fname );
            stream->file = file;
            stream->base.mode |= DAO_STREAM_READABLE|DAO_STREAM_WRITABLE;
            _DaoFileStream_InitCallbacks( stream );
            DaoTuple_SetType( tuple, daox_type_namestream );
            DaoTuple_SetItem( tuple, (DaoValue*) vv, 0 );
            DaoTuple_SetItem( tuple, (DaoValue*) stream, 2 );
            DaoMap_Insert( httpFILE, (DaoValue*) vk, (DaoValue*) tuple );

            offset = 0;
            while( (pos2 = DString_FindChars( buffer, boundary, 0 )) == DAO_NULLPOS ) {
                offset = buffer->size - boundarylen;
                if( offset > 0 ) {
                    isize.value += offset;
                    fwrite( buffer->chars, 1, offset, file );
                    buffer->size -= offset;
                    memmove( buffer->chars, buffer->chars + offset, buffer->size );
                }
                postlen = fread( postbuf, 1, sizeof(postbuf), stdin );
                DString_AppendBytes( buffer, postbuf, postlen );
            }
            isize.value += pos2 - 4;
            fwrite( buffer->chars, 1, pos2 - 4, file );  /* \r\n-- */
            buffer->size -= pos2 + boundarylen;
            memmove( buffer->chars, buffer->chars + pos2 + boundarylen, buffer->size );
            rewind( file );
            DaoTuple_SetItem( tuple, (DaoValue*) & isize, 1 );
        }
    }
    DString_Delete( buffer );
}