blob: 701e9b835686e50cc6bf6a694599d111271ef184 [file] [log] [blame]
/*
* 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 <string.h>
#include <assert.h>
using namespace std;
CBinaryStream::CBinaryStream(const string& strFileName, bool bOut, uint32_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
ifstream::pos_type uiFileSize = _fileStream.tellg();
// Validate file size
if (_uiDataSize + sizeof(_uiStructureChecksum) != (uint32_t)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, uint32_t uiSize)
{
assert(_uiPos + uiSize <= _uiDataSize);
memcpy(&_puiData[_uiPos], puiData, uiSize);
_uiPos += uiSize;
}
void CBinaryStream::read(uint8_t* puiData, uint32_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;
}