|
|
| version 1.316, 2020/11/16 21:22:36 | version 1.324, 2020/12/30 18:06:42 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: commonly functions. | Parser: commonly functions. |
| Copyright (c) 2000-2017 Art. Lebedev Studio (http://www.artlebedev.com) | Copyright (c) 2000-2020 Art. Lebedev Studio (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| Line 110 int pa_get_valid_file_options_count(Hash | Line 110 int pa_get_valid_file_options_count(Hash |
| #ifndef DOXYGEN | #ifndef DOXYGEN |
| struct File_read_action_info { | struct File_read_action_info { |
| char **data; size_t *data_size; | char **data; size_t *data_size; |
| char* buf; size_t offset; size_t limit; | char* buf; uint64_t offset; size_t limit; |
| }; | }; |
| #endif | #endif |
| static void file_read_action(struct stat& finfo, int f, const String& file_spec, void *context) { | static void file_read_action(struct stat& finfo, int f, const String& file_spec, void *context) { |
| File_read_action_info& info = *static_cast<File_read_action_info *>(context); | File_read_action_info& info = *static_cast<File_read_action_info *>(context); |
| size_t to_read_size = info.limit; | size_t to_read_size = check_file_size(info.limit && info.limit < finfo.st_size ? info.limit : finfo.st_size, &file_spec); |
| if(!to_read_size) | |
| to_read_size = check_file_size(finfo.st_size, &file_spec); | |
| if(to_read_size) { | if(to_read_size) { |
| if(info.offset) | if(info.offset) |
| lseek(f, info.offset, SEEK_SET); | pa_lseek(f, info.offset, SEEK_SET); // seek never fails as POSIX allows the file offset to be set beyond the EOF |
| *info.data = info.buf ? info.buf : (char *)pa_malloc_atomic(to_read_size+1); | *info.data = info.buf ? info.buf : (char *)pa_malloc_atomic(to_read_size+1); |
| ssize_t result = read(f, *info.data, to_read_size); | ssize_t result = read(f, *info.data, to_read_size); |
| if(result<0) | if(result<0) |
| Line 136 static void file_read_action(struct stat | Line 134 static void file_read_action(struct stat |
| } | } |
| } | } |
| File_read_result file_read_binary(const String& file_spec, bool fail_on_read_problem, char* buf, size_t offset, size_t limit) { | File_read_result file_read_binary(const String& file_spec, bool fail_on_read_problem, char* buf, uint64_t offset, size_t limit) { |
| File_read_result result = {false, 0, 0, 0}; | File_read_result result = {false, 0, 0, 0}; |
| File_read_action_info info = {&result.str, &result.length, buf, offset, limit}; | File_read_action_info info = {&result.str, &result.length, buf, offset, limit}; |
| Line 288 bool file_read_action_under_lock(const S | Line 286 bool file_read_action_under_lock(const S |
| } | } |
| void create_dir_for_file(const String& file_spec) { | void create_dir_for_file(const String& file_spec) { |
| size_t pos_after=1; | const char *str=file_spec.taint_cstr(String::L_FILE_SPEC); |
| size_t pos_before; | if(str[0]){ |
| while((pos_before=file_spec.pos('/', pos_after))!=STRING_NOT_FOUND) { | const char *pos=str+1; |
| pa_mkdir(file_spec.mid(0, pos_before).taint_cstr(String::L_FILE_SPEC), 0775); | while((pos=strchr(pos,'/')) && pos[1]) { // to avoid trailing /, see #1166 |
| pos_after=pos_before+1; | pa_mkdir(pa_strdup(str,pos-str), 0775); |
| pos++; | |
| } | |
| } | } |
| } | } |
| Line 532 bool file_stat(const String& file_spec, | Line 532 bool file_stat(const String& file_spec, |
| } | } |
| size_t check_file_size(uint64_t size, const String* file_spec){ | size_t check_file_size(uint64_t size, const String* file_spec){ |
| if(size > pa_file_size_limit) | if(size > (uint64_t)pa_file_size_limit) |
| throw Exception(PARSER_RUNTIME, file_spec, "content size of %.15g bytes exceeds the limit (%.15g bytes)", (double)size, (double)pa_file_size_limit); | throw Exception(PARSER_RUNTIME, file_spec, "content size of %.15g bytes exceeds the limit (%.15g bytes)", (double)size, (double)pa_file_size_limit); |
| return (size_t)size; | return (size_t)size; |
| } | } |
| Line 566 const char* capitalize(const char* s){ | Line 566 const char* capitalize(const char* s){ |
| return (const char*)result; | return (const char*)result; |
| } | } |
| char *str_lower(const char *s, size_t helper_length){ | char *str_lower(const char *s, size_t length){ |
| char *result=pa_strdup(s, helper_length); | char *result=pa_strdup(s, length); |
| for(char* c=result; *c; c++) | for(char* c=result; *c; c++) |
| *c=(char)tolower((unsigned char)*c); | *c=(char)tolower((unsigned char)*c); |
| return result; | return result; |
| } | } |
| char *str_upper(const char *s, size_t helper_length){ | char *str_upper(const char *s, size_t length){ |
| char *result=pa_strdup(s, helper_length); | char *result=pa_strdup(s, length); |
| for(char* c=result; *c; c++) | for(char* c=result; *c; c++) |
| *c=(char)toupper((unsigned char)*c); | *c=(char)toupper((unsigned char)*c); |
| return result; | return result; |
| Line 669 char *pa_strcat(const char *a, const cha | Line 669 char *pa_strcat(const char *a, const cha |
| return result; | return result; |
| } | } |
| const char *pa_filename(const char *path){ | |
| if(!path) | |
| return NULL; | |
| for(const char *c = path + strlen(path) - 1; c >= path; c--) { | |
| if(*c == '/' || *c == '\\') | |
| return c+1; | |
| } | |
| return path; | |
| } | |
| // format: %[flags][width][.precision]type http://msdn.microsoft.com/ru-ru/library/56e442dc(en-us,VS.80).aspx | // format: %[flags][width][.precision]type http://msdn.microsoft.com/ru-ru/library/56e442dc(en-us,VS.80).aspx |
| // flags: '-', '+', ' ', '#', '0' http://msdn.microsoft.com/ru-ru/library/8aky45ct(en-us,VS.80).aspx | // flags: '-', '+', ' ', '#', '0' http://msdn.microsoft.com/ru-ru/library/8aky45ct(en-us,VS.80).aspx |
| Line 936 const char* hex_string(unsigned char* by | Line 945 const char* hex_string(unsigned char* by |
| return bytes_hex; | return bytes_hex; |
| } | } |
| int file_block_read(const int f, unsigned char* buffer, const size_t size){ | ssize_t file_block_read(const int f, void* buffer, const size_t size){ |
| int nCount = read(f, buffer, size); | ssize_t nCount = read(f, buffer, size); |
| if (nCount < 0) | if (nCount < 0) |
| throw Exception("file.read", 0, "read failed: %s (%d)", strerror(errno), errno); | throw Exception("file.read", 0, "read failed: %s (%d)", strerror(errno), errno); |
| return nCount; | return nCount; |