vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / media / plugins / ape_reader / MAClib / StdLibFileIO.cpp
blobd46c1ad062ecb99f7206f5ca9aaad07ad69b09e6
1 #include "All.h"
3 #ifdef IO_USE_STD_LIB_FILE_IO
5 #include "StdLibFileIO.h"
7 ///////////////////////////////////////////////////////
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
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
39 //// Binary/Low-Level-IO ///////////////////////////////////////////
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.
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.
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
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.
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
100 ///////////////////////////////////////////////////////
102 CStdLibFileIO::CStdLibFileIO()
104 memset(m_cFileName, 0, MAX_PATH);
105 m_bReadOnly = FALSE;
106 m_pFile = NULL;
109 CStdLibFileIO::~CStdLibFileIO()
111 Close();
114 int CStdLibFileIO::GetHandle()
116 return FILENO(m_pFile);
119 int CStdLibFileIO::Open(LPCTSTR pName)
121 // DBEXP("CStdLibFileIO::Open","");
123 Close();
125 m_bReadOnly = FALSE;
127 if (0 == strcmp(pName, "-") || 0 == strcmp(pName, "/dev/stdin"))
129 m_pFile = SETBINARY_IN(stdin);
130 m_bReadOnly = TRUE; // ReadOnly
132 else if (0 == strcmp (pName, "/dev/stdout"))
134 m_pFile = SETBINARY_OUT(stdout);
135 m_bReadOnly = FALSE; // WriteOnly
137 else
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
144 if ( !m_pFile ) {
145 // Try read only open
146 m_pFile = fopen(pName, "rb");
147 m_bReadOnly = TRUE;
149 // <-- SHINTA
152 if (!m_pFile)
153 return -1;
155 strcpy(m_cFileName, pName);
157 return 0;
160 int CStdLibFileIO::Close()
162 int nRetVal = -1;
164 if (m_pFile != NULL)
166 nRetVal = fclose(m_pFile);
167 m_pFile = NULL;
170 return nRetVal;
173 int CStdLibFileIO::Read(void * pBuffer, unsigned int nBytesToRead, unsigned int * pBytesRead)
175 *pBytesRead = fread(pBuffer, 1, nBytesToRead, m_pFile);
176 return ferror(m_pFile) ? ERROR_IO_READ : 0;
179 int CStdLibFileIO::Write(const void * pBuffer, unsigned int nBytesToWrite, unsigned int * pBytesWritten)
181 *pBytesWritten = fwrite(pBuffer, 1, nBytesToWrite, m_pFile);
183 return (ferror(m_pFile) || (*pBytesWritten != nBytesToWrite)) ? ERROR_IO_WRITE : 0;
186 int CStdLibFileIO::Seek(int nDistance, unsigned int nMoveMode)
188 return fseek(m_pFile, nDistance, nMoveMode);
191 int CStdLibFileIO::SetEOF()
193 return ftruncate(GetHandle(), GetPosition());
196 int CStdLibFileIO::GetPosition()
198 fpos_t fPosition;
200 memset(&fPosition, 0, sizeof(fPosition));
201 fgetpos(m_pFile, &fPosition);
202 return fPosition;
203 // return _FPOSOFF(fPosition); //?? SHINTA
206 int CStdLibFileIO::GetSize()
208 int nCurrentPosition = GetPosition();
209 Seek(0, FILE_END);
210 int nLength = GetPosition();
211 Seek(nCurrentPosition, FILE_BEGIN);
212 return nLength;
215 int CStdLibFileIO::GetName(char * pBuffer)
217 strcpy(pBuffer, m_cFileName);
218 return 0;
221 int CStdLibFileIO::Create(const wchar_t * pName)
223 Close();
225 if (0 == strcmp (pName, "-") || 0 == strcmp (pName, "/dev/stdout"))
227 m_pFile = SETBINARY_OUT(stdout);
228 m_bReadOnly = FALSE; // WriteOnly
230 else
232 m_pFile = fopen (pName, "w+b"); // Read/Write // SHINTA
233 m_bReadOnly = FALSE;
236 if (!m_pFile)
237 return -1;
239 strcpy (m_cFileName, pName);
241 return 0;
244 int CStdLibFileIO::Delete()
246 Close();
247 return unlink (m_cFileName); // 0 success, -1 error
250 #endif // #ifdef IO_USE_STD_LIB_FILE_IO