/* * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "file_impl.h" #include <cassert> #ifdef _WIN32 #include <Windows.h> #else #include <stdarg.h> #include <string.h> #endif namespace webrtc { FileWrapper* FileWrapper::Create() { return new FileWrapperImpl(); } FileWrapperImpl::FileWrapperImpl() : _id(NULL), _open(false), _looping(false), _readOnly(false), _text(false), _maxSizeInBytes(-1), _sizeInBytes(0) { memset(_fileNameUTF8, 0, kMaxFileNameSize); } FileWrapperImpl::~FileWrapperImpl() { if (_id != NULL) { fclose(_id); } } WebRtc_Word32 FileWrapperImpl::CloseFile() { if (_id != NULL) { fclose(_id); _id = NULL; } memset(_fileNameUTF8, 0, kMaxFileNameSize); _open = false; return 0; } int FileWrapperImpl::Rewind() { if(_looping || !_readOnly) { if (_id != NULL) { _sizeInBytes = 0; return fseek(_id, 0, SEEK_SET); } } return -1; } WebRtc_Word32 FileWrapperImpl::SetMaxFileSize(WebRtc_Word32 bytes) { _maxSizeInBytes = bytes; return 0; } WebRtc_Word32 FileWrapperImpl::Flush() { if (_id != NULL) { return fflush(_id); } return -1; } WebRtc_Word32 FileWrapperImpl::FileName(WebRtc_Word8* fileNameUTF8, WebRtc_UWord32 size) const { WebRtc_Word32 len = static_cast<WebRtc_Word32>(strlen(_fileNameUTF8)); if(len > kMaxFileNameSize) { assert(false); return -1; } if(len < 1) { return -1; } // Make sure to NULL terminate if(size < (WebRtc_UWord32)len) { len = size - 1; } memcpy(fileNameUTF8, _fileNameUTF8, len); fileNameUTF8[len] = 0; return 0; } bool FileWrapperImpl::Open() const { return _open; } WebRtc_Word32 FileWrapperImpl::OpenFile(const WebRtc_Word8 *fileNameUTF8, const bool readOnly, const bool loop, const bool text) { WebRtc_Word32 length = (WebRtc_Word32)strlen(fileNameUTF8); if (length > kMaxFileNameSize) { return -1; } _readOnly = readOnly; FILE *tmpId = NULL; #if defined _WIN32 wchar_t wideFileName[kMaxFileNameSize]; wideFileName[0] = 0; MultiByteToWideChar(CP_UTF8, 0 /*UTF8 flag*/, fileNameUTF8, -1 /*Null terminated string*/, wideFileName, kMaxFileNameSize); if(text) { if(readOnly) { tmpId = _wfopen(wideFileName, L"rt"); } else { tmpId = _wfopen(wideFileName, L"wt"); } } else { if(readOnly) { tmpId = _wfopen(wideFileName, L"rb"); } else { tmpId = _wfopen(wideFileName, L"wb"); } } #else if(text) { if(readOnly) { tmpId = fopen(fileNameUTF8, "rt"); } else { tmpId = fopen(fileNameUTF8, "wt"); } } else { if(readOnly) { tmpId = fopen(fileNameUTF8, "rb"); } else { tmpId = fopen(fileNameUTF8, "wb"); } } #endif if (tmpId != NULL) { // + 1 comes fro copying the NULL termination charachter too memcpy(_fileNameUTF8, fileNameUTF8, length + 1); if (_id != NULL) { fclose(_id); } _id = tmpId; _looping = loop; _open = true; return 0; } return -1; } int FileWrapperImpl::Read(void *buf, int len) { if(len < 0) { return 0; } if (_id != NULL) { WebRtc_Word32 res = static_cast<WebRtc_Word32>(fread(buf, 1, len, _id)); if (res != len) { if(!_looping) { CloseFile(); } } return res; } return -1; } WebRtc_Word32 FileWrapperImpl::WriteText(const WebRtc_Word8* text, ...) { assert(!_readOnly); assert(!_text); if (_id == NULL) { return -1; } char tempBuff[kFileMaxTextMessageSize]; if (text) { va_list args; va_start(args, text); #ifdef _WIN32 _vsnprintf(tempBuff, kFileMaxTextMessageSize-1, text, args); #else vsnprintf(tempBuff, kFileMaxTextMessageSize-1, text, args); #endif va_end(args); WebRtc_Word32 nBytes; nBytes = fprintf(_id, "%s", tempBuff); if (nBytes > 0) { return 0; } CloseFile(); } return -1; } bool FileWrapperImpl::Write(const void* buf, int len) { assert(!_readOnly); if (_id != NULL) { // Check if it's time to stop writing. if ((_maxSizeInBytes != -1) && _sizeInBytes + len > (WebRtc_UWord32)_maxSizeInBytes) { Flush(); return false; } size_t nBytes = fwrite((WebRtc_UWord8*)buf, 1, len, _id); if (nBytes > 0) { _sizeInBytes += static_cast<WebRtc_Word32>(nBytes); return true; } CloseFile(); } return false; } } // namespace webrtc