1/* 2 * Copyright (c) 2011-2014, Intel Corporation 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation and/or 13 * other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors 16 * may be used to endorse or promote products derived from this software without 17 * specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30#include "BinaryStream.h" 31#include <string.h> 32#include <assert.h> 33 34using namespace std; 35 36CBinaryStream::CBinaryStream(const string& strFileName, bool bOut, size_t uiDataSize, uint8_t uiStructureChecksum) : 37 _strFileName(strFileName), 38 _bOut(bOut), 39 _uiDataSize(uiDataSize), 40 _uiStructureChecksum(uiStructureChecksum), 41 _puiData(new uint8_t[uiDataSize]), 42 _uiPos(0), 43 _bOpen(false) 44{ 45} 46 47CBinaryStream::~CBinaryStream() 48{ 49 if (_bOpen) { 50 51 close(); 52 } 53 54 delete [] _puiData; 55} 56 57bool CBinaryStream::open(string& strError) 58{ 59 assert(!_bOpen); 60 61 _fileStream.open(_strFileName.c_str(), (_bOut ? ios::out : ios::in|ios::ate)|ios::binary); 62 63 if (!_fileStream.is_open() || !_fileStream.good()) { 64 65 strError = string("Failed to ") + (_bOut ? "write" : "read") + "-open"; 66 67 return false; 68 } 69 if (!_bOut) { 70 71 // Get file size 72 size_t uiFileSize = _fileStream.tellg(); 73 74 // Validate file size 75 if (_uiDataSize + sizeof(_uiStructureChecksum) != uiFileSize) { 76 77 // Size different from expected 78 strError = "Unexpected file size"; 79 80 return false; 81 } 82 83 // Back to beginning of file 84 _fileStream.seekg(0, ios::beg); 85 86 // Get data 87 _fileStream.read((char*)_puiData, _uiDataSize); 88 89 // File checksum 90 uint8_t uiFileChecksum; 91 _fileStream.read((char*)&uiFileChecksum, sizeof(uiFileChecksum)); 92 93 // Data checksum 94 uint8_t uiDataChecksum = computeChecksum(); 95 96 // Validate checksum 97 if (uiDataChecksum != uiFileChecksum) { 98 99 strError = "Integrity checks failed"; 100 101 return false; 102 } 103 } 104 105 // Keep track 106 _bOpen = true; 107 108 return true; 109} 110 111void CBinaryStream::close() 112{ 113 assert(_bOpen); 114 115 if (_bOut) { 116 117 // Get data 118 _fileStream.write((const char*)_puiData, _uiDataSize); 119 120 // Compute checksum 121 uint8_t uiDataChecksum = computeChecksum(); 122 123 // Write checksum 124 _fileStream.write((const char*)&uiDataChecksum, sizeof(uiDataChecksum)); 125 } 126 127 // Keep track 128 _bOpen = false; 129 130 // Close file 131 _fileStream.close(); 132} 133 134void CBinaryStream::reset() 135{ 136 _uiPos = 0; 137} 138 139void CBinaryStream::write(const uint8_t* puiData, size_t uiSize) 140{ 141 assert(_uiPos + uiSize <= _uiDataSize); 142 143 memcpy(&_puiData[_uiPos], puiData, uiSize); 144 145 _uiPos += uiSize; 146} 147 148void CBinaryStream::read(uint8_t* puiData, size_t uiSize) 149{ 150 assert(_uiPos + uiSize <= _uiDataSize); 151 152 memcpy(puiData, &_puiData[_uiPos], uiSize); 153 154 _uiPos += uiSize; 155} 156 157uint8_t CBinaryStream::computeChecksum() const 158{ 159 uint32_t uiIndex; 160 uint8_t uiDataChecksum = _uiStructureChecksum; 161 162 for (uiIndex = 0; uiIndex < _uiDataSize; uiIndex++) { 163 164 uiDataChecksum += _puiData[uiIndex]; 165 } 166 return uiDataChecksum; 167} 168 169bool CBinaryStream::isOut() const 170{ 171 return _bOut; 172} 173