blob: 6046c2c77c3721719ac17f9ac86d397724100b8a [file] [log] [blame]
niklase@google.comf0779a22011-05-30 11:39:38 +00001/*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "file_impl.h"
12
13#include <cassert>
14
15#ifdef _WIN32
16 #include <Windows.h>
17#else
18 #include <stdarg.h>
19 #include <string.h>
20#endif
21
22namespace webrtc {
23FileWrapper* FileWrapper::Create()
24{
25 return new FileWrapperImpl();
26}
27
28FileWrapperImpl::FileWrapperImpl()
29 : _id(NULL),
30 _open(false),
31 _looping(false),
32 _readOnly(false),
33 _text(false),
34 _maxSizeInBytes(-1),
35 _sizeInBytes(0)
36{
37 memset(_fileNameUTF8, 0, kMaxFileNameSize);
38}
39
40FileWrapperImpl::~FileWrapperImpl()
41{
42 if (_id != NULL)
43 {
44 fclose(_id);
45 }
46}
47
48WebRtc_Word32 FileWrapperImpl::CloseFile()
49{
50 if (_id != NULL)
51 {
52 fclose(_id);
53 _id = NULL;
54 }
55 memset(_fileNameUTF8, 0, kMaxFileNameSize);
56 _open = false;
57 return 0;
58}
59
60int FileWrapperImpl::Rewind()
61{
62 if(_looping || !_readOnly)
63 {
64 if (_id != NULL)
65 {
66 _sizeInBytes = 0;
67 return fseek(_id, 0, SEEK_SET);
68 }
69 }
70 return -1;
71}
72
73WebRtc_Word32 FileWrapperImpl::SetMaxFileSize(WebRtc_Word32 bytes)
74{
75 _maxSizeInBytes = bytes;
76 return 0;
77}
78
79WebRtc_Word32 FileWrapperImpl::Flush()
80{
81 if (_id != NULL)
82 {
83 return fflush(_id);
84 }
85 return -1;
86}
87
88WebRtc_Word32 FileWrapperImpl::FileName(WebRtc_Word8* fileNameUTF8,
89 WebRtc_UWord32 size) const
90{
91 WebRtc_Word32 len = static_cast<WebRtc_Word32>(strlen(_fileNameUTF8));
92 if(len > kMaxFileNameSize)
93 {
94 assert(false);
95 return -1;
96 }
97 if(len < 1)
98 {
99 return -1;
100 }
101 // Make sure to NULL terminate
102 if(size < (WebRtc_UWord32)len)
103 {
104 len = size - 1;
105 }
106 memcpy(fileNameUTF8, _fileNameUTF8, len);
107 fileNameUTF8[len] = 0;
108 return 0;
109}
110
111bool
112FileWrapperImpl::Open() const
113{
114 return _open;
115}
116
117WebRtc_Word32 FileWrapperImpl::OpenFile(const WebRtc_Word8 *fileNameUTF8,
118 const bool readOnly, const bool loop,
119 const bool text)
120{
121 WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8);
122 if (length > kMaxFileNameSize)
123 {
124 return -1;
125 }
126
127 _readOnly = readOnly;
128
129 FILE *tmpId = NULL;
130#if defined _WIN32
131 wchar_t wideFileName[kMaxFileNameSize];
132 wideFileName[0] = 0;
133
134 MultiByteToWideChar(CP_UTF8,
135 0 /*UTF8 flag*/,
136 fileNameUTF8,
137 -1 /*Null terminated string*/,
138 wideFileName,
139 kMaxFileNameSize);
140 if(text)
141 {
142 if(readOnly)
143 {
144 tmpId = _wfopen(wideFileName, L"rt");
145 } else {
146 tmpId = _wfopen(wideFileName, L"wt");
147 }
148 } else {
149 if(readOnly)
150 {
151 tmpId = _wfopen(wideFileName, L"rb");
152 } else {
153 tmpId = _wfopen(wideFileName, L"wb");
154 }
155 }
156#else
157 if(text)
158 {
159 if(readOnly)
160 {
161 tmpId = fopen(fileNameUTF8, "rt");
162 } else {
163 tmpId = fopen(fileNameUTF8, "wt");
164 }
165 } else {
166 if(readOnly)
167 {
168 tmpId = fopen(fileNameUTF8, "rb");
169 } else {
170 tmpId = fopen(fileNameUTF8, "wb");
171 }
172 }
173#endif
174
175 if (tmpId != NULL)
176 {
177 // + 1 comes fro copying the NULL termination charachter too
178 memcpy(_fileNameUTF8, fileNameUTF8, length + 1);
179 if (_id != NULL)
180 {
181 fclose(_id);
182 }
183 _id = tmpId;
184 _looping = loop;
185 _open = true;
186 return 0;
187 }
188 return -1;
189}
190
191int FileWrapperImpl::Read(void *buf, int len)
192{
193 if(len < 0)
194 {
195 return 0;
196 }
197 if (_id != NULL)
198 {
199 WebRtc_Word32 res = static_cast<WebRtc_Word32>(fread(buf, 1, len, _id));
200 if (res != len)
201 {
202 if(!_looping)
203 {
204 CloseFile();
205 }
206 }
207 return res;
208 }
209 return -1;
210}
211
212WebRtc_Word32 FileWrapperImpl::WriteText(const WebRtc_Word8* text, ...)
213{
214 assert(!_readOnly);
215 assert(!_text);
216
217 if (_id == NULL)
218 {
219 return -1;
220 }
221
222 char tempBuff[kFileMaxTextMessageSize];
223 if (text)
224 {
225 va_list args;
226 va_start(args, text);
227#ifdef _WIN32
228 _vsnprintf(tempBuff, kFileMaxTextMessageSize-1, text, args);
229#else
230 vsnprintf(tempBuff, kFileMaxTextMessageSize-1, text, args);
231#endif
232 va_end(args);
233 WebRtc_Word32 nBytes;
234 nBytes = fprintf(_id, "%s", tempBuff);
235 if (nBytes > 0)
236 {
237 return 0;
238 }
239 CloseFile();
240 }
241 return -1;
242}
243
244bool FileWrapperImpl::Write(const void* buf, int len)
245{
246 assert(!_readOnly);
247 if (_id != NULL)
248 {
249 // Check if it's time to stop writing.
250 if ((_maxSizeInBytes != -1) &&
251 _sizeInBytes + len > (WebRtc_UWord32)_maxSizeInBytes)
252 {
253 Flush();
254 return false;
255 }
256
257 size_t nBytes = fwrite((WebRtc_UWord8*)buf, 1, len, _id);
258 if (nBytes > 0)
259 {
260 _sizeInBytes += static_cast<WebRtc_Word32>(nBytes);
261 return true;
262 }
263 CloseFile();
264 }
265 return false;
266}
267} // namespace webrtc