1
/* Copyright (C) 2009 PrimeBase Technologies GmbH, Germany
3
* PrimeBase Media Stream for MySQL
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
* System table utility functions.
24
#include "cslib/CSConfig.h"
26
#include <sys/types.h>
32
#include "cslib/CSGlobal.h"
33
#include "cslib/CSStrUtil.h"
34
#include "cslib/CSPath.h"
36
#include "systab_util_ms.h"
38
//======================
39
void SysTabRec::logError(const char *text)
44
snprintf(msg, 80, ", damaged at or near position %"PRIu32" \n", (uint32_t) (ptr - getBuffer(0)));
45
CSL.log(self, CSLog::Warning, db_name);
46
CSL.log(self, CSLog::Warning, ".");
47
CSL.log(self, CSLog::Warning, table_name);
48
CSL.log(self, CSLog::Warning, " table file ");
49
CSL.log(self, CSLog::Warning, file_name);
51
CSL.log(self, CSLog::Warning, " ");
52
CSL.log(self, CSLog::Warning, text);
54
CSL.log(self, CSLog::Warning, msg);
58
#define HEAD_MARKER ((uint32_t)0XABABABAB)
59
#define TAIL_MARKER ((uint32_t)0XCDCDCDCD)
60
//---------------------
61
bool SysTabRec::findRecord()
69
len = end_of_data - ptr;
73
// Look for the record header.
74
d.rec_chars = ptr; ptr +=4;
75
marker = CS_GET_DISK_4(d.int_val->val_4);
76
if (marker != HEAD_MARKER)
79
// Get the record length.
81
recordLength = CS_GET_DISK_4(d.int_val->val_4);
82
if (len < recordLength)
85
end_of_record = ptr + recordLength;
87
// Look for the record trailer.
88
d.rec_chars = end_of_record;
89
marker = CS_GET_DISK_4(d.int_val->val_4);
90
if (marker != TAIL_MARKER)
93
ptr +=4; // Skip the record length.
100
//---------------------
101
bool SysTabRec::firstRecord()
104
end_of_data = ptr + length();
107
logError("Missing record terminator, file being ignored");
114
//---------------------
115
bool SysTabRec::nextRecord()
118
return firstRecord();
120
if (ptr <= end_of_record)
121
ptr = end_of_record + 4;
126
//---------------------
127
void SysTabRec::resetRecord()
132
//---------------------
133
uint8_t SysTabRec::getInt1Field()
141
if (ptr > (end_of_record -1)) {
142
logError("Missing 1 byte int field");
149
val = CS_GET_DISK_1(d.int_val->val_1);
154
//---------------------
155
uint32_t SysTabRec::getInt4Field()
163
if (ptr > (end_of_record -4)) {
164
logError("Missing 4 byte int field");
171
val = CS_GET_DISK_4(d.int_val->val_4);
176
//---------------------
177
const char *SysTabRec::getStringField()
179
const char *val = "";
184
if (ptr > (end_of_record -1)) {
185
logError("Missing string field");
190
while (*ptr && ptr < end_of_record) ptr++;
191
if (ptr == end_of_record) {
192
logError("Unterminated string field");
202
//---------------------
203
void SysTabRec::clear()
208
//---------------------
209
void SysTabRec::beginRecord()
212
uint32_t len = length();
214
setLength(len + 8); // Room for header marker and record length.
216
d.rec_chars = getBuffer(len);
217
CS_SET_DISK_4(d.int_val->val_4, HEAD_MARKER);
219
start_of_record = len + 4;
222
//---------------------
223
void SysTabRec::endRecord()
226
uint32_t len = length();
228
// Write the record length to the head of the record
229
d.rec_chars = getBuffer(start_of_record);
230
CS_SET_DISK_4(d.int_val->val_4, len - start_of_record);
232
// Write the record trailer
234
d.rec_chars = getBuffer(len);
235
CS_SET_DISK_4(d.int_val->val_4, TAIL_MARKER);
238
//---------------------
239
void SysTabRec::setInt1Field(uint8_t val)
243
uint32_t len = length();
245
setLength(len +1); // Important: set the length before getting the buffer pointer
246
d.rec_chars = getBuffer(len);
247
CS_SET_DISK_1(d.int_val->val_1, val);
250
//---------------------
251
void SysTabRec::setInt4Field(uint32_t val)
255
uint32_t len = length();
257
setLength(len +4); // Important: set the length before getting the buffer pointer
258
d.rec_chars = getBuffer(len);
259
CS_SET_DISK_4(d.int_val->val_4, val);
262
//---------------------
263
void SysTabRec::setStringField(const char *val)
266
append(val, strlen(val) +1);
269
//---------------------
270
void SysTabRec::setStringField(const char *val, uint32_t len)
278
//======================
279
CSString *getPBMSPath(CSString *db_path)
281
char pbms_path[PATH_MAX];
285
cs_strcpy(PATH_MAX, pbms_path, db_path->getCString());
288
cs_remove_last_name_of_path(pbms_path);
290
return_(CSString::newString(pbms_path));
294
//----------------------------
295
CSPath *getSysFile(CSString *db_path, const char *name_arg, size_t min_size)
298
CSStringBuffer *name;
304
new_(name, CSStringBuffer());
306
name->append(name_arg);
307
name->append(".dat");
309
ptr = name->getBuffer(strlen(name_arg));
312
path = CSPath::newPath(RETAIN(db_path), name->getCString());
314
if (!path->exists()) {
318
tmp_path = CSPath::newPath(RETAIN(db_path), name->getCString());
320
if (tmp_path->exists()) {
322
tmp_path->rename(name->getCString());
327
// If the file if too small assume it is garbage.
328
if (path->exists() && (path->getSize() < min_size)) {