1/* 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 268