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