rdbxx  1.0.7_02
RDBColumn.cc
1 // --8<--8<--8<--8<--
2 //
3 // Copyright (C) 2006 Smithsonian Astrophysical Observatory
4 //
5 // This file is part of RDB
6 //
7 // RDB is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // RDB is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the
19 // Free Software Foundation, Inc.
20 // 51 Franklin Street, Fifth Floor
21 // Boston, MA 02110-1301, USA
22 //
23 // -->8-->8-->8-->8--
24 
25 #include <cstdlib>
26 #include "RDBColumn.h"
27 
37 istream&
38 operator>>(
39  istream& is,
40  RDBColumn& col
41  ) {
42 
43  try {
44  col.read( is );
45 
46  } catch ( RDBErr& rdberr ) {
47  rdberr.set_message( "operator>>(istream&,RDBColumn&): " );
48  throw( rdberr );
49 
50  } catch ( ... ) {
51  throw( RDBErr( "operator>>(istream&,RDBColumn&): unexpected exception caught" ) );
52 
53  }
54 
55  return is;
56 
57 }
58 
68 istream&
69 operator>>(
70  istream& is,
71  RDBColumn* col
72  ) {
73 
74  try {
75  col->read( is );
76 
77  } catch ( RDBErr& rdberr ) {
78  rdberr.set_message( "operator>>(istream&,RDBColumn*): " );
79  throw( rdberr );
80 
81  } catch ( ... ) {
82  throw( RDBErr( "operator>>(istream&,RDBColumn*): unexpected exception caught" ) );
83 
84  }
85 
86  return is;
87 
88 }
89 
99 ostream&
100 operator<<(
101  ostream& os,
102  const RDBColumn& col
103  ) {
104 
105  return col.write( os );
106 
107 }
108 
118 ostream&
119 operator<<(
120  ostream& os,
121  const RDBColumn* col
122  ) {
123 
124  return col->write( os );
125 
126 }
127 
137  const string& name,
138  const string& def
139  )
140  : _name(name), _def(def), _width(-1), _type(STRING), _just(LEFT),
141  _desc(""), _changed(false), _throw(true), _errno(0),
142  _precision(DBL_DIG), _group(false), _initgroup(true) {
143 
144  if ( !_def.empty( ) ) {
145  try {
146  setDef( _def );
147 
148  } catch ( RDBErr& rdberr ) {
149  rdberr.set_message( "RDBColumn::RDBColumn(string&,string&): " );
150  throw( rdberr );
151 
152  } catch ( ... ) {
153  throw( RDBErr( "RDBColumn::RDBColumn(string&,string&): unexpected exception caught" ) );
154 
155  }
156  }
157 }
158 
166  const RDBColumn& col
167  )
168  : _name(col._name), _def(col._def), _width(col._width),
169  _type(col._type), _just(col._just), _desc(col._desc),
170  _changed(col._changed), _throw(col._throw), _errno(col._errno),
171  _precision(col._precision), _group(col._group),
172  _initgroup(col._initgroup) {
173 
174 }
175 
181  void
182  ) {
183 
184 }
185 
190 RDBColumn&
192  const RDBColumn& col
193  ) {
194 
195  if ( this != &col ) {
196  _name = col._name;
197  _def = col._def;
198  _width = col._width;
199  _type = col._type;
200  _just = col._just;
201  _desc = col._desc;
202  _throw = col._throw;
203  _errno = col._errno;
204  _precision = col._precision;
205  _changed = col._changed;
206  _group = col._group;
207 
208  }
209 
210  return *this;
211 
212 }
213 
218 void
220  bool group
221  ) {
222 
223  _group = group;
224 
225 }
226 
231 bool
233  void
234  ) const {
235 
236  return _group;
237 
238 }
239 
246 void
248  const string& name
249  ) {
250 
251  _name = name;
252 
253 }
254 
265 void
267  const string& def
268  ) {
269 
270  _def = def;
271 
272  _width = -1;
273  _type = STRING;
274  _just = LEFT;
275  _desc.erase( );
276 
277  size_t defsize = def.size( );
278  char* cdef = new char[defsize+1];
279  strcpy( cdef, def.c_str() );
280  // cdef[defsize] = '\0';
281  int n = 0;
282 
283  if ( isdigit( cdef[0] ) ) {
284  char* ptr = NULL;
285  _width = strtol( cdef, &ptr, 10 );
286  if ( ptr ) {
287  n = ptr - cdef;
288 
289  }
290  }
291 
292  if ( NUMERIC == cdef[n] || STRING == cdef[n] || MONTH == cdef[n] ) {
293  _type = Type(cdef[n++]);
294 
295  } else if ( '-' == cdef[n] ) {
296  _type = STRING;
297  while ( '-' == cdef[n] ) {
298  n++;
299 
300  }
301  } else {
302  delete [] cdef;
303  throw( RDBErr( string("RDBColumn::setDef(string&): Bad type in column defintion '") + def + "' for '" + _name + "'" ) );
304 
305  }
306 
307  if ( '\0' != cdef[n] && ( LEFT == cdef[n] || RIGHT == cdef[n] ) ) {
308  _just = Just(cdef[n++]);
309 
310  }
311 
312  if ( '\0' != cdef[n] ) {
313  if ( ' ' == cdef[n] ) {
314  while ( ' ' == cdef[n] ) {
315  n++;
316 
317  }
318  _desc = &cdef[n];
319  }
320  else {
321  delete [] cdef;
322  throw( RDBErr( string("RDBColumn::setDef(string&): Bad just in column defintion '") + def + "' for '" + _name + "'" ) );
323 
324  }
325  }
326 
327  _changed = false;
328  delete [] cdef;
329 
330 }
331 
339 void
341  const long width
342  ) {
343 
344  _width = width;
345  _changed = true;
346 
347 }
348 
356 void
358  const RDBColumn::Type type
359  ) {
360 
361  _type = type;
362  _changed = true;
363 
364 }
365 
374 void
376  const RDBColumn::Just just
377  ) {
378 
379  _just = just;
380  _changed = true;
381 
382 }
383 
390 void
392  const string& desc
393  ) {
394 
395  _desc = desc;
396  _changed = true;
397 
398 }
399 
407 void
409  const int precision
410  ) {
411 
412  _precision = precision;
413 
414 }
415 
422 void
424  const bool t
425  ) {
426 
427  _throw = t;
428 
429 }
430 
437 void
439  const int no
440  ) {
441 
442  _errno = no;
443 
444 }
445 
447 void
449  double data[],
450  const size_t nelems
451  ) {
452 
453  throw( RDBErr( string("RDBColumn::mapData(double[],size_t): Wrong data type: double[] in column '") + _name + "'" ) );
454 
455 }
456 
458 void
460  long data[],
461  const size_t nelems
462  ) {
463 
464  throw( RDBErr( string("RDBColumn::mapData(long[],size_t): Wrong data type: long[] in column '") + _name + "'" ) );
465 
466 }
467 
469 void
471  string data[],
472  const size_t nelems
473  ) {
474 
475  throw( RDBErr( string("RDBColumn::mapData(stringdouble[],size_t): Wrong data type: string[] in column '") + _name + "'" ) );
476 
477 }
478 
483 string
485  void
486  ) const {
487 
488  return _name;
489 
490 }
491 
497 string
499  void
500  ) {
501 
502  if ( _changed ) {
503  _def.erase( );
504  _strstrm.seekp( 0 );
505  if ( ! _strstrm.good( ) )
506  _strstrm.clear( );
507  if ( -1 != _width )
508  _strstrm << _width;
509 
510  if ( RDBColumn::NUMERIC == _type )
511  _strstrm << 'N';
512  else if ( RDBColumn::STRING == _type )
513  _strstrm << 'S';
514  else
515  _strstrm << 'M';
516 
517  if ( RDBColumn::LEFT == _just )
518  _strstrm << '<';
519  else
520  _strstrm << '>';
521 
522  if ( 0 != _desc.length( ) )
523  _strstrm << ' ' << _desc;
524 
525  _strstrm << '\0';
526  _def = _strstrm.str( ).c_str( );
527  _changed = false;
528 
529  }
530 
531  return _def;
532 
533 }
534 
539 long
540 RDBColumn::getWidth(
541  void
542  ) const {
543 
544  return _width;
545 
546 }
547 
552 RDBColumn::Type
553 RDBColumn::getType(
554  void
555  ) const {
556 
557  return _type;
558 
559 }
560 
565 RDBColumn::Just
566 RDBColumn::getJust(
567  void
568  ) const {
569 
570  return _just;
571 
572 }
573 
578 string
579 RDBColumn::getDesc(
580  void
581  ) const {
582 
583  return _desc;
584 
585 }
586 
591 int
592 RDBColumn::getPrecision(
593  void
594  ) const {
595 
596  return _precision;
597 
598 }
599 
604 bool
605 RDBColumn::getThrow(
606  void
607  ) const {
608 
609  return _throw;
610 
611 }
612 
617 char*
618 RDBColumn::getErr(
619  void
620  ) const {
621 
622  return strerror( _errno );
623 
624 }
625 
630 int
631 RDBColumn::getErrNo(
632  void
633  ) const {
634 
635  return _errno;
636 
637 }
638 
646 void
647 RDBColumn::convert(
648  const double& idata,
649  double& odata
650  ) {
651 
652  odata = idata;
653 
654 }
655 
663 void
664 RDBColumn::convert(
665  const double& idata,
666  long& odata
667  ) {
668 
669  odata = (long) idata;
670 
671 }
672 
683 void
684 RDBColumn::convert(
685  const double& idata,
686  string& odata
687  ) {
688 
689  _strstrm.seekp( 0 );
690  if ( ! _strstrm.good( ) )
691  _strstrm.clear( );
692  _strstrm << setprecision( _precision ) << idata << '\0';
693  odata = _strstrm.str( ).c_str( );
694 
695 }
696 
704 void
705 RDBColumn::convert(
706  const long& idata,
707  double& odata
708  ) {
709 
710  odata = (double) idata;
711 
712 }
713 
721 void
722 RDBColumn::convert(
723  const long& idata,
724  long& odata
725  ) {
726 
727  odata = idata;
728 
729 }
730 
740 void
741 RDBColumn::convert(
742  const long& idata,
743  string& odata
744  ) {
745 
746  _strstrm.seekp( 0 );
747  if ( ! _strstrm.good( ) )
748  _strstrm.clear( );
749  _strstrm << idata << '\0';
750  odata = _strstrm.str( ).c_str( );
751 
752 }
753 
763 void
764 RDBColumn::convert(
765  const string& idata,
766  double& odata
767  ) {
768 
769  errno = 0;
770  char* endptr = NULL;
771  odata = strtod( idata.length( ) ? idata.c_str( ) : "NaN", &endptr );
772  _errno = errno;
773  if ( ( endptr && ( *endptr != '\0' ) ) ) {
774  if ( _throw ) {
775  throw( RDBErr( string("RDBColumn::convert(string&,double&): Non numeric data in column '") + _name + "' at '" + endptr + "'" ) );
776 
777  } else {
778  _errno = RDBColumn::OUTOFRANGE;
779 
780  }
781  }
782 
783 }
784 
795 void
796 RDBColumn::convert(
797  const string& idata,
798  long& odata
799  ) {
800 
801  errno = 0;
802  char* endptr = NULL;
803  odata = strtol( idata.length( ) ? idata.c_str( ) : "NaN", &endptr, 10 );
804  _errno = errno;
805  if ( ( endptr && *endptr != '\0' ) ) {
806  if ( *endptr != '.' ) {
807  if ( _throw ) {
808  throw( RDBErr( string("RDBColumn::convert(string&,long&): Non numeric data in column '") + _name + "' at '" + endptr + "'" ) );
809 
810  } else {
811  _errno = RDBColumn::NONNUMERIC;
812 
813  }
814  } else {
815  char* beginptr = endptr+1;
816  endptr = NULL;
817  strtol( beginptr, &endptr, 10 );
818  _errno = errno;
819  if ( ( endptr && *endptr != '\0' ) ) {
820  if ( _throw ) {
821  throw( RDBErr( string("RDBColumn::convert(string&,long&): Non numeric data in column '") + _name + "'at '" + endptr + "'" ) );
822 
823  } else {
824  _errno = RDBColumn::NONNUMERIC;
825 
826  }
827  } else {
828  if ( _throw ) {
829  throw( RDBErr( string("RDBColumn::convert(string&,long&): Lost precision in column '") + _name + "'" ) );
830 
831  } else {
832  _errno = RDBColumn::LOSTPRECISION;
833 
834  }
835  }
836  }
837  }
838 }
839 
847 void
848 RDBColumn::convert(
849  const string& idata,
850  string& odata
851  ) {
852 
853  odata = idata;
854 
855 }
856 
866 istream&
867 RDBColumn::extract(
868  istream& is,
869  double& data
870  ) {
871 
872  is >> data;
873  if ( ! is.good( ) ) {
874  throw( RDBErr( string("RDBColumn::extract(istream&,double&): Non numeric data in column '") + _name + "'" ) );
875  }
876 
877  return is;
878 
879 }
880 
890 istream&
891 RDBColumn::extract(
892  istream& is,
893  long& data
894  ) {
895 
896  is >> data;
897  if ( ! is.good( ) ) {
898  throw( RDBErr( string("RDBColumn::extract(istream&,long&): Non numeric data in column '") + _name + "'" ) );
899 
900  }
901 
902  return is;
903 
904 }
905 
916 istream&
917 RDBColumn::extract(
918  istream& is,
919  string& data
920  ) {
921 
922  string tmp;
923  is >> data;
924  if ( ! is.good( ) ) {
925  throw( RDBErr( string("RDBColumn::extract(stream&,string&): Row format error in column '") + _name + "'" ) );
926 
927  }
928 
929  while ( ' ' == is.peek( ) ) {
930  is >> tmp;
931  if ( ! is.good( ) ) {
932  throw( RDBErr( string("RDBColumn::extract(stream&,string&): Row format error in column '") + _name + "'" ) );
933 
934  }
935  data += ' ' + tmp;
936 
937  }
938 
939  return is;
940 
941 }
942 
952 ostream&
953 RDBColumn::insert(
954  ostream& os,
955  double& data
956  ) const {
957 
958  return os << setprecision( _precision ) << data;
959 
960 }
961 
971 ostream&
972 RDBColumn::insert(
973  ostream& os,
974  long& data
975  ) const {
976 
977  return os << setprecision( _precision ) << data;
978 
979 }
980 
990 ostream&
991 RDBColumn::insert(
992  ostream& os,
993  string& data
994  ) const {
995 
996  return os << setprecision( _precision ) << data;
997 
998 }
string _def
Definition.
Definition: RDBColumn.h:227
long _width
Width.
Definition: RDBColumn.h:229
string getName(void) const
Returns the name.
Definition: RDBColumn.cc:484
bool _throw
State of the exception throwing behavior.
Definition: RDBColumn.h:240
void setPrecision(const int precision)
Sets the precision for numeric output and numeric to string conversion.
Definition: RDBColumn.cc:408
RDBColumn & operator=(const RDBColumn &col)
Copies RDBColumn object.
Definition: RDBColumn.cc:191
Just
Acceptable column justifications.
Definition: RDBColumn.h:60
void setErrNo(const int no=0)
Sets the error status.
Definition: RDBColumn.cc:438
void setName(const string &name)
Sets the name.
Definition: RDBColumn.cc:247
stringstream _strstrm
Used for numeric to string conversion.
Definition: RDBColumn.h:246
bool _changed
Indicates state for the definition field.
Definition: RDBColumn.h:237
void setWidth(const long width)
Sets the width.
Definition: RDBColumn.cc:340
void setJust(const RDBColumn::Just just)
Sets the justification.
Definition: RDBColumn.cc:375
string _name
Name.
Definition: RDBColumn.h:225
void setType(const RDBColumn::Type type)
Sets the type.
Definition: RDBColumn.cc:357
void setDef(const string &def)
Sets the definition.
Definition: RDBColumn.cc:266
The parent class for all RDB related exceptions.
Definition: RDBErr.h:33
string _desc
Description.
Definition: RDBColumn.h:235
virtual void setGroup(bool group)
Turn on/off group tracking for this column object.
Definition: RDBColumn.cc:219
bool getGroup(void) const
Returns group status, RBOG if at beginning of a group, REOG if at ned of a group, or REOL if in the m...
Definition: RDBColumn.cc:232
int _errno
Error state.
Definition: RDBColumn.h:242
RDBColumn::Type _type
Data type.
Definition: RDBColumn.h:231
RDBColumn::Just _just
Justification.
Definition: RDBColumn.h:233
int _precision
Precision used for stream output or numeric to string conversion.
Definition: RDBColumn.h:244
virtual void mapData(double data[], const size_t nelems=1)
Maps data to user-supplied memory, if possible.
Definition: RDBColumn.cc:448
Type
Acceptable column types.
Definition: RDBColumn.h:62
virtual istream & read(istream &is)=0
Called by the stream insertion operator.
void setDesc(const string &desc)
Sets the description.
Definition: RDBColumn.cc:391
virtual ostream & write(ostream &os) const =0
Called by the stream extraction operator.
bool _group
This is a group column.
Definition: RDBColumn.h:248
void setThrow(const bool t=true)
Sets the excpeption throwing behavior.
Definition: RDBColumn.cc:423
string getDef(void)
Returns the definition.
Definition: RDBColumn.cc:498
virtual ~RDBColumn(void)
Deletes resources allocated by RDBColumn object.
Definition: RDBColumn.cc:180
RDBColumn(const string &name="", const string &def="")
Assigns name and definition to RDBColumn object.
Definition: RDBColumn.cc:136
Provides interface for general column related methods.
Definition: RDBColumn.h:43