|
rllib
1
|
00001 /*************************************************************************** 00002 rlspreadsheet.h - description 00003 ------------------- 00004 begin : Tue Jan 02 2001 00005 copyright : (C) 2001 by Rainer Lehrig 00006 email : lehrig@t-online.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This library is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as * 00013 * published by the Free Software Foundation * 00014 * * 00015 ***************************************************************************/ 00016 #include <stdio.h> 00017 #include <stdarg.h> 00018 #include <string.h> 00019 #include "rlspreadsheet.h" 00020 #include "rlcutil.h" 00021 00022 static const char null_string[] = ""; 00023 00024 // rlSpreadsheetCell 00025 rlSpreadsheetCell::rlSpreadsheetCell(const char *Text) 00026 { 00027 if(Text != NULL) 00028 { 00029 txt = new char[strlen(Text)+1]; 00030 strcpy(txt,Text); 00031 } 00032 else 00033 { 00034 txt = NULL; 00035 } 00036 nextCell = NULL; 00037 } 00038 00039 rlSpreadsheetCell::~rlSpreadsheetCell() 00040 { 00041 if(txt != NULL) delete [] txt; 00042 } 00043 00044 const char *rlSpreadsheetCell::text() 00045 { 00046 if(txt == NULL) return null_string; 00047 return txt; 00048 } 00049 00050 void rlSpreadsheetCell::setText(const char *Text) 00051 { 00052 if(txt != NULL) delete [] txt; 00053 if(Text == NULL) 00054 { 00055 txt = NULL; 00056 return; 00057 } 00058 txt = new char[strlen(Text)+1]; 00059 strcpy(txt,Text); 00060 } 00061 00062 int rlSpreadsheetCell::printf(const char *format, ...) 00063 { 00064 int ret; 00065 char buf[rl_PRINTF_LENGTH_SPREADSHEET]; // should be big enough 00066 00067 va_list ap; 00068 va_start(ap,format); 00069 ret = rlvsnprintf(buf, rl_PRINTF_LENGTH_SPREADSHEET - 1, format, ap); 00070 va_end(ap); 00071 setText(buf); 00072 return ret; 00073 } 00074 00075 void rlSpreadsheetCell::clear() 00076 { 00077 if(txt != NULL) delete [] txt; 00078 txt = NULL; 00079 } 00080 00081 void rlSpreadsheetCell::setNextCell(rlSpreadsheetCell *next) 00082 { 00083 nextCell = next; 00084 } 00085 00086 rlSpreadsheetCell *rlSpreadsheetCell::getNextCell() 00087 { 00088 return nextCell; 00089 } 00090 00091 int rlSpreadsheetCell::exists() 00092 { 00093 return 1; 00094 } 00095 00096 // rlSpreadsheetRow 00097 rlSpreadsheetRow::rlSpreadsheetRow() 00098 { 00099 firstCell = NULL; 00100 nextRow = NULL; 00101 } 00102 00103 rlSpreadsheetRow::~rlSpreadsheetRow() 00104 { 00105 rlSpreadsheetCell *item,*last; 00106 item = firstCell; 00107 while(item != NULL) 00108 { 00109 last = item; 00110 item = item->getNextCell(); 00111 if(item != last) delete last; 00112 } 00113 } 00114 00115 const char *rlSpreadsheetRow::text(int column) 00116 { 00117 int c = 1; 00118 rlSpreadsheetCell *item; 00119 00120 item = firstCell; 00121 while(item != NULL) 00122 { 00123 if(c == column) return item->text(); 00124 item = item->getNextCell(); 00125 c++; 00126 } 00127 return null_string; 00128 } 00129 00130 void rlSpreadsheetRow::setText(int column, const char *text) 00131 { 00132 int c = 1; 00133 rlSpreadsheetCell *item; 00134 00135 if(column < 1) return; 00136 if(firstCell == NULL) firstCell = new rlSpreadsheetCell; 00137 00138 item = firstCell; 00139 while(1) 00140 { 00141 if(c == column) { item->setText(text); return; } 00142 if(item->getNextCell() == NULL) item->setNextCell(new rlSpreadsheetCell); 00143 item = item->getNextCell(); 00144 c++; 00145 } 00146 } 00147 00148 int rlSpreadsheetRow::printf(int column, const char *format, ...) 00149 { 00150 int ret; 00151 char buf[rl_PRINTF_LENGTH_SPREADSHEET]; // should be big enough 00152 00153 va_list ap; 00154 va_start(ap,format); 00155 ret = rlvsnprintf(buf, rl_PRINTF_LENGTH_SPREADSHEET - 1, format, ap); 00156 va_end(ap); 00157 setText(column,buf); 00158 return ret; 00159 } 00160 00161 void rlSpreadsheetRow::clear() 00162 { 00163 rlSpreadsheetCell *item; 00164 00165 item = firstCell; 00166 while(item != NULL) 00167 { 00168 item->clear(); 00169 item = item->getNextCell(); 00170 } 00171 } 00172 00173 void rlSpreadsheetRow::setNextRow(rlSpreadsheetRow *next) 00174 { 00175 nextRow = next; 00176 } 00177 00178 rlSpreadsheetRow *rlSpreadsheetRow::getNextRow() 00179 { 00180 return nextRow; 00181 } 00182 00183 rlSpreadsheetCell *rlSpreadsheetRow::getFirstCell() 00184 { 00185 return firstCell; 00186 } 00187 00188 void rlSpreadsheetRow::readRow(const unsigned char *line, char delimitor) 00189 { 00190 int i,tab1,tab2,col; 00191 unsigned char *celltext; 00192 00193 clear(); 00194 00195 tab1 = tab2 = -1; 00196 col = 1; 00197 i = 0; 00198 while(line[i] != '\0') 00199 { 00200 if(line[i] == delimitor || line[i] == '\n' || line[i] == 0x0d) // normally delimitor='\t' 00201 { 00202 tab1 = tab2; 00203 tab2 = i; 00204 celltext = new unsigned char[tab2-tab1+1]; 00205 if(tab2 > tab1) 00206 { 00207 strncpy((char *) celltext,(const char *) &line[tab1+1],tab2-tab1); 00208 celltext[tab2-tab1-1] = '\0'; 00209 } 00210 else 00211 { 00212 celltext[0] = '\0'; 00213 } 00214 setText(col++, (char *) celltext); 00215 delete [] celltext; 00216 } 00217 i++; 00218 } 00219 00220 return; 00221 } 00222 00223 void rlSpreadsheetRow::writeRow(void *fp, char delimitor) 00224 { 00225 rlSpreadsheetCell *cell; 00226 if(fp == NULL) return; 00227 cell = firstCell; 00228 while(cell != NULL) 00229 { 00230 fprintf((FILE *) fp,"%s",cell->text()); 00231 cell = cell->getNextCell(); 00232 if(cell != NULL) fprintf((FILE *) fp, "%c", delimitor); 00233 } 00234 fprintf((FILE *) fp,"\n"); 00235 } 00236 00237 int rlSpreadsheetRow::exists(int column) 00238 { 00239 rlSpreadsheetCell *item; 00240 int c; 00241 00242 c = 1; 00243 item = firstCell; 00244 while(item != NULL) 00245 { 00246 if(c == column) return 1; 00247 c++; 00248 item = item->getNextCell(); 00249 } 00250 return 0; 00251 } 00252 00253 // rlSpreadsheetTable 00254 rlSpreadsheetTable::rlSpreadsheetTable(char del) 00255 { 00256 firstRow = NULL; 00257 nextTable = NULL; 00258 delimitor = del; 00259 } 00260 00261 rlSpreadsheetTable::~rlSpreadsheetTable() 00262 { 00263 rlSpreadsheetRow *item,*last; 00264 item = firstRow; 00265 while(item != NULL) 00266 { 00267 last = item; 00268 item = item->getNextRow(); 00269 if(item != last) delete last; 00270 } 00271 } 00272 00273 const char *rlSpreadsheetTable::text(int column, int row) 00274 { 00275 int r = 1; 00276 rlSpreadsheetRow *item; 00277 00278 item = firstRow; 00279 while(item != NULL) 00280 { 00281 if(r == row) return item->text(column); 00282 item = item->getNextRow(); 00283 r++; 00284 } 00285 return null_string; 00286 } 00287 00288 void rlSpreadsheetTable::setText(int column, int row, const char *text) 00289 { 00290 int r = 1; 00291 rlSpreadsheetRow *item,*nextitem; 00292 00293 if(row < 1) return; 00294 if(firstRow == NULL) firstRow = new rlSpreadsheetRow; 00295 item = firstRow; 00296 while(1) 00297 { 00298 if(r == row) { item->setText(column,text); return; } 00299 nextitem = item->getNextRow(); 00300 if(nextitem == NULL) item->setNextRow(new rlSpreadsheetRow); 00301 item = item->getNextRow(); 00302 r++; 00303 } 00304 } 00305 00306 int rlSpreadsheetTable::printf(int column, int row, const char *format, ...) 00307 { 00308 int ret; 00309 char buf[rl_PRINTF_LENGTH_SPREADSHEET]; // should be big enough 00310 00311 va_list ap; 00312 va_start(ap,format); 00313 ret = rlvsnprintf(buf, rl_PRINTF_LENGTH_SPREADSHEET - 1, format, ap); 00314 va_end(ap); 00315 setText(column,row,buf); 00316 return ret; 00317 } 00318 00319 void rlSpreadsheetTable::clear() 00320 { 00321 rlSpreadsheetRow *item; 00322 00323 item = firstRow; 00324 while(item != NULL) 00325 { 00326 item->clear(); 00327 item = item->getNextRow(); 00328 } 00329 } 00330 00331 int rlSpreadsheetTable::read(const char *filename) 00332 { 00333 FILE *fp; 00334 rlSpreadsheetRow *item,*last,*next; 00335 unsigned char *line; 00336 int r = 1; 00337 if(filename == NULL) return -1; 00338 00339 // delete old table 00340 item = firstRow; 00341 while(item != NULL) 00342 { 00343 last = item; 00344 item = item->getNextRow(); 00345 if(item != last) delete last; 00346 } 00347 00348 // read new table 00349 fp = fopen(filename,"r"); 00350 if(fp == NULL) return -1; 00351 line = new unsigned char[256*256+1]; 00352 while(fgets((char *) line,256*256,fp) != NULL) 00353 { 00354 if(r==1) 00355 { 00356 item = firstRow = new rlSpreadsheetRow; 00357 } 00358 else 00359 { 00360 next = new rlSpreadsheetRow; 00361 item->setNextRow(next); 00362 item = next; 00363 } 00364 item->readRow(line,delimitor); 00365 r++; 00366 } 00367 delete [] line; 00368 fclose(fp); 00369 return r - 1; // number of lines that have been read 00370 } 00371 00372 int rlSpreadsheetTable::write(const char *filename) 00373 { 00374 rlSpreadsheetRow *item; 00375 FILE *fp; 00376 if(filename == NULL) return -1; 00377 fp = fopen(filename,"w"); 00378 if(fp == NULL) return -1; 00379 00380 item = firstRow; 00381 while(item != NULL) 00382 { 00383 item->writeRow((void *) fp); 00384 item = item->getNextRow(); 00385 } 00386 00387 fclose(fp); 00388 return 0; 00389 } 00390 00391 void rlSpreadsheetTable::setNextTable(rlSpreadsheetTable *next) 00392 { 00393 nextTable = next; 00394 } 00395 00396 rlSpreadsheetRow *rlSpreadsheetTable::getFirstRow() 00397 { 00398 return firstRow; 00399 } 00400 00401 rlSpreadsheetTable *rlSpreadsheetTable::getNextTable() 00402 { 00403 return nextTable; 00404 } 00405 00406 int rlSpreadsheetTable::exists(int column, int row) 00407 { 00408 rlSpreadsheetRow *item; 00409 int r; 00410 00411 r = 1; 00412 item = firstRow; 00413 while(item != NULL) 00414 { 00415 if(r == row) return item->exists(column); 00416 r++; 00417 item = item->getNextRow(); 00418 } 00419 return 0; 00420 } 00421 00422 void rlSpreadsheetTable::setDelimitor(char _delimitor) 00423 { 00424 delimitor = _delimitor; 00425 } 00426 00427 // rlSpreadsheetWorkbook 00428 rlSpreadsheetWorkbook::rlSpreadsheetWorkbook(char del) 00429 { 00430 firstTable = NULL; 00431 delimitor = del; 00432 } 00433 00434 rlSpreadsheetWorkbook::~rlSpreadsheetWorkbook() 00435 { 00436 rlSpreadsheetTable *item,*last; 00437 item = firstTable; 00438 while(item != NULL) 00439 { 00440 last = item; 00441 item = item->getNextTable(); 00442 if(item != last) delete last; 00443 } 00444 } 00445 00446 const char *rlSpreadsheetWorkbook::text(int column, int row, int page) 00447 { 00448 int p = 1; 00449 rlSpreadsheetTable *item; 00450 00451 item = firstTable; 00452 while(item != NULL) 00453 { 00454 if(p == page) return item->text(column, row); 00455 item = item->getNextTable(); 00456 p++; 00457 } 00458 return null_string; 00459 } 00460 00461 void rlSpreadsheetWorkbook::setText(int column, int row, int page, const char *text) 00462 { 00463 int p = 1; 00464 rlSpreadsheetTable *item,*nextitem; 00465 00466 if(page < 1) return; 00467 if(firstTable == NULL) firstTable = new rlSpreadsheetTable; 00468 item = firstTable; 00469 while(1) 00470 { 00471 if(p == page) { item->setText(column, row, text); return; } 00472 nextitem = item->getNextTable(); 00473 if(nextitem == NULL) item->setNextTable(new rlSpreadsheetTable); 00474 item = item->getNextTable(); 00475 p++; 00476 } 00477 } 00478 00479 int rlSpreadsheetWorkbook::printf(int column, int row, int page, const char *format, ...) 00480 { 00481 int ret; 00482 char buf[rl_PRINTF_LENGTH_SPREADSHEET]; // should be big enough 00483 00484 va_list ap; 00485 va_start(ap,format); 00486 ret = rlvsnprintf(buf, rl_PRINTF_LENGTH_SPREADSHEET - 1, format, ap); 00487 va_end(ap); 00488 setText(column,row,page,buf); 00489 return ret; 00490 } 00491 00492 void rlSpreadsheetWorkbook::clear() 00493 { 00494 rlSpreadsheetTable *item; 00495 00496 item = firstTable; 00497 while(item != NULL) 00498 { 00499 item->clear(); 00500 item = item->getNextTable(); 00501 } 00502 } 00503 00504 int rlSpreadsheetWorkbook::read(const char *filename) 00505 { 00506 FILE *fp; 00507 rlSpreadsheetTable *item,*last,*next; 00508 int p = 1; 00509 char buf[16],*fname; 00510 if(filename == NULL) return -1; 00511 00512 // delete old workbook 00513 item = firstTable; 00514 while(item != NULL) 00515 { 00516 last = item; 00517 item = item->getNextTable(); 00518 if(item != last) delete last; 00519 } 00520 00521 // read new workbook 00522 fname = new char[strlen(filename)+16]; 00523 while(1) 00524 { 00525 strcpy(fname,filename); 00526 sprintf(buf,"%d.txt",p); 00527 strcat(fname,buf); 00528 // test if file exists 00529 fp = fopen(fname,"r"); 00530 if(fp == NULL) break; 00531 fclose(fp); 00532 if(p==1) 00533 { 00534 item = firstTable = new rlSpreadsheetTable(delimitor); 00535 } 00536 else 00537 { 00538 next = new rlSpreadsheetTable(delimitor); 00539 item->setNextTable(next); 00540 item = next; 00541 } 00542 if(item->read(fname) < 0) break; 00543 p++; 00544 } 00545 00546 delete [] fname; 00547 return 0; 00548 } 00549 00550 int rlSpreadsheetWorkbook::write(const char *filename) 00551 { 00552 rlSpreadsheetTable *item = NULL; 00553 int p = 1; 00554 char buf[16],*fname; 00555 if(filename == NULL) return -1; 00556 00557 // write workbook 00558 fname = new char[strlen(filename)+16]; 00559 while(1) 00560 { 00561 strcpy(fname,filename); 00562 sprintf(buf,"%d.txt",p); 00563 strcat(fname,buf); 00564 if(p==1) item = firstTable; 00565 else item = item->getNextTable(); 00566 if(item == NULL) break; 00567 if(item->write(fname) < 0) break; 00568 p++; 00569 } 00570 00571 delete [] fname; 00572 return 0; 00573 } 00574 00575 int rlSpreadsheetWorkbook::exists(int column, int row, int page) 00576 { 00577 rlSpreadsheetTable *item; 00578 int p; 00579 00580 p = 1; 00581 item = firstTable; 00582 while(item != NULL) 00583 { 00584 if(p == page) return item->exists(column,row); 00585 p++; 00586 item = item->getNextTable(); 00587 } 00588 return 0; 00589 } 00590 00591 rlSpreadsheetTable *rlSpreadsheetWorkbook::getFirstTable() 00592 { 00593 return firstTable; 00594 } 00595 00596 void rlSpreadsheetWorkbook::setDelimitor(char _delimitor) 00597 { 00598 delimitor = _delimitor; 00599 } 00600 00601
1.7.5.1