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