<commit_before>/*
* This source file is part of ArkGameFrame
* For the latest info, see https://github.com/ArkGame
*
* Copyright (c) 2013-2017 ArkGame authors.
*
* Licensed 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.
*
*/

#include "AFCRecordMgr.h"
#include "AFRecord.h"

AFCRecordMgr::AFCRecordMgr(const AFGUID& guid)
    : self(guid)
{

}

AFCRecordMgr::~AFCRecordMgr()
{
    ReleaseAll();
}

const AFGUID& AFCRecordMgr::Self()
{
    return self;
}

void AFCRecordMgr::ReleaseAll()
{
    for(size_t i = 0; i < GetCount(); ++i)
    {
        delete mxRecords[i];
        mxRecords[i] = NULL;
    }

    mxRecords.clear();
    mxRecordCallbacks.clear();
}

bool AFCRecordMgr::Exist(const char* name) const
{
    return mxIndices.exists(name);
}

bool AFCRecordMgr::Exist(const char* name, size_t& index) const
{
    return mxIndices.GetData(name, index);
}

bool AFCRecordMgr::GetRecordData(const char* name, const int row, const int col, AFIData& value)
{
    AFRecord* pRecord = GetRecord(name);
    if (NULL == pRecord)
    {
        return NULL;
    }

    return pRecord->GetValue(row, col, value);
}

void AFCRecordMgr::OnEventHandler(const AFGUID& self, const RECORD_EVENT_DATA& xEventData, const AFCData& oldData, const AFCData& newData)
{
    for (auto& iter : mxRecordCallbacks)
    {
        //TODO:check name from xEventData
        (*iter)(self, xEventData, oldData, newData);
    }
}

bool AFCRecordMgr::AddRecordInternal(AFRecord* record)
{
    assert(record != NULL);

    mxIndices.Add(record->GetName(), mxRecords.size());
    mxRecords.push_back(record);

    return true;
}

bool AFCRecordMgr::AddRecord(const AFGUID& self_id, const char* record_name, const AFIDataList& col_type_list, const int8_t feature)
{
    ARK_ASSERT(record_name != NULL && sizeof(record_name) > 0, "record name is invalid", __FILE__, __FUNCTION__);

    self = self_id;

    AFRecord* pRecord = ARK_NEW AFRecord();
    pRecord->SetName(record_name);
    pRecord->SetColCount(col_type_list.GetCount());
    for(int i = 0; i < col_type_list.GetCount(); ++i)
    {
        pRecord->SetColType(i, col_type_list.GetType(i));
    }

    pRecord->SetFeature(feature);

    return AddRecordInternal(pRecord);
}

bool AFCRecordMgr::AddRecordCallback(const char* record_name, const RECORD_EVENT_FUNCTOR_PTR& cb)
{
    //TODO:

    mxRecordCallbacks.push_back(cb);
    return true;
}

void AFCRecordMgr::Clear()
{
    ReleaseAll();
    mxIndices.Clear();
}

AFRecord* AFCRecordMgr::GetRecord(const char* name)
{
    size_t index;
    if(!mxIndices.GetData(name, index))
    {
        return NULL;
    }

    return mxRecords[index];
}

size_t AFCRecordMgr::GetCount() const
{
    return mxRecords.size();
}

AFRecord* AFCRecordMgr::GetRecordByIndex(size_t index) const
{
    assert(index < GetCount());
    return mxRecords[index];
}

bool AFCRecordMgr::SetRecordBool(const char* name, const int row, const int col, const bool value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    //callback
    do
    {
        AFCData oldData;
        if (!GetRecordData(name, row, col, oldData))
        {
            ARK_ASSERT_RET_VAL(0, false);
        }

        if (oldData.GetBool() == value)
        {
            return false;
        }

        if (!mxRecordCallbacks.empty())
        {
            AFCData newData;
            newData.SetBool(value);

            RECORD_EVENT_DATA xRecordEventData;
            xRecordEventData.nOpType = AFRecord::Update;
            xRecordEventData.nRow = row;
            xRecordEventData.nCol = col;
            xRecordEventData.strRecordName = name;

            OnEventHandler(self, xRecordEventData, oldData, newData);
        }
    } while (0);

    return record->SetBool(row, col, value);
}

bool AFCRecordMgr::SetRecordInt(const char* name, const int row, const int col, const int32_t value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    return record->SetInt(row, col, value);
}

bool AFCRecordMgr::SetRecordInt64(const char* name, const int row, const int col, const int64_t value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    return record->SetInt64(row, col, value);
}

bool AFCRecordMgr::SetRecordFloat(const char* name, const int row, const int col, const float value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    return record->SetFloat(row, col, value);
}

bool AFCRecordMgr::SetRecordDouble(const char* name, const int row, const int col, const double value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    return record->SetDouble(row, col, value);
}

bool AFCRecordMgr::SetRecordString(const char* name, const int row, const int col, const char* value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    return record->SetString(row, col, value);
}

bool AFCRecordMgr::SetRecordObject(const char* name, const int row, const int col, const AFGUID& value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    return record->SetObject(row, col, value);
}

bool AFCRecordMgr::GetRecordBool(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    return record->GetBool(row, col);
}

int32_t AFCRecordMgr::GetRecordInt(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_INT;
    }

    return record->GetInt(row, col);
}

int64_t AFCRecordMgr::GetRecordInt64(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_INT64;
    }

    return record->GetInt64(row, col);
}

float AFCRecordMgr::GetRecordFloat(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_FLOAT;
    }

    return record->GetFloat(row, col);
}

double AFCRecordMgr::GetRecordDouble(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_DOUBLE;
    }

    return record->GetDouble(row, col);
}

const char* AFCRecordMgr::GetRecordString(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_STR.c_str();
    }

    return record->GetString(row, col);
}

const AFGUID& AFCRecordMgr::GetRecordObject(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_GUID;
    }

    return record->GetObject(row, col);
}<commit_msg>Add record callback for other basic data type<commit_after>/*
* This source file is part of ArkGameFrame
* For the latest info, see https://github.com/ArkGame
*
* Copyright (c) 2013-2017 ArkGame authors.
*
* Licensed 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.
*
*/

#include "AFCRecordMgr.h"
#include "AFRecord.h"

AFCRecordMgr::AFCRecordMgr(const AFGUID& guid)
    : self(guid)
{

}

AFCRecordMgr::~AFCRecordMgr()
{
    ReleaseAll();
}

const AFGUID& AFCRecordMgr::Self()
{
    return self;
}

void AFCRecordMgr::ReleaseAll()
{
    for(size_t i = 0; i < GetCount(); ++i)
    {
        delete mxRecords[i];
        mxRecords[i] = NULL;
    }

    mxRecords.clear();
    mxRecordCallbacks.clear();
}

bool AFCRecordMgr::Exist(const char* name) const
{
    return mxIndices.exists(name);
}

bool AFCRecordMgr::Exist(const char* name, size_t& index) const
{
    return mxIndices.GetData(name, index);
}

bool AFCRecordMgr::GetRecordData(const char* name, const int row, const int col, AFIData& value)
{
    AFRecord* pRecord = GetRecord(name);
    if (NULL == pRecord)
    {
        return NULL;
    }

    return pRecord->GetValue(row, col, value);
}

void AFCRecordMgr::OnEventHandler(const AFGUID& self, const RECORD_EVENT_DATA& xEventData, const AFCData& oldData, const AFCData& newData)
{
    for (auto& iter : mxRecordCallbacks)
    {
        //TODO:check name from xEventData
        (*iter)(self, xEventData, oldData, newData);
    }
}

bool AFCRecordMgr::AddRecordInternal(AFRecord* record)
{
    assert(record != NULL);

    mxIndices.Add(record->GetName(), mxRecords.size());
    mxRecords.push_back(record);

    return true;
}

bool AFCRecordMgr::AddRecord(const AFGUID& self_id, const char* record_name, const AFIDataList& col_type_list, const int8_t feature)
{
    ARK_ASSERT(record_name != NULL && sizeof(record_name) > 0, "record name is invalid", __FILE__, __FUNCTION__);

    self = self_id;

    AFRecord* pRecord = ARK_NEW AFRecord();
    pRecord->SetName(record_name);
    pRecord->SetColCount(col_type_list.GetCount());
    for(int i = 0; i < col_type_list.GetCount(); ++i)
    {
        pRecord->SetColType(i, col_type_list.GetType(i));
    }

    pRecord->SetFeature(feature);

    return AddRecordInternal(pRecord);
}

bool AFCRecordMgr::AddRecordCallback(const char* record_name, const RECORD_EVENT_FUNCTOR_PTR& cb)
{
    //TODO:
    //record_name
    mxRecordCallbacks.push_back(cb);
    return true;
}

void AFCRecordMgr::Clear()
{
    ReleaseAll();
    mxIndices.Clear();
}

AFRecord* AFCRecordMgr::GetRecord(const char* name)
{
    size_t index;
    if(!mxIndices.GetData(name, index))
    {
        return NULL;
    }

    return mxRecords[index];
}

size_t AFCRecordMgr::GetCount() const
{
    return mxRecords.size();
}

AFRecord* AFCRecordMgr::GetRecordByIndex(size_t index) const
{
    assert(index < GetCount());
    return mxRecords[index];
}

bool AFCRecordMgr::SetRecordBool(const char* name, const int row, const int col, const bool value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    //callback
    do
    {
        AFCData oldData;
        if (!GetRecordData(name, row, col, oldData))
        {
            ARK_ASSERT_RET_VAL(0, false);
        }

        if (oldData.GetBool() == value)
        {
            return false;
        }

        if (!mxRecordCallbacks.empty())
        {
            AFCData newData;
            newData.SetBool(value);

            RECORD_EVENT_DATA xRecordEventData;
            xRecordEventData.nOpType = AFRecord::Update;
            xRecordEventData.nRow = row;
            xRecordEventData.nCol = col;
            xRecordEventData.strRecordName = name;

            OnEventHandler(self, xRecordEventData, oldData, newData);
        }
    } while (0);

    return record->SetBool(row, col, value);
}

bool AFCRecordMgr::SetRecordInt(const char* name, const int row, const int col, const int32_t value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    //callback
    do
    {
        AFCData oldData;
        if (!GetRecordData(name, row, col, oldData))
        {
            ARK_ASSERT_RET_VAL(0, false);
        }

        if (oldData.GetInt() == value)
        {
            return false;
        }

        if (!mxRecordCallbacks.empty())
        {
            AFCData newData;
            newData.SetInt(value);

            RECORD_EVENT_DATA xRecordEventData;
            xRecordEventData.nOpType = AFRecord::Update;
            xRecordEventData.nRow = row;
            xRecordEventData.nCol = col;
            xRecordEventData.strRecordName = name;

            OnEventHandler(self, xRecordEventData, oldData, newData);
        }
    } while (0);

    return record->SetInt(row, col, value);
}

bool AFCRecordMgr::SetRecordInt64(const char* name, const int row, const int col, const int64_t value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    //callback
    do
    {
        AFCData oldData;
        if (!GetRecordData(name, row, col, oldData))
        {
            ARK_ASSERT_RET_VAL(0, false);
        }

        if (oldData.GetInt64() == value)
        {
            return false;
        }

        if (!mxRecordCallbacks.empty())
        {
            AFCData newData;
            newData.SetInt64(value);

            RECORD_EVENT_DATA xRecordEventData;
            xRecordEventData.nOpType = AFRecord::Update;
            xRecordEventData.nRow = row;
            xRecordEventData.nCol = col;
            xRecordEventData.strRecordName = name;

            OnEventHandler(self, xRecordEventData, oldData, newData);
        }
    } while (0);

    return record->SetInt64(row, col, value);
}

bool AFCRecordMgr::SetRecordFloat(const char* name, const int row, const int col, const float value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    //callback
    do
    {
        AFCData oldData;
        if (!GetRecordData(name, row, col, oldData))
        {
            ARK_ASSERT_RET_VAL(0, false);
        }

        if (oldData.GetFloat() == value)
        {
            return false;
        }

        if (!mxRecordCallbacks.empty())
        {
            AFCData newData;
            newData.SetFloat(value);

            RECORD_EVENT_DATA xRecordEventData;
            xRecordEventData.nOpType = AFRecord::Update;
            xRecordEventData.nRow = row;
            xRecordEventData.nCol = col;
            xRecordEventData.strRecordName = name;

            OnEventHandler(self, xRecordEventData, oldData, newData);
        }
    } while (0);

    return record->SetFloat(row, col, value);
}

bool AFCRecordMgr::SetRecordDouble(const char* name, const int row, const int col, const double value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    //callback
    do
    {
        AFCData oldData;
        if (!GetRecordData(name, row, col, oldData))
        {
            ARK_ASSERT_RET_VAL(0, false);
        }

        if (oldData.GetDouble() == value)
        {
            return false;
        }

        if (!mxRecordCallbacks.empty())
        {
            AFCData newData;
            newData.SetDouble(value);

            RECORD_EVENT_DATA xRecordEventData;
            xRecordEventData.nOpType = AFRecord::Update;
            xRecordEventData.nRow = row;
            xRecordEventData.nCol = col;
            xRecordEventData.strRecordName = name;

            OnEventHandler(self, xRecordEventData, oldData, newData);
        }
    } while (0);

    return record->SetDouble(row, col, value);
}

bool AFCRecordMgr::SetRecordString(const char* name, const int row, const int col, const char* value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    //callback
    do
    {
        AFCData oldData;
        if (!GetRecordData(name, row, col, oldData))
        {
            ARK_ASSERT_RET_VAL(0, false);
        }

        if (ARK_STRICMP(oldData.GetString(), value) == 0)
        {
            return false;
        }

        if (!mxRecordCallbacks.empty())
        {
            AFCData newData;
            newData.SetString(value);

            RECORD_EVENT_DATA xRecordEventData;
            xRecordEventData.nOpType = AFRecord::Update;
            xRecordEventData.nRow = row;
            xRecordEventData.nCol = col;
            xRecordEventData.strRecordName = name;

            OnEventHandler(self, xRecordEventData, oldData, newData);
        }
    } while (0);

    return record->SetString(row, col, value);
}

bool AFCRecordMgr::SetRecordObject(const char* name, const int row, const int col, const AFGUID& value)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    //callback
    do
    {
        AFCData oldData;
        if (!GetRecordData(name, row, col, oldData))
        {
            ARK_ASSERT_RET_VAL(0, false);
        }

        if (oldData.GetObject() == value)
        {
            return false;
        }

        if (!mxRecordCallbacks.empty())
        {
            AFCData newData;
            newData.SetObject(value);

            RECORD_EVENT_DATA xRecordEventData;
            xRecordEventData.nOpType = AFRecord::Update;
            xRecordEventData.nRow = row;
            xRecordEventData.nCol = col;
            xRecordEventData.strRecordName = name;

            OnEventHandler(self, xRecordEventData, oldData, newData);
        }
    } while (0);

    return record->SetObject(row, col, value);
}

bool AFCRecordMgr::GetRecordBool(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return false;
    }

    return record->GetBool(row, col);
}

int32_t AFCRecordMgr::GetRecordInt(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_INT;
    }

    return record->GetInt(row, col);
}

int64_t AFCRecordMgr::GetRecordInt64(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_INT64;
    }

    return record->GetInt64(row, col);
}

float AFCRecordMgr::GetRecordFloat(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_FLOAT;
    }

    return record->GetFloat(row, col);
}

double AFCRecordMgr::GetRecordDouble(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_DOUBLE;
    }

    return record->GetDouble(row, col);
}

const char* AFCRecordMgr::GetRecordString(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_STR.c_str();
    }

    return record->GetString(row, col);
}

const AFGUID& AFCRecordMgr::GetRecordObject(const char* name, const int row, const int col)
{
    AFRecord* record = GetRecord(name);
    if(NULL == record)
    {
        return NULL_GUID;
    }

    return record->GetObject(row, col);
}<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkSelectionSource.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkSelectionSource.h"

#include "vtkCommand.h"
#include "vtkIdTypeArray.h"
#include "vtkDoubleArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkSelection.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTrivialProducer.h"

#include "vtkstd/vector"
#include "vtkstd/set"

vtkCxxRevisionMacro(vtkSelectionSource, "1.12");
vtkStandardNewMacro(vtkSelectionSource);

class vtkSelectionSourceInternals
{
public:
  vtkSelectionSourceInternals()
    {
    this->Values = NULL;
    }

  ~vtkSelectionSourceInternals()
    {
    if (this->Values)
      {
      this->Values->Delete();
      }
    }

  typedef vtkstd::set<vtkIdType> IDSetType;
  typedef vtkstd::vector<IDSetType> IDsType;
  IDsType IDs;

  vtkAbstractArray *Values;
};

//----------------------------------------------------------------------------
vtkSelectionSource::vtkSelectionSource()
{
  this->SetNumberOfInputPorts(0);
  this->Internal = new vtkSelectionSourceInternals;

  this->ContentType = vtkSelection::INDICES;
  this->FieldType = vtkSelection::CELL;
  this->ContainingCells = 1;
  this->PreserveTopology = 0;
  this->Inverse = 0;
  this->ExactTest = 1;
  this->ShowBounds = 0;
  this->ArrayName = NULL;
}

//----------------------------------------------------------------------------
vtkSelectionSource::~vtkSelectionSource()
{
  delete this->Internal;
  if (this->ArrayName)
    {
    delete[] this->ArrayName;
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::RemoveAllIDs()
{
  this->Internal->IDs.clear();
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkSelectionSource::RemoveAllValues()
{
  if (this->Internal->Values)
    {
    this->Internal->Values->Reset();
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::AddID(vtkIdType proc, vtkIdType id)
{
  if (this->ContentType != vtkSelection::GLOBALIDS &&
      this->ContentType != vtkSelection::INDICES)
    {
    return;
    }

  // proc == -1 means all processes. All other are stored at index proc+1
  proc++;

  if (proc >= (vtkIdType)this->Internal->IDs.size())
    {
    this->Internal->IDs.resize(proc+1);
    }
  vtkSelectionSourceInternals::IDSetType& idSet = this->Internal->IDs[proc];
  idSet.insert(id);
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkSelectionSource::AddLocation(double x, double y, double z)
{
  if (this->ContentType != vtkSelection::LOCATIONS)
    {
    return;
    }

  vtkDoubleArray *da = vtkDoubleArray::SafeDownCast(this->Internal->Values);
  if (da)
    {
    da->InsertNextTuple3(x,y,z);
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::AddThreshold(double min, double max)
{
  if (this->ContentType != vtkSelection::THRESHOLDS)
    {
    return;
    }

  vtkDoubleArray *da = vtkDoubleArray::SafeDownCast(this->Internal->Values);
  if (da)
    {
    da->InsertNextValue(min);
    da->InsertNextValue(max);
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::SetFrustum(double *vertices)
{
  if (this->ContentType != vtkSelection::FRUSTUM)
    {
    return;
    }

  vtkDoubleArray *da = vtkDoubleArray::SafeDownCast(this->Internal->Values);
  if (da)
    {
    double *data = da->GetPointer(0);
    memcpy(data, vertices, 32*sizeof(double));
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "ContentType: " ;
  switch (this->ContentType)
    {
  case vtkSelection::SELECTIONS:
    os << "SELECTIONS";
    break;
  case vtkSelection::COMPOSITE_SELECTIONS:
    os << "COMPOSITE_SELECTIONS";
    break;
  case vtkSelection::GLOBALIDS:
    os << "GLOBALIDS";
    break;
  case vtkSelection::VALUES:
    os << "VALUES";
    break;
  case vtkSelection::INDICES:
    os << "INDICES";
    break;
  case vtkSelection::FRUSTUM:
    os << "FRUSTUM";
    break;
  case vtkSelection::LOCATIONS:
    os << "LOCATIONS";
    break;
  case vtkSelection::THRESHOLDS:
    os << "THRESHOLDS";
    break;
  default:
    os << "UNKNOWN";
    }
  os << endl;

  os << indent << "FieldType: " ;
  switch (this->FieldType)
    {
  case vtkSelection::CELL:
    os << "CELL";
    break;
  case vtkSelection::POINT:
    os << "POINT";
    break;
  default:
    os << "UNKNOWN";
    }
  os << endl;

  os << indent << "ContainingCells: ";
  os << (this->ContainingCells?"CELLS":"POINTS") << endl;
  os << indent << "PreserveTopology: " << this->PreserveTopology << endl;
  os << indent << "Inverse: " << this->Inverse << endl;
  os << indent << "ExactTest: " << this->ExactTest << endl;
  os << indent << "ShowBounds: " << this->ShowBounds << endl;
  os << indent << "ArrayName: " << (this->ArrayName?this->ArrayName:"NULL") << endl;
}

//----------------------------------------------------------------------------
int vtkSelectionSource::RequestInformation(
  vtkInformation* vtkNotUsed(request),
  vtkInformationVector** vtkNotUsed(inputVector),
  vtkInformationVector* outputVector)
{
  // We can handle multiple piece request.
  vtkInformation* info = outputVector->GetInformationObject(0);
  info->Set(
    vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);

  return 1;
}

//----------------------------------------------------------------------------
int vtkSelectionSource::RequestData(
  vtkInformation* vtkNotUsed( request ),
  vtkInformationVector** vtkNotUsed( inputVector ),
  vtkInformationVector* outputVector )
{
  vtkSelection* output = vtkSelection::GetData(outputVector);

  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  int piece = 0;
  if (outInfo->Has(
        vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()))
    {
    piece = outInfo->Get(
      vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
    }

  if (
    (this->ContentType == vtkSelection::GLOBALIDS) ||
    (this->ContentType == vtkSelection::INDICES))
    {
    output->GetProperties()->Set(vtkSelection::CONTENT_TYPE(),
      this->ContentType);
    output->GetProperties()->Set(vtkSelection::FIELD_TYPE(),
      this->FieldType);

    // Number of selected items common to all pieces
    vtkIdType numCommonElems = 0;
    if (!this->Internal->IDs.empty())
      {
      numCommonElems = this->Internal->IDs[0].size();
      }
    if (piece+1 >= (int)this->Internal->IDs.size() &&
        numCommonElems == 0)
      {
      vtkDebugMacro("No selection for piece: " << piece);
      return 1;
      }

    // idx == 0 is the list for all pieces
    // idx == piece+1 is the list for the current piece
    size_t pids[2] = {0, piece+1};
    for(int i=0; i<2; i++)
      {
      size_t idx = pids[i];
      if (idx >= this->Internal->IDs.size())
        {
        continue;
        }

      vtkSelectionSourceInternals::IDSetType& selSet =
        this->Internal->IDs[idx];

      if (selSet.size() > 0)
        {
        // Create the selection list
        vtkIdTypeArray* selectionList = vtkIdTypeArray::New();
        selectionList->SetNumberOfTuples(selSet.size());
        // iterate over ids and insert to the selection list
        vtkSelectionSourceInternals::IDSetType::iterator iter =
          selSet.begin();
        for (vtkIdType idx2=0; iter != selSet.end(); iter++, idx2++)
          {
          selectionList->SetValue(idx2, *iter);
          }
        output->SetSelectionList(selectionList);
        selectionList->Delete();
        }
      }
    }

  if (
    (this->ContentType == vtkSelection::LOCATIONS)
    &&
    (this->Internal->Values != 0)
    )
    {
    output->GetProperties()->Set(vtkSelection::CONTENT_TYPE(),
                                 this->ContentType);
    output->GetProperties()->Set(vtkSelection::FIELD_TYPE(),
                                 this->FieldType);
    // Create the selection list
    vtkAbstractArray* selectionList = this->Internal->Values->NewInstance();
    selectionList->DeepCopy(this->Internal->Values);
    output->SetSelectionList(selectionList);
    selectionList->Delete();
    }

  if (
    (this->ContentType == vtkSelection::THRESHOLDS)
    &&
    (this->Internal->Values != 0)
    )
    {
    output->GetProperties()->Set(vtkSelection::CONTENT_TYPE(),
                                 this->ContentType);
    output->GetProperties()->Set(vtkSelection::FIELD_TYPE(),
                                 this->FieldType);
    // Create the selection list
    vtkAbstractArray* selectionList = this->Internal->Values->NewInstance();
    selectionList->DeepCopy(this->Internal->Values);
    output->SetSelectionList(selectionList);
    selectionList->Delete();
    }

  if (
    (this->ContentType == vtkSelection::FRUSTUM)
    &&
    (this->Internal->Values != 0)
    )
    {
    output->GetProperties()->Set(vtkSelection::CONTENT_TYPE(),
                                 this->ContentType);
    output->GetProperties()->Set(vtkSelection::FIELD_TYPE(),
                                 this->FieldType);
    // Create the selection list
    vtkAbstractArray* selectionList = this->Internal->Values->NewInstance();
    selectionList->DeepCopy(this->Internal->Values);
    output->SetSelectionList(selectionList);
    selectionList->Delete();
    }

  output->GetProperties()->Set(vtkSelection::CONTAINING_CELLS(),
                               this->ContainingCells);

  output->GetProperties()->Set(vtkSelection::PRESERVE_TOPOLOGY(),
                               this->PreserveTopology);

  output->GetProperties()->Set(vtkSelection::INVERSE(),
                               this->Inverse);

  output->GetProperties()->Set(vtkSelection::ARRAY_NAME(),
                               this->ArrayName);

  output->GetProperties()->Set(vtkSelection::EXACT_TEST(),
                               this->ExactTest);

  output->GetProperties()->Set(vtkSelection::SHOW_BOUNDS(),
                               this->ShowBounds);
  return 1;
}

//------------------------------------------------------------------------------
void vtkSelectionSource::SetContentType(int value)
{
  vtkDebugMacro(<< this->GetClassName() << " (" << this << "): setting ContentType to " << value);
  if (this->ContentType != value)
    {
    this->ContentType = value;
    this->RemoveAllIDs();
    this->RemoveAllValues();
    if (this->Internal->Values)
      {
      this->Internal->Values->Delete();
      }
    switch (value)
      {
      case vtkSelection::LOCATIONS:
        {
        vtkDoubleArray *da = vtkDoubleArray::New();
        da->SetNumberOfComponents(3);
        da->SetNumberOfTuples(0);
        this->Internal->Values = da;
        break;
        }
      case vtkSelection::THRESHOLDS:
        {
        vtkDoubleArray *da = vtkDoubleArray::New();
        da->SetNumberOfComponents(1);
        da->SetNumberOfTuples(0);
        this->Internal->Values = da;
        break;
        }
      case vtkSelection::FRUSTUM:
        {
        vtkDoubleArray *da = vtkDoubleArray::New();
        da->SetNumberOfComponents(4);
        da->SetNumberOfTuples(8);
        this->Internal->Values = da;
        break;
        }
      default:
        break;
      }
    this->Modified();
    }
}
<commit_msg>BUG: Dangling pointer.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkSelectionSource.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkSelectionSource.h"

#include "vtkCommand.h"
#include "vtkIdTypeArray.h"
#include "vtkDoubleArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkSelection.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTrivialProducer.h"

#include "vtkstd/vector"
#include "vtkstd/set"

vtkCxxRevisionMacro(vtkSelectionSource, "1.13");
vtkStandardNewMacro(vtkSelectionSource);

class vtkSelectionSourceInternals
{
public:
  vtkSelectionSourceInternals()
    {
    this->Values = NULL;
    }

  ~vtkSelectionSourceInternals()
    {
    if (this->Values)
      {
      this->Values->Delete();
      }
    }

  typedef vtkstd::set<vtkIdType> IDSetType;
  typedef vtkstd::vector<IDSetType> IDsType;
  IDsType IDs;

  vtkAbstractArray *Values;
};

//----------------------------------------------------------------------------
vtkSelectionSource::vtkSelectionSource()
{
  this->SetNumberOfInputPorts(0);
  this->Internal = new vtkSelectionSourceInternals;

  this->ContentType = vtkSelection::INDICES;
  this->FieldType = vtkSelection::CELL;
  this->ContainingCells = 1;
  this->PreserveTopology = 0;
  this->Inverse = 0;
  this->ExactTest = 1;
  this->ShowBounds = 0;
  this->ArrayName = NULL;
}

//----------------------------------------------------------------------------
vtkSelectionSource::~vtkSelectionSource()
{
  delete this->Internal;
  if (this->ArrayName)
    {
    delete[] this->ArrayName;
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::RemoveAllIDs()
{
  this->Internal->IDs.clear();
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkSelectionSource::RemoveAllValues()
{
  if (this->Internal->Values)
    {
    this->Internal->Values->Reset();
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::AddID(vtkIdType proc, vtkIdType id)
{
  if (this->ContentType != vtkSelection::GLOBALIDS &&
      this->ContentType != vtkSelection::INDICES)
    {
    return;
    }

  // proc == -1 means all processes. All other are stored at index proc+1
  proc++;

  if (proc >= (vtkIdType)this->Internal->IDs.size())
    {
    this->Internal->IDs.resize(proc+1);
    }
  vtkSelectionSourceInternals::IDSetType& idSet = this->Internal->IDs[proc];
  idSet.insert(id);
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkSelectionSource::AddLocation(double x, double y, double z)
{
  if (this->ContentType != vtkSelection::LOCATIONS)
    {
    return;
    }

  vtkDoubleArray *da = vtkDoubleArray::SafeDownCast(this->Internal->Values);
  if (da)
    {
    da->InsertNextTuple3(x,y,z);
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::AddThreshold(double min, double max)
{
  if (this->ContentType != vtkSelection::THRESHOLDS)
    {
    return;
    }

  vtkDoubleArray *da = vtkDoubleArray::SafeDownCast(this->Internal->Values);
  if (da)
    {
    da->InsertNextValue(min);
    da->InsertNextValue(max);
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::SetFrustum(double *vertices)
{
  if (this->ContentType != vtkSelection::FRUSTUM)
    {
    return;
    }

  vtkDoubleArray *da = vtkDoubleArray::SafeDownCast(this->Internal->Values);
  if (da)
    {
    double *data = da->GetPointer(0);
    memcpy(data, vertices, 32*sizeof(double));
    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkSelectionSource::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "ContentType: " ;
  switch (this->ContentType)
    {
  case vtkSelection::SELECTIONS:
    os << "SELECTIONS";
    break;
  case vtkSelection::COMPOSITE_SELECTIONS:
    os << "COMPOSITE_SELECTIONS";
    break;
  case vtkSelection::GLOBALIDS:
    os << "GLOBALIDS";
    break;
  case vtkSelection::VALUES:
    os << "VALUES";
    break;
  case vtkSelection::INDICES:
    os << "INDICES";
    break;
  case vtkSelection::FRUSTUM:
    os << "FRUSTUM";
    break;
  case vtkSelection::LOCATIONS:
    os << "LOCATIONS";
    break;
  case vtkSelection::THRESHOLDS:
    os << "THRESHOLDS";
    break;
  default:
    os << "UNKNOWN";
    }
  os << endl;

  os << indent << "FieldType: " ;
  switch (this->FieldType)
    {
  case vtkSelection::CELL:
    os << "CELL";
    break;
  case vtkSelection::POINT:
    os << "POINT";
    break;
  default:
    os << "UNKNOWN";
    }
  os << endl;

  os << indent << "ContainingCells: ";
  os << (this->ContainingCells?"CELLS":"POINTS") << endl;
  os << indent << "PreserveTopology: " << this->PreserveTopology << endl;
  os << indent << "Inverse: " << this->Inverse << endl;
  os << indent << "ExactTest: " << this->ExactTest << endl;
  os << indent << "ShowBounds: " << this->ShowBounds << endl;
  os << indent << "ArrayName: " << (this->ArrayName?this->ArrayName:"NULL") << endl;
}

//----------------------------------------------------------------------------
int vtkSelectionSource::RequestInformation(
  vtkInformation* vtkNotUsed(request),
  vtkInformationVector** vtkNotUsed(inputVector),
  vtkInformationVector* outputVector)
{
  // We can handle multiple piece request.
  vtkInformation* info = outputVector->GetInformationObject(0);
  info->Set(
    vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES(), -1);

  return 1;
}

//----------------------------------------------------------------------------
int vtkSelectionSource::RequestData(
  vtkInformation* vtkNotUsed( request ),
  vtkInformationVector** vtkNotUsed( inputVector ),
  vtkInformationVector* outputVector )
{
  vtkSelection* output = vtkSelection::GetData(outputVector);

  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  int piece = 0;
  if (outInfo->Has(
        vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()))
    {
    piece = outInfo->Get(
      vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER());
    }

  if (
    (this->ContentType == vtkSelection::GLOBALIDS) ||
    (this->ContentType == vtkSelection::INDICES))
    {
    output->GetProperties()->Set(vtkSelection::CONTENT_TYPE(),
      this->ContentType);
    output->GetProperties()->Set(vtkSelection::FIELD_TYPE(),
      this->FieldType);

    // Number of selected items common to all pieces
    vtkIdType numCommonElems = 0;
    if (!this->Internal->IDs.empty())
      {
      numCommonElems = this->Internal->IDs[0].size();
      }
    if (piece+1 >= (int)this->Internal->IDs.size() &&
        numCommonElems == 0)
      {
      vtkDebugMacro("No selection for piece: " << piece);
      return 1;
      }

    // idx == 0 is the list for all pieces
    // idx == piece+1 is the list for the current piece
    size_t pids[2] = {0, piece+1};
    for(int i=0; i<2; i++)
      {
      size_t idx = pids[i];
      if (idx >= this->Internal->IDs.size())
        {
        continue;
        }

      vtkSelectionSourceInternals::IDSetType& selSet =
        this->Internal->IDs[idx];

      if (selSet.size() > 0)
        {
        // Create the selection list
        vtkIdTypeArray* selectionList = vtkIdTypeArray::New();
        selectionList->SetNumberOfTuples(selSet.size());
        // iterate over ids and insert to the selection list
        vtkSelectionSourceInternals::IDSetType::iterator iter =
          selSet.begin();
        for (vtkIdType idx2=0; iter != selSet.end(); iter++, idx2++)
          {
          selectionList->SetValue(idx2, *iter);
          }
        output->SetSelectionList(selectionList);
        selectionList->Delete();
        }
      }
    }

  if (
    (this->ContentType == vtkSelection::LOCATIONS)
    &&
    (this->Internal->Values != 0)
    )
    {
    output->GetProperties()->Set(vtkSelection::CONTENT_TYPE(),
                                 this->ContentType);
    output->GetProperties()->Set(vtkSelection::FIELD_TYPE(),
                                 this->FieldType);
    // Create the selection list
    vtkAbstractArray* selectionList = this->Internal->Values->NewInstance();
    selectionList->DeepCopy(this->Internal->Values);
    output->SetSelectionList(selectionList);
    selectionList->Delete();
    }

  if (
    (this->ContentType == vtkSelection::THRESHOLDS)
    &&
    (this->Internal->Values != 0)
    )
    {
    output->GetProperties()->Set(vtkSelection::CONTENT_TYPE(),
                                 this->ContentType);
    output->GetProperties()->Set(vtkSelection::FIELD_TYPE(),
                                 this->FieldType);
    // Create the selection list
    vtkAbstractArray* selectionList = this->Internal->Values->NewInstance();
    selectionList->DeepCopy(this->Internal->Values);
    output->SetSelectionList(selectionList);
    selectionList->Delete();
    }

  if (
    (this->ContentType == vtkSelection::FRUSTUM)
    &&
    (this->Internal->Values != 0)
    )
    {
    output->GetProperties()->Set(vtkSelection::CONTENT_TYPE(),
                                 this->ContentType);
    output->GetProperties()->Set(vtkSelection::FIELD_TYPE(),
                                 this->FieldType);
    // Create the selection list
    vtkAbstractArray* selectionList = this->Internal->Values->NewInstance();
    selectionList->DeepCopy(this->Internal->Values);
    output->SetSelectionList(selectionList);
    selectionList->Delete();
    }

  output->GetProperties()->Set(vtkSelection::CONTAINING_CELLS(),
                               this->ContainingCells);

  output->GetProperties()->Set(vtkSelection::PRESERVE_TOPOLOGY(),
                               this->PreserveTopology);

  output->GetProperties()->Set(vtkSelection::INVERSE(),
                               this->Inverse);

  output->GetProperties()->Set(vtkSelection::ARRAY_NAME(),
                               this->ArrayName);

  output->GetProperties()->Set(vtkSelection::EXACT_TEST(),
                               this->ExactTest);

  output->GetProperties()->Set(vtkSelection::SHOW_BOUNDS(),
                               this->ShowBounds);
  return 1;
}

//------------------------------------------------------------------------------
void vtkSelectionSource::SetContentType(int value)
{
  vtkDebugMacro(<< this->GetClassName() << " (" << this << "): setting ContentType to " << value);
  if (this->ContentType != value)
    {
    this->ContentType = value;
    this->RemoveAllIDs();
    this->RemoveAllValues();
    if (this->Internal->Values)
      {
      this->Internal->Values->Delete();
      this->Internal->Values=0;
      }
    switch (value)
      {
      case vtkSelection::LOCATIONS:
        {
        vtkDoubleArray *da = vtkDoubleArray::New();
        da->SetNumberOfComponents(3);
        da->SetNumberOfTuples(0);
        this->Internal->Values = da;
        break;
        }
      case vtkSelection::THRESHOLDS:
        {
        vtkDoubleArray *da = vtkDoubleArray::New();
        da->SetNumberOfComponents(1);
        da->SetNumberOfTuples(0);
        this->Internal->Values = da;
        break;
        }
      case vtkSelection::FRUSTUM:
        {
        vtkDoubleArray *da = vtkDoubleArray::New();
        da->SetNumberOfComponents(4);
        da->SetNumberOfTuples(8);
        this->Internal->Values = da;
        break;
        }
      default:
        break;
      }
    this->Modified();
    }
}
<|endoftext|>


<commit_before>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define BUFSIZE 121
#define FILENAME "Testfile"
#define TEST_FILENAME "Testfile2"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1

using namespace std;

bool gremlin(Packet * pack, int corruptProb, int lossProb);
bool init(int argc, char** argv);
bool loadFile();
bool sendFile();
bool getFile();
char * recvPkt();
bool isvpack(unsigned char * p);
Packet createPacket(int index);
bool sendPacket();
bool isAck();
void handleAck();
void handleNak(int& x);

int seqNum;
int s;
int probCorrupt;
int probLoss;
string hs;
short int port;
char * file;
unsigned char* window[16]; //packet window
int windowBase; //used to determine position in window of arriving packets
int length;
struct sockaddr_in a;
struct sockaddr_in sa;
socklen_t salen;
string fstr;
bool dropPck;
Packet p;
int delayT;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  if(sendto(s, "GET Testfile", BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
    return false;
  }

  getFile();

  return 0;
}

bool init(int argc, char** argv) {
  windowBase = 0; //initialize windowBase
  s = 0;

  hs = string("131.204.14.") + argv[1]; /* Needs to be updated? Might be a string like "tux175.engr.auburn.edu." */
  port = 10038; /* Can be any port within 10038-10041, inclusive. */

  char* delayTStr = argv[2];
  delayT = boost::lexical_cast<int>(delayTStr);

  /*if(!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }*/

  if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY); //why does this always give us 0?
  a.sin_port = htons(0);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0){
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return false;
  }

  memset((char *)&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(port);
  inet_pton(AF_INET, hs.c_str(), &(sa.sin_addr));

  cout << endl;

  cout << "Server address (inet mode): " << inet_ntoa(sa.sin_addr) << endl;
  cout << "Port: " << ntohs(sa.sin_port) << endl;

  cout << endl << endl;

  /*fstr = string(file);

  cout << "File: " << endl << fstr << endl << endl;*/

  seqNum = 0;
  dropPck = false;
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= length / BUFSIZE; x++) {
    p = createPacket(x);
    if(!sendPacket()) continue;

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);
    if(index * BUFSIZE + BUFSIZE > length) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss;
    if((dropPck = gremlin(&p, pc, pl)) == false){
      if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
        return false;
      }
      return true;
    } else return false;
}
bool isAck() {
    recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&sa, &salen);

    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}

bool gremlin(Packet * pack, int corruptProb, int lossProb){
  bool dropPacket = false;
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  if(r <= (lossProb)){
    dropPacket = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return dropPacket;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[6];
  memcpy(css, &p[1], 6);
  css[5] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[7], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == seqNum) return false;
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){
  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  int rlen;
  int ack;

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&sa, &salen);

	/* Begin Window Loading */
	int tempSeqNum = boost::lexical_cast<int>(packet[0]);
	int properIndex = tempSeqNum - windowBase;

	window[properIndex] = packet;
	cout << "Packet loaded into window" << endl;
	char* tempTest = new char[6];
		memcpy(tempTest, &window[1], 0);
		tempTest[5] = '\0';

	cout << "The Checksum pulled from client window: " << tempTest[0] << endl;

	for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
	  char * sns = new char[3];
	  memcpy(sns, &packet[0], 3);
	  sns[2] = '\0';

      char * css = new char[6];
      memcpy(css, &packet[2], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << packet[0] << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      if(isvpack(packet)) {

		if(boost::lexical_cast<int>(sns) == windowBase) windowBase++; //increment base of window //FIXME
        file << dataPull;
		file.flush();
      }
      cout << "Sent response: ";
      cout << "ACK " << windowBase << endl;

	  if(packet[6] == '1') usleep(delayT*1000);

	  string wbs = to_string((long long)windowBase);
	  const char * ackval = wbs.c_str();

      if(sendto(s, ackval, PAKSIZE, 0, (struct sockaddr *)&sa, salen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}
<commit_msg>Fix testing statement<commit_after>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define BUFSIZE 121
#define FILENAME "Testfile"
#define TEST_FILENAME "Testfile2"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1

using namespace std;

bool gremlin(Packet * pack, int corruptProb, int lossProb);
bool init(int argc, char** argv);
bool loadFile();
bool sendFile();
bool getFile();
char * recvPkt();
bool isvpack(unsigned char * p);
Packet createPacket(int index);
bool sendPacket();
bool isAck();
void handleAck();
void handleNak(int& x);

int seqNum;
int s;
int probCorrupt;
int probLoss;
string hs;
short int port;
char * file;
unsigned char* window[16]; //packet window
int windowBase; //used to determine position in window of arriving packets
int length;
struct sockaddr_in a;
struct sockaddr_in sa;
socklen_t salen;
string fstr;
bool dropPck;
Packet p;
int delayT;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  if(sendto(s, "GET Testfile", BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
    return false;
  }

  getFile();

  return 0;
}

bool init(int argc, char** argv) {
  windowBase = 0; //initialize windowBase
  s = 0;

  hs = string("131.204.14.") + argv[1]; /* Needs to be updated? Might be a string like "tux175.engr.auburn.edu." */
  port = 10038; /* Can be any port within 10038-10041, inclusive. */

  char* delayTStr = argv[2];
  delayT = boost::lexical_cast<int>(delayTStr);

  /*if(!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }*/

  if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY); //why does this always give us 0?
  a.sin_port = htons(0);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0){
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return false;
  }

  memset((char *)&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(port);
  inet_pton(AF_INET, hs.c_str(), &(sa.sin_addr));

  cout << endl;

  cout << "Server address (inet mode): " << inet_ntoa(sa.sin_addr) << endl;
  cout << "Port: " << ntohs(sa.sin_port) << endl;

  cout << endl << endl;

  /*fstr = string(file);

  cout << "File: " << endl << fstr << endl << endl;*/

  seqNum = 0;
  dropPck = false;
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= length / BUFSIZE; x++) {
    p = createPacket(x);
    if(!sendPacket()) continue;

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);
    if(index * BUFSIZE + BUFSIZE > length) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss;
    if((dropPck = gremlin(&p, pc, pl)) == false){
      if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
        return false;
      }
      return true;
    } else return false;
}
bool isAck() {
    recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&sa, &salen);

    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}

bool gremlin(Packet * pack, int corruptProb, int lossProb){
  bool dropPacket = false;
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  if(r <= (lossProb)){
    dropPacket = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return dropPacket;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[2];
  memcpy(sns, &p[0], 1);
  sns[1] = '\0';

  char * css = new char[6];
  memcpy(css, &p[1], 6);
  css[5] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[7], 121);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  if(sn == seqNum) return false;
  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){
  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  int rlen;
  int ack;

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&sa, &salen);

	/* Begin Window Loading */
	int tempSeqNum = boost::lexical_cast<int>(packet[0]);
	int properIndex = tempSeqNum - windowBase;

	window[properIndex] = packet;
	cout << "Packet loaded into window" << endl;
	char* tempTest = new char[6];
		memcpy(tempTest, &window[1], 0);
		tempTest[5] = '\0';

	cout << "The Checksum pulled from client window: " << tempTest[0] << endl;

	for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
	  char * sns = new char[3];
	  memcpy(sns, &packet[0], 3);
	  sns[2] = '\0';

      char * css = new char[6];
      memcpy(css, &packet[2], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << sns << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      if(isvpack(packet)) {

		if(boost::lexical_cast<int>(sns) == windowBase) windowBase++; //increment base of window //FIXME
        file << dataPull;
		file.flush();
      }
      cout << "Sent response: ";
      cout << "ACK " << windowBase << endl;

	  if(packet[6] == '1') usleep(delayT*1000);

	  string wbs = to_string((long long)windowBase);
	  const char * ackval = wbs.c_str();

      if(sendto(s, ackval, PAKSIZE, 0, (struct sockaddr *)&sa, salen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageWeightedSum.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkImageWeightedSum.h"

#include "vtkObjectFactory.h"
#include "vtkDoubleArray.h"
#include "vtkImageData.h"
#include "vtkImageIterator.h"
#include "vtkImageProgressIterator.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkStreamingDemandDrivenPipeline.h"

vtkCxxRevisionMacro(vtkImageWeightedSum, "1.3");
vtkStandardNewMacro(vtkImageWeightedSum);

vtkCxxSetObjectMacro(vtkImageWeightedSum,Weights,vtkDoubleArray);
//----------------------------------------------------------------------------
// Description:
// Constructor sets default values
vtkImageWeightedSum::vtkImageWeightedSum()
{
  this->SetNumberOfInputPorts(1);

  // array of weights: need as many weights as inputs
  this->Weights = vtkDoubleArray::New();
  // By default normalize
  this->NormalizeByWeight = 1;
}

//----------------------------------------------------------------------------
vtkImageWeightedSum::~vtkImageWeightedSum()
{
  this->Weights->Delete();
}

//----------------------------------------------------------------------------
void vtkImageWeightedSum::SetWeight(vtkIdType id, double weight)
{
  // Reallocate if needed:
  this->Weights->SetNumberOfTuples(id+1);
  // Pass the new weight
  this->Weights->SetValue(id, weight);
}

//----------------------------------------------------------------------------
double vtkImageWeightedSum::CalculateTotalWeight()
{
  double totalWeight = 0.0;

  for(int i = 0; i < this->Weights->GetNumberOfTuples(); ++i)
    {
    totalWeight += this->Weights->GetValue(i);
    }
  return totalWeight;
}

//----------------------------------------------------------------------------
// Description:
// This templated function executes the filter for any type of data.
template <class T>
void vtkImageWeightedSumExecute(vtkImageWeightedSum *self,
                          vtkImageData **inDatas, int numInputs, vtkImageData *outData,
                          int outExt[6], int id, T*)
{
  const int fastpath = 256;
  vtkImageIterator<T> inItsFast[fastpath];
  T* inSIFast[fastpath];
  vtkImageProgressIterator<T> outIt(outData, outExt, self, id);

  double *weights = ((vtkDoubleArray *)self->GetWeights())->GetPointer(0);
  double totalWeight = self->CalculateTotalWeight();
  int normalize = self->GetNormalizeByWeight();
  vtkImageIterator<T> *inIts;
  T* *inSI;
  if( numInputs < fastpath )
    {
    inIts = inItsFast;
    inSI = inSIFast;
    }
  else
    {
    inIts = new vtkImageIterator<T>[numInputs];
    inSI = new T*[numInputs];
    }

  // Loop through all input ImageData to initialize iterators
  for(int i=0; i < numInputs; ++i)
    {
    inIts[i].Initialize(inDatas[i], outExt);
    }
  // Loop through ouput pixels
  while (!outIt.IsAtEnd())
    {
    for(int j=0; j < numInputs; ++j)
      {
      inSI[j] = inIts[j].BeginSpan();
      }
    T* outSI = outIt.BeginSpan();
    T* outSIEnd = outIt.EndSpan();
    // Pixel operation
    while (outSI != outSIEnd)
      {
      double sum = 0.;
      for(int k=0; k < numInputs; ++k)
        {
        sum += weights[k] * *inSI[k];
        }
      // Divide only if needed and different from 0
      if (normalize && totalWeight != 0.0)
        {
        sum /= totalWeight;
        }
      *outSI = static_cast<T>(sum); // do the cast only at the end
      outSI++;
      for(int l=0; l < numInputs; ++l)
        {
        inSI[l]++;
        }
      }
    for(int j=0; j < numInputs; ++j)
      {
      inIts[j].NextSpan();
      }
    outIt.NextSpan();
    }

  if( numInputs >= fastpath )
    {
    delete[] inIts;
    delete[] inSI;
    }
}

//----------------------------------------------------------------------------
// Description:
// This method is passed a input and output data, and executes the filter
// algorithm to fill the output from the input.
// It just executes a switch statement to call the correct function for
// the datas data types.
void vtkImageWeightedSum::ThreadedRequestData (
  vtkInformation * vtkNotUsed( request ),
  vtkInformationVector** vtkNotUsed( inputVector ),
  vtkInformationVector * vtkNotUsed( outputVector ),
  vtkImageData ***inData,
  vtkImageData **outData,
  int outExt[6], int id)
{
  if (inData[0][0] == NULL)
    {
    vtkErrorMacro(<< "Input " << 0 << " must be specified.");
    return;
    }

  // this filter expects that input is the same type as output.
  if (inData[0][0]->GetScalarType() != outData[0]->GetScalarType())
    {
    vtkErrorMacro(<< "Execute: input ScalarType, "
                  << inData[0][0]->GetScalarType()
                  << ", must match out ScalarType "
                  << outData[0]->GetScalarType());
    return;
    }

  int numInputs = this->GetNumberOfInputConnections(0);
  int numWeights = this->Weights->GetNumberOfTuples();
  if( numWeights != numInputs )
    {
    vtkErrorMacro( << "Execute: There are " << numInputs << " vtkImageData provided"
      << " but only " << numWeights << " number of weights provided" );
    return;
    }

  switch (inData[0][0]->GetScalarType())
    {
    vtkTemplateMacro(
      vtkImageWeightedSumExecute(this , inData[0], numInputs,
        outData[0], outExt, id, static_cast<VTK_TT *>(0))
      );
    default:
      vtkErrorMacro(<< "Execute: Unknown ScalarType");
      return;
    }
}

//----------------------------------------------------------------------------
int vtkImageWeightedSum::FillInputPortInformation(int i, vtkInformation* info)
{
  info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
  return this->Superclass::FillInputPortInformation(i,info);
}

//----------------------------------------------------------------------------
void vtkImageWeightedSum::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  // objects
  os << indent << "NormalizeByWeight: " <<
    (this->NormalizeByWeight ? "On" : "Off" ) << "\n";
  os << indent << "Weights: " << this->Weights << "\n";
  this->Weights->PrintSelf(os,indent.GetNextIndent());
}

<commit_msg>BUG: Need to properly reallocate the double array<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageWeightedSum.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkImageWeightedSum.h"

#include "vtkObjectFactory.h"
#include "vtkDoubleArray.h"
#include "vtkImageData.h"
#include "vtkImageIterator.h"
#include "vtkImageProgressIterator.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkStreamingDemandDrivenPipeline.h"

vtkCxxRevisionMacro(vtkImageWeightedSum, "1.4");
vtkStandardNewMacro(vtkImageWeightedSum);

vtkCxxSetObjectMacro(vtkImageWeightedSum,Weights,vtkDoubleArray);
//----------------------------------------------------------------------------
// Description:
// Constructor sets default values
vtkImageWeightedSum::vtkImageWeightedSum()
{
  this->SetNumberOfInputPorts(1);

  // array of weights: need as many weights as inputs
  this->Weights = vtkDoubleArray::New();
  // By default normalize
  this->NormalizeByWeight = 1;
}

//----------------------------------------------------------------------------
vtkImageWeightedSum::~vtkImageWeightedSum()
{
  this->Weights->Delete();
}

//----------------------------------------------------------------------------
void vtkImageWeightedSum::SetWeight(vtkIdType id, double weight)
{
  // Reallocate if needed and pass the new weight
  this->Weights->InsertValue(id, weight);
}

//----------------------------------------------------------------------------
double vtkImageWeightedSum::CalculateTotalWeight()
{
  double totalWeight = 0.0;

  for(int i = 0; i < this->Weights->GetNumberOfTuples(); ++i)
    {
    totalWeight += this->Weights->GetValue(i);
    }
  return totalWeight;
}

//----------------------------------------------------------------------------
// Description:
// This templated function executes the filter for any type of data.
template <class T>
void vtkImageWeightedSumExecute(vtkImageWeightedSum *self,
                          vtkImageData **inDatas, int numInputs, vtkImageData *outData,
                          int outExt[6], int id, T*)
{
  const int fastpath = 256;
  vtkImageIterator<T> inItsFast[fastpath];
  T* inSIFast[fastpath];
  vtkImageProgressIterator<T> outIt(outData, outExt, self, id);

  double *weights = ((vtkDoubleArray *)self->GetWeights())->GetPointer(0);
  double totalWeight = self->CalculateTotalWeight();
  int normalize = self->GetNormalizeByWeight();
  vtkImageIterator<T> *inIts;
  T* *inSI;
  if( numInputs < fastpath )
    {
    inIts = inItsFast;
    inSI = inSIFast;
    }
  else
    {
    inIts = new vtkImageIterator<T>[numInputs];
    inSI = new T*[numInputs];
    }

  // Loop through all input ImageData to initialize iterators
  for(int i=0; i < numInputs; ++i)
    {
    inIts[i].Initialize(inDatas[i], outExt);
    }
  // Loop through ouput pixels
  while (!outIt.IsAtEnd())
    {
    for(int j=0; j < numInputs; ++j)
      {
      inSI[j] = inIts[j].BeginSpan();
      }
    T* outSI = outIt.BeginSpan();
    T* outSIEnd = outIt.EndSpan();
    // Pixel operation
    while (outSI != outSIEnd)
      {
      double sum = 0.;
      for(int k=0; k < numInputs; ++k)
        {
        sum += weights[k] * *inSI[k];
        }
      // Divide only if needed and different from 0
      if (normalize && totalWeight != 0.0)
        {
        sum /= totalWeight;
        }
      *outSI = static_cast<T>(sum); // do the cast only at the end
      outSI++;
      for(int l=0; l < numInputs; ++l)
        {
        inSI[l]++;
        }
      }
    for(int j=0; j < numInputs; ++j)
      {
      inIts[j].NextSpan();
      }
    outIt.NextSpan();
    }

  if( numInputs >= fastpath )
    {
    delete[] inIts;
    delete[] inSI;
    }
}

//----------------------------------------------------------------------------
// Description:
// This method is passed a input and output data, and executes the filter
// algorithm to fill the output from the input.
// It just executes a switch statement to call the correct function for
// the datas data types.
void vtkImageWeightedSum::ThreadedRequestData (
  vtkInformation * vtkNotUsed( request ),
  vtkInformationVector** vtkNotUsed( inputVector ),
  vtkInformationVector * vtkNotUsed( outputVector ),
  vtkImageData ***inData,
  vtkImageData **outData,
  int outExt[6], int id)
{
  if (inData[0][0] == NULL)
    {
    vtkErrorMacro(<< "Input " << 0 << " must be specified.");
    return;
    }

  // this filter expects that input is the same type as output.
  if (inData[0][0]->GetScalarType() != outData[0]->GetScalarType())
    {
    vtkErrorMacro(<< "Execute: input ScalarType, "
                  << inData[0][0]->GetScalarType()
                  << ", must match out ScalarType "
                  << outData[0]->GetScalarType());
    return;
    }

  int numInputs = this->GetNumberOfInputConnections(0);
  int numWeights = this->Weights->GetNumberOfTuples();
  if( numWeights != numInputs )
    {
    vtkErrorMacro( << "Execute: There are " << numInputs << " vtkImageData provided"
      << " but only " << numWeights << " number of weights provided" );
    return;
    }

  switch (inData[0][0]->GetScalarType())
    {
    vtkTemplateMacro(
      vtkImageWeightedSumExecute(this , inData[0], numInputs,
        outData[0], outExt, id, static_cast<VTK_TT *>(0))
      );
    default:
      vtkErrorMacro(<< "Execute: Unknown ScalarType");
      return;
    }
}

//----------------------------------------------------------------------------
int vtkImageWeightedSum::FillInputPortInformation(int i, vtkInformation* info)
{
  info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
  return this->Superclass::FillInputPortInformation(i,info);
}

//----------------------------------------------------------------------------
void vtkImageWeightedSum::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  // objects
  os << indent << "NormalizeByWeight: " <<
    (this->NormalizeByWeight ? "On" : "Off" ) << "\n";
  os << indent << "Weights: " << this->Weights << "\n";
  this->Weights->PrintSelf(os,indent.GetNextIndent());
}

<|endoftext|>


<commit_before>#include "Effect.h"
#include "main.h"
#include <QFile>

Effect::Effect(RenderContext *context)
    : VideoNode(context),
    m_fboIndex(0),
    m_intensity(0),
    m_previous(0),
    m_blankPreviewFbo(0) {
}

void Effect::initialize() {
    QSize size = uiSettings->previewSize();

    delete m_displayPreviewFbo;
    m_displayPreviewFbo = new QOpenGLFramebufferObject(size);

    delete m_renderPreviewFbo;
    m_renderPreviewFbo = new QOpenGLFramebufferObject(size);

    delete m_blankPreviewFbo;
    m_blankPreviewFbo = new QOpenGLFramebufferObject(size);
}

void Effect::paint() {
    QSize size = uiSettings->previewSize();

    glClearColor(0, 0, 0, 0);
    glViewport(0, 0, size.width(), size.height());
    glDisable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT);
    glDisable(GL_BLEND);

    QOpenGLFramebufferObject *previousPreviewFbo;
    VideoNode *prev = previous();
    if(prev == 0) {
        resizeFbo(&m_blankPreviewFbo, size);
        m_blankPreviewFbo->bind();
        glClear(GL_COLOR_BUFFER_BIT);
        previousPreviewFbo = m_blankPreviewFbo;
    } else {
        previousPreviewFbo = prev->m_previewFbo;
    }

    m_programLock.lock();
    if(m_programs.count() > 0) {
        float values[] = {
            -1, -1,
            1, -1,
            -1, 1,
            1, 1
        };

        if(m_regeneratePreviewFbos) {
            foreach(QOpenGLFramebufferObject *f, m_previewFbos)
            delete f;
            m_previewFbos.clear();
            for(int i = 0; i < m_programs.count() + 1; i++) {
                m_previewFbos.append(new QOpenGLFramebufferObject(size));
                m_fboIndex = 0;
            }
            m_regeneratePreviewFbos = false;
        }

        for(int i = m_programs.count() - 1; i >= 0; i--) {
            resizeFbo(&m_previewFbos[(m_fboIndex + 1) % m_previewFbos.count()], size);
            auto target = m_previewFbos.at((m_fboIndex + 1) % m_previewFbos.count());
            auto  p = m_programs.at(i);

            p->bind();
            target->bind();

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, previousPreviewFbo->texture());
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, m_previewFbos.at(m_fboIndex)->texture());

            p->setAttributeArray(0, GL_FLOAT, values, 2);
            float intense = intensity();
            p->setUniformValue("iIntensity", intense);
            p->setUniformValue("iFrame", 0);
            p->setUniformValue("iChannelP", 1);
            p->enableAttributeArray(0);

            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

            p->disableAttributeArray(0);
            p->release();
        }

        m_fboIndex = (m_fboIndex + 1) % m_previewFbos.count();
        QOpenGLFramebufferObject::bindDefault();

        m_previewFbo = m_previewFbos.at(m_fboIndex);
    } else {
        m_previewFbo = previousPreviewFbo;
    }
    m_programLock.unlock();

    blitToRenderFbo();
}

Effect::~Effect() {
    beforeDestruction();
    foreach(QOpenGLShaderProgram *p, m_programs) delete p;
    foreach(QOpenGLFramebufferObject *fbo, m_previewFbos) delete fbo;
    m_programs.clear();
    m_previewFbos.clear();
    m_previewFbo = 0; // This points to one of m_previewFbos
}

QSet<VideoNode*> Effect::dependencies()
{
    QSet<VideoNode*> d;
    if(auto p = previous())
        d.insert(p);
    return d;
}

// Call this to load shader code into this Effect.
// This function is thread-safe, avoid calling this in the render thread.
// A current OpenGL context is required.
// Returns true if the program was loaded successfully
bool Effect::loadProgram(QString name) {
    QString filename = QString("../resources/effects/%1.glsl").arg(name);
    QFile file(filename);
    if(!file.open(QIODevice::ReadOnly)) {
        qDebug() << QString("Could not open \"%1\"").arg(filename);
        return false;
    }

    QTextStream s1(&file);
    QString s = s1.readAll();

    auto program = new QOpenGLShaderProgram();
    program->addShaderFromSourceCode(QOpenGLShader::Vertex,
                                       "attribute highp vec4 vertices;"
                                       "varying highp vec2 coords;"
                                       "void main() {"
                                       "    gl_Position = vertices;"
                                       "    coords = vertices.xy;"
                                       "}");
    program->addShaderFromSourceCode(QOpenGLShader::Fragment, s);
    program->bindAttributeLocation("vertices", 0);
    program->link();

    m_programLock.lock();
    foreach(QOpenGLShaderProgram *p, m_programs) delete p;
    m_programs.clear();
    m_programs.append(program);
    m_regeneratePreviewFbos = true;
    m_programLock.unlock();

    return true;
}

qreal Effect::intensity() {
    QMutexLocker locker(&m_intensityLock);
    return m_intensity;
}

VideoNode *Effect::previous() {
    QMutexLocker locker(&m_previousLock);
    return m_previous;
}

void Effect::setIntensity(qreal value) {
    {
        if(value > 1) value = 1;
        if(value < 0) value = 0;
        QMutexLocker locker(&m_intensityLock);
        if(m_intensity == value)
            return;
        m_intensity = value;
    }
    emit intensityChanged(value);
}

void Effect::setPrevious(VideoNode *value) {

    // TODO take context lock??
    {
        QMutexLocker locker(&m_context->m_contextLock);
        QMutexLocker locker(&m_previousLock);
        m_previous = value;
    }
}
<commit_msg>i'm dumb sometimes. v_v ( dedupe local variables. )<commit_after>#include "Effect.h"
#include "main.h"
#include <QFile>

Effect::Effect(RenderContext *context)
    : VideoNode(context),
    m_fboIndex(0),
    m_intensity(0),
    m_previous(0),
    m_blankPreviewFbo(0) {
}

void Effect::initialize() {
    QSize size = uiSettings->previewSize();

    delete m_displayPreviewFbo;
    m_displayPreviewFbo = new QOpenGLFramebufferObject(size);

    delete m_renderPreviewFbo;
    m_renderPreviewFbo = new QOpenGLFramebufferObject(size);

    delete m_blankPreviewFbo;
    m_blankPreviewFbo = new QOpenGLFramebufferObject(size);
}

void Effect::paint() {
    QSize size = uiSettings->previewSize();

    glClearColor(0, 0, 0, 0);
    glViewport(0, 0, size.width(), size.height());
    glDisable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT);
    glDisable(GL_BLEND);

    QOpenGLFramebufferObject *previousPreviewFbo;
    VideoNode *prev = previous();
    if(prev == 0) {
        resizeFbo(&m_blankPreviewFbo, size);
        m_blankPreviewFbo->bind();
        glClear(GL_COLOR_BUFFER_BIT);
        previousPreviewFbo = m_blankPreviewFbo;
    } else {
        previousPreviewFbo = prev->m_previewFbo;
    }

    m_programLock.lock();
    if(m_programs.count() > 0) {
        float values[] = {
            -1, -1,
            1, -1,
            -1, 1,
            1, 1
        };

        if(m_regeneratePreviewFbos) {
            foreach(QOpenGLFramebufferObject *f, m_previewFbos)
            delete f;
            m_previewFbos.clear();
            for(int i = 0; i < m_programs.count() + 1; i++) {
                m_previewFbos.append(new QOpenGLFramebufferObject(size));
                m_fboIndex = 0;
            }
            m_regeneratePreviewFbos = false;
        }

        for(int i = m_programs.count() - 1; i >= 0; i--) {
            resizeFbo(&m_previewFbos[(m_fboIndex + 1) % m_previewFbos.count()], size);
            auto target = m_previewFbos.at((m_fboIndex + 1) % m_previewFbos.count());
            auto  p = m_programs.at(i);

            p->bind();
            target->bind();

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, previousPreviewFbo->texture());
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, m_previewFbos.at(m_fboIndex)->texture());

            p->setAttributeArray(0, GL_FLOAT, values, 2);
            float intense = intensity();
            p->setUniformValue("iIntensity", intense);
            p->setUniformValue("iFrame", 0);
            p->setUniformValue("iChannelP", 1);
            p->enableAttributeArray(0);

            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

            p->disableAttributeArray(0);
            p->release();
        }

        m_fboIndex = (m_fboIndex + 1) % m_previewFbos.count();
        QOpenGLFramebufferObject::bindDefault();

        m_previewFbo = m_previewFbos.at(m_fboIndex);
    } else {
        m_previewFbo = previousPreviewFbo;
    }
    m_programLock.unlock();

    blitToRenderFbo();
}

Effect::~Effect() {
    beforeDestruction();
    foreach(QOpenGLShaderProgram *p, m_programs) delete p;
    foreach(QOpenGLFramebufferObject *fbo, m_previewFbos) delete fbo;
    m_programs.clear();
    m_previewFbos.clear();
    m_previewFbo = 0; // This points to one of m_previewFbos
}

QSet<VideoNode*> Effect::dependencies()
{
    QSet<VideoNode*> d;
    if(auto p = previous())
        d.insert(p);
    return d;
}

// Call this to load shader code into this Effect.
// This function is thread-safe, avoid calling this in the render thread.
// A current OpenGL context is required.
// Returns true if the program was loaded successfully
bool Effect::loadProgram(QString name) {
    QString filename = QString("../resources/effects/%1.glsl").arg(name);
    QFile file(filename);
    if(!file.open(QIODevice::ReadOnly)) {
        qDebug() << QString("Could not open \"%1\"").arg(filename);
        return false;
    }

    QTextStream s1(&file);
    QString s = s1.readAll();

    auto program = new QOpenGLShaderProgram();
    program->addShaderFromSourceCode(QOpenGLShader::Vertex,
                                       "attribute highp vec4 vertices;"
                                       "varying highp vec2 coords;"
                                       "void main() {"
                                       "    gl_Position = vertices;"
                                       "    coords = vertices.xy;"
                                       "}");
    program->addShaderFromSourceCode(QOpenGLShader::Fragment, s);
    program->bindAttributeLocation("vertices", 0);
    program->link();

    m_programLock.lock();
    foreach(QOpenGLShaderProgram *p, m_programs) delete p;
    m_programs.clear();
    m_programs.append(program);
    m_regeneratePreviewFbos = true;
    m_programLock.unlock();

    return true;
}

qreal Effect::intensity() {
    QMutexLocker locker(&m_intensityLock);
    return m_intensity;
}

VideoNode *Effect::previous() {
    QMutexLocker locker(&m_previousLock);
    return m_previous;
}

void Effect::setIntensity(qreal value) {
    {
        if(value > 1) value = 1;
        if(value < 0) value = 0;
        QMutexLocker locker(&m_intensityLock);
        if(m_intensity == value)
            return;
        m_intensity = value;
    }
    emit intensityChanged(value);
}

void Effect::setPrevious(VideoNode *value) {

    // TODO take context lock??
    {
        QMutexLocker clocker(&m_context->m_contextLock);
        QMutexLocker plocker(&m_previousLock);
        m_previous = value;
    }
}
<|endoftext|>


<commit_before>/*

    ofxTableGestures (formerly OF-TangibleFramework)
    Developed for Taller de Sistemes Interactius I
    Universitat Pompeu Fabra

    Copyright (c) 2011 Daniel Gallardo Grassot <daniel.gallardo@upf.edu>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#include "Figure.h"
#include "CollisionHelper.h"

namespace Figures
{

Figure::Figure():has_texture(false)
{
    bbox.Reset();
    matrix.SetIdentity();
}

Figure::~Figure()
{
    //dtor
}

void Figure::SetTexture(const std::string & path)
{
    if (path.compare("") == 0)
    {
        has_texture = false;
        return;
    }
    if(!texture.loadImage(path))
    {
        has_texture = false;
        return;
    }
    has_texture = true;
}

void Figure::SetTexture(ofImage& image)
{
    if(image.getHeight() == 0)
    {
        has_texture = false;
        return;
    }
    texture = image;
    has_texture = true;
}

void Figure::Draw()
{
    glGetDoublev(GL_MODELVIEW_MATRIX,matrix.data);
    if(CollisionHelper::debug_graphics)
    {
        bbox.Draw();
        ofNoFill();
        ofSetLineWidth(1.0f);
    }
    Design();
    if(CollisionHelper::debug_graphics)
        ofFill();

}

void Figure::DrawStroke()
{
    glGetDoublev(GL_MODELVIEW_MATRIX,matrix.data);
    DesignStroke();
    if(CollisionHelper::debug_graphics)
        bbox.Draw();
}

bool Figure::Collide(ofPoint const & point)
{
    ofPoint target = (CollisionHelper::ignore_transformation_matrix*matrix).TransformInverse(point);
    //std::cout << (CollisionHelper::ignore_transformation_matrix*matrix).ToString() << std::endl;
    //if(bbox.Collide(target.x,target.y) && CheckCollision(target))return true;
    //std::cout << target.x << " " << target.y << " -- " << point.x << " " << point.y << std::endl;
    if(bbox.Collide(target.x,target.y))
        if(CheckCollision(target))
            return true;
    return false;
}

ofPoint Figure::GetCentre()
{
    ofPoint center;
    /*center.x = 0;
    center.y = 0;
    center.z = 0;*/
    GetCentre(center.x,center.y);
    return matrix.Transform(center);
}

void Figure::GetCentre(float & x, float & y)
{
    ofPoint center;
    center.x = 0;
    center.y = 0;
    center.z = 0;
    matrix.Transform(center);
    x = center.x;
    y = center.y;
}

Matrix & Figure::getMatrix()
{
    return matrix;
}

}
<commit_msg>inverted textures for of 0.8.0<commit_after>/*

    ofxTableGestures (formerly OF-TangibleFramework)
    Developed for Taller de Sistemes Interactius I
    Universitat Pompeu Fabra

    Copyright (c) 2011 Daniel Gallardo Grassot <daniel.gallardo@upf.edu>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#include "Figure.h"
#include "CollisionHelper.h"

namespace Figures
{

Figure::Figure():has_texture(false)
{
    bbox.Reset();
    matrix.SetIdentity();
}

Figure::~Figure()
{
    //dtor
}

void Figure::SetTexture(const std::string & path)
{
    if (path.compare("") == 0)
    {
        has_texture = false;
        return;
    }
    if(!texture.loadImage(path))
    {
        has_texture = false;
        return;
    }
    texture.rotate90(2);
    has_texture = true;
}

void Figure::SetTexture(ofImage& image)
{
    if(image.getHeight() == 0)
    {
        has_texture = false;
        return;
    }
    texture = image;
    has_texture = true;
}

void Figure::Draw()
{
    glGetDoublev(GL_MODELVIEW_MATRIX,matrix.data);
    if(CollisionHelper::debug_graphics)
    {
        bbox.Draw();
        ofNoFill();
        ofSetLineWidth(1.0f);
    }
    Design();
    if(CollisionHelper::debug_graphics)
        ofFill();

}

void Figure::DrawStroke()
{
    glGetDoublev(GL_MODELVIEW_MATRIX,matrix.data);
    DesignStroke();
    if(CollisionHelper::debug_graphics)
        bbox.Draw();
}

bool Figure::Collide(ofPoint const & point)
{
    ofPoint target = (CollisionHelper::ignore_transformation_matrix*matrix).TransformInverse(point);
    //std::cout << (CollisionHelper::ignore_transformation_matrix*matrix).ToString() << std::endl;
    //if(bbox.Collide(target.x,target.y) && CheckCollision(target))return true;
    //std::cout << target.x << " " << target.y << " -- " << point.x << " " << point.y << std::endl;
    if(bbox.Collide(target.x,target.y))
        if(CheckCollision(target))
            return true;
    return false;
}

ofPoint Figure::GetCentre()
{
    ofPoint center;
    /*center.x = 0;
    center.y = 0;
    center.z = 0;*/
    GetCentre(center.x,center.y);
    return matrix.Transform(center);
}

void Figure::GetCentre(float & x, float & y)
{
    ofPoint center;
    center.x = 0;
    center.y = 0;
    center.z = 0;
    matrix.Transform(center);
    x = center.x;
    y = center.y;
}

Matrix & Figure::getMatrix()
{
    return matrix;
}

}
<|endoftext|>


<commit_before>#include "Folder.h"
#include "File.h"

#include "database/SqliteTools.h"
#include "filesystem/IDirectory.h"

namespace policy
{
    const std::string FolderTable::Name = "Folder";
    const std::string FolderTable::CacheColumn = "path";
    unsigned int Folder::* const FolderTable::PrimaryKey = &Folder::m_id;

    const FolderCache::KeyType&FolderCache::key(const std::shared_ptr<Folder>& self)
    {
        return self->path();
    }

    FolderCache::KeyType FolderCache::key( sqlite3_stmt* stmt )
    {
        return sqlite::Traits<FolderCache::KeyType>::Load( stmt, 1 );
    }

}

Folder::Folder( DBConnection dbConnection, sqlite3_stmt* stmt )
    : m_dbConection( dbConnection )
{
    m_id = sqlite::Traits<unsigned int>::Load( stmt, 0 );
    m_path = sqlite::Traits<std::string>::Load( stmt, 1 );
    m_parent = sqlite::Traits<unsigned int>::Load( stmt, 2 );
    m_lastModificationDate = sqlite::Traits<unsigned int>::Load( stmt, 3 );
    m_isRemovable = sqlite::Traits<bool>::Load( stmt, 4 );
}

Folder::Folder( const std::string& path, time_t lastModificationDate, bool isRemovable, unsigned int parent )
    : m_path( path )
    , m_parent( parent )
    , m_lastModificationDate( lastModificationDate )
    , m_isRemovable( isRemovable )
{
}

bool Folder::createTable(DBConnection connection)
{
    std::string req = "CREATE TABLE IF NOT EXISTS " + policy::FolderTable::Name +
            "("
            "id_folder INTEGER PRIMARY KEY AUTOINCREMENT,"
            "path TEXT UNIQUE ON CONFLICT FAIL,"
            "id_parent UNSIGNED INTEGER,"
            "last_modification_date UNSIGNED INTEGER,"
            "is_removable INTEGER,"
            "FOREIGN KEY (id_parent) REFERENCES " + policy::FolderTable::Name +
            "(id_folder) ON DELETE CASCADE"
            ")";
    return sqlite::Tools::executeRequest( connection, req );
}

FolderPtr Folder::create( DBConnection connection, const std::string& path, time_t lastModificationDate, bool isRemovable, unsigned int parentId )
{
    auto self = std::make_shared<Folder>( path, lastModificationDate, isRemovable, parentId );
    static const std::string req = "INSERT INTO " + policy::FolderTable::Name +
            "(path, id_parent, last_modification_date, is_removable) VALUES(?, ?, ?, ?)";
    if ( _Cache::insert( connection, self, req, path, sqlite::ForeignKey( parentId ),
                         lastModificationDate, isRemovable ) == false )
        return nullptr;
    self->m_dbConection = connection;
    return self;
}

unsigned int Folder::id() const
{
    return m_id;
}

const std::string& Folder::path()
{
    return m_path;
}

std::vector<FilePtr> Folder::files()
{
    static const std::string req = "SELECT * FROM " + policy::FileTable::Name +
        " WHERE folder_id = ?";
    return sqlite::Tools::fetchAll<File, IFile>( m_dbConection, req, m_id );
}

std::vector<FolderPtr> Folder::folders()
{
    static const std::string req = "SELECT * FROM " + policy::FolderTable::Name +
            " WHERE id_parent = ?";
    return sqlite::Tools::fetchAll<Folder, IFolder>( m_dbConection, req, m_id );
}

FolderPtr Folder::parent()
{
    //FIXME: use path to be able to fetch from cache?
    static const std::string req = "SELECT * FROM " + policy::FolderTable::Name +
            " WHERE id_folder = ?";
    return sqlite::Tools::fetchOne<Folder>( m_dbConection, req, m_parent );
}

unsigned int Folder::lastModificationDate()
{
    return m_lastModificationDate;
}

bool Folder::setLastModificationDate( unsigned int lastModificationDate )
{
    static const std::string req = "UPDATE " + policy::FolderTable::Name +
            " SET last_modification_date = ? WHERE id_folder = ?";
    if ( sqlite::Tools::executeUpdate( m_dbConection, req, lastModificationDate, m_id ) == false )
        return false;
    m_lastModificationDate = lastModificationDate;
    return true;
}

bool Folder::isRemovable()
{
    return m_isRemovable;
}
<commit_msg>Folder: Add missing initialization<commit_after>#include "Folder.h"
#include "File.h"

#include "database/SqliteTools.h"
#include "filesystem/IDirectory.h"

namespace policy
{
    const std::string FolderTable::Name = "Folder";
    const std::string FolderTable::CacheColumn = "path";
    unsigned int Folder::* const FolderTable::PrimaryKey = &Folder::m_id;

    const FolderCache::KeyType&FolderCache::key(const std::shared_ptr<Folder>& self)
    {
        return self->path();
    }

    FolderCache::KeyType FolderCache::key( sqlite3_stmt* stmt )
    {
        return sqlite::Traits<FolderCache::KeyType>::Load( stmt, 1 );
    }

}

Folder::Folder( DBConnection dbConnection, sqlite3_stmt* stmt )
    : m_dbConection( dbConnection )
{
    m_id = sqlite::Traits<unsigned int>::Load( stmt, 0 );
    m_path = sqlite::Traits<std::string>::Load( stmt, 1 );
    m_parent = sqlite::Traits<unsigned int>::Load( stmt, 2 );
    m_lastModificationDate = sqlite::Traits<unsigned int>::Load( stmt, 3 );
    m_isRemovable = sqlite::Traits<bool>::Load( stmt, 4 );
}

Folder::Folder( const std::string& path, time_t lastModificationDate, bool isRemovable, unsigned int parent )
    : m_id( 0 )
    , m_path( path )
    , m_parent( parent )
    , m_lastModificationDate( lastModificationDate )
    , m_isRemovable( isRemovable )
{
}

bool Folder::createTable(DBConnection connection)
{
    std::string req = "CREATE TABLE IF NOT EXISTS " + policy::FolderTable::Name +
            "("
            "id_folder INTEGER PRIMARY KEY AUTOINCREMENT,"
            "path TEXT UNIQUE ON CONFLICT FAIL,"
            "id_parent UNSIGNED INTEGER,"
            "last_modification_date UNSIGNED INTEGER,"
            "is_removable INTEGER,"
            "FOREIGN KEY (id_parent) REFERENCES " + policy::FolderTable::Name +
            "(id_folder) ON DELETE CASCADE"
            ")";
    return sqlite::Tools::executeRequest( connection, req );
}

FolderPtr Folder::create( DBConnection connection, const std::string& path, time_t lastModificationDate, bool isRemovable, unsigned int parentId )
{
    auto self = std::make_shared<Folder>( path, lastModificationDate, isRemovable, parentId );
    static const std::string req = "INSERT INTO " + policy::FolderTable::Name +
            "(path, id_parent, last_modification_date, is_removable) VALUES(?, ?, ?, ?)";
    if ( _Cache::insert( connection, self, req, path, sqlite::ForeignKey( parentId ),
                         lastModificationDate, isRemovable ) == false )
        return nullptr;
    self->m_dbConection = connection;
    return self;
}

unsigned int Folder::id() const
{
    return m_id;
}

const std::string& Folder::path()
{
    return m_path;
}

std::vector<FilePtr> Folder::files()
{
    static const std::string req = "SELECT * FROM " + policy::FileTable::Name +
        " WHERE folder_id = ?";
    return sqlite::Tools::fetchAll<File, IFile>( m_dbConection, req, m_id );
}

std::vector<FolderPtr> Folder::folders()
{
    static const std::string req = "SELECT * FROM " + policy::FolderTable::Name +
            " WHERE id_parent = ?";
    return sqlite::Tools::fetchAll<Folder, IFolder>( m_dbConection, req, m_id );
}

FolderPtr Folder::parent()
{
    //FIXME: use path to be able to fetch from cache?
    static const std::string req = "SELECT * FROM " + policy::FolderTable::Name +
            " WHERE id_folder = ?";
    return sqlite::Tools::fetchOne<Folder>( m_dbConection, req, m_parent );
}

unsigned int Folder::lastModificationDate()
{
    return m_lastModificationDate;
}

bool Folder::setLastModificationDate( unsigned int lastModificationDate )
{
    static const std::string req = "UPDATE " + policy::FolderTable::Name +
            " SET last_modification_date = ? WHERE id_folder = ?";
    if ( sqlite::Tools::executeUpdate( m_dbConection, req, lastModificationDate, m_id ) == false )
        return false;
    m_lastModificationDate = lastModificationDate;
    return true;
}

bool Folder::isRemovable()
{
    return m_isRemovable;
}
<|endoftext|>