1 //
2 // This file is part of the SDTS++ toolkit, written by the U.S.
3 // Geological Survey. It is experimental software, written to support
4 // USGS research and cartographic data production.
5 //
6 // SDTS++ is public domain software. It may be freely copied,
7 // distributed, and modified. The USGS welcomes user feedback, but makes
8 // no committment to any level of support for this code. See the SDTS
9 // web site at http://mcmcweb.er.usgs.gov/sdts for more information,
10 // including points of contact.
11 //
12 // $Id: sb_Comp.cpp,v 1.4 2002/10/11 19:55:50 mcoletti Exp $
13 //
14
15 #include "builder/sb_Comp.h"
16
17
18 #include <iostream>
19 #include <strstream>
20 #include <string>
21
22 using namespace std;
23
24 #include <limits.h>
25 #include <float.h>
26
27 #ifndef INCLUDED_SB_UTILS_H
28 #include "builder/sb_Utils.h"
29 #endif
30
31 #ifndef INCLUDED_SB_FOREIGNID_H
32 #include "builder/sb_ForeignID.h"
33 #endif
34
35 #ifndef INCLUDED_SC_RECORD_H
36 #include "container/sc_Record.h"
37 #endif
38
39 #ifndef INCLUDED_SC_FIELD_H
40 #include "container/sc_Field.h"
41 #endif
42
43 #ifndef INCLUDED_SC_SUBFIELD_H
44 #include "container/sc_Subfield.h"
45 #endif
46
47 #ifndef INCLUDED_SIO_8211CONVERTER_H
48 #include "io/sio_8211Converter.h"
49 #endif
50
51 #ifndef INCLUDED_SIO_CONVERTERFACTORY_H
52 #include "io/sio_ConverterFactory.h"
53 #endif
54
55
56
57 static const char* _ident = "$Id: sb_Comp.cpp,v 1.4 2002/10/11 19:55:50 mcoletti Exp $";
58
59 // Strings and integers are initialized with these values; they are used
60 // to indicate whether a given module value has been assigned a value or not.
61
62 // (XXX I arbitrarily chose 0x4 as the sentinal value. I hate ad hoc crap.)
63
64 static const string UNVALUED_STRING(1, static_cast<string::value_type>(0x4) );
65
66 static const long UNVALUED_LONG = INT_MIN;
67
68 static const double UNVALUED_DOUBLE = DBL_MAX;
69
70
71 struct sb_Comp_Imp
72 {
73 string _ObjectRepresentation;
74 sb_AttributeIDs _AttributeIDs;
75 sb_ForeignIDs _ForeignIDs;
76 sb_ForeignIDs _CompositeIDs;
77
78
sb_Comp_Impsb_Comp_Imp79 sb_Comp_Imp()
80 : _ObjectRepresentation( UNVALUED_STRING )
81 {}
82
resetsb_Comp_Imp83 void reset()
84 {
85 _ObjectRepresentation = UNVALUED_STRING;
86 _AttributeIDs.clear ();
87 _ForeignIDs.clear ();
88 _CompositeIDs.clear ();
89
90 }
91
92 };// struct sb_Comp_Imp
93
94
sb_Comp()95 sb_Comp::sb_Comp()
96 : _imp( new sb_Comp_Imp() )
97 {
98 setMnemonic("COMP");
99 setID( 1 );
100
101
102 // insert static initializers
103
104 } // Comp ctor
105
106
~sb_Comp()107 sb_Comp::~sb_Comp()
108 {
109 } // Comp dtor
110
111
112
113
114
115 static sio_8211Schema _schema; // module specific schema
116
117 static
118 void
_build_schema(sio_8211Schema & schema)119 _build_schema( sio_8211Schema& schema )
120 {
121 schema.clear(); // make sure we are starting with clean schema
122
123 schema.push_back( sio_8211FieldFormat() );
124
125 sio_8211FieldFormat& field_format = schema.back();
126
127 field_format.setDataStructCode( sio_8211FieldFormat::vector );
128 field_format.setDataTypeCode( sio_8211FieldFormat::mixed_data_type );
129 field_format.setName( "Comp" );
130 field_format.setTag( "COMPOSITE" );
131
132
133 field_format.push_back( sio_8211SubfieldFormat() );
134
135 field_format.back().setLabel( "MODN" );
136 field_format.back().setType( sio_8211SubfieldFormat::A );
137 field_format.back().setFormat( sio_8211SubfieldFormat::variable );
138 field_format.back().setConverter( sio_ConverterFactory::instance()->get( "A" ) );
139
140 field_format.push_back( sio_8211SubfieldFormat() );
141
142 field_format.back().setLabel( "RCID" );
143 field_format.back().setType( sio_8211SubfieldFormat::I );
144 field_format.back().setFormat( sio_8211SubfieldFormat::variable );
145 field_format.back().setConverter( sio_ConverterFactory::instance()->get( "I" ) );
146
147
148 field_format.push_back( sio_8211SubfieldFormat() );
149
150 field_format.back().setLabel( "OBRP" );
151 field_format.back().setType( sio_8211SubfieldFormat::A );
152 field_format.back().setFormat( sio_8211SubfieldFormat::variable );
153 field_format.back().setConverter( sio_ConverterFactory::instance()->get( "A" ));
154
155
156 sb_ForeignID foreign_id;
157 sb_AttributeID attribute_id;
158
159 attribute_id.addFieldToSchema( schema, "AttributeID", "ATID", true );
160 foreign_id.addFieldToSchema( schema, "ForeignID", "FRID", true );
161 foreign_id.addFieldToSchema( schema, "CompositeID", "CPID", true );
162
163 } // _build_schema
164
165
166 static
167 bool
_ingest_record(sb_Comp & comp,sb_Comp_Imp & comp_imp,sc_Record const & record)168 _ingest_record( sb_Comp& comp, sb_Comp_Imp &comp_imp, sc_Record const& record )
169 {
170
171 // Make sure we have a record from an
172 // External Spatial Reference module.
173
174 sc_FieldCntr::const_iterator curfield;
175
176 if ( ! sb_Utils::getFieldByMnem( record,"COMP",curfield) )
177 {
178 #ifdef SDTSXX_DEBUG
179 cerr << "sb_Comp::sb_Comp(sc_Record const&): "
180 << "Not an composite record.";
181 cerr << endl;
182 #endif
183 return false;
184 }
185
186
187 // We have a primary field from a module. Start// picking it apart.
188
189 sc_SubfieldCntr::const_iterator cursubfield;
190
191 string tmp_str;
192 long tmp_int;
193
194
195 // MODN
196 if (sb_Utils::getSubfieldByMnem(*curfield,"MODN",cursubfield))
197 {
198 cursubfield->getA( tmp_str );
199 comp.setMnemonic( tmp_str );
200 }
201
202
203 // RCID
204 if (sb_Utils::getSubfieldByMnem(*curfield,"RCID",cursubfield))
205 {
206 cursubfield->getI( tmp_int );
207 comp.setID( tmp_int );
208 }
209
210
211 // OBRP
212 if (sb_Utils::getSubfieldByMnem(*curfield,"OBRP",cursubfield))
213 {
214 cursubfield->getA( comp_imp._ObjectRepresentation);
215 }
216 else
217 {
218 return false;
219 }
220
221
222 // ATID
223 if ( sb_Utils::getFieldByMnem( record,"ATID",curfield) )
224 {
225 //As this is potentially a repeating field, we just keep
226 //grabbing fields until we get one that's well, not anAttributeID
227 while ( curfield != record.end() && curfield->mnemonic() == "ATID" )
228 {
229
230 comp_imp._AttributeIDs.push_back( sb_AttributeID() );
231 if ( ! comp_imp._AttributeIDs.back().assign( *curfield ) )
232 {
233
234 return false;
235 }
236
237 curfield++;
238 }
239 }
240 else
241 {
242 // this is an optional filed, so no worries if we get here
243 }
244
245
246 // FRID
247 if ( sb_Utils::getFieldByMnem( record,"FRID",curfield) )
248 {
249 //As this is potentially a repeating field, we just keep
250 //grabbing fields until we get one that's well, not anForeignID
251 while ( curfield != record.end() && curfield->mnemonic() == "FRID" )
252 {
253
254 comp_imp._ForeignIDs.push_back( sb_ForeignID() );
255 if ( ! comp_imp._ForeignIDs.back().assign( *curfield ) )
256 {
257
258 return false;
259 }
260
261 curfield++;
262 }
263 }
264 else
265 {
266 // this is an optional filed, so no worries if we get here
267 }
268
269
270 // CPID
271 if ( sb_Utils::getFieldByMnem( record,"CPID",curfield) )
272 {
273 //As this is potentially a repeating field, we just keep
274 //grabbing fields until we get one that's well, not anCompositeID
275 while ( curfield != record.end() && curfield->mnemonic() == "CPID" )
276 {
277
278 comp_imp._CompositeIDs.push_back( sb_ForeignID() );
279 if ( ! comp_imp._CompositeIDs.back().assign( *curfield ) )
280 {
281
282 return false;
283 }
284
285 curfield++;
286 }
287 }
288 else
289 {
290 // this is an optional filed, so no worries if we get here
291 }
292
293
294 return true;
295
296
297 } // _ingest_record
298
299
300
301
302 bool
getObjectRepresentation(string & val) const303 sb_Comp::getObjectRepresentation( string & val ) const
304 {
305 if ( _imp->_ObjectRepresentation == UNVALUED_STRING )
306 return false;
307
308 val = _imp->_ObjectRepresentation;
309
310 return true;
311
312 } // sb_Comp::getObjectRepresentation
313
314
315 bool
getAttributeID(std::list<std::string> & val) const316 sb_Comp::getAttributeID( std::list<std::string> & val ) const
317 {
318 if ( _imp->_AttributeIDs.empty() )
319 return false;
320
321 // We'll let the programmer worry about the proper maintanence of
322 // the given list of strings. HTat is, it'll be up to them to
323 // clear the contents or not before invoking this member function.
324 string tmp_string;
325
326 for ( sb_AttributeIDs::const_iterator i =_imp->_AttributeIDs.begin(); i != _imp->_AttributeIDs.end();i++ )
327 {
328 if ( ! i->packedIdentifierString( tmp_string ) )
329 {
330 return false;
331 }
332 val.push_back( tmp_string );
333 }
334 return true;
335 } //sb_Comp::getAttributeID(std::string& val)
336
337
338 bool
getAttributeID(sb_AttributeIDs & val) const339 sb_Comp::getAttributeID( sb_AttributeIDs & val ) const
340 {
341
342 val = _imp->_AttributeIDs;
343 return true;
344
345 } // sb_Comp::getAttributeID
346
347
348 bool
getForeignID(std::list<std::string> & val) const349 sb_Comp::getForeignID( std::list<std::string> & val ) const
350 {
351 if ( _imp->_ForeignIDs.empty() )
352 return false;
353
354 // We'll let the programmer worry about the proper maintanence of
355 // the given list of strings. HTat is, it'll be up to them to
356 // clear the contents or not before invoking this member function.
357 string tmp_string;
358
359 for ( sb_ForeignIDs::const_iterator i =_imp->_ForeignIDs.begin(); i != _imp->_ForeignIDs.end();i++ )
360 {
361 if ( ! i->packedIdentifierString( tmp_string ) )
362 {
363 return false;
364 }
365 val.push_back( tmp_string );
366 }
367 return true;
368 } //sb_Comp::getForeignID(std::string& val)
369
370
371 bool
getForeignID(sb_ForeignIDs & val) const372 sb_Comp::getForeignID( sb_ForeignIDs & val ) const
373 {
374
375 val = _imp->_ForeignIDs;
376 return true;
377
378 } // sb_Comp::getForeignID
379
380
381 bool
getCompositeID(std::list<std::string> & val) const382 sb_Comp::getCompositeID( std::list<std::string> & val ) const
383 {
384 if ( _imp->_CompositeIDs.empty() )
385 return false;
386
387 // We'll let the programmer worry about the proper maintanence of
388 // the given list of strings. HTat is, it'll be up to them to
389 // clear the contents or not before invoking this member function.
390 string tmp_string;
391
392 for ( sb_ForeignIDs::const_iterator i =_imp->_CompositeIDs.begin(); i != _imp->_CompositeIDs.end();i++ )
393 {
394 if ( ! i->packedIdentifierString( tmp_string ) )
395 {
396 return false;
397 }
398 val.push_back( tmp_string );
399 }
400 return true;
401 } //sb_Comp::getCompositeID(std::string& val)
402
403
404 bool
getCompositeID(sb_ForeignIDs & val) const405 sb_Comp::getCompositeID( sb_ForeignIDs & val ) const
406 {
407
408 val = _imp->_CompositeIDs;
409 return true;
410
411 } // sb_Comp::getCompositeID
412
413
414 bool
getSchema(sio_8211Schema & schema) const415 sb_Comp::getSchema( sio_8211Schema& schema ) const
416 {
417 // If the schema hasn't been
418 // initialized, please do so.
419
420 if ( _schema.empty() )
421 {
422 _build_schema( _schema );
423 }
424
425 if ( _schema.empty() ) // oops ... something screwed up
426 {
427 return false;
428 }
429
430 schema = _schema;
431
432 return true;
433
434 } // sb_Comp::getSchema
435
436
437
438
439 bool
getRecord(sc_Record & record) const440 sb_Comp::getRecord( sc_Record & record ) const
441 {
442 record.clear(); // start with a clean slate
443
444 // first field, which contains module name and record number
445
446 sb_ForeignID tmp_foreign_id;
447
448 record.push_back( sc_Field() );
449
450 record.back().setMnemonic( "COMP" );
451
452 record.back().setName( "Composite" );
453
454 string tmp_str;
455
456 getMnemonic( tmp_str );
457 sb_Utils::add_subfield( record.back(), "MODN", tmp_str );
458 sb_Utils::add_subfield( record.back(), "RCID", getID() );
459
460 if ( getObjectRepresentation( tmp_str ) )
461 {
462 sb_Utils::add_subfield( record.back(),"OBRP", tmp_str );
463 }
464 else
465 {
466 sb_Utils::add_empty_subfield( record.back(), "OBRP", sc_Subfield::is_A );
467 }
468
469
470 for ( sb_AttributeIDs::const_iterator i = _imp->_AttributeIDs.begin();
471 i != _imp->_AttributeIDs.end(); i++ )
472 {
473 sb_Utils::add_foreignID ( record, *i );
474 }
475
476
477 for ( sb_ForeignIDs::const_iterator j = _imp->_ForeignIDs.begin();
478 j != _imp->_ForeignIDs.end();
479 j++ )
480 {
481 sb_Utils::add_foreignID ( record, *j );
482 }
483
484
485 for ( sb_ForeignIDs::const_iterator k = _imp->_CompositeIDs.begin();
486 k != _imp->_CompositeIDs.end();
487 k++ )
488 {
489 sb_Utils::add_foreignID ( record, *k );
490 }
491
492
493 return true;
494
495
496 } // Comp::getRecord
497
498
499
500
501 bool
setObjectRepresentation(string const & val)502 sb_Comp::setObjectRepresentation( string const& val )
503 {
504 _imp->_ObjectRepresentation = val;
505
506 return true;
507 } // sb_Comp::setObjectRepresentation
508
509
510 bool
setAttributeID(sb_AttributeIDs const & val)511 sb_Comp::setAttributeID( sb_AttributeIDs const& val )
512 {
513 _imp->_AttributeIDs = val;
514
515 return true;
516 } // sb_Comp::setAttributeID
517
518
519 bool
setForeignID(sb_ForeignIDs const & val)520 sb_Comp::setForeignID( sb_ForeignIDs const& val )
521 {
522 _imp->_ForeignIDs = val;
523
524 return true;
525 } // sb_Comp::setForeignID
526
527
528 bool
setCompositeID(sb_ForeignIDs const & val)529 sb_Comp::setCompositeID( sb_ForeignIDs const& val )
530 {
531 _imp->_CompositeIDs = val;
532
533 return true;
534 } // sb_Comp::setCompositeID
535
536
537 bool
setRecord(sc_Record const & record)538 sb_Comp::setRecord( sc_Record const& record )
539 {
540 _imp->reset(); // reset to new state; i.e., clear out foreign
541 // identifiers, etc.
542 return _ingest_record( *this, *_imp, record );
543 } // sb_Comp::setRecord
544
545
546
547
548 void
unDefineObjectRepresentation()549 sb_Comp::unDefineObjectRepresentation( )
550 {
551 _imp->_ObjectRepresentation = UNVALUED_STRING;
552 } // sb_Comp::unDefineObjectRepresentation
553
554
555 void
unDefineAttributeID()556 sb_Comp::unDefineAttributeID( )
557 {
558 _imp->_AttributeIDs.clear();
559 } // sb_Comp::unDefineAttributeID
560
561
562 void
unDefineForeignID()563 sb_Comp::unDefineForeignID( )
564 {
565 _imp->_ForeignIDs.clear();
566 } // sb_Comp::unDefineForeignID
567
568
569 void
unDefineCompositeID()570 sb_Comp::unDefineCompositeID( )
571 {
572 _imp->_CompositeIDs.clear();
573 } // sb_Comp::unDefineCompositeID
574
575
576 sio_8211Schema&
schema_()577 sb_Comp::schema_()
578 {
579 if ( _schema.empty() )
580 {
581 buildSpecificSchema_();
582 }
583
584 return _schema;
585 } // sb_Comp::schema_()
586
587
588
589 void
buildSpecificSchema_()590 sb_Comp::buildSpecificSchema_()
591 {_build_schema( _schema );
592 } // sb_Comp::buildSpecificSchema_()
593