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; }
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; }
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 ); } }
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 ); } }
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; }
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; }
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 ); }