| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							| 
									
										
										
										
											2008-04-16 22:40:48 +00:00
										 |  |  |  * of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bli | 
					
						
							| 
									
										
										
										
											2019-07-07 15:38:41 +10:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Some really low-level file operations. | 
					
						
							| 
									
										
										
										
											2011-02-27 20:37:56 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2012-09-16 04:58:18 +00:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include <sys/types.h>
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-30 17:56:01 +11:00
										 |  |  | #if defined(__NetBSD__) || defined(__DragonFly__) || defined(__HAIKU__)
 | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  | /* Other modern unix OS's should probably use this also. */ | 
					
						
							| 
									
										
										
										
											2014-01-07 13:39:00 +11:00
										 |  |  | #  include <sys/statvfs.h>
 | 
					
						
							|  |  |  | #  define USE_STATFS_STATVFS
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
 | 
					
						
							|  |  |  |     defined(__DragonFly__) | 
					
						
							|  |  |  | /* For statfs */ | 
					
						
							| 
									
										
										
										
											2013-04-24 20:19:01 +00:00
										 |  |  | #  include <sys/mount.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #  include <sys/param.h>
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-07 13:39:00 +11:00
										 |  |  | #if defined(__linux__) || defined(__hpux) || defined(__GNU__) || defined(__GLIBC__)
 | 
					
						
							|  |  |  | #  include <sys/vfs.h>
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #include <string.h> /* strcpy etc.. */
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-06 13:20:05 +00:00
										 |  |  | #ifdef WIN32
 | 
					
						
							| 
									
										
										
										
											2019-04-26 09:53:55 -06:00
										 |  |  | #  include "BLI_string_utf8.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #  include "BLI_winstuff.h"
 | 
					
						
							| 
									
										
										
										
											2012-04-15 07:54:07 +00:00
										 |  |  | #  include "utfconv.h"
 | 
					
						
							| 
									
										
										
										
											2020-07-14 16:04:18 +10:00
										 |  |  | #  include <ShObjIdl.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #  include <direct.h>
 | 
					
						
							|  |  |  | #  include <io.h>
 | 
					
						
							|  |  |  | #  include <stdbool.h>
 | 
					
						
							| 
									
										
										
										
											2012-04-15 07:54:07 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #  include <pwd.h>
 | 
					
						
							| 
									
										
										
										
											2012-04-15 07:54:07 +00:00
										 |  |  | #  include <sys/ioctl.h>
 | 
					
						
							|  |  |  | #  include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2009-09-06 13:20:05 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | /* lib includes */ | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-20 02:17:37 +00:00
										 |  |  | #include "BLI_fileops.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BLI_linklist.h"
 | 
					
						
							| 
									
										
										
										
											2012-09-03 22:04:14 +00:00
										 |  |  | #include "BLI_path_util.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BLI_string.h"
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2006-03-19 13:28:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Copies the current working directory into *dir (max size maxncpy), and | 
					
						
							|  |  |  |  * returns a pointer to same. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \note can return NULL when the size is not big enough | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2012-07-01 22:19:19 +00:00
										 |  |  | char *BLI_current_working_dir(char *dir, const size_t maxncpy) | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-26 09:53:55 -06:00
										 |  |  | #if defined(WIN32)
 | 
					
						
							|  |  |  |   wchar_t path[MAX_PATH]; | 
					
						
							|  |  |  |   if (_wgetcwd(path, MAX_PATH)) { | 
					
						
							|  |  |  |     if (BLI_strncpy_wchar_as_utf8(dir, path, maxncpy) != maxncpy) { | 
					
						
							|  |  |  |       return dir; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const char *pwd = BLI_getenv("PWD"); | 
					
						
							|  |  |  |   if (pwd) { | 
					
						
							|  |  |  |     size_t srclen = BLI_strnlen(pwd, maxncpy); | 
					
						
							|  |  |  |     if (srclen != maxncpy) { | 
					
						
							|  |  |  |       memcpy(dir, pwd, srclen + 1); | 
					
						
							|  |  |  |       return dir; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 11:23:02 +02:00
										 |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   return getcwd(dir, maxncpy); | 
					
						
							| 
									
										
										
										
											2019-04-26 09:53:55 -06:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the number of free bytes on the volume containing the specified pathname. */ | 
					
						
							|  |  |  | /* Not actually used anywhere.
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-10-22 15:35:49 +00:00
										 |  |  | double BLI_dir_free_space(const char *dir) | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #ifdef WIN32
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   DWORD sectorspc, bytesps, freec, clusters; | 
					
						
							|  |  |  |   char tmp[4]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tmp[0] = '\\'; | 
					
						
							| 
									
										
										
										
											2021-02-05 16:23:34 +11:00
										 |  |  |   tmp[1] = 0; /* Just a fail-safe. */ | 
					
						
							| 
									
										
										
										
											2020-03-07 00:58:48 +11:00
										 |  |  |   if (ELEM(dir[0] == '/', '\\')) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     tmp[0] = '\\'; | 
					
						
							|  |  |  |     tmp[1] = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (dir[1] == ':') { | 
					
						
							|  |  |  |     tmp[0] = dir[0]; | 
					
						
							|  |  |  |     tmp[1] = ':'; | 
					
						
							|  |  |  |     tmp[2] = '\\'; | 
					
						
							|  |  |  |     tmp[3] = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GetDiskFreeSpace(tmp, §orspc, &bytesps, &freec, &clusters); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (double)(freec * bytesps * sectorspc); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2008-01-26 20:36:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  ifdef USE_STATFS_STATVFS
 | 
					
						
							|  |  |  |   struct statvfs disk; | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  |   struct statfs disk; | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   char name[FILE_MAXDIR], *slash; | 
					
						
							|  |  |  |   int len = strlen(dir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (len >= FILE_MAXDIR) { | 
					
						
							|  |  |  |     /* path too long */ | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   strcpy(name, dir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (len) { | 
					
						
							|  |  |  |     slash = strrchr(name, '/'); | 
					
						
							|  |  |  |     if (slash) { | 
					
						
							|  |  |  |       slash[1] = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     strcpy(name, "/"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #  if defined(USE_STATFS_STATVFS)
 | 
					
						
							|  |  |  |   if (statvfs(name, &disk)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  elif defined(USE_STATFS_4ARGS)
 | 
					
						
							|  |  |  |   if (statfs(name, &disk, sizeof(struct statfs), 0)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  |   if (statfs(name, &disk)) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (((double)disk.f_bsize) * ((double)disk.f_bfree)); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-18 12:13:03 -06:00
										 |  |  | int64_t BLI_ftell(FILE *stream) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  |   return _ftelli64(stream); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   return ftell(stream); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int BLI_fseek(FILE *stream, int64_t offset, int whence) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  |   return _fseeki64(stream, offset, whence); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   return fseek(stream, offset, whence); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int64_t BLI_lseek(int fd, int64_t offset, int whence) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  |   return _lseeki64(fd, offset, whence); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   return lseek(fd, offset, whence); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the file size of an opened file descriptor. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-10-22 15:35:49 +00:00
										 |  |  | size_t BLI_file_descriptor_size(int file) | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-06 17:16:46 +01:00
										 |  |  |   BLI_stat_t st; | 
					
						
							|  |  |  |   if ((file < 0) || (BLI_fstat(file, &st) == -1)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return st.st_size; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Returns the size of a file. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-10-22 15:35:49 +00:00
										 |  |  | size_t BLI_file_size(const char *path) | 
					
						
							| 
									
										
										
										
											2008-01-21 22:10:20 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BLI_stat_t stats; | 
					
						
							|  |  |  |   if (BLI_stat(path, &stats) == -1) { | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return stats.st_size; | 
					
						
							| 
									
										
										
										
											2008-01-21 22:10:20 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-26 08:14:41 -07:00
										 |  |  | /* Return file attributes. Apple version of this function is defined in storage_apple.mm */ | 
					
						
							| 
									
										
										
										
											2020-03-26 17:52:41 +01:00
										 |  |  | #ifndef __APPLE__
 | 
					
						
							| 
									
										
										
										
											2020-02-21 08:18:29 -08:00
										 |  |  | eFileAttributes BLI_file_attributes(const char *path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int ret = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 17:52:41 +01:00
										 |  |  | #  ifdef WIN32
 | 
					
						
							| 
									
										
										
										
											2020-05-26 08:14:41 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (BLI_path_extension_check(path, ".lnk")) { | 
					
						
							|  |  |  |     return FILE_ATTR_ALIAS; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-10 14:07:15 -07:00
										 |  |  |   WCHAR wline[FILE_MAXDIR]; | 
					
						
							| 
									
										
										
										
											2020-05-15 08:10:57 -07:00
										 |  |  |   if (conv_utf_8_to_16(path, wline, ARRAY_SIZE(wline)) != 0) { | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-02-21 08:18:29 -08:00
										 |  |  |   DWORD attr = GetFileAttributesW(wline); | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_READONLY) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_READONLY; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_HIDDEN) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_HIDDEN; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_SYSTEM) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_SYSTEM; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_ARCHIVE) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_ARCHIVE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_COMPRESSED) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_COMPRESSED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_ENCRYPTED) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_ENCRYPTED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_TEMPORARY) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_TEMPORARY; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_SPARSE_FILE) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_SPARSE_FILE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_OFFLINE) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_OFFLINE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { | 
					
						
							|  |  |  |     ret |= FILE_ATTR_REPARSE_POINT; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-10 22:58:30 +10:00
										 |  |  | #  else
 | 
					
						
							| 
									
										
										
										
											2020-02-21 08:18:29 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 14:46:07 +01:00
										 |  |  |   UNUSED_VARS(path); | 
					
						
							| 
									
										
										
										
											2020-02-21 08:18:29 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* TODO:
 | 
					
						
							|  |  |  |    * If Immutable set FILE_ATTR_READONLY | 
					
						
							|  |  |  |    * If Archived set FILE_ATTR_ARCHIVE | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-03-26 17:52:41 +01:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2020-02-21 08:18:29 -08:00
										 |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-26 17:52:41 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-26 08:14:41 -07:00
										 |  |  | /* Return alias/shortcut file target. Apple version is defined in storage_apple.mm */ | 
					
						
							| 
									
										
										
										
											2020-03-26 17:52:41 +01:00
										 |  |  | #ifndef __APPLE__
 | 
					
						
							| 
									
										
										
										
											2020-10-09 14:39:26 +05:30
										 |  |  | bool BLI_file_alias_target(const char *filepath, | 
					
						
							|  |  |  |                            /* This parameter can only be `const` on Linux since
 | 
					
						
							|  |  |  |                             * redirections are not supported there. | 
					
						
							|  |  |  |                             * NOLINTNEXTLINE: readability-non-const-parameter. */ | 
					
						
							|  |  |  |                            char r_targetpath[FILE_MAXDIR]) | 
					
						
							| 
									
										
										
										
											2020-03-26 17:52:41 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-05-26 08:14:41 -07:00
										 |  |  | #  ifdef WIN32
 | 
					
						
							|  |  |  |   if (!BLI_path_extension_check(filepath, ".lnk")) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   IShellLinkW *Shortcut = NULL; | 
					
						
							|  |  |  |   bool success = false; | 
					
						
							|  |  |  |   CoInitializeEx(NULL, COINIT_MULTITHREADED); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   HRESULT hr = CoCreateInstance( | 
					
						
							|  |  |  |       &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (LPVOID *)&Shortcut); | 
					
						
							|  |  |  |   if (SUCCEEDED(hr)) { | 
					
						
							|  |  |  |     IPersistFile *PersistFile; | 
					
						
							|  |  |  |     hr = Shortcut->lpVtbl->QueryInterface(Shortcut, &IID_IPersistFile, (LPVOID *)&PersistFile); | 
					
						
							|  |  |  |     if (SUCCEEDED(hr)) { | 
					
						
							|  |  |  |       WCHAR path_utf16[FILE_MAXDIR] = {0}; | 
					
						
							|  |  |  |       if (conv_utf_8_to_16(filepath, path_utf16, ARRAY_SIZE(path_utf16)) == 0) { | 
					
						
							|  |  |  |         hr = PersistFile->lpVtbl->Load(PersistFile, path_utf16, STGM_READ); | 
					
						
							|  |  |  |         if (SUCCEEDED(hr)) { | 
					
						
							|  |  |  |           hr = Shortcut->lpVtbl->Resolve(Shortcut, 0, SLR_NO_UI | SLR_UPDATE); | 
					
						
							|  |  |  |           if (SUCCEEDED(hr)) { | 
					
						
							|  |  |  |             wchar_t target_utf16[FILE_MAXDIR] = {0}; | 
					
						
							|  |  |  |             hr = Shortcut->lpVtbl->GetPath(Shortcut, target_utf16, FILE_MAXDIR, NULL, 0); | 
					
						
							|  |  |  |             if (SUCCEEDED(hr)) { | 
					
						
							| 
									
										
										
										
											2020-10-09 14:39:26 +05:30
										 |  |  |               success = (conv_utf_16_to_8(target_utf16, r_targetpath, FILE_MAXDIR) == 0); | 
					
						
							| 
									
										
										
										
											2020-05-26 08:14:41 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           PersistFile->lpVtbl->Release(PersistFile); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Shortcut->lpVtbl->Release(Shortcut); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 14:39:26 +05:30
										 |  |  |   return (success && r_targetpath[0]); | 
					
						
							| 
									
										
										
										
											2020-07-10 22:58:30 +10:00
										 |  |  | #  else
 | 
					
						
							| 
									
										
										
										
											2020-10-09 14:39:26 +05:30
										 |  |  |   UNUSED_VARS(r_targetpath, filepath); | 
					
						
							| 
									
										
										
										
											2020-05-26 08:14:41 -07:00
										 |  |  |   /* File-based redirection not supported. */ | 
					
						
							| 
									
										
										
										
											2020-03-26 17:52:41 +01:00
										 |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2020-05-26 08:14:41 -07:00
										 |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2020-03-26 17:52:41 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-02-21 08:18:29 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2018-02-26 19:58:31 +11:00
										 |  |  |  * Returns the st_mode from stat-ing the specified path name, or 0 if stat fails | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  |  * (most likely doesn't exist or no access). | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  | int BLI_exists(const char *path) | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-05-27 15:34:55 -04:00
										 |  |  | #if defined(WIN32)
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BLI_stat_t st; | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |   wchar_t *tmp_16 = alloc_utf16_from_8(path, 1); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int len, res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   len = wcslen(tmp_16); | 
					
						
							|  |  |  |   /* in Windows #stat doesn't recognize dir ending on a slash
 | 
					
						
							|  |  |  |    * so we remove it here */ | 
					
						
							| 
									
										
										
										
											2020-03-07 00:58:48 +11:00
										 |  |  |   if ((len > 3) && ELEM(tmp_16[len - 1], L'\\', L'/')) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     tmp_16[len - 1] = '\0'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* two special cases where the trailing slash is needed:
 | 
					
						
							|  |  |  |    * 1. after the share part of a UNC path | 
					
						
							|  |  |  |    * 2. after the C:\ when the path is the volume only | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   if ((len >= 3) && (tmp_16[0] == L'\\') && (tmp_16[1] == L'\\')) { | 
					
						
							| 
									
										
										
										
											2020-04-08 16:29:46 +10:00
										 |  |  |     BLI_path_normalize_unc_16(tmp_16); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((tmp_16[1] == L':') && (tmp_16[2] == L'\0')) { | 
					
						
							|  |  |  |     tmp_16[2] = L'\\'; | 
					
						
							|  |  |  |     tmp_16[3] = L'\0'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   res = BLI_wstat(tmp_16, &st); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   free(tmp_16); | 
					
						
							|  |  |  |   if (res == -1) { | 
					
						
							| 
									
										
										
										
											2020-08-08 11:02:11 +10:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2006-03-19 13:28:01 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   struct stat st; | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |   BLI_assert(!BLI_path_is_rel(path)); | 
					
						
							|  |  |  |   if (stat(path, &st)) { | 
					
						
							|  |  |  |     return (0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2006-03-19 13:28:01 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return (st.st_mode); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-01 21:46:55 +00:00
										 |  |  | #ifdef WIN32
 | 
					
						
							| 
									
										
										
										
											2019-11-06 17:16:46 +01:00
										 |  |  | int BLI_fstat(int fd, BLI_stat_t *buffer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #  if defined(_MSC_VER)
 | 
					
						
							|  |  |  |   return _fstat64(fd, buffer); | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  |   return _fstat(fd, buffer); | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-28 22:50:40 +06:00
										 |  |  | int BLI_stat(const char *path, BLI_stat_t *buffer) | 
					
						
							| 
									
										
										
										
											2012-05-01 21:46:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   int r; | 
					
						
							|  |  |  |   UTF16_ENCODE(path); | 
					
						
							| 
									
										
										
										
											2013-04-17 19:35:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   r = BLI_wstat(path_16, buffer); | 
					
						
							| 
									
										
										
										
											2013-04-17 19:35:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   UTF16_UN_ENCODE(path); | 
					
						
							|  |  |  |   return r; | 
					
						
							| 
									
										
										
										
											2012-05-01 21:46:55 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-06-23 10:07:06 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | #  if defined(_MSC_VER)
 | 
					
						
							|  |  |  |   return _wstat64(path, buffer); | 
					
						
							|  |  |  | #  else
 | 
					
						
							|  |  |  |   return _wstat(path, buffer); | 
					
						
							|  |  |  | #  endif
 | 
					
						
							| 
									
										
										
										
											2014-06-23 10:07:06 +09:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-05-01 21:46:55 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-11-06 17:16:46 +01:00
										 |  |  | int BLI_fstat(int fd, struct stat *buffer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return fstat(fd, buffer); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-01 21:46:55 +00:00
										 |  |  | int BLI_stat(const char *path, struct stat *buffer) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return stat(path, buffer); | 
					
						
							| 
									
										
										
										
											2012-05-01 21:46:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Does the specified path point to a directory? | 
					
						
							|  |  |  |  * \note Would be better in fileops.c except that it needs stat.h so add here | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | bool BLI_is_dir(const char *file) | 
					
						
							| 
									
										
										
										
											2011-09-28 05:53:40 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return S_ISDIR(BLI_exists(file)); | 
					
						
							| 
									
										
										
										
											2009-10-16 10:22:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Does the specified path point to a non-directory? | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | bool BLI_is_file(const char *path) | 
					
						
							| 
									
										
										
										
											2011-12-12 18:06:36 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   const int mode = BLI_exists(path); | 
					
						
							|  |  |  |   return (mode && !S_ISDIR(mode)); | 
					
						
							| 
									
										
										
										
											2011-12-12 18:06:36 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Use for both text and binary file reading. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void *file_read_data_as_mem_impl(FILE *fp, | 
					
						
							|  |  |  |                                         bool read_size_exact, | 
					
						
							|  |  |  |                                         size_t pad_bytes, | 
					
						
							|  |  |  |                                         size_t *r_size) | 
					
						
							| 
									
										
										
										
											2015-12-14 17:12:16 +11:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-06 17:16:46 +01:00
										 |  |  |   BLI_stat_t st; | 
					
						
							|  |  |  |   if (BLI_fstat(fileno(fp), &st) == -1) { | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (S_ISDIR(st.st_mode)) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-03-18 12:13:03 -06:00
										 |  |  |   if (BLI_fseek(fp, 0L, SEEK_END) == -1) { | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* Don't use the 'st_size' because it may be the symlink. */ | 
					
						
							| 
									
										
										
										
											2020-03-18 12:13:03 -06:00
										 |  |  |   const long int filelen = BLI_ftell(fp); | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |   if (filelen == -1) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-03-18 12:13:03 -06:00
										 |  |  |   if (BLI_fseek(fp, 0L, SEEK_SET) == -1) { | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |   void *mem = MEM_mallocN(filelen + pad_bytes, __func__); | 
					
						
							|  |  |  |   if (mem == NULL) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |   const long int filelen_read = fread(mem, 1, filelen, fp); | 
					
						
							|  |  |  |   if ((filelen_read < 0) || ferror(fp)) { | 
					
						
							|  |  |  |     MEM_freeN(mem); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |   if (read_size_exact) { | 
					
						
							|  |  |  |     if (filelen_read != filelen) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       MEM_freeN(mem); | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |       return NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     if (filelen_read < filelen) { | 
					
						
							|  |  |  |       mem = MEM_reallocN(mem, filelen_read + pad_bytes); | 
					
						
							|  |  |  |       if (mem == NULL) { | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  |   *r_size = filelen_read; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return mem; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-30 10:43:07 +10:00
										 |  |  | void *BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   FILE *fp = BLI_fopen(filepath, "r"); | 
					
						
							|  |  |  |   void *mem = NULL; | 
					
						
							|  |  |  |   if (fp) { | 
					
						
							| 
									
										
										
										
											2019-08-01 16:12:39 +10:00
										 |  |  |     mem = file_read_data_as_mem_impl(fp, false, pad_bytes, r_size); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     fclose(fp); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return mem; | 
					
						
							| 
									
										
										
										
											2015-12-14 17:12:16 +11:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 18:16:14 +11:00
										 |  |  | void *BLI_file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   FILE *fp = BLI_fopen(filepath, "rb"); | 
					
						
							|  |  |  |   void *mem = NULL; | 
					
						
							|  |  |  |   if (fp) { | 
					
						
							| 
									
										
										
										
											2019-08-01 16:12:39 +10:00
										 |  |  |     mem = file_read_data_as_mem_impl(fp, true, pad_bytes, r_size); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     fclose(fp); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return mem; | 
					
						
							| 
									
										
										
										
											2015-12-21 18:16:14 +11:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-12-14 17:12:16 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-26 18:01:42 +11:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Return the text file data with: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * - Newlines replaced with '\0'. | 
					
						
							| 
									
										
										
										
											2020-06-27 14:34:16 +10:00
										 |  |  |  * - Optionally trim white-space, replacing trailing <space> & <tab> with '\0'. | 
					
						
							| 
									
										
										
										
											2020-02-26 18:01:42 +11:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This is an alternative to using #BLI_file_read_as_lines, | 
					
						
							|  |  |  |  * allowing us to loop over lines without converting it into a linked list | 
					
						
							|  |  |  |  * with individual allocations. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \param trim_trailing_space: Replace trailing spaces & tabs with nil. | 
					
						
							|  |  |  |  * This arguments prevents the caller from counting blank lines (if that's important). | 
					
						
							|  |  |  |  * \param pad_bytes: When this is non-zero, the first byte is set to nil, | 
					
						
							|  |  |  |  * to simplify parsing the file. | 
					
						
							|  |  |  |  * It's recommended to pass in 1, so all text is nil terminated. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Example looping over lines: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \code{.c} | 
					
						
							|  |  |  |  * size_t data_len; | 
					
						
							|  |  |  |  * char *data = BLI_file_read_text_as_mem_with_newline_as_nil(filepath, true, 1, &data_len); | 
					
						
							|  |  |  |  * char *data_end = data + data_len; | 
					
						
							|  |  |  |  * for (char *line = data; line != data_end; line = strlen(line) + 1) { | 
					
						
							|  |  |  |  *  printf("line='%s'\n", line); | 
					
						
							|  |  |  |  * } | 
					
						
							|  |  |  |  * \endcode | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void *BLI_file_read_text_as_mem_with_newline_as_nil(const char *filepath, | 
					
						
							|  |  |  |                                                     bool trim_trailing_space, | 
					
						
							|  |  |  |                                                     size_t pad_bytes, | 
					
						
							|  |  |  |                                                     size_t *r_size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *mem = BLI_file_read_text_as_mem(filepath, pad_bytes, r_size); | 
					
						
							|  |  |  |   if (mem != NULL) { | 
					
						
							|  |  |  |     char *mem_end = mem + *r_size; | 
					
						
							|  |  |  |     if (pad_bytes != 0) { | 
					
						
							|  |  |  |       *mem_end = '\0'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for (char *p = mem, *p_next; p != mem_end; p = p_next) { | 
					
						
							|  |  |  |       p_next = memchr(p, '\n', mem_end - p); | 
					
						
							|  |  |  |       if (p_next != NULL) { | 
					
						
							|  |  |  |         if (trim_trailing_space) { | 
					
						
							|  |  |  |           for (char *p_trim = p_next - 1; p_trim > p && ELEM(*p_trim, ' ', '\t'); p_trim--) { | 
					
						
							|  |  |  |             *p_trim = '\0'; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         *p_next = '\0'; | 
					
						
							|  |  |  |         p_next++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         p_next = mem_end; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return mem; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * Reads the contents of a text file and returns the lines in a linked list. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  | LinkNode *BLI_file_read_as_lines(const char *filepath) | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |   FILE *fp = BLI_fopen(filepath, "r"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   LinkNodePair lines = {NULL, NULL}; | 
					
						
							|  |  |  |   char *buf; | 
					
						
							|  |  |  |   size_t size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!fp) { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-18 12:13:03 -06:00
										 |  |  |   BLI_fseek(fp, 0, SEEK_END); | 
					
						
							|  |  |  |   size = (size_t)BLI_ftell(fp); | 
					
						
							|  |  |  |   BLI_fseek(fp, 0, SEEK_SET); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (UNLIKELY(size == (size_t)-1)) { | 
					
						
							|  |  |  |     fclose(fp); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   buf = MEM_mallocN(size, "file_as_lines"); | 
					
						
							|  |  |  |   if (buf) { | 
					
						
							|  |  |  |     size_t i, last = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * size = because on win32 reading | 
					
						
							|  |  |  |      * all the bytes in the file will return | 
					
						
							|  |  |  |      * less bytes because of `CRNL` changes. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     size = fread(buf, 1, size, fp); | 
					
						
							|  |  |  |     for (i = 0; i <= size; i++) { | 
					
						
							|  |  |  |       if (i == size || buf[i] == '\n') { | 
					
						
							|  |  |  |         char *line = BLI_strdupn(&buf[last], i - last); | 
					
						
							|  |  |  |         BLI_linklist_append(&lines, line); | 
					
						
							|  |  |  |         last = i + 1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MEM_freeN(buf); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   fclose(fp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return lines.list; | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Frees memory from a previous call to BLI_file_read_as_lines. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-10-22 15:35:49 +00:00
										 |  |  | void BLI_file_free_lines(LinkNode *lines) | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   BLI_linklist_freeN(lines); | 
					
						
							| 
									
										
										
										
											2002-10-12 11:37:38 +00:00
										 |  |  | } | 
					
						
							| 
									
										
											  
											
												Merge image related changes from the render branch. This includes the image
tile cache code in imbuf, but it is not hooked up to the render engine.
Imbuf module: some small refactoring and removing a lot of unused or old code
(about 6.5k lines).
* Added a ImFileType struct with callbacks to make adding an file format type,
  or making changes to the API easier.
* Move imbuf init/exit code into IMB_init()/IMB_exit() functions.
* Increased mipmap levels from 10 to 20, you run into this limit already with
  a 2k image.
* Removed hamx, amiga, anim5 format support.
* Removed colormap saving, only simple colormap code now for reading tga.
* Removed gen_dynlibtiff.py, editing this is almost as much work as just
  editing the code directly.
* Functions removed that were only used for sequencer plugin API:
  IMB_anim_nextpic, IMB_clever_double, IMB_antialias, IMB_gamwarp,
  IMB_scalefieldImBuf, IMB_scalefastfieldImBuf, IMB_onethird, IMB_halflace,
  IMB_dit0, IMB_dit2, IMB_cspace
* Write metadata info into OpenEXR images. Can be viewed with the command
  line utility 'exrheader'
For the image tile cache code, see this page:
http://wiki.blender.org/index.php/Dev:2.5/Source/Imaging/ImageTileCache
											
										 
											2010-05-07 15:18:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-19 08:43:08 -07:00
										 |  |  | /** is file1 older than file2 */ | 
					
						
							| 
									
										
										
										
											2013-03-05 03:17:46 +00:00
										 |  |  | bool BLI_file_older(const char *file1, const char *file2) | 
					
						
							| 
									
										
											  
											
												Merge image related changes from the render branch. This includes the image
tile cache code in imbuf, but it is not hooked up to the render engine.
Imbuf module: some small refactoring and removing a lot of unused or old code
(about 6.5k lines).
* Added a ImFileType struct with callbacks to make adding an file format type,
  or making changes to the API easier.
* Move imbuf init/exit code into IMB_init()/IMB_exit() functions.
* Increased mipmap levels from 10 to 20, you run into this limit already with
  a 2k image.
* Removed hamx, amiga, anim5 format support.
* Removed colormap saving, only simple colormap code now for reading tga.
* Removed gen_dynlibtiff.py, editing this is almost as much work as just
  editing the code directly.
* Functions removed that were only used for sequencer plugin API:
  IMB_anim_nextpic, IMB_clever_double, IMB_antialias, IMB_gamwarp,
  IMB_scalefieldImBuf, IMB_scalefastfieldImBuf, IMB_onethird, IMB_halflace,
  IMB_dit0, IMB_dit2, IMB_cspace
* Write metadata info into OpenEXR images. Can be viewed with the command
  line utility 'exrheader'
For the image tile cache code, see this page:
http://wiki.blender.org/index.php/Dev:2.5/Source/Imaging/ImageTileCache
											
										 
											2010-05-07 15:18:04 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-04-12 02:15:33 +00:00
										 |  |  | #ifdef WIN32
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   struct _stat st1, st2; | 
					
						
							| 
									
										
										
										
											2012-03-20 02:17:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   UTF16_ENCODE(file1); | 
					
						
							|  |  |  |   UTF16_ENCODE(file2); | 
					
						
							| 
									
										
										
										
											2013-04-17 19:35:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   if (_wstat(file1_16, &st1)) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (_wstat(file2_16, &st2)) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-20 02:17:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   UTF16_UN_ENCODE(file2); | 
					
						
							|  |  |  |   UTF16_UN_ENCODE(file1); | 
					
						
							| 
									
										
										
										
											2012-03-20 02:17:37 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   struct stat st1, st2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (stat(file1, &st1)) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (stat(file2, &st2)) { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-03-20 02:17:37 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   return (st1.st_mtime < st2.st_mtime); | 
					
						
							| 
									
										
											  
											
												Merge image related changes from the render branch. This includes the image
tile cache code in imbuf, but it is not hooked up to the render engine.
Imbuf module: some small refactoring and removing a lot of unused or old code
(about 6.5k lines).
* Added a ImFileType struct with callbacks to make adding an file format type,
  or making changes to the API easier.
* Move imbuf init/exit code into IMB_init()/IMB_exit() functions.
* Increased mipmap levels from 10 to 20, you run into this limit already with
  a 2k image.
* Removed hamx, amiga, anim5 format support.
* Removed colormap saving, only simple colormap code now for reading tga.
* Removed gen_dynlibtiff.py, editing this is almost as much work as just
  editing the code directly.
* Functions removed that were only used for sequencer plugin API:
  IMB_anim_nextpic, IMB_clever_double, IMB_antialias, IMB_gamwarp,
  IMB_scalefieldImBuf, IMB_scalefastfieldImBuf, IMB_onethird, IMB_halflace,
  IMB_dit0, IMB_dit2, IMB_cspace
* Write metadata info into OpenEXR images. Can be viewed with the command
  line utility 'exrheader'
For the image tile cache code, see this page:
http://wiki.blender.org/index.php/Dev:2.5/Source/Imaging/ImageTileCache
											
										 
											2010-05-07 15:18:04 +00:00
										 |  |  | } |