Commit 48f8b64ae495b64d404c91c8dbb86355e6771505

Authored by Jürgen Knödlseder
1 parent f0032bb6

Implement resize_data() method for all classes (except for Bit columns) and impl…

…ement elements() method for defining variable-length column.

A variable-length column is now constructued by passing a negative column vector length. The size of a row is specified using the elements() method that makes use of the resize_data() method implemented by the derived classes. The only column type that is not yet implemented is the Bit column. Also the string columns do not yet work properly for variable-length columns.
include/GFitsTableBitCol.hpp
... ... @@ -84,6 +84,7 @@ private:
84 84 virtual void alloc_data(void);
85 85 virtual void init_data(void);
86 86 virtual void fetch_data(void) const;
  87 + virtual void resize_data(const int& index, const int& number);
87 88 virtual void release_data(void);
88 89 virtual void* ptr_data(const int& index = 0);
89 90 virtual void* ptr_nulval(void);
... ...
include/GFitsTableBoolCol.hpp
... ... @@ -85,6 +85,7 @@ private:
85 85 virtual void alloc_data(void);
86 86 virtual void init_data(void);
87 87 virtual void fetch_data(void) const;
  88 + virtual void resize_data(const int& index, const int& number);
88 89 virtual void release_data(void);
89 90 virtual void* ptr_data(const int& index = 0);
90 91 virtual void* ptr_nulval(void);
... ...
include/GFitsTableByteCol.hpp
... ... @@ -80,6 +80,7 @@ private:
80 80 virtual void alloc_data(void);
81 81 virtual void init_data(void);
82 82 virtual void fetch_data(void) const;
  83 + virtual void resize_data(const int& index, const int& number);
83 84 virtual void release_data(void);
84 85 virtual void* ptr_data(const int& index = 0);
85 86 virtual void* ptr_nulval(void);
... ...
include/GFitsTableCDoubleCol.hpp
... ... @@ -81,6 +81,7 @@ private:
81 81 virtual void alloc_data(void);
82 82 virtual void init_data(void);
83 83 virtual void fetch_data(void) const;
  84 + virtual void resize_data(const int& index, const int& number);
84 85 virtual void release_data(void);
85 86 virtual void* ptr_data(const int& index = 0);
86 87 virtual void* ptr_nulval(void);
... ...
include/GFitsTableCFloatCol.hpp
... ... @@ -81,6 +81,7 @@ private:
81 81 virtual void alloc_data(void);
82 82 virtual void init_data(void);
83 83 virtual void fetch_data(void) const;
  84 + virtual void resize_data(const int& index, const int& number);
84 85 virtual void release_data(void);
85 86 virtual void* ptr_data(const int& index = 0);
86 87 virtual void* ptr_nulval(void);
... ...
include/GFitsTableCol.hpp
... ... @@ -108,7 +108,7 @@ protected:
108 108 virtual void alloc_data(void) = 0;
109 109 virtual void init_data(void) = 0;
110 110 virtual void fetch_data(void) const = 0;
111   - virtual void resize_data(const int& index, const int& number) {}
  111 + virtual void resize_data(const int& index, const int& number) = 0;
112 112 virtual void release_data(void) = 0;
113 113 virtual void* ptr_data(const int& index = 0) = 0;
114 114 virtual void* ptr_nulval(void) = 0;
... ...
include/GFitsTableDoubleCol.hpp
... ... @@ -80,6 +80,7 @@ private:
80 80 virtual void alloc_data(void);
81 81 virtual void init_data(void);
82 82 virtual void fetch_data(void) const;
  83 + virtual void resize_data(const int& index, const int& number);
83 84 virtual void release_data(void);
84 85 virtual void* ptr_data(const int& index = 0);
85 86 virtual void* ptr_nulval(void);
... ...
include/GFitsTableFloatCol.hpp
... ... @@ -80,6 +80,7 @@ private:
80 80 virtual void alloc_data(void);
81 81 virtual void init_data(void);
82 82 virtual void fetch_data(void) const;
  83 + virtual void resize_data(const int& index, const int& number);
83 84 virtual void release_data(void);
84 85 virtual void* ptr_data(const int& index = 0);
85 86 virtual void* ptr_nulval(void);
... ...
include/GFitsTableLongCol.hpp
... ... @@ -80,6 +80,7 @@ private:
80 80 virtual void alloc_data(void);
81 81 virtual void init_data(void);
82 82 virtual void fetch_data(void) const;
  83 + virtual void resize_data(const int& index, const int& number);
83 84 virtual void release_data(void);
84 85 virtual void* ptr_data(const int& index = 0);
85 86 virtual void* ptr_nulval(void);
... ...
include/GFitsTableLongLongCol.hpp
... ... @@ -80,6 +80,7 @@ private:
80 80 virtual void alloc_data(void);
81 81 virtual void init_data(void);
82 82 virtual void fetch_data(void) const;
  83 + virtual void resize_data(const int& index, const int& number);
83 84 virtual void release_data(void);
84 85 virtual void* ptr_data(const int& index = 0);
85 86 virtual void* ptr_nulval(void);
... ...
include/GFitsTableStringCol.hpp
... ... @@ -82,6 +82,7 @@ private:
82 82 virtual void alloc_data(void);
83 83 virtual void init_data(void);
84 84 virtual void fetch_data(void) const;
  85 + virtual void resize_data(const int& index, const int& number);
85 86 virtual void release_data(void);
86 87 virtual void* ptr_data(const int& index = 0);
87 88 virtual void* ptr_nulval(void);
... ...
include/GFitsTableULongCol.hpp
... ... @@ -80,6 +80,7 @@ private:
80 80 virtual void alloc_data(void);
81 81 virtual void init_data(void);
82 82 virtual void fetch_data(void) const;
  83 + virtual void resize_data(const int& index, const int& number);
83 84 virtual void release_data(void);
84 85 virtual void* ptr_data(const int& index = 0);
85 86 virtual void* ptr_nulval(void);
... ...
include/GFitsTableUShortCol.hpp
... ... @@ -80,6 +80,7 @@ private:
80 80 virtual void alloc_data(void);
81 81 virtual void init_data(void);
82 82 virtual void fetch_data(void) const;
  83 + virtual void resize_data(const int& index, const int& number);
83 84 virtual void release_data(void);
84 85 virtual void* ptr_data(const int& index = 0);
85 86 virtual void* ptr_nulval(void);
... ...
src/fits/GFitsTableBitCol.cpp
... ... @@ -723,6 +723,28 @@ void GFitsTableBitCol::fetch_data(void) const
723 723  
724 724  
725 725 /***********************************************************************//**
  726 + * @brief Resize column data
  727 + *
  728 + * @param[in] index Start index.
  729 + * @param[in] number Number of elements to add/remove.
  730 + *
  731 + * Adds or removes elements from specified index on. Adding is done if
  732 + * @p number is a positive number, removing if @p number is negative.
  733 + * Note that the method does not change the validity of the arguments.
  734 + * This needs to be done by the client.
  735 + *
  736 + * @todo Needs to be implemented
  737 + ***************************************************************************/
  738 +void GFitsTableBitCol::resize_data(const int& index, const int& number)
  739 +{
  740 + //TODO
  741 +
  742 + // Return
  743 + return;
  744 +}
  745 +
  746 +
  747 +/***********************************************************************//**
726 748 * @brief Release column data
727 749 ***************************************************************************/
728 750 void GFitsTableBitCol::release_data(void)
... ...
src/fits/GFitsTableBoolCol.cpp
... ... @@ -531,7 +531,8 @@ void GFitsTableBoolCol::copy_members(const GFitsTableBoolCol& column)
531 531  
532 532 // Copy column data
533 533 if (column.m_data != NULL && m_size > 0) {
534   - alloc_data();
  534 + if (m_data != NULL) delete [] m_data;
  535 + m_data = new bool[m_size];
535 536 for (int i = 0; i < m_size; ++i) {
536 537 m_data[i] = column.m_data[i];
537 538 }
... ... @@ -644,6 +645,10 @@ void GFitsTableBoolCol::alloc_data(void)
644 645 m_data = new bool[m_size];
645 646 }
646 647  
  648 + // Allocate also buffer
  649 + free_buffer();
  650 + alloc_buffer();
  651 +
647 652 // Return
648 653 return;
649 654 }
... ... @@ -660,16 +665,7 @@ void GFitsTableBoolCol::alloc_data(void)
660 665 ***************************************************************************/
661 666 void GFitsTableBoolCol::fetch_data(void) const
662 667 {
663   - // Calculate size of memory
664   - m_size = m_number * m_length;
665   -
666   - // Free old buffer memory
667   - free_buffer();
668   -
669   - // Allocate buffer memory
670   - alloc_buffer();
671   -
672   - // Save column
  668 + // Load column
673 669 const_cast<GFitsTableBoolCol*>(this)->load_column();
674 670  
675 671 // Extract values from buffer
... ... @@ -686,6 +682,73 @@ void GFitsTableBoolCol::fetch_data(void) const
686 682  
687 683  
688 684 /***********************************************************************//**
  685 + * @brief Resize column data
  686 + *
  687 + * @param[in] index Start index.
  688 + * @param[in] number Number of elements to add/remove.
  689 + *
  690 + * Adds or removes elements from specified index on. Adding is done if
  691 + * @p number is a positive number, removing if @p number is negative.
  692 + * Note that the method does not change the validity of the arguments.
  693 + * This needs to be done by the client.
  694 + ***************************************************************************/
  695 +void GFitsTableBoolCol::resize_data(const int& index, const int& number)
  696 +{
  697 + // Continue only if number of elements is not zero
  698 + if (number != 0) {
  699 +
  700 + // If data are not available then load them now
  701 + if (m_data == NULL) fetch_data();
  702 +
  703 + // If elements should be removed then do not allocate new memory
  704 + // but just move elements forward and change the logical size of
  705 + // memory. Only if all elements should be removed the memory is
  706 + // released.
  707 + if (number < 0) {
  708 + if (m_data != NULL) {
  709 + int left = index - number;
  710 + bool* dst = m_data + index;
  711 + bool* src = m_data + left;
  712 + int num = m_size - left;
  713 + for (int i = 0; i < num; ++i) {
  714 + *dst++ = *src++;
  715 + }
  716 + m_size += number;
  717 + if (m_size < 1) {
  718 + release_data();
  719 + }
  720 + }
  721 + }
  722 +
  723 + // If elements should be added then allocate new memory, copy over
  724 + // the old data and initialise the new elements
  725 + else {
  726 + int left = m_size - index;
  727 + m_size += number;
  728 + bool* new_data = new bool[m_size];
  729 + bool* dst = new_data;
  730 + bool* src = m_data;
  731 + for (int i = 0; i < index; ++i) {
  732 + *dst++ = *src++;
  733 + }
  734 + for (int i = 0; i < number; ++i) {
  735 + *dst++ = false;
  736 + }
  737 + for (int i = 0; i < left; ++i) {
  738 + *dst++ = *src++;
  739 + }
  740 + if (m_data != NULL) delete [] m_data;
  741 + m_data = new_data;
  742 + }
  743 +
  744 + } // endif: number was non-zero
  745 +
  746 + // Return
  747 + return;
  748 +}
  749 +
  750 +
  751 +/***********************************************************************//**
689 752 * @brief Release column data
690 753 ***************************************************************************/
691 754 void GFitsTableBoolCol::release_data(void)
... ...
src/fits/GFitsTableByteCol.cpp
... ... @@ -620,6 +620,71 @@ void GFitsTableByteCol::fetch_data(void) const
620 620  
621 621  
622 622 /***********************************************************************//**
  623 + * @brief Resize column data
  624 + *
  625 + * @param[in] index Start index.
  626 + * @param[in] number Number of elements to add/remove.
  627 + *
  628 + * Adds or removes elements from specified index on. Adding is done if
  629 + * @p number is a positive number, removing if @p number is negative.
  630 + * Note that the method does not change the validity of the arguments.
  631 + * This needs to be done by the client.
  632 + ***************************************************************************/
  633 +void GFitsTableByteCol::resize_data(const int& index, const int& number)
  634 +{
  635 + // Continue only if number of elements is not zero
  636 + if (number != 0) {
  637 +
  638 + // If data are not available then load them now
  639 + if (m_data == NULL) fetch_data();
  640 +
  641 + // If elements should be removed then do not allocate new memory
  642 + // but just move elements forward and change the logical size of
  643 + // memory. Only if all elements should be removed the memory is
  644 + // released.
  645 + if (number < 0) {
  646 + int left = index - number;
  647 + unsigned char* dst = m_data + index;
  648 + unsigned char* src = m_data + left;
  649 + int num = m_size - left;
  650 + for (int i = 0; i < num; ++i) {
  651 + *dst++ = *src++;
  652 + }
  653 + m_size += number;
  654 + if (m_size < 1) {
  655 + release_data();
  656 + }
  657 + }
  658 +
  659 + // If elements should be added then allocate new memory, copy over
  660 + // the old data and initialise the new elements
  661 + else {
  662 + int left = m_size - index;
  663 + m_size += number;
  664 + unsigned char* new_data = new unsigned char[m_size];
  665 + unsigned char* dst = new_data;
  666 + unsigned char* src = m_data;
  667 + for (int i = 0; i < index; ++i) {
  668 + *dst++ = *src++;
  669 + }
  670 + for (int i = 0; i < number; ++i) {
  671 + *dst++ = 0;
  672 + }
  673 + for (int i = 0; i < left; ++i) {
  674 + *dst++ = *src++;
  675 + }
  676 + if (m_data != NULL) delete [] m_data;
  677 + m_data = new_data;
  678 + }
  679 +
  680 + } // endif: number was non-zero
  681 +
  682 + // Return
  683 + return;
  684 +}
  685 +
  686 +
  687 +/***********************************************************************//**
623 688 * @brief Release column data
624 689 ***************************************************************************/
625 690 void GFitsTableByteCol::release_data(void)
... ...
src/fits/GFitsTableCDoubleCol.cpp
... ... @@ -630,6 +630,73 @@ void GFitsTableCDoubleCol::fetch_data(void) const
630 630  
631 631  
632 632 /***********************************************************************//**
  633 + * @brief Resize column data
  634 + *
  635 + * @param[in] index Start index.
  636 + * @param[in] number Number of elements to add/remove.
  637 + *
  638 + * Adds or removes elements from specified index on. Adding is done if
  639 + * @p number is a positive number, removing if @p number is negative.
  640 + * Note that the method does not change the validity of the arguments.
  641 + * This needs to be done by the client.
  642 + ***************************************************************************/
  643 +void GFitsTableCDoubleCol::resize_data(const int& index, const int& number)
  644 +{
  645 + // Continue only if number of elements is not zero
  646 + if (number != 0) {
  647 +
  648 + // If data are not available then load them now
  649 + if (m_data == NULL) fetch_data();
  650 +
  651 + // If elements should be removed then do not allocate new memory
  652 + // but just move elements forward and change the logical size of
  653 + // memory. Only if all elements should be removed the memory is
  654 + // released.
  655 + if (number < 0) {
  656 + int left = index - number;
  657 + GFits::cdouble* dst = m_data + index;
  658 + GFits::cdouble* src = m_data + left;
  659 + int num = m_size - left;
  660 + for (int i = 0; i < num; ++i) {
  661 + *dst++ = *src++;
  662 + }
  663 + m_size += number;
  664 + if (m_size < 1) {
  665 + release_data();
  666 + }
  667 + }
  668 +
  669 + // If elements should be added then allocate new memory, copy over
  670 + // the old data and initialise the new elements
  671 + else {
  672 + int left = m_size - index;
  673 + m_size += number;
  674 + GFits::cdouble* new_data = new GFits::cdouble[m_size];
  675 + GFits::cdouble* dst = new_data;
  676 + GFits::cdouble* src = m_data;
  677 + for (int i = 0; i < index; ++i) {
  678 + *dst++ = *src++;
  679 + }
  680 + for (int i = 0; i < number; ++i) {
  681 + dst->re = 0.0;
  682 + dst->im = 0.0;
  683 + dst++;
  684 + }
  685 + for (int i = 0; i < left; ++i) {
  686 + *dst++ = *src++;
  687 + }
  688 + if (m_data != NULL) delete [] m_data;
  689 + m_data = new_data;
  690 + }
  691 +
  692 + } // endif: number was non-zero
  693 +
  694 + // Return
  695 + return;
  696 +}
  697 +
  698 +
  699 +/***********************************************************************//**
633 700 * @brief Release column data
634 701 ***************************************************************************/
635 702 void GFitsTableCDoubleCol::release_data(void)
... ...
src/fits/GFitsTableCFloatCol.cpp
... ... @@ -630,6 +630,73 @@ void GFitsTableCFloatCol::fetch_data(void) const
630 630  
631 631  
632 632 /***********************************************************************//**
  633 + * @brief Resize column data
  634 + *
  635 + * @param[in] index Start index.
  636 + * @param[in] number Number of elements to add/remove.
  637 + *
  638 + * Adds or removes elements from specified index on. Adding is done if
  639 + * @p number is a positive number, removing if @p number is negative.
  640 + * Note that the method does not change the validity of the arguments.
  641 + * This needs to be done by the client.
  642 + ***************************************************************************/
  643 +void GFitsTableCFloatCol::resize_data(const int& index, const int& number)
  644 +{
  645 + // Continue only if number of elements is not zero
  646 + if (number != 0) {
  647 +
  648 + // If data are not available then load them now
  649 + if (m_data == NULL) fetch_data();
  650 +
  651 + // If elements should be removed then do not allocate new memory
  652 + // but just move elements forward and change the logical size of
  653 + // memory. Only if all elements should be removed the memory is
  654 + // released.
  655 + if (number < 0) {
  656 + int left = index - number;
  657 + GFits::cfloat* dst = m_data + index;
  658 + GFits::cfloat* src = m_data + left;
  659 + int num = m_size - left;
  660 + for (int i = 0; i < num; ++i) {
  661 + *dst++ = *src++;
  662 + }
  663 + m_size += number;
  664 + if (m_size < 1) {
  665 + release_data();
  666 + }
  667 + }
  668 +
  669 + // If elements should be added then allocate new memory, copy over
  670 + // the old data and initialise the new elements
  671 + else {
  672 + int left = m_size - index;
  673 + m_size += number;
  674 + GFits::cfloat* new_data = new GFits::cfloat[m_size];
  675 + GFits::cfloat* dst = new_data;
  676 + GFits::cfloat* src = m_data;
  677 + for (int i = 0; i < index; ++i) {
  678 + *dst++ = *src++;
  679 + }
  680 + for (int i = 0; i < number; ++i) {
  681 + dst->re = 0.0;
  682 + dst->im = 0.0;
  683 + dst++;
  684 + }
  685 + for (int i = 0; i < left; ++i) {
  686 + *dst++ = *src++;
  687 + }
  688 + if (m_data != NULL) delete [] m_data;
  689 + m_data = new_data;
  690 + }
  691 +
  692 + } // endif: number was non-zero
  693 +
  694 + // Return
  695 + return;
  696 +}
  697 +
  698 +
  699 +/***********************************************************************//**
633 700 * @brief Release column data
634 701 ***************************************************************************/
635 702 void GFitsTableCFloatCol::release_data(void)
... ...
src/fits/GFitsTableDoubleCol.cpp
... ... @@ -623,6 +623,71 @@ void GFitsTableDoubleCol::fetch_data(void) const
623 623  
624 624  
625 625 /***********************************************************************//**
  626 + * @brief Resize column data
  627 + *
  628 + * @param[in] index Start index.
  629 + * @param[in] number Number of elements to add/remove.
  630 + *
  631 + * Adds or removes elements from specified index on. Adding is done if
  632 + * @p number is a positive number, removing if @p number is negative.
  633 + * Note that the method does not change the validity of the arguments.
  634 + * This needs to be done by the client.
  635 + ***************************************************************************/
  636 +void GFitsTableDoubleCol::resize_data(const int& index, const int& number)
  637 +{
  638 + // Continue only if number of elements is not zero
  639 + if (number != 0) {
  640 +
  641 + // If data are not available then load them now
  642 + if (m_data == NULL) fetch_data();
  643 +
  644 + // If elements should be removed then do not allocate new memory
  645 + // but just move elements forward and change the logical size of
  646 + // memory. Only if all elements should be removed the memory is
  647 + // released.
  648 + if (number < 0) {
  649 + int left = index - number;
  650 + double* dst = m_data + index;
  651 + double* src = m_data + left;
  652 + int num = m_size - left;
  653 + for (int i = 0; i < num; ++i) {
  654 + *dst++ = *src++;
  655 + }
  656 + m_size += number;
  657 + if (m_size < 1) {
  658 + release_data();
  659 + }
  660 + }
  661 +
  662 + // If elements should be added then allocate new memory, copy over
  663 + // the old data and initialise the new elements
  664 + else {
  665 + int left = m_size - index;
  666 + m_size += number;
  667 + double* new_data = new double[m_size];
  668 + double* dst = new_data;
  669 + double* src = m_data;
  670 + for (int i = 0; i < index; ++i) {
  671 + *dst++ = *src++;
  672 + }
  673 + for (int i = 0; i < number; ++i) {
  674 + *dst++ = 0.0;
  675 + }
  676 + for (int i = 0; i < left; ++i) {
  677 + *dst++ = *src++;
  678 + }
  679 + if (m_data != NULL) delete [] m_data;
  680 + m_data = new_data;
  681 + }
  682 +
  683 + } // endif: number was non-zero
  684 +
  685 + // Return
  686 + return;
  687 +}
  688 +
  689 +
  690 +/***********************************************************************//**
626 691 * @brief Release column data
627 692 ***************************************************************************/
628 693 void GFitsTableDoubleCol::release_data(void)
... ...
src/fits/GFitsTableFloatCol.cpp
... ... @@ -623,6 +623,71 @@ void GFitsTableFloatCol::fetch_data(void) const
623 623  
624 624  
625 625 /***********************************************************************//**
  626 + * @brief Resize column data
  627 + *
  628 + * @param[in] index Start index.
  629 + * @param[in] number Number of elements to add/remove.
  630 + *
  631 + * Adds or removes elements from specified index on. Adding is done if
  632 + * @p number is a positive number, removing if @p number is negative.
  633 + * Note that the method does not change the validity of the arguments.
  634 + * This needs to be done by the client.
  635 + ***************************************************************************/
  636 +void GFitsTableFloatCol::resize_data(const int& index, const int& number)
  637 +{
  638 + // Continue only if number of elements is not zero
  639 + if (number != 0) {
  640 +
  641 + // If data are not available then load them now
  642 + if (m_data == NULL) fetch_data();
  643 +
  644 + // If elements should be removed then do not allocate new memory
  645 + // but just move elements forward and change the logical size of
  646 + // memory. Only if all elements should be removed the memory is
  647 + // released.
  648 + if (number < 0) {
  649 + int left = index - number;
  650 + float* dst = m_data + index;
  651 + float* src = m_data + left;
  652 + int num = m_size - left;
  653 + for (int i = 0; i < num; ++i) {
  654 + *dst++ = *src++;
  655 + }
  656 + m_size += number;
  657 + if (m_size < 1) {
  658 + release_data();
  659 + }
  660 + }
  661 +
  662 + // If elements should be added then allocate new memory, copy over
  663 + // the old data and initialise the new elements
  664 + else {
  665 + int left = m_size - index;
  666 + m_size += number;
  667 + float* new_data = new float[m_size];
  668 + float* dst = new_data;
  669 + float* src = m_data;
  670 + for (int i = 0; i < index; ++i) {
  671 + *dst++ = *src++;
  672 + }
  673 + for (int i = 0; i < number; ++i) {
  674 + *dst++ = 0.0;
  675 + }
  676 + for (int i = 0; i < left; ++i) {
  677 + *dst++ = *src++;
  678 + }
  679 + if (m_data != NULL) delete [] m_data;
  680 + m_data = new_data;
  681 + }
  682 +
  683 + } // endif: number was non-zero
  684 +
  685 + // Return
  686 + return;
  687 +}
  688 +
  689 +
  690 +/***********************************************************************//**
626 691 * @brief Release column data
627 692 ***************************************************************************/
628 693 void GFitsTableFloatCol::release_data(void)
... ...
src/fits/GFitsTableLongCol.cpp
... ... @@ -623,6 +623,71 @@ void GFitsTableLongCol::fetch_data(void) const
623 623  
624 624  
625 625 /***********************************************************************//**
  626 + * @brief Resize column data
  627 + *
  628 + * @param[in] index Start index.
  629 + * @param[in] number Number of elements to add/remove.
  630 + *
  631 + * Adds or removes elements from specified index on. Adding is done if
  632 + * @p number is a positive number, removing if @p number is negative.
  633 + * Note that the method does not change the validity of the arguments.
  634 + * This needs to be done by the client.
  635 + ***************************************************************************/
  636 +void GFitsTableLongCol::resize_data(const int& index, const int& number)
  637 +{
  638 + // Continue only if number of elements is not zero
  639 + if (number != 0) {
  640 +
  641 + // If data are not available then load them now
  642 + if (m_data == NULL) fetch_data();
  643 +
  644 + // If elements should be removed then do not allocate new memory
  645 + // but just move elements forward and change the logical size of
  646 + // memory. Only if all elements should be removed the memory is
  647 + // released.
  648 + if (number < 0) {
  649 + int left = index - number;
  650 + long* dst = m_data + index;
  651 + long* src = m_data + left;
  652 + int num = m_size - left;
  653 + for (int i = 0; i < num; ++i) {
  654 + *dst++ = *src++;
  655 + }
  656 + m_size += number;
  657 + if (m_size < 1) {
  658 + release_data();
  659 + }
  660 + }
  661 +
  662 + // If elements should be added then allocate new memory, copy over
  663 + // the old data and initialise the new elements
  664 + else {
  665 + int left = m_size - index;
  666 + m_size += number;
  667 + long* new_data = new long[m_size];
  668 + long* dst = new_data;
  669 + long* src = m_data;
  670 + for (int i = 0; i < index; ++i) {
  671 + *dst++ = *src++;
  672 + }
  673 + for (int i = 0; i < number; ++i) {
  674 + *dst++ = 0;
  675 + }
  676 + for (int i = 0; i < left; ++i) {
  677 + *dst++ = *src++;
  678 + }
  679 + if (m_data != NULL) delete [] m_data;
  680 + m_data = new_data;
  681 + }
  682 +
  683 + } // endif: number was non-zero
  684 +
  685 + // Return
  686 + return;
  687 +}
  688 +
  689 +
  690 +/***********************************************************************//**
626 691 * @brief Release column data
627 692 ***************************************************************************/
628 693 void GFitsTableLongCol::release_data(void)
... ...
src/fits/GFitsTableLongLongCol.cpp
... ... @@ -623,6 +623,71 @@ void GFitsTableLongLongCol::fetch_data(void) const
623 623  
624 624  
625 625 /***********************************************************************//**
  626 + * @brief Resize column data
  627 + *
  628 + * @param[in] index Start index.
  629 + * @param[in] number Number of elements to add/remove.
  630 + *
  631 + * Adds or removes elements from specified index on. Adding is done if
  632 + * @p number is a positive number, removing if @p number is negative.
  633 + * Note that the method does not change the validity of the arguments.
  634 + * This needs to be done by the client.
  635 + ***************************************************************************/
  636 +void GFitsTableLongLongCol::resize_data(const int& index, const int& number)
  637 +{
  638 + // Continue only if number of elements is not zero
  639 + if (number != 0) {
  640 +
  641 + // If data are not available then load them now
  642 + if (m_data == NULL) fetch_data();
  643 +
  644 + // If elements should be removed then do not allocate new memory
  645 + // but just move elements forward and change the logical size of
  646 + // memory. Only if all elements should be removed the memory is
  647 + // released.
  648 + if (number < 0) {
  649 + int left = index - number;
  650 + long long* dst = m_data + index;
  651 + long long* src = m_data + left;
  652 + int num = m_size - left;
  653 + for (int i = 0; i < num; ++i) {
  654 + *dst++ = *src++;
  655 + }
  656 + m_size += number;
  657 + if (m_size < 1) {
  658 + release_data();
  659 + }
  660 + }
  661 +
  662 + // If elements should be added then allocate new memory, copy over
  663 + // the old data and initialise the new elements
  664 + else {
  665 + int left = m_size - index;
  666 + m_size += number;
  667 + long long* new_data = new long long[m_size];
  668 + long long* dst = new_data;
  669 + long long* src = m_data;
  670 + for (int i = 0; i < index; ++i) {
  671 + *dst++ = *src++;
  672 + }
  673 + for (int i = 0; i < number; ++i) {
  674 + *dst++ = 0;
  675 + }
  676 + for (int i = 0; i < left; ++i) {
  677 + *dst++ = *src++;
  678 + }
  679 + if (m_data != NULL) delete [] m_data;
  680 + m_data = new_data;
  681 + }
  682 +
  683 + } // endif: number was non-zero
  684 +
  685 + // Return
  686 + return;
  687 +}
  688 +
  689 +
  690 +/***********************************************************************//**
626 691 * @brief Release column data
627 692 ***************************************************************************/
628 693 void GFitsTableLongLongCol::release_data(void)
... ...
src/fits/GFitsTableStringCol.cpp
... ... @@ -539,7 +539,8 @@ void GFitsTableStringCol::copy_members(const GFitsTableStringCol&amp; column)
539 539  
540 540 // Copy column data
541 541 if (column.m_data != NULL && m_size > 0) {
542   - alloc_data();
  542 + if (m_data != NULL) delete [] m_data;
  543 + m_data = new std::string[m_size];
543 544 for (int i = 0; i < m_size; ++i) {
544 545 m_data[i] = column.m_data[i];
545 546 }
... ... @@ -662,6 +663,10 @@ void GFitsTableStringCol::alloc_data(void)
662 663 m_data = new std::string[m_size];
663 664 }
664 665  
  666 + // Allocate also buffer
  667 + free_buffer();
  668 + alloc_buffer();
  669 +
665 670 // Return
666 671 return;
667 672 }
... ... @@ -679,13 +684,13 @@ void GFitsTableStringCol::alloc_data(void)
679 684 void GFitsTableStringCol::fetch_data(void) const
680 685 {
681 686 // Calculate size of memory
682   - m_size = m_number * m_length;
  687 + //m_size = m_number * m_length;
683 688  
684 689 // Free old buffer memory
685   - free_buffer();
  690 + //free_buffer();
686 691  
687 692 // Allocate buffer memory
688   - alloc_buffer();
  693 + //alloc_buffer();
689 694  
690 695 // Load column
691 696 const_cast<GFitsTableStringCol*>(this)->load_column();
... ... @@ -706,6 +711,71 @@ void GFitsTableStringCol::fetch_data(void) const
706 711  
707 712  
708 713 /***********************************************************************//**
  714 + * @brief Resize column data
  715 + *
  716 + * @param[in] index Start index.
  717 + * @param[in] number Number of elements to add/remove.
  718 + *
  719 + * Adds or removes elements from specified index on. Adding is done if
  720 + * @p number is a positive number, removing if @p number is negative.
  721 + * Note that the method does not change the validity of the arguments.
  722 + * This needs to be done by the client.
  723 + ***************************************************************************/
  724 +void GFitsTableStringCol::resize_data(const int& index, const int& number)
  725 +{
  726 + // Continue only if number of elements is not zero
  727 + if (number != 0) {
  728 +
  729 + // If data are not available then load them now
  730 + if (m_data == NULL) fetch_data();
  731 +
  732 + // If elements should be removed then do not allocate new memory
  733 + // but just move elements forward and change the logical size of
  734 + // memory. Only if all elements should be removed the memory is
  735 + // released.
  736 + if (number < 0) {
  737 + int left = index - number;
  738 + std::string* dst = m_data + index;
  739 + std::string* src = m_data + left;
  740 + int num = m_size - left;
  741 + for (int i = 0; i < num; ++i) {
  742 + *dst++ = *src++;
  743 + }
  744 + m_size += number;
  745 + if (m_size < 1) {
  746 + release_data();
  747 + }
  748 + }
  749 +
  750 + // If elements should be added then allocate new memory, copy over
  751 + // the old data and initialise the new elements
  752 + else {
  753 + int left = m_size - index;
  754 + m_size += number;
  755 + std::string* new_data = new std::string[m_size];
  756 + std::string* dst = new_data;
  757 + std::string* src = m_data;
  758 + for (int i = 0; i < index; ++i) {
  759 + *dst++ = *src++;
  760 + }
  761 + for (int i = 0; i < number; ++i) {
  762 + *dst++ = "";
  763 + }
  764 + for (int i = 0; i < left; ++i) {
  765 + *dst++ = *src++;
  766 + }
  767 + if (m_data != NULL) delete [] m_data;
  768 + m_data = new_data;
  769 + }
  770 +
  771 + } // endif: number was non-zero
  772 +
  773 + // Return
  774 + return;
  775 +}
  776 +
  777 +
  778 +/***********************************************************************//**
709 779 * @brief Release column data
710 780 ***************************************************************************/
711 781 void GFitsTableStringCol::release_data(void)
... ...
src/fits/GFitsTableULongCol.cpp
... ... @@ -619,6 +619,71 @@ void GFitsTableULongCol::fetch_data(void) const
619 619  
620 620  
621 621 /***********************************************************************//**
  622 + * @brief Resize column data
  623 + *
  624 + * @param[in] index Start index.
  625 + * @param[in] number Number of elements to add/remove.
  626 + *
  627 + * Adds or removes elements from specified index on. Adding is done if
  628 + * @p number is a positive number, removing if @p number is negative.
  629 + * Note that the method does not change the validity of the arguments.
  630 + * This needs to be done by the client.
  631 + ***************************************************************************/
  632 +void GFitsTableULongCol::resize_data(const int& index, const int& number)
  633 +{
  634 + // Continue only if number of elements is not zero
  635 + if (number != 0) {
  636 +
  637 + // If data are not available then load them now
  638 + if (m_data == NULL) fetch_data();
  639 +
  640 + // If elements should be removed then do not allocate new memory
  641 + // but just move elements forward and change the logical size of
  642 + // memory. Only if all elements should be removed the memory is
  643 + // released.
  644 + if (number < 0) {
  645 + int left = index - number;
  646 + unsigned long* dst = m_data + index;
  647 + unsigned long* src = m_data + left;
  648 + int num = m_size - left;
  649 + for (int i = 0; i < num; ++i) {
  650 + *dst++ = *src++;
  651 + }
  652 + m_size += number;
  653 + if (m_size < 1) {
  654 + release_data();
  655 + }
  656 + }
  657 +
  658 + // If elements should be added then allocate new memory, copy over
  659 + // the old data and initialise the new elements
  660 + else {
  661 + int left = m_size - index;
  662 + m_size += number;
  663 + unsigned long* new_data = new unsigned long[m_size];
  664 + unsigned long* dst = new_data;
  665 + unsigned long* src = m_data;
  666 + for (int i = 0; i < index; ++i) {
  667 + *dst++ = *src++;
  668 + }
  669 + for (int i = 0; i < number; ++i) {
  670 + *dst++ = 0;
  671 + }
  672 + for (int i = 0; i < left; ++i) {
  673 + *dst++ = *src++;
  674 + }
  675 + if (m_data != NULL) delete [] m_data;
  676 + m_data = new_data;
  677 + }
  678 +
  679 + } // endif: number was non-zero
  680 +
  681 + // Return
  682 + return;
  683 +}
  684 +
  685 +
  686 +/***********************************************************************//**
622 687 * @brief Release column data
623 688 ***************************************************************************/
624 689 void GFitsTableULongCol::release_data(void)
... ...
src/fits/GFitsTableUShortCol.cpp
... ... @@ -619,6 +619,71 @@ void GFitsTableUShortCol::fetch_data(void) const
619 619  
620 620  
621 621 /***********************************************************************//**
  622 + * @brief Resize column data
  623 + *
  624 + * @param[in] index Start index.
  625 + * @param[in] number Number of elements to add/remove.
  626 + *
  627 + * Adds or removes elements from specified index on. Adding is done if
  628 + * @p number is a positive number, removing if @p number is negative.
  629 + * Note that the method does not change the validity of the arguments.
  630 + * This needs to be done by the client.
  631 + ***************************************************************************/
  632 +void GFitsTableUShortCol::resize_data(const int& index, const int& number)
  633 +{
  634 + // Continue only if number of elements is not zero
  635 + if (number != 0) {
  636 +
  637 + // If data are not available then load them now
  638 + if (m_data == NULL) fetch_data();
  639 +
  640 + // If elements should be removed then do not allocate new memory
  641 + // but just move elements forward and change the logical size of
  642 + // memory. Only if all elements should be removed the memory is
  643 + // released.
  644 + if (number < 0) {
  645 + int left = index - number;
  646 + unsigned short* dst = m_data + index;
  647 + unsigned short* src = m_data + left;
  648 + int num = m_size - left;
  649 + for (int i = 0; i < num; ++i) {
  650 + *dst++ = *src++;
  651 + }
  652 + m_size += number;
  653 + if (m_size < 1) {
  654 + release_data();
  655 + }
  656 + }
  657 +
  658 + // If elements should be added then allocate new memory, copy over
  659 + // the old data and initialise the new elements
  660 + else {
  661 + int left = m_size - index;
  662 + m_size += number;
  663 + unsigned short* new_data = new unsigned short[m_size];
  664 + unsigned short* dst = new_data;
  665 + unsigned short* src = m_data;
  666 + for (int i = 0; i < index; ++i) {
  667 + *dst++ = *src++;
  668 + }
  669 + for (int i = 0; i < number; ++i) {
  670 + *dst++ = 0;
  671 + }
  672 + for (int i = 0; i < left; ++i) {
  673 + *dst++ = *src++;
  674 + }
  675 + if (m_data != NULL) delete [] m_data;
  676 + m_data = new_data;
  677 + }
  678 +
  679 + } // endif: number was non-zero
  680 +
  681 + // Return
  682 + return;
  683 +}
  684 +
  685 +
  686 +/***********************************************************************//**
622 687 * @brief Release column data
623 688 ***************************************************************************/
624 689 void GFitsTableUShortCol::release_data(void)
... ...
test/test_GFits.cpp
... ... @@ -208,6 +208,71 @@
208 208 col2.string(i,j)+" is not "+gammalib::str(val)); \
209 209 } \
210 210 }
  211 +#define TEST_TABLE2_BOOL \
  212 + for (int i = 0; i < nrows; ++i) { \
  213 + for (int j = 0; j < nvec; ++j) { \
  214 + col2(i,j) = (i % 2) * (j % 2); \
  215 + } \
  216 + } \
  217 + for (int i = 0; i < nrows; ++i) { \
  218 + for (int j = 0; j < nvec; ++j) { \
  219 + int ival = ((i % 2) * (j % 2)); \
  220 + std::string sval = ((i % 2) * (j % 2)) ? "T" : "F"; \
  221 + test_assert((col2(i,j) == ival), \
  222 + "Test access operator row "+gammalib::str(i)+" and element "+gammalib::str(j), \
  223 + gammalib::str(col2(i,j))+" is not "+gammalib::str(ival)); \
  224 + test_assert((col2.real(i,j) == double(ival)), \
  225 + "Test real() method for row "+gammalib::str(i)+" and element "+gammalib::str(j), \
  226 + gammalib::str(col2.real(i,j))+" is not "+gammalib::str(double(ival))); \
  227 + test_assert((col2.integer(i,j) == int(ival)), \
  228 + "Test integer() method for row "+gammalib::str(i)+" and element "+gammalib::str(j), \
  229 + gammalib::str(col2.integer(i,j))+" is not "+gammalib::str(int(ival))); \
  230 + test_assert((col2.string(i,j) == gammalib::str(ival) || col2.string(i,j) == sval), \
  231 + "Test string() method for row "+gammalib::str(i)+" and element "+gammalib::str(j), \
  232 + col2.string(i,j)+" is not "+gammalib::str(ival)+" or "+sval); \
  233 + } \
  234 + }
  235 +#define TEST_TABLE2_STRING \
  236 + for (int i = 0; i < nrows; ++i) { \
  237 + for (int j = 0; j < nvec; ++j) { \
  238 + col2(i,j) = gammalib::str(double(i)*2.3 + double(j)*11.7 + 0.95); \
  239 + } \
  240 + } \
  241 + for (int i = 0; i < nrows; ++i) { \
  242 + for (int j = 0; j < nvec; ++j) { \
  243 + double val = double(i)*2.3 + double(j)*11.7 + 0.95; \
  244 + test_value(gammalib::todouble(col2(i,j)), val, 1e-6, \
  245 + "Test access operator row "+gammalib::str(i)+" and element "+gammalib::str(j)); \
  246 + test_value(col2.real(i,j), val, 1e-6, \
  247 + "Test real() method for row "+gammalib::str(i)+" and element "+gammalib::str(j)); \
  248 + test_value(col2.integer(i,j), int(val), 1e-6, \
  249 + "Test integer() method for row "+gammalib::str(i)+" and element "+gammalib::str(j)); \
  250 + test_assert((col2.string(i,j) == gammalib::str(val)), \
  251 + "Test string() method for row "+gammalib::str(i)+" and element "+gammalib::str(j), \
  252 + col2.string(i,j)+" is not "+gammalib::str(val)); \
  253 + } \
  254 + }
  255 +#define TEST_VARTABLE \
  256 + for (int i = 0; i < nrows; ++i) { \
  257 + col3.elements(i,i+1); \
  258 + for (int j = 0; j < i+1; ++j) { \
  259 + col3(i,j) = double(i)*2.3 + double(j)*11.7 + 0.95; \
  260 + } \
  261 + } \
  262 + for (int i = 0; i < nrows; ++i) { \
  263 + for (int j = 0; j < i+1; ++j) { \
  264 + double val = double(i)*2.3 + double(j)*11.7 + 0.95; \
  265 + test_value(col3(i,j), val, 1e-6, \
  266 + "Test access operator row "+gammalib::str(i)+" and element "+gammalib::str(j)); \
  267 + test_value(col3.real(i,j), val, 1e-6, \
  268 + "Test real() method for row "+gammalib::str(i)+" and element "+gammalib::str(j)); \
  269 + test_value(col3.integer(i,j), int(val), 1e-6, \
  270 + "Test integer() method for row "+gammalib::str(i)+" and element "+gammalib::str(j)); \
  271 + test_assert((col3.string(i,j) == gammalib::str(val)), \
  272 + "Test string() method for row "+gammalib::str(i)+" and element "+gammalib::str(j), \
  273 + col3.string(i,j)+" is not "+gammalib::str(val)); \
  274 + } \
  275 + }
211 276 #define TEST_VARTABLE_INT \
212 277 for (int i = 0; i < nrows; ++i) { \
213 278 col3.elements(i,i+1); \
... ... @@ -232,48 +297,50 @@
232 297 col3.string(i,j)+" is not "+gammalib::str(val)); \
233 298 } \
234 299 }
235   -#define TEST_TABLE2_BOOL \
  300 +#define TEST_VARTABLE_BOOL \
236 301 for (int i = 0; i < nrows; ++i) { \
237   - for (int j = 0; j < nvec; ++j) { \
238   - col2(i,j) = (i % 2) * (j % 2); \
  302 + col3.elements(i,i+1); \
  303 + for (int j = 0; j < i+1; ++j) { \
  304 + col3(i,j) = (i % 2) * (j % 2); \
239 305 } \
240 306 } \
241 307 for (int i = 0; i < nrows; ++i) { \
242   - for (int j = 0; j < nvec; ++j) { \
  308 + for (int j = 0; j < i+1; ++j) { \
243 309 int ival = ((i % 2) * (j % 2)); \
244 310 std::string sval = ((i % 2) * (j % 2)) ? "T" : "F"; \
245   - test_assert((col2(i,j) == ival), \
  311 + test_assert((col3(i,j) == ival), \
246 312 "Test access operator row "+gammalib::str(i)+" and element "+gammalib::str(j), \
247   - gammalib::str(col2(i,j))+" is not "+gammalib::str(ival)); \
248   - test_assert((col2.real(i,j) == double(ival)), \
  313 + gammalib::str(col3(i,j))+" is not "+gammalib::str(ival)); \
  314 + test_assert((col3.real(i,j) == double(ival)), \
249 315 "Test real() method for row "+gammalib::str(i)+" and element "+gammalib::str(j), \
250   - gammalib::str(col2.real(i,j))+" is not "+gammalib::str(double(ival))); \
251   - test_assert((col2.integer(i,j) == int(ival)), \
  316 + gammalib::str(col3.real(i,j))+" is not "+gammalib::str(double(ival))); \
  317 + test_assert((col3.integer(i,j) == int(ival)), \
252 318 "Test integer() method for row "+gammalib::str(i)+" and element "+gammalib::str(j), \
253   - gammalib::str(col2.integer(i,j))+" is not "+gammalib::str(int(ival))); \
254   - test_assert((col2.string(i,j) == gammalib::str(ival) || col2.string(i,j) == sval), \
  319 + gammalib::str(col3.integer(i,j))+" is not "+gammalib::str(int(ival))); \
  320 + test_assert((col3.string(i,j) == gammalib::str(ival) || col3.string(i,j) == sval), \
255 321 "Test string() method for row "+gammalib::str(i)+" and element "+gammalib::str(j), \
256   - col2.string(i,j)+" is not "+gammalib::str(ival)+" or "+sval); \
  322 + col3.string(i,j)+" is not "+gammalib::str(ival)+" or "+sval); \
257 323 } \
258 324 }
259   -#define TEST_TABLE2_STRING \
  325 +#define TEST_VARTABLE_STRING \
260 326 for (int i = 0; i < nrows; ++i) { \
261   - for (int j = 0; j < nvec; ++j) { \
262   - col2(i,j) = gammalib::str(double(i)*2.3 + double(j)*11.7 + 0.95); \
  327 + col3.elements(i,i+1); \
  328 + for (int j = 0; j < i+1; ++j) { \
  329 + col3(i,j) = gammalib::str(double(i)*2.3 + double(j)*11.7 + 0.95); \
263 330 } \
264 331 } \
265 332 for (int i = 0; i < nrows; ++i) { \
266   - for (int j = 0; j < nvec; ++j) { \
  333 + for (int j = 0; j < i+1; ++j) { \
267 334 double val = double(i)*2.3 + double(j)*11.7 + 0.95; \
268   - test_value(gammalib::todouble(col2(i,j)), val, 1e-6, \
  335 + test_value(gammalib::todouble(col3(i,j)), val, 1e-6, \
269 336 "Test access operator row "+gammalib::str(i)+" and element "+gammalib::str(j)); \
270   - test_value(col2.real(i,j), val, 1e-6, \
  337 + test_value(col3.real(i,j), val, 1e-6, \
271 338 "Test real() method for row "+gammalib::str(i)+" and element "+gammalib::str(j)); \
272   - test_value(col2.integer(i,j), int(val), 1e-6, \
  339 + test_value(col3.integer(i,j), int(val), 1e-6, \
273 340 "Test integer() method for row "+gammalib::str(i)+" and element "+gammalib::str(j)); \
274   - test_assert((col2.string(i,j) == gammalib::str(val)), \
  341 + test_assert((col3.string(i,j) == gammalib::str(val)), \
275 342 "Test string() method for row "+gammalib::str(i)+" and element "+gammalib::str(j), \
276   - col2.string(i,j)+" is not "+gammalib::str(val)); \
  343 + col3.string(i,j)+" is not "+gammalib::str(val)); \
277 344 } \
278 345 }
279 346 #define TEST_WRITE_TABLES \
... ... @@ -284,6 +351,7 @@
284 351 GFitsBinTable table = GFitsBinTable(nrows); \
285 352 table.append_column(col1); \
286 353 table.insert_column(1, col2); \
  354 + table.append_column(col3); \
287 355 fits.append(table); \
288 356 fits.save(); \
289 357 fits.close(); \
... ... @@ -945,6 +1013,10 @@ void TestGFits::test_bintable_double(void)
945 1013 GFitsTableDoubleCol col2("DOUBLE10", nrows, nvec);
946 1014 TEST_TABLE2;
947 1015  
  1016 + // Test variable-length column table
  1017 + GFitsTableDoubleCol col3("DOUBLEVAR", nrows, -1);
  1018 + TEST_VARTABLE;
  1019 +
948 1020 // Write tables
949 1021 TEST_WRITE_TABLES;
950 1022  
... ... @@ -995,6 +1067,10 @@ void TestGFits::test_bintable_float(void)
995 1067 GFitsTableFloatCol col2("FLOAT10", nrows, nvec);
996 1068 TEST_TABLE2;
997 1069  
  1070 + // Test variable-length column table
  1071 + GFitsTableFloatCol col3("FLOATVAR", nrows, -1);
  1072 + TEST_VARTABLE;
  1073 +
998 1074 // Write tables
999 1075 TEST_WRITE_TABLES;
1000 1076  
... ... @@ -1101,6 +1177,10 @@ void TestGFits::test_bintable_short(void)
1101 1177 GFitsTableUShortCol col2("USHORT10", nrows, nvec);
1102 1178 TEST_TABLE2_INT;
1103 1179  
  1180 + // Test variable-length column table
  1181 + GFitsTableUShortCol col3("USHORTVAR", nrows, -1);
  1182 + TEST_VARTABLE_INT;
  1183 +
1104 1184 // Write tables
1105 1185 TEST_WRITE_TABLES;
1106 1186  
... ... @@ -1152,6 +1232,10 @@ void TestGFits::test_bintable_long(void)
1152 1232 GFitsTableLongCol col2("LONG10", nrows, nvec);
1153 1233 TEST_TABLE2_INT;
1154 1234  
  1235 + // Test variable-length column table
  1236 + GFitsTableLongCol col3("LONGVAR", nrows, -1);
  1237 + TEST_VARTABLE_INT;
  1238 +
1155 1239 // Write tables
1156 1240 TEST_WRITE_TABLES;
1157 1241  
... ... @@ -1203,6 +1287,10 @@ void TestGFits::test_bintable_longlong(void)
1203 1287 GFitsTableLongLongCol col2("LONGLONG10", nrows, nvec);
1204 1288 TEST_TABLE2_INT;
1205 1289  
  1290 + // Test variable-length column table
  1291 + GFitsTableLongLongCol col3("LONGLONGVAR", nrows, -1);
  1292 + TEST_VARTABLE_INT;
  1293 +
1206 1294 // Write tables
1207 1295 TEST_WRITE_TABLES;
1208 1296  
... ... @@ -1254,6 +1342,10 @@ void TestGFits::test_bintable_ulong(void)
1254 1342 GFitsTableULongCol col2("ULONG10", nrows, nvec);
1255 1343 TEST_TABLE2_INT;
1256 1344  
  1345 + // Test variable-length column table
  1346 + GFitsTableULongCol col3("ULONGVAR", nrows, -1);
  1347 + TEST_VARTABLE_INT;
  1348 +
1257 1349 // Write tables
1258 1350 TEST_WRITE_TABLES;
1259 1351  
... ... @@ -1305,6 +1397,11 @@ void TestGFits::test_bintable_string(void)
1305 1397 GFitsTableStringCol col2("STRING10", nrows, 20, nvec);
1306 1398 TEST_TABLE2_STRING;
1307 1399  
  1400 + // Test variable-length column table
  1401 + GFitsTableStringCol col3("STRINGVAR", nrows, 1);
  1402 + //GFitsTableStringCol col3("STRINGVAR", nrows, -1);
  1403 + //TEST_VARTABLE_STRING;
  1404 +
1308 1405 // Write tables
1309 1406 TEST_WRITE_TABLES;
1310 1407  
... ... @@ -1356,6 +1453,10 @@ void TestGFits::test_bintable_logical(void)
1356 1453 GFitsTableBoolCol col2("LOGICAL10", nrows, nvec);
1357 1454 TEST_TABLE2_BOOL;
1358 1455  
  1456 + // Test variable-length column table
  1457 + GFitsTableBoolCol col3("LOGICALVAR", nrows, -1);
  1458 + TEST_VARTABLE_BOOL;
  1459 +
1359 1460 // Write tables
1360 1461 TEST_WRITE_TABLES;
1361 1462  
... ... @@ -1407,6 +1508,10 @@ void TestGFits::test_bintable_bit(void)
1407 1508 GFitsTableBitCol col2("BIT10", nrows, nvec);
1408 1509 TEST_TABLE2_BOOL;
1409 1510  
  1511 + // Test variable-length column table
  1512 + GFitsTableBitCol col3("BITVAR", nrows, -1);
  1513 + //TEST_VARTABLE_BOOL;
  1514 +
1410 1515 // Write tables
1411 1516 TEST_WRITE_TABLES;
1412 1517  
... ...