CCfits
2.4
|
00001 // Astrophysics Science Division, 00002 // NASA/ Goddard Space Flight Center 00003 // HEASARC 00004 // http://heasarc.gsfc.nasa.gov 00005 // e-mail: ccfits@legacy.gsfc.nasa.gov 00006 // 00007 // Original author: Ben Dorman 00008 00009 #ifndef COLUMNT_H 00010 #define COLUMNT_H 00011 00012 #ifdef _MSC_VER 00013 #include "MSconfig.h" 00014 #endif 00015 00016 #include "ColumnData.h" 00017 #include "ColumnVectorData.h" 00018 #include "FITSUtil.h" 00019 #include <typeinfo> 00020 #include <vector> 00021 #include <algorithm> 00022 #include "NewKeyword.h" 00023 00024 #ifdef SSTREAM_DEFECT 00025 # include <strstream> 00026 #else 00027 # include <sstream> 00028 #endif 00029 00030 00031 // by design, if the data are not read yet we will return an exception. 00032 // here the test is if the entire column has already been read. 00033 using std::complex; 00034 using std::valarray; 00035 00036 // get specified elements of a scalar column. These two functions allow the 00037 // user to return either a vector or a valarray depending on the input container. 00038 00039 namespace CCfits 00040 { 00041 template <typename S> 00042 void Column::read(std::vector<S>& vals, long first, long last) 00043 { 00044 read(vals,first,last,static_cast<S*>(0)); 00045 } 00046 00047 00048 template <typename S> 00049 void Column::read(std::vector<S>& vals, long first, long last, S* nullValue) 00050 { 00051 // problem: S does not give the type of the Column, but the return type, 00052 // so the user must specify this. 00053 parent()->makeThisCurrent(); 00054 long nelements = numberOfElements(first,last); 00055 00056 if (ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this)) 00057 { 00058 // fails if user requested outputType different from input type. 00059 00060 00061 if (!isRead()) col->readColumnData(first,nelements,nullValue); 00062 // scalar column with vector output can just be assigned. 00063 FITSUtil::fill(vals,col->data(),first,last); 00064 } 00065 else 00066 { 00067 FITSUtil::MatchType<S> outputType; 00068 if ( outputType() == type() ) 00069 { 00070 // in this case user tried to read vector data from scalar, 00071 // (i.e. first argument was vector<valarray<S> >. 00072 // since the cast won't fail on template parameter grounds. 00073 throw Column::WrongColumnType(name()); 00074 } 00075 00076 try 00077 { 00078 // about exceptions. The dynamic_casts could throw 00079 // std::bad_cast. If this happens something is seriously 00080 // wrong since the Column stores the value of type() 00081 // appropriate to each of the casts on construction. 00082 // 00083 // the InvalidDataType exception should not be possible. 00084 if ( type() == Tdouble ) 00085 { 00086 ColumnData<double>& col 00087 = dynamic_cast<ColumnData<double>&>(*this); 00088 if (!isRead()) col.readColumnData(first,nelements); 00089 FITSUtil::fill(vals,col.data(),first,last); 00090 00091 } 00092 else if (type() == Tfloat) 00093 { 00094 ColumnData<float>& col 00095 = dynamic_cast<ColumnData<float>&>(*this); 00096 if (!isRead()) col.readColumnData(first,nelements); 00097 FITSUtil::fill(vals,col.data(),first,last); 00098 } 00099 else if (type() == Tint) 00100 { 00101 int nullVal(0); 00102 if (nullValue) nullVal = static_cast<int>(*nullValue); 00103 ColumnData<int>& col 00104 = dynamic_cast<ColumnData<int>&>(*this); 00105 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00106 FITSUtil::fill(vals,col.data(),first,last); 00107 } 00108 else if (type() == Tshort) 00109 { 00110 short nullVal(0); 00111 if (nullValue) nullVal = static_cast<short>(*nullValue); 00112 ColumnData<short>& col 00113 = dynamic_cast<ColumnData<short>&>(*this); 00114 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00115 FITSUtil::fill(vals,col.data(),first,last); 00116 } 00117 else if (type() == Tlong) 00118 { 00119 long nullVal(0); 00120 if (nullValue) nullVal = static_cast<long>(*nullValue); 00121 ColumnData<long>& col 00122 = dynamic_cast<ColumnData<long>&>(*this); 00123 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00124 FITSUtil::fill(vals,col.data(),first,last); 00125 } 00126 else if (type() == Tlonglong) 00127 { 00128 LONGLONG nullVal(0); 00129 if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue); 00130 ColumnData<LONGLONG>& col 00131 = dynamic_cast<ColumnData<LONGLONG>&>(*this); 00132 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00133 FITSUtil::fill(vals,col.data(),first,last); 00134 } 00135 else if (type() == Tlogical) 00136 { 00137 bool nullVal(0); 00138 if (nullValue) nullVal = static_cast<bool>(*nullValue); 00139 ColumnData<bool>& col 00140 = dynamic_cast<ColumnData<bool>&>(*this); 00141 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00142 FITSUtil::fill(vals,col.data(),first,last); 00143 } 00144 else if (type() == Tbit || type() == Tbyte) 00145 { 00146 unsigned char nullVal(0); 00147 if (nullValue) nullVal = static_cast<unsigned char>(*nullValue); 00148 ColumnData<unsigned char>& col 00149 = dynamic_cast<ColumnData<unsigned char>&>(*this); 00150 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00151 FITSUtil::fill(vals,col.data(),first,last); 00152 } 00153 else if (type() == Tushort) 00154 { 00155 unsigned short nullVal(0); 00156 if (nullValue) nullVal= static_cast<unsigned short>(*nullValue); 00157 ColumnData<unsigned short>& col 00158 = dynamic_cast<ColumnData<unsigned short>&>(*this); 00159 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00160 FITSUtil::fill(vals,col.data(),first,last); 00161 } 00162 else if (type() == Tuint) 00163 { 00164 unsigned int nullVal(0); 00165 if (nullValue) nullVal = static_cast<unsigned int>(*nullValue); 00166 ColumnData<unsigned int>& col 00167 = dynamic_cast<ColumnData<unsigned int>&>(*this); 00168 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00169 FITSUtil::fill(vals,col.data(),first,last); 00170 } 00171 else if (type() == Tulong) 00172 { 00173 unsigned long nullVal(0); 00174 if (nullValue) nullVal = static_cast<unsigned long>(*nullValue); 00175 ColumnData<unsigned long>& col 00176 = dynamic_cast<ColumnData<unsigned long>&>(*this); 00177 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00178 FITSUtil::fill(vals,col.data(),first,last); 00179 } 00180 else 00181 { 00182 throw InvalidDataType(name()); 00183 00184 } 00185 00186 } 00187 catch (std::bad_cast) 00188 { 00189 throw WrongColumnType(name()); 00190 } 00191 } 00192 00193 } 00194 00195 template <typename S> 00196 void Column::read(std::valarray<S>& vals, long first, long last) 00197 { 00198 read(vals,first,last,static_cast<S*>(0)); 00199 } 00200 00201 00202 template <typename S> 00203 void Column::read(std::valarray<S>& vals, long first, long last, S* nullValue) 00204 { 00205 // require the whole scalar column to have been read. 00206 00207 00208 long nelements = numberOfElements(first,last); 00209 parent()->makeThisCurrent(); 00210 if ( ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this)) 00211 { 00212 // fails if user requested outputType different from input type. 00213 00214 00215 if (!isRead()) col->readColumnData(first,nelements,nullValue); 00216 FITSUtil::fill(vals,col->data(),first,last); 00217 00218 } 00219 else 00220 { 00221 FITSUtil::MatchType<S> outputType; 00222 if ( outputType() == type() ) 00223 { 00224 // in this case user tried to read vector data from scalar, 00225 // (i.e. first argument was vector<valarray<S> >. 00226 // since the cast won't fail on template parameter grounds. 00227 throw Column::WrongColumnType(name()); 00228 } 00229 00230 try 00231 { 00232 // about exceptions. The dynamic_casts could throw 00233 // std::bad_cast. If this happens something is seriously 00234 // wrong since the Column stores the value of type() 00235 // appropriate to each of the casts on construction. 00236 // 00237 // the InvalidDataType exception should not be possible. 00238 if ( type() == Tdouble ) 00239 { 00240 ColumnData<double>& col 00241 = dynamic_cast<ColumnData<double>&>(*this); 00242 if (!isRead()) col.readColumnData(first,nelements); 00243 FITSUtil::fill(vals,col.data(),first,last); 00244 } 00245 else if (type() == Tfloat) 00246 { 00247 ColumnData<float>& col 00248 = dynamic_cast<ColumnData<float>&>(*this); 00249 if (!isRead()) col.readColumnData(first,nelements); 00250 FITSUtil::fill(vals,col.data(),first,last); 00251 } 00252 else if (type() == Tint) 00253 { 00254 int nullVal(0); 00255 if (nullValue) nullVal = static_cast<int>(*nullValue); 00256 ColumnData<int>& col 00257 = dynamic_cast<ColumnData<int>&>(*this); 00258 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00259 FITSUtil::fill(vals,col.data(),first,last); 00260 } 00261 else if (type() == Tshort) 00262 { 00263 short nullVal(0); 00264 if (nullValue) nullVal = static_cast<short>(*nullValue); 00265 ColumnData<short>& col 00266 = dynamic_cast<ColumnData<short>&>(*this); 00267 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00268 FITSUtil::fill(vals,col.data(),first,last); 00269 } 00270 else if (type() == Tlong) 00271 { 00272 long nullVal(0); 00273 if (nullValue) nullVal = static_cast<long>(*nullValue); 00274 ColumnData<long>& col 00275 = dynamic_cast<ColumnData<long>&>(*this); 00276 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00277 FITSUtil::fill(vals,col.data(),first,last); 00278 } 00279 else if (type() == Tlonglong) 00280 { 00281 LONGLONG nullVal(0); 00282 if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue); 00283 ColumnData<LONGLONG>& col 00284 = dynamic_cast<ColumnData<LONGLONG>&>(*this); 00285 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00286 FITSUtil::fill(vals,col.data(),first,last); 00287 } 00288 else if (type() == Tlogical) 00289 { 00290 bool nullVal(0); 00291 if (nullValue) nullVal = static_cast<bool>(*nullValue); 00292 ColumnData<bool>& col 00293 = dynamic_cast<ColumnData<bool>&>(*this); 00294 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00295 FITSUtil::fill(vals,col.data(),first,last); 00296 } 00297 else if (type() == Tbit || type() == Tbyte) 00298 { 00299 unsigned char nullVal(0); 00300 if (nullValue) nullVal = static_cast<unsigned char>(*nullValue); 00301 ColumnData<unsigned char>& col 00302 = dynamic_cast<ColumnData<unsigned char>&>(*this); 00303 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00304 FITSUtil::fill(vals,col.data(),first,last); 00305 } 00306 else if (type() == Tushort) 00307 { 00308 unsigned short nullVal(0); 00309 if (nullValue) nullVal 00310 = static_cast<unsigned short>(*nullValue); 00311 ColumnData<unsigned short>& col 00312 = dynamic_cast<ColumnData<unsigned short>&>(*this); 00313 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00314 FITSUtil::fill(vals,col.data(),first,last); 00315 } 00316 else if (type() == Tuint) 00317 { 00318 unsigned int nullVal(0); 00319 if (nullValue) nullVal 00320 = static_cast<unsigned int>(*nullValue); 00321 ColumnData<unsigned int>& col 00322 = dynamic_cast<ColumnData<unsigned int>&>(*this); 00323 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00324 FITSUtil::fill(vals,col.data(),first,last); 00325 } 00326 else if (type() == Tulong) 00327 { 00328 unsigned long nullVal(0); 00329 if (nullValue) nullVal 00330 = static_cast<unsigned long>(*nullValue); 00331 ColumnData<unsigned long>& col 00332 = dynamic_cast<ColumnData<unsigned long>&>(*this); 00333 if (!isRead()) col.readColumnData(first,nelements,&nullVal); 00334 FITSUtil::fill(vals,col.data(),first,last); 00335 } 00336 else 00337 { 00338 throw InvalidDataType(name()); 00339 00340 } 00341 00342 } 00343 catch (std::bad_cast) 00344 { 00345 throw WrongColumnType(name()); 00346 } 00347 } 00348 00349 } 00350 00351 // get a single row from a vector column. There's no default row number, must 00352 // be specified. 00353 template <typename S> 00354 void Column::read(std::valarray<S>& vals, long row) 00355 { 00356 read(vals,row,static_cast<S*>(0)); 00357 } 00358 00359 00360 template <typename S> 00361 void Column::read(std::valarray<S>& vals, long row, S* nullValue) 00362 { 00363 if (row > parent()->rows()) 00364 { 00365 throw Column::InvalidRowNumber(name()); 00366 } 00367 parent()->makeThisCurrent(); 00368 // isRead() returns true if the data were read in the ctor. 00369 if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this)) 00370 { 00371 // fails if user requested outputType different from input type. 00372 00373 00374 00375 // input and output are both valarrays. Since one should not 00376 // be able to call a constructor for a non-numeric valarray type, 00377 // there shouldn't be any InvalidType problems. However, there 00378 // is still the vector/scalar possibility and the implicit 00379 // conversion request to deal with. 00380 00381 if (!isRead()) col->readRow(row,nullValue); 00382 FITSUtil::fill(vals,col->data(row)); 00383 } 00384 else 00385 { 00386 FITSUtil::MatchType<S> outputType; 00387 if ( outputType() == type() ) 00388 { 00389 // in this case user tried to read vector row from scalar column. 00390 // one could be charitable and return a valarray of size 1, 00391 // but... I'm going to throw an exception suggesting the user 00392 // might not have meant that. 00393 00394 throw Column::WrongColumnType(name()); 00395 } 00396 00397 // the InvalidDataType exception should not be possible. 00398 try 00399 { 00400 // about exceptions. The dynamic_casts could throw 00401 // std::bad_cast. If this happens something is seriously 00402 // wrong since the Column stores the value of type() 00403 // appropriate to each of the casts on construction. 00404 // 00405 // the InvalidDataType exception should not be possible. 00406 if ( type() == Tdouble || type() == VTdouble ) 00407 { 00408 ColumnVectorData<double>& col 00409 = dynamic_cast<ColumnVectorData<double>&>(*this); 00410 if (!isRead()) col.readRow(row); 00411 FITSUtil::fill(vals,col.data(row)); 00412 00413 } 00414 else if (type() == Tfloat || type() == VTfloat ) 00415 { 00416 ColumnVectorData<float>& col 00417 = dynamic_cast<ColumnVectorData<float>&>(*this); 00418 if (!isRead()) col.readRow(row); 00419 FITSUtil::fill(vals,col.data(row)); 00420 } 00421 else if (type() == Tint || type() == VTint ) 00422 { 00423 int nullVal(0); 00424 if (nullValue) nullVal = static_cast<int>(*nullValue); 00425 ColumnVectorData<int>& col 00426 = dynamic_cast<ColumnVectorData<int>&>(*this); 00427 if (!isRead()) col.readRow(row,&nullVal); 00428 FITSUtil::fill(vals,col.data(row)); 00429 } 00430 else if (type() == Tshort || type() == VTshort ) 00431 { 00432 short nullVal(0); 00433 if (nullValue) nullVal = static_cast<short>(*nullValue); 00434 ColumnVectorData<short>& col 00435 = dynamic_cast<ColumnVectorData<short>&>(*this); 00436 if (!isRead()) col.readRow(row,&nullVal); 00437 FITSUtil::fill(vals,col.data(row)); 00438 } 00439 else if (type() == Tlong || type() == VTlong ) 00440 { 00441 long nullVal(0); 00442 if (nullValue) nullVal = static_cast<long>(*nullValue); 00443 ColumnVectorData<long>& col 00444 = dynamic_cast<ColumnVectorData<long>&>(*this); 00445 if (!isRead()) col.readRow(row,&nullVal); 00446 FITSUtil::fill(vals,col.data(row)); 00447 } 00448 else if (type() == Tlonglong || type() == VTlonglong ) 00449 { 00450 LONGLONG nullVal(0); 00451 if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue); 00452 ColumnVectorData<LONGLONG>& col 00453 = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this); 00454 if (!isRead()) col.readRow(row,&nullVal); 00455 FITSUtil::fill(vals,col.data(row)); 00456 } 00457 else if (type() == Tlogical || type() == VTlogical ) 00458 { 00459 bool nullVal(0); 00460 if (nullValue) nullVal = static_cast<bool>(*nullValue); 00461 ColumnVectorData<bool>& col 00462 = dynamic_cast<ColumnVectorData<bool>&>(*this); 00463 if (!isRead()) col.readRow(row,&nullVal); 00464 FITSUtil::fill(vals,col.data(row)); 00465 } 00466 else if (type() == Tbit || type() == Tbyte || 00467 type() == VTbit || type() == VTbyte ) 00468 { 00469 unsigned char nullVal(0); 00470 if (nullValue) nullVal 00471 = static_cast<unsigned char>(*nullValue); 00472 ColumnVectorData<unsigned char>& col 00473 = dynamic_cast<ColumnVectorData<unsigned char>&>(*this); 00474 if (!isRead()) col.readRow(row,&nullVal); 00475 FITSUtil::fill(vals,col.data(row)); 00476 } 00477 else if (type() == Tushort || type() == VTushort) 00478 { 00479 unsigned short nullVal(0); 00480 if (nullValue) nullVal 00481 = static_cast<unsigned short>(*nullValue); 00482 ColumnVectorData<unsigned short>& col 00483 = dynamic_cast<ColumnVectorData<unsigned short>&>(*this); 00484 if (!isRead()) col.readRow(row,&nullVal); 00485 FITSUtil::fill(vals,col.data(row)); 00486 } 00487 else if (type() == Tuint || type() == VTuint) 00488 { 00489 unsigned int nullVal(0); 00490 if (nullValue) nullVal 00491 = static_cast<unsigned int>(*nullValue); 00492 ColumnVectorData<unsigned int>& col 00493 = dynamic_cast<ColumnVectorData<unsigned int>&>(*this); 00494 if (!isRead()) col.readRow(row,&nullVal); 00495 FITSUtil::fill(vals,col.data(row)); 00496 } 00497 else if (type() == Tulong || type() == VTulong) 00498 { 00499 unsigned long nullVal(0); 00500 if (nullValue) nullVal 00501 = static_cast<unsigned long>(*nullValue); 00502 ColumnVectorData<unsigned long>& col 00503 = dynamic_cast<ColumnVectorData<unsigned long>&>(*this); 00504 if (!isRead()) col.readRow(row,&nullVal); 00505 FITSUtil::fill(vals,col.data(row)); 00506 } 00507 else 00508 { 00509 throw InvalidDataType(name()); 00510 00511 } 00512 00513 } 00514 catch (std::bad_cast) 00515 { 00516 throw WrongColumnType(name()); 00517 } 00518 } 00519 } 00520 00521 template <typename S> 00522 void Column::readArrays(std::vector<std::valarray<S> >& vals, long first, long last) 00523 { 00524 readArrays(vals,first,last,static_cast<S*>(0)); 00525 } 00526 00527 template <typename S> 00528 void Column::readArrays(std::vector<std::valarray<S> >& vals, 00529 long first, long last, S* nullValue) 00530 { 00531 00532 parent()->makeThisCurrent(); 00533 // again, can only call this if the entire column has been read from disk. 00534 // user expects 1 based indexing. If 0 based indices are supplied, 00535 // add one to both ranges. 00536 long range = numberOfElements(first,last); 00537 00538 vals.resize(range); 00539 00540 00541 if ( ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this)) 00542 { 00543 for (int j = 0; j < range; ++j) 00544 { 00545 if (!isRead()) col->readRow(j + first,nullValue); 00546 FITSUtil::fill(vals[j],col->data(j+first)); 00547 } 00548 } 00549 else 00550 { 00551 FITSUtil::MatchType<S> outputType; 00552 if ( outputType() == type() ) 00553 { 00554 // in this case user tried to read vector data from scalar, 00555 // (i.e. first argument was vector<valarray<S> >. 00556 // since the cast won't fail on template parameter grounds. 00557 throw Column::WrongColumnType(name()); 00558 } 00559 // the InvalidDataType exception should not be possible. 00560 try 00561 { 00562 if ( type() == Tdouble || type() == VTdouble ) 00563 { 00564 ColumnVectorData<double>& col 00565 = dynamic_cast<ColumnVectorData<double>&>(*this); 00566 for (int j = 0; j < range; ++j) 00567 { 00568 if (!isRead()) col.readRow(j + first); 00569 FITSUtil::fill(vals[j],col.data(j+first)); 00570 } 00571 } 00572 else if ( type() == Tfloat || type() == VTfloat ) 00573 { 00574 ColumnVectorData<float>& col 00575 = dynamic_cast<ColumnVectorData<float>&>(*this); 00576 for (int j = 0; j < range; ++j) 00577 { 00578 if (!isRead()) col.readRow(j + first); 00579 FITSUtil::fill(vals[j],col.data(j+first)); 00580 } 00581 } 00582 else if ( type() == Tint || type() == VTint ) 00583 { 00584 int nullVal(0); 00585 if (nullValue) nullVal = static_cast<int>(*nullValue); 00586 ColumnVectorData<int>& col 00587 = dynamic_cast<ColumnVectorData<int>&>(*this); 00588 for (int j = 0; j < range; ++j) 00589 { 00590 if (!isRead()) col.readRow(j + first,&nullVal); 00591 FITSUtil::fill(vals[j],col.data(j+first)); 00592 } 00593 } 00594 else if ( type() == Tshort || type() == VTshort ) 00595 { 00596 short nullVal(0); 00597 if (nullValue) nullVal = static_cast<short>(*nullValue); 00598 ColumnVectorData<short>& col 00599 = dynamic_cast<ColumnVectorData<short>&>(*this); 00600 for (int j = 0; j < range; ++j) 00601 { 00602 if (!isRead()) col.readRow(j + first,&nullVal); 00603 FITSUtil::fill(vals[j],col.data(j+first)); 00604 } 00605 } 00606 else if ( type() == Tlong || type() == VTlong ) 00607 { 00608 long nullVal(0); 00609 if (nullValue) nullVal = static_cast<long>(*nullValue); 00610 ColumnVectorData<long>& col 00611 = dynamic_cast<ColumnVectorData<long>&>(*this); 00612 for (int j = 0; j < range; ++j) 00613 { 00614 if (!isRead()) col.readRow(j + first,&nullVal); 00615 FITSUtil::fill(vals[j],col.data(j+first)); 00616 } 00617 } 00618 else if ( type() == Tlonglong || type() == VTlonglong ) 00619 { 00620 LONGLONG nullVal(0); 00621 if (nullValue) nullVal = static_cast<LONGLONG>(*nullValue); 00622 ColumnVectorData<LONGLONG>& col 00623 = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this); 00624 for (int j = 0; j < range; ++j) 00625 { 00626 if (!isRead()) col.readRow(j + first,&nullVal); 00627 FITSUtil::fill(vals[j],col.data(j+first)); 00628 } 00629 } 00630 else if ( type() == Tlogical || type() == VTlogical ) 00631 { 00632 bool nullVal(0); 00633 if (nullValue) nullVal = static_cast<bool>(*nullValue); 00634 ColumnVectorData<bool>& col 00635 = dynamic_cast<ColumnVectorData<bool>&>(*this); 00636 for (int j = 0; j < range; ++j) 00637 { 00638 if (!isRead()) col.readRow(j + first,&nullVal); 00639 FITSUtil::fill(vals[j],col.data(j+first)); 00640 } 00641 } 00642 else if (type() == Tbit || type() == Tbyte || 00643 type() == VTbit || type() == VTbyte ) 00644 { 00645 unsigned char nullVal(0); 00646 if (nullValue) nullVal 00647 = static_cast<unsigned char>(*nullValue); 00648 ColumnVectorData<unsigned char>& col 00649 = dynamic_cast<ColumnVectorData<unsigned char>&>(*this); 00650 for (int j = 0; j < range; ++j) 00651 { 00652 if (!isRead()) col.readRow(j + first,&nullVal); 00653 FITSUtil::fill(vals[j],col.data(j+first)); 00654 } 00655 } 00656 else if ( type() == Tushort || type() == VTushort ) 00657 { 00658 unsigned short nullVal(0); 00659 if (nullValue) nullVal 00660 = static_cast<unsigned short>(*nullValue); 00661 ColumnVectorData<unsigned short>& col 00662 = dynamic_cast<ColumnVectorData<unsigned short>&>(*this); 00663 for (int j = 0; j < range; ++j) 00664 { 00665 if (!isRead()) col.readRow(j + first,&nullVal); 00666 FITSUtil::fill(vals[j],col.data(j+first)); 00667 } 00668 } 00669 else if ( type() == Tuint || type() == VTuint ) 00670 { 00671 unsigned int nullVal(0); 00672 if (nullValue) nullVal 00673 = static_cast<unsigned int>(*nullValue); 00674 ColumnVectorData<unsigned int>& col 00675 = dynamic_cast<ColumnVectorData<unsigned int>&>(*this); 00676 for (int j = 0; j < range; ++j) 00677 { 00678 if (!isRead()) col.readRow(j + first,&nullVal); 00679 FITSUtil::fill(vals[j],col.data(j+first)); 00680 } 00681 } 00682 else if ( type() == Tulong || type() == VTulong ) 00683 { 00684 unsigned long nullVal(0); 00685 if (nullValue) nullVal 00686 = static_cast<unsigned long>(*nullValue); 00687 ColumnVectorData<unsigned long>& col 00688 = dynamic_cast<ColumnVectorData<unsigned long>&>(*this); 00689 for (int j = 0; j < range; ++j) 00690 { 00691 if (!isRead()) col.readRow(j + first,&nullVal); 00692 FITSUtil::fill(vals[j],col.data(j+first)); 00693 } 00694 } 00695 else 00696 { 00697 throw InvalidDataType(name()); 00698 } 00699 00700 } 00701 catch (std::bad_cast) 00702 { 00703 throw WrongColumnType(name()); 00704 00705 } 00706 00707 } 00708 } 00709 00710 template <typename S> 00711 void Column::write (const std::vector<S>& indata, long firstRow) 00712 { 00713 // nullValue is now a pointer, so this is ok. 00714 // got to cast the 0 to a pointer to S to avoid 00715 // overloading ambiguities. 00716 write(indata,firstRow,static_cast<S*>(0)); 00717 } 00718 00719 template <typename S> 00720 void Column::write (const std::valarray<S>& indata, long firstRow) 00721 { 00722 size_t n(indata.size()); 00723 std::vector<S> __tmp(n); 00724 for (size_t j = 0; j < n; ++j) __tmp[j] = indata[j]; 00725 write(__tmp,firstRow,static_cast<S*>(0)); 00726 } 00727 00728 template <typename S> 00729 void Column::write (S* indata, long nRows, long firstRow) 00730 { 00731 write(indata,nRows,firstRow,static_cast<S*>(0)); 00732 } 00733 00734 00735 template <typename S> 00736 void Column::write (const std::vector<S>& indata, long firstRow, S* nullValue) 00737 { 00738 // although underlying code needs to convert the input vector 00739 // into a C array, this must be the underlying implementation 00740 // [which the others call] because it accepts string arguments 00741 // which the version with a pointer won't. [no version that 00742 // translates to a char** argument]. 00743 00744 00745 parent()->makeThisCurrent(); 00746 firstRow = std::max(firstRow,static_cast<long>(1)); 00747 if (ColumnData<S>* col = dynamic_cast<ColumnData<S>*>(this)) 00748 { 00749 col->writeData(indata,firstRow,nullValue); 00750 } 00751 else 00752 { 00753 // alright, input data type has to be rewritten as output 00754 // data type. 00755 FITSUtil::MatchType<S> inType; 00756 if ( inType() == type()) 00757 { 00758 String msg("Incorrect call: writing to vector column "); 00759 msg += name(); 00760 msg += " requires specification of # rows or vector lengths"; 00761 throw WrongColumnType(msg); 00762 } 00763 else 00764 { 00765 if ( type() == Tdouble ) 00766 { 00767 ColumnData<double>& col 00768 = dynamic_cast<ColumnData<double>&>(*this); 00769 std::vector<double> __tmp; 00770 FITSUtil::fill(__tmp,indata,1,indata.size()); 00771 col.writeData(__tmp,firstRow); 00772 } 00773 else if ( type() == Tfloat ) 00774 { 00775 ColumnData<float>& col 00776 = dynamic_cast<ColumnData<float>&>(*this); 00777 std::vector<float> __tmp; 00778 FITSUtil::fill(__tmp,indata,1,indata.size()); 00779 col.writeData(__tmp,firstRow); 00780 } 00781 else if ( type() == Tint ) 00782 { 00783 int nullVal = 0; 00784 int* pNullVal = 0; 00785 if (nullValue) 00786 { 00787 nullVal = static_cast<int>(*nullValue); 00788 pNullVal = &nullVal; 00789 } 00790 if (nullValue) nullVal = static_cast<int>(*nullValue); 00791 ColumnData<int>& col 00792 = dynamic_cast<ColumnData<int>&>(*this); 00793 std::vector<int> __tmp; 00794 FITSUtil::fill(__tmp,indata,1,indata.size()); 00795 col.writeData(__tmp,firstRow,pNullVal); 00796 } 00797 else if ( type() == Tshort ) 00798 { 00799 short nullVal(0); 00800 short* pNullVal = 0; 00801 if (nullValue) 00802 { 00803 nullVal = static_cast<short>(*nullValue); 00804 pNullVal = &nullVal; 00805 } 00806 ColumnData<short>& col 00807 = dynamic_cast<ColumnData<short>&>(*this); 00808 std::vector<short> __tmp; 00809 FITSUtil::fill(__tmp,indata,1,indata.size()); 00810 col.writeData(__tmp,firstRow,pNullVal); 00811 } 00812 else if ( type() == Tlong ) 00813 { 00814 long nullVal(0); 00815 long* pNullVal = 0; 00816 if (nullValue) 00817 { 00818 nullVal = static_cast<long>(*nullValue); 00819 pNullVal = &nullVal; 00820 } 00821 ColumnData<long>& col 00822 = dynamic_cast<ColumnData<long>&>(*this); 00823 std::vector<long> __tmp; 00824 FITSUtil::fill(__tmp,indata,1,indata.size()); 00825 col.writeData(__tmp,firstRow,pNullVal); 00826 } 00827 else if ( type() == Tlonglong ) 00828 { 00829 LONGLONG nullVal(0); 00830 LONGLONG* pNullVal = 0; 00831 if (nullValue) 00832 { 00833 nullVal = static_cast<LONGLONG>(*nullValue); 00834 pNullVal = &nullVal; 00835 } 00836 ColumnData<LONGLONG>& col 00837 = dynamic_cast<ColumnData<LONGLONG>&>(*this); 00838 std::vector<LONGLONG> __tmp; 00839 FITSUtil::fill(__tmp,indata,1,indata.size()); 00840 col.writeData(__tmp,firstRow,pNullVal); 00841 } 00842 else if ( type() == Tlogical ) 00843 { 00844 bool nullVal(0); 00845 bool* pNullVal = 0; 00846 if (nullValue) 00847 { 00848 nullVal = static_cast<bool>(*nullValue); 00849 pNullVal = &nullVal; 00850 } 00851 ColumnData<bool>& col 00852 = dynamic_cast<ColumnData<bool>&>(*this); 00853 std::vector<bool> __tmp; 00854 FITSUtil::fill(__tmp,indata,1,indata.size()); 00855 col.writeData(__tmp,firstRow,pNullVal); 00856 } 00857 else if ( type() == Tbyte ) 00858 { 00859 unsigned char nullVal(0); 00860 unsigned char* pNullVal = 0; 00861 if (nullValue) 00862 { 00863 nullVal = static_cast<unsigned char>(*nullValue); 00864 pNullVal = &nullVal; 00865 } 00866 ColumnData<unsigned char>& col 00867 = dynamic_cast<ColumnData<unsigned char>&>(*this); 00868 std::vector<unsigned char> __tmp; 00869 FITSUtil::fill(__tmp,indata,1,indata.size()); 00870 col.writeData(__tmp,firstRow,pNullVal); 00871 } 00872 else if ( type() == Tushort ) 00873 { 00874 unsigned short nullVal(0); 00875 unsigned short* pNullVal = 0; 00876 if (nullValue) 00877 { 00878 nullVal = static_cast<unsigned short>(*nullValue); 00879 pNullVal = &nullVal; 00880 } 00881 ColumnData<unsigned short>& col 00882 = dynamic_cast<ColumnData<unsigned short>&>(*this); 00883 std::vector<unsigned short> __tmp; 00884 FITSUtil::fill(__tmp,indata,1,indata.size()); 00885 col.writeData(__tmp,firstRow,pNullVal); 00886 } 00887 else if ( type() == Tuint ) 00888 { 00889 unsigned int nullVal(0); 00890 unsigned int* pNullVal = 0; 00891 if (nullValue) 00892 { 00893 nullVal = static_cast<unsigned int>(*nullValue); 00894 pNullVal = &nullVal; 00895 } 00896 ColumnData<unsigned int>& col 00897 = dynamic_cast<ColumnData<unsigned int>&>(*this); 00898 std::vector<unsigned int> __tmp; 00899 FITSUtil::fill(__tmp,indata,1,indata.size()); 00900 col.writeData(__tmp,firstRow,pNullVal); 00901 } 00902 else if ( type() == Tulong ) 00903 { 00904 unsigned long nullVal(0); 00905 unsigned long* pNullVal = 0; 00906 if (nullValue) 00907 { 00908 nullVal = static_cast<unsigned long>(*nullValue); 00909 pNullVal = &nullVal; 00910 } 00911 ColumnData<unsigned long>& col 00912 = dynamic_cast<ColumnData<unsigned long>&>(*this); 00913 std::vector<unsigned long> __tmp; 00914 FITSUtil::fill(__tmp,indata,1,indata.size()); 00915 col.writeData(__tmp,firstRow,pNullVal); 00916 } 00917 else 00918 { 00919 throw InvalidDataType(name()); 00920 } 00921 } 00922 } 00923 } 00924 00925 00926 template <typename S> 00927 void Column::write (const std::valarray<S>& indata, long firstRow, S* nullValue) 00928 { 00929 // for scalar columns. 00930 std::vector<S> __tmp; 00931 FITSUtil::fill(__tmp,indata); 00932 write(__tmp,firstRow,nullValue); 00933 } 00934 00935 template <typename S> 00936 void Column::write (S* indata, long nRows, long firstRow, S* nullValue) 00937 { 00938 // for scalar columns, data specified with C array 00939 if (nRows <= 0) throw InvalidNumberOfRows(nRows); 00940 std::vector<S> __tmp(nRows); 00941 std::copy(&indata[0],&indata[nRows],__tmp.begin()); 00942 write(__tmp,firstRow, nullValue); 00943 00944 } 00945 00946 template <typename S> 00947 void Column::write (const std::valarray<S>& indata, const std::vector<long>& vectorLengths, 00948 long firstRow) 00949 { 00950 // variable length arrays written from an input valarray. 00951 // does not allow NULL value. 00952 00953 using namespace std; 00954 const size_t nRows = vectorLengths.size(); 00955 // Calculate the sums of the vector lengths first simply to do a 00956 // check against the size of indata. 00957 vector<long> sums(nRows+1); 00958 sums[0] = 0; 00959 vector<long>::iterator itSums = sums.begin() + 1; 00960 partial_sum(vectorLengths.begin(), vectorLengths.end(), itSums); 00961 if (indata.size() < static_cast<size_t>(sums[nRows])) 00962 { 00963 #ifdef SSTREAM_DEFECT 00964 ostrstream msgStr; 00965 #else 00966 ostringstream msgStr; 00967 #endif 00968 msgStr << " input data size: " << indata.size() << " vector length sum: " << sums[nRows]; 00969 #ifdef SSTREAM_DEFECT 00970 msgStr << std::ends; 00971 #endif 00972 00973 String msg(msgStr.str()); 00974 throw Column::InsufficientElements(msg); 00975 } 00976 vector<valarray<S> > vvArray(nRows); 00977 for (size_t iRow=0; iRow<nRows; ++iRow) 00978 { 00979 valarray<S>& vArray = vvArray[iRow]; 00980 long first = sums[iRow]; 00981 long last = sums[iRow+1]; 00982 vArray.resize(last - first); 00983 for (long iElem=first; iElem<last; ++iElem) 00984 { 00985 vArray[iElem - first] = indata[iElem]; 00986 } 00987 } 00988 writeArrays(vvArray, firstRow, static_cast<S*>(0)); 00989 } 00990 00991 template <typename S> 00992 void Column::write (const std::vector<S>& indata,const std::vector<long>& vectorLengths, 00993 long firstRow) 00994 { 00995 // variable length write 00996 // implement as valarray version 00997 std::valarray<S> __tmp(indata.size()); 00998 std::copy(indata.begin(),indata.end(),&__tmp[0]); 00999 write(__tmp,vectorLengths,firstRow); 01000 01001 } 01002 01003 template <typename S> 01004 void Column::write (S* indata, long nelements, const std::vector<long>& vectorLengths, 01005 long firstRow) 01006 { 01007 // implement as valarray version, which will also check array size. 01008 size_t n(vectorLengths.size()); 01009 std::valarray<S> __tmp(indata,nelements); 01010 write(__tmp,vectorLengths,firstRow); 01011 } 01012 01013 template <typename S> 01014 void Column::write (const std::valarray<S>& indata, long nRows, long firstRow) 01015 { 01016 write(indata,nRows,firstRow,static_cast<S*>(0)); 01017 } 01018 01019 template <typename S> 01020 void Column::write (const std::vector<S>& indata, long nRows, long firstRow) 01021 { 01022 write(indata,nRows,firstRow,static_cast<S*>(0)); 01023 } 01024 01025 template <typename S> 01026 void Column::write (S* indata, long nelements, long nRows, long firstRow) 01027 { 01028 write(indata,nelements,nRows,firstRow,static_cast<S*>(0)); 01029 } 01030 01031 01032 01033 template <typename S> 01034 void Column::write (const std::valarray<S>& indata, long nRows, long firstRow, 01035 S* nullValue) 01036 { 01037 // Write equivalent lengths of data to rows of a vector column. 01038 // The column may be either fixed or variable width, but if it's fixed 01039 // width the lengths must equal the column's repeat value or an 01040 // exception is thrown. 01041 if (nRows <= 0) 01042 throw InvalidNumberOfRows(nRows); 01043 firstRow = std::max(firstRow,static_cast<long>(1)); 01044 #ifdef SSTREAM_DEFECT 01045 std::ostrstream msgStr; 01046 #else 01047 std::ostringstream msgStr; 01048 #endif 01049 const size_t numRows = static_cast<size_t>(nRows); 01050 if (indata.size() % numRows) 01051 { 01052 msgStr << "To use this write function, input array size" 01053 <<"\n must be exactly divisible by requested num rows: " 01054 << nRows; 01055 throw InsufficientElements(msgStr.str()); 01056 } 01057 01058 const size_t cellsize = indata.size()/numRows; 01059 if (!varLength() && cellsize != repeat() ) 01060 { 01061 msgStr << "column: " << name() 01062 << "\n input data size: " << indata.size() 01063 << " required: " << nRows*repeat(); 01064 String msg(msgStr.str()); 01065 throw InsufficientElements(msg); 01066 } 01067 01068 std::vector<std::valarray<S> > vvArray(numRows); 01069 for (size_t i=0; i<numRows; ++i) 01070 { 01071 vvArray[i].resize(cellsize); 01072 vvArray[i] = indata[std::slice(cellsize*i,cellsize,1)]; 01073 } 01074 writeArrays(vvArray, firstRow, nullValue); 01075 } 01076 01077 template <typename S> 01078 void Column::write (const std::vector<S>& indata, long nRows, long firstRow, S* nullValue) 01079 { 01080 // fixed length write of vector 01081 // implement as valarray version 01082 if (nRows <= 0) throw InvalidNumberOfRows(nRows); 01083 std::valarray<S> __tmp(indata.size()); 01084 std::copy(indata.begin(),indata.end(),&__tmp[0]); 01085 write(__tmp,nRows,firstRow, nullValue); 01086 } 01087 01088 template <typename S> 01089 void Column::write (S* indata, long nelements, long nRows, long firstRow, S* nullValue) 01090 { 01091 // fixed length write of C-array 01092 // implement as valarray version 01093 if (nRows <= 0) throw InvalidNumberOfRows(nRows); 01094 std::valarray<S> __tmp(indata,nelements); 01095 write(__tmp,nRows,firstRow, nullValue); 01096 } 01097 01098 01099 template <typename S> 01100 void Column::writeArrays (const std::vector<std::valarray<S> >& indata, long firstRow) 01101 { 01102 // vector<valarray>, no null value. 01103 writeArrays(indata,firstRow,static_cast<S*>(0)); 01104 } 01105 01106 template <typename S> 01107 void Column::writeArrays (const std::vector<std::valarray<S> >& indata, long firstRow, 01108 S* nullValue) 01109 { 01110 // vector<valarray>, null value. primary 01111 01112 01113 using std::valarray; 01114 using std::vector; 01115 parent()->makeThisCurrent(); 01116 firstRow = std::max(firstRow,static_cast<long>(1)); 01117 if (ColumnVectorData<S>* col = dynamic_cast<ColumnVectorData<S>*>(this)) 01118 { 01119 col->writeData(indata,firstRow,nullValue); 01120 } 01121 else 01122 { 01123 // alright, input data type has to be rewritten as output 01124 // data type. 01125 FITSUtil::MatchType<S> inType; 01126 if ( inType() == type()) 01127 { 01128 String msg("Incorrect call: writing vectors to scalar column "); 01129 throw WrongColumnType(msg); 01130 } 01131 else 01132 { 01133 size_t n(indata.size()); 01134 if ( type() == Tdouble || type() == VTdouble) 01135 { 01136 ColumnVectorData<double>& col 01137 = dynamic_cast<ColumnVectorData<double>&>(*this); 01138 vector<valarray<double> > __tmp(n); 01139 for (size_t i = 0; i < n; ++i) 01140 { 01141 FITSUtil::fill(__tmp[i],indata[i]); 01142 } 01143 col.writeData(__tmp,firstRow); 01144 } 01145 else if ( type() == Tfloat || type() == VTfloat) 01146 { 01147 ColumnVectorData<float>& col 01148 = dynamic_cast<ColumnVectorData<float>&>(*this); 01149 vector<valarray<float> > __tmp(n); 01150 for (size_t i = 0; i < n; ++i) 01151 { 01152 FITSUtil::fill(__tmp[i],indata[i]); 01153 } 01154 col.writeData(__tmp,firstRow); 01155 } 01156 else if ( type() == Tint || type() == VTint) 01157 { 01158 ColumnVectorData<int>& col 01159 = dynamic_cast<ColumnVectorData<int>&>(*this); 01160 vector<valarray<int> > __tmp(n); 01161 int nullVal(0); 01162 int* pNullVal = 0; 01163 if (nullValue) 01164 { 01165 nullVal = static_cast<int>(*nullValue); 01166 pNullVal = &nullVal; 01167 } 01168 for (size_t i = 0; i < n; ++i) 01169 { 01170 FITSUtil::fill(__tmp[i],indata[i]); 01171 } 01172 col.writeData(__tmp,firstRow,pNullVal); 01173 } 01174 else if ( type() == Tshort || type() == VTshort) 01175 { 01176 ColumnVectorData<short>& col 01177 = dynamic_cast<ColumnVectorData<short>&>(*this); 01178 vector<valarray<short> > __tmp(n); 01179 short nullVal(0); 01180 short* pNullVal = 0; 01181 if (nullValue) 01182 { 01183 nullVal = static_cast<short>(*nullValue); 01184 pNullVal = &nullVal; 01185 } 01186 for (size_t i = 0; i < n; ++i) 01187 { 01188 FITSUtil::fill(__tmp[i],indata[i]); 01189 } 01190 col.writeData(__tmp,firstRow,pNullVal); 01191 } 01192 else if ( type() == Tlong || type() == VTlong) 01193 { 01194 ColumnVectorData<long>& col 01195 = dynamic_cast<ColumnVectorData<long>&>(*this); 01196 vector<valarray<long> > __tmp(n); 01197 long nullVal(0); 01198 long* pNullVal = 0; 01199 if (nullValue) 01200 { 01201 nullVal = static_cast<long>(*nullValue); 01202 pNullVal = &nullVal; 01203 } 01204 for (size_t i = 0; i < n; ++i) 01205 { 01206 FITSUtil::fill(__tmp[i],indata[i]); 01207 } 01208 col.writeData(__tmp,firstRow,pNullVal); 01209 } 01210 else if ( type() == Tlonglong || type() == VTlonglong) 01211 { 01212 ColumnVectorData<LONGLONG>& col 01213 = dynamic_cast<ColumnVectorData<LONGLONG>&>(*this); 01214 vector<valarray<LONGLONG> > __tmp(n); 01215 LONGLONG nullVal(0); 01216 LONGLONG* pNullVal = 0; 01217 if (nullValue) 01218 { 01219 nullVal = static_cast<LONGLONG>(*nullValue); 01220 pNullVal = &nullVal; 01221 } 01222 for (size_t i = 0; i < n; ++i) 01223 { 01224 FITSUtil::fill(__tmp[i],indata[i]); 01225 } 01226 col.writeData(__tmp,firstRow,pNullVal); 01227 } 01228 else if ( type() == Tlogical || type() == VTlogical) 01229 { 01230 ColumnVectorData<bool>& col 01231 = dynamic_cast<ColumnVectorData<bool>&>(*this); 01232 bool nullVal(0); 01233 bool* pNullVal = 0; 01234 if (nullValue) 01235 { 01236 nullVal = static_cast<bool>(*nullValue); 01237 pNullVal = &nullVal; 01238 } 01239 vector<valarray<bool> > __tmp(n); 01240 for (size_t i = 0; i < n; ++i) 01241 { 01242 FITSUtil::fill(__tmp[i],indata[i]); 01243 } 01244 col.writeData(__tmp,firstRow,pNullVal); 01245 } 01246 else if ( type() == Tbyte || type() == VTbyte) 01247 { 01248 ColumnVectorData<unsigned char>& col 01249 = dynamic_cast<ColumnVectorData<unsigned char>&>(*this); 01250 unsigned char nullVal(0); 01251 unsigned char* pNullVal = 0; 01252 if (nullValue) 01253 { 01254 nullVal = static_cast<unsigned char>(*nullValue); 01255 pNullVal = &nullVal; 01256 } 01257 vector<valarray<unsigned char> > __tmp(n); 01258 for (size_t i = 0; i < n; ++i) 01259 { 01260 FITSUtil::fill(__tmp[i],indata[i]); 01261 } 01262 col.writeData(__tmp,firstRow,&nullVal); 01263 } 01264 else if ( type() == Tushort || type() == VTushort) 01265 { 01266 ColumnVectorData<unsigned short>& col 01267 = dynamic_cast<ColumnVectorData<unsigned short>&>(*this); 01268 unsigned short nullVal(0); 01269 unsigned short* pNullVal = 0; 01270 if (nullValue) 01271 { 01272 nullVal = static_cast<unsigned short>(*nullValue); 01273 pNullVal = &nullVal; 01274 } 01275 vector<valarray<unsigned short> > __tmp(n); 01276 for (size_t i = 0; i < n; ++i) 01277 { 01278 FITSUtil::fill(__tmp[i],indata[i]); 01279 } 01280 col.writeData(__tmp,firstRow,pNullVal); 01281 } 01282 else if ( type() == Tuint || type() == VTuint) 01283 { 01284 ColumnVectorData<unsigned int>& col 01285 = dynamic_cast<ColumnVectorData<unsigned int>&>(*this); 01286 unsigned int nullVal(0); 01287 unsigned int* pNullVal = 0; 01288 if (nullValue) 01289 { 01290 nullVal = static_cast<unsigned int>(*nullValue); 01291 pNullVal = &nullVal; 01292 } 01293 vector<valarray<unsigned int> > __tmp(n); 01294 for (size_t i = 0; i < n; ++i) 01295 { 01296 FITSUtil::fill(__tmp[i],indata[i]); 01297 } 01298 col.writeData(__tmp,firstRow,pNullVal); 01299 } 01300 else if ( type() == Tulong || type() == VTulong) 01301 { 01302 ColumnVectorData<unsigned long>& col 01303 = dynamic_cast<ColumnVectorData<unsigned long>&>(*this); 01304 unsigned long nullVal(0); 01305 unsigned long* pNullVal = 0; 01306 if (nullValue) 01307 { 01308 nullVal = static_cast<unsigned long>(*nullValue); 01309 pNullVal = &nullVal; 01310 } 01311 vector<valarray<unsigned long> > __tmp(n); 01312 for (size_t i = 0; i < n; ++i) 01313 { 01314 FITSUtil::fill(__tmp[i],indata[i]); 01315 } 01316 col.writeData(__tmp,firstRow,pNullVal); 01317 } 01318 else 01319 { 01320 throw InvalidDataType(name()); 01321 } 01322 } 01323 } 01324 } 01325 01326 01327 template <typename T> 01328 void Column::addNullValue(T nullVal) 01329 { 01330 parent()->makeThisCurrent(); 01331 int status(0); 01332 #ifdef SSTREAM_DEFECT 01333 std::ostrstream keyName; 01334 keyName << "TNULL" << index() << std::ends; 01335 char* nullKey = const_cast<char*>(keyName.str()); 01336 #else 01337 std::ostringstream keyName; 01338 keyName << "TNULL" << index(); 01339 String keyNameStr = keyName.str(); 01340 char* nullKey = const_cast<char*>(keyNameStr.c_str()); 01341 #endif 01342 01343 01344 FITSUtil::MatchType<T> inputType; 01345 int dataType = static_cast<int>(inputType()); 01346 if (dataType == static_cast<int>(Tstring)) 01347 throw InvalidDataType("attempting to set TNULLn to a string."); 01348 01349 // update key but don't add to keyword list because it's really a column 01350 // property not a table metadata property. And it needs to be automatically 01351 // renumbered if columns are inserted or deleted. 01352 if (fits_update_key(fitsPointer(),dataType,nullKey,&nullVal,0,&status)) 01353 throw FitsError(status); 01354 01355 // The following is called to make sure the HDU struct is immediately 01356 // updated in case a column write operation is performed shortly after this 01357 // function exits. 01358 if (fits_set_hdustruc(fitsPointer(),&status)) throw FitsError(status); 01359 01360 } 01361 01362 template <typename T> 01363 bool Column::getNullValue(T* nullVal) const 01364 { 01365 parent()->makeThisCurrent(); 01366 #ifdef SSTREAM_DEFECT 01367 std::ostrstream keyName; 01368 keyName << "TNULL" << index() << std::ends; 01369 char* nullKey = const_cast<char*>(keyName.str()); 01370 #else 01371 std::ostringstream keyName; 01372 keyName << "TNULL" << index(); 01373 String keyNameStr = keyName.str(); 01374 char* nullKey = const_cast<char*>(keyNameStr.c_str()); 01375 #endif 01376 01377 int status=0; 01378 FITSUtil::MatchType<T> inputType; 01379 int dataType = static_cast<int>(inputType()); 01380 if (dataType == static_cast<int>(Tstring)) 01381 throw InvalidDataType("attempting to read TNULLn into a string."); 01382 T tmpVal(*nullVal); 01383 01384 bool keyExists = false; 01385 if (fits_read_key(m_parent->fitsPointer(), dataType, nullKey, &tmpVal, 0, &status)) 01386 { 01387 if (status == KEY_NO_EXIST || status == VALUE_UNDEFINED) 01388 return keyExists; 01389 else 01390 throw FitsError(status); 01391 } 01392 keyExists = true; 01393 *nullVal = tmpVal; 01394 return keyExists; 01395 } 01396 01397 } // namespace CCfits 01398 01399 #endif