FALCON_FUNC Uploaded_read( Falcon::VMachine *vm ) { Falcon::CoreObject *self = vm->self().asObject(); Falcon::Item i_data; if ( self->getProperty( "data", i_data ) && ( i_data.isMemBuf() || i_data.isString() ) ) { vm->regA().setBoolean( false ); return; } Falcon::Item i_storage; if ( ! self->getProperty( "storage", i_storage ) || ! i_storage.isString() ) { // invalid storage? throw new Falcon::TypeError( Falcon::ErrorParam( Falcon::e_inv_params, __LINE__ ). extra( ".storage" ) ); } Falcon::FileStream fs; if ( ! fs.open( *i_storage.asString(), Falcon::BaseFileStream::e_omReadOnly, Falcon::BaseFileStream::e_smShareRead ) ) { throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ). sysError( (uint32) fs.lastError() ) ); } Falcon::int64 filesize = fs.seekEnd(0); Falcon::MemBuf *mb = new Falcon::MemBuf_1( (uint32) filesize ); fs.seekBegin( 0 ); Falcon::int64 readIn = 0; while ( readIn < filesize ) { Falcon::int32 len = fs.read( mb->data() + readIn, (int32)( filesize - readIn ) ); if ( len < 0 ) { throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ). sysError( (uint32) fs.lastError() ) ); // anyhow, try to close to avoid system leaks. fs.close(); } readIn += len; } self->setProperty( "data", mb ); if ( ! fs.close() ) { throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ). sysError( (uint32) fs.lastError() ) ); } vm->regA().setBoolean( true ); }
/*# @method open Uploaded @brief Opens a read-only Falcon Stream pointing to the uploaed file. @return A Falcon stream. @raise IoError on open or write error. @raise TypeError if the storage property is not a valid filename. If @b data is filled, this method creates a memory read-only StringStream accessing the data as a file. If it was stored in a temporary file named as reported by the @b storage property, that file is open in read-only/shared mode. This method allows to obtain a valid readable stream no matter if the uploaded file was cached in memory or temporarily stored to disk. */ FALCON_FUNC Uploaded_open( Falcon::VMachine *vm ) { Falcon::CoreObject *self = vm->self().asObject(); Falcon::Item i_data; // try to read the data. Falcon::Stream *ret = 0; if ( self->getProperty( "data", i_data ) ) { if ( i_data.isMemBuf() ) { ret = new Falcon::StringStream(); Falcon::MemBuf *mb = i_data.asMemBuf(); ret->write( mb->data(), mb->size() ); ret->seekBegin(0); } else if ( i_data.isString() ) { ret = new Falcon::StringStream( *i_data.asString() ); } } // try to load from storage if we didn't create a stream. if ( ret == 0 ) { Falcon::Item i_storage; if ( ! self->getProperty( "storage", i_storage ) || ! i_storage.isString() ) { // invalid storage? throw new Falcon::TypeError( Falcon::ErrorParam( Falcon::e_inv_params, __LINE__ ) .extra( ".storage" ) ); } Falcon::FileStream *temp = new Falcon::FileStream(); if ( ! temp->open( *i_storage.asString(), Falcon::BaseFileStream::e_omReadOnly ) ) { Falcon::int64 le = temp->lastError(); delete temp; throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ) .sysError( (uint32) le ) ); } ret = temp; } // create the stream. Falcon::Item *stream_cls = vm->findWKI( "Stream" ); fassert( stream_cls != 0 ); fassert( stream_cls->isClass() ); Falcon::CoreObject *oret = stream_cls->asClass()->createInstance(); oret->setUserData( ret ); vm->retval( oret ); }
FALCON_FUNC Uploaded_store( Falcon::VMachine *vm ) { Falcon::Item *ip_path = vm->param(0); if ( ip_path == 0 || ( ! ip_path->isString() && ! ip_path->isOfClass( "Stream" ) ) ) { throw new Falcon::ParamError( Falcon::ErrorParam( Falcon::e_inv_params, __LINE__ ) .extra( "S|Stream" ) ); } Falcon::CoreObject *self = vm->self().asObject(); //=============================================== // Do we store from data? // Falcon::Item i_data; if ( self->getProperty( "data", i_data ) && ( i_data.isMemBuf() || i_data.isString() ) ) { Falcon::FileStream* tgFile = 0; Falcon::Stream *tgStream; // try to save to ip_path; if ( ip_path->isString() ) { // try to open the file. tgFile = new Falcon::FileStream; if ( ! tgFile->create( *ip_path->asString(), Falcon::BaseFileStream::e_aUserRead | Falcon::BaseFileStream::e_aUserWrite ) ) { Falcon::int64 le = tgFile->lastError(); delete tgFile; throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ). sysError( (uint32) le ) ); } tgStream = tgFile; } else tgStream = static_cast<Falcon::Stream*>( ip_path->asObject()->getUserData() ); Falcon::int64 written = 0; Falcon::uint32 len = i_data.isString() ? i_data.asString()->size() : i_data.asMemBuf()->size(); Falcon::byte* data = i_data.isString() ? i_data.asString()->getRawStorage() : i_data.asMemBuf()->data(); int wrt = 0; while ( written < len ) { wrt = tgStream->write( data + written, (uint32)( len - written ) ); if ( wrt < 0 ) { Falcon::int64 le = tgStream->lastError(); delete tgFile; throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ). sysError( (uint32) le ) ); } written += wrt; } if ( ! tgStream->close() ) { Falcon::int64 le = tgStream->lastError(); delete tgFile; // ok also if 0 throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ) .sysError( (uint32)le ) ); } // success return; } // ============================================= // Do we store from storage? Falcon::Item i_storage; if ( ! self->getProperty( "storage", i_storage ) || ! i_storage.isString() ) { // invalid storage? throw new Falcon::TypeError( Falcon::ErrorParam( Falcon::e_inv_params, __LINE__ ) .extra( ".storage" ) ); } const Falcon::String &fname = *i_storage.asString(); // First, try to rename the file. if ( ip_path->isString() ) { Falcon::int32 status; // fname -> dest if ( Falcon::Sys::fal_move( fname, *ip_path->asString(), status ) ) return; // great, we did it } Falcon::FileStream infile; if ( ! infile.open( fname, Falcon::BaseFileStream::e_omReadOnly ) || ! infile.good() ) { throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ). sysError( (uint32) infile.lastError() ) ); } // no way? -- try to copy it. Falcon::FileStream* tgFile = 0; Falcon::Stream *tgStream; // try to save to ip_path; if ( ip_path->isString() ) { // try to open the file. tgFile = new Falcon::FileStream(); if ( ! tgFile->create( *ip_path->asString(), Falcon::BaseFileStream::e_aUserRead | Falcon::BaseFileStream::e_aUserWrite ) ) { Falcon::int64 le = tgFile->lastError(); delete tgFile; throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ). sysError( (uint32) le ) ); } tgStream = tgFile; } else tgStream = static_cast<Falcon::Stream*>( ip_path->asObject()->getUserData() ); Falcon::byte buffer[2048]; int wrt = 0; while ( ! infile.eof() ) { wrt = infile.read( buffer, 2048 ); if ( wrt < 0 ) { delete tgFile; throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ). sysError( (uint32) infile.lastError() ) ); } wrt = tgStream->write( buffer, wrt ); if ( wrt < 0 ) { Falcon::int64 le = tgStream->lastError(); delete tgFile; throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ). sysError( (uint32) le ) ); } } // silently try to unlink the source file infile.close(); Falcon::int32 status; Falcon::Sys::fal_unlink( fname, status ); // do not raise again if in error if ( ! tgStream->close() ) { Falcon::int64 le = tgStream->lastError(); delete tgFile; throw new Falcon::IoError( Falcon::ErrorParam( Falcon::e_io_error, __LINE__ ) .sysError( (uint32) le ) ); } delete tgFile; }