1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 // list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 // this list of conditions and the following disclaimer in the documentation
15 // and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32
33 #include "dbJournalLog.h"
34
35 #include <string>
36
37 namespace odb {
38
39 #define DEBUG_JOURNAL_LOG
40
41 #ifdef DEBUG_JOURNAL_LOG
42 #define SET_TYPE(TYPE) _data.push_back((char) TYPE)
43 #define CHECK_TYPE(TYPE) \
44 LogDataType type = (LogDataType) next(); \
45 ZASSERT(type == TYPE)
46 #else
47 #define SET_TYPE(TYPE)
48 #define CHECK_TYPE(TYPE)
49 #endif
50
51 enum LogDataType
52 {
53 LOG_BOOL,
54 LOG_CHAR,
55 LOG_UCHAR,
56 LOG_INT,
57 LOG_UINT,
58 LOG_FLOAT,
59 LOG_DOUBLE,
60 LOG_STRING
61 };
62
dbJournalLog()63 dbJournalLog::dbJournalLog() : _idx(0), _debug(0)
64 {
65 #ifdef DEBUG_JOURNAL_LOG
66 _debug = 1;
67 #endif
68 }
69
~dbJournalLog()70 dbJournalLog::~dbJournalLog()
71 {
72 clear();
73 }
74
push(bool value)75 void dbJournalLog::push(bool value)
76 {
77 SET_TYPE(LOG_BOOL);
78 _data.push_back((value == true) ? 1 : 0);
79 }
80
push(char value)81 void dbJournalLog::push(char value)
82 {
83 SET_TYPE(LOG_CHAR);
84 _data.push_back(value);
85 }
86
push(unsigned char value)87 void dbJournalLog::push(unsigned char value)
88 {
89 SET_TYPE(LOG_UCHAR);
90 _data.push_back(value);
91 }
92
push(int value)93 void dbJournalLog::push(int value)
94 {
95 SET_TYPE(LOG_INT);
96 unsigned char* v = (unsigned char*) &value;
97 _data.push_back(v[0]);
98 _data.push_back(v[1]);
99 _data.push_back(v[2]);
100 _data.push_back(v[3]);
101 }
102
push(unsigned int value)103 void dbJournalLog::push(unsigned int value)
104 {
105 SET_TYPE(LOG_UINT);
106 unsigned char* v = (unsigned char*) &value;
107 _data.push_back(v[0]);
108 _data.push_back(v[1]);
109 _data.push_back(v[2]);
110 _data.push_back(v[3]);
111 }
112
push(float value)113 void dbJournalLog::push(float value)
114 {
115 SET_TYPE(LOG_FLOAT);
116 unsigned char* v = (unsigned char*) &value;
117 _data.push_back(v[0]);
118 _data.push_back(v[1]);
119 _data.push_back(v[2]);
120 _data.push_back(v[3]);
121 }
122
push(double value)123 void dbJournalLog::push(double value)
124 {
125 SET_TYPE(LOG_DOUBLE);
126 unsigned char* v = (unsigned char*) &value;
127 _data.push_back(v[0]);
128 _data.push_back(v[1]);
129 _data.push_back(v[2]);
130 _data.push_back(v[3]);
131 _data.push_back(v[4]);
132 _data.push_back(v[5]);
133 _data.push_back(v[6]);
134 _data.push_back(v[7]);
135 }
136
push(const char * value)137 void dbJournalLog::push(const char* value)
138 {
139 SET_TYPE(LOG_STRING);
140 if (value == NULL)
141 push(-1);
142 else {
143 int len = strlen(value);
144 push(len);
145
146 for (; *value != '\0'; ++value)
147 _data.push_back(*value);
148 }
149 }
150
pop(bool & value)151 void dbJournalLog::pop(bool& value)
152 {
153 CHECK_TYPE(LOG_BOOL);
154 value = (next() == 1) ? true : false;
155 }
156
pop(char & value)157 void dbJournalLog::pop(char& value)
158 {
159 CHECK_TYPE(LOG_CHAR);
160 value = next();
161 }
162
pop(unsigned char & value)163 void dbJournalLog::pop(unsigned char& value)
164 {
165 CHECK_TYPE(LOG_UCHAR);
166 value = next();
167 }
168
pop(int & value)169 void dbJournalLog::pop(int& value)
170 {
171 CHECK_TYPE(LOG_INT);
172 unsigned char* v = (unsigned char*) &value;
173 v[0] = next();
174 v[1] = next();
175 v[2] = next();
176 v[3] = next();
177 }
178
pop(unsigned int & value)179 void dbJournalLog::pop(unsigned int& value)
180 {
181 CHECK_TYPE(LOG_UINT);
182 unsigned char* v = (unsigned char*) &value;
183 v[0] = next();
184 v[1] = next();
185 v[2] = next();
186 v[3] = next();
187 }
188
pop(float & value)189 void dbJournalLog::pop(float& value)
190 {
191 CHECK_TYPE(LOG_FLOAT);
192 unsigned char* v = (unsigned char*) &value;
193 v[0] = next();
194 v[1] = next();
195 v[2] = next();
196 v[3] = next();
197 }
198
pop(double & value)199 void dbJournalLog::pop(double& value)
200 {
201 CHECK_TYPE(LOG_DOUBLE);
202 unsigned char* v = (unsigned char*) &value;
203 v[0] = next();
204 v[1] = next();
205 v[2] = next();
206 v[3] = next();
207 v[4] = next();
208 v[5] = next();
209 v[6] = next();
210 v[7] = next();
211 }
212
pop(char * & value)213 void dbJournalLog::pop(char*& value)
214 {
215 CHECK_TYPE(LOG_STRING);
216 int len;
217 pop(len);
218
219 if (len == -1) {
220 value = NULL;
221 return;
222 }
223
224 value = (char*) malloc(len + 1);
225
226 int i;
227 for (i = 0; i < len; ++i)
228 value[i] = next();
229
230 value[i] = '\0';
231 }
232
pop(std::string & value)233 void dbJournalLog::pop(std::string& value)
234 {
235 CHECK_TYPE(LOG_STRING);
236 int len;
237 pop(len);
238
239 if (len == -1) {
240 value = "";
241 return;
242 }
243
244 value.reserve(len + 1);
245 value = "";
246
247 int i;
248 for (i = 0; i < len; ++i)
249 value.push_back(next());
250 }
251
operator >>(dbIStream & stream,dbJournalLog & log)252 dbIStream& operator>>(dbIStream& stream, dbJournalLog& log)
253 {
254 uint debug;
255 stream >> debug;
256 assert((int) debug == log._debug); // debug mismatch
257 stream >> log._data;
258 return stream;
259 }
260
operator <<(dbOStream & stream,const dbJournalLog & log)261 dbOStream& operator<<(dbOStream& stream, const dbJournalLog& log)
262 {
263 stream << log._debug;
264 stream << log._data;
265 return stream;
266 }
267
268 } // namespace odb
269