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 102CStdLibFileIO::CStdLibFileIO() 103{ 104 memset(m_cFileName, 0, MAX_PATH); 105 m_bReadOnly = FALSE; 106 m_pFile = NULL; 107} 108 109CStdLibFileIO::~CStdLibFileIO() 110{ 111 Close(); 112} 113 114int CStdLibFileIO::GetHandle() 115{ 116 return FILENO(m_pFile); 117} 118 119int 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 160int 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 173int 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 179int 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 186int CStdLibFileIO::Seek(int nDistance, unsigned int nMoveMode) 187{ 188 return fseek(m_pFile, nDistance, nMoveMode); 189} 190 191int CStdLibFileIO::SetEOF() 192{ 193 return ftruncate(GetHandle(), GetPosition()); 194} 195 196int 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 206int 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 215int CStdLibFileIO::GetName(char * pBuffer) 216{ 217 strcpy(pBuffer, m_cFileName); 218 return 0; 219} 220 221int 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 244int 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