Bug Summary

File:src/fits/GFitsHeaderCard.cpp
Location:line 868, column 13
Description:Attempt to free released memory

Annotated Source Code

1/***************************************************************************
2 * GFitsHeaderCard.cpp - FITS header card class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2008-2013 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program 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, see <http://www.gnu.org/licenses/>. *
19 * *
20 ***************************************************************************/
21/**
22 * @file GFitsHeaderCard.cpp
23 * @brief FITS header card class implementation
24 * @author Juergen Knoedlseder
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H1
29#include <config.h>
30#endif
31#include <cfloat>
32#include <climits>
33#include "GException.hpp"
34#include "GTools.hpp"
35#include "GFitsCfitsio.hpp"
36#include "GFits.hpp"
37#include "GFitsHeaderCard.hpp"
38
39/* __ Method name definitions ____________________________________________ */
40#define G_COPY_DTYPE"GFitsHeaderCard::copy_dtype(GFitsHeaderCard&)" "GFitsHeaderCard::copy_dtype(GFitsHeaderCard&)"
41#define G_FREE_DTYPE"GFitsHeaderCard::free_dtype()" "GFitsHeaderCard::free_dtype()"
42#define G_SET_DTYPE"GFitsHeaderCard::set_dtype(std::string&)" "GFitsHeaderCard::set_dtype(std::string&)"
43#define G_READ_NUM"GFitsHeaderCard::read(void*, int&)" "GFitsHeaderCard::read(void*, int&)"
44#define G_READ_STR"GFitsHeaderCard::read(void*, std::string&)" "GFitsHeaderCard::read(void*, std::string&)"
45#define G_WRITE"GFitsHeaderCard::write(void*)" "GFitsHeaderCard::write(void*)"
46
47/* __ Definitions ________________________________________________________ */
48
49/* __ Macros _____________________________________________________________ */
50
51/* __ Coding definitions _________________________________________________ */
52
53/* __ Enumerations _______________________________________________________ */
54
55/* __ Debug definitions __________________________________________________ */
56
57
58/*==========================================================================
59 = =
60 = Constructors/destructors =
61 = =
62 ==========================================================================*/
63
64/***********************************************************************//**
65 * @brief Void constructor
66 ***************************************************************************/
67GFitsHeaderCard::GFitsHeaderCard(void)
68{
69 // Initialise class members
70 init_members();
71
72 // Return
73 return;
74}
75
76
77/***********************************************************************//**
78 * @brief Constructor for string cards
79 *
80 * @param[in] keyname Card name.
81 * @param[in] value Card string value.
82 * @param[in] comment Card comment.
83 *
84 * This constructor builds a header card from the keyname, value and comment.
85 ***************************************************************************/
86GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
87 const std::string& value,
88 const std::string& comment)
89{
90 // Initialise class members
91 init_members();
92
93 // Set members
94 this->keyname(keyname);
95 this->value("'"+value+"'");
96 this->comment(comment);
97
98 // Return
99 return;
100}
101
102
103/***********************************************************************//**
104 * @brief Constructor for floating point cards
105 *
106 * @param[in] keyname Card name.
107 * @param[in] value Card floating point value.
108 * @param[in] comment Card comment.
109 *
110 * This constructor builds a header card from the keyname, value and comment.
111 ***************************************************************************/
112GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
113 const double& value,
114 const std::string& comment)
115{
116 // Initialise class members
117 init_members();
118
119 // Set members
120 this->keyname(keyname);
121 this->value(value);
122 this->comment(comment);
123
124 // Return
125 return;
126}
127
128
129/***********************************************************************//**
130 * @brief Constructor for integer cards
131 *
132 * @param[in] keyname Card name.
133 * @param[in] value Card integer value.
134 * @param[in] comment Card comment.
135 *
136 * This constructor builds a header card from the keyname, value and comment.
137 ***************************************************************************/
138GFitsHeaderCard::GFitsHeaderCard(const std::string& keyname,
139 const int& value,
140 const std::string& comment)
141{
142 // Initialise class members
143 init_members();
144
145 // Set members
146 this->keyname(keyname);
147 this->value(value);
148 this->comment(comment);
149
150 // Return
151 return;
152}
153
154
155/***********************************************************************//**
156 * @brief Copy constructor
157 *
158 * @param[in] card Header card.
159 ***************************************************************************/
160GFitsHeaderCard::GFitsHeaderCard(const GFitsHeaderCard& card)
161{
162 // Initialise class members for clean destruction
163 init_members();
164
165 // Copy members
166 copy_members(card);
167
168 // Return
169 return;
170}
171
172
173/***********************************************************************//**
174 * @brief Destructor
175 ***************************************************************************/
176GFitsHeaderCard::~GFitsHeaderCard(void)
177{
178 // Free members
179 free_members();
180
181 // Return
182 return;
183}
184
185/*==========================================================================
186 = =
187 = Operators =
188 = =
189 ==========================================================================*/
190
191/***********************************************************************//**
192 * @brief Assignment operator
193 *
194 * @param[in] card Header card.
195 * @return Header card.
196 ***************************************************************************/
197GFitsHeaderCard& GFitsHeaderCard::operator=(const GFitsHeaderCard& card)
198{
199 // Execute only if object is not identical
200 if (this != &card) {
201
202 // Free members
203 free_members();
204
205 // Initialise private members for clean destruction
206 init_members();
207
208 // Copy members
209 copy_members(card);
210
211 } // endif: object was not identical
212
213 // Return this object
214 return *this;
215}
216
217
218/*==========================================================================
219 = =
220 = Public methods =
221 = =
222 ==========================================================================*/
223
224/***********************************************************************//**
225 * @brief Clear header card
226 ***************************************************************************/
227void GFitsHeaderCard::clear(void)
228{
229 // Free members
230 free_members();
231
232 // Initialise members
233 init_members();
234
235 // Return
236 return;
237}
238
239
240/***********************************************************************//**
241 * @brief Clone header card
242 *
243 * @return Pointer to deep copy of header card.
244 ***************************************************************************/
245GFitsHeaderCard* GFitsHeaderCard::clone(void) const
246{
247 return new GFitsHeaderCard(*this);
248}
249
250
251/***********************************************************************//**
252 * @brief Set name of header card
253 *
254 * @param[in] keyname Card name.
255 ***************************************************************************/
256void GFitsHeaderCard::keyname(const std::string& keyname)
257{
258 // Set name of card
259 m_keyname = keyname;
260
261 // Return
262 return;
263}
264
265
266/***********************************************************************//**
267 * @brief Set string value of header card
268 *
269 * @param[in] value Card string value.
270 *
271 * This method sets the value of a string header card. The internal string
272 * representation contains hyphens, yet for keyword writing the hyphens are
273 * stripped.
274 ***************************************************************************/
275void GFitsHeaderCard::value(const std::string& value)
276{
277 // Free data type
278 free_dtype();
16
Calling 'GFitsHeaderCard::free_dtype'
279
280 // Set value
281 m_value = value;
282
283 // Attach hyphens to internal string representation if required
284 if (m_value[0] != '\x27') {
285 m_value = "'" + m_value;
286 }
287 if (m_value[m_value.length()-1] != '\x27') {
288 m_value = m_value + "'";
289 }
290
291 // Strip hyphens and whitespace from datatype value that is used for
292 // keyword writing
293 std::string value_dtype =
294 gammalib::strip_whitespace(m_value.substr(1, m_value.length() - 2));
295
296 // Set data type
297 m_dtype = __TSTRING16;
298 m_value_dtype = new std::string(value_dtype);
299
300 // Return
301 return;
302}
303
304
305/***********************************************************************//**
306 * @brief Set boolean value of header card
307 *
308 * @param[in] value Card boolean value.
309 ***************************************************************************/
310void GFitsHeaderCard::value(const bool& value)
311{
312 // Free data type
313 free_dtype();
314
315 // Set value and data type
316 m_value = (value) ? "T" : "F";
317 m_dtype = __TLOGICAL14;
318 m_value_dtype = new bool(value);
319
320 // Return
321 return;
322}
323
324
325/***********************************************************************//**
326 * @brief Set single precision value of header card
327 *
328 * @param[in] value Card single precision value.
329 ***************************************************************************/
330void GFitsHeaderCard::value(const float& value)
331{
332 // Free data type
333 free_dtype();
334
335 // Set value and data type
336 m_value = gammalib::str(value);
337 m_dtype = __TFLOAT42;
338 m_value_dtype = new float(value);
339
340 // Return
341 return;
342}
343
344
345/***********************************************************************//**
346 * @brief Set double precision value of header card
347 *
348 * @param[in] value Card double precision value.
349 ***************************************************************************/
350void GFitsHeaderCard::value(const double& value)
351{
352 // Free data type
353 free_dtype();
354
355 // Set value and data type
356 m_value = gammalib::str(value);
357 m_dtype = __TDOUBLE82;
358 m_value_dtype = new double(value);
359
360 // Return
361 return;
362}
363
364
365/***********************************************************************//**
366 * @brief Set unsigned short integer value of header card
367 *
368 * @param[in] value Card unsigned short integer value.
369 ***************************************************************************/
370void GFitsHeaderCard::value(const unsigned short& value)
371{
372 // Free data type
373 free_dtype();
374
375 // Set value and data type
376 m_value = gammalib::str(value);
377 m_dtype = __TUSHORT20;
378 m_value_dtype = new unsigned short(value);
379
380 // Return
381 return;
382}
383
384
385/***********************************************************************//**
386 * @brief Set short integer value of header card
387 *
388 * @param[in] value Card short integer value.
389 ***************************************************************************/
390void GFitsHeaderCard::value(const short& value)
391{
392 // Free data type
393 free_dtype();
394
395 // Set value and data type
396 m_value = gammalib::str(value);
397 m_dtype = __TSHORT21;
398 m_value_dtype = new short(value);
399
400 // Return
401 return;
402}
403
404
405/***********************************************************************//**
406 * @brief Set unsigned integer value of header card
407 *
408 * @param[in] value Card unsigned integer value.
409 ***************************************************************************/
410void GFitsHeaderCard::value(const unsigned int& value)
411{
412 // Free data type
413 free_dtype();
414
415 // Set value and data type
416 m_value = gammalib::str(value);
417 m_dtype = __TUINT30;
418 m_value_dtype = new unsigned int(value);
419
420 // Return
421 return;
422}
423
424
425/***********************************************************************//**
426 * @brief Set integer value of header card
427 *
428 * @param[in] value Card integer value.
429 ***************************************************************************/
430void GFitsHeaderCard::value(const int& value)
431{
432 // Free data type
433 free_dtype();
434
435 // Set value and data type
436 m_value = gammalib::str(value);
437 m_dtype = __TINT31;
438 m_value_dtype = new int(value);
439
440 // Return
441 return;
442}
443
444
445/***********************************************************************//**
446 * @brief Set long integer value of header card
447 *
448 * @param[in] value Card long integer value.
449 ***************************************************************************/
450void GFitsHeaderCard::value(const long& value)
451{
452 // Free data type
453 free_dtype();
454
455 // Set value and data type
456 m_value = gammalib::str(value);
457 m_dtype = __TLONG41;
458 m_value_dtype = new long(value);
459
460 // Return
461 return;
462}
463
464
465/***********************************************************************//**
466 * @brief Set unsigned integer long value of header card
467 *
468 * @param[in] value Card unsigned long integer value.
469 ***************************************************************************/
470void GFitsHeaderCard::value(const unsigned long& value)
471{
472 // Free data type
473 free_dtype();
474
475 // Set value and data type
476 m_value = gammalib::str(value);
477 m_dtype = __TULONG40;
478 m_value_dtype = new unsigned long(value);
479
480 // Return
481 return;
482}
483
484
485/***********************************************************************//**
486 * @brief Set long long integer value of header card
487 *
488 * @param[in] value Card long long integer value.
489 ***************************************************************************/
490void GFitsHeaderCard::value(const long long& value)
491{
492 // Free data type
493 free_dtype();
494
495 // Set value and data type
496 m_value = gammalib::str(value);
497 m_dtype = __TLONGLONG81;
498 m_value_dtype = new long long(value);
499
500 // Return
501 return;
502}
503
504
505/***********************************************************************//**
506 * @brief Return header card value as string
507 *
508 * Convert header card value into a string.
509 * Any hyphens that may occur in the FITS card will be automatically stripped.
510 ***************************************************************************/
511std::string GFitsHeaderCard::string(void) const
512{
513 // Initialize return value to actual value string
514 std::string result = m_value;
515
516 // Type dependent conversion
517 if (m_value_dtype != NULL__null) {
518 switch (m_dtype) {
519 case __TSTRING16:
520 if (m_value.length() > 2) {
521 result = gammalib::strip_whitespace(m_value.substr(1, m_value.length() - 2));
522 }
523 break;
524 default:
525 break;
526 }
527 }
528
529 // Return string
530 return result;
531
532}
533
534
535/***********************************************************************//**
536 * @brief Return header card value as double precision
537 *
538 * Convert header card value into a double precision value. In case that the
539 * card did not contain a numerical value, 0 will be returned by the
540 * method.
541 ***************************************************************************/
542double GFitsHeaderCard::real(void) const
543{
544 // Initialize return value to 0.0
545 double result = 0.0;
546
547 // Type dependent conversion
548 if (m_value_dtype != NULL__null) {
549 switch (m_dtype) {
550 case __TSTRING16:
551 if (m_value.length() > 2) {
552 result = gammalib::todouble(m_value.substr(1, m_value.length() - 2));
553 }
554 break;
555 case __TLOGICAL14:
556 result = (m_value == "T") ? 1.0 : 0.0;
557 break;
558 default:
559 result = gammalib::todouble(m_value);
560 break;
561 }
562 }
563
564 // Return string
565 return result;
566
567}
568
569
570/***********************************************************************//**
571 * @brief Return header card value as integer
572*
573 * Convert header card value into a integer value. In case that the
574 * card did not contain a numerical value, 0 will be returned by the
575 * method.
576 ***************************************************************************/
577int GFitsHeaderCard::integer(void) const
578{
579 // Initialize return value to 0
580 int result = 0;
581
582 // Type dependent conversion
583 if (m_value_dtype != NULL__null) {
584 switch (m_dtype) {
585 case __TSTRING16:
586 if (m_value.length() > 2) {
587 result = gammalib::toint(m_value.substr(1, m_value.length() - 2));
588 }
589 break;
590 case __TLOGICAL14:
591 result = (m_value == "T") ? 1 : 0;
592 break;
593 default:
594 result = gammalib::toint(m_value);
595 break;
596 }
597 }
598
599 // Return string
600 return result;
601
602}
603
604
605/***********************************************************************//**
606 * @brief Print header card information
607 *
608 * @param[in] chatter Chattiness (defaults to NORMAL).
609 * @return String containing header card information.
610 ***************************************************************************/
611std::string GFitsHeaderCard::print(const GChatter& chatter) const
612{
613 // Initialise result string
614 std::string result;
615
616 // Continue only if chatter is not silent
617 if (chatter != SILENT) {
618
619 // Append keyname
620 result.append(gammalib::left(m_keyname,8));
621
622 // Format values
623 if (m_keyname != "COMMENT" && m_keyname != "HISTORY" && m_keyname != "") {
624 if (m_unit.length() > 0) {
625 result.append(" ="+gammalib::right(m_value,21)+" / ["+m_unit+"] "+m_comment);
626 }
627 else {
628 result.append(" ="+gammalib::right(m_value,21)+" / "+m_comment);
629 }
630 }
631 else {
632 result.append(" "+m_comment);
633 }
634
635 // Attach card type
636 if (m_value_dtype != NULL__null) {
637 switch (m_dtype) {
638 case __TNULL0:
639 result.append(" <null>");
640 break;
641 case __TBIT1:
642 result.append(" <bit>");
643 break;
644 case __TBYTE11:
645 result.append(" <byte>");
646 break;
647 case __TSBYTE12:
648 result.append(" <signed byte>");
649 break;
650 case __TLOGICAL14:
651 result.append(" <bool>");
652 break;
653 case __TSTRING16:
654 result.append(" <string>");
655 break;
656 case __TUSHORT20:
657 result.append(" <unsigned short>");
658 break;
659 case __TSHORT21:
660 result.append(" <short>");
661 break;
662 case __TUINT30:
663 result.append(" <unsigned int>");
664 break;
665 case __TINT31:
666 result.append(" <int>");
667 break;
668 case __TULONG40:
669 result.append(" <unsigned long>");
670 break;
671 case __TLONG41:
672 result.append(" <long>");
673 break;
674 case __TLONGLONG81:
675 result.append(" <long long>");
676 break;
677 case __TFLOAT42:
678 result.append(" <float>");
679 break;
680 case __TDOUBLE82:
681 result.append(" <double>");
682 break;
683 case __TCOMPLEX83:
684 result.append(" <complex>");
685 break;
686 case __TDBLCOMPLEX163:
687 result.append(" <double complex>");
688 break;
689 default:
690 result.append(" <unsupported value "+gammalib::str(m_dtype)+">");
691 break;
692 }
693 }
694 /*
695 else {
696 switch (m_dtype) {
697 case __TNULL:
698 result.append(" <null>");
699 break;
700 default:
701 result.append(" <non native>");
702 break;
703 }
704 }
705 */
706
707 } // endif: chatter was not silent
708
709 // Return result
710 return result;
711}
712
713
714/*==========================================================================
715 = =
716 = Private methods =
717 = =
718 ==========================================================================*/
719
720/***********************************************************************//**
721 * @brief Initialise class members
722 ***************************************************************************/
723void GFitsHeaderCard::init_members(void)
724{
725 // Initialise members
726 m_keyname.clear();
727 m_value.clear();
728 m_unit.clear();
729 m_comment.clear();
730 m_value_dtype = NULL__null;
731 m_dtype = __TNULL0;
732 m_value_decimals = 10;
733 m_comment_write = true; // Was false before, not sure why ...
734
735 // Return
736 return;
737}
738
739
740/***********************************************************************//**
741 * @brief Copy class members
742 *
743 * @param[in] card Header card to be copied
744 ***************************************************************************/
745void GFitsHeaderCard::copy_members(const GFitsHeaderCard& card)
746{
747 // Copy members
748 m_keyname = card.m_keyname;
749 m_value = card.m_value;
750 m_value_decimals = card.m_value_decimals;
751 m_unit = card.m_unit;
752 m_comment = card.m_comment;
753 m_comment_write = card.m_comment_write;
754
755 // Copy native data types
756 copy_dtype(card);
757
758 // Return
759 return;
760}
761
762
763/***********************************************************************//**
764 * @brief Delete class members
765 ***************************************************************************/
766void GFitsHeaderCard::free_members(void)
767{
768 // Free members
769 free_dtype();
770
771 // Return
772 return;
773}
774
775
776/***********************************************************************//**
777 * @brief Copy dtype
778 *
779 * @param[in] card Header card.
780 *
781 * Copies the data type of a header card.
782 ***************************************************************************/
783void GFitsHeaderCard::copy_dtype(const GFitsHeaderCard& card)
784{
785 // Copy data type
786 if (card.m_value_dtype != NULL__null) {
787 m_dtype = card.m_dtype;
788 switch (m_dtype) {
789 case __TLOGICAL14:
790 m_value_dtype = new bool(*((bool*)card.m_value_dtype));
791 break;
792 case __TSTRING16:
793 m_value_dtype = new std::string(*((std::string*)card.m_value_dtype));
794 break;
795 case __TUSHORT20:
796 m_value_dtype = new unsigned short(*((unsigned short*)card.m_value_dtype));
797 break;
798 case __TSHORT21:
799 m_value_dtype = new short(*((short*)card.m_value_dtype));
800 break;
801 case __TUINT30:
802 m_value_dtype = new unsigned int(*((unsigned int*)card.m_value_dtype));
803 break;
804 case __TINT31:
805 m_value_dtype = new int(*((int*)card.m_value_dtype));
806 break;
807 case __TULONG40:
808 m_value_dtype = new unsigned long(*((unsigned long*)card.m_value_dtype));
809 break;
810 case __TLONG41:
811 m_value_dtype = new long(*((long*)card.m_value_dtype));
812 break;
813 case __TLONGLONG81:
814 m_value_dtype = new long long(*((long long*)card.m_value_dtype));
815 break;
816 case __TFLOAT42:
817 m_value_dtype = new float(*((float*)card.m_value_dtype));
818 break;
819 case __TDOUBLE82:
820 m_value_dtype = new double(*((double*)card.m_value_dtype));
821 break;
822 default:
823 std::string msg = "Invalid data type code "+
824 gammalib::str(m_dtype)+" encountered.";
825 gammalib::warning(G_COPY_DTYPE"GFitsHeaderCard::copy_dtype(GFitsHeaderCard&)", msg);
826 break;
827 }
828 }
829
830 // Return
831 return;
832}
833
834
835/***********************************************************************//**
836 * @brief Free dtype
837 ***************************************************************************/
838void GFitsHeaderCard::free_dtype(void)
839{
840 // Free data type
841 if (m_value_dtype != NULL__null) {
7
Taking true branch
17
Taking true branch
842 switch (m_dtype) {
8
Control jumps to 'case 81:' at line 867
18
Control jumps to 'case 81:' at line 867
843 case __TLOGICAL14:
844 delete (bool*)m_value_dtype;
845 break;
846 case __TSTRING16:
847 delete (std::string*)m_value_dtype;
848 break;
849 case __TUSHORT20:
850 delete (unsigned short*)m_value_dtype;
851 break;
852 case __TSHORT21:
853 delete (short*)m_value_dtype;
854 break;
855 case __TUINT30:
856 delete (unsigned int*)m_value_dtype;
857 break;
858 case __TINT31:
859 delete (int*)m_value_dtype;
860 break;
861 case __TULONG40:
862 delete (unsigned long*)m_value_dtype;
863 break;
864 case __TLONG41:
865 delete (long*)m_value_dtype;
866 break;
867 case __TLONGLONG81:
868 delete (long long*)m_value_dtype;
9
Memory is released
19
Attempt to free released memory
869 break;
10
Execution continues on line 885
870 case __TFLOAT42:
871 delete (float*)m_value_dtype;
872 break;
873 case __TDOUBLE82:
874 delete (double*)m_value_dtype;
875 break;
876 default:
877 std::string msg = "Invalid data type code "+
878 gammalib::str(m_dtype)+" encountered.";
879 gammalib::warning(G_FREE_DTYPE"GFitsHeaderCard::free_dtype()", msg);
880 break;
881 }
882 }
883
884 // Return
885 return;
886}
887
888
889/***********************************************************************//**
890 * @brief Set native data type from card string
891 *
892 * @param[in] value Card string.
893 *
894 * The native data type is determined from the card string. This method sets
895 * the members m_dtype and m_value_type. The card type is determined by
896 * analyzing the card value.
897 *
898 * @todo Implement syntax checking for integer or float values.
899 ***************************************************************************/
900void GFitsHeaderCard::set_dtype(const std::string& value)
901{
902 // Free data type
903 free_dtype();
6
Calling 'GFitsHeaderCard::free_dtype'
11
Returning; memory was released
904
905 // Main loop to allow fall through
906 do {
907
908 // Get index of last string element
909 int last = m_value.length() - 1;
910
911 // If value is empty and there is a COMMENT, HISTORY or BLANKFIELD
912 // (empty) keyword then we have a commentary card. We can just
913 // skip this card here. Otherwise we have an undefined value, also
914 // called NULL value.
915 if (last < 0) {
12
Assuming 'last' is >= 0
13
Taking false branch
916 if (m_keyname == "COMMENT" ||
917 m_keyname == "HISTORY" ||
918 m_keyname == "") {
919 continue;
920 }
921 else {
922 m_dtype = __TNULL0;
923 continue;
924 }
925 }
926
927 // If value is enclosed in parentheses then we have a string
928 if (m_value[0] == '\x27' && m_value[last] == '\x27') {
14
Taking true branch
929 this->value(value);
15
Calling 'GFitsHeaderCard::value'
930 continue;
931 }
932
933 // If value has only one digit and is either 'F' or 'T' we have a
934 // Boolean
935 if (last == 0 && (m_value[0] == 'F' || m_value[0] == 'T')) {
936 this->value((m_value[0] == 'T'));
937 continue;
938 }
939
940 // Conversion
941 double value_dbl = gammalib::todouble(m_value);
942 long long value_ll = gammalib::tolonglong(m_value);
943 unsigned long long value_ull = gammalib::toulonglong(m_value);
944
945 // Check if we have an integer
946 if ((value_dbl >= 0 && value_dbl == value_ull) ||
947 (value_dbl < 0 && value_dbl == value_ll)) {
948
949 // Consider positive integers as unsigned
950 if (value_dbl >= 0) {
951 if (value_ull > ULONG_MAX(9223372036854775807L *2UL+1UL)) {
952 m_dtype = __TLONGLONG81;
953 m_value_dtype = new long long(value_ll);
954 }
955 else if (value_ull > USHRT_MAX(32767 *2 +1)) {
956 m_dtype = __TULONG40;
957 m_value_dtype = new unsigned long(value_ull);
958 }
959 else {
960 m_dtype = __TUSHORT20;
961 m_value_dtype = new unsigned short(value_ull);
962 }
963 }
964
965 // ... otherwise consider signed
966 else {
967 if (value_ll > LONG_MAX9223372036854775807L || value_ll < LONG_MIN(-9223372036854775807L -1L)) {
968 m_dtype = __TLONGLONG81;
969 m_value_dtype = new long long(value_ll);
970 }
971 else if (value_ll > SHRT_MAX32767 || value_ll < SHRT_MIN(-32767 -1)) {
972 m_dtype = __TLONG41;
973 m_value_dtype = new long(value_ll);
974 }
975 else {
976 m_dtype = __TSHORT21;
977 m_value_dtype = new short(value_ll);
978 }
979 }
980 } // endif: handled integers
981
982 // ... otherwise handle floats
983 else {
984 if (value_dbl > FLT_MAX3.40282347e+38F || value_dbl < FLT_MIN1.17549435e-38F) {
985 m_dtype = __TDOUBLE82;
986 m_value_dtype = new double(value_dbl);
987 }
988 else {
989 m_dtype = __TFLOAT42;
990 m_value_dtype = new float(value_dbl);
991 }
992 }
993
994 } while(0);
995
996 // Return
997 return;
998}
999
1000
1001/***********************************************************************//**
1002 * @brief Read header card from FITS file
1003 *
1004 * @param[in] vptr FITS file void pointer.
1005 * @param[in] keynum Number of the header card.
1006 ***************************************************************************/
1007void GFitsHeaderCard::read(void* vptr, const int& keynum)
1008{
1009 // Initialise status
1010 int status = 0;
1011
1012 // Move to HDU
1013 gammalib::fits_move_to_hdu(G_READ_NUM"GFitsHeaderCard::read(void*, int&)", vptr);
1014
1015 // Read keyword
1016 char keyname[80];
1017 char value[80];
1018 char comment[80];
1019 status = __ffgkyn(FPTR(vptr), keynum, keyname, value, comment, &status)ffgkyn(((__fitsfile*)vptr), keynum, keyname, value, comment, &
status)
;
1020 if (status != 0) {
1021 throw GException::fits_error(G_READ_NUM"GFitsHeaderCard::read(void*, int&)", status);
1022 }
1023
1024 // Store result
1025 m_keyname.assign(keyname);
1026 m_value.assign(value);
1027 m_comment.assign(comment);
1028
1029 // Determine card type
1030 set_dtype(m_value);
1031
1032 // Return
1033 return;
1034}
1035
1036
1037/***********************************************************************//**
1038 * @brief Read header card from FITS file
1039 *
1040 * @param[in] vptr FITS file void pointer.
1041 * @param[in] keyname Name of the header card.
1042 *
1043 * @exception GException::invalid_value
1044 * Specified @p keyname not found in FITS header.
1045 * @exception GException::fits_error
1046 * cfitsio error occured.
1047 ***************************************************************************/
1048void GFitsHeaderCard::read(void* vptr, const std::string& keyname)
1049{
1050 // Initialise FITS status
1051 int status = 0;
1052
1053 // Move to HDU
1054 gammalib::fits_move_to_hdu(G_READ_STR"GFitsHeaderCard::read(void*, std::string&)", vptr);
1055
1056 // Read keyword
1057 char value[80];
1058 char comment[80];
1059 status = __ffgkey(FPTR(vptr), (char*)keyname.c_str(), value, comment,ffgkey(((__fitsfile*)vptr), (char*)keyname.c_str(), value, comment
, &status)
1060 &status)ffgkey(((__fitsfile*)vptr), (char*)keyname.c_str(), value, comment
, &status)
;
1061
1062 // Catch error
1063 if (status == 202) { // Keyword not found
1
Assuming 'status' is not equal to 202
2
Taking false branch
1064 std::string msg = "Header card with keyword \""+keyname+"\" not"
1065 " found in FITS header (status=202).";
1066 throw GException::invalid_value(G_READ_STR"GFitsHeaderCard::read(void*, std::string&)", msg);
1067 }
1068 else if (status != 0) { // Any other error
3
Assuming 'status' is equal to 0
4
Taking false branch
1069 std::string msg = "Unable to read keyword \""+keyname+"\" from"
1070 " FITS extension "+
1071 gammalib::str((FPTR(vptr)((__fitsfile*)vptr)->HDUposition))+
1072 " header.";
1073 throw GException::fits_error(G_READ_STR"GFitsHeaderCard::read(void*, std::string&)", status, msg);
1074 }
1075
1076 // Store result
1077 m_keyname = keyname;
1078 m_value.assign(value);
1079 m_comment.assign(comment);
1080
1081 // Determine card type
1082 set_dtype(m_value);
5
Calling 'GFitsHeaderCard::set_dtype'
1083
1084 // Return
1085 return;
1086}
1087
1088
1089/***********************************************************************//**
1090 * @brief Write header card
1091 *
1092 * @param[in] vptr FITS file void pointer.
1093 *
1094 * Writes any kind of header card to a FITS file.
1095 ***************************************************************************/
1096void GFitsHeaderCard::write(void* vptr) const
1097{
1098 // Initialise status
1099 int status = 0;
1100
1101 // Move to HDU
1102 gammalib::fits_move_to_hdu(G_WRITE"GFitsHeaderCard::write(void*)", vptr);
1103
1104 // If card is comment then write comment
1105 if (m_keyname == "COMMENT") {
1106 if (m_comment_write) {
1107 status = __ffpcom(FPTR(vptr), (char*)m_comment.c_str(), &status)ffpcom(((__fitsfile*)vptr), (char*)m_comment.c_str(), &status
)
;
1108 }
1109 }
1110
1111 // If card is history then write history
1112 else if (m_keyname == "HISTORY") {
1113 if (m_comment_write) {
1114 status = __ffphis(FPTR(vptr), (char*)m_comment.c_str(), &status)ffphis(((__fitsfile*)vptr), (char*)m_comment.c_str(), &status
)
;
1115 }
1116 }
1117
1118 // If card is BLANKFIELD (empty keyword) then write empty line
1119 else if (m_keyname == "") {
1120 if (m_comment_write) {
1121 status = __ffprec(FPTR(vptr), "", &status)ffprec(((__fitsfile*)vptr), "", &status);
1122 }
1123 }
1124
1125 // If card holds a native data type then write it
1126 else if (m_value_dtype != NULL__null) {
1127 switch (m_dtype) {
1128 case __TLOGICAL14:
1129 {
1130 int value = (*((bool*)m_value_dtype)) ? 1 : 0;
1131 status = __ffukyl(FPTR(vptr), (char*)m_keyname.c_str(), value,ffukyl(((__fitsfile*)vptr), (char*)m_keyname.c_str(), value, (
char*)m_comment.c_str(), &status)
1132 (char*)m_comment.c_str(), &status)ffukyl(((__fitsfile*)vptr), (char*)m_keyname.c_str(), value, (
char*)m_comment.c_str(), &status)
;
1133 }
1134 break;
1135 case __TSTRING16:
1136 status = __ffukys(FPTR(vptr), (char*)m_keyname.c_str(),ffukys(((__fitsfile*)vptr), (char*)m_keyname.c_str(), (char*)
((std::string*)m_value_dtype)->c_str(), (char*)m_comment.c_str
(), &status)
1137 (char*)((std::string*)m_value_dtype)->c_str(),ffukys(((__fitsfile*)vptr), (char*)m_keyname.c_str(), (char*)
((std::string*)m_value_dtype)->c_str(), (char*)m_comment.c_str
(), &status)
1138 (char*)m_comment.c_str(), &status)ffukys(((__fitsfile*)vptr), (char*)m_keyname.c_str(), (char*)
((std::string*)m_value_dtype)->c_str(), (char*)m_comment.c_str
(), &status)
;
1139 break;
1140 case __TFLOAT42:
1141 status = __ffukye(FPTR(vptr), (char*)m_keyname.c_str(),ffukye(((__fitsfile*)vptr), (char*)m_keyname.c_str(), *((float
*)m_value_dtype), decimals(), (char*)m_comment.c_str(), &
status)
1142 *((float*)m_value_dtype), decimals(),ffukye(((__fitsfile*)vptr), (char*)m_keyname.c_str(), *((float
*)m_value_dtype), decimals(), (char*)m_comment.c_str(), &
status)
1143 (char*)m_comment.c_str(), &status)ffukye(((__fitsfile*)vptr), (char*)m_keyname.c_str(), *((float
*)m_value_dtype), decimals(), (char*)m_comment.c_str(), &
status)
;
1144 break;
1145 case __TDOUBLE82:
1146 status = __ffukyd(FPTR(vptr), (char*)m_keyname.c_str(),ffukyd(((__fitsfile*)vptr), (char*)m_keyname.c_str(), *((double
*)m_value_dtype), decimals(), (char*)m_comment.c_str(), &
status)
1147 *((double*)m_value_dtype), decimals(),ffukyd(((__fitsfile*)vptr), (char*)m_keyname.c_str(), *((double
*)m_value_dtype), decimals(), (char*)m_comment.c_str(), &
status)
1148 (char*)m_comment.c_str(), &status)ffukyd(((__fitsfile*)vptr), (char*)m_keyname.c_str(), *((double
*)m_value_dtype), decimals(), (char*)m_comment.c_str(), &
status)
;
1149 break;
1150 default:
1151 status = __ffuky(FPTR(vptr), m_dtype, (char*)m_keyname.c_str(),ffuky(((__fitsfile*)vptr), m_dtype, (char*)m_keyname.c_str(),
m_value_dtype, (char*)m_comment.c_str(), &status)
1152 m_value_dtype, (char*)m_comment.c_str(), &status)ffuky(((__fitsfile*)vptr), m_dtype, (char*)m_keyname.c_str(),
m_value_dtype, (char*)m_comment.c_str(), &status)
;
1153 break;
1154 }
1155 } // endif: had native data type
1156
1157 // ... otherwise if card holds a NULL value then write it
1158 else if (m_dtype == __TNULL0) {
1159 status = __ffukyu(FPTR(vptr), (char*)m_keyname.c_str(),ffukyu(((__fitsfile*)vptr), (char*)m_keyname.c_str(), (char*)
m_comment.c_str(), &status)
1160 (char*)m_comment.c_str(), &status)ffukyu(((__fitsfile*)vptr), (char*)m_keyname.c_str(), (char*)
m_comment.c_str(), &status)
;
1161 }
1162
1163 // ... capture all other stuff
1164 else {
1165 std::string msg = "The code should never arrive at this point!\n"
1166 "The keyname \""+m_keyname+"\" is neither"
1167 " \"COMMENT\" nor \"HISTRORY\" but it has a"
1168 " NULL data type value and a data type of"
1169 " "+gammalib::str(m_dtype)+".\n"
1170 "Maybe an invalid FITS header card has been"
1171 " encountered in reading a file?";
1172 gammalib::warning(G_WRITE"GFitsHeaderCard::write(void*)", msg);
1173 }
1174
1175 // Throw exception in case of a FITS error
1176 if (status != 0) {
1177 throw GException::fits_error(G_WRITE"GFitsHeaderCard::write(void*)", status);
1178 }
1179
1180 // Return
1181 return;
1182}