1 #include "All.h" 2 3 #ifdef IO_USE_STD_LIB_FILE_IO 4 5 #include "StdLibFileIO.h" 6 7 /////////////////////////////////////////////////////// 8 9 // low level I/O, where are prototypes and constants? 10 #if defined _WIN32 || defined __TURBOC__ || defined __ZTC__ || defined _MSC_VER 11 # include <io.h> 12 # include <fcntl.h> 13 # include <time.h> 14 # include <sys/types.h> 15 # include <sys/stat.h> 16 #elif defined __unix__ || defined __linux__ 17 # include <fcntl.h> 18 # include <unistd.h> 19 # include <sys/time.h> 20 # include <sys/ioctl.h> 21 # include <sys/types.h> 22 # include <sys/stat.h> 23 #else 24 # include <fcntl.h> 25 # include <unistd.h> 26 # include <sys/ioctl.h> 27 # include <sys/stat.h> 28 #endif 29 30 31 #ifndef O_BINARY 32 # ifdef _O_BINARY 33 # define O_BINARY _O_BINARY 34 # else 35 # define O_BINARY 0 36 # endif 37 #endif 38 39 //// Binary/Low-Level-IO /////////////////////////////////////////// 40 // 41 // All file I/O is basicly handled via an ANSI file pointer (type: FILE*) in 42 // FILEIO-Mode 1 and via a POSIX file descriptor (type: int) in 43 // FILEIO-Mode 2 and 3. 44 // 45 // Some operation are only available via the POSIX interface (fcntl, setmode, 46 // ...) so we need a function to get the file descriptor from a file pointer. 47 // In FILEIO-Mode 2 and 3 this is a dummy function because we always working 48 // with this file descriptors. 49 // 50 51 #if defined __BORLANDC__ || defined _WIN32 52 # define FILENO(__fp) _fileno ((__fp)) 53 #elif defined __CYGWIN__ || defined __TURBOC__ || defined __unix__ || defined __EMX__ || defined _MSC_VER 54 # define FILENO(__fp) fileno ((__fp)) 55 #else 56 # define FILENO(__fp) fileno ((__fp)) 57 #endif 58 59 60 // 61 // If we have access to a file via file name, we can open the file with an 62 // additional "b" or a O_BINARY within the (f)open function to get a 63 // transparent untranslated data stream which is necessary for audio bitstream 64 // data and also for PCM data. If we are working with 65 // stdin/stdout/FILENO_STDIN/FILENO_STDOUT we can't open the file with this 66 // attributes, because the files are already open. So we need a non 67 // standardized sequence to switch to this mode (not necessary for Unix). 68 // Mostly the sequency is the same for incoming and outgoing streams, but only 69 // mostly so we need one for IN and one for OUT. 70 // Macros are called with the file pointer and you get back the untransalted file 71 // pointer which can be equal or different from the original. 72 // 73 74 #if defined __EMX__ 75 # define SETBINARY_IN(__fp) (_fsetmode ( (__fp), "b" ), (__fp)) 76 # define SETBINARY_OUT(__fp) (_fsetmode ( (__fp), "b" ), (__fp)) 77 #elif defined __TURBOC__ || defined __BORLANDC__ 78 # define SETBINARY_IN(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) 79 # define SETBINARY_OUT(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) 80 #elif defined __CYGWIN__ 81 # define SETBINARY_IN(__fp) (setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) 82 # define SETBINARY_OUT(__fp) (setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) 83 #elif defined _WIN32 84 # define SETBINARY_IN(__fp) (_setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) 85 # define SETBINARY_OUT(__fp) (_setmode ( FILENO ((__fp)), _O_BINARY ), (__fp)) 86 #elif defined _MSC_VER 87 # define SETBINARY_IN(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) 88 # define SETBINARY_OUT(__fp) (setmode ( FILENO ((__fp)), O_BINARY ), (__fp)) 89 #elif defined __unix__ 90 # define SETBINARY_IN(__fp) (__fp) 91 # define SETBINARY_OUT(__fp) (__fp) 92 #elif 0 93 # define SETBINARY_IN(__fp) (freopen ( NULL, "rb", (__fp) ), (__fp)) 94 # define SETBINARY_OUT(__fp) (freopen ( NULL, "wb", (__fp) ), (__fp)) 95 #else 96 # define SETBINARY_IN(__fp) (__fp) 97 # define SETBINARY_OUT(__fp) (__fp) 98 #endif 99 100 /////////////////////////////////////////////////////// 101 102 CStdLibFileIO::CStdLibFileIO() 103 { 104 memset(m_cFileName, 0, MAX_PATH); 105 m_bReadOnly = FALSE; 106 m_pFile = NULL; 107 } 108 109 CStdLibFileIO::~CStdLibFileIO() 110 { 111 Close(); 112 } 113 114 int CStdLibFileIO::GetHandle() 115 { 116 return FILENO(m_pFile); 117 } 118 119 int CStdLibFileIO::Open(LPCTSTR pName) 120 { 121 // DBEXP("CStdLibFileIO::Open",""); 122 123 Close(); 124 125 m_bReadOnly = FALSE; 126 127 if (0 == strcmp(pName, "-") || 0 == strcmp(pName, "/dev/stdin")) 128 { 129 m_pFile = SETBINARY_IN(stdin); 130 m_bReadOnly = TRUE; // ReadOnly 131 } 132 else if (0 == strcmp (pName, "/dev/stdout")) 133 { 134 m_pFile = SETBINARY_OUT(stdout); 135 m_bReadOnly = FALSE; // WriteOnly 136 } 137 else 138 { 139 // SHINTA --> 140 // "rb" to "rb+"; to change APE tag by CAPETag::SetField() 141 m_pFile = fopen(pName, "rb+"); 142 m_bReadOnly = FALSE; // Read/Write 143 144 if ( !m_pFile ) { 145 // Try read only open 146 m_pFile = fopen(pName, "rb"); 147 m_bReadOnly = TRUE; 148 } 149 // <-- SHINTA 150 } 151 152 if (!m_pFile) 153 return -1; 154 155 strcpy(m_cFileName, pName); 156 157 return 0; 158 } 159 160 int CStdLibFileIO::Close() 161 { 162 int nRetVal = -1; 163 164 if (m_pFile != NULL) 165 { 166 nRetVal = fclose(m_pFile); 167 m_pFile = NULL; 168 } 169 170 return nRetVal; 171 } 172 173 int CStdLibFileIO::Read(void * pBuffer, unsigned int nBytesToRead, unsigned int * pBytesRead) 174 { 175 *pBytesRead = fread(pBuffer, 1, nBytesToRead, m_pFile); 176 return ferror(m_pFile) ? ERROR_IO_READ : 0; 177 } 178 179 int CStdLibFileIO::Write(const void * pBuffer, unsigned int nBytesToWrite, unsigned int * pBytesWritten) 180 { 181 *pBytesWritten = fwrite(pBuffer, 1, nBytesToWrite, m_pFile); 182 183 return (ferror(m_pFile) || (*pBytesWritten != nBytesToWrite)) ? ERROR_IO_WRITE : 0; 184 } 185 186 int CStdLibFileIO::Seek(int nDistance, unsigned int nMoveMode) 187 { 188 return fseek(m_pFile, nDistance, nMoveMode); 189 } 190 191 int CStdLibFileIO::SetEOF() 192 { 193 return ftruncate(GetHandle(), GetPosition()); 194 } 195 196 int CStdLibFileIO::GetPosition() 197 { 198 fpos_t fPosition; 199 200 memset(&fPosition, 0, sizeof(fPosition)); 201 fgetpos(m_pFile, &fPosition); 202 return fPosition; 203 // return _FPOSOFF(fPosition); //?? SHINTA 204 } 205 206 int CStdLibFileIO::GetSize() 207 { 208 int nCurrentPosition = GetPosition(); 209 Seek(0, FILE_END); 210 int nLength = GetPosition(); 211 Seek(nCurrentPosition, FILE_BEGIN); 212 return nLength; 213 } 214 215 int CStdLibFileIO::GetName(char * pBuffer) 216 { 217 strcpy(pBuffer, m_cFileName); 218 return 0; 219 } 220 221 int CStdLibFileIO::Create(const char* pName) 222 { 223 Close(); 224 225 if (0 == strcmp (pName, "-") || 0 == strcmp (pName, "/dev/stdout")) 226 { 227 m_pFile = SETBINARY_OUT(stdout); 228 m_bReadOnly = FALSE; // WriteOnly 229 } 230 else 231 { 232 m_pFile = fopen (pName, "w+b"); // Read/Write // SHINTA 233 m_bReadOnly = FALSE; 234 } 235 236 if (!m_pFile) 237 return -1; 238 239 strcpy (m_cFileName, pName); 240 241 return 0; 242 } 243 244 int CStdLibFileIO::Delete() 245 { 246 Close(); 247 return unlink (m_cFileName); // 0 success, -1 error 248 } 249 250 #endif // #ifdef IO_USE_STD_LIB_FILE_IO 251