--- parser3/src/classes/file.C 2006/11/14 17:26:00 1.147 +++ parser3/src/classes/file.C 2007/02/07 15:50:32 1.151 @@ -5,7 +5,7 @@ Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char * const IDENT_FILE_C="$Date: 2006/11/14 17:26:00 $"; +static const char * const IDENT_FILE_C="$Date: 2007/02/07 15:50:32 $"; #include "pa_config_includes.h" @@ -150,6 +150,47 @@ static void _move(Request& r, MethodPara r.absolute(vto_file_name.as_string())); } +static void copy_process_source( + struct stat& , + int from_file, + const String& , const char* /*fname*/, bool, + void *context) { + int& to_file=*static_cast(context); + + int nCount=0; + do { + unsigned char buffer[FILE_BUFFER_SIZE]; + nCount = file_block_read(from_file, buffer, sizeof(buffer)); + int written=write(to_file, buffer, nCount); + if( written < 0 ) + throw Exception(0, + 0, + "write failed: %s (%d)", strerror(errno), errno); + + } while(nCount > 0); +} + +static void copy_open_target(int f, void *from_spec) { + String& file_spec=*static_cast(from_spec); + file_read_action_under_lock(file_spec, "copy", copy_process_source, &f); +}; + +static void _copy(Request& r, MethodParams& params) { + Value& vfrom_file_name=params.as_no_junction(0, "from file name must not be code"); + Value& vto_file_name=params.as_no_junction(1, "to file name must not be code"); + + String from_spec = r.absolute(vfrom_file_name.as_string()); + const String& to_spec = r.absolute(vto_file_name.as_string()); + + create_dir_for_file(to_spec); + + file_write_action_under_lock( + to_spec, + "copy", + copy_open_target, + &from_spec); +} + static void _load_pass_param( HashStringValue::key_type key, HashStringValue::value_type value, @@ -796,6 +837,8 @@ static void _sql(Request& r, MethodParam } static void _base64(Request& r, MethodParams& params) { + bool dynamic = !(&r.get_self() == file_class); + if ( dynamic ){ VFile& self=GET_SELF(r, VFile); if(params.count()) { // decode @@ -810,6 +853,12 @@ static void _base64(Request& r, MethodPa const char* encoded=pa_base64_encode(self.value_ptr(), self.value_size()); r.write_assign_lang(*new String(encoded, 0, true/*once ?param=base64(something) was needed*/)); } + } else { + // encode + const String& file_spec=params.as_string(0, "file name must be string"); + const char* encoded=pa_base64_encode(r.absolute(file_spec)); + r.write_assign_lang(*new String(encoded, 0, true/*once ?param=base64(something) was needed*/)); + } } static void _crc32(Request& r, MethodParams& params) { @@ -841,14 +890,14 @@ static void file_md5_file_action( { PA_MD5_CTX& md5context=*static_cast(context); if(finfo.st_size) { - size_t nCount=0; + int nCount=0; do { unsigned char buffer[FILE_BUFFER_SIZE]; - nCount = read(f, buffer, sizeof(buffer)); + nCount = file_block_read(f, buffer, sizeof(buffer)); if ( nCount ){ pa_MD5Update(&md5context, (const unsigned char*)buffer, nCount); } - } while(nCount); + } while(nCount > 0); } } @@ -959,7 +1008,8 @@ MFile::MFile(): Methoded("file") { // ^file::base64[string] << decode // ^file.base64[] << encode - add_native_method("base64", Method::CT_DYNAMIC, _base64, 0, 1); + // ^file:base64[file-name] << encode + add_native_method("base64", Method::CT_ANY, _base64, 0, 1); // ^file.crc32[] // ^file:crc32[file-name] @@ -969,4 +1019,6 @@ MFile::MFile(): Methoded("file") { // ^file:md5[file-name] add_native_method("md5", Method::CT_ANY, _md5, 0, 1); + // ^file:copy[from-file-name;to-file-name] + add_native_method("copy", Method::CT_STATIC, _copy, 2, 2); }