~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/systab_util_ms.cc

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2009 PrimeBase Technologies GmbH, Germany
2
 
 *
3
 
 * PrimeBase Media Stream for MySQL
4
 
 *
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.
9
 
 *
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.
14
 
 *
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
18
 
 *
19
 
 * Barry Leslie
20
 
 *
21
 
 * System table utility functions.
22
 
 *
23
 
 */
24
 
#include "cslib/CSConfig.h"
25
 
 
26
 
#include <sys/types.h>
27
 
#include <sys/stat.h>
28
 
#include <stdlib.h>
29
 
#include <time.h>
30
 
#include <inttypes.h>
31
 
 
32
 
#include "cslib/CSGlobal.h"
33
 
#include "cslib/CSStrUtil.h"
34
 
#include "cslib/CSPath.h"
35
 
 
36
 
#include "systab_util_ms.h"
37
 
 
38
 
//======================
39
 
void SysTabRec::logError(const char *text)
40
 
{
41
 
        char msg[80];
42
 
        enter_();
43
 
        
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);
50
 
        if (text) {
51
 
                CSL.log(self, CSLog::Warning, " ");
52
 
                CSL.log(self, CSLog::Warning, text);
53
 
        }
54
 
        CSL.log(self, CSLog::Warning, msg);
55
 
        exit_();
56
 
}
57
 
 
58
 
#define HEAD_MARKER ((uint32_t)0XABABABAB)
59
 
#define TAIL_MARKER ((uint32_t)0XCDCDCDCD)
60
 
//---------------------
61
 
bool SysTabRec::findRecord()
62
 
{
63
 
        uint32_t len, marker;
64
 
        CSDiskData d;
65
 
 
66
 
        badRecord = true;
67
 
        
68
 
        while (badRecord) {
69
 
                len = end_of_data - ptr;
70
 
                if (len < 12)
71
 
                        return false;
72
 
                
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) 
77
 
                        continue;
78
 
                        
79
 
                // Get the record length.
80
 
                d.rec_chars = ptr;      
81
 
                recordLength = CS_GET_DISK_4(d.int_val->val_4);
82
 
                if (len < recordLength)
83
 
                        continue;
84
 
                
85
 
                end_of_record = ptr + recordLength;
86
 
                
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) 
91
 
                        continue;
92
 
                        
93
 
                ptr +=4; // Skip the record length.
94
 
                badRecord = false;              
95
 
        }
96
 
        
97
 
        return true;
98
 
}
99
 
 
100
 
//---------------------
101
 
bool SysTabRec::firstRecord()
102
 
{
103
 
        ptr = getBuffer(0);
104
 
        end_of_data = ptr + length();
105
 
        
106
 
        if (!findRecord()) {
107
 
                logError("Missing record terminator, file being ignored");
108
 
                return false;
109
 
        }
110
 
        
111
 
        return true;
112
 
}
113
 
 
114
 
//---------------------
115
 
bool SysTabRec::nextRecord()
116
 
{
117
 
        if (!ptr)
118
 
                return firstRecord();
119
 
                
120
 
        if (ptr <= end_of_record) 
121
 
                ptr = end_of_record + 4;
122
 
        
123
 
        return findRecord();
124
 
}
125
 
        
126
 
//---------------------
127
 
void SysTabRec::resetRecord()
128
 
{
129
 
        ptr= 0;
130
 
}
131
 
 
132
 
//---------------------
133
 
uint8_t SysTabRec::getInt1Field()
134
 
{
135
 
        uint8_t val = 0;
136
 
        CSDiskData d;
137
 
        
138
 
        if (badRecord)
139
 
                return val;
140
 
                
141
 
        if (ptr > (end_of_record -1)) {
142
 
                logError("Missing 1 byte int field");
143
 
                ptr = end_of_record;
144
 
                badRecord = true;
145
 
                return val;
146
 
        }
147
 
        
148
 
        d.rec_chars = ptr;
149
 
        val = CS_GET_DISK_1(d.int_val->val_1);
150
 
        ptr += 1;               
151
 
        return val;
152
 
}
153
 
 
154
 
//---------------------
155
 
uint32_t SysTabRec::getInt4Field()
156
 
{
157
 
        uint32_t val = 0;
158
 
        CSDiskData d;
159
 
        
160
 
        if (badRecord)
161
 
                return val;
162
 
                
163
 
        if (ptr > (end_of_record -4)) {
164
 
                logError("Missing 4 byte int field");
165
 
                ptr = end_of_record;
166
 
                badRecord = true;
167
 
                return val;
168
 
        }
169
 
        
170
 
        d.rec_chars = ptr;
171
 
        val = CS_GET_DISK_4(d.int_val->val_4);
172
 
        ptr += 4;               
173
 
        return val;
174
 
}
175
 
 
176
 
//---------------------
177
 
const char *SysTabRec::getStringField()
178
 
{
179
 
        const char *val = "";
180
 
        
181
 
        if (badRecord)
182
 
                return val;
183
 
                
184
 
        if (ptr > (end_of_record -1)) {
185
 
                logError("Missing string field");
186
 
                badRecord = true;
187
 
                ptr = end_of_record;
188
 
        } else {
189
 
                val = ptr;
190
 
                while (*ptr && ptr < end_of_record) ptr++;
191
 
                if (ptr == end_of_record) {
192
 
                        logError("Unterminated string field");
193
 
                        badRecord = true;
194
 
                        val = "";
195
 
                } else
196
 
                        ptr++;
197
 
        }
198
 
        
199
 
        return val;
200
 
}
201
 
 
202
 
//---------------------
203
 
void SysTabRec::clear()
204
 
{
205
 
        setLength(0);
206
 
}
207
 
 
208
 
//---------------------
209
 
void SysTabRec::beginRecord()
210
 
{
211
 
        CSDiskData d;
212
 
        uint32_t len = length();
213
 
        
214
 
        setLength(len + 8); // Room for header marker and record length.
215
 
 
216
 
        d.rec_chars = getBuffer(len);
217
 
        CS_SET_DISK_4(d.int_val->val_4, HEAD_MARKER);   
218
 
 
219
 
        start_of_record = len + 4;
220
 
}
221
 
 
222
 
//---------------------
223
 
void SysTabRec::endRecord()
224
 
{
225
 
        CSDiskData d;
226
 
        uint32_t len = length();
227
 
        
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); 
231
 
 
232
 
        // Write the record trailer
233
 
        setLength(len + 4); 
234
 
        d.rec_chars = getBuffer(len);
235
 
        CS_SET_DISK_4(d.int_val->val_4, TAIL_MARKER);           
236
 
}
237
 
 
238
 
//---------------------
239
 
void SysTabRec::setInt1Field(uint8_t val)
240
 
{
241
 
        CSDiskData d;
242
 
 
243
 
        uint32_t len = length();
244
 
        
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);   
248
 
}
249
 
 
250
 
//---------------------
251
 
void SysTabRec::setInt4Field(uint32_t val)
252
 
{
253
 
        CSDiskData d;
254
 
 
255
 
        uint32_t len = length();
256
 
        
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);   
260
 
}
261
 
 
262
 
//---------------------
263
 
void SysTabRec::setStringField(const char *val)
264
 
{
265
 
        if (!val) val = "";
266
 
        append(val, strlen(val) +1);
267
 
}
268
 
 
269
 
//---------------------
270
 
void SysTabRec::setStringField(const char *val, uint32_t len)
271
 
{
272
 
        if (val)
273
 
                append(val, len);
274
 
        append("", 1);
275
 
}
276
 
 
277
 
 
278
 
//======================
279
 
CSString *getPBMSPath(CSString *db_path)
280
 
{
281
 
        char pbms_path[PATH_MAX];
282
 
        enter_();
283
 
        
284
 
        push_(db_path); 
285
 
        cs_strcpy(PATH_MAX, pbms_path, db_path->getCString());
286
 
        release_(db_path);
287
 
        
288
 
        cs_remove_last_name_of_path(pbms_path);
289
 
 
290
 
        return_(CSString::newString(pbms_path));
291
 
}
292
 
 
293
 
 
294
 
//----------------------------
295
 
CSPath *getSysFile(CSString *db_path, const char *name_arg, size_t min_size)
296
 
{
297
 
        CSPath                  *path;
298
 
        CSStringBuffer  *name;
299
 
        char                    *ptr;
300
 
 
301
 
        enter_();
302
 
        
303
 
        push_(db_path);
304
 
        new_(name, CSStringBuffer());
305
 
        push_(name);
306
 
        name->append(name_arg);
307
 
        name->append(".dat");
308
 
        
309
 
        ptr = name->getBuffer(strlen(name_arg));
310
 
 
311
 
try_again:
312
 
        path = CSPath::newPath(RETAIN(db_path), name->getCString());
313
 
        push_(path);
314
 
        if (!path->exists()) {
315
 
                CSPath *tmp_path;
316
 
 
317
 
                strcpy(ptr, ".tmp");
318
 
                tmp_path = CSPath::newPath(RETAIN(db_path), name->getCString());
319
 
                push_(tmp_path);
320
 
                if (tmp_path->exists()) {
321
 
                        strcpy(ptr, ".dat");
322
 
                        tmp_path->rename(name->getCString());
323
 
                }
324
 
                release_(tmp_path);
325
 
        }
326
 
        
327
 
        // If the file if too small assume it is garbage.
328
 
        if (path->exists() && (path->getSize() < min_size)) {
329
 
                path->removeFile();
330
 
                release_(path);
331
 
                goto try_again;
332
 
        }
333
 
        
334
 
        pop_(path);
335
 
        release_(name);
336
 
        release_(db_path);
337
 
        return_(path);
338
 
}
339