Diff for /parser3/src/main/pa_common.C between versions 1.296 and 1.301

version 1.296, 2016/12/21 21:14:42 version 1.301, 2017/02/06 16:17:12
Line 79  volatile const char * IDENT_PA_COMMON_C= Line 79  volatile const char * IDENT_PA_COMMON_C=
   
 const String file_status_name(FILE_STATUS_NAME);  const String file_status_name(FILE_STATUS_NAME);
   
   // forwards
   
   const UTF16* pa_utf16_encode(const char* in, Charset& source_charset);
   
 // functions  // functions
   
   #ifdef _MSC_VER
   
   int pa_stat(const char *pathname, struct stat *buffer){
           const UTF16* utf16name=pa_utf16_encode(pathname, pa_thread_request().charsets.source());
           return _wstat64((const wchar_t *)utf16name, buffer);
   }
   
   int pa_open(const char *pathname, int flags, int mode){
           const UTF16* utf16name=pa_utf16_encode(pathname, pa_thread_request().charsets.source());
           return _wopen((const wchar_t *)utf16name, flags, mode);
   }
   
   FILE *pa_fopen(const char *pathname, const char *mode){
           const UTF16* utf16name=pa_utf16_encode(pathname, pa_thread_request().charsets.source());
           const UTF16* utf16mode=pa_utf16_encode(mode, pa_thread_request().charsets.source());
           return _wfopen((const wchar_t *)utf16name, (const wchar_t *)utf16mode);
   }
   
   #endif
   
 char* file_read_text(Request_charsets& charsets, const String& file_spec, bool fail_on_read_problem, HashStringValue* params, bool 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);          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;          return file.success?file.str:0;
Line 118  static void file_read_action(struct stat Line 142  static void file_read_action(struct stat
         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.count;          size_t to_read_size=info.count;
         if(!to_read_size)          if(!to_read_size)
                 to_read_size=(size_t)finfo.st_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);                          lseek(f, info.offset, SEEK_SET);
Line 234  bool file_read_action_under_lock(const S Line 258  bool file_read_action_under_lock(const S
         //   they delay update till open, so we would receive "!^test[" string          //   they delay update till open, so we would receive "!^test[" string
         //   if would do stat, next open.          //   if would do stat, next open.
         // later: it seems, even this does not help sometimes          // later: it seems, even this does not help sometimes
         if((f=open(fname, O_RDONLY|(as_text?_O_TEXT:_O_BINARY)))>=0) {          if((f=pa_open(fname, O_RDONLY|(as_text?_O_TEXT:_O_BINARY)))>=0) {
                 try {                  try {
                         if(pa_lock_shared_blocking(f)!=0)                          if(pa_lock_shared_blocking(f)!=0)
                                 throw Exception("file.lock", &file_spec, "shared lock failed: %s (%d), actual filename '%s'", strerror(errno), errno, fname);                                  throw Exception("file.lock", &file_spec, "shared lock failed: %s (%d), actual filename '%s'", strerror(errno), errno, fname);
   
                         struct stat finfo;                          struct stat finfo;
                         if(fstat(f, &finfo)!=0)                          if(pa_fstat(f, &finfo)!=0)
                                 throw Exception("file.missing", // hardly possible: we just opened it OK                                  throw Exception("file.missing", // hardly possible: we just opened it OK
                                         &file_spec, "stat failed: %s (%d), actual filename '%s'", strerror(errno), errno, fname);                                          &file_spec, "stat failed: %s (%d), actual filename '%s'", strerror(errno), errno, fname);
   
Line 287  bool file_write_action_under_lock( Line 311  bool file_write_action_under_lock(
         if(access(fname, W_OK)!=0) // no          if(access(fname, W_OK)!=0) // no
                 create_dir_for_file(file_spec);                   create_dir_for_file(file_spec); 
   
         if((f=open(fname,           if((f=pa_open(fname, 
                 O_CREAT|O_RDWR                  O_CREAT|O_RDWR
                 |(as_text?_O_TEXT:_O_BINARY)                  |(as_text?_O_TEXT:_O_BINARY)
                 |(do_append?O_APPEND:PA_O_TRUNC), 0664))>=0) {                  |(do_append?O_APPEND:PA_O_TRUNC), 0664))>=0) {
Line 302  bool file_write_action_under_lock( Line 326  bool file_write_action_under_lock(
                 try {                  try {
 #if (defined(HAVE_FCHMOD) && defined(PA_SAFE_MODE))  #if (defined(HAVE_FCHMOD) && defined(PA_SAFE_MODE))
                         struct stat finfo;                          struct stat finfo;
                         if(fstat(f, &finfo)==0 && finfo.st_mode & 0111)                          if(pa_fstat(f, &finfo)==0 && finfo.st_mode & 0111)
                                 fchmod(f, finfo.st_mode & 0666/*clear executable bits*/); // backward: ignore errors if any                                  fchmod(f, finfo.st_mode & 0666/*clear executable bits*/); // backward: ignore errors if any
 #endif  #endif
                         action(f, context);                          action(f, context);
Line 462  void file_move(const String& old_spec, c Line 486  void file_move(const String& old_spec, c
   
 bool entry_exists(const char* fname, struct stat *afinfo) {  bool entry_exists(const char* fname, struct stat *afinfo) {
         struct stat lfinfo;          struct stat lfinfo;
         bool result=stat(fname, &lfinfo)==0;          bool result=pa_stat(fname, &lfinfo)==0;
         if(afinfo)          if(afinfo)
                 *afinfo=lfinfo;                  *afinfo=lfinfo;
         return result;          return result;
Line 496  bool file_executable(const String& file_ Line 520  bool file_executable(const String& file_
 bool file_stat(const String& file_spec, uint64_t& rsize, time_t& ratime, time_t& rmtime, time_t& rctime, bool fail_on_read_problem) {  bool file_stat(const String& file_spec, uint64_t& rsize, time_t& ratime, time_t& rmtime, time_t& rctime, bool fail_on_read_problem) {
         const char* fname=file_spec.taint_cstr(String::L_FILE_SPEC);           const char* fname=file_spec.taint_cstr(String::L_FILE_SPEC); 
         struct stat finfo;          struct stat finfo;
         if(stat(fname, &finfo)!=0) {          if(pa_stat(fname, &finfo)!=0) {
                 if(fail_on_read_problem)                  if(fail_on_read_problem)
                         throw Exception("file.missing", &file_spec, "getting file size failed: %s (%d), real filename '%s'", strerror(errno), errno, fname);                          throw Exception("file.missing", &file_spec, "getting file size failed: %s (%d), real filename '%s'", strerror(errno), errno, fname);
                 else                  else
                         return false;                          return false;
         }          }
         rsize=finfo.st_size;          rsize=finfo.st_size;
         ratime=finfo.st_atime;          ratime=(time_t)finfo.st_atime;
         rmtime=finfo.st_mtime;          rmtime=(time_t)finfo.st_mtime;
         rctime=finfo.st_ctime;          rctime=(time_t)finfo.st_ctime;
         return true;          return true;
 }  }
   
   size_t check_file_size(uint64_t size, const String& file_spec){
           if(size > 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;
   }
   
 /**   /** 
         String related functions          String related functions
 */  */
Line 1163  struct File_base64_action_info { Line 1193  struct File_base64_action_info {
         unsigned char** base64;          unsigned char** base64;
 };   }; 
   
 static void file_base64_file_action(struct stat& finfo, int f, const String&, void *context) {  static void file_base64_file_action(struct stat& finfo, int f, const String& file_spec, void *context) {
   
         if(finfo.st_size) {           if(finfo.st_size) { 
                 File_base64_action_info& info=*static_cast<File_base64_action_info *>(context);                  File_base64_action_info& info=*static_cast<File_base64_action_info *>(context);
                 *info.base64=new(PointerFreeGC) unsigned char[finfo.st_size * 2 + 6];                   *info.base64=new(PointerFreeGC) unsigned char[check_file_size(finfo.st_size, file_spec) * 2 + 6]; 
                 unsigned char* base64 = *info.base64;                  unsigned char* base64 = *info.base64;
                 int state=0;                  int state=0;
                 int save=0;                  int save=0;
Line 1246  inline void CalcCrc32(const unsigned cha Line 1276  inline void CalcCrc32(const unsigned cha
 }  }
   
   
 const unsigned long pa_crc32(const char *in, size_t in_size){  unsigned long pa_crc32(const char *in, size_t in_size){
         unsigned long crc32=0xFFFFFFFF;          unsigned long crc32=0xFFFFFFFF;
   
         InitCrc32Table();          InitCrc32Table();
Line 1269  static void file_crc32_file_action(struc Line 1299  static void file_crc32_file_action(struc
         }          }
 }  }
   
 const unsigned long pa_crc32(const String& file_spec){  unsigned long pa_crc32(const String& file_spec){
         unsigned long crc32=0xFFFFFFFF;          unsigned long crc32=0xFFFFFFFF;
         file_read_action_under_lock(file_spec, "crc32", file_crc32_file_action, &crc32);          file_read_action_under_lock(file_spec, "crc32", file_crc32_file_action, &crc32);
         return ~crc32;           return ~crc32; 
Line 1302  Charset* detect_charset(const char* cont Line 1332  Charset* detect_charset(const char* cont
         return 0;          return 0;
 }  }
   
   const UTF16* pa_utf16_encode(const char* in, Charset& source_charset){
          if(!in)
                  return 0;
   
          String::C sIn(in,strlen(in));
   
          UTF16* utf16=(UTF16*)pa_malloc_atomic(sIn.length*2+2);
          UTF16* utf16_end=utf16;
   
          if(!source_charset.isUTF8())
                  sIn=Charset::transcode(sIn, source_charset, pa_UTF8_charset);
   
          int status=pa_convertUTF8toUTF16((const UTF8**)&sIn.str, (const UTF8*)(sIn.str+sIn.length), &utf16_end, utf16+sIn.length+1, strictConversion);
          if(status != conversionOK)
                  throw Exception("utf-16 encode", new String(in), "utf-16 conversion failed (%d)", status);
   
              *utf16_end=0;
   
          return utf16;
   }
   
   const char* pa_utf16_decode(const UTF16* in, Charset& asked_charset){
           if(!in)
                   return 0;
   
           const UTF16* utf16_start=in;
           const UTF16* utf16_end;
   
           for(utf16_end=in; *utf16_end; utf16_end++);
   
           char *result = (char *)pa_malloc_atomic((utf16_end-in)*6+1);
           char *result_end = result;
   
           int status=pa_convertUTF16toUTF8(&utf16_start, utf16_end, (UTF8**)&result_end, (UTF8*)(result+(utf16_end-in)*6), strictConversion);
   
           if(status != conversionOK)
                   throw Exception("utf-16 decode", 0, "utf conversion failed (%d)", status);
   
           *result_end='\0';
   
           if(!asked_charset.isUTF8())
                   result = (char *)Charset::transcode(result, pa_UTF8_charset, asked_charset).cstr();
   
           return result;
   }
   
 static bool is_latin(const char *in){  static bool is_latin(const char *in){
         for(; *in; in++){          for(; *in; in++){
Line 1313  static bool is_latin(const char *in){ Line 1388  static bool is_latin(const char *in){
   
 #define MAX_IDNA_LENGTH 256  #define MAX_IDNA_LENGTH 256
   
 const char *pa_idna_encode(const char *in, Charset &source_charset){  const char *pa_idna_encode(const char *in, Charset& source_charset){
         if(!in || is_latin(in))          if(!in || is_latin(in))
                 return in;                  return in;
   

Removed from v.1.296  
changed lines
  Added in v.1.301


E-mail: