--- parser3/src/main/pa_common.C 2012/03/08 21:19:38 1.266 +++ parser3/src/main/pa_common.C 2013/07/04 10:27:49 1.271 @@ -1,7 +1,7 @@ /** @file Parser: commonly functions. - Copyright(c) 2001-2012 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2000-2012 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) * BASE64 part @@ -26,8 +26,6 @@ * */ -static const char * const IDENT_COMMON_C="$Date: 2012/03/08 21:19:38 $"; - #include "pa_common.h" #include "pa_exception.h" #include "pa_hash.h" @@ -38,6 +36,8 @@ static const char * const IDENT_COMMON_C #include "pcre.h" #include "pa_request.h" +volatile const char * IDENT_PA_COMMON_C="$Id: pa_common.C,v 1.271 2013/07/04 10:27:49 moko Exp $" IDENT_PA_COMMON_H IDENT_PA_HASH_H IDENT_PA_ARRAY_H IDENT_PA_STACK_H; + // some maybe-undefined constants #ifndef _O_TEXT @@ -118,23 +118,13 @@ void fix_line_breaks(char *str, size_t& str[length]=0; // terminating } -char* file_read_text(Request_charsets& charsets, - const String& file_spec, - bool fail_on_read_problem, - HashStringValue* params, - bool transcode_result) { - File_read_result file= - file_read(charsets, file_spec, true, params, fail_on_read_problem, 0, 0, 0, transcode_result); +char* file_read_text(Request_charsets& charsets, const String& file_spec, bool fail_on_read_problem, HashStringValue* params, bool transcode_result) { + File_read_result file=file_read(charsets, file_spec, true, params, fail_on_read_problem, 0, 0, 0, transcode_result); return file.success?file.str:0; } -char* file_load_text(Request& r, - const String& file_spec, - bool fail_on_read_problem, - HashStringValue* params, - bool transcode_result) { - File_read_result file= - file_load(r, file_spec, true, params, fail_on_read_problem, 0, 0, 0, transcode_result); +char* file_load_text(Request& r, const String& file_spec, bool fail_on_read_problem, HashStringValue* params, bool transcode_result) { + File_read_result file=file_load(r, file_spec, true, params, fail_on_read_problem, 0, 0, 0, transcode_result); return file.success?file.str:0; } @@ -160,29 +150,21 @@ struct File_read_action_info { char* buf; size_t offset; size_t count; }; #endif -static void file_read_action( - struct stat& finfo, - int f, - const String& file_spec, const char* /*fname*/, bool as_text, - void *context) { + +static void file_read_action(struct stat& finfo, int f, const String& file_spec, const char* /*fname*/, bool as_text, void *context) { File_read_action_info& info=*static_cast(context); size_t to_read_size=info.count; if(!to_read_size) to_read_size=(size_t)finfo.st_size; assert( !(info.buf && as_text) ); - if(to_read_size) { + if(to_read_size) { if(info.offset) lseek(f, info.offset, SEEK_SET); - *info.data=info.buf - ? info.buf - : (char *)pa_malloc_atomic(to_read_size+1); - *info.data_size=(size_t)read(f, *info.data, to_read_size); - - if(ssize_t(*info.data_size)<0 || *info.data_size>to_read_size) - throw Exception("file.read", - &file_spec, - "read failed: actually read %u bytes count not in [0..%u] valid range", - *info.data_size, to_read_size); + *info.data=info.buf ? info.buf : (char *)pa_malloc_atomic(to_read_size+1); + ssize_t result=read(f, *info.data, to_read_size); + if(result<0) + throw Exception("file.read", &file_spec, "read failed: %s (%d)", strerror(errno), errno); + *info.data_size=result; } else { // empty file // for both, text and binary: for text we need that terminator, for binary we need nonzero pointer to be able to save such files *info.data=(char *)pa_malloc_atomic(1); @@ -414,16 +396,18 @@ struct File_write_action_info { size_t length; }; #endif + static void file_write_action(int f, void *context) { File_write_action_info& info=*static_cast(context); if(info.length) { - int written=write(f, info.str, info.length); + ssize_t written=write(f, info.str, info.length); if(written<0) - throw Exception("file.access", - 0, - "write failed: %s (%d)", strerror(errno), errno); + throw Exception("file.write", 0, "write failed: %s (%d)", strerror(errno), errno); + if(written!=info.length) + throw Exception("file.write", 0, "write failed: %u of %u bytes written", written, info.length); } } + void file_write( Request_charsets& charsets, const String& file_spec, @@ -509,7 +493,7 @@ static void rmdir(const String& file_spe }; } -bool file_delete(const String& file_spec, bool fail_on_problem) { +bool file_delete(const String& file_spec, bool fail_on_problem, bool keep_empty_dirs) { const char* fname=file_spec.taint_cstr(String::L_FILE_SPEC); if(unlink(fname)!=0) if(fail_on_problem) @@ -520,11 +504,13 @@ bool file_delete(const String& file_spec else return false; - rmdir(file_spec, 1); + if(!keep_empty_dirs) + rmdir(file_spec, 1); + return true; } -void file_move(const String& old_spec, const String& new_spec) { +void file_move(const String& old_spec, const String& new_spec, bool keep_empty_dirs) { const char* old_spec_cstr=old_spec.taint_cstr(String::L_FILE_SPEC); const char* new_spec_cstr=new_spec.taint_cstr(String::L_FILE_SPEC); @@ -536,7 +522,8 @@ void file_move(const String& old_spec, c "rename failed: %s (%d), actual filename '%s' to '%s'", strerror(errno), errno, old_spec_cstr, new_spec_cstr); - rmdir(old_spec, 1); + if(!keep_empty_dirs) + rmdir(old_spec, 1); } @@ -563,7 +550,8 @@ bool dir_exists(const String& file_spec) const String* file_exist(const String& path, const String& name) { String& result=*new String(path); - result << "/"; + if(path.last_char() != '/') + result << "/"; result << name; return file_exist(result)?&result:0; } @@ -824,6 +812,26 @@ char* unescape_chars(const char* cp, int return s; } +char *search_stop(char*& current, char cstop_at) { + // sanity check + if(!current) + return 0; + + // skip leading WS + while(*current==' ' || *current=='\t') + current++; + if(!*current) + return current=0; + + char *result=current; + if(char *pstop_at=strchr(current, cstop_at)) { + *pstop_at=0; + current=pstop_at+1; + } else + current=0; + return result; +} + #ifdef WIN32 void back_slashes_to_slashes(char* s) { if(s) @@ -1026,7 +1034,7 @@ int __snprintf(char* b, size_t s, const * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. * */ -static char *base64_alphabet = +static const char *base64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /**