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 // 13 // $Id: sc_Subfield.h,v 1.10 2003/01/03 20:41:05 mcoletti Exp $ 14 // 15 16 #ifndef INCLUDED_SCSUBFIELD_HXX 17 #define INCLUDED_SCSUBFIELD_HXX 18 19 #include <iostream> 20 #include <string> 21 22 #ifndef INCLUDED_SCMULTITYPEVALUE_HXX 23 #include <sdts++/container/sc_MultiTypeValue.h> 24 #endif 25 26 27 28 /** 29 \note 30 31 * Attribute subfields should have their mnemonic set to 32 either "ATTP" or "ATTS", and their name set to the actual 33 name of the attribute. Non- attribute subfields should have 34 their mnemonic set to one of the subfield mnemonics defined 35 by the SDTS. The name of a non-attribute subfield does not 36 have to be set, and will not be if read from a transfer. 37 38 Also, it's possible for a subfield to have a type, but have 39 no value. A subfield starts out this by default and can be 40 set to this null state via the setUnvalued() member. This 41 is useful if you have to have a 'placeholder' subfield in 42 an sc_Record that doesn't have any value at all. 43 44 This class represents an SDTS Subfield. A Subfield has a value 45 that is one of several types. 46 47 Using one of the 'set' methods sets both the value *and* the 48 type. There is no way to set a value without setting the 49 type. There is no way to "lock" the type; setting an instance to 50 a new value with a different type will change the type associated 51 with the instance. This models the behavior of a variable whose 52 type has run-time binding. The type of the variable depends on 53 the type of the value assigned to it. 54 55 'get'ting the value of an instance will fail unless the member 56 function corresponding to the current type of the instance is 57 used. For example, getting a string value for a subfield set as 58 a BI32 will fail. 59 60 An SDTS Subfield has the following attributes: 61 Type: 62 "The Data Type shall indicate the manner in which the subfield 63 shall be encoded." -- The SDTS, section 4.2.1 "Specification Layout". 64 The data type is one of: 65 A: graphic characters, alphanumeric characters, or 66 alphabetic characters. 67 I: implicit-point (integer) 68 R: explicit-point unscaled (fixed point real) 69 S: explicit-point scaled (floating point real) 70 B: bitfield data 71 C: character mode bitfield (binary in zero and one characters) 72 73 The 'B' type may have additional qualification as follows: 74 BI8: 8 bit signed integer 75 BI16: 16 bit signed integer 76 BI24: 24 bit signed integer 77 BI32: 32 bit signed integer 78 BUI: unsigned integer, length specified by implementation 79 BUI8: 8 bit unsigned integer 80 BUI16: 16 bit unsigned integer 81 BUI24: 24 bit unsigned integer 82 BUI32: 32 bit unsigned integer 83 BFP32: 32 bit floating point real 84 BFP64: 64 bit floating point real 85 86 In an sc_Subfield, the types listed above are actually 87 stored using one of long, unsigned long, double, string or 88 vector<char>. The mapping from SDTS data type to C++ is as 89 follows: 90 91 A string 92 I long 93 R,S double 94 C Not Implemented 95 BUI Not Implemented 96 BI8, BI16, BI24, BI32 long 97 BUI8, BUI16, BUI24, BUI32 unsigned long 98 BFP32 float 99 BFP64 double 100 101 Value: 102 The actual value stored in the Subfield. 103 104 Name: 105 A string representing the subfield name ("Module Name", 106 "Record ID", etc). 107 108 Mnemonic: 109 A string representing the subfield mnemonic ("MODN", "RCID", etc). 110 111 112 113 */ 114 class sc_Subfield 115 { 116 public: 117 118 /// Denotes a subfield's type. 119 enum SubfieldType { is_A, 120 is_I, 121 is_R, 122 is_S, 123 is_C, 124 is_B, 125 is_BI8, 126 is_BI16, 127 is_BI24, 128 is_BI32, 129 is_BUI, 130 is_BUI8, 131 is_BUI16, 132 is_BUI24, 133 is_BUI32, 134 is_BFP32, 135 is_BFP64 136 }; 137 138 /// 139 sc_Subfield(); 140 141 /// 142 sc_Subfield( std::string const& name, std::string const& mnemonic ); 143 144 /// 145 sc_Subfield(sc_Subfield const& right); 146 147 /// 148 ~sc_Subfield(); 149 150 /// 151 sc_Subfield& operator=(sc_Subfield const& right); 152 153 /// 154 bool operator==(sc_Subfield const& right) const; 155 156 /// 157 bool operator!=(sc_Subfield const& right) const; 158 159 /// 160 SubfieldType getSubfieldType() const; 161 162 /// Returns the SDTS Name of this subfield (if one has been set). 163 std::string const& getName() const; 164 165 /// abbreviation for getName() name()166 std::string const &name() const { return getName(); } 167 168 /// Returns the SDTS Mnemonic of this subfield (if one has been set). 169 std::string const& getMnemonic() const; 170 171 /// abbreviation for getMnemonic() mnemonic()172 std::string const& mnemonic() const { return getMnemonic(); } 173 174 /// 175 bool getA(std::string& val) const; 176 177 /// 178 bool getI(long& val) const; 179 180 /// 181 bool getR(double& val) const; 182 183 /// 184 bool getS(double& val) const; 185 186 /// 187 bool getC(std::string& val) const; 188 189 /// 190 bool getBI8(long& val) const; 191 192 /// 193 bool getBI16(long& val) const; 194 195 /// 196 bool getBI24(long& val) const; 197 198 /// 199 bool getBI32(long& val) const; 200 201 /// 202 bool getBUI8(unsigned long& val) const; 203 204 /// 205 bool getBUI16(unsigned long& val) const; 206 207 /// 208 bool getBUI24(unsigned long& val) const; 209 210 /// 211 bool getBUI32(unsigned long& val) const; 212 213 // bool getB(xyzzy) const; // Not Implemented. 214 215 /// 216 bool getBFP32(float& val) const; 217 218 /// 219 bool getBFP64(double& val) const; 220 221 /// convert the value to an integer, returning false if the underlying type doesn't support it 222 /** 223 The is a convenience member function to spare the programmer 224 from having to go through a variety of machinations to first 225 check the type, then use a variable of the correct type, use 226 it, then convert it back to the target type. That's all just 227 silly. So I do it all here for you. 228 229 */ 230 bool getInt( int & val ) const; 231 232 233 /// convert the value to a real, returning false if the underlying type doesn't support it 234 /** 235 The is a convenience member function to spare the programmer 236 from having to go through a variety of machinations to first 237 check the type, then use a variable of the correct type, use 238 it, then convert it back to the target type. That's all just 239 silly. So I do it all here for you. 240 241 */ 242 bool getFloat( float & val ) const; 243 244 245 246 /// convert the value to a real, returning false if the underlying type doesn't support it 247 /** 248 The is a convenience member function to spare the programmer 249 from having to go through a variety of machinations to first 250 check the type, then use a variable of the correct type, use 251 it, then convert it back to the target type. That's all just 252 silly. So I do it all here for you. 253 254 */ 255 bool getDouble( double & val ) const; 256 257 /** 258 Returns the 'value' of the subfield in an object that can be 259 one of several different types. 260 SlUtils defines functions for extracting specific 261 C++ types from a sc_Subfield using this member function. 262 (For example, see: SlUtils::getDoubleFromSubfield()) */ 263 sc_MultiTypeValue const& getValue() const; 264 265 /// 266 std::string const& setName(std::string const& name); name(std::string const & name)267 std::string const& name(std::string const& name) { return setName(name); } 268 269 /// 270 std::string const& setMnemonic(std::string const& mnem); mnemonic(std::string const & mnem)271 std::string const& mnemonic(std::string const& mnem) { return setMnemonic(mnem); } 272 273 //@{ 274 /// set the subfield to the given value and lock it into its type 275 void setA(std::string const& val); 276 void setI(long val); 277 void setR(double val); 278 void setS(double val); 279 void setC(std::string const& val); 280 // void setB(xyzzy); // NOT IMPLEMENTED. 281 void setBI8(long val); 282 void setBI16(long val); 283 void setBI24(long val); 284 void setBI32(long val); 285 void setBUI8(unsigned long val); 286 void setBUI16(unsigned long val); 287 void setBUI24(unsigned long val); 288 void setBUI32(unsigned long val); 289 void setBFP32(float val); 290 void setBFP64(double val); 291 //@} 292 293 /** 294 This resets the subfield back to a 'uninitialized' state such that 295 it still has a type, but no value. 296 */ 297 void setUnvalued(); 298 299 /// returns true if the subfield has no value and associated type isUnvalued()300 bool isUnvalued() const { return value_.null(); } 301 302 private: 303 304 /// SDTS Subfield Name 305 std::string name_; 306 307 /// SDTS Subfield Mnemonic 308 std::string mnemonic_; 309 310 /// 311 sc_MultiTypeValue value_; 312 313 /// 314 SubfieldType type_; 315 316 friend std::ostream& operator<<(std::ostream&, sc_Subfield const&); 317 318 }; // class sc_Subfield 319 320 321 322 #endif // INCLUDED_SCSUBFIELD_HXX 323