1/*
2******************************************************************************
3*
4*   Copyright (C) 1997-2011, International Business Machines
5*   Corporation and others.  All Rights Reserved.
6*
7******************************************************************************
8*
9* File FILESTRM.C
10*
11* @author       Glenn Marcy
12*
13* Modification History:
14*
15*   Date        Name        Description
16*   5/8/98      gm          Created
17*  03/02/99     stephen     Reordered params in ungetc to match stdio
18*                           Added wopen
19*   3/29/99     helena      Merged Stephen and Bertrand's changes.
20*
21******************************************************************************
22*/
23
24#include "filestrm.h"
25
26#include "cmemory.h"
27
28#include <stdio.h>
29
30U_CAPI FileStream* U_EXPORT2
31T_FileStream_open(const char* filename, const char* mode)
32{
33    if(filename != NULL && *filename != 0 && mode != NULL && *mode != 0) {
34        FILE *file = fopen(filename, mode);
35        return (FileStream*)file;
36    } else {
37        return NULL;
38    }
39}
40
41/*
42U_CAPI FileStream* U_EXPORT2
43T_FileStream_wopen(const wchar_t* filename, const wchar_t* mode)
44{
45   // TBD: _wfopen is believed to be MS-specific?
46#if U_PLATFORM_USES_ONLY_WIN32_API
47    FILE* result = _wfopen(filename, mode);
48    return (FileStream*)result;
49#else
50    size_t fnMbsSize, mdMbsSize;
51    char *fn, *md;
52    FILE *result;
53
54    // convert from wchar_t to char
55    fnMbsSize = wcstombs(NULL, filename, ((size_t)-1) >> 1);
56    fn = (char*)uprv_malloc(fnMbsSize+2);
57    wcstombs(fn, filename, fnMbsSize);
58    fn[fnMbsSize] = 0;
59
60    mdMbsSize = wcstombs(NULL, mode, ((size_t)-1) >> 1);
61    md = (char*)uprv_malloc(mdMbsSize+2);
62    wcstombs(md, mode, mdMbsSize);
63    md[mdMbsSize] = 0;
64
65    result = fopen(fn, md);
66    uprv_free(fn);
67    uprv_free(md);
68    return (FileStream*)result;
69#endif
70}
71*/
72U_CAPI void U_EXPORT2
73T_FileStream_close(FileStream* fileStream)
74{
75    if (fileStream != 0)
76        fclose((FILE*)fileStream);
77}
78
79U_CAPI UBool U_EXPORT2
80T_FileStream_file_exists(const char* filename)
81{
82    FILE* temp = fopen(filename, "r");
83    if (temp) {
84        fclose(temp);
85        return TRUE;
86    } else
87        return FALSE;
88}
89
90/*static const int32_t kEOF;
91const int32_t FileStream::kEOF = EOF;*/
92
93/*
94U_CAPI FileStream*
95T_FileStream_tmpfile()
96{
97    FILE* file = tmpfile();
98    return (FileStream*)file;
99}
100*/
101
102U_CAPI int32_t U_EXPORT2
103T_FileStream_read(FileStream* fileStream, void* addr, int32_t len)
104{
105    return fread(addr, 1, len, (FILE*)fileStream);
106}
107
108U_CAPI int32_t U_EXPORT2
109T_FileStream_write(FileStream* fileStream, const void* addr, int32_t len)
110{
111
112    return fwrite(addr, 1, len, (FILE*)fileStream);
113}
114
115U_CAPI void U_EXPORT2
116T_FileStream_rewind(FileStream* fileStream)
117{
118    rewind((FILE*)fileStream);
119}
120
121U_CAPI int32_t U_EXPORT2
122T_FileStream_putc(FileStream* fileStream, int32_t ch)
123{
124    int32_t c = fputc(ch, (FILE*)fileStream);
125    return c;
126}
127
128U_CAPI int U_EXPORT2
129T_FileStream_getc(FileStream* fileStream)
130{
131    int c = fgetc((FILE*)fileStream);
132    return c;
133}
134
135U_CAPI int32_t U_EXPORT2
136T_FileStream_ungetc(int32_t ch, FileStream* fileStream)
137{
138
139    int32_t c = ungetc(ch, (FILE*)fileStream);
140    return c;
141}
142
143U_CAPI int32_t U_EXPORT2
144T_FileStream_peek(FileStream* fileStream)
145{
146    int32_t c = fgetc((FILE*)fileStream);
147    return ungetc(c, (FILE*)fileStream);
148}
149
150U_CAPI char* U_EXPORT2
151T_FileStream_readLine(FileStream* fileStream, char* buffer, int32_t length)
152{
153    return fgets(buffer, length, (FILE*)fileStream);
154}
155
156U_CAPI int32_t U_EXPORT2
157T_FileStream_writeLine(FileStream* fileStream, const char* buffer)
158{
159    return fputs(buffer, (FILE*)fileStream);
160}
161
162U_CAPI int32_t U_EXPORT2
163T_FileStream_size(FileStream* fileStream)
164{
165    int32_t savedPos = ftell((FILE*)fileStream);
166    int32_t size = 0;
167
168    /*Changes by Bertrand A. D. doesn't affect the current position
169    goes to the end of the file before ftell*/
170    fseek((FILE*)fileStream, 0, SEEK_END);
171    size = (int32_t)ftell((FILE*)fileStream);
172    fseek((FILE*)fileStream, savedPos, SEEK_SET);
173    return size;
174}
175
176U_CAPI int U_EXPORT2
177T_FileStream_eof(FileStream* fileStream)
178{
179    return feof((FILE*)fileStream);
180}
181
182/*
183 Warning
184 This function may not work consistently on all platforms
185 (e.g. HP-UX, FreeBSD and MacOSX don't return an error when
186 putc is used on a file opened as readonly)
187*/
188U_CAPI int U_EXPORT2
189T_FileStream_error(FileStream* fileStream)
190{
191    return (fileStream == 0 || ferror((FILE*)fileStream));
192}
193
194/* This function doesn't work. */
195/* force the stream to set its error flag*/
196/*U_CAPI void U_EXPORT2
197T_FileStream_setError(FileStream* fileStream)
198{
199    fseek((FILE*)fileStream, 99999, SEEK_SET);
200}
201*/
202
203U_CAPI FileStream* U_EXPORT2
204T_FileStream_stdin(void)
205{
206    return (FileStream*)stdin;
207}
208
209U_CAPI FileStream* U_EXPORT2
210T_FileStream_stdout(void)
211{
212    return (FileStream*)stdout;
213}
214
215
216U_CAPI FileStream* U_EXPORT2
217T_FileStream_stderr(void)
218{
219    return (FileStream*)stderr;
220}
221
222U_CAPI UBool U_EXPORT2
223T_FileStream_remove(const char* fileName){
224    return (remove(fileName) == 0);
225}
226