rllib  1
rlspreadsheet.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  rlspreadsheet.h - description
3  -------------------
4  begin : Tue Jan 02 2001
5  copyright : (C) 2001 by R. Lehrig
6  email : lehrig@t-online.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
13  * published by the Free Software Foundation *
14  * *
15  ***************************************************************************/
16 #include <stdio.h>
17 #include <stdarg.h>
18 #include <string.h>
19 #include "rlspreadsheet.h"
20 #include "rlcutil.h"
21 
22 static const char null_string[] = "";
23 
24 // rlSpreadsheetCell
26 {
27  if(Text != NULL)
28  {
29  txt = new char[strlen(Text)+1];
30  strcpy(txt,Text);
31  }
32  else
33  {
34  txt = NULL;
35  }
36  nextCell = NULL;
37 }
38 
40 {
41  if(txt != NULL) delete [] txt;
42 }
43 
45 {
46  if(txt == NULL) return null_string;
47  return txt;
48 }
49 
50 void rlSpreadsheetCell::setText(const char *Text)
51 {
52  if(txt != NULL) delete [] txt;
53  if(Text == NULL)
54  {
55  txt = NULL;
56  return;
57  }
58  txt = new char[strlen(Text)+1];
59  strcpy(txt,Text);
60 }
61 
62 int rlSpreadsheetCell::printf(const char *format, ...)
63 {
64  int ret;
65  char buf[rl_PRINTF_LENGTH_SPREADSHEET]; // should be big enough
66 
67  va_list ap;
68  va_start(ap,format);
69  ret = rlvsnprintf(buf, rl_PRINTF_LENGTH_SPREADSHEET - 1, format, ap);
70  va_end(ap);
71  setText(buf);
72  return ret;
73 }
74 
76 {
77  if(txt != NULL) delete [] txt;
78  txt = NULL;
79 }
80 
82 {
83  nextCell = next;
84 }
85 
87 {
88  return nextCell;
89 }
90 
92 {
93  return 1;
94 }
95 
96 // rlSpreadsheetRow
98 {
99  firstCell = NULL;
100  nextRow = NULL;
101 }
102 
104 {
105  rlSpreadsheetCell *item,*last;
106  item = firstCell;
107  while(item != NULL)
108  {
109  last = item;
110  item = item->getNextCell();
111  if(item != last) delete last;
112  }
113 }
114 
115 const char *rlSpreadsheetRow::text(int column)
116 {
117  int c = 1;
118  rlSpreadsheetCell *item;
119 
120  item = firstCell;
121  while(item != NULL)
122  {
123  if(c == column) return item->text();
124  item = item->getNextCell();
125  c++;
126  }
127  return null_string;
128 }
129 
130 void rlSpreadsheetRow::setText(int column, const char *text)
131 {
132  int c = 1;
133  rlSpreadsheetCell *item;
134 
135  if(column < 1) return;
136  if(firstCell == NULL) firstCell = new rlSpreadsheetCell;
137 
138  item = firstCell;
139  while(1)
140  {
141  if(c == column) { item->setText(text); return; }
142  if(item->getNextCell() == NULL) item->setNextCell(new rlSpreadsheetCell);
143  item = item->getNextCell();
144  c++;
145  }
146 }
147 
148 int rlSpreadsheetRow::printf(int column, const char *format, ...)
149 {
150  int ret;
151  char buf[rl_PRINTF_LENGTH_SPREADSHEET]; // should be big enough
152 
153  va_list ap;
154  va_start(ap,format);
155  ret = rlvsnprintf(buf, rl_PRINTF_LENGTH_SPREADSHEET - 1, format, ap);
156  va_end(ap);
157  setText(column,buf);
158  return ret;
159 }
160 
162 {
163  rlSpreadsheetCell *item;
164 
165  item = firstCell;
166  while(item != NULL)
167  {
168  item->clear();
169  item = item->getNextCell();
170  }
171 }
172 
174 {
175  nextRow = next;
176 }
177 
179 {
180  return nextRow;
181 }
182 
184 {
185  return firstCell;
186 }
187 
188 void rlSpreadsheetRow::readRow(const unsigned char *line, char delimitor)
189 {
190  int i,tab1,tab2,col;
191  unsigned char *celltext;
192 
193  clear();
194 
195  tab1 = tab2 = -1;
196  col = 1;
197  i = 0;
198  while(line[i] != '\0')
199  {
200  if(line[i] == delimitor || line[i] == '\n' || line[i] == 0x0d) // normally delimitor='\t'
201  {
202  tab1 = tab2;
203  tab2 = i;
204  celltext = new unsigned char[tab2-tab1+1];
205  if(tab2 > tab1)
206  {
207  strncpy((char *) celltext,(const char *) &line[tab1+1],tab2-tab1);
208  celltext[tab2-tab1-1] = '\0';
209  }
210  else
211  {
212  celltext[0] = '\0';
213  }
214  setText(col++, (char *) celltext);
215  delete [] celltext;
216  }
217  i++;
218  }
219 
220  return;
221 }
222 
223 void rlSpreadsheetRow::writeRow(void *fp, char delimitor)
224 {
225  rlSpreadsheetCell *cell;
226  if(fp == NULL) return;
227  cell = firstCell;
228  while(cell != NULL)
229  {
230  fprintf((FILE *) fp,"%s",cell->text());
231  cell = cell->getNextCell();
232  if(cell != NULL) fprintf((FILE *) fp, "%c", delimitor);
233  }
234  fprintf((FILE *) fp,"\n");
235 }
236 
238 {
239  rlSpreadsheetCell *item;
240  int c;
241 
242  c = 1;
243  item = firstCell;
244  while(item != NULL)
245  {
246  if(c == column) return 1;
247  c++;
248  item = item->getNextCell();
249  }
250  return 0;
251 }
252 
253 // rlSpreadsheetTable
255 {
256  firstRow = NULL;
257  nextTable = NULL;
258  delimitor = del;
259 }
260 
262 {
263  rlSpreadsheetRow *item,*last;
264  item = firstRow;
265  while(item != NULL)
266  {
267  last = item;
268  item = item->getNextRow();
269  if(item != last) delete last;
270  }
271 }
272 
273 const char *rlSpreadsheetTable::text(int column, int row)
274 {
275  int r = 1;
276  rlSpreadsheetRow *item;
277 
278  item = firstRow;
279  while(item != NULL)
280  {
281  if(r == row) return item->text(column);
282  item = item->getNextRow();
283  r++;
284  }
285  return null_string;
286 }
287 
288 void rlSpreadsheetTable::setText(int column, int row, const char *text)
289 {
290  int r = 1;
291  rlSpreadsheetRow *item,*nextitem;
292 
293  if(row < 1) return;
294  if(firstRow == NULL) firstRow = new rlSpreadsheetRow;
295  item = firstRow;
296  while(1)
297  {
298  if(r == row) { item->setText(column,text); return; }
299  nextitem = item->getNextRow();
300  if(nextitem == NULL) item->setNextRow(new rlSpreadsheetRow);
301  item = item->getNextRow();
302  r++;
303  }
304 }
305 
306 int rlSpreadsheetTable::printf(int column, int row, const char *format, ...)
307 {
308  int ret;
309  char buf[rl_PRINTF_LENGTH_SPREADSHEET]; // should be big enough
310 
311  va_list ap;
312  va_start(ap,format);
313  ret = rlvsnprintf(buf, rl_PRINTF_LENGTH_SPREADSHEET - 1, format, ap);
314  va_end(ap);
315  setText(column,row,buf);
316  return ret;
317 }
318 
320 {
321  rlSpreadsheetRow *item;
322 
323  item = firstRow;
324  while(item != NULL)
325  {
326  item->clear();
327  item = item->getNextRow();
328  }
329 }
330 
331 int rlSpreadsheetTable::read(const char *filename)
332 {
333  FILE *fp;
334  rlSpreadsheetRow *item,*last,*next;
335  unsigned char *line;
336  int r = 1;
337  if(filename == NULL) return -1;
338 
339  // delete old table
340  item = firstRow;
341  while(item != NULL)
342  {
343  last = item;
344  item = item->getNextRow();
345  if(item != last) delete last;
346  }
347 
348  // read new table
349  fp = fopen(filename,"r");
350  if(fp == NULL) return -1;
351  line = new unsigned char[256*256+1];
352  while(fgets((char *) line,256*256,fp) != NULL)
353  {
354  if(r==1)
355  {
356  item = firstRow = new rlSpreadsheetRow;
357  }
358  else
359  {
360  next = new rlSpreadsheetRow;
361  item->setNextRow(next);
362  item = next;
363  }
364  item->readRow(line,delimitor);
365  r++;
366  }
367  delete [] line;
368  fclose(fp);
369  return r - 1; // number of lines that have been read
370 }
371 
372 int rlSpreadsheetTable::write(const char *filename)
373 {
374  rlSpreadsheetRow *item;
375  FILE *fp;
376  if(filename == NULL) return -1;
377  fp = fopen(filename,"w");
378  if(fp == NULL) return -1;
379 
380  item = firstRow;
381  while(item != NULL)
382  {
383  item->writeRow((void *) fp, delimitor);
384  item = item->getNextRow();
385  }
386 
387  fclose(fp);
388  return 0;
389 }
390 
392 {
393  nextTable = next;
394 }
395 
397 {
398  return firstRow;
399 }
400 
402 {
403  return nextTable;
404 }
405 
406 int rlSpreadsheetTable::exists(int column, int row)
407 {
408  rlSpreadsheetRow *item;
409  int r;
410 
411  r = 1;
412  item = firstRow;
413  while(item != NULL)
414  {
415  if(r == row) return item->exists(column);
416  r++;
417  item = item->getNextRow();
418  }
419  return 0;
420 }
421 
422 void rlSpreadsheetTable::setDelimitor(char _delimitor)
423 {
424  delimitor = _delimitor;
425 }
426 
427 // rlSpreadsheetWorkbook
429 {
430  firstTable = NULL;
431  delimitor = del;
432 }
433 
435 {
436  rlSpreadsheetTable *item,*last;
437  item = firstTable;
438  while(item != NULL)
439  {
440  last = item;
441  item = item->getNextTable();
442  if(item != last) delete last;
443  }
444 }
445 
446 const char *rlSpreadsheetWorkbook::text(int column, int row, int page)
447 {
448  int p = 1;
449  rlSpreadsheetTable *item;
450 
451  item = firstTable;
452  while(item != NULL)
453  {
454  if(p == page) return item->text(column, row);
455  item = item->getNextTable();
456  p++;
457  }
458  return null_string;
459 }
460 
461 void rlSpreadsheetWorkbook::setText(int column, int row, int page, const char *text)
462 {
463  int p = 1;
464  rlSpreadsheetTable *item,*nextitem;
465 
466  if(page < 1) return;
467  if(firstTable == NULL) firstTable = new rlSpreadsheetTable;
468  item = firstTable;
469  while(1)
470  {
471  if(p == page) { item->setText(column, row, text); return; }
472  nextitem = item->getNextTable();
473  if(nextitem == NULL) item->setNextTable(new rlSpreadsheetTable);
474  item = item->getNextTable();
475  p++;
476  }
477 }
478 
479 int rlSpreadsheetWorkbook::printf(int column, int row, int page, const char *format, ...)
480 {
481  int ret;
482  char buf[rl_PRINTF_LENGTH_SPREADSHEET]; // should be big enough
483 
484  va_list ap;
485  va_start(ap,format);
486  ret = rlvsnprintf(buf, rl_PRINTF_LENGTH_SPREADSHEET - 1, format, ap);
487  va_end(ap);
488  setText(column,row,page,buf);
489  return ret;
490 }
491 
493 {
494  rlSpreadsheetTable *item;
495 
496  item = firstTable;
497  while(item != NULL)
498  {
499  item->clear();
500  item = item->getNextTable();
501  }
502 }
503 
504 int rlSpreadsheetWorkbook::read(const char *filename)
505 {
506  FILE *fp;
507  rlSpreadsheetTable *item,*last,*next;
508  int p = 1;
509  char buf[16],*fname;
510  if(filename == NULL) return -1;
511 
512  // delete old workbook
513  item = firstTable;
514  while(item != NULL)
515  {
516  last = item;
517  item = item->getNextTable();
518  if(item != last) delete last;
519  }
520 
521  // read new workbook
522  fname = new char[strlen(filename)+16];
523  while(1)
524  {
525  strcpy(fname,filename);
526  sprintf(buf,"%d.txt",p);
527  strcat(fname,buf);
528  // test if file exists
529  fp = fopen(fname,"r");
530  if(fp == NULL) break;
531  fclose(fp);
532  if(p==1)
533  {
535  }
536  else
537  {
538  next = new rlSpreadsheetTable(delimitor);
539  item->setNextTable(next);
540  item = next;
541  }
542  if(item->read(fname) < 0) break;
543  p++;
544  }
545 
546  delete [] fname;
547  return 0;
548 }
549 
550 int rlSpreadsheetWorkbook::write(const char *filename)
551 {
552  rlSpreadsheetTable *item = NULL;
553  int p = 1;
554  char buf[16],*fname;
555  if(filename == NULL) return -1;
556 
557  // write workbook
558  fname = new char[strlen(filename)+16];
559  while(1)
560  {
561  strcpy(fname,filename);
562  sprintf(buf,"%d.txt",p);
563  strcat(fname,buf);
564  if(p==1) item = firstTable;
565  else item = item->getNextTable();
566  if(item == NULL) break;
567  if(item->write(fname) < 0) break;
568  p++;
569  }
570 
571  delete [] fname;
572  return 0;
573 }
574 
575 int rlSpreadsheetWorkbook::exists(int column, int row, int page)
576 {
577  rlSpreadsheetTable *item;
578  int p;
579 
580  p = 1;
581  item = firstTable;
582  while(item != NULL)
583  {
584  if(p == page) return item->exists(column,row);
585  p++;
586  item = item->getNextTable();
587  }
588  return 0;
589 }
590 
592 {
593  return firstTable;
594 }
595 
597 {
598  delimitor = _delimitor;
600  while(table != NULL)
601  {
602  table->setDelimitor(delimitor);
603  table = table->getNextTable();
604  }
605 }
606 
607 
const char * text(int column)
rlSpreadsheetRow * nextRow
Definition: rlspreadsheet.h:62
const char * text(int column, int row)
void setText(int column, const char *text)
int read(const char *filename)
void setText(int column, int row, const char *text)
int printf(const char *format,...)
rlSpreadsheetCell * getFirstCell()
int write(const char *filename)
rlSpreadsheetRow()
column = 1...N
rlSpreadsheetCell * nextCell
Definition: rlspreadsheet.h:38
rlSpreadsheetRow * firstRow
Definition: rlspreadsheet.h:88
virtual ~rlSpreadsheetCell()
const char * text()
rlSpreadsheetRow * getNextRow()
static const char null_string[]
const char * text(int column, int row, int page)
int exists(int column, int row, int page)
void setDelimitor(char delimitor)
int printf(int column, int row, const char *format,...)
void setNextCell(rlSpreadsheetCell *next)
rlSpreadsheetCell * firstCell
Definition: rlspreadsheet.h:61
rlSpreadsheetCell * getNextCell()
#define rl_PRINTF_LENGTH_SPREADSHEET
Definition: rldefine.h:72
int rlvsnprintf(char *text, int len, const char *format, va_list ap)
Definition: rlcutil.cpp:197
rlSpreadsheetTable * getFirstTable()
void setDelimitor(char delimitor)
int read(const char *filename)
rlSpreadsheetTable * nextTable
Definition: rlspreadsheet.h:89
void setText(const char *text)
void setNextTable(rlSpreadsheetTable *next)
void setNextRow(rlSpreadsheetRow *next)
int printf(int column, const char *format,...)
rlSpreadsheetTable * getNextTable()
rlSpreadsheetWorkbook(char delimitor='\t')
column = 1...N, row = 1...N, page = 1...N
rlSpreadsheetTable(char delimitor='\t')
column = 1...N, row = 1...N
virtual ~rlSpreadsheetTable()
void setText(int column, int row, int page, const char *text)
int write(const char *filename)
rlSpreadsheetRow * getFirstRow()
rlSpreadsheetCell(const char *text=0)
int exists(int column)
void readRow(const unsigned char *line, char delimitor='\t')
int printf(int column, int row, int page, const char *format,...)
rlSpreadsheetTable * firstTable
virtual ~rlSpreadsheetRow()
int exists(int column, int row)
void writeRow(void *fp, char delimitor='\t')
virtual ~rlSpreadsheetWorkbook()