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
34 using namespace std;
35
CBinaryStream(const string & strFileName,bool bOut,size_t uiDataSize,uint8_t uiStructureChecksum)36 CBinaryStream::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
~CBinaryStream()47 CBinaryStream::~CBinaryStream()
48 {
49 if (_bOpen) {
50
51 close();
52 }
53
54 delete [] _puiData;
55 }
56
open(string & strError)57 bool 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
close()111 void 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
reset()134 void CBinaryStream::reset()
135 {
136 _uiPos = 0;
137 }
138
write(const uint8_t * puiData,size_t uiSize)139 void 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
read(uint8_t * puiData,size_t uiSize)148 void 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
computeChecksum() const157 uint8_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
isOut() const169 bool CBinaryStream::isOut() const
170 {
171 return _bOut;
172 }
173