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