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