/* ----------------------------------------------------------------------- *//** * * @file ArrayHandle_impl.hpp * *//* ----------------------------------------------------------------------- */ #ifndef MADLIB_POSTGRES_ARRAYHANDLE_IMPL_HPP #define MADLIB_POSTGRES_ARRAYHANDLE_IMPL_HPP namespace madlib { namespace dbconnector { namespace postgres { template inline ArrayHandle::ArrayHandle(ArrayType *inArray): mArray(inArray) { if (inArray == NULL) { mData = NULL; mNumElems = -1; mElemLen = -1; mElemByVal = false; mElemAlign = -1; } else { madlib_get_typlenbyvalalign(ARR_ELEMTYPE(inArray), &mElemLen, &mElemByVal, &mElemAlign); if (mElemByVal) { mData = reinterpret_cast(ARR_DATA_PTR(inArray)); mNumElems = static_cast(this->size()); } else { // FIXME deallocate memory for datum_ptr and mData! Datum *datum_ptr; deconstruct_array(inArray, ARR_ELEMTYPE(inArray), mElemLen, mElemByVal, mElemAlign, &datum_ptr, NULL, &mNumElems); mData = new T[mNumElems]; for (int i = 0; i < mNumElems; i ++) { varlena *detoast_ptr = PG_DETOAST_DATUM(datum_ptr[i]); char *index_ptr = reinterpret_cast(&detoast_ptr); mData[i] = *(reinterpret_cast(index_ptr)); } } } } template inline const T* ArrayHandle::ptr() const { if (mArray == NULL) { return NULL; } if (mElemByVal) { return reinterpret_cast(ARR_DATA_PTR(mArray)); } else { return reinterpret_cast(mData); } } template inline size_t ArrayHandle::size() const { madlib_assert(ptr() != NULL, std::runtime_error( "Attempt to getting size() of a NULL array detected.")); // An empty array has dimensionality 0. size_t arraySize = ARR_NDIM(mArray) ? 1 : 0; for (int i = 0; i < ARR_NDIM(mArray); ++i) { arraySize *= ARR_DIMS(mArray)[i]; } return arraySize; } template inline size_t ArrayHandle::dims() const { madlib_assert(ptr() != NULL, std::runtime_error( "Attempt to getting dims() of a NULL array detected.")); return ARR_NDIM(mArray); } template inline size_t ArrayHandle::sizeOfDim(size_t inDim) const { if (inDim >= dims()) { throw std::invalid_argument("Invalid dimension."); } return ARR_DIMS(mArray)[inDim]; } template inline const ArrayType* ArrayHandle::array() const { return mArray; } template inline const T& ArrayHandle::operator[](size_t inIndex) const { madlib_assert(ptr() != NULL, std::runtime_error( "Indexing (operator[]) into a NULL array detected.")); madlib_assert(inIndex < size(), std::runtime_error( "Out-of-bounds array access detected.")); return ptr()[inIndex]; } template inline T* MutableArrayHandle::ptr() { return const_cast(static_cast*>(this)->ptr()); } template inline ArrayType* MutableArrayHandle::array() { return const_cast< ArrayType* >(Base::mArray); } template inline T& MutableArrayHandle::operator[](size_t inIndex) { return const_cast( static_cast*>(this)->operator[](inIndex) ); } } // namespace postgres } // namespace dbconnector } // namespace madlib #endif // defined(MADLIB_POSTGRES_ARRAYHANDLE_IMPL_HPP)