static int DaoStringStream_Read( DaoStream *stream, DString *data, int count ) { DaoStringStream *self = (DaoStringStream*) stream; DString_Reset( data, 0 ); if( self->offset >= self->base.buffer->size ) return -1; if( count >= 0 ){ DString_SubString( self->base.buffer, data, self->offset, count ); self->offset += data->size; }else if( count == -1 ){ int delim = '\n'; daoint pos = DString_FindChar( self->base.buffer, delim, self->offset ); if( self->offset == 0 && (pos == DAO_NULLPOS || pos == self->base.buffer->size-1) ){ DString_Append( data, self->base.buffer ); self->offset = self->base.buffer->size; }else if( pos == DAO_NULLPOS ){ DString_SubString( self->base.buffer, data, pos, -1 ); self->offset = self->base.buffer->size; }else{ DString_SubString( self->base.buffer, data, pos, pos - self->offset + 1 ); self->offset = pos + 1; } if( self->base.mode & DAO_STREAM_AUTOCONV ) DString_ToUTF8( data ); return self->offset < self->base.buffer->size; }else{ if( self->offset == 0 ){ DString_Assign( data, self->base.buffer ); }else{ DString_SubString( self->base.buffer, data, self->offset, -1 ); } self->offset += data->size; } return data->size; }
int DaoRegex_ChangeExt( DaoRegex *self, DString *input, DString *output, DString *target, int index, daoint *start2, daoint *end2 ) { daoint start = start2 ? (daoint) *start2 : 0; daoint end = end2 ? (daoint) *end2 : 0; daoint i, n=0, p1=start, p2=end, p3, last; DaoValue *value = NULL; DaoString matched = {DAO_STRING,0,0,0,0,NULL}; DList *array = DList_New( DAO_DATA_VALUE ); DString *tmp = DString_New(); DString *tmp2 = DString_New(); DString_Reset( output, 0 ); if( self == NULL || input->size == 0 ) goto DoNothing; matched.value = tmp; Dao_ParseTarget( target, array, (DaoValue*) & matched ); if( end == 0 ) end = p2 = DString_Size( input ); n = last = 0; while( DaoRegex_Match( self, input, & p1, & p2 ) ){ n += 1; if( index ==0 || n == index ){ DString_SubString( input, tmp2, last, p1 - last ); DString_Append( output, tmp2 ); DString_Clear( tmp ); for(i=0; i<array->size; i++){ value = array->items.pValue[i]; if( value->type == DAO_INTEGER ){ if( DaoRegex_SubMatch( self, value->xInteger.value, & p1, & p3 ) ){ DString_SubString( input, tmp2, p1, p3 - p1 ); DString_Append( tmp, tmp2 ); } }else{ DString_Append( tmp, value->xString.value ); } } DString_Append( output, tmp ); last = p2; } if( start2 ) *start2 = p1; if( end2 ) *end2 = p2; p1 = p2; p2 = end; if( index && n == index ) break; } DString_SubString( input, tmp2, last, end - last ); DString_Append( output, tmp2 ); DoNothing: DString_Delete( tmp ); DString_Delete( tmp2 ); DList_Delete( array ); return n; }
int DaoStream_ReadLine( DaoStream *self, DString *line ) { int ch, delim = '\n'; char buf[IO_BUF_SIZE]; char *start = buf, *end = buf + IO_BUF_SIZE; DString_Clear( line ); DString_ToMBS( line ); if( self->redirect && self->redirect->StdioRead ){ self->redirect->StdioRead( self->redirect, line, 0 ); return line->size >0; }else if( self->file ){ return DaoFile_ReadLine( self->file, line ); }else if( self->attribs & DAO_IO_STRING ){ daoint pos = DString_FindWChar( self->streamString, delim, 0 ); if( pos == MAXSIZE ){ DString_Assign( line, self->streamString ); DString_Clear( self->streamString ); }else{ DString_SubString( self->streamString, line, 0, pos+1 ); DString_Erase( self->streamString, 0, pos+1 ); } return self->streamString->size >0; }else{ *start = ch = getchar(); start += 1; while( ch != delim && ch != EOF ){ *start = ch = getchar(); start += 1; if( start == end ){ if( ch == EOF ) start -= 1; DString_AppendDataMBS( line, buf, start-buf ); start = buf; } } if( ch == EOF && start != buf ) start -= 1; DString_AppendDataMBS( line, buf, start-buf ); clearerr( stdin ); return ch != EOF; } return 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 ); }