00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "cslib/CSConfig.h"
00025
00026 #include <sys/types.h>
00027 #include <sys/stat.h>
00028 #include <stdlib.h>
00029 #include <time.h>
00030 #include <inttypes.h>
00031
00032 #include "cslib/CSGlobal.h"
00033 #include "cslib/CSStrUtil.h"
00034 #include "cslib/CSPath.h"
00035
00036 #include "systab_util_ms.h"
00037
00038
00039 void SysTabRec::logError(const char *text)
00040 {
00041 char msg[80];
00042 enter_();
00043
00044 snprintf(msg, 80, ", damaged at or near position %"PRIu32" \n", (uint32_t) (ptr - getBuffer(0)));
00045 CSL.log(self, CSLog::Warning, db_name);
00046 CSL.log(self, CSLog::Warning, ".");
00047 CSL.log(self, CSLog::Warning, table_name);
00048 CSL.log(self, CSLog::Warning, " table file ");
00049 CSL.log(self, CSLog::Warning, file_name);
00050 if (text) {
00051 CSL.log(self, CSLog::Warning, " ");
00052 CSL.log(self, CSLog::Warning, text);
00053 }
00054 CSL.log(self, CSLog::Warning, msg);
00055 exit_();
00056 }
00057
00058 #define HEAD_MARKER ((uint32_t)0XABABABAB)
00059 #define TAIL_MARKER ((uint32_t)0XCDCDCDCD)
00060
00061 bool SysTabRec::findRecord()
00062 {
00063 uint32_t len, marker;
00064 CSDiskData d;
00065
00066 badRecord = true;
00067
00068 while (badRecord) {
00069 len = end_of_data - ptr;
00070 if (len < 12)
00071 return false;
00072
00073
00074 d.rec_chars = ptr; ptr +=4;
00075 marker = CS_GET_DISK_4(d.int_val->val_4);
00076 if (marker != HEAD_MARKER)
00077 continue;
00078
00079
00080 d.rec_chars = ptr;
00081 recordLength = CS_GET_DISK_4(d.int_val->val_4);
00082 if (len < recordLength)
00083 continue;
00084
00085 end_of_record = ptr + recordLength;
00086
00087
00088 d.rec_chars = end_of_record;
00089 marker = CS_GET_DISK_4(d.int_val->val_4);
00090 if (marker != TAIL_MARKER)
00091 continue;
00092
00093 ptr +=4;
00094 badRecord = false;
00095 }
00096
00097 return true;
00098 }
00099
00100
00101 bool SysTabRec::firstRecord()
00102 {
00103 ptr = getBuffer(0);
00104 end_of_data = ptr + length();
00105
00106 if (!findRecord()) {
00107 logError("Missing record terminator, file being ignored");
00108 return false;
00109 }
00110
00111 return true;
00112 }
00113
00114
00115 bool SysTabRec::nextRecord()
00116 {
00117 if (!ptr)
00118 return firstRecord();
00119
00120 if (ptr <= end_of_record)
00121 ptr = end_of_record + 4;
00122
00123 return findRecord();
00124 }
00125
00126
00127 void SysTabRec::resetRecord()
00128 {
00129 ptr= 0;
00130 }
00131
00132
00133 uint8_t SysTabRec::getInt1Field()
00134 {
00135 uint8_t val = 0;
00136 CSDiskData d;
00137
00138 if (badRecord)
00139 return val;
00140
00141 if (ptr > (end_of_record -1)) {
00142 logError("Missing 1 byte int field");
00143 ptr = end_of_record;
00144 badRecord = true;
00145 return val;
00146 }
00147
00148 d.rec_chars = ptr;
00149 val = CS_GET_DISK_1(d.int_val->val_1);
00150 ptr += 1;
00151 return val;
00152 }
00153
00154
00155 uint32_t SysTabRec::getInt4Field()
00156 {
00157 uint32_t val = 0;
00158 CSDiskData d;
00159
00160 if (badRecord)
00161 return val;
00162
00163 if (ptr > (end_of_record -4)) {
00164 logError("Missing 4 byte int field");
00165 ptr = end_of_record;
00166 badRecord = true;
00167 return val;
00168 }
00169
00170 d.rec_chars = ptr;
00171 val = CS_GET_DISK_4(d.int_val->val_4);
00172 ptr += 4;
00173 return val;
00174 }
00175
00176
00177 const char *SysTabRec::getStringField()
00178 {
00179 const char *val = "";
00180
00181 if (badRecord)
00182 return val;
00183
00184 if (ptr > (end_of_record -1)) {
00185 logError("Missing string field");
00186 badRecord = true;
00187 ptr = end_of_record;
00188 } else {
00189 val = ptr;
00190 while (*ptr && ptr < end_of_record) ptr++;
00191 if (ptr == end_of_record) {
00192 logError("Unterminated string field");
00193 badRecord = true;
00194 val = "";
00195 } else
00196 ptr++;
00197 }
00198
00199 return val;
00200 }
00201
00202
00203 void SysTabRec::clear()
00204 {
00205 setLength(0);
00206 }
00207
00208
00209 void SysTabRec::beginRecord()
00210 {
00211 CSDiskData d;
00212 uint32_t len = length();
00213
00214 setLength(len + 8);
00215
00216 d.rec_chars = getBuffer(len);
00217 CS_SET_DISK_4(d.int_val->val_4, HEAD_MARKER);
00218
00219 start_of_record = len + 4;
00220 }
00221
00222
00223 void SysTabRec::endRecord()
00224 {
00225 CSDiskData d;
00226 uint32_t len = length();
00227
00228
00229 d.rec_chars = getBuffer(start_of_record);
00230 CS_SET_DISK_4(d.int_val->val_4, len - start_of_record);
00231
00232
00233 setLength(len + 4);
00234 d.rec_chars = getBuffer(len);
00235 CS_SET_DISK_4(d.int_val->val_4, TAIL_MARKER);
00236 }
00237
00238
00239 void SysTabRec::setInt1Field(uint8_t val)
00240 {
00241 CSDiskData d;
00242
00243 uint32_t len = length();
00244
00245 setLength(len +1);
00246 d.rec_chars = getBuffer(len);
00247 CS_SET_DISK_1(d.int_val->val_1, val);
00248 }
00249
00250
00251 void SysTabRec::setInt4Field(uint32_t val)
00252 {
00253 CSDiskData d;
00254
00255 uint32_t len = length();
00256
00257 setLength(len +4);
00258 d.rec_chars = getBuffer(len);
00259 CS_SET_DISK_4(d.int_val->val_4, val);
00260 }
00261
00262
00263 void SysTabRec::setStringField(const char *val)
00264 {
00265 if (!val) val = "";
00266 append(val, strlen(val) +1);
00267 }
00268
00269
00270 void SysTabRec::setStringField(const char *val, uint32_t len)
00271 {
00272 if (val)
00273 append(val, len);
00274 append("", 1);
00275 }
00276
00277
00278
00279 CSString *getPBMSPath(CSString *db_path)
00280 {
00281 char pbms_path[PATH_MAX];
00282 enter_();
00283
00284 push_(db_path);
00285 cs_strcpy(PATH_MAX, pbms_path, db_path->getCString());
00286 release_(db_path);
00287
00288 cs_remove_last_name_of_path(pbms_path);
00289
00290 return_(CSString::newString(pbms_path));
00291 }
00292
00293
00294
00295 CSPath *getSysFile(CSString *db_path, const char *name_arg, size_t min_size)
00296 {
00297 CSPath *path;
00298 CSStringBuffer *name;
00299 char *ptr;
00300
00301 enter_();
00302
00303 push_(db_path);
00304 new_(name, CSStringBuffer());
00305 push_(name);
00306 name->append(name_arg);
00307 name->append(".dat");
00308
00309 ptr = name->getBuffer(strlen(name_arg));
00310
00311 try_again:
00312 path = CSPath::newPath(RETAIN(db_path), name->getCString());
00313 push_(path);
00314 if (!path->exists()) {
00315 CSPath *tmp_path;
00316
00317 strcpy(ptr, ".tmp");
00318 tmp_path = CSPath::newPath(RETAIN(db_path), name->getCString());
00319 push_(tmp_path);
00320 if (tmp_path->exists()) {
00321 strcpy(ptr, ".dat");
00322 tmp_path->rename(name->getCString());
00323 }
00324 release_(tmp_path);
00325 }
00326
00327
00328 if (path->exists() && (path->getSize() < min_size)) {
00329 path->removeFile();
00330 release_(path);
00331 goto try_again;
00332 }
00333
00334 pop_(path);
00335 release_(name);
00336 release_(db_path);
00337 return_(path);
00338 }
00339