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
102CStdLibFileIO::CStdLibFileIO()
103{
104    memset(m_cFileName, 0, MAX_PATH);
105    m_bReadOnly = FALSE;
106    m_pFile = NULL;
107}
108
109CStdLibFileIO::~CStdLibFileIO()
110{
111    Close();
112}
113
114int CStdLibFileIO::GetHandle()
115{
116    return FILENO(m_pFile);
117}
118
119int 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
160int 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
173int 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
179int 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
186int CStdLibFileIO::Seek(int nDistance, unsigned int nMoveMode)
187{
188    return fseek(m_pFile, nDistance, nMoveMode);
189}
190
191int CStdLibFileIO::SetEOF()
192{
193    return ftruncate(GetHandle(), GetPosition());
194}
195
196int 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
206int 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
215int CStdLibFileIO::GetName(char * pBuffer)
216{
217    strcpy(pBuffer, m_cFileName);
218    return 0;
219}
220
221int 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
244int 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