1b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner/*
2b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * Copyright (c) 2011-2014, Intel Corporation
3b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * All rights reserved.
4b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
5b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * Redistribution and use in source and binary forms, with or without modification,
6b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * are permitted provided that the following conditions are met:
7b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
8b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 1. Redistributions of source code must retain the above copyright notice, this
9b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * list of conditions and the following disclaimer.
10b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
11b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 2. Redistributions in binary form must reproduce the above copyright notice,
12b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * this list of conditions and the following disclaimer in the documentation and/or
13b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * other materials provided with the distribution.
14b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
15b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * 3. Neither the name of the copyright holder nor the names of its contributors
16b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * may be used to endorse or promote products derived from this software without
17b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * specific prior written permission.
18b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner *
19b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28b76c9d6de717a9a1cfd94e7a8eca7ee4a2035cd7David Wagner * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2968a912857707864bbaaff9808717813105072a6ePatrick Benavoli */
3068a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include "BinaryStream.h"
3168a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include <string.h>
3268a912857707864bbaaff9808717813105072a6ePatrick Benavoli#include <assert.h>
3368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
3468a912857707864bbaaff9808717813105072a6ePatrick Benavoliusing namespace std;
3568a912857707864bbaaff9808717813105072a6ePatrick Benavoli
36911844b16c6b627f421bc3368de427de3ca9f60cPatrick BenavoliCBinaryStream::CBinaryStream(const string& strFileName, bool bOut, size_t uiDataSize, uint8_t uiStructureChecksum) :
3768a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _strFileName(strFileName),
3868a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _bOut(bOut),
3968a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _uiDataSize(uiDataSize),
4068a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _uiStructureChecksum(uiStructureChecksum),
4168a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _puiData(new uint8_t[uiDataSize]),
4268a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _uiPos(0),
4368a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _bOpen(false)
4468a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
4568a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
4668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
4768a912857707864bbaaff9808717813105072a6ePatrick BenavoliCBinaryStream::~CBinaryStream()
4868a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
4968a912857707864bbaaff9808717813105072a6ePatrick Benavoli    if (_bOpen) {
5068a912857707864bbaaff9808717813105072a6ePatrick Benavoli
5168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        close();
5268a912857707864bbaaff9808717813105072a6ePatrick Benavoli    }
53ccb745447386f49e018fe39d1ec54a652eefa57fDavid Wagner
54ccb745447386f49e018fe39d1ec54a652eefa57fDavid Wagner    delete [] _puiData;
5568a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
5668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
5768a912857707864bbaaff9808717813105072a6ePatrick Benavolibool CBinaryStream::open(string& strError)
5868a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
5968a912857707864bbaaff9808717813105072a6ePatrick Benavoli    assert(!_bOpen);
6068a912857707864bbaaff9808717813105072a6ePatrick Benavoli
6168a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _fileStream.open(_strFileName.c_str(), (_bOut ? ios::out : ios::in|ios::ate)|ios::binary);
6268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
6368a912857707864bbaaff9808717813105072a6ePatrick Benavoli    if (!_fileStream.is_open() || !_fileStream.good()) {
6468a912857707864bbaaff9808717813105072a6ePatrick Benavoli
6568a912857707864bbaaff9808717813105072a6ePatrick Benavoli        strError = string("Failed to ") + (_bOut ? "write" : "read") + "-open";
6668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
6768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        return false;
6868a912857707864bbaaff9808717813105072a6ePatrick Benavoli    }
6968a912857707864bbaaff9808717813105072a6ePatrick Benavoli    if (!_bOut) {
7068a912857707864bbaaff9808717813105072a6ePatrick Benavoli
7168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Get file size
72911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavoli        size_t uiFileSize = _fileStream.tellg();
7368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
7468a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Validate file size
75911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavoli        if (_uiDataSize + sizeof(_uiStructureChecksum) != uiFileSize) {
7668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
7768a912857707864bbaaff9808717813105072a6ePatrick Benavoli            // Size different from expected
7868a912857707864bbaaff9808717813105072a6ePatrick Benavoli            strError = "Unexpected file size";
7968a912857707864bbaaff9808717813105072a6ePatrick Benavoli
8068a912857707864bbaaff9808717813105072a6ePatrick Benavoli            return false;
8168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
8268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
8368a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Back to beginning of file
8468a912857707864bbaaff9808717813105072a6ePatrick Benavoli        _fileStream.seekg(0, ios::beg);
8568a912857707864bbaaff9808717813105072a6ePatrick Benavoli
8668a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Get data
8768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        _fileStream.read((char*)_puiData, _uiDataSize);
8868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
8968a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // File checksum
9068a912857707864bbaaff9808717813105072a6ePatrick Benavoli        uint8_t uiFileChecksum;
9168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        _fileStream.read((char*)&uiFileChecksum, sizeof(uiFileChecksum));
9268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
9368a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Data checksum
9468a912857707864bbaaff9808717813105072a6ePatrick Benavoli        uint8_t uiDataChecksum = computeChecksum();
9568a912857707864bbaaff9808717813105072a6ePatrick Benavoli
9668a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Validate checksum
9768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        if (uiDataChecksum != uiFileChecksum) {
9868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
9968a912857707864bbaaff9808717813105072a6ePatrick Benavoli            strError = "Integrity checks failed";
10068a912857707864bbaaff9808717813105072a6ePatrick Benavoli
10168a912857707864bbaaff9808717813105072a6ePatrick Benavoli            return false;
10268a912857707864bbaaff9808717813105072a6ePatrick Benavoli        }
10368a912857707864bbaaff9808717813105072a6ePatrick Benavoli    }
10468a912857707864bbaaff9808717813105072a6ePatrick Benavoli
10568a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Keep track
10668a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _bOpen = true;
10768a912857707864bbaaff9808717813105072a6ePatrick Benavoli
10868a912857707864bbaaff9808717813105072a6ePatrick Benavoli    return true;
10968a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
11068a912857707864bbaaff9808717813105072a6ePatrick Benavoli
11168a912857707864bbaaff9808717813105072a6ePatrick Benavolivoid CBinaryStream::close()
11268a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
11368a912857707864bbaaff9808717813105072a6ePatrick Benavoli    assert(_bOpen);
11468a912857707864bbaaff9808717813105072a6ePatrick Benavoli
11568a912857707864bbaaff9808717813105072a6ePatrick Benavoli    if (_bOut) {
11668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
11768a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Get data
11868a912857707864bbaaff9808717813105072a6ePatrick Benavoli        _fileStream.write((const char*)_puiData, _uiDataSize);
11968a912857707864bbaaff9808717813105072a6ePatrick Benavoli
12068a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Compute checksum
12168a912857707864bbaaff9808717813105072a6ePatrick Benavoli        uint8_t uiDataChecksum = computeChecksum();
12268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
12368a912857707864bbaaff9808717813105072a6ePatrick Benavoli        // Write checksum
12468a912857707864bbaaff9808717813105072a6ePatrick Benavoli        _fileStream.write((const char*)&uiDataChecksum, sizeof(uiDataChecksum));
12568a912857707864bbaaff9808717813105072a6ePatrick Benavoli    }
12668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
12768a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Keep track
12868a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _bOpen = false;
12968a912857707864bbaaff9808717813105072a6ePatrick Benavoli
13068a912857707864bbaaff9808717813105072a6ePatrick Benavoli    // Close file
13168a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _fileStream.close();
13268a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
13368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
13468a912857707864bbaaff9808717813105072a6ePatrick Benavolivoid CBinaryStream::reset()
13568a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
13668a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _uiPos = 0;
13768a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
13868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
139911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavolivoid CBinaryStream::write(const uint8_t* puiData, size_t uiSize)
14068a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
14168a912857707864bbaaff9808717813105072a6ePatrick Benavoli    assert(_uiPos + uiSize <= _uiDataSize);
14268a912857707864bbaaff9808717813105072a6ePatrick Benavoli
14368a912857707864bbaaff9808717813105072a6ePatrick Benavoli    memcpy(&_puiData[_uiPos], puiData, uiSize);
14468a912857707864bbaaff9808717813105072a6ePatrick Benavoli
14568a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _uiPos += uiSize;
14668a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
14768a912857707864bbaaff9808717813105072a6ePatrick Benavoli
148911844b16c6b627f421bc3368de427de3ca9f60cPatrick Benavolivoid CBinaryStream::read(uint8_t* puiData, size_t uiSize)
14968a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
15068a912857707864bbaaff9808717813105072a6ePatrick Benavoli    assert(_uiPos + uiSize <= _uiDataSize);
15168a912857707864bbaaff9808717813105072a6ePatrick Benavoli
15268a912857707864bbaaff9808717813105072a6ePatrick Benavoli    memcpy(puiData, &_puiData[_uiPos], uiSize);
15368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
15468a912857707864bbaaff9808717813105072a6ePatrick Benavoli    _uiPos += uiSize;
15568a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
15668a912857707864bbaaff9808717813105072a6ePatrick Benavoli
15768a912857707864bbaaff9808717813105072a6ePatrick Benavoliuint8_t CBinaryStream::computeChecksum() const
15868a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
15968a912857707864bbaaff9808717813105072a6ePatrick Benavoli    uint32_t uiIndex;
16068a912857707864bbaaff9808717813105072a6ePatrick Benavoli    uint8_t uiDataChecksum = _uiStructureChecksum;
16168a912857707864bbaaff9808717813105072a6ePatrick Benavoli
16268a912857707864bbaaff9808717813105072a6ePatrick Benavoli    for (uiIndex = 0; uiIndex < _uiDataSize; uiIndex++) {
16368a912857707864bbaaff9808717813105072a6ePatrick Benavoli
16468a912857707864bbaaff9808717813105072a6ePatrick Benavoli        uiDataChecksum += _puiData[uiIndex];
16568a912857707864bbaaff9808717813105072a6ePatrick Benavoli    }
16668a912857707864bbaaff9808717813105072a6ePatrick Benavoli    return uiDataChecksum;
16768a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
16868a912857707864bbaaff9808717813105072a6ePatrick Benavoli
16968a912857707864bbaaff9808717813105072a6ePatrick Benavolibool CBinaryStream::isOut() const
17068a912857707864bbaaff9808717813105072a6ePatrick Benavoli{
17168a912857707864bbaaff9808717813105072a6ePatrick Benavoli    return _bOut;
17268a912857707864bbaaff9808717813105072a6ePatrick Benavoli}
173