/* * Copyright (c) 2011-2014, Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "BinaryStream.h" #include #include using namespace std; CBinaryStream::CBinaryStream(const string& strFileName, bool bOut, size_t uiDataSize, uint8_t uiStructureChecksum) : _strFileName(strFileName), _bOut(bOut), _uiDataSize(uiDataSize), _uiStructureChecksum(uiStructureChecksum), _puiData(new uint8_t[uiDataSize]), _uiPos(0), _bOpen(false) { } CBinaryStream::~CBinaryStream() { if (_bOpen) { close(); } delete [] _puiData; } bool CBinaryStream::open(string& strError) { assert(!_bOpen); _fileStream.open(_strFileName.c_str(), (_bOut ? ios::out : ios::in|ios::ate)|ios::binary); if (!_fileStream.is_open() || !_fileStream.good()) { strError = string("Failed to ") + (_bOut ? "write" : "read") + "-open"; return false; } if (!_bOut) { // Get file size size_t uiFileSize = _fileStream.tellg(); // Validate file size if (_uiDataSize + sizeof(_uiStructureChecksum) != uiFileSize) { // Size different from expected strError = "Unexpected file size"; return false; } // Back to beginning of file _fileStream.seekg(0, ios::beg); // Get data _fileStream.read((char*)_puiData, _uiDataSize); // File checksum uint8_t uiFileChecksum; _fileStream.read((char*)&uiFileChecksum, sizeof(uiFileChecksum)); // Data checksum uint8_t uiDataChecksum = computeChecksum(); // Validate checksum if (uiDataChecksum != uiFileChecksum) { strError = "Integrity checks failed"; return false; } } // Keep track _bOpen = true; return true; } void CBinaryStream::close() { assert(_bOpen); if (_bOut) { // Get data _fileStream.write((const char*)_puiData, _uiDataSize); // Compute checksum uint8_t uiDataChecksum = computeChecksum(); // Write checksum _fileStream.write((const char*)&uiDataChecksum, sizeof(uiDataChecksum)); } // Keep track _bOpen = false; // Close file _fileStream.close(); } void CBinaryStream::reset() { _uiPos = 0; } void CBinaryStream::write(const uint8_t* puiData, size_t uiSize) { assert(_uiPos + uiSize <= _uiDataSize); memcpy(&_puiData[_uiPos], puiData, uiSize); _uiPos += uiSize; } void CBinaryStream::read(uint8_t* puiData, size_t uiSize) { assert(_uiPos + uiSize <= _uiDataSize); memcpy(puiData, &_puiData[_uiPos], uiSize); _uiPos += uiSize; } uint8_t CBinaryStream::computeChecksum() const { uint32_t uiIndex; uint8_t uiDataChecksum = _uiStructureChecksum; for (uiIndex = 0; uiIndex < _uiDataSize; uiIndex++) { uiDataChecksum += _puiData[uiIndex]; } return uiDataChecksum; } bool CBinaryStream::isOut() const { return _bOut; }