text:
#include "GenerationInfoList.h"
#include <macgyver/Exception.h>
#include <grid-files/common/GeneralFunctions.h>
#include <grid-files/common/AutoWriteLock.h>
#include <grid-files/common/AutoThreadLock.h>
#include <grid-files/common/AutoReadLock.h>
#include <grid-files/common/ShowFunction.h>
#include <boost/functional/hash.hpp>

#define FUNCTION_TRACE FUNCTION_TRACE_OFF

namespace SmartMet
{
namespace T
{

int generationInfo_compare_1(const void *_val1,const void *_val2)
{
  if (_val1 != nullptr  &&  _val2 != nullptr)
  {
    GenerationInfoPtr *obj1 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val1));
    GenerationInfoPtr *obj2 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val2));

    return (*obj1)->compare(1,(*obj2));
  }
  return 0;
}

int generationInfo_compare_2(const void *_val1,const void *_val2)
{
  if (_val1 != nullptr  &&  _val2 != nullptr)
  {
    GenerationInfoPtr *obj1 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val1));
    GenerationInfoPtr *obj2 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val2));

    return (*obj1)->compare(2,(*obj2));
  }
  return 0;
}

int generationInfo_compare_3(const void *_val1,const void *_val2)
{
  if (_val1 != nullptr  &&  _val2 != nullptr)
  {
    GenerationInfoPtr *obj1 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val1));
    GenerationInfoPtr *obj2 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val2));

    return (*obj1)->compare(3,(*obj2));
  }
  return 0;
}

int generationInfo_compare_4(const void *_val1,const void *_val2)
{
  if (_val1 != nullptr  &&  _val2 != nullptr)
  {
    GenerationInfoPtr *obj1 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val1));
    GenerationInfoPtr *obj2 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val2));

    return (*obj1)->compare(4,(*obj2));
  }
  return 0;
}

int generationInfo_compare_5(const void *_val1,const void *_val2)
{
  if (_val1 != nullptr  &&  _val2 != nullptr)
  {
    GenerationInfoPtr *obj1 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val1));
    GenerationInfoPtr *obj2 = const_cast<GenerationInfoPtr*>(reinterpret_cast<const GenerationInfoPtr *>(_val2));

    return (*obj1)->compare(5,(*obj2));
  }
  return 0;
}

GenerationInfoList::GenerationInfoList()
{
  FUNCTION_TRACE
  try
  {
    mModificationLockPtr = &mModificationLock;
    mReleaseObjects = true;
    mComparisonMethod = GenerationInfo::ComparisonMethod::none;
    mSize = 0;
    mLength = 0;
    mArray = nullptr;
    mModificationLock.setLockingEnabled(false);
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfoList::GenerationInfoList(GenerationInfoList& generationInfoList)
{
  FUNCTION_TRACE
  try
  {
    mModificationLock.setLockingEnabled(false);
    mModificationLockPtr = &mModificationLock;
    if (generationInfoList.getModificationLockPtr() != mModificationLockPtr)
      generationInfoList.lock();

    mReleaseObjects = true;
    mArray = nullptr;
    mSize = generationInfoList.getSize();
    mLength = generationInfoList.getLength();
    mComparisonMethod = generationInfoList.mComparisonMethod;
    if (mSize > 0)
    {
      mArray = new GenerationInfoPtr[mSize];

      for (uint t=0; t<mSize; t++)
      {
        GenerationInfo *info = generationInfoList.getGenerationInfoByIndexNoCheck(t);
        if (info != nullptr && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        {
          mArray[t] = info->duplicate();
        }
        else
        {
          mArray[t] = nullptr;
        }
      }
    }
    if (generationInfoList.getModificationLockPtr() != mModificationLockPtr)
      generationInfoList.unlock();
  }
  catch (...)
  {
    generationInfoList.unlock();
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfoList::~GenerationInfoList()
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr)
      return;

    AutoWriteLock lock(mModificationLockPtr);
    if (mReleaseObjects && mLength > 0)
    {
      for (uint t=0; t<mLength; t++)
      {
        if (mArray[t] != nullptr  &&  mReleaseObjects)
          delete mArray[t];
      }
    }
    delete[] mArray;
  }
  catch (...)
  {
    Fmi::Exception exception(BCP,"Destructor failed",nullptr);
    exception.printError();
  }
}

GenerationInfoList& GenerationInfoList::operator=(GenerationInfoList& generationInfoList)
{
  FUNCTION_TRACE
  try
  {
    if (&generationInfoList == this)
      return *this;

    clear();

    AutoWriteLock lock(mModificationLockPtr);

    if (generationInfoList.getModificationLockPtr() != mModificationLockPtr)
      generationInfoList.lock();

    mArray = nullptr;
    uint p = 0;
    mSize = generationInfoList.getSize();
    mLength = generationInfoList.getLength();
    mComparisonMethod = generationInfoList.mComparisonMethod;
    if (mSize > 0)
    {
      mArray = new GenerationInfoPtr[mSize];

      for (uint t=0; t<mSize; t++)
      {
        mArray[t] = nullptr;
        GenerationInfo *info = generationInfoList.getGenerationInfoByIndexNoCheck(t);
        if (info != nullptr && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        {
          if (mReleaseObjects)
            mArray[p] = info->duplicate();
          else
            mArray[p] = info;

          p++;
        }
      }
    }
    if (generationInfoList.getModificationLockPtr() != mModificationLockPtr)
      generationInfoList.unlock();

    mLength = p;
    return *this;
  }
  catch (...)
  {
    generationInfoList.unlock();
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::setModificationLockPtr(ModificationLock* modificationLockPtr)
{
  FUNCTION_TRACE
  try
  {
    if (modificationLockPtr != nullptr)
      mModificationLockPtr = modificationLockPtr;
    else
      mModificationLockPtr = &mModificationLock;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

ModificationLock*  GenerationInfoList::getModificationLockPtr()
{
  FUNCTION_TRACE
  try
  {
    return mModificationLockPtr;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::lock()
{
  FUNCTION_TRACE
  try
  {
    return mModificationLockPtr->lock();
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::unlock()
{
  FUNCTION_TRACE
  try
  {
    return mModificationLockPtr->unlock();
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::addGenerationInfo(GenerationInfo *generationInfo)
{
  FUNCTION_TRACE
  try
  {
    if (generationInfo == nullptr)
      return nullptr;

    AutoWriteLock lock(mModificationLockPtr);

    if (mArray == nullptr  ||  mLength == mSize)
    {
      increaseSize(mSize + mSize/5 + 10);
    }

    if (mComparisonMethod == GenerationInfo::ComparisonMethod::none)
    {
      mArray[mLength] = generationInfo;
      mLength++;
      return generationInfo;
    }

    int idx = getClosestIndexNoLock(mComparisonMethod,*generationInfo);

    if (idx < C_INT(mLength)  &&  mArray[idx] != nullptr  &&   mArray[idx]->compare(mComparisonMethod,generationInfo) == 0)
    {
      // If generation with the same id exists, we should not add the new content, because other generationLists might point
      // the existing generation record;

      return mArray[idx];
    }

    while (idx < C_INT(mLength)  &&  mArray[idx] != nullptr  &&   mArray[idx]->compare(mComparisonMethod,generationInfo) < 0)
    {
      idx++;
    }

    if (idx == C_INT(mLength))
    {
      mArray[mLength] = generationInfo;
      mLength++;
      return generationInfo;
    }

    if (idx < C_INT(mLength))
      memmove(&mArray[idx+1],&mArray[idx],sizeof(void*)*(mLength-idx));

    mArray[idx] = generationInfo;
    mLength++;
    return generationInfo;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::increaseSize(uint newSize)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr)
    {
      mSize = newSize;
      mLength = 0;
      mArray = new GenerationInfoPtr[mSize];

      for (uint t=0; t<mSize; t++)
      {
        mArray[t] = nullptr;
      }
      return;
    }

    GenerationInfoPtr *newArray = new GenerationInfoPtr[newSize];
    for (uint t=0; t<newSize; t++)
    {
      if (t < mSize)
      {
        newArray[t] = mArray[t];
      }
      else
      {
        newArray[t] = nullptr;
      }
    }

    delete[] mArray;
    mArray = newArray;
    mSize = newSize;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::clear()
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr)
      return;

    AutoWriteLock lock(mModificationLockPtr);
    if (mReleaseObjects && mLength > 0)
    {
      for (uint t=0; t<mLength; t++)
      {
        if (mArray[t] != nullptr)
          delete mArray[t];

        mArray[t] = nullptr;
      }
    }
    delete[] mArray;
    mArray = nullptr;
    mSize = 0;
    mLength = 0;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

int GenerationInfoList::getClosestIndex(uint comparisonMethod,GenerationInfo& generationInfo)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return 0;

    AutoReadLock lock(mModificationLockPtr);
    return getClosestIndexNoLock(comparisonMethod,generationInfo);
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

int GenerationInfoList::getClosestIndexNoLock(uint comparisonMethod,GenerationInfo& generationInfo)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr  ||  mLength == 0)
      return 0;

    if (comparisonMethod != mComparisonMethod)
    {
      for (uint t=0; t<mLength; t++)
      {
        if (mArray[t] != nullptr)
        {
          int res = mArray[t]->compare(comparisonMethod,&generationInfo);
          if (res == 0)
          {
            return t;
          }
        }
      }
      return 0;
    }

    int low = 0;
    int high = C_INT(mLength) - 1;
    int mid = 0;

    while (low <= high)
    {
      mid = (low + high) / 2;
      int res = mArray[mid]->compare(comparisonMethod,&generationInfo);

      if (res == 0)
      {
        while (mid > 0  &&  mArray[mid-1]->compare(comparisonMethod,&generationInfo) == 0)
          mid--;

        return mid;
      }

      if (res < 0)
        low = mid + 1;
      else
        high = mid - 1;
    }

    if (mid >= 0  &&  mid < C_INT(mLength))
    {
      if (mArray[mid]->compare(comparisonMethod,&generationInfo) < 0)
      {
        while (mid < C_INT(mLength)  &&  mArray[mid] != nullptr  &&   mArray[mid]->compare(comparisonMethod,&generationInfo) < 0)
          mid++;

        return mid-1;
      }
      else
      {
        while (mid > 0  &&  mArray[mid] != nullptr  &&   mArray[mid]->compare(comparisonMethod,&generationInfo) > 0)
          mid--;

        return mid;
      }
    }
    return 0;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

bool GenerationInfoList::deleteGenerationInfoById(uint generationId)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return false;

    AutoWriteLock lock(mModificationLockPtr);

    GenerationInfo search;
    search.mGenerationId = generationId;
    int idx = getClosestIndexNoLock(GenerationInfo::ComparisonMethod::generationId,search);
    if (idx < 0 ||  idx >= C_INT(mLength))
      return false;

    GenerationInfo *info = mArray[idx];
    if (info->mGenerationId != generationId)
      return false;

    for (uint t=C_UINT(idx)+1; t<mLength; t++)
    {
      mArray[t-1] = mArray[t];
      mArray[t] = nullptr;
    }

    if (mReleaseObjects)
      delete info;

    mLength--;
    return true;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

uint GenerationInfoList::deleteGenerationInfoListByProducerId(uint producerId)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return 0;

    AutoWriteLock lock(mModificationLockPtr);
    uint p = 0;
    uint cnt = 0;
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      mArray[t] = nullptr;
      if (info != nullptr)
      {
        if (info->mProducerId == producerId)
        {
          cnt++;
          if (mReleaseObjects)
            delete info;
        }
        else
        {
          mArray[p] = info;
          p++;
        }
      }
    }
    mLength = p;
    return cnt;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

uint GenerationInfoList::deleteMarkedGenerations()
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return 0;

    AutoWriteLock lock(mModificationLockPtr);
    uint p = 0;
    uint cnt = 0;
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      mArray[t] = nullptr;
      if (info != nullptr)
      {
        if (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration)
        {
          cnt++;
          if (mReleaseObjects)
            delete info;
        }
        else
        {
          mArray[p] = info;
          p++;
        }
      }
    }
    mLength = p;
    return cnt;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

uint GenerationInfoList::markDeleted()
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return 0;

    AutoWriteLock lock(mModificationLockPtr);
    uint cnt = 0;
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr)
      {
        info->mFlags |= T::GenerationInfo::Flags::DeletedGeneration;
        cnt++;
      }
    }
    return cnt;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

uint GenerationInfoList::markDeletedByProducerId(uint producerId)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return 0;

    AutoWriteLock lock(mModificationLockPtr);
    uint cnt = 0;
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr)
      {
        if (info->mProducerId == producerId)
        {
          info->mFlags |= T::GenerationInfo::Flags::DeletedGeneration;
          cnt++;
        }
      }
    }
    return cnt;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

uint GenerationInfoList::markDeletedBySourceId(uint sourceId)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return 0;

    AutoWriteLock lock(mModificationLockPtr);
    uint cnt = 0;
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr)
      {
        if (info->mSourceId == sourceId)
        {
          info->mFlags |= T::GenerationInfo::Flags::DeletedGeneration;
          cnt++;
        }
      }
    }
    return cnt;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

uint GenerationInfoList::markDeletedById(uint generationId)
{
  FUNCTION_TRACE
  try
  {
    AutoReadLock lock(mModificationLockPtr);

    GenerationInfo *info  = getGenerationInfoById(generationId);
    if (info != nullptr)
    {
      info->mFlags |= T::GenerationInfo::Flags::DeletedGeneration;
      return 1;
    }
    return 0;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::getGenerationInfoById(uint generationId)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return nullptr;

    AutoReadLock lock(mModificationLockPtr);

    GenerationInfo search;
    search.mGenerationId = generationId;
    int idx = getClosestIndexNoLock(GenerationInfo::ComparisonMethod::generationId,search);
    if (idx < 0  ||  C_UINT(idx) >= getLength())
      return nullptr;

    GenerationInfo *info = getGenerationInfoByIndexNoCheck(idx);
    if (info != nullptr  &&  info->mGenerationId == generationId && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
      return info;

    return nullptr;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

bool GenerationInfoList::getGenerationInfoById(uint generationId,GenerationInfo& generationInfo)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return false;

    AutoReadLock lock(mModificationLockPtr);

    GenerationInfo search;
    search.mGenerationId = generationId;
    int idx = getClosestIndexNoLock(GenerationInfo::ComparisonMethod::generationId,search);
    if (idx < 0  ||  C_UINT(idx) >= getLength())
      return false;

    GenerationInfo *info = getGenerationInfoByIndexNoCheck(idx);
    if (info != nullptr  &&  info->mGenerationId == generationId && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
    {
      generationInfo = *info;
      return true;
    }

    return false;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

uint GenerationInfoList::deleteGenerationInfoListBySourceId(uint sourceId)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return 0;

    AutoWriteLock lock(mModificationLockPtr);
    uint p = 0;
    uint cnt = 0;
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      mArray[t] = nullptr;
      if (info != nullptr)
      {
        if (info->mSourceId == sourceId)
        {
          cnt++;
          if (mReleaseObjects)
            delete info;
        }
        else
        {
          mArray[p] = info;
          p++;
        }
      }
    }
    mLength = p;
    return cnt;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::getGenerationInfoByIndex(uint index)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return nullptr;

    AutoReadLock lock(mModificationLockPtr);
    if (index >= mLength)
      return nullptr;

    return mArray[index];
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::getGenerationInfoByIndexNoCheck(uint index)
{
  FUNCTION_TRACE
  try
  {
    return mArray[index];
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::getGenerationInfoByName(const std::string& generationName)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return nullptr;

    AutoReadLock lock(mModificationLockPtr);
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  strcasecmp(info->mName.c_str(),generationName.c_str()) == 0 && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        return info;
    }
    return nullptr;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

bool GenerationInfoList::getGenerationInfoByName(const std::string& generationName,GenerationInfo& generationInfo)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return false;

    AutoReadLock lock(mModificationLockPtr);
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  strcasecmp(info->mName.c_str(),generationName.c_str()) == 0 && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
      {
        generationInfo = *info;
        return true;
      }
    }
    return false;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::getGenerationInfoByAnalysisTime(uint generationId,const std::string& analysisTime)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return nullptr;

    AutoReadLock lock(mModificationLockPtr);

    if (mComparisonMethod == T::GenerationInfo::ComparisonMethod::analysisTime_generationId)
    {
      GenerationInfo search;
      search.mGenerationId = generationId;
      search.mAnalysisTime = analysisTime;
      int idx = getClosestIndexNoLock(mComparisonMethod,search);
      if (idx >= 0  ||  C_UINT(idx) < getLength())
      {
        GenerationInfo *info = getGenerationInfoByIndexNoCheck(idx);
        if (info != nullptr  &&  info->mAnalysisTime == analysisTime  && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
          return info;
      }
      return nullptr;
    }

    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mAnalysisTime ==  analysisTime && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        return info;
    }
    return nullptr;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::getGenerationInfoByAnalysisTime(const std::string& analysisTime)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return nullptr;

    AutoReadLock lock(mModificationLockPtr);

    if (mComparisonMethod == T::GenerationInfo::ComparisonMethod::analysisTime)
    {
      GenerationInfo search;
      search.mAnalysisTime = analysisTime;
      int idx = getClosestIndexNoLock(T::GenerationInfo::ComparisonMethod::analysisTime,search);
      if (idx >= 0  ||  C_UINT(idx) < getLength())
      {
        GenerationInfo *info = getGenerationInfoByIndexNoCheck(idx);
        if (info != nullptr  &&  info->mAnalysisTime == analysisTime  && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
          return info;
      }
      return nullptr;
    }

    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mAnalysisTime ==  analysisTime && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        return info;
    }
    return nullptr;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

int GenerationInfoList::getGenerationInfoIndexByAnalysisTime(uint generationId,const std::string& analysisTime)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return -1;

    AutoReadLock lock(mModificationLockPtr);

    if (mComparisonMethod == T::GenerationInfo::ComparisonMethod::analysisTime_generationId)
    {
      GenerationInfo search;
      search.mGenerationId = generationId;
      search.mAnalysisTime = analysisTime;
      int idx = getClosestIndexNoLock(mComparisonMethod,search);
      if (idx >= 0  ||  C_UINT(idx) < getLength())
      {
        GenerationInfo *info = getGenerationInfoByIndexNoCheck(idx);
        if (info != nullptr  &&  info->mAnalysisTime == analysisTime  && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
          return idx;
      }
      return -1;
    }

    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mAnalysisTime == analysisTime && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        return t;

    }
    return -1;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

int GenerationInfoList::getGenerationInfoIndexByAnalysisTime(const std::string& analysisTime)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return -1;

    AutoReadLock lock(mModificationLockPtr);

    if (mComparisonMethod == T::GenerationInfo::ComparisonMethod::analysisTime)
    {
      GenerationInfo search;
      search.mAnalysisTime = analysisTime;
      int idx = getClosestIndexNoLock(mComparisonMethod,search);
      if (idx >= 0  ||  C_UINT(idx) < getLength())
      {
        GenerationInfo *info = getGenerationInfoByIndexNoCheck(idx);
        if (info != nullptr  &&  info->mAnalysisTime == analysisTime  && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
          return idx;
      }
      return -1;
    }

    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mAnalysisTime == analysisTime && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        return t;

    }
    return -1;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

int GenerationInfoList::getGenerationInfoIndexByGenerationId(uint generationId)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return -1;

    AutoReadLock lock(mModificationLockPtr);
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mGenerationId == generationId && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        return t;
    }
    return -1;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::getGenerationInfoListByProducerId(uint producerId,GenerationInfoList& generationInfoList)
{
  FUNCTION_TRACE
  try
  {
    generationInfoList.clear();

    if (mArray == nullptr ||  mLength == 0)
      return;

    AutoReadLock lock(mModificationLockPtr);

    int len =  getLength();
    int idx = 0;

    if (mComparisonMethod == GenerationInfo::ComparisonMethod::producerId)
    {
      GenerationInfo search;
      search.mProducerId = producerId;

      idx = getClosestIndexNoLock(GenerationInfo::ComparisonMethod::producerId,search);
      if (idx < 0  || idx >= len)
        return;

    }

    for (int t=idx; t<len; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr)
      {
        if (info->mProducerId == producerId && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        {
          if (generationInfoList.getReleaseObjects())
            generationInfoList.addGenerationInfo(info->duplicate());
          else
            generationInfoList.addGenerationInfo(info);
        }
        else
        {
          if (mComparisonMethod == GenerationInfo::ComparisonMethod::producerId  &&  info->mProducerId > producerId)
            return;
        }
      }
    }
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

std::size_t GenerationInfoList::getHash()
{
  FUNCTION_TRACE
  try
  {
    std::size_t hash = 0;
    if (mArray == nullptr ||  mLength == 0)
      return hash;

    AutoReadLock lock(mModificationLockPtr);

    int len = getLength();
    for (int t=0; t<len; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
      {
        boost::hash_combine(hash,info->mGenerationId);
        boost::hash_combine(hash,info->mStatus);
      }
    }
    return hash;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

std::size_t GenerationInfoList::getHashByProducerId(uint producerId)
{
  FUNCTION_TRACE
  try
  {
    std::size_t hash = 0;
    if (mArray == nullptr ||  mLength == 0)
      return hash;

    AutoReadLock lock(mModificationLockPtr);

    int len =  getLength();
    int idx = 0;

    if (mComparisonMethod == GenerationInfo::ComparisonMethod::producerId)
    {
      GenerationInfo search;
      search.mProducerId = producerId;

      idx = getClosestIndexNoLock(GenerationInfo::ComparisonMethod::producerId,search);
      if (idx < 0  || idx >= len)
        return hash;

    }

    for (int t=idx; t<len; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr)
      {
        if (info->mProducerId == producerId && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        {
          boost::hash_combine(hash,info->mGenerationId);
          boost::hash_combine(hash,info->mStatus);
        }
        else
        {
          if (mComparisonMethod == GenerationInfo::ComparisonMethod::producerId  &&  info->mProducerId > producerId)
            return hash;
        }
      }
    }
    return hash;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::getGenerationInfoListByProducerIdAndStatus(uint producerId,GenerationInfoList& generationInfoList,uchar generationStatus)
{
  FUNCTION_TRACE
  try
  {
    generationInfoList.clear();

    if (mArray == nullptr ||  mLength == 0)
      return;

    AutoReadLock lock(mModificationLockPtr);

    int len =  getLength();
    int idx = 0;

    if (mComparisonMethod == GenerationInfo::ComparisonMethod::producerId)
    {
      GenerationInfo search;
      search.mProducerId = producerId;

      idx = getClosestIndexNoLock(GenerationInfo::ComparisonMethod::producerId,search);
      if (idx < 0  || idx >= len)
        return;

    }

    for (int t=idx; t<len; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr)
      {
        if (info->mProducerId == producerId  &&  info->mStatus == generationStatus && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        {
          if (generationInfoList.getReleaseObjects())
            generationInfoList.addGenerationInfo(info->duplicate());
          else
            generationInfoList.addGenerationInfo(info);
        }
        else
        {
          if (mComparisonMethod == GenerationInfo::ComparisonMethod::producerId  &&  info->mProducerId > producerId)
            return;
        }
      }
    }
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::getGenerationInfoListByAnalysisTime(const std::string& analysisTime,GenerationInfoList& generationInfoList)
{
  FUNCTION_TRACE
  try
  {
    generationInfoList.clear();

    if (mArray == nullptr ||  mLength == 0)
      return;

    AutoReadLock lock(mModificationLockPtr);
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mAnalysisTime == analysisTime && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
      {
        if (generationInfoList.getReleaseObjects())
          generationInfoList.addGenerationInfo(info->duplicate());
        else
          generationInfoList.addGenerationInfo(info);
      }
    }
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::getLastGenerationInfoByProducerIdAndStatus(uint producerId,uchar generationStatus)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return nullptr;

    AutoReadLock lock(mModificationLockPtr);
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mProducerId == producerId  &&  info->mStatus == generationStatus && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        return info;
    }
    return nullptr;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

bool GenerationInfoList::getLastGenerationInfoByProducerIdAndStatus(uint producerId,uchar generationStatus,T::GenerationInfo& generationInfo)
{
  FUNCTION_TRACE
  try
  {
    GenerationInfo *info = getLastGenerationInfoByProducerIdAndStatus(producerId,generationStatus);
    if (info == nullptr)
      return false;

    generationInfo = *info;
    return true;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::getLastGenerationInfoByAnalysisTime()
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return nullptr;

    AutoReadLock lock(mModificationLockPtr);
    T::GenerationInfo *generationInfo = nullptr;
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
      {
        if (generationInfo == nullptr  ||  generationInfo->mAnalysisTime < info->mAnalysisTime)
          generationInfo = info;
      }
    }
    return generationInfo;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo* GenerationInfoList::getLastGenerationInfoByProducerId(uint producerId)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return nullptr;

    AutoReadLock lock(mModificationLockPtr);
    T::GenerationInfo *generationInfo = nullptr;
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mProducerId == producerId && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
      {
        if (generationInfo == nullptr  ||  generationInfo->mName < info->mName)
          generationInfo = info;
      }
    }
    return generationInfo;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

GenerationInfo*  GenerationInfoList::getPrevGenerationInfoByProducerId(uint producerId,const std::string& nextGenerationName)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return nullptr;

    AutoReadLock lock(mModificationLockPtr);
    T::GenerationInfo *generationInfo = nullptr;
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mProducerId == producerId && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
      {
        if ((generationInfo == nullptr  &&  info->mName < nextGenerationName)  ||  (generationInfo != nullptr  &&  generationInfo->mName < info->mName  &&  info->mName < nextGenerationName))
          generationInfo = info;
      }
    }
    return generationInfo;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::getGenerationInfoListBySourceId(uint sourceId,GenerationInfoList& generationInfoList)
{
  FUNCTION_TRACE
  try
  {
    generationInfoList.clear();

    if (mArray == nullptr ||  mLength == 0)
      return;

    AutoReadLock lock(mModificationLockPtr);
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr  &&  info->mSourceId == sourceId && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
      {
        if (generationInfoList.getReleaseObjects())
          generationInfoList.addGenerationInfo(info->duplicate());
        else
          generationInfoList.addGenerationInfo(info);
      }
    }
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

uint GenerationInfoList::getLength()
{
  FUNCTION_TRACE
  try
  {
    return mLength;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

uint GenerationInfoList::getSize() const
{
  FUNCTION_TRACE
  try
  {
    return mSize;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

bool GenerationInfoList::getReleaseObjects()
{
  FUNCTION_TRACE
  try
  {
    return mReleaseObjects;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::setReleaseObjects(bool releaseObjects)
{
  FUNCTION_TRACE
  try
  {
    mReleaseObjects = releaseObjects;
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::getAnalysisTimes(std::vector<std::string>& analysisTimes,bool reverseOrder)
{
  FUNCTION_TRACE
  try
  {
    if (mArray == nullptr ||  mLength == 0)
      return;

    AutoReadLock lock(mModificationLockPtr);

    std::set<std::string> newList;

    uint sz = getLength();
    for (uint t=0; t<sz; t++)
    {
      GenerationInfo *info = getGenerationInfoByIndexNoCheck(t);
      if (info != nullptr && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
      newList.insert(info->mAnalysisTime);
    }

    analysisTimes.reserve(sz);
    if (!reverseOrder)
    {
      for (auto it = newList.begin(); it != newList.end(); ++it)
      {
        analysisTimes.emplace_back(*it);
      }
    }
    else
    {
      for (auto it = newList.rbegin(); it != newList.rend(); ++it)
      {
        analysisTimes.emplace_back(*it);
      }
    }
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::setLockingEnabled(bool lockingEnabled)
{
  FUNCTION_TRACE
  try
  {
    mModificationLock.setLockingEnabled(lockingEnabled);
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::setComparisonMethod(uint comparisonMethod)
{
  FUNCTION_TRACE
  try
  {
    if (mComparisonMethod == comparisonMethod)
      return;

    sort(comparisonMethod);
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::sort(uint comparisonMethod)
{
  FUNCTION_TRACE
  try
  {
    if (mComparisonMethod == comparisonMethod)
      return;

    AutoWriteLock lock(mModificationLockPtr);
    mComparisonMethod = comparisonMethod;

    if (mArray == nullptr || mLength < 2)
      return;

    switch (comparisonMethod)
    {
      case 1:
        qsort(mArray,mLength,sizeof(GenerationInfoPtr),generationInfo_compare_1);
        break;
      case 2:
        qsort(mArray,mLength,sizeof(GenerationInfoPtr),generationInfo_compare_2);
        break;
      case 3:
        qsort(mArray,mLength,sizeof(GenerationInfoPtr),generationInfo_compare_3);
        break;
      case 4:
        qsort(mArray,mLength,sizeof(GenerationInfoPtr),generationInfo_compare_4);
        break;
      case 5:
        qsort(mArray,mLength,sizeof(GenerationInfoPtr),generationInfo_compare_5);
        break;
    }
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::writeToFile(const std::string& filename)
{
  FUNCTION_TRACE
  try
  {
    AutoReadLock lock(mModificationLockPtr);

    FILE *file = fopen(filename.c_str(),"we");
    if (file == nullptr)
    {
      Fmi::Exception exception(BCP,"Cannot create the file!");
      exception.addParameter("Filename",filename);
      throw exception;
    }

    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr && (info->mFlags & T::GenerationInfo::Flags::DeletedGeneration) == 0)
        fprintf(file,"%s\n",info->getCsv().c_str());
    }
    fclose(file);
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

void GenerationInfoList::print(std::ostream& stream,uint level,uint optionFlags)
{
  FUNCTION_TRACE
  try
  {
    AutoReadLock lock(mModificationLockPtr);

    stream << space(level) << "GenerationInfoList\n";
    stream << space(level) << "- mComparisonMethod  = " << mComparisonMethod << "\n";
    for (uint t=0; t<mLength; t++)
    {
      GenerationInfo *info = mArray[t];
      if (info != nullptr)
        info->print(stream,level+1,optionFlags);
    }
  }
  catch (...)
  {
    throw Fmi::Exception(BCP,"Operation failed!",nullptr);
  }
}

}
}

max_stars_repo_name: fmidev/smartmet-library-grid-content

max_issues_repo_name: fmidev/smartmet-library-grid-content

max_forks_repo_name: fmidev/smartmet-library-grid-content


text: #include <boost/fusion/algorithm/query/none.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
//---------------------------------------------------------------------------//
// Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
//
// Distributed under the Boost Software License, Version 1.0
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//---------------------------------------------------------------------------//

#ifndef CRYPTO3_DECODE_HPP
#define CRYPTO3_DECODE_HPP

#include <boost/crypto3/codec/algorithm/codec.hpp>

#include <boost/crypto3/codec/codec_value.hpp>
#include <boost/crypto3/codec/codec_state.hpp>

#include <boost/crypto3/detail/type_traits.hpp>

namespace boost {
    namespace crypto3 {
        /*!
         * @brief Decodes the elements with particular codec defined with Decoder
         * in the range, defined by [first, last), and inserts the result to
         * another range beginning at out.
         *
         * @ingroup codec_algorithms
         *
         * @tparam Decoder Must meet the requirements of Codec which determines the
         * particular algorithm to be used with range given.
         * @tparam InputIterator Must meet the requirements of InputIterator.
         * @tparam OutputIterator Must meet the requirements of OutputIterator.
         *
         * @param first Iterator defines the beginning of the range to be decoded.
         * @param last Iterator defines the end of the range to be decoded.
         * @param out Iterator defines the beginning of the destination range.
         *
         * @return Output iterator to the element in the destination range, one past the last element inserted.
         */
        template<typename Decoder, typename InputIterator, typename OutputIterator>
        typename std::enable_if<detail::is_iterator<OutputIterator>::value, OutputIterator>::type
            decode(InputIterator first, InputIterator last, OutputIterator out) {

            typedef typename Decoder::stream_decoder_type DecodingMode;
            typedef typename codec::accumulator_set<DecodingMode> CodecAccumulator;

            typedef codec::detail::value_codec_impl<CodecAccumulator> DecoderStateImpl;
            typedef codec::detail::itr_codec_impl<DecoderStateImpl, OutputIterator> DecoderImpl;

            return DecoderImpl(first, last, std::move(out), CodecAccumulator());
        }

        /*!
         * @brief Decodes the elements with particular codec defined with Decoder
         * in the range, defined by [first, last) and returns the result with any
         * type convertible to the type satisfying SequenceContainer with the value
         * type satisfying Integral concept requirements.
         *
         * @ingroup codec_algorithms
         *
         * @tparam Decoder Must meet the requirements of Codec which determines the
         * particular algorithm to be used with range given.
         * @tparam InputIterator Must meet the requirements of InputIterator.
         * @tparam CodecAccumulator Must meet the requirements of AccumulatorSet.
         *
         * @param first Iterator defines the beginning of the range to be decoded.
         * @param last Iterator defines the end of the range to be decoded.
         *
         * @return Decoded data emplaced in any type convertible to the type
         * satisfying SequenceContainer with the value type satisfying Integral
         * concept requirements.
         */
        template<typename Decoder,
                 typename InputIterator,
                 typename CodecAccumulator = typename codec::accumulator_set<typename Decoder::stream_decoder_type>>
        codec::detail::range_codec_impl<codec::detail::value_codec_impl<CodecAccumulator>> decode(InputIterator first,
                                                                                InputIterator last) {

            typedef codec::detail::value_codec_impl<CodecAccumulator> DecoderStateImpl;
            typedef codec::detail::range_codec_impl<DecoderStateImpl> DecoderImpl;

            return DecoderImpl(first, last, CodecAccumulator());
        }

        /*!
         * @brief Decodes the elements with particular codec defined with Decoder
         * in the range, defined by rng and inserts the result to destination
         * range beginning at out.
         *
         * @ingroup codec_algorithms
         *
         * @tparam Decoder Must meet the requirements of Codec which determines the
         * particular algorithm to be used with range given.
         * @tparam SinglePassRange Must meet the requirements of SinglePassRange
         * @tparam OutputIterator Must meet the requirements of OutputIterator.
         *
         * @param rng Defines the range to be processed by decoder.
         * @param acc AccumulatorSet defines the destination decoded data would be stored.
         *
         * @return Output iterator to the element in the destination range, one past the last element inserted.
         */
        template<typename Decoder,
                 typename InputIterator,
                 typename CodecAccumulator = typename codec::accumulator_set<typename Decoder::stream_decoder_type>>
        typename std::enable_if<boost::accumulators::detail::is_accumulator_set<CodecAccumulator>::value,
                                CodecAccumulator>::type &
            decode(InputIterator first, InputIterator last, CodecAccumulator &acc) {

            typedef codec::detail::ref_codec_impl<CodecAccumulator> DecoderStateImpl;
            typedef codec::detail::range_codec_impl<DecoderStateImpl> DecoderImpl;

            return DecoderImpl(first, last, std::forward<CodecAccumulator>(acc));
        }

        /*!
         * @brief Decodes the elements with particular codec defined with Decoder
         * in the range, defined by rng and inserts the result to destination
         * range beginning at out.
         *
         * @ingroup codec_algorithms
         *
         * @tparam Decoder Must meet the requirements of Codec which determines the
         * particular algorithm to be used with range given.
         * @tparam SinglePassRange Must meet the requirements of SinglePassRange
         * @tparam CodecAccumulator Must meet the requirements of AccumulatorSet.
         *
         * @param rng Defines the range to be processed by decoder.
         * @param out Defines the beginning of destination range.
         * @return CodecAccumulator AccumulatorSet non-const reference equal to acc.
         */
        template<typename Decoder, typename SinglePassRange, typename OutputIterator>
        typename std::enable_if<detail::is_iterator<OutputIterator>::value, OutputIterator>::type
            decode(const SinglePassRange &rng, OutputIterator out) {

            typedef typename Decoder::stream_decoder_type DecodingMode;
            typedef typename codec::accumulator_set<DecodingMode> CodecAccumulator;

            typedef codec::detail::value_codec_impl<CodecAccumulator> DecoderStateImpl;
            typedef codec::detail::itr_codec_impl<DecoderStateImpl, OutputIterator> DecoderImpl;

            return DecoderImpl(rng, std::move(out), CodecAccumulator());
        }

        /*!
         * @brief Decodes the elements with particular codec defined with Decoder
         * in the range, defined by rng and inserts the result to destination
         * range beginning at out.
         *
         * @ingroup codec_algorithms
         *
         * @tparam Decoder Must meet the requirements of Codec which determines the
         * particular algorithm to be used with range given.
         * @tparam SinglePassRange Must meet the requirements of SinglePassRange
         * @tparam CodecAccumulator Must meet the requirements of AccumulatorSet.
         *
         * @param rng Defines the range to be processed by decoder.
         * @param acc AccumulatorSet defines the destination decoded data would be stored.
         * @return CodecAccumulator AccumulatorSet non-const reference equal to acc.
         */
        template<typename Decoder,
                 typename SinglePassRange,
                 typename CodecAccumulator = typename codec::accumulator_set<typename Decoder::stream_decoder_type>>
        typename std::enable_if<boost::accumulators::detail::is_accumulator_set<CodecAccumulator>::value,
                                CodecAccumulator>::type &
            decode(const SinglePassRange &rng, CodecAccumulator &acc) {

            typedef codec::detail::value_codec_impl<CodecAccumulator> DecoderStateImpl;
            typedef codec::detail::range_codec_impl<DecoderStateImpl> DecoderImpl;

            return DecoderImpl(rng, std::forward<CodecAccumulator>(acc));
        }

        /*!
         * @brief Decodes the elements with particular codec defined with Decoder
         * in the range, defined by rng and returns the result with any
         * type convertible to the type satisfying SequenceContainer with the value
         * type satisfying Integral concept requirements.
         *
         * @ingroup codec_algorithms
         *
         * @tparam Decoder Must meet the requirements of Codec which determines the
         * particular algorithm to be used with range given.
         * @tparam SinglePassRange Must meet the requirements of SinglePassRange
         *
         * @param r Defines the range to be processed by decoder.
         *
         * @return Decoded data emplaced in any type convertible to the type
         * satisfying SequenceContainer with the value type satisfying Integral
         * concept requirements.
         */
        template<typename Decoder,
                 typename SinglePassRange,
                 typename CodecAccumulator = typename codec::accumulator_set<typename Decoder::stream_decoder_type>>
        codec::detail::range_codec_impl<codec::detail::value_codec_impl<CodecAccumulator>>
            decode(const SinglePassRange &r) {

            typedef codec::detail::value_codec_impl<CodecAccumulator> DecoderStateImpl;
            typedef codec::detail::range_codec_impl<DecoderStateImpl> DecoderImpl;

            return DecoderImpl(r, CodecAccumulator());
        }
    }    // namespace crypto3
}    // namespace boost

#endif    // include guard

max_stars_repo_name: NilFoundation/boost-crypto

max_issues_repo_name: NilFoundation/boost-crypto

max_forks_repo_name: NilFoundation/boost-crypto


text:
/*=============================================================================
    Boost.Wave: A Standard compliant C++ preprocessor library
    Definition of the preprocessor context

    http://www.boost.org/

    Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost
    Software License, Version 1.0. (See accompanying file
    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

#if !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)
#define CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED

#include <string>
#include <vector>
#include <stack>

#include <boost/concept_check.hpp>

#include <boost/wave/wave_config.hpp>
#include <boost/wave/token_ids.hpp>

#include <boost/wave/util/unput_queue_iterator.hpp>
#include <boost/wave/util/cpp_ifblock.hpp>
#include <boost/wave/util/cpp_include_paths.hpp>
#include <boost/wave/util/iteration_context.hpp>
#include <boost/wave/util/cpp_iterator.hpp>
#include <boost/wave/util/cpp_macromap.hpp>

#include <boost/wave/preprocessing_hooks.hpp>
#include <boost/wave/cpp_iteration_context.hpp>
#include <boost/wave/language_support.hpp>

///////////////////////////////////////////////////////////////////////////////
namespace boost {
namespace wave {

///////////////////////////////////////////////////////////////////////////////
//
//  The C preprocessor context template class
//
//      The boost::wave::context template is the main interface class to
//      control the behaviour of the preprocessing engine.
//
//      The following template parameters has to be supplied:
//
//      IteratorT       The iterator type of the underlying input stream
//      LexIteratorT    The lexer iterator type to use as the token factory
//      InputPolicyT    The input policy type to use for loading the files
//                      to be included. This template parameter is optional and
//                      defaults to the
//                          iteration_context_policies::load_file_to_string
//                      type
//      TraceT          The trace policy to use for trace and include file
//                      notification callback.
//
///////////////////////////////////////////////////////////////////////////////

template <
    typename IteratorT,
    typename LexIteratorT,
    typename InputPolicyT = iteration_context_policies::load_file_to_string,
    typename TraceT = context_policies::default_preprocessing_hooks
>
class context {

public:

// concept checks
// the given iterator shall be at least a forward iterator type
    BOOST_CLASS_REQUIRE(IteratorT, boost, ForwardIteratorConcept);

// public typedefs
    typedef typename LexIteratorT::token_type       token_type;
    typedef context<IteratorT, LexIteratorT, InputPolicyT, TraceT>
        self_type;

    typedef IteratorT                               target_iterator_type;
    typedef LexIteratorT                            lexer_type;
    typedef pp_iterator<self_type>                  iterator_type;

    typedef InputPolicyT                            input_policy_type;
    typedef typename token_type::position_type      position_type;

// type of a token sequence
    typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
        token_sequence_type;

// types of the policies
    typedef TraceT                                  trace_policy_type;

private:
// stack of shared_ptr's to the pending iteration contexts
    typedef boost::shared_ptr<base_iteration_context<lexer_type> >
        iteration_ptr_type;
    typedef boost::wave::util::iteration_context_stack<iteration_ptr_type>
            iteration_context_stack_type;
    typedef typename iteration_context_stack_type::size_type iter_size_type;

// the context object should not be copied around
    context(context const& rhs);
    context& operator= (context const& rhs);

public:
    context(target_iterator_type const &first_, target_iterator_type const &last_,
            char const *fname = "<Unknown>", TraceT const &trace_ = TraceT())
    :   first(first_), last(last_), filename(fname)
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
        , current_filename(fname)
#endif
        , macros(*this), language(boost::wave::support_cpp), trace(trace_)
    {
        macros.init_predefined_macros(fname);
        includes.init_initial_path();
    }

// iterator interface
    iterator_type begin()
    {
        includes.set_current_directory(filename.c_str());
        return iterator_type(*this, first, last, position_type(filename.c_str()),
            get_language());
    }
    iterator_type end() const
        { return iterator_type(); }

// maintain include paths
    bool add_include_path(char const *path_)
        { return includes.add_include_path(path_, false);}
    bool add_sysinclude_path(char const *path_)
        { return includes.add_include_path(path_, true);}
    void set_sysinclude_delimiter() { includes.set_sys_include_delimiter(); }
    typename iteration_context_stack_type::size_type get_iteration_depth() const
        { return iter_ctxs.size(); }

// maintain defined macros
#if BOOST_WAVE_ENABLE_COMMANDLINE_MACROS != 0
    bool add_macro_definition(std::string macrostring,
            bool is_predefined = false)
        { return boost::wave::util::add_macro_definition(*this, macrostring,
            is_predefined, get_language()); }
#endif
    bool add_macro_definition(token_type const &name, bool has_params,
            std::vector<token_type> &parameters, token_sequence_type &definition,
            bool is_predefined = false)
        { return macros.add_macro(name, has_params, parameters, definition,
            is_predefined); }
    template <typename IteratorT2>
    bool is_defined_macro(IteratorT2 const &begin, IteratorT2 const &end)
        { return macros.is_defined(begin, end); }
    bool remove_macro_definition(typename token_type::string_type const &name,
            bool even_predefined = false)
        {
            return macros.remove_macro(
                token_type(T_IDENTIFIER, name, macros.get_main_pos()),
                even_predefined);
        }
    bool remove_macro_definition(token_type const &token,
            bool even_predefined = false)
        { return macros.remove_macro(token, even_predefined); }
    void reset_macro_definitions()
        { macros.reset_macromap(); macros.init_predefined_macros(); }

// get the pp-iterator version information
    static std::string get_version()
        { return boost::wave::util::predefined_macros::get_fullversion(false); }
    static std::string get_version_string()
        { return boost::wave::util::predefined_macros::get_versionstr(false); }

    void set_language(boost::wave::language_support language_)
    {
        language = language_;
        reset_macro_definitions();
    }
    boost::wave::language_support get_language() const { return language; }

// change and ask for maximal possible include nesting depth
    void set_max_include_nesting_depth(iter_size_type new_depth)
        { iter_ctxs.set_max_include_nesting_depth(new_depth); }
    iter_size_type get_max_include_nesting_depth() const
        { return iter_ctxs.get_max_include_nesting_depth(); }

// access the trace policy
    trace_policy_type &get_trace_policy()
        { return trace; }

#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
protected:
    friend class boost::wave::pp_iterator<
        boost::wave::context<IteratorT, lexer_type, InputPolicyT, TraceT> >;
    friend class boost::wave::impl::pp_iterator_functor<
        boost::wave::context<IteratorT, lexer_type, InputPolicyT, TraceT> >;
#endif

// maintain include paths (helper functions)
    bool find_include_file (std::string &s, std::string &d, bool is_system,
        char const *current_file) const
    { return includes.find_include_file(s, d, is_system, current_file); }
    void set_current_directory(char const *path_)
        { includes.set_current_directory(path_); }

// conditional compilation contexts
    bool get_if_block_status() const { return ifblocks.get_status(); }
    void enter_if_block(bool new_status)
        { ifblocks.enter_if_block(new_status); }
    bool enter_elif_block(bool new_status)
        { return ifblocks.enter_elif_block(new_status); }
    bool enter_else_block() { return ifblocks.enter_else_block(); }
    bool exit_if_block() { return ifblocks.exit_if_block(); }
    typename boost::wave::util::if_block_stack::size_type get_if_block_depth() const
        { return ifblocks.get_if_block_depth(); }

// stack of iteration contexts
    iteration_ptr_type pop_iteration_context()
        { iteration_ptr_type top = iter_ctxs.top(); iter_ctxs.pop(); return top; }
    void push_iteration_context(position_type const &act_pos, iteration_ptr_type iter_ctx)
        { iter_ctxs.push(act_pos, iter_ctx); }

    position_type &get_main_pos() { return macros.get_main_pos(); }

///////////////////////////////////////////////////////////////////////////////
//
//  expand_tokensequence():
//      expands all macros contained in a given token sequence, handles '##'
//      and '#' pp operators and re-scans the resulting sequence
//      (essentially preprocesses the token sequence).
//
//      The expand_undefined parameter is true during macro expansion inside
//      a C++ expression given for a #if or #elif statement.
//
///////////////////////////////////////////////////////////////////////////////
    template <typename IteratorT2>
    token_type expand_tokensequence(IteratorT2 &first, IteratorT2 const &last,
        token_sequence_type &pending, token_sequence_type &expanded,
        bool expand_undefined = false)
    {
        return macros.expand_tokensequence(first, last, pending, expanded,
            expand_undefined);
    }

    template <typename IteratorT2>
    void expand_whole_tokensequence(IteratorT2 &first, IteratorT2 const &last,
        token_sequence_type &expanded, bool expand_undefined = true)
    {
        macros.expand_whole_tokensequence(expanded, first, last,
            expand_undefined);

    // remove any contained placeholder
        boost::wave::util::impl::remove_placeholders(expanded);
    }

public:
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
// support for #pragma once
// maintain the real name of the current preprocessed file
    void set_current_filename(char const *real_name)
        { current_filename = real_name; }
    std::string const &get_current_filename() const
        { return current_filename; }

// maintain the list of known headers containing #pragma once
    bool has_pragma_once(std::string const &filename)
        { return includes.has_pragma_once(filename); }
    bool add_pragma_once_header(std::string const &filename)
        { return includes.add_pragma_once_header(filename); }
#endif

// forwarding functions for the context policy hooks
    template <typename ContainerT>
    bool interpret_pragma(ContainerT &pending, token_type const &option,
        ContainerT const &values, token_type const &act_token)
    {
        return trace.interpret_pragma(*this, pending, option, values,
            act_token);
    }
    template <typename ParametersT, typename DefinitionT>
    void defined_macro(token_type const &name, bool is_functionlike,
        ParametersT const &parameters, DefinitionT const &definition,
        bool is_predefined)
    {
        trace.defined_macro(name, is_functionlike, parameters, definition,
            is_predefined);
    }
    void undefined_macro(token_type const &token)
    {
        trace.undefined_macro(token);
    }

private:
// the main input stream
    target_iterator_type first;         // underlying input stream
    target_iterator_type last;
    std::string filename;               // associated main filename
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
    std::string current_filename;       // real name of current preprocessed file
#endif

    boost::wave::util::if_block_stack ifblocks;   // conditional compilation contexts
    boost::wave::util::include_paths includes;    // lists of include directories to search
    iteration_context_stack_type iter_ctxs;       // iteration contexts
    boost::wave::util::macromap<self_type> macros;  // map of defined macros
    boost::wave::language_support language;       // supported language/extensions
    trace_policy_type trace;                      // trace policy instance
};

///////////////////////////////////////////////////////////////////////////////
}   // namespace wave
}   // namespace boost

#endif // !defined(CPP_CONTEXT_HPP_907485E2_6649_4A87_911B_7F7225F3E5B8_INCLUDED)

max_stars_repo_name: schinmayee/nimbus

max_issues_repo_name: schinmayee/nimbus

max_forks_repo_name: schinmayee/nimbus


text:
#ifndef CONNECTION_H
#define CONNECTION_H

#include <iostream>
#include <unistd.h>

#include <boost/move/move.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>

#include <boost/asio.hpp>
#include <boost/asio/buffer.hpp>

#include "../helpers/helper.hpp"
#include "IP.hpp"

/*************** Types & Names ***************************************************************************************/

namespace b_asio = boost::asio;
namespace b_ip   = b_asio::ip;

using b_ip::tcp;

// typedef boost::shared_ptr<double[]> xfer_shr_ptr;
// typedef boost::array<double,32> xfer_type;
typedef vector<double> xfer_type; // NOTE: *Copied* structures!

typedef boost::packaged_task<int>   task_t;
typedef boost::shared_ptr<task_t>   ptask_t;

/*************** Utilities *******************************************************************************************/

string get_local_ip_addr( b_ip::tcp::socket& sock );
string get_local_ip_addr();

/*************** Structs and Enum ************************************************************************************/

/***** ID / Status Codes *****/

enum MsgType{
    REQUEST  ,
    RESPONSE ,
};
typedef enum MsgType msg_t;

enum StatusType{
    VALID   ,
    ERROR   ,
    EMPTY   ,
    OPEN    ,
    CLOSED  ,
    WAITING ,
    RUNNING ,
    STOPPED ,
};
typedef enum StatusType status_t;

/***** Service Message *****/

struct SrvMsg{
    /*** Vars ***/
    msg_t     type;
    status_t  status;
    size_t    sequence;
    xfer_type data;
    size_t    payload_size;
    /*** Functions ***/
    SrvMsg( msg_t typ , status_t stts , size_t seq , size_t N ) : type{typ} , status{stts} , sequence{seq} {
        payload_size = sizeof( double ) * N;
        data /*---*/ = xfer_type();
    };
};

/*************** concurrent_queue ************************************************************************************/

template<typename T>
class concurrent_queue{
// a simple thread-safe multiple producer, multiple consumer queue (LOCKS)
// https://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

/***** Protected *****/ protected:

std::queue<T> /*-------*/ _queue; // - Underlying queue
mutable boost::mutex /*--------*/ _mutex; // - Lock
boost::condition_variable cond_var; // Semaphore

/***** Public *****/ public:

// concurrent_queue( boost::mutex& mtx , boost::condition_variable& cnd ) : _mutex{ mtc } , cond_var{cnd} {}

void push( T const& data ){
    // Lock the queue, push data, unlock, notify
    boost::mutex::scoped_lock lock(_mutex);
    _queue.push( data );
    lock.unlock();
    cond_var.notify_one();
}

bool empty() const{
    // Lock the queue, then return `true` if the queue is empty
    boost::mutex::scoped_lock lock(_mutex);
    return _queue.empty();
}

bool try_pop( T& popped_value ){
    /* returns true if there was a value to retrieve (in which case it retrieves it), or false to indicate that the queue was empty. */
    boost::mutex::scoped_lock lock( _mutex );
    if( _queue.empty() ){  return false;  }
    popped_value = _queue.front();
    _queue.pop();
    return true;
}

void wait_and_pop( T& popped_value ){
    // If multiple threads are popping entries from a full queue, then they just get serialized inside wait_and_pop, and everything works fine.
    boost::mutex::scoped_lock lock(_mutex);
    while( _queue.empty() ){  cond_var.wait( lock );  }
    popped_value=_queue.front();
    _queue.pop();
}

void clear(){
    T popped_value;
    while( !empty() ){  try_pop( popped_value );  }
}

};

/*************** Service *********************************************************************************************/

/***** ServiceQueue *****/

template<typename T>
struct ServiceQueue{
// Container class for running one service
/***** Public *****/ public:

/*** Vars ***/
string /*--------*/ topicName;
size_t /*--------*/ queueSize,
                    seq_req  ,
                    seq_rsp  ;
concurrent_queue<T> Q_req;
concurrent_queue<T> Q_rsp;

/*** Functions ***/

SrvMsg req_pop_msg(){
    // Pop from requests and create message
    T    data;
    bool result = Q_req.try_pop( data );
    if( result ){
        return SrvMsg( REQUEST , VALID , seq_req++  , data );
    }else{
        return SrvMsg( REQUEST , EMPTY , _BAD_INDEX , data );
    }
};

SrvMsg rsp_pop_msg(){
    // Pop from responses and create message
    T    data;
    bool result = Q_rsp.try_pop( data );
    if( result ){
        return SrvMsg( RESPONSE , VALID , seq_req++  , data );
    }else{
        return SrvMsg( RESPONSE , EMPTY , _BAD_INDEX , data );
    }
};

ServiceQueue( string tpcName , size_t qLen ) : topicName{ tpcName } , queueSize{ qLen }{  seq_req = seq_rsp = 0;  };
~ServiceQueue(){  Q_req.clear();  Q_rsp.clear();  }
};

/*************** Connection ******************************************************************************************/
// `Connection` handles messages for one client, and holds data related to that

#define BUF_SZ 1024

typedef boost::shared_ptr<b_asio::mutable_buffer>  buf_ptr;

// https://gist.github.com/wush978/6190443
class Connection{

/***** Public *****/ public:

Connection( b_asio::io_service& io_service_ ); // Begin with a closed connection and no bytes transferred
// Each individual socket connection is given a file descriptor

bool accept( b_asio::io_service& io_service_ , tcp::acceptor& acceptor_ );

bool Connection::is_closed();

void read( b_asio::mutable_buffer& outBuffer );
void write( b_asio::mutable_buffer& inBuffer );

bool try_read_bytes( size_t Nbytes , b_asio::mutable_buffer& outBuffer );

/*** Vars ***/
status_t /*------------*/ status;
size_t /*--------------*/ bytes_rcvd;
size_t /*--------------*/ bytes_sent;
boost::system::error_code netError;
string /*--------------*/ ip;
string /*--------------*/ port;
tcp::socket /*---------*/ socket;
};

#endif


text:
/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

#ifndef SD_SLIDESORTER_VISUAL_STATE_HXX
#define SD_SLIDESORTER_VISUAL_STATE_HXX

#include <sal/types.h>
#include <tools/gen.hxx>
#include <boost/function.hpp>

namespace sd { namespace slidesorter { namespace model {

class PageDescriptor;

/** This class gives access to values related to the visualization of page
    objects.  This includes animation state when blending from one state to
    another.
*/
class VisualState
{
public:
    enum State {
        VS_Selected,
        VS_Focused,
        VS_Current,
        VS_Excluded,
        VS_None };

    VisualState (const sal_Int32 nPageId);
    ~VisualState (void);

    State GetCurrentVisualState (void) const;
    State GetOldVisualState (void) const;
    void SetVisualState (const State eState);
    double GetVisualStateBlend (void) const;
    void SetVisualStateBlend (const double nBlend);

    void UpdateVisualState (const PageDescriptor& rDescriptor);

    void SetMouseOverState (const bool bIsMouseOver);

    sal_Int32 GetStateAnimationId (void) const;
    void SetStateAnimationId (const sal_Int32 nAnimationId);

    Point GetLocationOffset (void) const;
    bool SetLocationOffset (const Point& rPoint);
    sal_Int32 GetLocationAnimationId (void) const;
    void SetLocationAnimationId (const sal_Int32 nAnimationId);

    double GetButtonAlpha (void) const;
    void SetButtonAlpha (const double nAlpha);
    double GetButtonBarAlpha (void) const;
    void SetButtonBarAlpha (const double nAlpha);
    sal_Int32 GetButtonAlphaAnimationId (void) const;
    void SetButtonAlphaAnimationId (const sal_Int32 nAnimationId);

    sal_Int32 mnPageId; // For debugging

private:
    State meCurrentVisualState;
    State meOldVisualState;
    double mnVisualStateBlend;
    sal_Int32 mnStateAnimationId;
    bool mbOldMouseOverState;
    bool mbCurrentMouseOverState;

    Point maLocationOffset;
    sal_Int32 mnLocationAnimationId;

    double mnButtonAlpha;
    double mnButtonBarAlpha;
    sal_Int32 mnButtonAlphaAnimationId;
};

} } } // end of namespace ::sd::slidesorter::model

#endif

ext: hxx

max_stars_repo_name: Grosskopf/openoffice

max_issues_repo_name: Grosskopf/openoffice

max_forks_repo_name: Grosskopf/openoffice


text:
#include <devConfig.h>
#include <devSettings.h>

#include <utilsDBNavi.h>
#include <utilsWebHttpsReqSync.h>

#include <cstdlib>
#include <iostream>
#include <optional>
#include <string>

#include <boost/filesystem.hpp>
#include <boost/json.hpp>

//https://www.glonass-iac.ru/glonass/sostavOG/sostavOG_calc.php?lang=ru&sort=point
//https://www.glonass-iac.ru/gps/sostavOG/sostavOG_calc.php?lang=ru
//
// PREFERABLE
//https://www.glonass-iac.ru/glonass/sostavOG/sostavOG_calc.php?lang=en&sort=point
//https://www.glonass-iac.ru/gps/sostavOG/sostavOG_calc.php?lang=en

void StoreGLONASS(utils::db::tDBNavi& a_dbNavi, const boost::json::value& value);
void StoreGPS(utils::db::tDBNavi& a_dbNavi, const boost::json::value& a_value);

utils::tExitCode RetrieveData(const std::string& a_target, std::function<void(utils::db::tDBNavi&, const boost::json::value&)> a_handler);

int main(int argc, char** argv)
{
	try
	{
		const boost::filesystem::path Path{ argv[0] };
		boost::filesystem::path PathFile = Path.filename();
		if (PathFile.has_extension())
			PathFile.replace_extension();

		const std::string FileNameConf = PathFile.string() + ".conf";
		dev::g_Settings = dev::tSettings(FileNameConf);
	}
	catch (std::exception& e)
	{
		std::cerr << "Exception: " << e.what() << "\n";

		return static_cast<int>(utils::tExitCode::EX_CONFIG);
	}

	utils::tExitCode CErr = RetrieveData("/glonass/sostavOG/sostavOG_calc.php?lang=en&sort=point", StoreGLONASS);
	if (CErr != utils::tExitCode::EX_OK)
		return static_cast<int>(CErr);

	CErr = RetrieveData("/gps/sostavOG/sostavOG_calc.php?lang=en", StoreGPS);
	if (CErr != utils::tExitCode::EX_OK)
		return static_cast<int>(CErr);

	return static_cast<int>(utils::tExitCode::EX_OK);
}

utils::tExitCode RetrieveData(const std::string& a_target, std::function<void(utils::db::tDBNavi&, const boost::json::value&)> a_handler)
{
	std::optional<std::string> resData = utils::web::HttpsReqSync("glonass-iac.ru", a_target);

	if (!resData.has_value())
		return utils::tExitCode::EX_UNAVAILABLE;

	std::string resDataText(std::move(resData.value()));

	try
	{
		boost::json::value jsonData = boost::json::parse(resDataText);

		utils::db::tDBNavi dbNavi(dev::g_Settings.DB.Host, dev::g_Settings.DB.User, dev::g_Settings.DB.Passwd, dev::g_Settings.DB.DB, dev::g_Settings.DB.Port);

		for (const auto& i : jsonData.as_array())
		{
			if (boost::json::value_to<std::string>(i.at("name")) == "OG")
			{
				const auto& satellites = i.at("data");

				a_handler(dbNavi, satellites);
			}
		}
	}
	catch (std::exception const& exJson)
	{
		std::cerr << "Error: " << exJson.what() << std::endl;

		return utils::tExitCode::EX_DATAERR;
	}

	return utils::tExitCode::EX_OK;
}

ext: cpp


text:
/**
 \file
 Implementation of the Corsika shower reader

 \author Lukas Nellen
 \version $Id$
 \date 29 Jan 2004
 */

#include <corsika/Constants.h>
#include <corsika/ShowerFile.h>
#include <corsika/ShowerParticleStream.h>
#include <corsika/IOException.h>
#include <corsika/Block.h>
#include <corsika/Shower.h>
#include <corsika/LongFile.h>
#include <corsika/LongProfile.h>
#include <corsika/particle/ParticleList.h>

#include <sstream>
#include <string>
#include <cmath>
#include <iostream>

#include <boost/tokenizer.hpp>
#include <boost/filesystem.hpp>

using namespace std;
using namespace corsika;

namespace bfs = boost::filesystem;

typedef boost::tokenizer<boost::char_separator<char> > mytok;

static void log(const std::string& mess)
{
    std::cout << mess << std::endl;
}
static void log(const std::ostringstream& mess)
{
    std::cout << mess.str() << std::endl;
}

#define INFO(mess) log(mess);
#define ERROR(mess) log(mess);
#define FATAL(mess) log(mess);

ShowerFile::ShowerFile() :
    fRawStream(),
    fCurrentPosition(0),
    fObservationLevel(1),
    fIsThinned(true),
    fFileScanned(false)
{}

ShowerFile::ShowerFile(const std::string& theFileName, bool requireParticleFile) :
fRawStream(),
fCurrentPosition(0),
fObservationLevel(1),
fIsThinned(true),
fFileScanned(false)
{
    // only call Open() if the particle file is required (default behaviour)
    if (requireParticleFile) Open(theFileName);
}

void ShowerFile::Open(const std::string& theFileName, bool scan)
{
    Close();

    // Compute the name for the long file
    string file = theFileName;

    bfs::path p(theFileName);
    p.replace_extension(".long");
    fLongFile = p.string();

    p = bfs::path(fLongFile);
    if ( !(bfs::exists(p) && bfs::is_regular_file(p)) ) fLongFile = "";

    fRawStream = RawStream::Create(theFileName);
    fIsThinned = fRawStream->IsThinned();
    if (scan && fRawStream->IsSeekable())
    {
        fIndex.Scan(*fRawStream, false);
        fFileScanned = true;
    }
    else if (!fRawStream->IsSeekable())
    {
        ostringstream msg;
        msg << "File " << theFileName << " does not support random access. This class can not handle it";
        throw IOException(msg.str());
    }
    if (fIsThinned) ReadRunHeader<Thinned>();
    else ReadRunHeader<NotThinned>();
}

void ShowerFile::Close()
{
    fRunHeader = corsika::RunHeader();
    fRawStream.reset();

    fIndex.eventHeaders.clear();
    fIndex.eventTrailers.clear();
    fIndex.longBlocks.clear();
    fIndex.IDToPosition.clear();
}

template <class Thinning> Status ShowerFile::Read()
{
    if (!fRawStream || fCurrentPosition >= fIndex.eventHeaders.size())
        return eEOF;

    fRawStream->SeekTo(fIndex.eventHeaders[fCurrentPosition]);

    Block<Thinning> headerBlock;
    if (!fRawStream->GetNextBlock(headerBlock))
    {
        ostringstream err;
        err << "Cannot read CORSIKA shower header for position "
        << fCurrentPosition;
        FATAL(err);
        return eFail;
    }

    if (!headerBlock.IsEventHeader())
    {
        ostringstream err;
        err << "First block at position " << fCurrentPosition
        << " is not event header";
        FATAL(err);
        return eFail;
    }
    const EventHeader& header = headerBlock.AsEventHeader;

    fRawStream->SeekTo(fIndex.eventTrailers[fCurrentPosition]);

    Block<Thinning> trailerBlock;
    if (!fRawStream->GetNextBlock(trailerBlock))
    {
        ostringstream err;
        err << "Cannot read CORSIKA shower trailer for position "
        << fCurrentPosition;
        FATAL(err);
        return eFail;
    }
    if (!trailerBlock.IsEventTrailer())
    {
        ostringstream err;
        err << "Block at position " << fCurrentPosition
        << " is not event trailer";
        FATAL(err);
        return eFail;
    }

    const EventTrailer& trailer = trailerBlock.AsEventTrailer;

    if (fObservationLevel > header.fObservationLevels)
    {
        ostringstream info;
        info << "The requested observation level: " << fObservationLevel
        << " does not exist (max obs. level: "
        << header.fObservationLevels << "), "
        << "switching to level 1.";
        fObservationLevel = 1;
        INFO(info);
    }

    // Corsika starts at the top of the atmosphere, not
    const float heightObsLevel =
    header.fObservationHeight[int(header.fObservationLevels) - 1]; // in cm
    const float heightFirstInt = abs(header.fZFirst); // in cm

    double hReference;
    const double hAtmBoundary = (header.fStartingHeight>0? header.fStartingHeight: 112.8292*1e5); // in cm

    // for the SLANT and CURVED options, clock starts at the margin of
    // the atmosphere. This is indicated by fZFirst < 0
    if (header.fZFirst < 0.) hReference = hAtmBoundary;
    else hReference = heightFirstInt;

    double timeShift = 0;

    const double Zenith = header.fTheta;
    const double cosZenith = cos(Zenith);

    if (header.fFlagCurved)
    {

        INFO("CURVED version");

        if (ParticleList::CorsikaToPDG(int(header.fParticleId)) == Particle::ePhoton)
            hReference = heightFirstInt;

        timeShift = (pow((kEarthRadius + heightObsLevel)*cosZenith, 2) +
                     pow(hReference - heightObsLevel, 2) +
                     2*(kEarthRadius + heightObsLevel)*(hReference - heightObsLevel));
        timeShift = sqrt(timeShift);
        timeShift -= (kEarthRadius + heightObsLevel)*cosZenith;
        timeShift /= kSpeedOfLight;

        ostringstream info;
        info << "TimeShift to core: " << timeShift/1e9; // output in ns
        INFO(info);

    }
    else
        timeShift = (hReference - heightObsLevel) / (cosZenith * kSpeedOfLight);

    ShowerParticleStream* particleIterator =
    new ShowerParticleStream(fRawStream,
                             fIndex.eventHeaders[fCurrentPosition] + 1,
                             timeShift,
                             fObservationLevel,
                             true); // last one is keepMuProd
    fCurrentShower = Shower(header, trailer, particleIterator);

    if (fIndex.longBlocks.size() > 0)
        ReadLongBlocks<Thinning>();
    else if ( fLongFile != "" )
        ReadLongFile();

    ++fCurrentPosition;

    return eSuccess;
}

template <class Thinning> Status ShowerFile::ReadRunHeader()
{
    Block<Thinning> runHeaderBlock;
    if (!fRawStream->GetNextBlock(runHeaderBlock))
    {
        FATAL("Cannot read CORSIKA run header");
        return eFail;
    }
    if (!runHeaderBlock.IsRunHeader())
    {
        FATAL("First block is not a run header");
        return eFail;
    }
    fRunHeader = runHeaderBlock.AsRunHeader;
    return eSuccess;
}

Status ShowerFile::FindEvent(const unsigned int eventId)
{
    if (!IsOpen()) return eEOF;
    const IdToPositionMap::const_iterator iter = fIndex.IDToPosition.find(eventId);
    if (iter == fIndex.IDToPosition.end() || iter->second >= fIndex.eventHeaders.size())
        return eFail;

    fCurrentPosition = iter->second;
    if (fIsThinned) return Read<Thinned>();
    return Read<NotThinned>();
}

size_t ShowerFile::GetNEvents()
{
    if (!fRawStream) throw IOException("Cannot request number of events from closed file");
    if (!fRawStream->IsSeekable()) throw IOException("Cannot request number of events for this file. It is not seekable.");

    if (!fFileScanned)
    {
        fIndex.Scan(*fRawStream, false);
        fFileScanned = true;
    }
    return fIndex.IDToPosition.size();
}

Status ShowerFile::ReadLongFile()
{
    //cout << "reading long file " << fLongFile << endl;
    if (!fCorsikaLongFile)
        fCorsikaLongFile.reset(new LongFile(fLongFile, GetCurrentShower().GetZenith()));

    if (fCorsikaLongFile->size() >= fCurrentPosition)
    {
        LongProfile p = fCorsikaLongFile->GetProfile(fCurrentPosition);
        fCurrentShower.fdEdX = p.fdEdX;
        fCurrentShower.fChargeProfile = p.fChargeProfile;
        fCurrentShower.fGammaProfile = p.fGammaProfile;
        fCurrentShower.fElectronProfile = p.fElectronProfile;
        fCurrentShower.fPositronProfile = p.fPositronProfile;
        fCurrentShower.fMuonProfile = p.fMuonProfile;
        fCurrentShower.fAntiMuonProfile = p.fAntiMuonProfile;
        fCurrentShower.fHadronProfile = p.fHadronProfile;
        fCurrentShower.fNucleiProfile = p.fNucleiProfile;
        fCurrentShower.fCherenkovProfile = p.fCherenkovProfile;
        fCurrentShower.fDepth_dE = p.fDepth_dE;
        fCurrentShower.fDepth = p.fDepth;

        fCurrentShower.SetGaisserHillasParams(p.fGaisserHillas);
        fCurrentShower.SetCalorimetricEnergy(p.fCalorimetricEnergy);
    }
    else
    {
        fCurrentShower.fdEdX.clear();
        fCurrentShower.fChargeProfile.clear();
        fCurrentShower.fGammaProfile.clear();
        fCurrentShower.fElectronProfile.clear();
        fCurrentShower.fPositronProfile.clear();
        fCurrentShower.fMuonProfile.clear();
        fCurrentShower.fAntiMuonProfile.clear();
        fCurrentShower.fHadronProfile.clear();
        fCurrentShower.fNucleiProfile.clear();
        fCurrentShower.fCherenkovProfile.clear();
        fCurrentShower.fDepth_dE.clear();
        fCurrentShower.fDepth.clear();

        fCurrentShower.SetCalorimetricEnergy(0);

        GaisserHillasParameter gh;
        fCurrentShower.SetGaisserHillasParams(gh);
    }
    return eSuccess;
}

template <class Thinning> Status ShowerFile::ReadLongBlocks()
{
    fRawStream->SeekTo(fIndex.longBlocks[fCurrentPosition]);

    Block<Thinning> block;
    if (!fRawStream->GetNextBlock(block) || !block.IsLongitudinal())
    {
        ostringstream err;
        err << "Cannot read CORSIKA long block at position "
            << fCurrentPosition;
        FATAL(err);
        return eFail;
    }

    if (!block.IsLongitudinal())
    {
        ostringstream err;
        err << "Block at position " << fCurrentPosition
        << " is not longitudinal";
        FATAL(err);
        return eFail;
    }
    const LongitudinalBlock& longBlock = block.AsLongitudinalBlock;

    vector<double> auxDeltaEn;
    vector<double> auxCharge;
    vector<double> auxGammas;
    vector<double> auxElectrons;
    vector<double> auxPositrons;
    vector<double> auxMuons;
    vector<double> auxAntiMuons;
    vector<double> auxHadrons;
    vector<double> auxNuclei;
    vector<double> auxCherenkov;
    vector<double> auxDepth_dE;
    vector<double> auxDepth;

    const int nBlocks = int(longBlock.fStepsAndBlocks)%100;
    //cout << int(longBlock.fStepsAndBlocks/100)<< " steps in " << nBlocks << " blocks" << endl;
    int i = 0;

    for (; i != kLongEntriesPerBlock; ++i)
    {
        if (i && !longBlock.fEntries[i].fDepth)
            break;
        auxDeltaEn.push_back(0);
        auxCharge.push_back(longBlock.fEntries[i].fCharged);
        auxGammas.push_back(longBlock.fEntries[i].fGamma);
        auxElectrons.push_back(longBlock.fEntries[i].fEminus);
        auxPositrons.push_back(longBlock.fEntries[i].fEplus);
        auxMuons.push_back(longBlock.fEntries[i].fMuMinus);
        auxAntiMuons.push_back(longBlock.fEntries[i].fMuPlus);
        auxHadrons.push_back(longBlock.fEntries[i].fHadron);
        auxNuclei.push_back(longBlock.fEntries[i].fNuclei);
        auxCherenkov.push_back(longBlock.fEntries[i].fCherenkov);
        auxDepth.push_back(longBlock.fEntries[i].fDepth);
        auxDepth_dE.push_back(longBlock.fEntries[i].fDepth);
    }

    for (int b = 1; b < nBlocks; ++b)
    {
        if (!fRawStream->GetNextBlock(block) || !block.IsLongitudinal())
        {
            ostringstream err;
            err << "Cannot read CORSIKA long block #" << b << "at position "
            << fCurrentPosition;
            FATAL(err);
            return eFail;
        }
        const LongitudinalBlock& longBlock = block.AsLongitudinalBlock;
        for (int j = 0; j != kLongEntriesPerBlock; ++j,++i)
        {
            if (j && !longBlock.fEntries[j].fDepth)
                break;
            auxDeltaEn.push_back(0);
            auxCharge.push_back(longBlock.fEntries[j].fCharged);
            auxGammas.push_back(longBlock.fEntries[j].fGamma);
            auxElectrons.push_back(longBlock.fEntries[j].fEminus);
            auxPositrons.push_back(longBlock.fEntries[j].fEplus);
            auxMuons.push_back(longBlock.fEntries[j].fMuMinus);
            auxAntiMuons.push_back(longBlock.fEntries[j].fMuPlus);
            auxHadrons.push_back(longBlock.fEntries[j].fHadron);
            auxNuclei.push_back(longBlock.fEntries[j].fNuclei);
            auxCherenkov.push_back(longBlock.fEntries[j].fCherenkov);
            auxDepth.push_back(longBlock.fEntries[j].fDepth);
            auxDepth_dE.push_back(longBlock.fEntries[j].fDepth);
        }
    }
    //cout << i << " entries read" << endl;

    fCurrentShower.fdEdX = auxDeltaEn;
    fCurrentShower.fChargeProfile = auxCharge;
    fCurrentShower.fGammaProfile = auxGammas;
    fCurrentShower.fElectronProfile = auxElectrons;
    fCurrentShower.fPositronProfile = auxPositrons;
    fCurrentShower.fMuonProfile = auxMuons;
    fCurrentShower.fAntiMuonProfile = auxAntiMuons;
    fCurrentShower.fHadronProfile = auxHadrons;
    fCurrentShower.fNucleiProfile = auxNuclei;
    fCurrentShower.fCherenkovProfile = auxCherenkov;
    fCurrentShower.fDepth_dE = auxDepth_dE;
    fCurrentShower.fDepth = auxDepth;

    // fCurrentShower.SetGaisserHillasParams(gh);
    // fCurrentShower.SetCalorimetricEnergy(energyDepositSum);

    return eSuccess;
}

ext: cxx