blob: 2dc3380b1d16d4c1f69524c34148f5f1d2201365 [file] [log] [blame]
David Wagnerb76c9d62014-02-05 18:30:24 +01001/*
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.
Patrick Benavoli68a91282011-08-31 11:23:23 +020029 */
30#include "BinaryStream.h"
31#include <string.h>
32#include <assert.h>
33
34using namespace std;
35
Patrick Benavoli911844b2014-07-23 01:27:00 +020036CBinaryStream::CBinaryStream(const string& strFileName, bool bOut, size_t uiDataSize, uint8_t uiStructureChecksum) :
Patrick Benavoli68a91282011-08-31 11:23:23 +020037 _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{
Patrick Benavoli68a91282011-08-31 11:23:23 +020049 if (_bOpen) {
50
51 close();
52 }
David Wagnerccb74542014-09-24 09:42:11 +020053
54 delete [] _puiData;
Patrick Benavoli68a91282011-08-31 11:23:23 +020055}
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
Patrick Benavoli911844b2014-07-23 01:27:00 +020072 size_t uiFileSize = _fileStream.tellg();
Patrick Benavoli68a91282011-08-31 11:23:23 +020073
74 // Validate file size
Patrick Benavoli911844b2014-07-23 01:27:00 +020075 if (_uiDataSize + sizeof(_uiStructureChecksum) != uiFileSize) {
Patrick Benavoli68a91282011-08-31 11:23:23 +020076
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
Patrick Benavoli911844b2014-07-23 01:27:00 +0200139void CBinaryStream::write(const uint8_t* puiData, size_t uiSize)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200140{
141 assert(_uiPos + uiSize <= _uiDataSize);
142
143 memcpy(&_puiData[_uiPos], puiData, uiSize);
144
145 _uiPos += uiSize;
146}
147
Patrick Benavoli911844b2014-07-23 01:27:00 +0200148void CBinaryStream::read(uint8_t* puiData, size_t uiSize)
Patrick Benavoli68a91282011-08-31 11:23:23 +0200149{
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}