<commit_before>#include "DefaultReporter.h"
#include <cstdio>
#include <iostream>
#include "TestDetails.h"

namespace xUnitpp
{

namespace DefaultReporter
{
    void ReportStart(const TestDetails &, int)
    {
    }

    void ReportFailure(const TestDetails &testDetails, int dataIndex, const std::string &msg)
    {
        if (dataIndex < 0)
        {
            std::cerr << (testDetails.Filename + "(" + std::to_string(testDetails.Line) +
                "): error in " + testDetails.Name + ": " + msg + "\n");
        }
        else
        {
            std::cerr << (testDetails.Filename + "(" + std::to_string(testDetails.Line) +
                "): error in " + testDetails.Name + "(" + std::to_string(dataIndex) + "): " + msg + "\n");
        }
    }

    void ReportSkip(const TestDetails &testDetails, const std::string &reason)
    {
        std::cerr << (testDetails.Filename + "(" + std::to_string(testDetails.Line) +
            "): skipping " + testDetails.Name + ": " + reason + "\n");
    }

    void ReportFinish(const TestDetails &, int, std::chrono::milliseconds)
    {
    }

    void ReportAllTestsComplete(size_t testCount, size_t skipped, size_t failureCount, std::chrono::milliseconds totalTime)
    {
        std::string total = std::to_string(testCount) + " tests, ";
        std::string failures = std::to_string(failureCount) + " failed, ";
        std::string skips = std::to_string(skipped) + " skipped.\n";

        std::string header;

        if (failureCount > 0)
        {
            header = "FAILURE: ";
        }
        else if (skipped > 0)
        {
            header = "WARNING: ";
        }
        else
        {
            header = "Success: ";
        }

        std::cout << (header + total + failures + skips);

        header = "Test time: ";
        std::cout << (header + std::to_string(totalTime.count()) + " milliseconds.\n");
    }

}

}
<commit_msg>better summary report from default reporter<commit_after>#include "DefaultReporter.h"
#include <cstdio>
#include <iostream>
#include "TestDetails.h"

namespace xUnitpp
{

namespace DefaultReporter
{
    void ReportStart(const TestDetails &, int)
    {
    }

    void ReportFailure(const TestDetails &testDetails, int dataIndex, const std::string &msg)
    {
        if (dataIndex < 0)
        {
            std::cerr << (testDetails.Filename + "(" + std::to_string(testDetails.Line) +
                "): error in " + testDetails.Name + ": " + msg + "\n");
        }
        else
        {
            std::cerr << (testDetails.Filename + "(" + std::to_string(testDetails.Line) +
                "): error in " + testDetails.Name + "(" + std::to_string(dataIndex) + "): " + msg + "\n");
        }
    }

    void ReportSkip(const TestDetails &testDetails, const std::string &reason)
    {
        std::cerr << (testDetails.Filename + "(" + std::to_string(testDetails.Line) +
            "): skipping " + testDetails.Name + ": " + reason + "\n");
    }

    void ReportFinish(const TestDetails &, int, std::chrono::milliseconds)
    {
    }

    void ReportAllTestsComplete(size_t testCount, size_t skipped, size_t failureCount, std::chrono::milliseconds totalTime)
    {
        std::string total = std::to_string(testCount) + " tests, ";
        std::string failures = std::to_string(failureCount) + " failed, ";
        std::string skips = std::to_string(skipped) + " skipped.\n";

        std::string header;

        if (failureCount > 0)
        {
            header = "\nFAILURE: ";
        }
        else if (skipped > 0)
        {
            header = "\nWARNING: ";
        }
        else
        {
            header = "\nSuccess: ";
        }

        std::cout << (header + total + failures + skips);

        header = "Test time: ";
        std::cout << (header + std::to_string(totalTime.count()) + " milliseconds.\n");
    }

}

}
<|endoftext|>


<commit_before>#include "raster.h"
#include "connectorinterface.h"
#include "symboltable.h"
#include "table.h"
#include "pixeliterator.h"

using namespace Ilwis;

RasterCoverage::RasterCoverage()
{
}

RasterCoverage::RasterCoverage(const Resource& resource) : Coverage(resource){

}

RasterCoverage::~RasterCoverage()
{
    _georef.set(0);
}

const IGeoReference& RasterCoverage::georeference() const
{
    return _georef;
}

void RasterCoverage::georeference(const IGeoReference &grf, bool resetData)
{
    if ( isReadOnly())
        return;
    changed(true);

    _georef = grf;
    if ( resetData)
        _grid.reset(0);
    else if ( !_grid || grf->size().twod() != _grid->size().twod() ) {
        _grid.reset(0);

    }
    if ( _georef.isValid() ) {
        _georef->compute();
        coordinateSystem(grf->coordinateSystem()); // mandatory
    }
    if (_georef.isValid()){
        if ( _size.isValid() && !_size.isNull() && !resetData)
            _size = Size<>(_georef->size().xsize(), _georef->size().ysize(), _size.zsize());
        else
            _size = _georef->size();
    }
    else
        _size = Size<>();
    if (!_grid && _size.isValid()){
            gridRef()->prepare(this,_size);
    }
}

IlwisTypes RasterCoverage::ilwisType() const
{
    return itRASTER;
}

RasterCoverage *RasterCoverage::clone()
{
    RasterCoverage *raster = new RasterCoverage();
    copyTo(raster);
    return raster;

}

const DataDefinition &RasterCoverage::datadef(quint32 layer) const
{
    if ( layer == WHOLE_RASTER)
        return _datadefCoverage;
    if ( layer >= _datadefBands.size())
        throw ErrorObject(TR("invalid index for layer access"));

    return _datadefBands[layer];
}

DataDefinition &RasterCoverage::datadefRef(quint32 layer)
{
    if ( layer == WHOLE_RASTER)
        return _datadefCoverage;
    if ( layer >= _datadefBands.size())
        _datadefBands.resize(layer + 1);

    return _datadefBands[layer];
}

void RasterCoverage::copyBinary(const IRasterCoverage& raster, quint32 inputIndex, quint32 outputIndex) {
    if ( isNumericalUndef(inputIndex) || isNumericalUndef(outputIndex)){
        ERROR2(ERR_ILLEGAL_VALUE_2,TR("layer index"), isNumericalUndef(inputIndex) ? "input" : "output");
        return;
    }
    if ( inputIndex >= size().zsize()){
       //ERROR2(ERR_ILLEGAL_VALUE_2,TR("layer index"), "input");
    }
    IRasterCoverage gcNew;
    gcNew.set(this);
    Size<> inputSize =  raster->size();
    Size<> sz(inputSize.xsize(),inputSize.ysize(), outputIndex + 1);
    gcNew->georeference()->size(sz);
    PixelIterator iterIn(raster, BoundingBox(Pixel(0,0,inputIndex), Pixel(inputSize.xsize(), inputSize.ysize(), inputIndex + 1)));
    PixelIterator iterOut(gcNew, BoundingBox(Pixel(0,0,outputIndex), Pixel(inputSize.xsize(), inputSize.ysize(), outputIndex + 1)));
    if ( raster->id() == id() && inputIndex == outputIndex){
        ERROR2(ERR_ILLEGALE_OPERATION2, TR("copy"),TR("identical layers in same raster"));
        return;
    }
    std::for_each(iterOut, iterOut.end(), [&](double& v){
         v = *iterIn;
        ++iterIn;
    });
}

NumericStatistics &RasterCoverage::statistics(int mode, int bins)
{
    if ( mode == ContainerStatistics<double>::pNONE)
        return Coverage::statistics(mode);
    IRasterCoverage raster(this);
    PixelIterator iter(raster);
    statistics().calculate(iter, iter.end(), (ContainerStatistics<double>::PropertySets)mode, bins);
    auto rng = raster->datadefRef().range<NumericRange>();
    rng->min(statistics().prop(NumericStatistics::pMIN));
    rng->max(statistics().prop(NumericStatistics::pMAX));
    return Coverage::statistics(mode);
}

UPGrid &RasterCoverage::gridRef()
{
    if (!_grid)
        _grid.reset( new Grid);
    return _grid;
}

const UPGrid &RasterCoverage::grid() const
{
    if ( _grid)
        return _grid;
    throw ErrorObject(TR("Grid not yet initialized")) ;
}

void RasterCoverage::copyTo(IlwisObject *obj)
{
    Locker<> lock(_mutex);
    Coverage::copyTo(obj);
    RasterCoverage *raster = static_cast<RasterCoverage *>(obj);
    raster->_georef = _georef;
    raster->_datadefCoverage = _datadefCoverage;
    if ( _grid) {
        raster->_grid.reset(_grid->clone());
    }
    raster->_attributeTable = _attributeTable;
    raster->_size = _size;

}

Resource RasterCoverage::source(int mode) const
{
    Resource resource = Coverage::source(mode);
    if ( mode & IlwisObject::cmEXTENDED) {
        resource.addProperty("georeference", georeference()->id());
        resource.addProperty("domain", _datadefCoverage.domain()->id());
        resource.setExtendedType( resource.extendedType() | itDOMAIN |  itGEOREF);
    }
    return resource;
}

Size<> RasterCoverage::size() const
{
    if (_size.isValid() && !_size.isNull())
        return _size;
    if (_grid)
        const_cast<RasterCoverage *>(this)->_size = _grid->size();
    else if ( _georef.isValid())
        const_cast<RasterCoverage *>(this)->_size = _georef->size();

    return _size;

}

void RasterCoverage::unloadBinary() {
    if (_grid != 0) {
        return _grid->unload();
    }
}

PixelIterator RasterCoverage::end()
{
   const IRasterCoverage raster(this);
   PixelIterator iter(raster);
   return iter.end();

}

PixelIterator RasterCoverage::begin()
{
    IRasterCoverage raster(this);
    return PixelIterator(raster);
}

PixelIterator RasterCoverage::band(const QString &variantIndex)
{
    int index = _bandDefinition.index(variantIndex);
    if ( index >= size().zsize() || index < 0)
        return PixelIterator();

    return bandPrivate(index);
}

PixelIterator RasterCoverage::band(double bandIndex)
{
    int index = _bandDefinition.index(bandIndex);
    if ( index >= size().zsize() || index < 0)
        return PixelIterator();

    return bandPrivate(index);
}

PixelIterator RasterCoverage::bandPrivate(quint32 bandIndex)
{
    BoundingBox box(Pixel(0,0,bandIndex), Pixel(size().xsize()-1,size().ysize()-1, bandIndex));
    IRasterCoverage raster(this);
    return PixelIterator(raster,box);
}

bool RasterCoverage::band(const QString &bandIndex,  PixelIterator inputIter)
{
    if ( !_bandDefinition.domain()->contains(bandIndex))
        return false;
    int bndIndex = _bandDefinition.index(bandIndex);
    if ( bndIndex >= size().zsize()){
        _size.zsize(bndIndex + 1);
        _grid->setBandProperties(this, 1);
    }
    return bandPrivate(bndIndex, inputIter);
}

bool RasterCoverage::band(double bandIndex,  PixelIterator inputIter)
{
    if ( !_bandDefinition.domain()->contains(bandIndex))
        return false;
    int bndIndex = _bandDefinition.index(bandIndex);
    if ( bndIndex >= size().zsize()){
        _size.zsize(bndIndex + 1);
        _grid->setBandProperties(this, 1);
    }
    return bandPrivate(bndIndex, inputIter);
}

void RasterCoverage::setBandDefinition(QString bandIndex, const DataDefinition &def)
{
    int bndIndex = _bandDefinition.index(bandIndex);
    if ( bndIndex != iUNDEF){
        if ( bndIndex >= _datadefBands.size())
            _datadefBands.resize(bndIndex + 1);
        _datadefBands[bndIndex] = def;
    }
}

void RasterCoverage::setBandDefinition(double bandIndex, const DataDefinition &def)
{
    int bndIndex = _bandDefinition.index(bandIndex);
    if ( bndIndex != iUNDEF){
        if ( bndIndex >= _datadefBands.size())
            _datadefBands.resize(bndIndex + 1);
        _datadefBands[bndIndex] = def;
    }
}

bool RasterCoverage::bandPrivate(quint32 bandIndex,  PixelIterator inputIter)
{
    if ( inputIter.box().size().zsize() != 1)
        return false;
    bool isFirstLayer = !size().isValid() || size().isNull();
    if (!isFirstLayer)    { // if it is not the first layer, some rules for this raster have already been defined(2dsize + domain)
        if ( inputIter.box().xlength() != size().xsize() || inputIter.box().ylength() != size().ysize())
            return false;
        if (!inputIter.raster()->datadef().domain()->isCompatibleWith(datadef().domain().ptr()))
            return false;
    }

    if ( isFirstLayer ){ //  totally new band in new coverage, initialize everything

        coordinateSystem(inputIter.raster()->coordinateSystem());
        georeference(inputIter.raster()->georeference());
        datadefRef() = inputIter.raster()->datadef();
        envelope(inputIter.raster()->envelope());

        Size<> twodsz = inputIter.box().size().twod();
        size(Size<>(twodsz.xsize(), twodsz.ysize() ,stackDefinition().count()));
        _datadefBands.resize(stackDefinition().count());
    }
    datadefRef(bandIndex) = inputIter.raster()->datadef(inputIter.box().zlength());
//    grid()->setBandProperties(this,bandIndex);

    PixelIterator iter = bandPrivate(bandIndex);
    while(iter != iter.end()){
        *iter = *inputIter;
        ++iter;
        ++inputIter;
    }
    return true;

}

void RasterCoverage::getData(quint32 blockIndex)
{
    if ( !connector().isNull()){
        connector()->loadData(this, {"blockindex", blockIndex});
    }
}

bool RasterCoverage::canUse(const IlwisObject *obj, bool strict) const
{
    if ( Coverage::canUse(obj, strict))
        return true;

    if ( hasType(obj->ilwisType(),itDOMAIN)){
        IDomain dom;
        dom.prepare(obj->id());
        if ( dom.isValid()){
            if (strict){

            }else {
                if ( hasType(dom->valueType(), itNUMBER) && hasType( datadef().domain()->valueType(), itNUMBER)){
                    return true;
                }
                if ( hasType(dom->ilwisType(), itITEMDOMAIN) && hasType( datadef().domain()->valueType(), itITEMDOMAIN)){
                    return datadef().domain()->isCompatibleWith(obj);
                }
            }
        }
    }
    return false;
}

void RasterCoverage::size(const Size<> &sz)
{
    if ( isReadOnly())
        return;

    // size must always be positive or undefined
    if (sz.xsize() > 0 && sz.ysize() > 0) {
        changed(true);
        _size = sz;
        gridRef()->prepare(this, sz);
        if (_georef.isValid())
            _georef->size(sz);
         stackDefinitionRef().setSubDefinition(sz.zsize()); // default filling, can be overruled
        for(int i = 0; i < sz.zsize(); ++i)
            datadefRef(i) = datadef();
    }
}

ITable RasterCoverage::attributeTable() const
{
    return _attributeTable;
}

bool RasterCoverage::hasAttributes() const
{
    return _attributeTable.isValid();
}

void RasterCoverage::attributeTable(const ITable& tbl)
{
    if ( isReadOnly())
        return;
    changed(true);
    _attributeTable = tbl;
}

RasterStackDefinition &RasterCoverage::stackDefinitionRef()
{
    return _bandDefinition;
}

const RasterStackDefinition &RasterCoverage::stackDefinition() const
{
    return _bandDefinition;
}

void RasterCoverage::name(const QString &nam)
{
    if ( isReadOnly())
        return;
    changed(true);

    IlwisObject::name(nam);
    if ( _attributeTable.isValid()) {
        if ( _attributeTable->isAnonymous()) {
            _attributeTable->name(nam + "_attributes");
        }
    }
}

QString RasterCoverage::name() const
{
    return Identity::name();
}

<commit_msg>corrected copying the datadef from the source PixelIterator (the band that the previous code is looking for isn't there)<commit_after>#include "raster.h"
#include "connectorinterface.h"
#include "symboltable.h"
#include "table.h"
#include "pixeliterator.h"

using namespace Ilwis;

RasterCoverage::RasterCoverage()
{
}

RasterCoverage::RasterCoverage(const Resource& resource) : Coverage(resource){

}

RasterCoverage::~RasterCoverage()
{
    _georef.set(0);
}

const IGeoReference& RasterCoverage::georeference() const
{
    return _georef;
}

void RasterCoverage::georeference(const IGeoReference &grf, bool resetData)
{
    if ( isReadOnly())
        return;
    changed(true);

    _georef = grf;
    if ( resetData)
        _grid.reset(0);
    else if ( !_grid || grf->size().twod() != _grid->size().twod() ) {
        _grid.reset(0);

    }
    if ( _georef.isValid() ) {
        _georef->compute();
        coordinateSystem(grf->coordinateSystem()); // mandatory
    }
    if (_georef.isValid()){
        if ( _size.isValid() && !_size.isNull() && !resetData)
            _size = Size<>(_georef->size().xsize(), _georef->size().ysize(), _size.zsize());
        else
            _size = _georef->size();
    }
    else
        _size = Size<>();
    if (!_grid && _size.isValid()){
            gridRef()->prepare(this,_size);
    }
}

IlwisTypes RasterCoverage::ilwisType() const
{
    return itRASTER;
}

RasterCoverage *RasterCoverage::clone()
{
    RasterCoverage *raster = new RasterCoverage();
    copyTo(raster);
    return raster;

}

const DataDefinition &RasterCoverage::datadef(quint32 layer) const
{
    if ( layer == WHOLE_RASTER)
        return _datadefCoverage;
    if ( layer >= _datadefBands.size())
        throw ErrorObject(TR("invalid index for layer access"));

    return _datadefBands[layer];
}

DataDefinition &RasterCoverage::datadefRef(quint32 layer)
{
    if ( layer == WHOLE_RASTER)
        return _datadefCoverage;
    if ( layer >= _datadefBands.size())
        _datadefBands.resize(layer + 1);

    return _datadefBands[layer];
}

void RasterCoverage::copyBinary(const IRasterCoverage& raster, quint32 inputIndex, quint32 outputIndex) {
    if ( isNumericalUndef(inputIndex) || isNumericalUndef(outputIndex)){
        ERROR2(ERR_ILLEGAL_VALUE_2,TR("layer index"), isNumericalUndef(inputIndex) ? "input" : "output");
        return;
    }
    if ( inputIndex >= size().zsize()){
       //ERROR2(ERR_ILLEGAL_VALUE_2,TR("layer index"), "input");
    }
    IRasterCoverage gcNew;
    gcNew.set(this);
    Size<> inputSize =  raster->size();
    Size<> sz(inputSize.xsize(),inputSize.ysize(), outputIndex + 1);
    gcNew->georeference()->size(sz);
    PixelIterator iterIn(raster, BoundingBox(Pixel(0,0,inputIndex), Pixel(inputSize.xsize(), inputSize.ysize(), inputIndex + 1)));
    PixelIterator iterOut(gcNew, BoundingBox(Pixel(0,0,outputIndex), Pixel(inputSize.xsize(), inputSize.ysize(), outputIndex + 1)));
    if ( raster->id() == id() && inputIndex == outputIndex){
        ERROR2(ERR_ILLEGALE_OPERATION2, TR("copy"),TR("identical layers in same raster"));
        return;
    }
    std::for_each(iterOut, iterOut.end(), [&](double& v){
         v = *iterIn;
        ++iterIn;
    });
}

NumericStatistics &RasterCoverage::statistics(int mode, int bins)
{
    if ( mode == ContainerStatistics<double>::pNONE)
        return Coverage::statistics(mode);
    IRasterCoverage raster(this);
    PixelIterator iter(raster);
    statistics().calculate(iter, iter.end(), (ContainerStatistics<double>::PropertySets)mode, bins);
    auto rng = raster->datadefRef().range<NumericRange>();
    rng->min(statistics().prop(NumericStatistics::pMIN));
    rng->max(statistics().prop(NumericStatistics::pMAX));
    return Coverage::statistics(mode);
}

UPGrid &RasterCoverage::gridRef()
{
    if (!_grid)
        _grid.reset( new Grid);
    return _grid;
}

const UPGrid &RasterCoverage::grid() const
{
    if ( _grid)
        return _grid;
    throw ErrorObject(TR("Grid not yet initialized")) ;
}

void RasterCoverage::copyTo(IlwisObject *obj)
{
    Locker<> lock(_mutex);
    Coverage::copyTo(obj);
    RasterCoverage *raster = static_cast<RasterCoverage *>(obj);
    raster->_georef = _georef;
    raster->_datadefCoverage = _datadefCoverage;
    if ( _grid) {
        raster->_grid.reset(_grid->clone());
    }
    raster->_attributeTable = _attributeTable;
    raster->_size = _size;

}

Resource RasterCoverage::source(int mode) const
{
    Resource resource = Coverage::source(mode);
    if ( mode & IlwisObject::cmEXTENDED) {
        resource.addProperty("georeference", georeference()->id());
        resource.addProperty("domain", _datadefCoverage.domain()->id());
        resource.setExtendedType( resource.extendedType() | itDOMAIN |  itGEOREF);
    }
    return resource;
}

Size<> RasterCoverage::size() const
{
    if (_size.isValid() && !_size.isNull())
        return _size;
    if (_grid)
        const_cast<RasterCoverage *>(this)->_size = _grid->size();
    else if ( _georef.isValid())
        const_cast<RasterCoverage *>(this)->_size = _georef->size();

    return _size;

}

void RasterCoverage::unloadBinary() {
    if (_grid != 0) {
        return _grid->unload();
    }
}

PixelIterator RasterCoverage::end()
{
   const IRasterCoverage raster(this);
   PixelIterator iter(raster);
   return iter.end();

}

PixelIterator RasterCoverage::begin()
{
    IRasterCoverage raster(this);
    return PixelIterator(raster);
}

PixelIterator RasterCoverage::band(const QString &variantIndex)
{
    int index = _bandDefinition.index(variantIndex);
    if ( index >= size().zsize() || index < 0)
        return PixelIterator();

    return bandPrivate(index);
}

PixelIterator RasterCoverage::band(double bandIndex)
{
    int index = _bandDefinition.index(bandIndex);
    if ( index >= size().zsize() || index < 0)
        return PixelIterator();

    return bandPrivate(index);
}

PixelIterator RasterCoverage::bandPrivate(quint32 bandIndex)
{
    BoundingBox box(Pixel(0,0,bandIndex), Pixel(size().xsize()-1,size().ysize()-1, bandIndex));
    IRasterCoverage raster(this);
    return PixelIterator(raster,box);
}

bool RasterCoverage::band(const QString &bandIndex,  PixelIterator inputIter)
{
    if ( !_bandDefinition.domain()->contains(bandIndex))
        return false;
    int bndIndex = _bandDefinition.index(bandIndex);
    if ( bndIndex >= size().zsize()){
        _size.zsize(bndIndex + 1);
        _grid->setBandProperties(this, 1);
    }
    return bandPrivate(bndIndex, inputIter);
}

bool RasterCoverage::band(double bandIndex,  PixelIterator inputIter)
{
    if ( !_bandDefinition.domain()->contains(bandIndex))
        return false;
    int bndIndex = _bandDefinition.index(bandIndex);
    if ( bndIndex >= size().zsize()){
        _size.zsize(bndIndex + 1);
        _grid->setBandProperties(this, 1);
    }
    return bandPrivate(bndIndex, inputIter);
}

void RasterCoverage::setBandDefinition(QString bandIndex, const DataDefinition &def)
{
    int bndIndex = _bandDefinition.index(bandIndex);
    if ( bndIndex != iUNDEF){
        if ( bndIndex >= _datadefBands.size())
            _datadefBands.resize(bndIndex + 1);
        _datadefBands[bndIndex] = def;
    }
}

void RasterCoverage::setBandDefinition(double bandIndex, const DataDefinition &def)
{
    int bndIndex = _bandDefinition.index(bandIndex);
    if ( bndIndex != iUNDEF){
        if ( bndIndex >= _datadefBands.size())
            _datadefBands.resize(bndIndex + 1);
        _datadefBands[bndIndex] = def;
    }
}

bool RasterCoverage::bandPrivate(quint32 bandIndex,  PixelIterator inputIter)
{
    if ( inputIter.box().size().zsize() != 1)
        return false;
    bool isFirstLayer = !size().isValid() || size().isNull();
    if (!isFirstLayer)    { // if it is not the first layer, some rules for this raster have already been defined(2dsize + domain)
        if ( inputIter.box().xlength() != size().xsize() || inputIter.box().ylength() != size().ysize())
            return false;
        if (!inputIter.raster()->datadef().domain()->isCompatibleWith(datadef().domain().ptr()))
            return false;
    }

    if ( isFirstLayer ){ //  totally new band in new coverage, initialize everything

        coordinateSystem(inputIter.raster()->coordinateSystem());
        georeference(inputIter.raster()->georeference());
        datadefRef() = inputIter.raster()->datadef();
        envelope(inputIter.raster()->envelope());

        Size<> twodsz = inputIter.box().size().twod();
        size(Size<>(twodsz.xsize(), twodsz.ysize() ,stackDefinition().count()));
        _datadefBands.resize(stackDefinition().count());
    }
    datadefRef(bandIndex) = inputIter.raster()->datadef();
//    grid()->setBandProperties(this,bandIndex);

    PixelIterator iter = bandPrivate(bandIndex);
    while(iter != iter.end()){
        *iter = *inputIter;
        ++iter;
        ++inputIter;
    }
    return true;

}

void RasterCoverage::getData(quint32 blockIndex)
{
    if ( !connector().isNull()){
        connector()->loadData(this, {"blockindex", blockIndex});
    }
}

bool RasterCoverage::canUse(const IlwisObject *obj, bool strict) const
{
    if ( Coverage::canUse(obj, strict))
        return true;

    if ( hasType(obj->ilwisType(),itDOMAIN)){
        IDomain dom;
        dom.prepare(obj->id());
        if ( dom.isValid()){
            if (strict){

            }else {
                if ( hasType(dom->valueType(), itNUMBER) && hasType( datadef().domain()->valueType(), itNUMBER)){
                    return true;
                }
                if ( hasType(dom->ilwisType(), itITEMDOMAIN) && hasType( datadef().domain()->valueType(), itITEMDOMAIN)){
                    return datadef().domain()->isCompatibleWith(obj);
                }
            }
        }
    }
    return false;
}

void RasterCoverage::size(const Size<> &sz)
{
    if ( isReadOnly())
        return;

    // size must always be positive or undefined
    if (sz.xsize() > 0 && sz.ysize() > 0) {
        changed(true);
        _size = sz;
        gridRef()->prepare(this, sz);
        if (_georef.isValid())
            _georef->size(sz);
         stackDefinitionRef().setSubDefinition(sz.zsize()); // default filling, can be overruled
        for(int i = 0; i < sz.zsize(); ++i)
            datadefRef(i) = datadef();
    }
}

ITable RasterCoverage::attributeTable() const
{
    return _attributeTable;
}

bool RasterCoverage::hasAttributes() const
{
    return _attributeTable.isValid();
}

void RasterCoverage::attributeTable(const ITable& tbl)
{
    if ( isReadOnly())
        return;
    changed(true);
    _attributeTable = tbl;
}

RasterStackDefinition &RasterCoverage::stackDefinitionRef()
{
    return _bandDefinition;
}

const RasterStackDefinition &RasterCoverage::stackDefinition() const
{
    return _bandDefinition;
}

void RasterCoverage::name(const QString &nam)
{
    if ( isReadOnly())
        return;
    changed(true);

    IlwisObject::name(nam);
    if ( _attributeTable.isValid()) {
        if ( _attributeTable->isAnonymous()) {
            _attributeTable->name(nam + "_attributes");
        }
    }
}

QString RasterCoverage::name() const
{
    return Identity::name();
}

<|endoftext|>


<commit_before>/**
 * @copyright
 * ====================================================================
 * Copyright (c) 2003 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 * @endcopyright
 *
 * @file JNIUtil.cpp
 * @brief Implementation of the class JNIUtil
 */

#include "JNIUtil.h"
#include <locale.h>
#include <apr_strings.h>
#include <apr_tables.h>
#include <apr_general.h>
#include <apr_lib.h>

#include <svn_pools.h>
#include <svn_config.h>
//#include <ios>

#include "SVNBase.h"
#include "JNIMutex.h"
#include "JNICriticalSection.h"
#include "JNIThreadData.h"
#include "JNIStringHolder.h"

apr_pool_t *JNIUtil::g_pool = NULL;
std::list<SVNBase*> JNIUtil::g_finalizedObjects;
JNIMutex *JNIUtil::g_finalizedObjectsMutex = NULL;
JNIMutex *JNIUtil::g_logMutex = NULL;
bool JNIUtil::g_initException;
bool JNIUtil::g_inInit;
JNIEnv *JNIUtil::g_initEnv;
char JNIUtil::g_initFormatBuffer[formatBufferSize];
int JNIUtil::g_logLevel = JNIUtil::noLog;
std::ofstream JNIUtil::g_logStream;
Pool *JNIUtil::g_requestPool;

bool JNIUtil::JNIInit(JNIEnv *env)
{
	static bool run = false;
	if(run)
	{
		env->ExceptionClear();
		setEnv(env);
		JNICriticalSection cs(*g_finalizedObjectsMutex) ;
		if(isExceptionThrown())
		{
			return false;
		}

		for(std::list<SVNBase*>::iterator it = g_finalizedObjects.begin(); it != g_finalizedObjects.end(); it++)
		{
			delete *it;
		}
		g_finalizedObjects.clear();

		return true;
	}
	run = true;
	if(g_inInit)
	{
		return false;
	}
	g_inInit = true;
	g_initEnv = env;

	/* C programs default to the "C" locale by default.  But because svn
	 is supposed to be i18n-aware, it should inherit the default
	 locale of its environment.  */
	setlocale (LC_ALL, "");

	/* Initialize the APR subsystem, and register an atexit() function
	to Uninitialize that subsystem at program exit. */
	apr_status_t apr_err = apr_initialize ();
	if (apr_err)
	{
		fprintf (stderr, "error: apr_initialize\n");
		return false;
	}
	int err2 = atexit (apr_terminate);
	if (err2)
	{
		fprintf (stderr, "error: atexit returned %d\n", err2);
		return false;
	}

	/* Create our top-level pool. */
	g_pool = svn_pool_create (NULL);

	svn_error_t *err = svn_config_ensure (NULL, g_pool); // we use the default directory for config files
	if (err)
	{
		svn_pool_destroy (g_pool);
		handleSVNError(err);
		return false;
	}

	g_finalizedObjectsMutex = new JNIMutex(g_pool);
	if(isExceptionThrown())
	{
		return false;
	}

	g_logMutex = new JNIMutex(g_pool);
	if(isExceptionThrown())
	{
		return false;
	}

	if(!JNIThreadData::initThreadData())
	{
		return false;
	}

	setEnv(env);
	if(isExceptionThrown())
	{
		return false;
	}

	g_initEnv = NULL;
	g_inInit = false;
	return true;
}

apr_pool_t * JNIUtil::getPool()
{
	return g_pool;
}

void JNIUtil::throwError(const char *message)
{
	if(getLogLevel() >= errorLog)
	{
		JNICriticalSection cs(*g_logMutex);
		g_logStream << "Error thrown <" << message << ">" << std::endl;
	}
	JNIEnv *env = getEnv();
	jclass clazz = env->FindClass(JAVA_PACKAGE"/JNIError");
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->ThrowNew(clazz, message);
	setExceptionThrown();
	env->DeleteLocalRef(clazz);
}

void JNIUtil::handleSVNError(svn_error_t *err)
{
	JNIEnv *env = getEnv();
	jclass clazz = env->FindClass(JAVA_PACKAGE"/ClientException");
	if(getLogLevel() >= exceptionLog)
	{
		JNICriticalSection cs(*g_logMutex);
		g_logStream << "Error SVN exception thrown message:<";
		g_logStream << err->message << "> file:<" << err->file << "> apr-err:<" << err->apr_err;
		g_logStream	<< ">" << std::endl;
	}
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}

	std::string buffer;
	assembleErrorMessage(err, 0, APR_SUCCESS, buffer);
	jstring jmessage = makeJString(buffer.c_str());
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}
	jstring jfile = makeJString(err->file);
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}
	jmethodID mid = env->GetMethodID(clazz, "<init>", "(Ljava/lang/String;Ljava/lang/String;I)V");
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}
	jobject error = env->NewObject(clazz, mid, jmessage, jfile, static_cast<jint>(err->apr_err));
	svn_error_clear(err);
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->DeleteLocalRef(clazz);
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->DeleteLocalRef(jmessage);
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->DeleteLocalRef(jfile);
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->Throw(static_cast<jthrowable>(error));
}

void JNIUtil::putFinalizedClient(SVNBase *cl)
{
	if(getLogLevel() >= errorLog)
	{
		JNICriticalSection cs(*g_logMutex);
		g_logStream << "a client object was not disposed" << std::endl;
	}
	JNICriticalSection cs(*g_finalizedObjectsMutex);
	if(isExceptionThrown())
	{
		return;
	}

	g_finalizedObjects.push_back(cl);

}

void JNIUtil::handleAPRError(int error, const char *op)
{
	char *buffer = getFormatBuffer();
	if(buffer == NULL)
	{
		return;
	}
    apr_snprintf(buffer, formatBufferSize, "an error occured in funcation %s with return value %d",
		op, error);

	throwError(buffer);
}

bool JNIUtil::isExceptionThrown()
{
	if(g_inInit)
	{
		return g_initException;
	}
	JNIThreadData *data = JNIThreadData::getThreadData();
	return data == NULL || data->m_exceptionThrown;
}

void JNIUtil::setEnv(JNIEnv *env)
{
	JNIThreadData *data = JNIThreadData::getThreadData();
	data->m_env = env;
	data->m_exceptionThrown = false;
}

JNIEnv * JNIUtil::getEnv()
{
	if(g_inInit)
	{
		return g_initEnv;
	}
	JNIThreadData *data = JNIThreadData::getThreadData();
	return data->m_env;
}

bool JNIUtil::isJavaExceptionThrown()
{
	JNIEnv *env = getEnv();
	if(env->ExceptionCheck())
	{
		jthrowable exp = env->ExceptionOccurred();
		env->ExceptionDescribe();
		env->Throw(exp);
		env->DeleteLocalRef(exp);
		return true;
	}
	return false;
}

jstring JNIUtil::makeJString(const char *txt)
{
	if(txt == NULL)
	{
		return NULL;
	}
	JNIEnv *env = getEnv();
	jstring js = env->NewStringUTF(txt);
	return js;
}

void JNIUtil::setExceptionThrown()
{
	if(g_inInit)
	{
		g_initException = true;
	}
	JNIThreadData *data = JNIThreadData::getThreadData();
	data->m_exceptionThrown = true;
}

void JNIUtil::initLogFile(int level, jstring path)
{
	JNICriticalSection cs(*g_logMutex);
	if(g_logLevel > noLog)
	{
		g_logStream.close();
	}
	g_logLevel = level;
	JNIStringHolder myPath(path);
	if(g_logLevel > noLog)
	{
		g_logStream.open(myPath, std::ios::app);
		//g_logStream.open(myPath, std::ios_base::app);
	}
}

char * JNIUtil::getFormatBuffer()
{
	if(g_inInit)
	{
		return g_initFormatBuffer;
	}
	JNIThreadData *data = JNIThreadData::getThreadData();
	if(data == NULL)
	{
		return g_initFormatBuffer;
	}
	return data->m_formatBuffer;
}

int JNIUtil::getLogLevel()
{
	return g_logLevel;
}

void JNIUtil::logMessage(const char *message)
{
	JNICriticalSection cs(*g_logMutex);
	g_logStream << message << std::endl;
}

jobject JNIUtil::createDate(apr_time_t time)
{
	jlong javatime = time /1000;
	JNIEnv *env = getEnv();
	jclass clazz = env->FindClass("java/util/Date");
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	static jmethodID mid = 0;
	if(mid == 0)
	{
		mid = env->GetMethodID(clazz, "<init>", "(J)V");
		if(isJavaExceptionThrown())
		{
			return NULL;
		}
	}
	jobject ret = env->NewObject(clazz, mid, javatime);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	env->DeleteLocalRef(clazz);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	return ret;
}

Pool * JNIUtil::getRequestPool()
{
	return g_requestPool;
}

void JNIUtil::setRequestPool(Pool *pool)
{
	g_requestPool = pool;
}

jbyteArray JNIUtil::makeJByteArray(const signed char *data, int length)
{
	if(data == NULL || length == 0)
	{
		return NULL;
	}
	JNIEnv *env = getEnv();
	jbyteArray ret = env->NewByteArray(length);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	jbyte *retdata = env->GetByteArrayElements(ret, NULL);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	memcpy(retdata, data, length);
	env->ReleaseByteArrayElements(ret, retdata, 0);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	return ret;
}

void JNIUtil::assembleErrorMessage(svn_error_t *err, int depth, apr_status_t parent_apr_err, std::string &buffer)
{
    char errbuf[256];
//  char utfbuf[2048];
//  const char *err_string;

  /* Pretty-print the error */
  /* Note: we can also log errors here someday. */

  /* When we're recursing, don't repeat the top-level message if its
     the same as before. */
  if (depth == 0 || err->apr_err != parent_apr_err)
    {
      /* Is this a Subversion-specific error code? */
      if ((err->apr_err > APR_OS_START_USEERR)
          && (err->apr_err <= APR_OS_START_CANONERR))
          buffer.append(svn_strerror (err->apr_err, errbuf, sizeof (errbuf)));
      /* Otherwise, this must be an APR error code. */
      else
		  buffer.append(apr_strerror (err->apr_err, errbuf, sizeof (errbuf)));
      buffer.append("\n");
    }
  if (err->message)
	  buffer.append("svn: ").append(err->message).append("\n");

  if (err->child)
    assembleErrorMessage(err->child, depth + 1, err->apr_err, buffer);

}
<commit_msg>Fix typos in a javahl error message.<commit_after>/**
 * @copyright
 * ====================================================================
 * Copyright (c) 2003 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 * @endcopyright
 *
 * @file JNIUtil.cpp
 * @brief Implementation of the class JNIUtil
 */

#include "JNIUtil.h"
#include <locale.h>
#include <apr_strings.h>
#include <apr_tables.h>
#include <apr_general.h>
#include <apr_lib.h>

#include <svn_pools.h>
#include <svn_config.h>
//#include <ios>

#include "SVNBase.h"
#include "JNIMutex.h"
#include "JNICriticalSection.h"
#include "JNIThreadData.h"
#include "JNIStringHolder.h"

apr_pool_t *JNIUtil::g_pool = NULL;
std::list<SVNBase*> JNIUtil::g_finalizedObjects;
JNIMutex *JNIUtil::g_finalizedObjectsMutex = NULL;
JNIMutex *JNIUtil::g_logMutex = NULL;
bool JNIUtil::g_initException;
bool JNIUtil::g_inInit;
JNIEnv *JNIUtil::g_initEnv;
char JNIUtil::g_initFormatBuffer[formatBufferSize];
int JNIUtil::g_logLevel = JNIUtil::noLog;
std::ofstream JNIUtil::g_logStream;
Pool *JNIUtil::g_requestPool;

bool JNIUtil::JNIInit(JNIEnv *env)
{
	static bool run = false;
	if(run)
	{
		env->ExceptionClear();
		setEnv(env);
		JNICriticalSection cs(*g_finalizedObjectsMutex) ;
		if(isExceptionThrown())
		{
			return false;
		}

		for(std::list<SVNBase*>::iterator it = g_finalizedObjects.begin(); it != g_finalizedObjects.end(); it++)
		{
			delete *it;
		}
		g_finalizedObjects.clear();

		return true;
	}
	run = true;
	if(g_inInit)
	{
		return false;
	}
	g_inInit = true;
	g_initEnv = env;

	/* C programs default to the "C" locale by default.  But because svn
	 is supposed to be i18n-aware, it should inherit the default
	 locale of its environment.  */
	setlocale (LC_ALL, "");

	/* Initialize the APR subsystem, and register an atexit() function
	to Uninitialize that subsystem at program exit. */
	apr_status_t apr_err = apr_initialize ();
	if (apr_err)
	{
		fprintf (stderr, "error: apr_initialize\n");
		return false;
	}
	int err2 = atexit (apr_terminate);
	if (err2)
	{
		fprintf (stderr, "error: atexit returned %d\n", err2);
		return false;
	}

	/* Create our top-level pool. */
	g_pool = svn_pool_create (NULL);

	svn_error_t *err = svn_config_ensure (NULL, g_pool); // we use the default directory for config files
	if (err)
	{
		svn_pool_destroy (g_pool);
		handleSVNError(err);
		return false;
	}

	g_finalizedObjectsMutex = new JNIMutex(g_pool);
	if(isExceptionThrown())
	{
		return false;
	}

	g_logMutex = new JNIMutex(g_pool);
	if(isExceptionThrown())
	{
		return false;
	}

	if(!JNIThreadData::initThreadData())
	{
		return false;
	}

	setEnv(env);
	if(isExceptionThrown())
	{
		return false;
	}

	g_initEnv = NULL;
	g_inInit = false;
	return true;
}

apr_pool_t * JNIUtil::getPool()
{
	return g_pool;
}

void JNIUtil::throwError(const char *message)
{
	if(getLogLevel() >= errorLog)
	{
		JNICriticalSection cs(*g_logMutex);
		g_logStream << "Error thrown <" << message << ">" << std::endl;
	}
	JNIEnv *env = getEnv();
	jclass clazz = env->FindClass(JAVA_PACKAGE"/JNIError");
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->ThrowNew(clazz, message);
	setExceptionThrown();
	env->DeleteLocalRef(clazz);
}

void JNIUtil::handleSVNError(svn_error_t *err)
{
	JNIEnv *env = getEnv();
	jclass clazz = env->FindClass(JAVA_PACKAGE"/ClientException");
	if(getLogLevel() >= exceptionLog)
	{
		JNICriticalSection cs(*g_logMutex);
		g_logStream << "Error SVN exception thrown message:<";
		g_logStream << err->message << "> file:<" << err->file << "> apr-err:<" << err->apr_err;
		g_logStream	<< ">" << std::endl;
	}
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}

	std::string buffer;
	assembleErrorMessage(err, 0, APR_SUCCESS, buffer);
	jstring jmessage = makeJString(buffer.c_str());
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}
	jstring jfile = makeJString(err->file);
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}
	jmethodID mid = env->GetMethodID(clazz, "<init>", "(Ljava/lang/String;Ljava/lang/String;I)V");
	if(isJavaExceptionThrown())
	{
		svn_error_clear(err);
		return;
	}
	jobject error = env->NewObject(clazz, mid, jmessage, jfile, static_cast<jint>(err->apr_err));
	svn_error_clear(err);
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->DeleteLocalRef(clazz);
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->DeleteLocalRef(jmessage);
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->DeleteLocalRef(jfile);
	if(isJavaExceptionThrown())
	{
		return;
	}
	env->Throw(static_cast<jthrowable>(error));
}

void JNIUtil::putFinalizedClient(SVNBase *cl)
{
	if(getLogLevel() >= errorLog)
	{
		JNICriticalSection cs(*g_logMutex);
		g_logStream << "a client object was not disposed" << std::endl;
	}
	JNICriticalSection cs(*g_finalizedObjectsMutex);
	if(isExceptionThrown())
	{
		return;
	}

	g_finalizedObjects.push_back(cl);

}

void JNIUtil::handleAPRError(int error, const char *op)
{
	char *buffer = getFormatBuffer();
	if(buffer == NULL)
	{
		return;
	}
    apr_snprintf(buffer, formatBufferSize, "an error occurred in function %s with return value %d",
		op, error);

	throwError(buffer);
}

bool JNIUtil::isExceptionThrown()
{
	if(g_inInit)
	{
		return g_initException;
	}
	JNIThreadData *data = JNIThreadData::getThreadData();
	return data == NULL || data->m_exceptionThrown;
}

void JNIUtil::setEnv(JNIEnv *env)
{
	JNIThreadData *data = JNIThreadData::getThreadData();
	data->m_env = env;
	data->m_exceptionThrown = false;
}

JNIEnv * JNIUtil::getEnv()
{
	if(g_inInit)
	{
		return g_initEnv;
	}
	JNIThreadData *data = JNIThreadData::getThreadData();
	return data->m_env;
}

bool JNIUtil::isJavaExceptionThrown()
{
	JNIEnv *env = getEnv();
	if(env->ExceptionCheck())
	{
		jthrowable exp = env->ExceptionOccurred();
		env->ExceptionDescribe();
		env->Throw(exp);
		env->DeleteLocalRef(exp);
		return true;
	}
	return false;
}

jstring JNIUtil::makeJString(const char *txt)
{
	if(txt == NULL)
	{
		return NULL;
	}
	JNIEnv *env = getEnv();
	jstring js = env->NewStringUTF(txt);
	return js;
}

void JNIUtil::setExceptionThrown()
{
	if(g_inInit)
	{
		g_initException = true;
	}
	JNIThreadData *data = JNIThreadData::getThreadData();
	data->m_exceptionThrown = true;
}

void JNIUtil::initLogFile(int level, jstring path)
{
	JNICriticalSection cs(*g_logMutex);
	if(g_logLevel > noLog)
	{
		g_logStream.close();
	}
	g_logLevel = level;
	JNIStringHolder myPath(path);
	if(g_logLevel > noLog)
	{
		g_logStream.open(myPath, std::ios::app);
		//g_logStream.open(myPath, std::ios_base::app);
	}
}

char * JNIUtil::getFormatBuffer()
{
	if(g_inInit)
	{
		return g_initFormatBuffer;
	}
	JNIThreadData *data = JNIThreadData::getThreadData();
	if(data == NULL)
	{
		return g_initFormatBuffer;
	}
	return data->m_formatBuffer;
}

int JNIUtil::getLogLevel()
{
	return g_logLevel;
}

void JNIUtil::logMessage(const char *message)
{
	JNICriticalSection cs(*g_logMutex);
	g_logStream << message << std::endl;
}

jobject JNIUtil::createDate(apr_time_t time)
{
	jlong javatime = time /1000;
	JNIEnv *env = getEnv();
	jclass clazz = env->FindClass("java/util/Date");
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	static jmethodID mid = 0;
	if(mid == 0)
	{
		mid = env->GetMethodID(clazz, "<init>", "(J)V");
		if(isJavaExceptionThrown())
		{
			return NULL;
		}
	}
	jobject ret = env->NewObject(clazz, mid, javatime);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	env->DeleteLocalRef(clazz);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	return ret;
}

Pool * JNIUtil::getRequestPool()
{
	return g_requestPool;
}

void JNIUtil::setRequestPool(Pool *pool)
{
	g_requestPool = pool;
}

jbyteArray JNIUtil::makeJByteArray(const signed char *data, int length)
{
	if(data == NULL || length == 0)
	{
		return NULL;
	}
	JNIEnv *env = getEnv();
	jbyteArray ret = env->NewByteArray(length);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	jbyte *retdata = env->GetByteArrayElements(ret, NULL);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	memcpy(retdata, data, length);
	env->ReleaseByteArrayElements(ret, retdata, 0);
	if(isJavaExceptionThrown())
	{
		return NULL;
	}
	return ret;
}

void JNIUtil::assembleErrorMessage(svn_error_t *err, int depth, apr_status_t parent_apr_err, std::string &buffer)
{
    char errbuf[256];
//  char utfbuf[2048];
//  const char *err_string;

  /* Pretty-print the error */
  /* Note: we can also log errors here someday. */

  /* When we're recursing, don't repeat the top-level message if its
     the same as before. */
  if (depth == 0 || err->apr_err != parent_apr_err)
    {
      /* Is this a Subversion-specific error code? */
      if ((err->apr_err > APR_OS_START_USEERR)
          && (err->apr_err <= APR_OS_START_CANONERR))
          buffer.append(svn_strerror (err->apr_err, errbuf, sizeof (errbuf)));
      /* Otherwise, this must be an APR error code. */
      else
		  buffer.append(apr_strerror (err->apr_err, errbuf, sizeof (errbuf)));
      buffer.append("\n");
    }
  if (err->message)
	  buffer.append("svn: ").append(err->message).append("\n");

  if (err->child)
    assembleErrorMessage(err->child, depth + 1, err->apr_err, buffer);

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: SchXMLExport.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: bm $ $Date: 2001-09-14 11:19:47 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef SCH_XMLEXPORT_HXX_
#define SCH_XMLEXPORT_HXX_

#ifndef _XMLOFF_SCH_XMLEXPORTHELPER_HXX_
#include "SchXMLExportHelper.hxx"
#endif
#ifndef _SCH_XMLAUTOSTYLEPOOLP_HXX_
#include "SchXMLAutoStylePoolP.hxx"
#endif
#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif
#ifndef _UNIVERSALL_REFERENCE_HXX
#include "uniref.hxx"
#endif
#ifndef _XMLOFF_PROPERTYSETMAPPER_HXX
#include "xmlprmap.hxx"
#endif
#ifndef _XMLOFF_PROPERTYHANDLERFACTORY_HXX
#include "prhdlfac.hxx"
#endif

namespace com { namespace sun { namespace star {
    namespace chart {
        class XDiagram;
        class XChartDocument;
        class XChartDataArray;
        struct ChartSeriesAddress;
    }
    namespace drawing {
        class XShape;
    }
    namespace task {
        class XStatusIndicator;
    }
}}}

class SvXMLAutoStylePoolP;
class SvXMLUnitConverter;
class XMLChartExportPropertyMapper;

// ------------------------------------------
// export class for a complete chart document
// ------------------------------------------

class SchXMLExport : public SvXMLExport
{
private:
    com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > mxStatusIndicator;
    SchXMLAutoStylePoolP maAutoStylePool;

    SchXMLExportHelper maExportHelper;

protected:
    virtual void _ExportStyles( sal_Bool bUsed );
    virtual void _ExportAutoStyles();
    virtual void _ExportMasterStyles();
    virtual void _ExportContent();

public:
    SchXMLExport( sal_uInt16 nExportFlags = EXPORT_ALL );
    virtual ~SchXMLExport();

    void SetProgress( sal_Int32 nPercentage );

    UniReference< XMLPropertySetMapper > GetPropertySetMapper() const { return maExportHelper.GetPropertySetMapper(); }

    // XServiceInfo ( : SvXMLExport )
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
};

#endif  // SCH_XMLEXPORT_HXX_
<commit_msg>INTEGRATION: CWS binfilter (1.7.144); FILE MERGED 2003/08/19 15:45:54 aw 1.7.144.2: #110680# Give ServiceManager as const reference and do not keep it as reference locally as member 2003/07/07 15:45:38 aw 1.7.144.1: #110680# Changed all components to use the ServiceManager they were created with.<commit_after>/*************************************************************************
 *
 *  $RCSfile: SchXMLExport.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2004-05-03 13:30:52 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef SCH_XMLEXPORT_HXX_
#define SCH_XMLEXPORT_HXX_

#ifndef _XMLOFF_SCH_XMLEXPORTHELPER_HXX_
#include "SchXMLExportHelper.hxx"
#endif
#ifndef _SCH_XMLAUTOSTYLEPOOLP_HXX_
#include "SchXMLAutoStylePoolP.hxx"
#endif
#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif
#ifndef _UNIVERSALL_REFERENCE_HXX
#include "uniref.hxx"
#endif
#ifndef _XMLOFF_PROPERTYSETMAPPER_HXX
#include "xmlprmap.hxx"
#endif
#ifndef _XMLOFF_PROPERTYHANDLERFACTORY_HXX
#include "prhdlfac.hxx"
#endif

namespace com { namespace sun { namespace star {
    namespace chart {
        class XDiagram;
        class XChartDocument;
        class XChartDataArray;
        struct ChartSeriesAddress;
    }
    namespace drawing {
        class XShape;
    }
    namespace task {
        class XStatusIndicator;
    }
}}}

class SvXMLAutoStylePoolP;
class SvXMLUnitConverter;
class XMLChartExportPropertyMapper;

// ------------------------------------------
// export class for a complete chart document
// ------------------------------------------

class SchXMLExport : public SvXMLExport
{
private:
    com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > mxStatusIndicator;
    SchXMLAutoStylePoolP maAutoStylePool;

    SchXMLExportHelper maExportHelper;

protected:
    virtual void _ExportStyles( sal_Bool bUsed );
    virtual void _ExportAutoStyles();
    virtual void _ExportMasterStyles();
    virtual void _ExportContent();

public:
    // #110680#
    SchXMLExport(
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
        sal_uInt16 nExportFlags = EXPORT_ALL );
    virtual ~SchXMLExport();

    void SetProgress( sal_Int32 nPercentage );

    UniReference< XMLPropertySetMapper > GetPropertySetMapper() const { return maExportHelper.GetPropertySetMapper(); }

    // XServiceInfo ( : SvXMLExport )
    virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException );
};

#endif  // SCH_XMLEXPORT_HXX_
<|endoftext|>


<commit_before>
#ifndef __AGGREGATOR_HPP__
#define __AGGREGATOR_HPP__

#include <vector>
#include <algorithm>
#include <queue>

#include <iostream>
#include <cassert>

#include <gasnet.h>

#include "common.hpp"
#include "gasnet_helpers.h"

#include "Communicator.hpp"

#include "MutableHeap.hpp"

#define DEBUG_AGGREGATOR 0

/// Type of aggregated active message handler
typedef void (* AggregatorAMHandler)( void *, size_t, void *, size_t );

/// Active message handler called to deaggregate aggregated messages.
extern void Aggregator_deaggregate_am( gasnet_token_t token, void * buf, size_t size );

/// Header for aggregated active messages.
struct AggregatorGenericCallHeader {
  uintptr_t function_pointer;
  Node destination;
  uint16_t args_size;
  uint16_t payload_size;
};

static std::ostream& operator<<( std::ostream& o, const AggregatorGenericCallHeader& h ) {
  return o << "[f="           << (void*) h.function_pointer
           << ",d=" << h.destination
           << ",a=" << h.args_size
           << ",p=" << h.payload_size
           << "(t=" << sizeof(h) + h.args_size + h.payload_size << ")"
           << "]";
}

/// Active message aggregation per-destination storage class.
template< const int max_size_ >
class AggregatorBuffer {
private:
public:
  int current_position_;
  char buffer_[ max_size_ ];

  AggregatorBuffer()
    : current_position_( 0 )
  { }

  /// use default copy constructor and assignment operator

  inline bool fits( size_t size ) const {
    return (current_position_ + size) < max_size_;
  }

  inline void insert( const void * data, size_t size ) {
    memcpy( &buffer_[ current_position_ ], data, size );
    current_position_ += size;
  }

  inline void flush() {
    current_position_ = 0;
  }
};

/// Active message aggregation class.
class Aggregator {
private:
  DISALLOW_COPY_AND_ASSIGN( Aggregator );

  /// Pointer to communication layer.
  Communicator * communicator_;

  /// max node count. used to allocate buffers.
  const int max_nodes_;

  /// number of bytes in each aggregation buffer
  /// TODO: this should track the IB MTU
  static const int buffer_size_ = 4024;

  /// buffers holding aggregated messages.
  std::vector< AggregatorBuffer< buffer_size_ > > buffers_;

  /// number of ticks to wait before automatically flushing a buffer.
  const int autoflush_ticks_;

  /// current timestamp for autoflusher.
  uint64_t previous_timestamp_;

  /// priority queue for autoflusher.
  MutableHeap< uint64_t, int > least_recently_sent_;

  /// handle for deaggregation active message
  const int aggregator_deaggregate_am_handle_;

  /// routing table for hierarchical aggregation
  std::vector< Node > route_map_;

  /// storage for deaggregation
  struct ReceivedAM {
    size_t size_;
    char buf_[buffer_size_];
    ReceivedAM( size_t size, void * buf )
      : size_( size )
      , buf_()
    {
      assert( size < buffer_size_ );
      memcpy( buf_, buf, size );
    }
  };
  std::queue< ReceivedAM > received_AM_queue_;
  void deaggregate( );
  friend void Aggregator_deaggregate_am( gasnet_token_t token, void * buf, size_t size );

public:

  /// Construct Aggregator. Takes a Communicator pointer in order to
  /// register active message handlers
  explicit Aggregator( Communicator * communicator );

  /// route map lookup for hierarchical aggregation
  inline Node get_target_for_node( Node n ) {
    return route_map_[ n ];
  }

  /// route map update for hierarchical aggregation
  inline void update_target_for_node( Node node, Node target ) {
    route_map_[ node ] = target;
  }

  /// send aggregated messages for node
  inline void flush( Node node ) {
    if (DEBUG_AGGREGATOR) std::cout << "flushing node " << node << std::endl;
    communicator_->poll();
    Node target = route_map_[ node ];
    communicator_->send( target,
                         aggregator_deaggregate_am_handle_,
                         buffers_[ target ].buffer_,
                         buffers_[ target ].current_position_ );
    buffers_[ target ].flush();
    least_recently_sent_.remove_key( target );
    deaggregate();
  }

  /// get timestamp. we avoid calling rdtsc for performance
  inline uint64_t get_timestamp() {
    return previous_timestamp_ + 1;
  }

  inline uint64_t get_previous_timestamp() {
    return previous_timestamp_;
  }

  /// poll communicator. send any aggregated messages that have been sitting for too long
  inline void poll() {
    communicator_->poll();
    uint64_t ts = get_timestamp();
    uint64_t flush_time = ts - autoflush_ticks_;
    if( !least_recently_sent_.empty() ) {                                    // if messages are waiting, and
      if( ( flush_time < least_recently_sent_.top_priority() ) ||  // we've wrapped around or
	  ( least_recently_sent_.top_priority() < flush_time ) ) { // we've waited long enough,
	flush( least_recently_sent_.top_key() );                   // send.
      }
    }
    previous_timestamp_ = ts;
    deaggregate();
  }

  inline const size_t max_size() const { return buffer_size_; }

  inline void aggregate( Node destination, AggregatorAMHandler fn_p,
                         const void * args, const size_t args_size,
                         const void * payload, const size_t payload_size ) {
    assert( destination < max_nodes_ );
    Node target = get_target_for_node( destination );

    // make sure arg struct and payload aren't too big.
    // in the future, this would lead us down a separate code path for large messages.
    // for now, fail.
    size_t total_call_size = payload_size + args_size + sizeof( AggregatorGenericCallHeader );
    assert( total_call_size < buffer_size_ ); // TODO: this is not specific enough

    // does call fit in aggregation buffer?
    if( !( buffers_[ target ].fits( total_call_size ) ) ) {
      // doesn't fit, so flush before inserting
      flush( target );
    }

    // now call must fit, so just insert it
    AggregatorGenericCallHeader header = { reinterpret_cast< intptr_t >( fn_p ),
                                           destination,
                                           args_size,
                                           payload_size };
    buffers_[ target ].insert( &header, sizeof( header ) );
    buffers_[ target ].insert( args, args_size );
    buffers_[ target ].insert( payload, payload_size );

    uint64_t ts = get_timestamp();
    least_recently_sent_.update_or_insert( target, ts );
    previous_timestamp_ = ts;
    if (DEBUG_AGGREGATOR) std::cout << "aggregated " << header << std::endl;
  }

};

extern Aggregator * global_aggregator;

template< typename ArgsStruct >
inline void SoftXMT_call_on( Node destination, void (* fn_p)(ArgsStruct *, size_t, void *, size_t),
                             const ArgsStruct * args, const size_t args_size = sizeof( ArgsStruct ),
                             const void * payload = NULL, const size_t payload_size = 0)
{
  assert( global_aggregator != NULL );
  global_aggregator->aggregate( destination,
                                reinterpret_cast< AggregatorAMHandler >( fn_p ),
                                static_cast< const void * >( args ), args_size,
                                static_cast< const void * >( payload ), payload_size );
}

#endif
<commit_msg>remove poll() deaggregate() from flush(); was causing buffer to fill. This is one solution; another would be to keep flushing until the buffer has space, but this has potential to starve the sender<commit_after>
#ifndef __AGGREGATOR_HPP__
#define __AGGREGATOR_HPP__

#include <vector>
#include <algorithm>
#include <queue>

#include <iostream>
#include <cassert>

#include <gasnet.h>

#include "common.hpp"
#include "gasnet_helpers.h"

#include "Communicator.hpp"

#include "MutableHeap.hpp"

#define DEBUG_AGGREGATOR 0

/// Type of aggregated active message handler
typedef void (* AggregatorAMHandler)( void *, size_t, void *, size_t );

/// Active message handler called to deaggregate aggregated messages.
extern void Aggregator_deaggregate_am( gasnet_token_t token, void * buf, size_t size );

/// Header for aggregated active messages.
struct AggregatorGenericCallHeader {
  uintptr_t function_pointer;
  Node destination;
  uint16_t args_size;
  uint16_t payload_size;
};

static std::ostream& operator<<( std::ostream& o, const AggregatorGenericCallHeader& h ) {
  return o << "[f="           << (void*) h.function_pointer
           << ",d=" << h.destination
           << ",a=" << h.args_size
           << ",p=" << h.payload_size
           << "(t=" << sizeof(h) + h.args_size + h.payload_size << ")"
           << "]";
}

/// Active message aggregation per-destination storage class.
template< const int max_size_ >
class AggregatorBuffer {
private:
public:
  int current_position_;
  char buffer_[ max_size_ ];

  AggregatorBuffer()
    : current_position_( 0 )
  { }

  /// use default copy constructor and assignment operator

  inline bool fits( size_t size ) const {
    return (current_position_ + size) < max_size_;
  }

  inline void insert( const void * data, size_t size ) {
    assert ( fits( size ) );
    memcpy( &buffer_[ current_position_ ], data, size );
    current_position_ += size;
  }

  inline void flush() {
    current_position_ = 0;
  }
};

/// Active message aggregation class.
class Aggregator {
private:
  DISALLOW_COPY_AND_ASSIGN( Aggregator );

  /// Pointer to communication layer.
  Communicator * communicator_;

  /// max node count. used to allocate buffers.
  const int max_nodes_;

  /// number of bytes in each aggregation buffer
  /// TODO: this should track the IB MTU
  static const int buffer_size_ = 4024;

  /// buffers holding aggregated messages.
  std::vector< AggregatorBuffer< buffer_size_ > > buffers_;

  /// number of ticks to wait before automatically flushing a buffer.
  const int autoflush_ticks_;

  /// current timestamp for autoflusher.
  uint64_t previous_timestamp_;

  /// priority queue for autoflusher.
  MutableHeap< uint64_t, int > least_recently_sent_;

  /// handle for deaggregation active message
  const int aggregator_deaggregate_am_handle_;

  /// routing table for hierarchical aggregation
  std::vector< Node > route_map_;

  /// storage for deaggregation
  struct ReceivedAM {
    size_t size_;
    char buf_[buffer_size_];
    ReceivedAM( size_t size, void * buf )
      : size_( size )
      , buf_()
    {
      assert( size < buffer_size_ );
      memcpy( buf_, buf, size );
    }
  };
  std::queue< ReceivedAM > received_AM_queue_;
  void deaggregate( );
  friend void Aggregator_deaggregate_am( gasnet_token_t token, void * buf, size_t size );

public:

  /// Construct Aggregator. Takes a Communicator pointer in order to
  /// register active message handlers
  explicit Aggregator( Communicator * communicator );

  /// route map lookup for hierarchical aggregation
  inline Node get_target_for_node( Node n ) {
    return route_map_[ n ];
  }

  /// route map update for hierarchical aggregation
  inline void update_target_for_node( Node node, Node target ) {
    route_map_[ node ] = target;
  }

  /// send aggregated messages for node
  inline void flush( Node node ) {
    if (DEBUG_AGGREGATOR) std::cout << "flushing node " << node << std::endl;
    Node target = route_map_[ node ];
    communicator_->send( target,
                         aggregator_deaggregate_am_handle_,
                         buffers_[ target ].buffer_,
                         buffers_[ target ].current_position_ );
    buffers_[ target ].flush();
    least_recently_sent_.remove_key( target );
  }

  /// get timestamp. we avoid calling rdtsc for performance
  inline uint64_t get_timestamp() {
    return previous_timestamp_ + 1;
  }

  inline uint64_t get_previous_timestamp() {
    return previous_timestamp_;
  }

  /// poll communicator. send any aggregated messages that have been sitting for too long
  inline void poll() {
    communicator_->poll();
    uint64_t ts = get_timestamp();
    uint64_t flush_time = ts - autoflush_ticks_;
    if( !least_recently_sent_.empty() ) {                                    // if messages are waiting, and
      if( ( flush_time < least_recently_sent_.top_priority() ) ||  // we've wrapped around or
	  ( least_recently_sent_.top_priority() < flush_time ) ) { // we've waited long enough,
	flush( least_recently_sent_.top_key() );                   // send.
      }
    }
    previous_timestamp_ = ts;
    deaggregate();
  }

  inline const size_t max_size() const { return buffer_size_; }

  inline void aggregate( Node destination, AggregatorAMHandler fn_p,
                         const void * args, const size_t args_size,
                         const void * payload, const size_t payload_size ) {
    assert( destination < max_nodes_ );
    Node target = get_target_for_node( destination );

    // make sure arg struct and payload aren't too big.
    // in the future, this would lead us down a separate code path for large messages.
    // for now, fail.
    size_t total_call_size = payload_size + args_size + sizeof( AggregatorGenericCallHeader );
    assert( total_call_size < buffer_size_ ); // TODO: this is not specific enough

    // does call fit in aggregation buffer?
    if( !( buffers_[ target ].fits( total_call_size ) ) ) {
      // doesn't fit, so flush before inserting
      flush( target );
      assert ( buffers_[ target ].fits( total_call_size ));
    }

    // now call must fit, so just insert it
    AggregatorGenericCallHeader header = { reinterpret_cast< intptr_t >( fn_p ),
                                           destination,
                                           args_size,
                                           payload_size };
    buffers_[ target ].insert( &header, sizeof( header ) );
    buffers_[ target ].insert( args, args_size );
    buffers_[ target ].insert( payload, payload_size );

    uint64_t ts = get_timestamp();
    least_recently_sent_.update_or_insert( target, ts );
    previous_timestamp_ = ts;
    if (DEBUG_AGGREGATOR) std::cout << "aggregated " << header << std::endl;
  }

};

extern Aggregator * global_aggregator;

template< typename ArgsStruct >
inline void SoftXMT_call_on( Node destination, void (* fn_p)(ArgsStruct *, size_t, void *, size_t),
                             const ArgsStruct * args, const size_t args_size = sizeof( ArgsStruct ),
                             const void * payload = NULL, const size_t payload_size = 0)
{
  assert( global_aggregator != NULL );
  global_aggregator->aggregate( destination,
                                reinterpret_cast< AggregatorAMHandler >( fn_p ),
                                static_cast< const void * >( args ), args_size,
                                static_cast< const void * >( payload ), payload_size );
}

#endif
<|endoftext|>


<commit_before>// Copyright 2011 The Avalon Project Authors. All rights reserved.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the LICENSE file.
// Steffen Grundmann, June 2011
#include "helmsman/filter_block.h"

#include <stdio.h>
#include "helmsman/apparent.h"
#include "helmsman/boat.h"  // kWindSensorOffsetRad
#include "helmsman/controller_io.h"
#include "helmsman/sampling_period.h"
#include "lib/filter/median_filter.h"
#include "lib/filter/sliding_average_filter.h"
#include "lib/filter/wrap_around_filter.h"

#include "common/check.h"
#include "common/normalize.h"
#include "common/polar.h"
#include "common/unknown.h"

namespace {
struct FilterElement {
  FilterInterface* filter;
  const double* in;
  double* out;
};

const double kShortFilterPeriod = 1.0; // s
const double kLongFilterPeriod = 100.0; // s, N.B. The state Initial cannot be
                                        // shorter than this time period.
}  // namespace

void FilterBlock::Filter(const ControllerInput& in,
                         FilteredMeasurements* fil) {
  double zz[kChannels];
  double mag_wind_m_s = KnotsToMeterPerSecond(in.wind.mag_kn);
  double alpha_wind_rad = NormalizeRad(Deg2Rad(in.wind.alpha_deg));

  double angle_sail_raw = (alpha_wind_rad - M_PI + kWindSensorOffsetRad);

  FilterElement in_block[kChannels] = {
      {median_ + 0,  &in.imu.speed_m_s,              zz + 0},  // in m/s
      {median_ + 1,  &in.imu.position.longitude_deg, zz + 1},  // GPS-Data
      {median_ + 2,  &in.imu.position.latitude_deg,  zz + 2},
      {median_ + 3,  &in.imu.attitude.phi_x_rad,     zz + 3},  // roll; IMU-Data
      {median_ + 4,  &in.imu.attitude.phi_y_rad,     zz + 4},  // pitch;
      {&wrap_med_1_, &in.imu.attitude.phi_z_rad,     zz + 5},  // yaw;
      {median_ + 6,  &in.imu.gyro.omega_z_rad_s,     zz + 6},
      {median_ + 7,  &in.imu.temperature_c,          zz + 7},  // in deg C
      {median_ + 8,  &mag_wind_m_s,                  zz + 8},  // Wind
      {&wrap_med_2_, &alpha_wind_rad,                zz + 9}};
  CHECK_EQ(kChannels, sizeof(in_block) / sizeof(in_block[0]));
  bool valid = true;
  for (int i = 0; i < kChannels; ++i) {
    CHECK_NE(in_block[i].filter, NULL);
    if (isnan(*in_block[i].in))
      fprintf(stderr, "Filter channel %d has NaN data.\n", i);
    *in_block[i].out = in_block[i].filter->Filter(*in_block[i].in);
    valid = valid && in_block[i].filter->ValidOutput();
  }

  zz[5] = NormalizeRad(zz[5]);
  zz[9] = NormalizeRad(zz[9]);

  FilterElement out_block[] = {
      {&average_0_, zz + 0, &fil->mag_boat},      // in m/s
      {&average_1_, zz + 1, &fil->longitude_deg}, // GPS-Data
      {&average_2_, zz + 2, &fil->latitude_deg},
      {&average_3_, zz + 3, &fil->phi_x_rad},     // roll; IMU-Data
      {&average_4_, zz + 4, &fil->phi_y_rad},     // pitch;
      {&wrap_1_,    zz + 5, &fil->phi_z_boat},    // yaw;
      {&average_6_, zz + 6, &fil->omega_boat},
      {&average_7_, zz + 7, &fil->temperature_c}, // in deg C
      {&average_8_, zz + 8, &fil->mag_sensor},    // Wind
      {&wrap_2_,    zz + 9, &fil->angle_sensor}};
  CHECK_EQ(kChannels, sizeof(out_block) / sizeof(out_block[0]));
  for (int i = 0; i < kChannels; ++i) {
    CHECK_NE(out_block[i].filter, NULL);
    *out_block[i].out = out_block[i].filter->Filter(*out_block[i].in);
    valid = valid && out_block[i].filter->ValidOutput();
  }

  if (in.drives.homed_sail) {
    // The wind sensor is telling where the wind is coming from, but we work
    // with motion vectors pointing here the wind is going to.
    fil->angle_app = SymmetricRad(angle_sail_raw + in.drives.gamma_sail_rad);
    fil->mag_app = fil->mag_sensor;

    Polar wind_true(0, 0);
    TruePolar(Polar(fil->angle_app,  fil->mag_app),
              Polar(fil->phi_z_boat, fil->mag_boat),
              fil->phi_z_boat,
              &wind_true);

    fil->mag_true = average_mag_true_.Filter(
        median_mag_true_.Filter(wind_true.Mag()));
    fil->alpha_true = SymmetricRad(wrap_3_.Filter(
        wrap_med_3_.Filter(NormalizeRad(wind_true.AngleRad()))));
  } else {
    fil->angle_app = kUnknown;
    fil->mag_app = fil->mag_sensor;
    fil->alpha_true = kUnknown;  // TODO check that all later processing does not stumble over this.
    fil->mag_true = kUnknown;
  }
  fil->valid = valid;
}

FilterBlock::FilterBlock()
  : initial_(true),
    len_short_(kShortFilterPeriod / kSamplingPeriod),
    len_long_(kLongFilterPeriod / kSamplingPeriod),
    average_0_(len_short_),
    average_1_(len_short_),
    average_2_(len_short_),
    average_3_(len_short_),
    average_4_(len_short_),
    average_5_(len_short_),
    average_6_(len_short_),
    average_7_(len_short_),
    average_8_(len_short_),
    average_9_(len_short_),
    average_mag_true_(len_long_),
    wrap_med_1_(&median_wr_1_),
    wrap_med_2_(&median_wr_2_),
    wrap_med_3_(&median_wr_3_),
    average_wr_1_(len_short_),
    average_wr_2_(len_short_),
    average_wr_3_(len_long_),
    wrap_1_(&average_wr_1_),
    wrap_2_(&average_wr_2_),
    wrap_3_(&average_wr_3_) {}

bool FilterBlock::ValidTrueWind() {
  return wrap_3_.ValidOutput();
}
<commit_msg>wind_sensor change<commit_after>// Copyright 2011 The Avalon Project Authors. All rights reserved.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the LICENSE file.
// Steffen Grundmann, June 2011
#include "helmsman/filter_block.h"

#include <stdio.h>
#include "helmsman/apparent.h"
#include "helmsman/boat.h"  // kWindSensorOffsetRad
#include "helmsman/controller_io.h"
#include "helmsman/sampling_period.h"
#include "lib/filter/median_filter.h"
#include "lib/filter/sliding_average_filter.h"
#include "lib/filter/wrap_around_filter.h"

#include "common/check.h"
#include "common/normalize.h"
#include "common/polar.h"
#include "common/unknown.h"

namespace {
struct FilterElement {
  FilterInterface* filter;
  const double* in;
  double* out;
};

const double kShortFilterPeriod = 1.0; // s
const double kLongFilterPeriod = 100.0; // s, N.B. The state Initial cannot be
                                        // shorter than this time period.
}  // namespace

void FilterBlock::Filter(const ControllerInput& in,
                         FilteredMeasurements* fil) {
  double zz[kChannels];
  double mag_wind_m_s = KnotsToMeterPerSecond(in.wind_sensor.mag_m_s);
  double alpha_wind_rad = NormalizeRad(Deg2Rad(in.wind_sensor.alpha_deg));

  double angle_sail_raw = (alpha_wind_rad - M_PI + kWindSensorOffsetRad);

  FilterElement in_block[kChannels] = {
      {median_ + 0,  &in.imu.speed_m_s,              zz + 0},  // in m/s
      {median_ + 1,  &in.imu.position.longitude_deg, zz + 1},  // GPS-Data
      {median_ + 2,  &in.imu.position.latitude_deg,  zz + 2},
      {median_ + 3,  &in.imu.attitude.phi_x_rad,     zz + 3},  // roll; IMU-Data
      {median_ + 4,  &in.imu.attitude.phi_y_rad,     zz + 4},  // pitch;
      {&wrap_med_1_, &in.imu.attitude.phi_z_rad,     zz + 5},  // yaw;
      {median_ + 6,  &in.imu.gyro.omega_z_rad_s,     zz + 6},
      {median_ + 7,  &in.imu.temperature_c,          zz + 7},  // in deg C
      {median_ + 8,  &mag_wind_m_s,                  zz + 8},  // Wind
      {&wrap_med_2_, &alpha_wind_rad,                zz + 9}};
  CHECK_EQ(kChannels, sizeof(in_block) / sizeof(in_block[0]));
  bool valid = true;
  for (int i = 0; i < kChannels; ++i) {
    CHECK_NE(in_block[i].filter, NULL);
    if (isnan(*in_block[i].in))
      fprintf(stderr, "Filter channel %d has NaN data.\n", i);
    *in_block[i].out = in_block[i].filter->Filter(*in_block[i].in);
    valid = valid && in_block[i].filter->ValidOutput();
  }

  zz[5] = NormalizeRad(zz[5]);
  zz[9] = NormalizeRad(zz[9]);

  FilterElement out_block[] = {
      {&average_0_, zz + 0, &fil->mag_boat},      // in m/s
      {&average_1_, zz + 1, &fil->longitude_deg}, // GPS-Data
      {&average_2_, zz + 2, &fil->latitude_deg},
      {&average_3_, zz + 3, &fil->phi_x_rad},     // roll; IMU-Data
      {&average_4_, zz + 4, &fil->phi_y_rad},     // pitch;
      {&wrap_1_,    zz + 5, &fil->phi_z_boat},    // yaw;
      {&average_6_, zz + 6, &fil->omega_boat},
      {&average_7_, zz + 7, &fil->temperature_c}, // in deg C
      {&average_8_, zz + 8, &fil->mag_sensor},    // Wind
      {&wrap_2_,    zz + 9, &fil->angle_sensor}};
  CHECK_EQ(kChannels, sizeof(out_block) / sizeof(out_block[0]));
  for (int i = 0; i < kChannels; ++i) {
    CHECK_NE(out_block[i].filter, NULL);
    *out_block[i].out = out_block[i].filter->Filter(*out_block[i].in);
    valid = valid && out_block[i].filter->ValidOutput();
  }

  if (in.drives.homed_sail) {
    // The wind sensor is telling where the wind is coming from, but we work
    // with motion vectors pointing here the wind is going to.
    fil->angle_app = SymmetricRad(angle_sail_raw + in.drives.gamma_sail_rad);
    fil->mag_app = fil->mag_sensor;

    Polar wind_true(0, 0);
    TruePolar(Polar(fil->angle_app,  fil->mag_app),
              Polar(fil->phi_z_boat, fil->mag_boat),
              fil->phi_z_boat,
              &wind_true);

    fil->mag_true = average_mag_true_.Filter(
        median_mag_true_.Filter(wind_true.Mag()));
    fil->alpha_true = SymmetricRad(wrap_3_.Filter(
        wrap_med_3_.Filter(NormalizeRad(wind_true.AngleRad()))));
  } else {
    fil->angle_app = kUnknown;
    fil->mag_app = fil->mag_sensor;
    fil->alpha_true = kUnknown;  // TODO check that all later processing does not stumble over this.
    fil->mag_true = kUnknown;
  }
  fil->valid = valid;
}

FilterBlock::FilterBlock()
  : initial_(true),
    len_short_(kShortFilterPeriod / kSamplingPeriod),
    len_long_(kLongFilterPeriod / kSamplingPeriod),
    average_0_(len_short_),
    average_1_(len_short_),
    average_2_(len_short_),
    average_3_(len_short_),
    average_4_(len_short_),
    average_5_(len_short_),
    average_6_(len_short_),
    average_7_(len_short_),
    average_8_(len_short_),
    average_9_(len_short_),
    average_mag_true_(len_long_),
    wrap_med_1_(&median_wr_1_),
    wrap_med_2_(&median_wr_2_),
    wrap_med_3_(&median_wr_3_),
    average_wr_1_(len_short_),
    average_wr_2_(len_short_),
    average_wr_3_(len_long_),
    wrap_1_(&average_wr_1_),
    wrap_2_(&average_wr_2_),
    wrap_3_(&average_wr_3_) {}

bool FilterBlock::ValidTrueWind() {
  return wrap_3_.ValidOutput();
}
<|endoftext|>