static void DString_PartialAppend( DString *self, DString *other, int max ) { if( other->size > max ){ DString_AppendBytes( self, other->chars, max-1-!isalnum(other->chars[max-2]) ); DString_AppendChar( self, '~' ); }else{ DString_Append( self, other ); } }
void DString_SetBytes( DString *self, const char *bytes, daoint count ) { if( count < 0 ){ DString_SetChars( self, bytes ); }else{ DString_Clear( self ); DString_AppendBytes( self, bytes, count ); } }
int DaoFile_ReadAll( FILE *fin, DString *output, int close ) { char buf[IO_BUF_SIZE]; DString_Reset( output, 0 ); if( fin == NULL ) return 0; while(1){ // TODO: read directly into output; size_t count = fread( buf, 1, IO_BUF_SIZE, fin ); if( count ==0 ) break; DString_AppendBytes( output, buf, count ); } if( close ) fclose( fin ); return 1; }
int DaoFile_ReadPart( FILE *fin, DString *output, daoint offset, daoint count ) { char buf[IO_BUF_SIZE]; daoint k, m, size = output->size; if( fin == NULL ) return 0; fseek( fin, offset, SEEK_SET ); while( count > 0 ){ m = count < IO_BUF_SIZE ? count : IO_BUF_SIZE; k = fread( buf, 1, m, fin ); if( k == 0 ) break; DString_AppendBytes( output, buf, k ); count -= k; } return output->size - size; }
static void DaoIO_ReadFile( DaoProcess *proc, DaoValue *p[], int N ) { DString *res = DaoProcess_PutChars( proc, "" ); daoint silent = p[1]->xBoolean.value; if( DString_Size( p[0]->xString.value ) ==0 ){ char buf[4096]; while(1){ size_t count = fread( buf, 1, sizeof( buf ), stdin ); if( count ==0 ) break; DString_AppendBytes( res, buf, count ); } }else{ FILE *fin = DaoIO_OpenFile( proc, p[0]->xString.value, "r", silent ); struct stat info; if( fin == NULL ) return; fstat( fileno( fin ), &info ); DString_Reserve( res, info.st_size ); DString_Reset( res, fread( res->chars, 1, info.st_size, fin ) ); fclose( fin ); } }
void DaoCGI_SendFile( DaoProcess *proc, DaoValue *p[], int N ) { DString *mbs; DString *file = DaoValue_TryGetString( p[0] ); DString *mime = DaoValue_TryGetString( p[1] ); DString *notfound = DaoValue_TryGetString( p[2] ); char buf[IO_BUF_SIZE]; FILE *fin = fopen( DString_GetData( file ), "r" ); if( fin == NULL ) { printf( "%s", DString_GetData( notfound ) ); return; } mbs = DString_New(); printf( "Content-Type: %s\n\n", DString_GetData( mime ) ); while(1) { size_t count = fread( buf, 1, IO_BUF_SIZE, fin ); if( count ==0 ) break; DString_Reset( mbs, 0 ); DString_AppendBytes( mbs, buf, count ); DaoFile_WriteString( stdout, mbs ); } fclose( fin ); DString_Delete( mbs ); }
static int DaoStringStream_Write( DaoStream *stream, const void *data, int count ) { DaoStringStream *self = (DaoStringStream*) stream; DString_AppendBytes( self->base.buffer, (char*) data, count ); return count; }
void DString_Append( DString *self, DString *chs ) { DString_AppendBytes( self, chs->chars, chs->size ); }
void DString_AppendChars( DString *self, const char *chs ) { DString_AppendBytes(self, chs, strlen( chs )); }
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 ); }
static int DaoStream_WriteBuffer( DaoStream *self, const void *data, int count ) { DString_AppendBytes( self->buffer, (char*) data, count ); return count; }