xref: /haiku/src/add-ons/media/plugins/ape_reader/MAClib/StdLibFileIO.cpp (revision 053cc0d4fe060114342762e1e8dbbf86a9cad259)
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 
CStdLibFileIO()102 CStdLibFileIO::CStdLibFileIO()
103 {
104     memset(m_cFileName, 0, MAX_PATH);
105     m_bReadOnly = FALSE;
106     m_pFile = NULL;
107 }
108 
~CStdLibFileIO()109 CStdLibFileIO::~CStdLibFileIO()
110 {
111     Close();
112 }
113 
GetHandle()114 int CStdLibFileIO::GetHandle()
115 {
116     return FILENO(m_pFile);
117 }
118 
Open(LPCTSTR pName)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 
Close()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 
Read(void * pBuffer,unsigned int nBytesToRead,unsigned int * pBytesRead)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 
Write(const void * pBuffer,unsigned int nBytesToWrite,unsigned int * pBytesWritten)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 
Seek(int nDistance,unsigned int nMoveMode)186 int CStdLibFileIO::Seek(int nDistance, unsigned int nMoveMode)
187 {
188     return fseek(m_pFile, nDistance, nMoveMode);
189 }
190 
SetEOF()191 int CStdLibFileIO::SetEOF()
192 {
193     return ftruncate(GetHandle(), GetPosition());
194 }
195 
GetPosition()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 
GetSize()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 
GetName(char * pBuffer)215 int CStdLibFileIO::GetName(char * pBuffer)
216 {
217     strcpy(pBuffer, m_cFileName);
218     return 0;
219 }
220 
Create(const char * pName)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 
Delete()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