<commit_before>//
//  gclass.cpp
//  etc
//
//  Created by Oleksii Tiurenkov on 9/30/15.
//  Copyright (c) 2015 Oleksii Tiurenkov. All rights reserved.
//

#include "gclass.h"
#include <fstream>
#include <iostream>
#include "GLOBAL_CONST.h"

using namespace std;

std::string random_string( size_t length )
{
    auto randchar = []() -> char
    {
        const char charset[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
        const size_t max_index = (sizeof(charset) - 1);
        return charset[ rand() % max_index ];
    };
    std::string str(length,0);
    std::generate_n( str.begin(), length, randchar );
    return str;
}

Gclass* Gclass::loadFromFile(std::string dir, std::string filename)
{
    Gclass* result = nullptr;
    //open file
    ifstream infile(dir+filename, ios_base::binary|ios_base::in|ios::ate);
    //if file opened
    if (infile.is_open())
    {
        //get file size
        size_t buffersize =infile.tellg();
        //create buffer
        char* bufferArray = new char[buffersize];
        //return to file start
        infile.seekg(ios::beg);
        //read all from file
        infile.read(bufferArray, buffersize);
        //close file
        infile.close();
        result = new Gclass;
        size_t bufferlength = buffersize/sizeof(shima_t);
        shima_t* shimaBuffer = reinterpret_cast<shima_t*>(bufferArray);
        result->internalArray.assign(shimaBuffer, shimaBuffer + bufferlength);
        //save file name
        result->filename = filename;
        delete [] bufferArray;
    }
    return result;
}

bool Gclass::save(std::string dir)
{
    bool result = false;
    ofstream outfile(dir + filename, ios_base::binary|ios_base::out|ios::trunc);
    if (outfile.is_open())
    {
        shima_t* shimaBuffer = new shima_t[internalArray.size()];
        std::copy(internalArray.begin(),internalArray.end(),shimaBuffer);
        outfile.write(reinterpret_cast<char*>(shimaBuffer), internalArray.size() * sizeof(shima_t));
        outfile.close();
        result = true;
    }
    else
    {
        cerr << "Error:" << strerror(errno) << endl;
        cout << "Error opening file";
    }
    return result;
}

void Gclass::saveJSON(std::string dir)
{
    ofstream outfile(dir + filename+ ".json", ios_base::out|ios::trunc);
    if (outfile.is_open())
    {
        Fleet* fleet = fleetCreate();
        outfile << fleet->json();
        delete fleet;
        outfile.close();

    }
    else
    {
        cerr << "Error:" << strerror(errno) << endl;
        cout << "Error opening file";
    }

}

void Gclass::mutation()
{
    for (int i = 0; i < internalArray.size(); i++)
    {
        if (RADIATION > (rand()%MAX_SCALE))
        {
            internalArray[i]^= 1 << rand()%(sizeof(shima_t)*8);
        }
    }
}

Fleet* Gclass::fleetCreate() const
{
    return new Fleet(internalArray);
}

Gclass* Gclass::empty()
{
    Gclass* result = new Gclass;
    result->internalArray.push_back(0);
    result->filename = random_string(16);
    return result;
}

bool Gclass::betterThan(const Gclass *other) const
{
    return score > other->score;
}

size_t randomMedium(size_t length)
{
    long result = length/2 + (RADIATION > (rand()%MAX_SCALE)?rand()%3 -1 :0 );
    result = result > 0? result:0;
    result = length < result? length: result;
    return result;
}

Gclass* Gclass::crossover(Gclass *gene)
{
    size_t myGenes = randomMedium(internalArray.size());
    size_t theirsGenes = randomMedium(gene->internalArray.size());
    Gclass* result = new Gclass;
    if (rand()%2)
    {
        for(auto it = internalArray.begin(); it != internalArray.begin()+myGenes && it != internalArray.end(); it++) result->internalArray.push_back(*it);
        for(auto it = gene->internalArray.end() - theirsGenes; it != gene->internalArray.end(); it++) result->internalArray.push_back(*it);
    }
    else
    {
        for(auto it = gene->internalArray.begin(); it != gene->internalArray.begin()+theirsGenes && it != gene->internalArray.end(); it++)
            result->internalArray.push_back(*it);
        for(auto it = internalArray.end() - myGenes; it != internalArray.end(); it++) result->internalArray.push_back(*it);
    }
    //insert random gene
    if (RADIATION > (rand()%MAX_SCALE))
    {
        size_t position = internalArray.size() != 0 ?rand()%internalArray.size() : 0;
        shima_t shima   = rand();

        internalArray.insert(internalArray.begin() + position,shima);
    }
    result->filename = random_string(16);
    return result;
}

void Gclass::deleteGene(std::string dir)
{
    remove((dir + filename).c_str());
}

void Gclass::compare(Gclass* other)
{
    auto myFleet = fleetCreate();
    auto otherFleet = other->fleetCreate();

    switch (myFleet->result(otherFleet)) {
        case WIN:
            score+=3;
            break;
        case DRAW:
            score+=1;
            other->score+=1;
            break;
        case FAIL:
            other->score+=3;
            break;
        default:
            break;
    }
    delete myFleet;
    delete otherFleet;
}

void Gclass::print()
{
    auto fleet = fleetCreate();
    fleet->print();
    delete fleet;
}

void Gclass::clearScore()
{
    score = 0;
}

<commit_msg>Changed mutation<commit_after>//
//  gclass.cpp
//  etc
//
//  Created by Oleksii Tiurenkov on 9/30/15.
//  Copyright (c) 2015 Oleksii Tiurenkov. All rights reserved.
//

#include "gclass.h"
#include <fstream>
#include <iostream>
#include "GLOBAL_CONST.h"

using namespace std;

std::string random_string( size_t length )
{
    auto randchar = []() -> char
    {
        const char charset[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
        const size_t max_index = (sizeof(charset) - 1);
        return charset[ rand() % max_index ];
    };
    std::string str(length,0);
    std::generate_n( str.begin(), length, randchar );
    return str;
}

Gclass* Gclass::loadFromFile(std::string dir, std::string filename)
{
    Gclass* result = nullptr;
    //open file
    ifstream infile(dir+filename, ios_base::binary|ios_base::in|ios::ate);
    //if file opened
    if (infile.is_open())
    {
        //get file size
        size_t buffersize =infile.tellg();
        //create buffer
        char* bufferArray = new char[buffersize];
        //return to file start
        infile.seekg(ios::beg);
        //read all from file
        infile.read(bufferArray, buffersize);
        //close file
        infile.close();
        result = new Gclass;
        size_t bufferlength = buffersize/sizeof(shima_t);
        shima_t* shimaBuffer = reinterpret_cast<shima_t*>(bufferArray);
        result->internalArray.assign(shimaBuffer, shimaBuffer + bufferlength);
        //save file name
        result->filename = filename;
        delete [] bufferArray;
    }
    return result;
}

bool Gclass::save(std::string dir)
{
    bool result = false;
    ofstream outfile(dir + filename, ios_base::binary|ios_base::out|ios::trunc);
    if (outfile.is_open())
    {
        shima_t* shimaBuffer = new shima_t[internalArray.size()];
        std::copy(internalArray.begin(),internalArray.end(),shimaBuffer);
        outfile.write(reinterpret_cast<char*>(shimaBuffer), internalArray.size() * sizeof(shima_t));
        outfile.close();
        result = true;
    }
    else
    {
        cerr << "Error:" << strerror(errno) << endl;
        cout << "Error opening file";
    }
    return result;
}

void Gclass::saveJSON(std::string dir)
{
    ofstream outfile(dir + filename+ ".json", ios_base::out|ios::trunc);
    if (outfile.is_open())
    {
        Fleet* fleet = fleetCreate();
        outfile << fleet->json();
        delete fleet;
        outfile.close();

    }
    else
    {
        cerr << "Error:" << strerror(errno) << endl;
        cout << "Error opening file";
    }

}

void Gclass::mutation()
{
    for (int i = 0; i < internalArray.size(); i++)
    {
        if (RADIATION > (rand()%MAX_SCALE))
        {
            internalArray[i]^= 1 << rand()%(sizeof(shima_t)*8);
        }
    }
    //insert random gene
    if (RADIATION > (rand()%MAX_SCALE))
    {
        size_t position = internalArray.size() != 0 ?rand()%internalArray.size() : 0;
        shima_t shima   = rand();

        internalArray.insert(internalArray.begin() + position,shima);
    }
    //Swap two or delete
    if ((internalArray.size() > 1) && (RADIATION > (rand()%MAX_SCALE)))
    {
        size_t position1 = rand()%internalArray.size();
        size_t position2 = rand()%internalArray.size();
        if(position1 == position2)
        {
            internalArray.erase(internalArray.begin()+position1);
        }
        else
        {
            std::iter_swap(internalArray.begin() + position1, internalArray.begin() + position2);
        }
    }
}

Fleet* Gclass::fleetCreate() const
{
    return new Fleet(internalArray);
}

Gclass* Gclass::empty()
{
    Gclass* result = new Gclass;
    result->internalArray.push_back(0);
    result->filename = random_string(16);
    return result;
}

bool Gclass::betterThan(const Gclass *other) const
{
    return score > other->score;
}

size_t randomMedium(size_t length)
{
    long result = length/2 + (RADIATION > (rand()%MAX_SCALE)?rand()%3 -1 :0 );
    result = result > 0? result:0;
    result = length < result? length: result;
    return result;
}

Gclass* Gclass::crossover(Gclass *gene)
{
    size_t myGenes = randomMedium(internalArray.size());
    size_t theirsGenes = randomMedium(gene->internalArray.size());
    Gclass* result = new Gclass;
    if (rand()%2)
    {
        for(auto it = internalArray.begin(); it != internalArray.begin()+myGenes && it != internalArray.end(); it++) result->internalArray.push_back(*it);
        for(auto it = gene->internalArray.end() - theirsGenes; it != gene->internalArray.end(); it++) result->internalArray.push_back(*it);
    }
    else
    {
        for(auto it = gene->internalArray.begin(); it != gene->internalArray.begin()+theirsGenes && it != gene->internalArray.end(); it++)
            result->internalArray.push_back(*it);
        for(auto it = internalArray.end() - myGenes; it != internalArray.end(); it++) result->internalArray.push_back(*it);
    }

    result->filename = random_string(16);
    result->mutation();
    return result;
}

void Gclass::deleteGene(std::string dir)
{
    remove((dir + filename).c_str());
}

void Gclass::compare(Gclass* other)
{
    auto myFleet = fleetCreate();
    auto otherFleet = other->fleetCreate();

    switch (myFleet->result(otherFleet)) {
        case WIN:
            score+=3;
            break;
        case DRAW:
            score+=1;
            other->score+=1;
            break;
        case FAIL:
            other->score+=3;
            break;
        default:
            break;
    }
    delete myFleet;
    delete otherFleet;
}

void Gclass::print()
{
    auto fleet = fleetCreate();
    fleet->print();
    delete fleet;
}

void Gclass::clearScore()
{
    score = 0;
}

<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013      Mayank Madan <maddiemadan@gmail.com>
//

#include "GeoDataFlyTo.h"
#include "GeoDataTypes.h"
#include "GeoDataAbstractView.h"

namespace Marble {

class GeoDataFlyToPrivate
{
public:
    double m_duration;

    GeoDataFlyTo::FlyToMode m_flyToMode;

    GeoDataAbstractView* m_view;

    GeoDataFlyToPrivate();
};

GeoDataFlyToPrivate::GeoDataFlyToPrivate() :
    m_duration( 0.0 ), m_flyToMode(), m_view( 0 )
{

}

GeoDataFlyTo::GeoDataFlyTo() : d( new GeoDataFlyToPrivate )
{

}

GeoDataFlyTo::GeoDataFlyTo( const Marble::GeoDataFlyTo &other ) :
    GeoDataTourPrimitive( other ), d( new GeoDataFlyToPrivate( *other.d ) )
{

}

GeoDataFlyTo &GeoDataFlyTo::operator=( const GeoDataFlyTo &other )
{
    GeoDataTourPrimitive::operator=( other );
    *d = *other.d;
    return *this;
}

bool GeoDataFlyTo::operator==( const GeoDataFlyTo& other ) const
{
    return equals(other) &&
           d->m_duration == other.d->m_duration &&
           d->m_flyToMode == other.d->m_flyToMode &&
           d->m_view == other.d->m_view;
}

bool GeoDataFlyTo::operator!=( const GeoDataFlyTo& other ) const
{
    return !this->operator==(other);
}

GeoDataFlyTo::~GeoDataFlyTo()
{
    delete d;
}

const char *GeoDataFlyTo::nodeType() const
{
    return GeoDataTypes::GeoDataFlyToType;
}

const GeoDataAbstractView *GeoDataFlyTo::view() const
{
    return d->m_view;
}

GeoDataAbstractView *GeoDataFlyTo::view()
{
    return d->m_view;
}

void GeoDataFlyTo::setView( GeoDataAbstractView *view )
{
    d->m_view = view;
}

double GeoDataFlyTo::duration() const
{
    return d->m_duration;
}

void GeoDataFlyTo::setDuration( double duration )
{
    d->m_duration = duration;
}

GeoDataFlyTo::FlyToMode GeoDataFlyTo::flyToMode() const
{
    return d->m_flyToMode;
}

void GeoDataFlyTo::setFlyToMode( const GeoDataFlyTo::FlyToMode flyToMode )
{
    d->m_flyToMode = flyToMode;
}

}
<commit_msg>Fix equlity operator in GeoDataFlyTo - it now compares m_view based on nodeType<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013      Mayank Madan <maddiemadan@gmail.com>
//

#include "GeoDataFlyTo.h"
#include "GeoDataTypes.h"
#include "GeoDataAbstractView.h"
#include "GeoDataCamera.h"
#include "GeoDataLookAt.h"

namespace Marble {

class GeoDataFlyToPrivate
{
public:
    double m_duration;

    GeoDataFlyTo::FlyToMode m_flyToMode;

    GeoDataAbstractView* m_view;

    GeoDataFlyToPrivate();
};

GeoDataFlyToPrivate::GeoDataFlyToPrivate() :
    m_duration( 0.0 ), m_flyToMode(), m_view( 0 )
{

}

GeoDataFlyTo::GeoDataFlyTo() : d( new GeoDataFlyToPrivate )
{

}

GeoDataFlyTo::GeoDataFlyTo( const Marble::GeoDataFlyTo &other ) :
    GeoDataTourPrimitive( other ), d( new GeoDataFlyToPrivate( *other.d ) )
{

}

GeoDataFlyTo &GeoDataFlyTo::operator=( const GeoDataFlyTo &other )
{
    GeoDataTourPrimitive::operator=( other );
    *d = *other.d;
    return *this;
}

bool GeoDataFlyTo::operator==( const GeoDataFlyTo& other ) const
{
    if ( !equals(other) ||
         d->m_duration != other.d->m_duration ||
         d->m_flyToMode != other.d->m_flyToMode ) {
        return false;
    }

    if ( (!d->m_view && other.d->m_view) ||
         (d->m_view && !other.d->m_view) ) {
        return false;
    } else if ( !d->m_view && !other.d->m_view ) {
        return true;
    }

    if ( d->m_view->nodeType() != other.d->m_view->nodeType() ) {
        return false;
    }

    if ( d->m_view->nodeType() == GeoDataTypes::GeoDataCameraType ) {
        GeoDataCamera *thisCam = dynamic_cast<GeoDataCamera*>( d->m_view );
        GeoDataCamera *otherCam = dynamic_cast<GeoDataCamera*>( other.d->m_view );
        Q_ASSERT( thisCam && otherCam );

        if ( *thisCam != *otherCam ) {
            return false;
        }
    } else if ( d->m_view->nodeType() == GeoDataTypes::GeoDataLookAtType ) {
        GeoDataLookAt *thisLookAt = dynamic_cast<GeoDataLookAt*>( d->m_view );
        GeoDataLookAt *otherLookAt = dynamic_cast<GeoDataLookAt*>( other.d->m_view );
        Q_ASSERT( thisLookAt && otherLookAt );

        if ( *thisLookAt != *otherLookAt ) {
            return false;
        }
    }

    return true;
}

bool GeoDataFlyTo::operator!=( const GeoDataFlyTo& other ) const
{
    return !this->operator==(other);
}

GeoDataFlyTo::~GeoDataFlyTo()
{
    delete d;
}

const char *GeoDataFlyTo::nodeType() const
{
    return GeoDataTypes::GeoDataFlyToType;
}

const GeoDataAbstractView *GeoDataFlyTo::view() const
{
    return d->m_view;
}

GeoDataAbstractView *GeoDataFlyTo::view()
{
    return d->m_view;
}

void GeoDataFlyTo::setView( GeoDataAbstractView *view )
{
    d->m_view = view;
}

double GeoDataFlyTo::duration() const
{
    return d->m_duration;
}

void GeoDataFlyTo::setDuration( double duration )
{
    d->m_duration = duration;
}

GeoDataFlyTo::FlyToMode GeoDataFlyTo::flyToMode() const
{
    return d->m_flyToMode;
}

void GeoDataFlyTo::setFlyToMode( const GeoDataFlyTo::FlyToMode flyToMode )
{
    d->m_flyToMode = flyToMode;
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: indexentrysupplier_asian.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 04:45:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#include <rtl/ustrbuf.hxx>
#include <indexentrysupplier_asian.hxx>
#include <data/indexdata_alphanumeric.h>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::rtl;

namespace com { namespace sun { namespace star { namespace i18n {

IndexEntrySupplier_asian::IndexEntrySupplier_asian(
    const Reference < XMultiServiceFactory >& rxMSF ) : IndexEntrySupplier_Common(rxMSF)
{
    implementationName = "com.sun.star.i18n.IndexEntrySupplier_asian";
#ifdef SAL_DLLPREFIX
    OUString lib=OUString::createFromAscii(SAL_DLLPREFIX"index_data"SAL_DLLEXTENSION);
#else
    OUString lib=OUString::createFromAscii("index_data"SAL_DLLEXTENSION);
#endif
    hModule = osl_loadModule( lib.pData, SAL_LOADMODULE_DEFAULT );
}

IndexEntrySupplier_asian::~IndexEntrySupplier_asian()
{
    if (hModule) osl_unloadModule(hModule);
}

OUString SAL_CALL
IndexEntrySupplier_asian::getIndexCharacter( const OUString& rIndexEntry,
    const Locale& rLocale, const OUString& rAlgorithm ) throw (RuntimeException)
{
    sal_Unicode ch = rIndexEntry.toChar();
    if (hModule) {
        OUString get=OUString::createFromAscii("get_indexdata_");
        int (*func)()=NULL;
        if (rLocale.Language.equalsAscii("zh") && OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0)
            func=(int (*)())osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString::createFromAscii("_TW_")+rAlgorithm).pData);
        if (!func)
            func=(int (*)())osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString('_')+rAlgorithm).pData);
        if (func) {
            sal_uInt16** idx=(sal_uInt16**)func();
            sal_uInt16 address=idx[0][ch >> 8];
            if (address != 0xFFFF) {
                address=idx[1][address+(ch & 0xFF)];
                return idx[2] ? OUString(&idx[2][address]) : OUString(address);
            }
        }
    }
    // using alphanumeric index for non-define stirng
    return OUString(&idxStr[(ch & 0xFF00) ? 0 : ch], 1);
}

OUString SAL_CALL
IndexEntrySupplier_asian::getIndexKey( const OUString& rIndexEntry,
    const OUString& rPhoneticEntry, const Locale& rLocale) throw (RuntimeException)
{
    return getIndexCharacter(getEntry(rIndexEntry, rPhoneticEntry, rLocale), rLocale, aAlgorithm);
}

sal_Int16 SAL_CALL
IndexEntrySupplier_asian::compareIndexEntry(
    const OUString& rIndexEntry1, const OUString& rPhoneticEntry1, const Locale& rLocale1,
    const OUString& rIndexEntry2, const OUString& rPhoneticEntry2, const Locale& rLocale2 )
    throw (RuntimeException)
{
    sal_Int32 result = collator->compareString(getEntry(rIndexEntry1, rPhoneticEntry1, rLocale1),
                                    getEntry(rIndexEntry2, rPhoneticEntry2, rLocale2));

    // equivalent of phonetic entries does not mean equivalent of index entries.
    // we have to continue comparing index entry here.
    if (result == 0 && usePhonetic && rPhoneticEntry1.getLength() > 0 &&
            rLocale1.Language == rLocale2.Language && rLocale1.Country == rLocale2.Country &&
            rLocale1.Variant == rLocale2.Variant)
        result = collator->compareString(rIndexEntry1, rIndexEntry2);
    return sal::static_int_cast< sal_Int16 >(result); // result in { -1, 0, 1 }
}

OUString SAL_CALL
IndexEntrySupplier_asian::getPhoneticCandidate( const OUString& rIndexEntry,
        const Locale& rLocale ) throw (RuntimeException)
{
    if (hModule) {
        int (*func)()=NULL;
        const sal_Char *func_name=NULL;
        if (rLocale.Language.equalsAscii("zh"))
            func_name=(OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0) ?  "get_zh_zhuyin" : func_name="get_zh_pinyin";
        else if (rLocale.Language.equalsAscii("ko"))
            func_name="get_ko_phonetic";
        if (func_name)
            func=(int (*)())osl_getFunctionSymbol(hModule, OUString::createFromAscii(func_name).pData);
        if (func) {
            OUStringBuffer candidate;
            sal_uInt16** idx=(sal_uInt16**)func();
            for (sal_Int32 i=0; i < rIndexEntry.getLength(); i++) {
                sal_Unicode ch = rIndexEntry[i];
                sal_uInt16 address = idx[0][ch>>8];
                if (address != 0xFFFF) {
                    address = idx[1][address + (ch & 0xFF)];
                    if (i > 0 && rLocale.Language.equalsAscii("zh"))
                        candidate.appendAscii(" ");
                    if (idx[2])
                        candidate.append(&idx[2][address]);
                    else
                        candidate.append(address);
                } else
                    candidate.appendAscii(" ");
            }
            return candidate.makeStringAndClear();
        }
    }
    return OUString();
}
} } } }
<commit_msg>INTEGRATION: CWS warningfixes02 (1.7.2); FILE MERGED 2006/06/30 11:57:37 sb 1.7.2.1: #i66577# Made the code compile (warning-free) on a unxlngi6.pro GCC 4.1.1 Linux box.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: indexentrysupplier_asian.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-19 16:29:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#include <rtl/ustrbuf.hxx>
#include <indexentrysupplier_asian.hxx>
#include <data/indexdata_alphanumeric.h>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::rtl;

namespace com { namespace sun { namespace star { namespace i18n {

IndexEntrySupplier_asian::IndexEntrySupplier_asian(
    const Reference < XMultiServiceFactory >& rxMSF ) : IndexEntrySupplier_Common(rxMSF)
{
    implementationName = "com.sun.star.i18n.IndexEntrySupplier_asian";
#ifdef SAL_DLLPREFIX
    OUString lib=OUString::createFromAscii(SAL_DLLPREFIX"index_data"SAL_DLLEXTENSION);
#else
    OUString lib=OUString::createFromAscii("index_data"SAL_DLLEXTENSION);
#endif
    hModule = osl_loadModule( lib.pData, SAL_LOADMODULE_DEFAULT );
}

IndexEntrySupplier_asian::~IndexEntrySupplier_asian()
{
    if (hModule) osl_unloadModule(hModule);
}

OUString SAL_CALL
IndexEntrySupplier_asian::getIndexCharacter( const OUString& rIndexEntry,
    const Locale& rLocale, const OUString& rAlgorithm ) throw (RuntimeException)
{
    sal_Unicode ch = rIndexEntry.toChar();
    if (hModule) {
        OUString get=OUString::createFromAscii("get_indexdata_");
        int (*func)()=NULL;
        if (rLocale.Language.equalsAscii("zh") && OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0)
            func=(int (*)())osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString::createFromAscii("_TW_")+rAlgorithm).pData);
        if (!func)
            func=(int (*)())osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString('_')+rAlgorithm).pData);
        if (func) {
            sal_uInt16** idx=(sal_uInt16**)func();
            sal_uInt16 address=idx[0][ch >> 8];
            if (address != 0xFFFF) {
                address=idx[1][address+(ch & 0xFF)];
                return idx[2] ? OUString(&idx[2][address]) : OUString(address);
            }
        }
    }
    // using alphanumeric index for non-define stirng
    return OUString(&idxStr[(ch & 0xFF00) ? 0 : ch], 1);
}

OUString SAL_CALL
IndexEntrySupplier_asian::getIndexKey( const OUString& rIndexEntry,
    const OUString& rPhoneticEntry, const Locale& rLocale) throw (RuntimeException)
{
    return getIndexCharacter(getEntry(rIndexEntry, rPhoneticEntry, rLocale), rLocale, aAlgorithm);
}

sal_Int16 SAL_CALL
IndexEntrySupplier_asian::compareIndexEntry(
    const OUString& rIndexEntry1, const OUString& rPhoneticEntry1, const Locale& rLocale1,
    const OUString& rIndexEntry2, const OUString& rPhoneticEntry2, const Locale& rLocale2 )
    throw (RuntimeException)
{
    sal_Int32 result = collator->compareString(getEntry(rIndexEntry1, rPhoneticEntry1, rLocale1),
                                    getEntry(rIndexEntry2, rPhoneticEntry2, rLocale2));

    // equivalent of phonetic entries does not mean equivalent of index entries.
    // we have to continue comparing index entry here.
    if (result == 0 && usePhonetic && rPhoneticEntry1.getLength() > 0 &&
            rLocale1.Language == rLocale2.Language && rLocale1.Country == rLocale2.Country &&
            rLocale1.Variant == rLocale2.Variant)
        result = collator->compareString(rIndexEntry1, rIndexEntry2);
    return sal::static_int_cast< sal_Int16 >(result); // result in { -1, 0, 1 }
}

OUString SAL_CALL
IndexEntrySupplier_asian::getPhoneticCandidate( const OUString& rIndexEntry,
        const Locale& rLocale ) throw (RuntimeException)
{
    if (hModule) {
        int (*func)()=NULL;
        const sal_Char *func_name=NULL;
        if (rLocale.Language.equalsAscii("zh"))
            func_name=(OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0) ?  "get_zh_zhuyin" : "get_zh_pinyin";
        else if (rLocale.Language.equalsAscii("ko"))
            func_name="get_ko_phonetic";
        if (func_name)
            func=(int (*)())osl_getFunctionSymbol(hModule, OUString::createFromAscii(func_name).pData);
        if (func) {
            OUStringBuffer candidate;
            sal_uInt16** idx=(sal_uInt16**)func();
            for (sal_Int32 i=0; i < rIndexEntry.getLength(); i++) {
                sal_Unicode ch = rIndexEntry[i];
                sal_uInt16 address = idx[0][ch>>8];
                if (address != 0xFFFF) {
                    address = idx[1][address + (ch & 0xFF)];
                    if (i > 0 && rLocale.Language.equalsAscii("zh"))
                        candidate.appendAscii(" ");
                    if (idx[2])
                        candidate.append(&idx[2][address]);
                    else
                        candidate.append(address);
                } else
                    candidate.appendAscii(" ");
            }
            return candidate.makeStringAndClear();
        }
    }
    return OUString();
}
} } } }
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: attarray.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-21 15:56:26 $
 *
 *  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 SC_ATRARR_HXX
#define SC_ATRARR_HXX

#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

#ifndef SC_SCATTR_HXX
#include "attrib.hxx"
#endif

class ScDocument;
class ScMarkArray;
class ScPatternAttr;
class ScStyleSheet;

class Rectangle;
class SfxItemPoolCache;
class SfxStyleSheetBase;
class SvxBorderLine;
class SvxBoxItem;
class SvxBoxInfoItem;

#define SC_LINE_EMPTY           0
#define SC_LINE_SET             1
#define SC_LINE_DONTCARE        2

#define SC_ATTRARRAY_DELTA      4

struct ScLineFlags
{
    BYTE    nLeft;
    BYTE    nRight;
    BYTE    nTop;
    BYTE    nBottom;
    BYTE    nHori;
    BYTE    nVert;

    ScLineFlags() : nLeft(SC_LINE_EMPTY),nRight(SC_LINE_EMPTY),nTop(SC_LINE_EMPTY),
                    nBottom(SC_LINE_EMPTY),nHori(SC_LINE_EMPTY),nVert(SC_LINE_EMPTY) {}
};

struct ScAttrEntry
{
    SCROW                   nRow;
    const ScPatternAttr*    pPattern;
};

class ScAttrArray
{
private:
    SCCOL           nCol;
    SCTAB           nTab;
    ScDocument*     pDocument;

    SCSIZE          nCount;
    SCSIZE          nLimit;
    ScAttrEntry*    pData;

friend class ScDocument;                // fuer FillInfo
friend class ScDocumentIterator;
friend class ScAttrIterator;
friend class ScHorizontalAttrIterator;
friend void lcl_IterGetNumberFormat( ULONG& nFormat,
        const ScAttrArray*& rpArr, SCROW& nAttrEndRow,
        const ScAttrArray* pNewArr, SCROW nRow, ScDocument* pDoc );

    BOOL    ApplyFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
                            SCROW nStartRow, SCROW nEndRow,
                            BOOL bLeft, SCCOL nDistRight, BOOL bTop, SCROW nDistBottom );

public:
            ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc );
            ~ScAttrArray();

    void    SetTab(SCTAB nNewTab)   { nTab = nNewTab; }
    void    SetCol(SCCOL nNewCol)   { nCol = nNewCol; }

    void    TestData() const;
    void    Reset( const ScPatternAttr* pPattern, BOOL bAlloc = TRUE );
    BOOL    Concat(SCSIZE nPos);

    const ScPatternAttr* GetPattern( SCROW nRow ) const;
    const ScPatternAttr* GetPatternRange( SCROW& rStartRow, SCROW& rEndRow, SCROW nRow ) const;
    void    MergePatternArea( SCROW nStartRow, SCROW nEndRow, SfxItemSet** ppSet, BOOL bDeep ) const;

    void    MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
                            SCROW nStartRow, SCROW nEndRow, BOOL bLeft, SCCOL nDistRight ) const;
    void    ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
                            SCROW nStartRow, SCROW nEndRow, BOOL bLeft, SCCOL nDistRight );

    void    SetPattern( SCROW nRow, const ScPatternAttr* pPattern, BOOL bPutToPool = FALSE );
    void    SetPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern, BOOL bPutToPool = FALSE);
    void    ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, ScStyleSheet* pStyle );
    void    ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache );
    void    ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow,
                                const SvxBorderLine* pLine, BOOL bColorOnly );

    void    ClearItems( SCROW nStartRow, SCROW nEndRow, const USHORT* pWhich );
    void    ChangeIndent( SCROW nStartRow, SCROW nEndRow, BOOL bIncrement );

            /// Including current, may return -1
    SCsROW  GetNextUnprotected( SCsROW nRow, BOOL bUp ) const;

            /// May return -1 if not found
    SCsROW  SearchStyle( SCsROW nRow, const ScStyleSheet* pSearchStyle,
                            BOOL bUp, ScMarkArray* pMarkArray = NULL );
    BOOL    SearchStyleRange( SCsROW& rRow, SCsROW& rEndRow, const ScStyleSheet* pSearchStyle,
                            BOOL bUp, ScMarkArray* pMarkArray = NULL );

    BOOL    ApplyFlags( SCROW nStartRow, SCROW nEndRow, INT16 nFlags );
    BOOL    RemoveFlags( SCROW nStartRow, SCROW nEndRow, INT16 nFlags );

    BOOL    Search( SCROW nRow, SCSIZE& nIndex ) const;

    BOOL    HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes,
                        BOOL bLeft, BOOL bRight ) const;
    BOOL    HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const;
    BOOL    ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
                                SCCOL& rPaintCol, SCROW& rPaintRow,
                                BOOL bRefresh, BOOL bAttrs );
    BOOL    RemoveAreaMerge( SCROW nStartRow, SCROW nEndRow );

    void    FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pUsed, BOOL bReset );
    BOOL    IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const;

    void    DeleteAreaSafe(SCROW nStartRow, SCROW nEndRow);
    void    SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow,
                                    const ScPatternAttr* pWantedPattern, BOOL bDefault );
    void    CopyAreaSafe( SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray );

    BOOL    IsEmpty() const;

    SCROW   GetFirstEntryPos() const;
    SCROW   GetLastEntryPos( BOOL bIncludeBottom ) const;

    BOOL    GetFirstVisibleAttr( SCROW& rFirstRow ) const;
    BOOL    GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData ) const;
    BOOL    HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const;
    BOOL    IsVisibleEqual( const ScAttrArray& rOther,
                            SCROW nStartRow, SCROW nEndRow ) const;
    BOOL    IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW nEndRow ) const;

    BOOL    TestInsertCol( SCROW nStartRow, SCROW nEndRow) const;
    BOOL    TestInsertRow( SCSIZE nSize ) const;
    void    InsertRow( SCROW nStartRow, SCSIZE nSize );
    void    DeleteRow( SCROW nStartRow, SCSIZE nSize );
    void    DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex );
    void    DeleteArea( SCROW nStartRow, SCROW nEndRow );
    void    MoveTo( SCROW nStartRow, SCROW nEndRow, ScAttrArray& rAttrArray );
    void    CopyArea( SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray,
                        INT16 nStripFlags = 0 );

    void    DeleteHardAttr( SCROW nStartRow, SCROW nEndRow );

    void    Save( SvStream& rStream ) const;
    void    Load( SvStream& rStream );
    void    ConvertFontsAfterLoad();     // old binary file format
};

//  ------------------------------------------------------------------------------
//                              Iterator fuer Attribute
//  ------------------------------------------------------------------------------

class ScAttrIterator
{
    const ScAttrArray*  pArray;
    SCSIZE              nPos;
    SCROW               nRow;
    SCROW               nEndRow;
public:
    inline              ScAttrIterator( const ScAttrArray* pNewArray, SCROW nStart, SCROW nEnd );
    inline const ScPatternAttr* Next( SCROW& rTop, SCROW& rBottom );
    SCROW               GetNextRow() const { return nRow; }
};

inline ScAttrIterator::ScAttrIterator( const ScAttrArray* pNewArray, SCROW nStart, SCROW nEnd ) :
    pArray( pNewArray ),
    nRow( nStart ),
    nEndRow( nEnd )
{
    if ( nStart > 0 )
        pArray->Search( nStart, nPos );
    else
        nPos = 0;
}

inline const ScPatternAttr* ScAttrIterator::Next( SCROW& rTop, SCROW& rBottom )
{
    const ScPatternAttr* pRet;
    if ( nPos < pArray->nCount && nRow <= nEndRow )
    {
        rTop = nRow;
        rBottom = Min( pArray->pData[nPos].nRow, nEndRow );
        pRet = pArray->pData[nPos].pPattern;
        nRow = rBottom + 1;
        ++nPos;
    }
    else
        pRet = NULL;
    return pRet;
}

#endif

<commit_msg>INTEGRATION: CWS dr34 (1.6.2); FILE MERGED 2005/03/10 11:41:13 nn 1.6.2.1: #i44697# detect equal ScPatternAttr pointers across MergePatternArea calls<commit_after>/*************************************************************************
 *
 *  $RCSfile: attarray.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-03-29 13:28:51 $
 *
 *  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 SC_ATRARR_HXX
#define SC_ATRARR_HXX

#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

#ifndef SC_SCATTR_HXX
#include "attrib.hxx"
#endif

class ScDocument;
class ScMarkArray;
class ScPatternAttr;
class ScStyleSheet;

class Rectangle;
class SfxItemPoolCache;
class SfxStyleSheetBase;
class SvxBorderLine;
class SvxBoxItem;
class SvxBoxInfoItem;

#define SC_LINE_EMPTY           0
#define SC_LINE_SET             1
#define SC_LINE_DONTCARE        2

#define SC_ATTRARRAY_DELTA      4

struct ScLineFlags
{
    BYTE    nLeft;
    BYTE    nRight;
    BYTE    nTop;
    BYTE    nBottom;
    BYTE    nHori;
    BYTE    nVert;

    ScLineFlags() : nLeft(SC_LINE_EMPTY),nRight(SC_LINE_EMPTY),nTop(SC_LINE_EMPTY),
                    nBottom(SC_LINE_EMPTY),nHori(SC_LINE_EMPTY),nVert(SC_LINE_EMPTY) {}
};

struct ScMergePatternState
{
    SfxItemSet* pItemSet;           // allocated in MergePatternArea, used for resulting ScPatternAttr
    const ScPatternAttr* pOld1;     // existing objects, temporary
    const ScPatternAttr* pOld2;

    ScMergePatternState() : pItemSet(NULL), pOld1(NULL), pOld2(NULL) {}
};

struct ScAttrEntry
{
    SCROW                   nRow;
    const ScPatternAttr*    pPattern;
};

class ScAttrArray
{
private:
    SCCOL           nCol;
    SCTAB           nTab;
    ScDocument*     pDocument;

    SCSIZE          nCount;
    SCSIZE          nLimit;
    ScAttrEntry*    pData;

friend class ScDocument;                // fuer FillInfo
friend class ScDocumentIterator;
friend class ScAttrIterator;
friend class ScHorizontalAttrIterator;
friend void lcl_IterGetNumberFormat( ULONG& nFormat,
        const ScAttrArray*& rpArr, SCROW& nAttrEndRow,
        const ScAttrArray* pNewArr, SCROW nRow, ScDocument* pDoc );

    BOOL    ApplyFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
                            SCROW nStartRow, SCROW nEndRow,
                            BOOL bLeft, SCCOL nDistRight, BOOL bTop, SCROW nDistBottom );

public:
            ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc );
            ~ScAttrArray();

    void    SetTab(SCTAB nNewTab)   { nTab = nNewTab; }
    void    SetCol(SCCOL nNewCol)   { nCol = nNewCol; }

    void    TestData() const;
    void    Reset( const ScPatternAttr* pPattern, BOOL bAlloc = TRUE );
    BOOL    Concat(SCSIZE nPos);

    const ScPatternAttr* GetPattern( SCROW nRow ) const;
    const ScPatternAttr* GetPatternRange( SCROW& rStartRow, SCROW& rEndRow, SCROW nRow ) const;
    void    MergePatternArea( SCROW nStartRow, SCROW nEndRow, ScMergePatternState& rState, BOOL bDeep ) const;

    void    MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner, ScLineFlags& rFlags,
                            SCROW nStartRow, SCROW nEndRow, BOOL bLeft, SCCOL nDistRight ) const;
    void    ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInfoItem* pLineInner,
                            SCROW nStartRow, SCROW nEndRow, BOOL bLeft, SCCOL nDistRight );

    void    SetPattern( SCROW nRow, const ScPatternAttr* pPattern, BOOL bPutToPool = FALSE );
    void    SetPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern, BOOL bPutToPool = FALSE);
    void    ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, ScStyleSheet* pStyle );
    void    ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache );
    void    ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow,
                                const SvxBorderLine* pLine, BOOL bColorOnly );

    void    ClearItems( SCROW nStartRow, SCROW nEndRow, const USHORT* pWhich );
    void    ChangeIndent( SCROW nStartRow, SCROW nEndRow, BOOL bIncrement );

            /// Including current, may return -1
    SCsROW  GetNextUnprotected( SCsROW nRow, BOOL bUp ) const;

            /// May return -1 if not found
    SCsROW  SearchStyle( SCsROW nRow, const ScStyleSheet* pSearchStyle,
                            BOOL bUp, ScMarkArray* pMarkArray = NULL );
    BOOL    SearchStyleRange( SCsROW& rRow, SCsROW& rEndRow, const ScStyleSheet* pSearchStyle,
                            BOOL bUp, ScMarkArray* pMarkArray = NULL );

    BOOL    ApplyFlags( SCROW nStartRow, SCROW nEndRow, INT16 nFlags );
    BOOL    RemoveFlags( SCROW nStartRow, SCROW nEndRow, INT16 nFlags );

    BOOL    Search( SCROW nRow, SCSIZE& nIndex ) const;

    BOOL    HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes,
                        BOOL bLeft, BOOL bRight ) const;
    BOOL    HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const;
    BOOL    ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
                                SCCOL& rPaintCol, SCROW& rPaintRow,
                                BOOL bRefresh, BOOL bAttrs );
    BOOL    RemoveAreaMerge( SCROW nStartRow, SCROW nEndRow );

    void    FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pUsed, BOOL bReset );
    BOOL    IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const;

    void    DeleteAreaSafe(SCROW nStartRow, SCROW nEndRow);
    void    SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow,
                                    const ScPatternAttr* pWantedPattern, BOOL bDefault );
    void    CopyAreaSafe( SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray );

    BOOL    IsEmpty() const;

    SCROW   GetFirstEntryPos() const;
    SCROW   GetLastEntryPos( BOOL bIncludeBottom ) const;

    BOOL    GetFirstVisibleAttr( SCROW& rFirstRow ) const;
    BOOL    GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData ) const;
    BOOL    HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const;
    BOOL    IsVisibleEqual( const ScAttrArray& rOther,
                            SCROW nStartRow, SCROW nEndRow ) const;
    BOOL    IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW nEndRow ) const;

    BOOL    TestInsertCol( SCROW nStartRow, SCROW nEndRow) const;
    BOOL    TestInsertRow( SCSIZE nSize ) const;
    void    InsertRow( SCROW nStartRow, SCSIZE nSize );
    void    DeleteRow( SCROW nStartRow, SCSIZE nSize );
    void    DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex );
    void    DeleteArea( SCROW nStartRow, SCROW nEndRow );
    void    MoveTo( SCROW nStartRow, SCROW nEndRow, ScAttrArray& rAttrArray );
    void    CopyArea( SCROW nStartRow, SCROW nEndRow, long nDy, ScAttrArray& rAttrArray,
                        INT16 nStripFlags = 0 );

    void    DeleteHardAttr( SCROW nStartRow, SCROW nEndRow );

    void    Save( SvStream& rStream ) const;
    void    Load( SvStream& rStream );
    void    ConvertFontsAfterLoad();     // old binary file format
};

//  ------------------------------------------------------------------------------
//                              Iterator fuer Attribute
//  ------------------------------------------------------------------------------

class ScAttrIterator
{
    const ScAttrArray*  pArray;
    SCSIZE              nPos;
    SCROW               nRow;
    SCROW               nEndRow;
public:
    inline              ScAttrIterator( const ScAttrArray* pNewArray, SCROW nStart, SCROW nEnd );
    inline const ScPatternAttr* Next( SCROW& rTop, SCROW& rBottom );
    SCROW               GetNextRow() const { return nRow; }
};

inline ScAttrIterator::ScAttrIterator( const ScAttrArray* pNewArray, SCROW nStart, SCROW nEnd ) :
    pArray( pNewArray ),
    nRow( nStart ),
    nEndRow( nEnd )
{
    if ( nStart > 0 )
        pArray->Search( nStart, nPos );
    else
        nPos = 0;
}

inline const ScPatternAttr* ScAttrIterator::Next( SCROW& rTop, SCROW& rBottom )
{
    const ScPatternAttr* pRet;
    if ( nPos < pArray->nCount && nRow <= nEndRow )
    {
        rTop = nRow;
        rBottom = Min( pArray->pData[nPos].nRow, nEndRow );
        pRet = pArray->pData[nPos].pPattern;
        nRow = rBottom + 1;
        ++nPos;
    }
    else
        pRet = NULL;
    return pRet;
}

#endif

<|endoftext|>


<commit_before>#pragma once
#ifndef OPENGM_POPT_DATA_HXX
#define OPENGM_POPT_DATA_HXX

#include <vector>
//#include <string>
//#include <iostream>

#include <opengm/opengm.hxx>
#include <opengm/utilities/metaprogramming.hxx>
#include <opengm/utilities/tribool.hxx>
//#include <opengm/functions/reduced_view.hxx>
#include <opengm/functions/explicit_function.hxx>

namespace opengm {
//! [class popt_data]
/// Partial Optimaility Data (-Container)
///
/// Corresponding author: Joerg Hendrik Kappes
///
///\ingroup inference
template<class GM>
class POpt_Data {
public:
    typedef GM GraphicalModelType;
    typedef GM GmType;
    OPENGM_GM_TYPE_TYPEDEFS;

//    typedef ReducedViewFunction<GraphicalModelType>                  ReducedViewType;
    typedef opengm::ExplicitFunction<ValueType, LabelType, IndexType> ExplicitFunction;
    typedef GraphicalModel<ValueType, OperatorType, ExplicitFunction> ReducedGmType;

    POpt_Data(const GmType&);
    // Set
    void                                   setTrue(const IndexType, const LabelType);
    void                                   setFalse(const IndexType, const LabelType);
    void                                   setFalse(const IndexType factor, const std::vector<LabelType>& labeling);
    // Get Partial Optimality
    Tribool                                getPOpt(const IndexType, const LabelType) const;
    std::vector<opengm::Tribool>           getPOpt(const IndexType) const;
    ValueType                              getPOpt() const;
    // Get Optimal Certificates
    bool                                   getOpt(const IndexType) const;
    const std::vector<bool>&               getOpt() const;
    // Get Optimal Labels
    LabelType                              get(const IndexType) const;
    void                                   get(std::vector<LabelType>&) const;

    const GmType&                          graphicalModel() const {return gm_;}
    void                                   reducedGraphicalModel(ReducedGmType&) const;

    void                                   OriginalToReducedLabeling(const std::vector<LabelType>& lOrig, std::vector<LabelType>& lRed) const;
    void                                   ReducedToOriginalLabeling(std::vector<LabelType>& lOrig, const std::vector<LabelType>& lRed) const;

private:
    const GmType& gm_;
    std::vector<std::vector<opengm::Tribool> >   partialOptimality_;
    std::vector<bool>                            optimal_;
    std::vector<LabelType>                       labeling_;
    std::vector<IndexType>                       countFalse_;
    std::vector<std::vector<std::vector<LabelType> > >  excludedLabelings_; // for each factor the excluded labelings are pushed
    std::vector<std::vector<std::vector<LabelType> > > excludedCount_;
    // count for number of excluded labelings in which (variable,label) partakes
    // used for elimination of variables
};
//! [class popt_data]

//********************************************

template<class GM>
POpt_Data<GM>::POpt_Data
(
    const GmType& gm
)
    :  gm_(gm),
    partialOptimality_(std::vector<std::vector<opengm::Tribool> >(gm.numberOfVariables()) ),
    optimal_(std::vector<bool>(gm.numberOfVariables(),false)),
    labeling_(std::vector<LabelType>(gm.numberOfVariables(),0)),
    countFalse_(std::vector<IndexType>(gm.numberOfVariables(),0)),
    excludedLabelings_(gm.numberOfFactors()),
    excludedCount_(gm.numberOfFactors()) {

    for(IndexType var=0; var<gm_.numberOfVariables(); ++var) {
        partialOptimality_[var].resize(gm_.numberOfLabels(var),opengm::Tribool::Maybe);
    }
    for(size_t f=0; f<gm_.numberOfFactors(); f++) {
        excludedCount_[f].resize(gm_[f].numberOfVariables());
        for(size_t var=0; var<gm_[f].numberOfVariables(); var++) {
            excludedCount_[f][var].resize( gm_.numberOfVariables( gm_.variableOfFactor(f,var) ), 0);
        }
    }
}

//********************************************

// Set
template<class GM>
void POpt_Data<GM>:: setTrue(const IndexType var, const LabelType label) {
    OPENGM_ASSERT( var   < gm_.numberOfVariables() );
    OPENGM_ASSERT( label < gm_.numberOfLabels(var) );

    optimal_[var] = true;
    labeling_[var]  = label;

    OPENGM_ASSERT(partialOptimality_[var][label] != false);
    partialOptimality_[var][label] = true;

    for(size_t i=0; i<label; ++i) {
        OPENGM_ASSERT(partialOptimality_[var][i] != true);
        partialOptimality_[var][i] = false;
    }
    for(size_t i=label+1; i<partialOptimality_[var].size(); ++i) {
        OPENGM_ASSERT(partialOptimality_[var][i] != true);
        partialOptimality_[var][i] = false;
    }
    countFalse_[var] = partialOptimality_[var].size()-1;
}

template<class GM>
void POpt_Data<GM>::setFalse(IndexType var, LabelType label) {
    OPENGM_ASSERT( var   < gm_.numberOfVariables() );
    OPENGM_ASSERT( label < gm_.numberOfLabels(var) );

    if( optimal_[var] ) {
        OPENGM_ASSERT(labeling_[var] != label);
    } else {
        OPENGM_ASSERT(partialOptimality_[var][label] != true);
        partialOptimality_[var][label] = false;
        if(++countFalse_[var] == partialOptimality_[var].size()-1) {
            for(size_t i=0; i<partialOptimality_[var].size(); ++i) {
                if( partialOptimality_[var][i] != false ) {
                    partialOptimality_[var][i] = true;
                    optimal_[var]              = true;
                    labeling_[var]             = i;
                    break;
                }
            }
        }
    }
}

template<class GM>
void POpt_Data<GM>::setFalse(IndexType f, const std::vector<LabelType>& labeling) {
    OPENGM_ASSERT( f < gm_.numberOfFactors() );
    OPENGM_ASSERT( labeling.size() == gm_[f].numberOfVariables() );
    bool labelingTrue = true;
    for(size_t var=0; var<gm_[f].numberOfVariables(); var++) {
        OPENGM_ASSERT( labeling[var] < gm_.numberOfVariables( gm_.variableOfFactor(f,var) ) );
        OPENGM_ASSERT( getPOpt(gm_.variableOfFactor(f,var), labeling[var]) != Tribool::False );
        getPOpt( gm_.variableOfFactor(f,var), labeling[var] ) == Tribool::True ? labelingTrue= true : labelingTrue = false;
    }
    OPENGM_ASSERT( labelingTrue == false);
    for(size_t e=0; e<excludedLabelings_[f].size(); e++) {
        OPENGM_ASSERT( std::equal(labeling.begin(), labeling.end(), excludedLabelings_[f][e].begin()) );
    }

    excludedLabelings_[f].push(labeling);

    // check for implications: e.g. if all labels (i,1), ... (i,n) are excluded, exclude label i for the first variables as well.
    for(size_t var=0; var<gm_[f].numberOfVariables(); var++) {
        excludedCount_[f][var][ labeling[var] ]++;
    }
    for(size_t var=0; var<gm_[f].numberOfVariables(); var++) {
        if(excludedCount_[f][var][ labeling[var] ] == gm_[f].size()/gm_.numberOfLabels(gm_.variableOfFactor(f,var)) ) {
            // label can be excluded
            setFalse(gm_.variableOfFactor(f,var), labeling[var]);
        }
    }
}

// Get Partial Optimality
template<class GM>
Tribool POpt_Data<GM>::getPOpt(const IndexType var, const LabelType label) const {
    OPENGM_ASSERT( var   < gm_.numberOfVariables() );
    OPENGM_ASSERT( label < gm_.numberOfLabels(var) );
    return partialOptimality_[var][label];
}

template<class GM>
std::vector<opengm::Tribool> POpt_Data<GM>::getPOpt(const IndexType var) const {
    OPENGM_ASSERT( var<gm_.numberOfVariables() );
    return partialOptimality_[var];
}

template<class GM>
typename GM::ValueType POpt_Data<GM>::getPOpt() const {
   size_t noExcludedLabels = 0;
   size_t noLabels = 0;
   for(size_t var=0; var<gm_.numberOfVariables(); var++) {
      noLabels += gm_.numberOfLabels(var);
      for(size_t i=0; i<gm_.numberOfLabels(var); i++) {
         if(getPOpt(var,i) == false)
            noExcludedLabels++;
      }
   }
   OPENGM_ASSERT(noLabels > 0);
   OPENGM_ASSERT(noExcludedLabels < noLabels);
   ValueType p = ValueType(noExcludedLabels) / ValueType(noLabels - gm_.numberOfVariables());

   OPENGM_ASSERT(p <= 1.0);
   return p;
}

// Get Optimality
template<class GM>
bool POpt_Data<GM>::getOpt(const IndexType var) const {
    OPENGM_ASSERT( var<gm_.numberOfVariables() );
    return optimal_[var];
}

template<class GM>
const std::vector<bool>& POpt_Data<GM>::getOpt() const {
    return optimal_;
}

// Get Optimal Labels
template<class GM>
typename GM::LabelType POpt_Data<GM>::get(const IndexType var) const {
    OPENGM_ASSERT( var<gm_.numberOfVariables() );
    return labeling_[var];
}

template<class GM>
void POpt_Data<GM>::get(std::vector<LabelType>& labeling) const {
    OPENGM_ASSERT(labeling.size() == gm_.numberOfVariables());
    for(IndexType var=0; var<gm_.numberOfVariables(); ++var) {
        if( optimal_[var] )
            labeling[var] = labeling_[var];
    }
}

template<class GM>
void POpt_Data<GM>::reducedGraphicalModel(ReducedGmType& reducedGm) const
{
   //Variables and their labels are included in case they are not optimal yet.

   IndexType newVariable[gm_.numberOfVariables()];
   IndexType variable = 0;

   for (IndexType v = 0; v < gm_.numberOfVariables(); v++) {
      if(!optimal_[v]) {
         newVariable[v] = variable;
         variable++;

         LabelType numLabels = 0;

         for(IndexType i = 0; i < gm_.numberOfLabels(v); i++) {
            if(!(partialOptimality_[v][i] == opengm::Tribool::False))
               numLabels++;
         }
         OPENGM_ASSERT(numLabels>1);
         reducedGm.addVariable(numLabels);
      }
   }

   //factors will be included in case one of their variables is not optimal yet.
   for (IndexType f = 0; f < gm_.numberOfFactors(); f++) {
      bool insert_f = false;
      size_t numVariables = 0;
      std::vector<IndexType> variablesOfFactor;
      std::vector<IndexType> numLabels;
      IndexType numLabelComb = 1;

      for(IndexType v = 0; v < gm_[f].numberOfVariables(); v++){
         if(!optimal_[gm_[f].variableIndex(v)]){
            insert_f = true;
            numVariables++;
            variablesOfFactor.std::vector<IndexType>::push_back(newVariable[gm_[f].variableIndex(v)]);
            numLabels.std::vector<IndexType>::push_back(reducedGm.numberOfLabels(newVariable[gm_[f].variableIndex(v)]));
            numLabelComb *= numLabels.std::vector<IndexType>::back();
         }
      }

      if(insert_f){
         ExplicitFunction g(numLabels.std::vector<IndexType>::begin(), numLabels.std::vector<IndexType>::end());
         LabelType reducedShape [numVariables];
         LabelType shape [gm_[f].numberOfVariables()];

         for(size_t v = 0; v < numVariables; v++){
            reducedShape[v] = 0;
         }

         for(size_t v = 0; v < gm_[f].numberOfVariables(); v++){
            if(optimal_[gm_[f].variableIndex(v)]){
               shape[v] = labeling_[gm_[f].variableIndex(v)];
            }else{
               shape[v] = 0;
            }
         }
         g(reducedShape) = gm_[f](shape);

         for(size_t comb = 1; comb < numLabelComb; comb++){
            //next label combination
            IndexType nextStep = 0;
            while(reducedShape[nextStep] = numLabels[nextStep] && nextStep < numVariables-1){
               nextStep++;
            }
            reducedShape[nextStep]++;

            size_t index = 0;
            for(size_t v = 0; v < nextStep; v++){
               reducedShape[v] = 0;

               while(optimal_[gm_[f].variableIndex(index)])
                  index++;

               size_t label = 0;
               while(partialOptimality_[gm_[f].variableIndex(index)][label] == opengm::Tribool::False)
                  label++;

               shape[index] = label;
               index++;
            }

            while(optimal_[gm_[f].variableIndex(index)]){
               index++;
            }
            shape[index]++;
            while(partialOptimality_[gm_[f].variableIndex(index)][shape[index]] == opengm::Tribool::False)
               shape[index]++;

            g(reducedShape) = gm_[f](shape);
         }

         typename ReducedGmType::FunctionIdentifier id = reducedGm.addFunction(g);

         reducedGm.addFactor(id, variablesOfFactor.std::vector<IndexType>::begin(), variablesOfFactor.std::vector<IndexType>::end());
      }
   }
}

template<class GM>
void POpt_Data<GM>::OriginalToReducedLabeling(const std::vector<LabelType>& lOrig, std::vector<LabelType>& lRed) const
{
}

template<class GM>
void POpt_Data<GM>::ReducedToOriginalLabeling(std::vector<LabelType>& lOrig, const std::vector<LabelType>& lRed) const
{
}

} // namespace opengm

#endif // #ifndef OPENGM_POPT_DATA_HXX
<commit_msg>wrote the functions which switch reduced into nonreduced labelings and back<commit_after>#pragma once
#ifndef OPENGM_POPT_DATA_HXX
#define OPENGM_POPT_DATA_HXX

#include <vector>
//#include <string>
//#include <iostream>

#include <opengm/opengm.hxx>
#include <opengm/utilities/metaprogramming.hxx>
#include <opengm/utilities/tribool.hxx>
//#include <opengm/functions/reduced_view.hxx>
#include <opengm/functions/explicit_function.hxx>

namespace opengm {
//! [class popt_data]
/// Partial Optimaility Data (-Container)
///
/// Corresponding author: Joerg Hendrik Kappes
///
///\ingroup inference
template<class GM>
class POpt_Data {
public:
    typedef GM GraphicalModelType;
    typedef GM GmType;
    OPENGM_GM_TYPE_TYPEDEFS;

//    typedef ReducedViewFunction<GraphicalModelType>                  ReducedViewType;
    typedef opengm::ExplicitFunction<ValueType, LabelType, IndexType> ExplicitFunction;
    typedef GraphicalModel<ValueType, OperatorType, ExplicitFunction> ReducedGmType;

    POpt_Data(const GmType&);
    // Set
    void                                   setTrue(const IndexType, const LabelType);
    void                                   setFalse(const IndexType, const LabelType);
    void                                   setFalse(const IndexType factor, const std::vector<LabelType>& labeling);
    // Get Partial Optimality
    Tribool                                getPOpt(const IndexType, const LabelType) const;
    std::vector<opengm::Tribool>           getPOpt(const IndexType) const;
    ValueType                              getPOpt() const;
    // Get Optimal Certificates
    bool                                   getOpt(const IndexType) const;
    const std::vector<bool>&               getOpt() const;
    // Get Optimal Labels
    LabelType                              get(const IndexType) const;
    void                                   get(std::vector<LabelType>&) const;

    const GmType&                          graphicalModel() const {return gm_;}
    void                                   reducedGraphicalModel(ReducedGmType&) const;

    void                                   OriginalToReducedLabeling(const std::vector<LabelType>& lOrig, std::vector<LabelType>& lRed) const;
    void                                   ReducedToOriginalLabeling(std::vector<LabelType>& lOrig, const std::vector<LabelType>& lRed) const;

private:
    const GmType& gm_;
    std::vector<std::vector<opengm::Tribool> >   partialOptimality_;
    std::vector<bool>                            optimal_;
    std::vector<LabelType>                       labeling_;
    std::vector<IndexType>                       countFalse_;
    std::vector<std::vector<std::vector<LabelType> > >  excludedLabelings_; // for each factor the excluded labelings are pushed
    std::vector<std::vector<std::vector<LabelType> > > excludedCount_;
    // count for number of excluded labelings in which (variable,label) partakes
    // used for elimination of variables
};
//! [class popt_data]

//********************************************

template<class GM>
POpt_Data<GM>::POpt_Data
(
    const GmType& gm
)
    :  gm_(gm),
    partialOptimality_(std::vector<std::vector<opengm::Tribool> >(gm.numberOfVariables()) ),
    optimal_(std::vector<bool>(gm.numberOfVariables(),false)),
    labeling_(std::vector<LabelType>(gm.numberOfVariables(),0)),
    countFalse_(std::vector<IndexType>(gm.numberOfVariables(),0)),
    excludedLabelings_(gm.numberOfFactors()),
    excludedCount_(gm.numberOfFactors()) {

    for(IndexType var=0; var<gm_.numberOfVariables(); ++var) {
        partialOptimality_[var].resize(gm_.numberOfLabels(var),opengm::Tribool::Maybe);
    }
    for(size_t f=0; f<gm_.numberOfFactors(); f++) {
        excludedCount_[f].resize(gm_[f].numberOfVariables());
        for(size_t var=0; var<gm_[f].numberOfVariables(); var++) {
            excludedCount_[f][var].resize( gm_.numberOfVariables( gm_.variableOfFactor(f,var) ), 0);
        }
    }
}

//********************************************

// Set
template<class GM>
void POpt_Data<GM>:: setTrue(const IndexType var, const LabelType label) {
    OPENGM_ASSERT( var   < gm_.numberOfVariables() );
    OPENGM_ASSERT( label < gm_.numberOfLabels(var) );

    optimal_[var] = true;
    labeling_[var]  = label;

    OPENGM_ASSERT(partialOptimality_[var][label] != false);
    partialOptimality_[var][label] = true;

    for(size_t i=0; i<label; ++i) {
        OPENGM_ASSERT(partialOptimality_[var][i] != true);
        partialOptimality_[var][i] = false;
    }
    for(size_t i=label+1; i<partialOptimality_[var].size(); ++i) {
        OPENGM_ASSERT(partialOptimality_[var][i] != true);
        partialOptimality_[var][i] = false;
    }
    countFalse_[var] = partialOptimality_[var].size()-1;
}

template<class GM>
void POpt_Data<GM>::setFalse(IndexType var, LabelType label) {
    OPENGM_ASSERT( var   < gm_.numberOfVariables() );
    OPENGM_ASSERT( label < gm_.numberOfLabels(var) );

    if( optimal_[var] ) {
        OPENGM_ASSERT(labeling_[var] != label);
    } else {
        OPENGM_ASSERT(partialOptimality_[var][label] != true);
        partialOptimality_[var][label] = false;
        if(++countFalse_[var] == partialOptimality_[var].size()-1) {
            for(size_t i=0; i<partialOptimality_[var].size(); ++i) {
                if( partialOptimality_[var][i] != false ) {
                    partialOptimality_[var][i] = true;
                    optimal_[var]              = true;
                    labeling_[var]             = i;
                    break;
                }
            }
        }
    }
}

template<class GM>
void POpt_Data<GM>::setFalse(IndexType f, const std::vector<LabelType>& labeling) {
    OPENGM_ASSERT( f < gm_.numberOfFactors() );
    OPENGM_ASSERT( labeling.size() == gm_[f].numberOfVariables() );
    bool labelingTrue = true;
    for(size_t var=0; var<gm_[f].numberOfVariables(); var++) {
        OPENGM_ASSERT( labeling[var] < gm_.numberOfVariables( gm_.variableOfFactor(f,var) ) );
        OPENGM_ASSERT( getPOpt(gm_.variableOfFactor(f,var), labeling[var]) != Tribool::False );
        getPOpt( gm_.variableOfFactor(f,var), labeling[var] ) == Tribool::True ? labelingTrue= true : labelingTrue = false;
    }
    OPENGM_ASSERT( labelingTrue == false);
    for(size_t e=0; e<excludedLabelings_[f].size(); e++) {
        OPENGM_ASSERT( std::equal(labeling.begin(), labeling.end(), excludedLabelings_[f][e].begin()) );
    }

    excludedLabelings_[f].push(labeling);

    // check for implications: e.g. if all labels (i,1), ... (i,n) are excluded, exclude label i for the first variables as well.
    for(size_t var=0; var<gm_[f].numberOfVariables(); var++) {
        excludedCount_[f][var][ labeling[var] ]++;
    }
    for(size_t var=0; var<gm_[f].numberOfVariables(); var++) {
        if(excludedCount_[f][var][ labeling[var] ] == gm_[f].size()/gm_.numberOfLabels(gm_.variableOfFactor(f,var)) ) {
            // label can be excluded
            setFalse(gm_.variableOfFactor(f,var), labeling[var]);
        }
    }
}

// Get Partial Optimality
template<class GM>
Tribool POpt_Data<GM>::getPOpt(const IndexType var, const LabelType label) const {
    OPENGM_ASSERT( var   < gm_.numberOfVariables() );
    OPENGM_ASSERT( label < gm_.numberOfLabels(var) );
    return partialOptimality_[var][label];
}

template<class GM>
std::vector<opengm::Tribool> POpt_Data<GM>::getPOpt(const IndexType var) const {
    OPENGM_ASSERT( var<gm_.numberOfVariables() );
    return partialOptimality_[var];
}

template<class GM>
typename GM::ValueType POpt_Data<GM>::getPOpt() const {
   size_t noExcludedLabels = 0;
   size_t noLabels = 0;
   for(size_t var=0; var<gm_.numberOfVariables(); var++) {
      noLabels += gm_.numberOfLabels(var);
      for(size_t i=0; i<gm_.numberOfLabels(var); i++) {
         if(getPOpt(var,i) == false)
            noExcludedLabels++;
      }
   }
   OPENGM_ASSERT(noLabels > 0);
   OPENGM_ASSERT(noExcludedLabels < noLabels);
   ValueType p = ValueType(noExcludedLabels) / ValueType(noLabels - gm_.numberOfVariables());

   OPENGM_ASSERT(p <= 1.0);
   return p;
}

// Get Optimality
template<class GM>
bool POpt_Data<GM>::getOpt(const IndexType var) const {
    OPENGM_ASSERT( var<gm_.numberOfVariables() );
    return optimal_[var];
}

template<class GM>
const std::vector<bool>& POpt_Data<GM>::getOpt() const {
    return optimal_;
}

// Get Optimal Labels
template<class GM>
typename GM::LabelType POpt_Data<GM>::get(const IndexType var) const {
    OPENGM_ASSERT( var<gm_.numberOfVariables() );
    return labeling_[var];
}

template<class GM>
void POpt_Data<GM>::get(std::vector<LabelType>& labeling) const {
    OPENGM_ASSERT(labeling.size() == gm_.numberOfVariables());
    for(IndexType var=0; var<gm_.numberOfVariables(); ++var) {
        if( optimal_[var] )
            labeling[var] = labeling_[var];
    }
}

template<class GM>
void POpt_Data<GM>::reducedGraphicalModel(ReducedGmType& reducedGm) const
{
   //Variables and their labels are included in case they are not optimal yet.

   IndexType newVariable[gm_.numberOfVariables()];
   IndexType variable = 0;

   for (IndexType v = 0; v < gm_.numberOfVariables(); v++) {
      if(!optimal_[v]) {
         newVariable[v] = variable;
         variable++;

         LabelType numLabels = 0;

         for(IndexType i = 0; i < gm_.numberOfLabels(v); i++) {
            if(!(partialOptimality_[v][i] == opengm::Tribool::False))
               numLabels++;
         }
         OPENGM_ASSERT(numLabels>1);
         reducedGm.addVariable(numLabels);
      }
   }

   //factors will be included in case one of their variables is not optimal yet.
   for (IndexType f = 0; f < gm_.numberOfFactors(); f++) {
      bool insert_f = false;
      size_t numVariables = 0;
      std::vector<IndexType> variablesOfFactor;
      std::vector<IndexType> numLabels;
      IndexType numLabelComb = 1;

      for(IndexType v = 0; v < gm_[f].numberOfVariables(); v++){
         if(!optimal_[gm_[f].variableIndex(v)]){
            insert_f = true;
            numVariables++;
            variablesOfFactor.std::vector<IndexType>::push_back(newVariable[gm_[f].variableIndex(v)]);
            numLabels.std::vector<IndexType>::push_back(reducedGm.numberOfLabels(newVariable[gm_[f].variableIndex(v)]));
            numLabelComb *= numLabels.std::vector<IndexType>::back();
         }
      }

      if(insert_f){
         ExplicitFunction g(numLabels.std::vector<IndexType>::begin(), numLabels.std::vector<IndexType>::end());
         LabelType reducedShape [numVariables];
         LabelType shape [gm_[f].numberOfVariables()];

         for(size_t v = 0; v < numVariables; v++){
            reducedShape[v] = 0;
         }

         for(size_t v = 0; v < gm_[f].numberOfVariables(); v++){
            if(optimal_[gm_[f].variableIndex(v)]){
               shape[v] = labeling_[gm_[f].variableIndex(v)];
            }else{
               shape[v] = 0;
            }
         }
         g(reducedShape) = gm_[f](shape);

         for(size_t comb = 1; comb < numLabelComb; comb++){
            //next label combination
            IndexType nextStep = 0;
            while(reducedShape[nextStep] = numLabels[nextStep] && nextStep < numVariables-1){
               nextStep++;
            }
            reducedShape[nextStep]++;

            size_t index = 0;
            for(size_t v = 0; v < nextStep; v++){
               reducedShape[v] = 0;

               while(optimal_[gm_[f].variableIndex(index)])
                  index++;

               size_t label = 0;
               while(partialOptimality_[gm_[f].variableIndex(index)][label] == opengm::Tribool::False)
                  label++;

               shape[index] = label;
               index++;
            }

            while(optimal_[gm_[f].variableIndex(index)]){
               index++;
            }
            shape[index]++;
            while(partialOptimality_[gm_[f].variableIndex(index)][shape[index]] == opengm::Tribool::False)
               shape[index]++;

            g(reducedShape) = gm_[f](shape);
         }

         typename ReducedGmType::FunctionIdentifier id = reducedGm.addFunction(g);

         reducedGm.addFactor(id, variablesOfFactor.std::vector<IndexType>::begin(), variablesOfFactor.std::vector<IndexType>::end());
      }
   }
}

template<class GM>
void POpt_Data<GM>::OriginalToReducedLabeling(const std::vector<LabelType>& lOrig, std::vector<LabelType>& lRed) const
{
    if(lOrig.std::vector<LabelType>::size() == gm_.numberOfVariables() && lRed.std::vector<LabelType>::empty())
    {
        for(size_t origIndex = 0; origIndex < gm_.numberOfVariables(); origIndex++)
        {
            if(optimal_[origIndex])
            {
              if(!lOrig[origIndex] == labeling_[origIndex])
              {
                  std::cout << "ERROR: The given labeling cannot be optimal." << std::endl;
                  return;
              }
            } else {
              lRed.std::vector<LabelType>::push_back(lOrig[origIndex]);
            }
        }
    }
}

template<class GM>
void POpt_Data<GM>::ReducedToOriginalLabeling(std::vector<LabelType>& lOrig, const std::vector<LabelType>& lRed) const
{
    size_t redIndex = 0;

    if(lOrig.std::vector<LabelType>::empty())
    {
        for(size_t origIndex = 0; origIndex < gm_.numberOfVariables(); origIndex++)
        {
            if(optimal_[origIndex])
            {
                lOrig.std::vector<LabelType>::push_back(labeling_[origIndex]);
            } else {
                lOrig.std::vector<LabelType>::push_back(lRed[redIndex]);
                redIndex++;
            }
        }
    }
}

} // namespace opengm

#endif // #ifndef OPENGM_POPT_DATA_HXX
<|endoftext|>


<commit_before>using namespace std;

#include <algorithm>    // std::max
#include "IntMap.h"
#include "IntStack.h"

namespace iProlog
{
	IntMap::IntMap(int const size, float const fillFactor) : m_fillFactor(fillFactor)
	{
	  InitializeInstanceFields();
	  if (fillFactor <= 0 || fillFactor >= 1)
	  {
		throw invalid_argument("FillFactor must be in (0, 1)");
	  }
	  if (size <= 0)
	  {
		throw invalid_argument("Size must be positive!");
	  }
	  const int capacity = arraySize(size, fillFactor);
	  m_mask = capacity - 1;
	  m_mask2 = capacity * 2 - 1;

	  m_data = std::vector<int>(capacity * 2);
	  m_threshold = static_cast<int>(capacity * fillFactor);
	}

	int IntMap::get(int const key)
	{
	  int ptr = (phiMix(key) & m_mask) << 1;

	  if (key == FREE_KEY)
	  {
		return m_hasFreeKey ? m_freeValue : NO_VALUE;
	  }

	  int k = m_data[ptr];

	  if (k == FREE_KEY)
	  {
		return NO_VALUE; //end of chain already
	  }
	  if (k == key) //we check FREE prior to this call
	  {
		return m_data[ptr + 1];
	  }

	  while (true)
	  {
		ptr = ptr + 2 & m_mask2; //that's next index
		k = m_data[ptr];
		if (k == FREE_KEY)
		{
		  return NO_VALUE;
		}
		if (k == key)
		{
		  return m_data[ptr + 1];
		}
	  }
	}

	bool IntMap::contains(int const key)
	{
	  return NO_VALUE != get(key);
	}

	bool IntMap::add(int const key)
	{
	  return NO_VALUE != put(key, 666);
	}

	bool IntMap::delete_Renamed(int const key)
	{
	  return NO_VALUE != remove(key);
	}

	bool IntMap::isEmpty()
	{
	  return 0 == m_size;
	}

	void IntMap::intersect0(IntMap *const m, std::vector<IntMap*> &maps, std::vector<IntMap*> &vmaps, IntStack *const r)
	{
	  const std::vector<int> data = m->m_data;
	  for (int k = 0; k < data.size(); k += 2)
	  {
		bool found = true;
		const int key = data[k];
		if (FREE_KEY == key)
		{
		  continue;
		}
		for (int i = 1; i < maps.size(); i++)
		{
		  IntMap * const map = maps[i];
		  const int val = map->get(key);

		  if (NO_VALUE == val)
		  {
			IntMap * const vmap = vmaps[i];
			const int vval = vmap->get(key);
			if (NO_VALUE == vval)
			{
			  found = false;
			  break;
			}
		  }
		}
		if (found)
		{
		  r->push(key);
		}
	  }
	}

	IntStack *IntMap::intersect(std::vector<IntMap*> &maps, std::vector<IntMap*> &vmaps)
	{
	  IntStack * const r = new IntStack();

	  intersect0(maps[0], maps, vmaps, r);
	  intersect0(vmaps[0], maps, vmaps, r);
	  return r;
	}

	int IntMap::put(int const key, int const value)
	{
	  if (key == FREE_KEY)
	  {
		const int ret = m_freeValue;
		if (!m_hasFreeKey)
		{
		  ++m_size;
		}
		m_hasFreeKey = true;
		m_freeValue = value;
		return ret;
	  }

	  int ptr = (phiMix(key) & m_mask) << 1;
	  int k = m_data[ptr];
	  if (k == FREE_KEY) //end of chain already
	  {
		m_data[ptr] = key;
		m_data[ptr + 1] = value;
		if (m_size >= m_threshold)
		{
		  rehash(m_data.size() * 2); //size is set inside
		}
		else
		{
		  ++m_size;
		}
		return NO_VALUE;
	  }
	  else if (k == key) //we check FREE prior to this call
	  {
		const int ret = m_data[ptr + 1];
		m_data[ptr + 1] = value;
		return ret;
	  }

	  while (true)
	  {
		ptr = ptr + 2 & m_mask2; //that's next index calculation
		k = m_data[ptr];
		if (k == FREE_KEY)
		{
		  m_data[ptr] = key;
		  m_data[ptr + 1] = value;
		  if (m_size >= m_threshold)
		  {
			rehash(m_data.size() * 2); //size is set inside
		  }
		  else
		  {
			++m_size;
		  }
		  return NO_VALUE;
		}
		else if (k == key)
		{
		  const int ret = m_data[ptr + 1];
		  m_data[ptr + 1] = value;
		  return ret;
		}
	  }
	}

	int IntMap::remove(int const key)
	{
	  if (key == FREE_KEY)
	  {
		if (!m_hasFreeKey)
		{
		  return NO_VALUE;
		}
		m_hasFreeKey = false;
		--m_size;
		return m_freeValue; //value is not cleaned
	  }

	  int ptr = (phiMix(key) & m_mask) << 1;
	  int k = m_data[ptr];
	  if (k == key) //we check FREE prior to this call
	  {
		const int res = m_data[ptr + 1];
		shiftKeys(ptr);
		--m_size;
		return res;
	  }
	  else if (k == FREE_KEY)
	  {
		return NO_VALUE; //end of chain already
	  }
	  while (true)
	  {
		ptr = ptr + 2 & m_mask2; //that's next index calculation
		k = m_data[ptr];
		if (k == key)
		{
		  const int res = m_data[ptr + 1];
		  shiftKeys(ptr);
		  --m_size;
		  return res;
		}
		else if (k == FREE_KEY)
		{
		  return NO_VALUE;
		}
	  }
	}

	int IntMap::shiftKeys(int pos)
	{
	  // Shift entries with the same hash.
	  int last, slot;
	  int k;
	  std::vector<int> data = m_data;
	  while (true)
	  {
		pos = (last = pos) + 2 & m_mask2;
		while (true)
		{
		  if ((k = data[pos]) == FREE_KEY)
		  {
			data[last] = FREE_KEY;
			return last;
		  }
		  slot = (phiMix(k) & m_mask) << 1; //calculate the starting slot for the current key
		  if (last <= pos ? last >= slot || slot > pos : last >= slot && slot > pos)
		  {
			break;
		  }
		  pos = pos + 2 & m_mask2; //go to the next entry
		}
		data[last] = k;
		data[last + 1] = data[pos + 1];
	  }
	}

	int IntMap::size()
	{
	  return m_size;
	}

	void IntMap::rehash(int const newCapacity)
	{
	  m_threshold = static_cast<int>(newCapacity / 2 * m_fillFactor);
	  m_mask = newCapacity / 2 - 1;
	  m_mask2 = newCapacity - 1;

	  const int oldCapacity = m_data.size();
	  const std::vector<int> oldData = m_data;

	  m_data = std::vector<int>(newCapacity);
	  m_size = m_hasFreeKey ? 1 : 0;

	  for (int i = 0; i < oldCapacity; i += 2)
	  {
		const int oldKey = oldData[i];
		if (oldKey != FREE_KEY)
		{
		  put(oldKey, oldData[i + 1]);
		}
	  }
	}

	long long IntMap::nextPowerOfTwo(long long x)
	{
	  if (x == 0)
	  {
		return 1;
	  }
	  x--;
	  x |= x >> 1;
	  x |= x >> 2;
	  x |= x >> 4;
	  x |= x >> 8;
	  x |= x >> 16;
	  return (x | x >> 32) + 1;
	}

	int IntMap::arraySize(int const expected, float const f)
	{
	  const long long s = max(2LL, nextPowerOfTwo(static_cast<long long>(ceil(expected / f))));
	  if (s > 1 << 30)
	  {
		throw invalid_argument("Too large (" + StringHelper::toString(expected) + " expected elements with load factor " + StringHelper::toString(f) + ")");
	  }
	  return static_cast<int>(s);
	}

	int IntMap::phiMix(int const x)
	{
	  const int h = x * INT_PHI;
	  return h ^ h >> 16;
	}

	string IntMap::toString()
	{
	  StringBuilder * const b = new StringBuilder("{");
	  const int l = m_data.size();
	  bool first = true;
	  for (int i = 0; i < l; i += 2)
	  {
		const int v = m_data[i];
		if (v != FREE_KEY)
		{
		  if (!first)
		  {
			b->append(',');
		  }
		  first = false;
		  b->append(v - 1);
		}
	  }
	  b->append("}");
	  return b->toString();
	}

	void IntMap::InitializeInstanceFields()
	{
		m_hasFreeKey = false;
		m_freeValue = 0;
		m_threshold = 0;
		m_size = 0;
		m_mask = 0;
		m_mask2 = 0;
	}
}
<commit_msg>Delete IntMap.cpp<commit_after><|endoftext|>


<commit_before>#include "elevated.hpp"
#include <sstream>
#include <sys/cygwin.h>
#include "winerror.hpp"

namespace cygscript {

bool ElevatedProcess::isAdmin() const {
	ImpersonationToken it;
	AdminSID sid;
	ACL acl(sid);
	AdminACL adminAcl(acl, sid);
	return adminAcl.hasAccess(it);
}

HINSTANCE ElevatedProcess::startElevated(int argc, char* const argv[]) {
	char winpath[MAX_PATH + 1];
	char windir[MAX_PATH + 1];
	int i;
	std::stringstream ss;
	for (i = 1; i < argc; ++i) {
		ss << argv[i] << " ";
	}
	std::string args = ss.str();
	args.pop_back();
	if (0 != cygwin_conv_path(
			CCP_POSIX_TO_WIN_A, argv[0], winpath, sizeof(winpath))) {
		throw std::runtime_error(strerror(errno));
	}
	if (0 != cygwin_conv_path(
			CCP_POSIX_TO_WIN_A, "/bin", windir, sizeof(windir))) {
		throw std::runtime_error(strerror(errno));
	}
	HINSTANCE inst = ShellExecuteA(
		NULL, "runas", winpath, args.c_str(), windir, SW_SHOWNORMAL);
	if ((int)(intptr_t)inst <= 32) {
		THROW_ERROR_CODE("Failed to start elevated process",
		                 (int)(intptr_t)inst);
	}
	return inst;
}

ElevatedProcess::ImpersonationToken::ImpersonationToken() {
	HANDLE hToken;
	if (!OpenThreadToken(
			GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &hToken)) {
		if (!OpenProcessToken(
				GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) {
			THROW_LAST_ERROR("Failed to open process token");
		}
	}
	BOOL ret = DuplicateToken(hToken, SecurityImpersonation, &_hToken);
	DWORD err = GetLastError();
	CloseHandle(hToken);
	if (!ret) {
		THROW_ERROR_CODE("Failed to duplicate process token", err);
	}
}

ElevatedProcess::ImpersonationToken::~ImpersonationToken() {
	if (_hToken) {
		CloseHandle(_hToken);
	}
}

ElevatedProcess::ImpersonationToken::operator HANDLE() const {
	return _hToken;
}

ElevatedProcess::AdminSID::AdminSID() {
	SID_IDENTIFIER_AUTHORITY sidAuthority = SECURITY_NT_AUTHORITY;
	if (!AllocateAndInitializeSid(
			&sidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &_sid)) {
		THROW_LAST_ERROR("Failed to initialize Admin SID");
	}
}

ElevatedProcess::AdminSID::~AdminSID() {
	if (_sid) {
		FreeSid(_sid);
	}
}

ElevatedProcess::AdminSID::operator PSID() const {
	return _sid;
}

ElevatedProcess::ACL::ACL(PSID const& psid) {
	_size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
	        GetLengthSid(psid) - sizeof(DWORD);
	_acl = (PACL)LocalAlloc(LPTR, _size);
	if (!_acl) {
		THROW_LAST_ERROR("Failed to allocate ACL");
	}
}

ElevatedProcess::ACL::~ACL() {
	if (_acl) {
		LocalFree(_acl);
	}
}

size_t ElevatedProcess::ACL::size() const {
	return _size;
}

ElevatedProcess::ACL::operator PACL() const {
	return _acl;
}

ElevatedProcess::AdminACL::AdminACL(ACL const& acl, AdminSID const& sid) {
	if (!InitializeSecurityDescriptor(&_sd, SECURITY_DESCRIPTOR_REVISION)) {
		THROW_LAST_ERROR("InitializeSecurityDescriptor");
	}
	if (!InitializeAcl(acl, (DWORD)acl.size(), ACL_REVISION2)) {
		THROW_LAST_ERROR("InitializeAcl");
	}
	if (!AddAccessAllowedAce(
			acl, ACL_REVISION2, FILE_READ_ACCESS | FILE_WRITE_ACCESS, sid)) {
		THROW_LAST_ERROR("AddAccessAllowedAce");
	}
	if (!SetSecurityDescriptorDacl(&_sd, TRUE, acl, FALSE)) {
		THROW_LAST_ERROR("SetSecurityDescriptorDacl");
	}
	SetSecurityDescriptorGroup(&_sd, sid, FALSE);
	SetSecurityDescriptorOwner(&_sd, sid, FALSE);
	if (!IsValidSecurityDescriptor(&_sd)) {
		throw std::runtime_error("Invalid security descriptor");
	}
}

ElevatedProcess::AdminACL::~AdminACL() {
}

bool ElevatedProcess::AdminACL::hasAccess(
	ImpersonationToken const& token) const {
	GENERIC_MAPPING gm;
	gm.GenericRead = FILE_READ_ACCESS;
	gm.GenericWrite = FILE_WRITE_ACCESS;
	gm.GenericExecute = 0;
	gm.GenericAll = FILE_READ_ACCESS | FILE_WRITE_ACCESS;
	PRIVILEGE_SET ps;
	DWORD size = sizeof(ps);
	DWORD access;
	BOOL status;
	if (!AccessCheck(
			(const PSECURITY_DESCRIPTOR)&_sd,
			token, FILE_READ_ACCESS,
			&gm, &ps, &size, &access, &status)) {
		THROW_LAST_ERROR("Failed to check access rights");
	}
	return status == TRUE ? true : false;
}

}
<commit_msg>Fix process elevation path issue<commit_after>#include "elevated.hpp"
#include <sstream>
#include <sys/cygwin.h>
#include "message.hpp"
#include "winerror.hpp"

namespace cygscript {

bool ElevatedProcess::isAdmin() const {
	ImpersonationToken it;
	AdminSID sid;
	ACL acl(sid);
	AdminACL adminAcl(acl, sid);
	return adminAcl.hasAccess(it);
}

HINSTANCE ElevatedProcess::startElevated(int argc, char* const argv[]) {
	char winpath[MAX_PATH + 1];
	char windir[MAX_PATH + 1];
	std::stringstream ss;
	for (int i = 1; i < argc; ++i) {
		ss << argv[i] << " ";
	}
	std::string args = ss.str();
	args.pop_back();
	if (0 != cygwin_conv_path(
			CCP_POSIX_TO_WIN_A | CCP_RELATIVE, argv[0], winpath,
			sizeof(winpath))) {
		throw std::runtime_error(strerror(errno));
	}
	if (0 != cygwin_conv_path(
			CCP_POSIX_TO_WIN_A, "/bin", windir, sizeof(windir))) {
		throw std::runtime_error(strerror(errno));
	}
	HINSTANCE inst = ShellExecuteA(
		NULL, "runas", winpath, args.c_str(), windir, SW_SHOWNORMAL);
	if ((int)(intptr_t)inst <= 32) {
		THROW_ERROR_CODE("Failed to start elevated process",
		                 (int)(intptr_t)inst);
	}
	return inst;
}

ElevatedProcess::ImpersonationToken::ImpersonationToken() {
	HANDLE hToken;
	if (!OpenThreadToken(
			GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &hToken)) {
		if (!OpenProcessToken(
				GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) {
			THROW_LAST_ERROR("Failed to open process token");
		}
	}
	BOOL ret = DuplicateToken(hToken, SecurityImpersonation, &_hToken);
	DWORD err = GetLastError();
	CloseHandle(hToken);
	if (!ret) {
		THROW_ERROR_CODE("Failed to duplicate process token", err);
	}
}

ElevatedProcess::ImpersonationToken::~ImpersonationToken() {
	if (_hToken) {
		CloseHandle(_hToken);
	}
}

ElevatedProcess::ImpersonationToken::operator HANDLE() const {
	return _hToken;
}

ElevatedProcess::AdminSID::AdminSID() {
	SID_IDENTIFIER_AUTHORITY sidAuthority = SECURITY_NT_AUTHORITY;
	if (!AllocateAndInitializeSid(
			&sidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &_sid)) {
		THROW_LAST_ERROR("Failed to initialize Admin SID");
	}
}

ElevatedProcess::AdminSID::~AdminSID() {
	if (_sid) {
		FreeSid(_sid);
	}
}

ElevatedProcess::AdminSID::operator PSID() const {
	return _sid;
}

ElevatedProcess::ACL::ACL(PSID const& psid) {
	_size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
	        GetLengthSid(psid) - sizeof(DWORD);
	_acl = (PACL)LocalAlloc(LPTR, _size);
	if (!_acl) {
		THROW_LAST_ERROR("Failed to allocate ACL");
	}
}

ElevatedProcess::ACL::~ACL() {
	if (_acl) {
		LocalFree(_acl);
	}
}

size_t ElevatedProcess::ACL::size() const {
	return _size;
}

ElevatedProcess::ACL::operator PACL() const {
	return _acl;
}

ElevatedProcess::AdminACL::AdminACL(ACL const& acl, AdminSID const& sid) {
	if (!InitializeSecurityDescriptor(&_sd, SECURITY_DESCRIPTOR_REVISION)) {
		THROW_LAST_ERROR("InitializeSecurityDescriptor");
	}
	if (!InitializeAcl(acl, (DWORD)acl.size(), ACL_REVISION2)) {
		THROW_LAST_ERROR("InitializeAcl");
	}
	if (!AddAccessAllowedAce(
			acl, ACL_REVISION2, FILE_READ_ACCESS | FILE_WRITE_ACCESS, sid)) {
		THROW_LAST_ERROR("AddAccessAllowedAce");
	}
	if (!SetSecurityDescriptorDacl(&_sd, TRUE, acl, FALSE)) {
		THROW_LAST_ERROR("SetSecurityDescriptorDacl");
	}
	SetSecurityDescriptorGroup(&_sd, sid, FALSE);
	SetSecurityDescriptorOwner(&_sd, sid, FALSE);
	if (!IsValidSecurityDescriptor(&_sd)) {
		throw std::runtime_error("Invalid security descriptor");
	}
}

ElevatedProcess::AdminACL::~AdminACL() {
}

bool ElevatedProcess::AdminACL::hasAccess(
	ImpersonationToken const& token) const {
	GENERIC_MAPPING gm;
	gm.GenericRead = FILE_READ_ACCESS;
	gm.GenericWrite = FILE_WRITE_ACCESS;
	gm.GenericExecute = 0;
	gm.GenericAll = FILE_READ_ACCESS | FILE_WRITE_ACCESS;
	PRIVILEGE_SET ps;
	DWORD size = sizeof(ps);
	DWORD access;
	BOOL status;
	if (!AccessCheck(
			(const PSECURITY_DESCRIPTOR)&_sd,
			token, FILE_READ_ACCESS,
			&gm, &ps, &size, &access, &status)) {
		THROW_LAST_ERROR("Failed to check access rights");
	}
	return status == TRUE ? true : false;
}

}
<|endoftext|>


<commit_before>#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <cassert>
#include "machine.hpp"
#ifdef WIN32
#include <Windows.h>
#include <conio.h>
#endif
using namespace std;
using namespace dcpupp;

static void printHelp()
{
	cout << "" << endl;
}

struct Options
{
	unsigned sleepMs;
	unsigned videoAddress;
	unsigned updateInterval;

	Options()
		: sleepMs(10)
		, videoAddress(32768) //0x8000
		, updateInterval(5)
	{
	}
};

int main(int argc, char **argv)
{
	const vector<string> args(argv + 1, argv + argc);

	Machine::Memory program;

	std::string programFileName;
	Options options;

	for (auto a = args.begin(); a != args.end(); ++a)
	{
		const auto &arg = *a;
		assert(!arg.empty());
		if (arg[0] == '-' &&
			arg.size() >= 2)
		{
			switch (arg[1])
			{
			case 's':
				options.sleepMs = atoi(arg.c_str() + 2);
				break;

			case 'v':
				options.videoAddress = atoi(arg.c_str() + 2);
				break;

			case 'u':
				options.updateInterval = stoi(arg.c_str() + 2);

			default:
				cerr << "Invalid option '" << arg << "'";
				break;
			}
		}
		else
		{
			programFileName = *a;
		}
	}

	if (programFileName.empty())
	{
		printHelp();
		return 0;
	}

	{
		std::ifstream programFile(programFileName.c_str(), std::ios::binary);
		if (!programFile)
		{
			cerr << "Could not open file '" << programFileName << "'" << endl;
			return 1;
		}

		program = readProgramFromFile(programFile);
	}

	Machine machine(std::move(program));

	struct DebuggingContext
	{
		Machine &machine;
		const Options &options;
		unsigned intervalCounter;
#ifdef WIN32
		HANDLE console;
#endif

		explicit DebuggingContext(Machine &machine, const Options &options)
			: machine(machine)
			, options(options)
			, intervalCounter(0)
#ifdef WIN32
			, console(GetStdHandle(STD_OUTPUT_HANDLE))
#endif
		{
		}

		void printInfo()
		{
#ifdef WIN32
			{
				COORD coord = {0, 0};
				DWORD count;
				CONSOLE_SCREEN_BUFFER_INFO csbi;
				GetConsoleScreenBufferInfo(console, &csbi);
				FillConsoleOutputCharacter(console, ' ',
					csbi.dwSize.X * csbi.dwSize.Y,
					coord, &count);
				SetConsoleCursorPosition(console, coord);
			}
#else
			write(1, "\E[H\E[2J", 7);
#endif

#ifdef WIN32
			SetConsoleTextAttribute(console,
				FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
#endif
			for (size_t i = 0; i < 8; ++i)
			{
				printf("%c: %04x, ", "ABCXYZIJ"[i], machine.registers[i]);
			}
			puts("");
			printf("SP: %04x, PC: %04x, O: %04x\n", machine.sp, machine.pc, machine.o);

			const size_t width = 32, height = 12;
			for (size_t y = 0; y < height; ++y)
			{
				for (size_t x = 0; x < width; ++x)
				{
					const size_t charAddress = options.videoAddress +
						y * width +
						x;
					const Word c = machine.memory[charAddress];

#ifdef WIN32
					SetConsoleTextAttribute(console, c >> 8);
#endif
					fputc((char)c, stdout);
					//write(1, &c, 1);
				}

				fputc('\n', stdout);
			}

			fflush(stdout);
			if (options.sleepMs)
			{
#ifdef WIN32
				Sleep(options.sleepMs);
#else
				usleep(options.sleepMs * 1000);
#endif
			}
		}

		bool startInstruction()
		{
			++intervalCounter;
			if (intervalCounter == options.updateInterval)
			{
				printInfo();
				intervalCounter = 0;
			}
			return true;
		}
	};

	DebuggingContext context(machine, options);
	machine.run(context);
}

<commit_msg>emulator output improved, timing corrected, console width and height options -w and -h<commit_after>#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <cassert>
#include "machine.hpp"
#ifdef WIN32
#include <Windows.h>
#include <conio.h>
#endif
using namespace std;
using namespace dcpupp;

static void printHelp()
{
	cout << "" << endl;
}

struct Options
{
	unsigned sleepMs;
	unsigned videoAddress;
	unsigned updateInterval;
	unsigned consoleWidth;
	unsigned consoleHeight;

	Options()
		: sleepMs(10)
		, videoAddress(32768) //0x8000
		, updateInterval(5)
		, consoleWidth(32)
		, consoleHeight(12)
	{
	}
};

int main(int argc, char **argv)
{
	const vector<string> args(argv + 1, argv + argc);

	Machine::Memory program;

	std::string programFileName;
	Options options;

	for (auto a = args.begin(); a != args.end(); ++a)
	{
		const auto &arg = *a;
		assert(!arg.empty());
		if (arg[0] == '-' &&
			arg.size() >= 2)
		{
			switch (arg[1])
			{
			case 's':
				options.sleepMs = atoi(arg.c_str() + 2);
				break;

			case 'v':
				options.videoAddress = atoi(arg.c_str() + 2);
				break;

			case 'u':
				options.updateInterval = stoi(arg.c_str() + 2);
				break;

			case 'w':
				options.consoleWidth = stoi(arg.c_str() + 2);
				break;

			case 'h':
				options.consoleHeight = stoi(arg.c_str() + 2);
				break;

			default:
				cerr << "Invalid option '" << arg << "'";
				break;
			}
		}
		else
		{
			programFileName = *a;
		}
	}

	if (programFileName.empty())
	{
		printHelp();
		return 0;
	}

	{
		std::ifstream programFile(programFileName.c_str(), std::ios::binary);
		if (!programFile)
		{
			cerr << "Could not open file '" << programFileName << "'" << endl;
			return 1;
		}

		program = readProgramFromFile(programFile);
	}

	Machine machine(std::move(program));

	struct DebuggingContext
	{
		Machine &machine;
		const Options &options;
		unsigned intervalCounter;
#ifdef WIN32
		HANDLE console;
#endif

		explicit DebuggingContext(Machine &machine, const Options &options)
			: machine(machine)
			, options(options)
			, intervalCounter(0)
#ifdef WIN32
			, console(GetStdHandle(STD_OUTPUT_HANDLE))
#endif
		{
		}

		void setDefaultTextColors()
		{
#ifdef WIN32
			SetConsoleTextAttribute(console,
				FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
#endif
		}

		void printVerticalBar()
		{
			fputc(' ', stdout);
			for (size_t x = 0; x < options.consoleWidth; ++x)
			{
				fputc('-', stdout);
			}
			fputc('\n', stdout);
		}

		void printInfo()
		{
#ifdef WIN32
			{
				COORD coord = {0, 0};
				DWORD count;
				CONSOLE_SCREEN_BUFFER_INFO csbi;
				GetConsoleScreenBufferInfo(console, &csbi);
				FillConsoleOutputCharacter(console, ' ',
					csbi.dwSize.X * csbi.dwSize.Y,
					coord, &count);
				SetConsoleCursorPosition(console, coord);
			}
#else
			write(1, "\E[H\E[2J", 7);
#endif

			setDefaultTextColors();
			printf("A: %04x, B: %04x, C: %04x\n", machine.registers[0],
				machine.registers[1], machine.registers[2]);
			printf("X: %04x, Y: %04x, Z: %04x\n", machine.registers[3],
				machine.registers[4], machine.registers[5]);
			printf("I: %04x, J: %04x\n", machine.registers[6],
				machine.registers[7]);

			puts("");
			printf("SP: %04x, PC: %04x, O: %04x\n", machine.sp, machine.pc, machine.o);

			printVerticalBar();
			for (size_t y = 0; y < options.consoleHeight; ++y)
			{
				fputc('|', stdout);
				for (size_t x = 0; x < options.consoleWidth; ++x)
				{
					const size_t charAddress = options.videoAddress +
						y * options.consoleWidth +
						x;
					const Word c = machine.memory[charAddress];

#ifdef WIN32
					SetConsoleTextAttribute(console, c >> 8);
#endif
					fputc((char)c, stdout);
				}
				setDefaultTextColors();
				fputc('|', stdout);
				fputc('\n', stdout);
			}
			printVerticalBar();
			fflush(stdout);
		}

		bool startInstruction()
		{
			++intervalCounter;
			if (intervalCounter == options.updateInterval)
			{
				printInfo();
				intervalCounter = 0;
			}

			if (options.sleepMs)
			{
#ifdef WIN32
				Sleep(options.sleepMs);
#else
				usleep(options.sleepMs * 1000);
#endif
			}
			return true;
		}
	};

	DebuggingContext context(machine, options);
	machine.run(context);
}

<|endoftext|>