<commit_before>#include <ir/index_manager/index/IndexReader.h>
#include <ir/index_manager/index/TermReader.h>
#include <ir/index_manager/index/Indexer.h>
#include <ir/index_manager/index/MultiIndexBarrelReader.h>
#include <ir/index_manager/index/IndexBarrelWriter.h>
#include <util/izene_log.h>

#include <util/ThreadModel.h>

using namespace izenelib::ir::indexmanager;

IndexReader::IndexReader(Indexer* pIndex)
        :pIndexer_(pIndex)
        ,pBarrelsInfo_(NULL)
        ,pBarrelReader_(NULL)
        ,pDocFilter_(NULL)
        ,pDocLengthReader_(NULL)
{
    pBarrelsInfo_ = pIndexer_->getBarrelsInfo();

    Directory* pDirectory = pIndexer_->getDirectory();
    if(pDirectory->fileExists(DELETED_DOCS))
    {
        pDocFilter_ = new BitVector;
        pDocFilter_->read(pDirectory, DELETED_DOCS);
    }
    ///todo since only one collection is used within indexmanager, so we only get collectionmeta for one collection to build
    ///up the DocLengthReader
    if(pIndexer_->getIndexManagerConfig()->indexStrategy_.indexDocLength_)
        pDocLengthReader_ = new DocLengthReader(
                                pIndexer_->getCollectionsMeta().begin()->second.getDocumentSchema(),
                                pIndexer_->getDirectory());
}

IndexReader::~IndexReader()
{
    if (pBarrelReader_)
    {
        delete pBarrelReader_;
        pBarrelReader_ = NULL;
    }

    flush();
    if(pDocFilter_) delete pDocFilter_;
    pDocFilter_ = NULL;

    if(pDocLengthReader_)
    {
        delete pDocLengthReader_;
        pDocLengthReader_ = NULL;
    }
}

void IndexReader::delDocFilter()
{
    DVLOG(2) << "=> IndexReader::delDocFilter(), pDocFilter_: " << pDocFilter_;
    if(pDocFilter_)
    {
        if(pIndexer_->getDirectory()->fileExists(DELETED_DOCS))
            pIndexer_->getDirectory()->deleteFile(DELETED_DOCS);
        pDocFilter_->clear();
    }
    DVLOG(2) << "<= IndexReader::delDocFilter()";
}

void IndexReader::flush()
{
    if(pDocFilter_)
    {
        boost::mutex::scoped_lock docFilterLock(docFilterMutex_);

        if(pDocFilter_->any())
            pDocFilter_->write(pIndexer_->getDirectory(), DELETED_DOCS);
    }
}

docid_t IndexReader::maxDoc()
{
    return pBarrelsInfo_->maxDocId();
}

size_t IndexReader::docLength(docid_t docId, fieldid_t fid)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (!pDocLengthReader_)
        return 0;
    return pDocLengthReader_->docLength(docId, fid);
}

double IndexReader::getAveragePropertyLength(fieldid_t fid)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    boost::mutex::scoped_lock indexReaderLock(this->mutex_);
    if (!pDocLengthReader_)
        return 0;
    return pDocLengthReader_->averagePropertyLength(fid);
}

bool IndexReader::hasMemBarrelReader()
{
    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    if(pBarrelReader_)
        return pBarrelReader_->hasMemBarrel();
    else
        return false;
}

void IndexReader::createBarrelReader()
{
    boost::mutex::scoped_lock lock(this->mutex_);

    if(pBarrelReader_)
        return;

    DVLOG(2) << "=> IndexReader::createBarrelReader()";

    if(int32_t bc = pBarrelsInfo_->getBarrelCount())
    {
        DVLOG(2) << "IndexReader::createBarrelReader() => " << bc << " barrels...";

        if(bc == 1)
        {
            boost::mutex::scoped_lock lock(pBarrelsInfo_->getMutex());

            pBarrelsInfo_->startIterator();
            if(pBarrelsInfo_->hasNext())
            {
                BarrelInfo* pBarrelInfo = pBarrelsInfo_->next();
                if(pBarrelInfo->isSearchable() && pBarrelInfo->getDocCount() > 0)
                {
                    if(IndexBarrelWriter* pBarrelWriter = pBarrelInfo->getWriter())
                        pBarrelReader_ = pBarrelWriter->inMemoryReader();
                    else
                        pBarrelReader_ = new SingleIndexBarrelReader(this, pBarrelInfo);
                }
            }
        }
        else if(bc > 1)
            pBarrelReader_ = new MultiIndexBarrelReader(this, pBarrelsInfo_);

        if(pDocLengthReader_)
            pDocLengthReader_->load(pBarrelsInfo_->maxDocId());
    }

    DVLOG(2) << "<= IndexReader::createBarrelReader()";
}

TermReader* IndexReader::getTermReader(collectionid_t colID)
{
    //boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    //if(!lock.owns_lock())
        //return NULL;
    izenelib::util::ScopedReadLock<izenelib::util::ReadWriteLock> lock(pIndexer_->mutex_);
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (pBarrelReader_ == NULL)
        return NULL;
    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        pTermReader->setSkipInterval(pIndexer_->getSkipInterval());
        pTermReader->setMaxSkipLevel(pIndexer_->getMaxSkipLevel());
        if(pDocFilter_)
            pTermReader->setDocFilter(pDocFilter_);
        return pTermReader->clone();
    }
    else
        return NULL;
}

void IndexReader::reopen()
{
    DVLOG(2) << "=> IndexReader::reopen()";

    {
        boost::mutex::scoped_lock lock(this->mutex_);
        if(pBarrelReader_)
        {
            DVLOG(2) << "IndexReader::reopen() => delete pBarrelReader_: " << pBarrelReader_;

            delete pBarrelReader_;
            pBarrelReader_ = NULL;

            DVLOG(2) << "IndexReader::reopen() <= delete pBarrelReader_";
        }
    }
    createBarrelReader();

    DVLOG(2) << "<= IndexReader::reopen(), pBarrelReader_: " << pBarrelReader_;
}

count_t IndexReader::numDocs()
{
    return pBarrelsInfo_->getDocCount();
}

void IndexReader::delDocument(collectionid_t colID,docid_t docId)
{
    DVLOG(4) << "=> IndexReader::delDocument(), collection id: " << colID << ", doc id: " << docId << " ...";

    if(pBarrelsInfo_->deleteDocument(colID, docId))
    {
        boost::mutex::scoped_lock docFilterLock(docFilterMutex_);

        if(!pDocFilter_)
        {
            // bit 0 is reserved, so that for doc id i, we can access it just using bit i
            pDocFilter_ = new BitVector(pBarrelsInfo_->maxDocId() + 1);
        }

        pDocFilter_->set(docId);
    }

    DVLOG(4) << "<= IndexReader::delDocument()";
}

freq_t IndexReader::docFreq(collectionid_t colID, Term* term)
{
    //boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    //if(!lock.owns_lock())
        //return 0;
    izenelib::util::ScopedReadLock<izenelib::util::ReadWriteLock> lock(pIndexer_->mutex_);

    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (pBarrelReader_ == NULL)
        return 0;

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        return pTermReader->docFreq(term);
    }

    return 0;
}

TermInfo* IndexReader::termInfo(collectionid_t colID,Term* term)
{
    //boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    //if(!lock.owns_lock())
        //return NULL;
    izenelib::util::ScopedReadLock<izenelib::util::ReadWriteLock> lock(pIndexer_->mutex_);

    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (pBarrelReader_ == NULL)
        return NULL;

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        return pTermReader->termInfo(term);
    }

    return 0;
}

size_t IndexReader::getDistinctNumTerms(collectionid_t colID, const std::string& property)
{
    //collection has been removed, need to rebuild the barrel reader
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (pBarrelReader_ == NULL)
        return 0;

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    return pBarrelReader_->getDistinctNumTerms(colID, property);
}
<commit_msg>tiny log<commit_after>#include <ir/index_manager/index/IndexReader.h>
#include <ir/index_manager/index/TermReader.h>
#include <ir/index_manager/index/Indexer.h>
#include <ir/index_manager/index/MultiIndexBarrelReader.h>
#include <ir/index_manager/index/IndexBarrelWriter.h>
#include <util/izene_log.h>

#include <util/ThreadModel.h>

using namespace izenelib::ir::indexmanager;

IndexReader::IndexReader(Indexer* pIndex)
        :pIndexer_(pIndex)
        ,pBarrelsInfo_(NULL)
        ,pBarrelReader_(NULL)
        ,pDocFilter_(NULL)
        ,pDocLengthReader_(NULL)
{
    pBarrelsInfo_ = pIndexer_->getBarrelsInfo();

    Directory* pDirectory = pIndexer_->getDirectory();
    if(pDirectory->fileExists(DELETED_DOCS))
    {
        pDocFilter_ = new BitVector;
        pDocFilter_->read(pDirectory, DELETED_DOCS);
    }
    ///todo since only one collection is used within indexmanager, so we only get collectionmeta for one collection to build
    ///up the DocLengthReader
    if(pIndexer_->getIndexManagerConfig()->indexStrategy_.indexDocLength_)
        pDocLengthReader_ = new DocLengthReader(
                                pIndexer_->getCollectionsMeta().begin()->second.getDocumentSchema(),
                                pIndexer_->getDirectory());
}

IndexReader::~IndexReader()
{
    if (pBarrelReader_)
    {
        delete pBarrelReader_;
        pBarrelReader_ = NULL;
    }

    flush();
    if(pDocFilter_) delete pDocFilter_;
    pDocFilter_ = NULL;

    if(pDocLengthReader_)
    {
        delete pDocLengthReader_;
        pDocLengthReader_ = NULL;
    }
}

void IndexReader::delDocFilter()
{
    DVLOG(2) << "=> IndexReader::delDocFilter(), pDocFilter_: " << pDocFilter_;
    if(pDocFilter_)
    {
        if(pIndexer_->getDirectory()->fileExists(DELETED_DOCS))
            pIndexer_->getDirectory()->deleteFile(DELETED_DOCS);
        pDocFilter_->clear();
    }
    DVLOG(2) << "<= IndexReader::delDocFilter()";
}

void IndexReader::flush()
{
    if(pDocFilter_)
    {
        boost::mutex::scoped_lock docFilterLock(docFilterMutex_);

        if(pDocFilter_->any())
            pDocFilter_->write(pIndexer_->getDirectory(), DELETED_DOCS);
    }
}

docid_t IndexReader::maxDoc()
{
    return pBarrelsInfo_->maxDocId();
}

size_t IndexReader::docLength(docid_t docId, fieldid_t fid)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (!pDocLengthReader_)
        return 0;
    return pDocLengthReader_->docLength(docId, fid);
}

double IndexReader::getAveragePropertyLength(fieldid_t fid)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    boost::mutex::scoped_lock indexReaderLock(this->mutex_);
    if (!pDocLengthReader_)
        return 0;
    return pDocLengthReader_->averagePropertyLength(fid);
}

bool IndexReader::hasMemBarrelReader()
{
    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    if(pBarrelReader_)
        return pBarrelReader_->hasMemBarrel();
    else
        return false;
}

void IndexReader::createBarrelReader()
{
    boost::mutex::scoped_lock lock(this->mutex_);

    if(pBarrelReader_)
        return;

    DVLOG(2) << "=> IndexReader::createBarrelReader()";

    if(int32_t bc = pBarrelsInfo_->getBarrelCount())
    {
        DVLOG(2) << "IndexReader::createBarrelReader() => " << bc << " barrels...";

        if(bc == 1)
        {
            boost::mutex::scoped_lock lock(pBarrelsInfo_->getMutex());

            pBarrelsInfo_->startIterator();
            if(pBarrelsInfo_->hasNext())
            {
                BarrelInfo* pBarrelInfo = pBarrelsInfo_->next();
                if(pBarrelInfo->isSearchable() && pBarrelInfo->getDocCount() > 0)
                {
                    if(IndexBarrelWriter* pBarrelWriter = pBarrelInfo->getWriter())
                        pBarrelReader_ = pBarrelWriter->inMemoryReader();
                    else
                        pBarrelReader_ = new SingleIndexBarrelReader(this, pBarrelInfo);
                }
            }
        }
        else if(bc > 1)
            pBarrelReader_ = new MultiIndexBarrelReader(this, pBarrelsInfo_);

        if(pDocLengthReader_)
            pDocLengthReader_->load(pBarrelsInfo_->maxDocId());
    }

    DVLOG(2) << "<= IndexReader::createBarrelReader()";
}

TermReader* IndexReader::getTermReader(collectionid_t colID)
{
    //boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    //if(!lock.owns_lock())
        //return NULL;
    izenelib::util::ScopedReadLock<izenelib::util::ReadWriteLock> lock(pIndexer_->mutex_);
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (pBarrelReader_ == NULL)
        return NULL;
    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        pTermReader->setSkipInterval(pIndexer_->getSkipInterval());
        pTermReader->setMaxSkipLevel(pIndexer_->getMaxSkipLevel());
        if(pDocFilter_)
            pTermReader->setDocFilter(pDocFilter_);
        return pTermReader->clone();
    }
    else
        return NULL;
}

void IndexReader::reopen()
{
    DVLOG(2) << "=> IndexReader::reopen()";

    {
        boost::mutex::scoped_lock lock(this->mutex_);
        if(pBarrelReader_)
        {
            DVLOG(2) << "IndexReader::reopen() => delete pBarrelReader_: " << pBarrelReader_;

            delete pBarrelReader_;
            pBarrelReader_ = NULL;

            DVLOG(2) << "IndexReader::reopen() <= delete pBarrelReader_";
        }
    }
    createBarrelReader();

    DVLOG(2) << "<= IndexReader::reopen(), pBarrelReader_: " << pBarrelReader_;
}

count_t IndexReader::numDocs()
{
    return pBarrelsInfo_->getDocCount();
}

void IndexReader::delDocument(collectionid_t colID,docid_t docId)
{
    DVLOG(4) << "=> IndexReader::delDocument(), collection id: " << colID << ", doc id: " << docId << " ...";

    if(pBarrelsInfo_->deleteDocument(colID, docId))
    {
        boost::mutex::scoped_lock docFilterLock(docFilterMutex_);

        if(!pDocFilter_)
        {
            // bit 0 is reserved, so that for doc id i, we can access it just using bit i
            pDocFilter_ = new BitVector(pBarrelsInfo_->maxDocId() + 1);
        }

        pDocFilter_->set(docId);
    }

    LOG(WARNING) << "<= IndexReader::delDocument() failed : " << docId;
}

freq_t IndexReader::docFreq(collectionid_t colID, Term* term)
{
    //boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    //if(!lock.owns_lock())
        //return 0;
    izenelib::util::ScopedReadLock<izenelib::util::ReadWriteLock> lock(pIndexer_->mutex_);

    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (pBarrelReader_ == NULL)
        return 0;

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        return pTermReader->docFreq(term);
    }

    return 0;
}

TermInfo* IndexReader::termInfo(collectionid_t colID,Term* term)
{
    //boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    //if(!lock.owns_lock())
        //return NULL;
    izenelib::util::ScopedReadLock<izenelib::util::ReadWriteLock> lock(pIndexer_->mutex_);

    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (pBarrelReader_ == NULL)
        return NULL;

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        return pTermReader->termInfo(term);
    }

    return 0;
}

size_t IndexReader::getDistinctNumTerms(collectionid_t colID, const std::string& property)
{
    //collection has been removed, need to rebuild the barrel reader
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    if (pBarrelReader_ == NULL)
        return 0;

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    return pBarrelReader_->getDistinctNumTerms(colID, property);
}
<|endoftext|>


<commit_before>#include <ir/index_manager/index/IndexReader.h>
#include <ir/index_manager/index/TermReader.h>
#include <ir/index_manager/index/Indexer.h>
#include <ir/index_manager/index/MultiIndexBarrelReader.h>

using namespace izenelib::ir::indexmanager;

IndexReader::IndexReader(Indexer* pIndex)
        :pIndexer_(pIndex)
        ,pBarrelsInfo_(NULL)
        ,pBarrelReader_(NULL)
        ,pForwardIndexReader_(NULL)
        ,pDocFilter_(NULL)
        ,pDocLengthReader_(NULL)
{
    pBarrelsInfo_ = pIndexer_->getBarrelsInfo();

    Directory* pDirectory = pIndexer_->getDirectory();
    if(pDirectory->fileExists(DELETED_DOCS))
    {
        pDocFilter_ = new BitVector;
        pDocFilter_->read(pDirectory, DELETED_DOCS);
    }
    ///todo since only one collection is used within indexmanager, so we only get collectionmeta for one collection to build
    ///up the DocLengthReader
    if(pIndexer_->getIndexManagerConfig()->indexStrategy_.indexDocLength_)
        pDocLengthReader_ = new DocLengthReader(pIndexer_->getCollectionsMeta().begin()->second.getDocumentSchema(),
                                                        pIndexer_->getDirectory());
}

IndexReader::~IndexReader(void)
{
    if (pBarrelReader_)
    {
        delete pBarrelReader_;
        pBarrelReader_ = NULL;
    }
    if(pForwardIndexReader_)
        delete pForwardIndexReader_;
    if(pDocFilter_)
    {
        if(pIndexer_->getDirectory()->fileExists(DELETED_DOCS))
            pIndexer_->getDirectory()->deleteFile(DELETED_DOCS);
        pDocFilter_->write(pIndexer_->getDirectory(), DELETED_DOCS);
        delete pDocFilter_;
    }
    if(pDocLengthReader_) {delete pDocLengthReader_; pDocLengthReader_ = NULL;}
}

void IndexReader::delDocFilter()
{
    if(pDocFilter_)
    {
        if(pIndexer_->getDirectory()->fileExists(DELETED_DOCS))
            pIndexer_->getDirectory()->deleteFile(DELETED_DOCS);
        delete pDocFilter_;
        pDocFilter_ = NULL;
    }
}

docid_t IndexReader::maxDoc()
{
    return pBarrelsInfo_->maxDocId();
}

size_t IndexReader::docLength(docid_t docId, fieldid_t fid)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    return pDocLengthReader_->docLength(docId, fid);
}

double IndexReader::getAveragePropertyLength(fieldid_t fid)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    boost::mutex::scoped_lock indexReaderLock(this->mutex_);
    return pDocLengthReader_->averagePropertyLength(fid);
}

void IndexReader::createBarrelReader()
{
    boost::mutex::scoped_lock lock(this->mutex_);

    if (pBarrelReader_)
        return;
    //    delete pBarrelReader_;
    int32_t bc = pBarrelsInfo_->getBarrelCount();
    BarrelInfo* pLastBarrel = pBarrelsInfo_->getLastBarrel();
    if ( (bc > 0) && pLastBarrel)
    {
        if (pLastBarrel->getDocCount() <= 0)///skip empty barrel
            bc--;
        pLastBarrel = (*pBarrelsInfo_)[bc - 1];
    }

    if (bc == 1)
    {
        if (pLastBarrel && pLastBarrel->getWriter())
            pBarrelReader_ = pLastBarrel->getWriter()->inMemoryReader();
        else
            pBarrelReader_ = new SingleIndexBarrelReader(pIndexer_,pLastBarrel);
    }
    else if (bc > 1)
    {
        pBarrelReader_ = new MultiIndexBarrelReader(pIndexer_,pBarrelsInfo_);
    }
    else
        SF1V5_THROW(ERROR_INDEX_COLLAPSE,"the index barrel number is 0.");

    if(pDocLengthReader_)
        pDocLengthReader_->load(pBarrelsInfo_->maxDocId());

    //pIndexer_->setDirty(false);///clear dirty_ flag

}

TermReader* IndexReader::getTermReader(collectionid_t colID)
{
    boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    if(!lock.owns_lock())
        return NULL;
    if (pBarrelReader_ == NULL)
        createBarrelReader();

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
        return pTermReader->clone();
    else
        return NULL;
}

void IndexReader::reopen()
{
    //if(pBarrelReader_)
        //delete pBarrelReader_;
    //pBarrelReader_ = NULL;
    /////pBarrelReader_->reopen();
    createBarrelReader();
}

ForwardIndexReader* IndexReader::getForwardIndexReader()
{
    if(!pForwardIndexReader_)
        pForwardIndexReader_ = new ForwardIndexReader(pIndexer_->getDirectory());

    return pForwardIndexReader_->clone();
}

count_t IndexReader::numDocs()
{
    return pBarrelsInfo_->getDocCount();
}

BarrelInfo* IndexReader::findDocumentInBarrels(collectionid_t colID, docid_t docID)
{
    for (int i = pBarrelsInfo_->getBarrelCount() - 1; i >= 0; i--)
    {
        BarrelInfo* pBarrelInfo = (*pBarrelsInfo_)[i];
        if ((pBarrelInfo->baseDocIDMap.find(colID) != pBarrelInfo->baseDocIDMap.end())&&
                (pBarrelInfo->baseDocIDMap[colID] <= docID))
            return pBarrelInfo;
    }
    return NULL;
}

void IndexReader::deleteDocumentPhysically(IndexerDocument* pDoc)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    boost::mutex::scoped_lock lock(this->mutex_);
    pBarrelReader_->deleteDocumentPhysically(pDoc);
    DocId uniqueID;
    pDoc->getDocId(uniqueID);
    BarrelInfo* pBarrelInfo = findDocumentInBarrels(uniqueID.colId, uniqueID.docId);
    pBarrelInfo->deleteDocument(uniqueID.docId);
    map<IndexerPropertyConfig, IndexerDocumentPropertyType> propertyValueList;
    pDoc->getPropertyList(propertyValueList);
    for (map<IndexerPropertyConfig, IndexerDocumentPropertyType>::iterator iter = propertyValueList.begin(); iter != propertyValueList.end(); ++iter)
    {
        if(!iter->first.isIndex())
            continue;
        if (!iter->first.isForward())
        {
            pIndexer_->getBTreeIndexer()->remove(uniqueID.colId, iter->first.getPropertyId(), boost::get<PropertyType>(iter->second), uniqueID.docId);
        }
    }
    pIndexer_->setDirty(true);//flush barrelsinfo when Indexer quit
}

void IndexReader::delDocument(collectionid_t colID,docid_t docId)
{
    BarrelInfo* pBarrelInfo = findDocumentInBarrels(colID, docId);
    if(NULL == pBarrelInfo)
        return;
    pBarrelInfo->deleteDocument(docId);

    if(!pDocFilter_)
    {
        pDocFilter_ = new BitVector(pBarrelsInfo_->getDocCount() + 1);
    }
    pDocFilter_->set(docId);
}

freq_t IndexReader::docFreq(collectionid_t colID, Term* term)
{
    boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    if(!lock.owns_lock())
        return 0;

    if (pBarrelReader_ == NULL)
        createBarrelReader();

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        return pTermReader->docFreq(term);
    }

    return 0;
}

TermInfo* IndexReader::termInfo(collectionid_t colID,Term* term)
{
    boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    if(!lock.owns_lock())
        return NULL;
    if (pBarrelReader_ == NULL)
        createBarrelReader();

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        return pTermReader->termInfo(term);
    }

    return 0;
}

size_t IndexReader::getDistinctNumTerms(collectionid_t colID, const std::string& property)
{
    //collection has been removed, need to rebuild the barrel reader
    if (pBarrelReader_ == NULL)
        createBarrelReader();

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    return pBarrelReader_->getDistinctNumTerms(colID, property);
}

<commit_msg>remove unnecessary exception<commit_after>#include <ir/index_manager/index/IndexReader.h>
#include <ir/index_manager/index/TermReader.h>
#include <ir/index_manager/index/Indexer.h>
#include <ir/index_manager/index/MultiIndexBarrelReader.h>

using namespace izenelib::ir::indexmanager;

IndexReader::IndexReader(Indexer* pIndex)
        :pIndexer_(pIndex)
        ,pBarrelsInfo_(NULL)
        ,pBarrelReader_(NULL)
        ,pForwardIndexReader_(NULL)
        ,pDocFilter_(NULL)
        ,pDocLengthReader_(NULL)
{
    pBarrelsInfo_ = pIndexer_->getBarrelsInfo();

    Directory* pDirectory = pIndexer_->getDirectory();
    if(pDirectory->fileExists(DELETED_DOCS))
    {
        pDocFilter_ = new BitVector;
        pDocFilter_->read(pDirectory, DELETED_DOCS);
    }
    ///todo since only one collection is used within indexmanager, so we only get collectionmeta for one collection to build
    ///up the DocLengthReader
    if(pIndexer_->getIndexManagerConfig()->indexStrategy_.indexDocLength_)
        pDocLengthReader_ = new DocLengthReader(pIndexer_->getCollectionsMeta().begin()->second.getDocumentSchema(),
                                                        pIndexer_->getDirectory());
}

IndexReader::~IndexReader(void)
{
    if (pBarrelReader_)
    {
        delete pBarrelReader_;
        pBarrelReader_ = NULL;
    }
    if(pForwardIndexReader_)
        delete pForwardIndexReader_;
    if(pDocFilter_)
    {
        if(pIndexer_->getDirectory()->fileExists(DELETED_DOCS))
            pIndexer_->getDirectory()->deleteFile(DELETED_DOCS);
        pDocFilter_->write(pIndexer_->getDirectory(), DELETED_DOCS);
        delete pDocFilter_;
    }
    if(pDocLengthReader_) {delete pDocLengthReader_; pDocLengthReader_ = NULL;}
}

void IndexReader::delDocFilter()
{
    if(pDocFilter_)
    {
        if(pIndexer_->getDirectory()->fileExists(DELETED_DOCS))
            pIndexer_->getDirectory()->deleteFile(DELETED_DOCS);
        delete pDocFilter_;
        pDocFilter_ = NULL;
    }
}

docid_t IndexReader::maxDoc()
{
    return pBarrelsInfo_->maxDocId();
}

size_t IndexReader::docLength(docid_t docId, fieldid_t fid)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    return pDocLengthReader_->docLength(docId, fid);
}

double IndexReader::getAveragePropertyLength(fieldid_t fid)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    boost::mutex::scoped_lock indexReaderLock(this->mutex_);
    return pDocLengthReader_->averagePropertyLength(fid);
}

void IndexReader::createBarrelReader()
{
    boost::mutex::scoped_lock lock(this->mutex_);

    if (pBarrelReader_)
        return;
    //    delete pBarrelReader_;
    int32_t bc = pBarrelsInfo_->getBarrelCount();
    BarrelInfo* pLastBarrel = pBarrelsInfo_->getLastBarrel();
    if ( (bc > 0) && pLastBarrel)
    {
        if (pLastBarrel->getDocCount() <= 0)///skip empty barrel
            bc--;
        pLastBarrel = (*pBarrelsInfo_)[bc - 1];
    }

    if (bc == 1)
    {
        if (pLastBarrel && pLastBarrel->getWriter())
            pBarrelReader_ = pLastBarrel->getWriter()->inMemoryReader();
        else
            pBarrelReader_ = new SingleIndexBarrelReader(pIndexer_,pLastBarrel);
    }
    else if (bc > 1)
    {
        pBarrelReader_ = new MultiIndexBarrelReader(pIndexer_,pBarrelsInfo_);
    }
    else
        return;

    if(pDocLengthReader_)
        pDocLengthReader_->load(pBarrelsInfo_->maxDocId());

    //pIndexer_->setDirty(false);///clear dirty_ flag

}

TermReader* IndexReader::getTermReader(collectionid_t colID)
{
    boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    if(!lock.owns_lock())
        return NULL;
    if (pBarrelReader_ == NULL)
        createBarrelReader();

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
        return pTermReader->clone();
    else
        return NULL;
}

void IndexReader::reopen()
{
    //if(pBarrelReader_)
        //delete pBarrelReader_;
    //pBarrelReader_ = NULL;
    /////pBarrelReader_->reopen();
    createBarrelReader();
}

ForwardIndexReader* IndexReader::getForwardIndexReader()
{
    if(!pForwardIndexReader_)
        pForwardIndexReader_ = new ForwardIndexReader(pIndexer_->getDirectory());

    return pForwardIndexReader_->clone();
}

count_t IndexReader::numDocs()
{
    return pBarrelsInfo_->getDocCount();
}

BarrelInfo* IndexReader::findDocumentInBarrels(collectionid_t colID, docid_t docID)
{
    for (int i = pBarrelsInfo_->getBarrelCount() - 1; i >= 0; i--)
    {
        BarrelInfo* pBarrelInfo = (*pBarrelsInfo_)[i];
        if ((pBarrelInfo->baseDocIDMap.find(colID) != pBarrelInfo->baseDocIDMap.end())&&
                (pBarrelInfo->baseDocIDMap[colID] <= docID))
            return pBarrelInfo;
    }
    return NULL;
}

void IndexReader::deleteDocumentPhysically(IndexerDocument* pDoc)
{
    if (pBarrelReader_ == NULL)
        createBarrelReader();
    boost::mutex::scoped_lock lock(this->mutex_);
    pBarrelReader_->deleteDocumentPhysically(pDoc);
    DocId uniqueID;
    pDoc->getDocId(uniqueID);
    BarrelInfo* pBarrelInfo = findDocumentInBarrels(uniqueID.colId, uniqueID.docId);
    pBarrelInfo->deleteDocument(uniqueID.docId);
    map<IndexerPropertyConfig, IndexerDocumentPropertyType> propertyValueList;
    pDoc->getPropertyList(propertyValueList);
    for (map<IndexerPropertyConfig, IndexerDocumentPropertyType>::iterator iter = propertyValueList.begin(); iter != propertyValueList.end(); ++iter)
    {
        if(!iter->first.isIndex())
            continue;
        if (!iter->first.isForward())
        {
            pIndexer_->getBTreeIndexer()->remove(uniqueID.colId, iter->first.getPropertyId(), boost::get<PropertyType>(iter->second), uniqueID.docId);
        }
    }
    pIndexer_->setDirty(true);//flush barrelsinfo when Indexer quit
}

void IndexReader::delDocument(collectionid_t colID,docid_t docId)
{
    BarrelInfo* pBarrelInfo = findDocumentInBarrels(colID, docId);
    if(NULL == pBarrelInfo)
        return;
    pBarrelInfo->deleteDocument(docId);

    if(!pDocFilter_)
    {
        pDocFilter_ = new BitVector(pBarrelsInfo_->getDocCount() + 1);
    }
    pDocFilter_->set(docId);
}

freq_t IndexReader::docFreq(collectionid_t colID, Term* term)
{
    boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    if(!lock.owns_lock())
        return 0;

    if (pBarrelReader_ == NULL)
        createBarrelReader();

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        return pTermReader->docFreq(term);
    }

    return 0;
}

TermInfo* IndexReader::termInfo(collectionid_t colID,Term* term)
{
    boost::try_mutex::scoped_try_lock lock(pIndexer_->mutex_);
    if(!lock.owns_lock())
        return NULL;
    if (pBarrelReader_ == NULL)
        createBarrelReader();

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    TermReader* pTermReader = pBarrelReader_->termReader(colID);
    if (pTermReader)
    {
        return pTermReader->termInfo(term);
    }

    return 0;
}

size_t IndexReader::getDistinctNumTerms(collectionid_t colID, const std::string& property)
{
    //collection has been removed, need to rebuild the barrel reader
    if (pBarrelReader_ == NULL)
        createBarrelReader();

    boost::mutex::scoped_lock indexReaderLock(this->mutex_);

    return pBarrelReader_->getDistinctNumTerms(colID, property);
}

<|endoftext|>


<commit_before>
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "gm.h"
#include "SkBitmap.h"
#include "SkShader.h"
#include "SkXfermode.h"
#include "SkColorPriv.h"

namespace skiagm {

class Xfermodes2GM : public GM {
public:
    Xfermodes2GM() {}

protected:
    SkString onShortName() override {
        return SkString("xfermodes2");
    }

    SkISize onISize() override {
        return SkISize::Make(455, 475);
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));

        const SkScalar w = SkIntToScalar(kSize);
        const SkScalar h = SkIntToScalar(kSize);

        SkPaint labelP;
        labelP.setAntiAlias(true);
        sk_tool_utils::set_portable_typeface(&labelP);
        labelP.setTextAlign(SkPaint::kCenter_Align);

        const int W = 6;

        SkScalar x = 0, y = 0;
        for (size_t m = 0; m <= SkXfermode::kLastMode; m++) {
            SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(m);
            SkXfermode* xm = SkXfermode::Create(mode);
            SkAutoUnref aur(xm);

            canvas->save();

            canvas->translate(x, y);
            SkPaint p;
            p.setAntiAlias(false);
            p.setStyle(SkPaint::kFill_Style);
            p.setShader(fBG);
            SkRect r = SkRect::MakeWH(w, h);
            canvas->drawRect(r, p);

            canvas->saveLayer(&r, NULL);

            p.setShader(fDst);
            canvas->drawRect(r, p);
            p.setShader(fSrc);
            p.setXfermode(xm);
            canvas->drawRect(r, p);

            canvas->restore();

            r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
            p.setStyle(SkPaint::kStroke_Style);
            p.setShader(NULL);
            p.setXfermode(NULL);
            canvas->drawRect(r, p);

            canvas->restore();

#if 1
            canvas->drawText(SkXfermode::ModeName(mode), strlen(SkXfermode::ModeName(mode)),
                             x + w/2, y - labelP.getTextSize()/2, labelP);
#endif
            x += w + SkIntToScalar(10);
            if ((m % W) == W - 1) {
                x = 0;
                y += h + SkIntToScalar(30);
            }
        }
    }

private:
    void onOnceBeforeDraw() override {
        static const uint32_t kCheckData[] = {
            SkPackARGB32(0xFF, 0x40, 0x40, 0x40),
            SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0),
            SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0),
            SkPackARGB32(0xFF, 0x40, 0x40, 0x40)
        };
        SkBitmap bg;
        bg.allocN32Pixels(2, 2, true);
        memcpy(bg.getPixels(), kCheckData, sizeof(kCheckData));

        SkMatrix lm;
        lm.setScale(SkIntToScalar(16), SkIntToScalar(16));
        fBG.reset(SkShader::CreateBitmapShader(bg,
                                               SkShader::kRepeat_TileMode,
                                               SkShader::kRepeat_TileMode,
                                               &lm));

        SkBitmap dstBmp;
        dstBmp.allocN32Pixels(kSize, kSize);
        SkPMColor* pixels = reinterpret_cast<SkPMColor*>(dstBmp.getPixels());

        for (int y = 0; y < kSize; ++y) {
            int c = y * (1 << kShift);
            SkPMColor rowColor = SkPackARGB32(c, c, 0, c/2);
            for (int x = 0; x < kSize; ++x) {
                pixels[kSize * y + x] = rowColor;
            }
        }
        fSrc.reset(SkShader::CreateBitmapShader(dstBmp,
                                                SkShader::kClamp_TileMode,
                                                SkShader::kClamp_TileMode));
        SkBitmap srcBmp;
        srcBmp.allocN32Pixels(kSize, kSize);
        pixels = reinterpret_cast<SkPMColor*>(srcBmp.getPixels());

        for (int x = 0; x < kSize; ++x) {
            int c = x * (1 << kShift);
            SkPMColor colColor = SkPackARGB32(c, 0, c, c/2);
            for (int y = 0; y < kSize; ++y) {
                pixels[kSize * y + x] = colColor;
            }
        }
        fDst.reset(SkShader::CreateBitmapShader(srcBmp,
                                                SkShader::kClamp_TileMode,
                                                SkShader::kClamp_TileMode));
    }

    enum {
        kShift = 2,
        kSize = 256 >> kShift,
    };

    SkAutoTUnref<SkShader> fBG;
    SkAutoTUnref<SkShader> fSrc;
    SkAutoTUnref<SkShader> fDst;

    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static GM* MyFactory(void*) { return new Xfermodes2GM; }
static GMRegistry reg(MyFactory);

}
<commit_msg>Fix variable names in xfermodes2 gm test<commit_after>
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "gm.h"
#include "SkBitmap.h"
#include "SkShader.h"
#include "SkXfermode.h"
#include "SkColorPriv.h"

namespace skiagm {

class Xfermodes2GM : public GM {
public:
    Xfermodes2GM() {}

protected:
    SkString onShortName() override {
        return SkString("xfermodes2");
    }

    SkISize onISize() override {
        return SkISize::Make(455, 475);
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));

        const SkScalar w = SkIntToScalar(kSize);
        const SkScalar h = SkIntToScalar(kSize);

        SkPaint labelP;
        labelP.setAntiAlias(true);
        sk_tool_utils::set_portable_typeface(&labelP);
        labelP.setTextAlign(SkPaint::kCenter_Align);

        const int W = 6;

        SkScalar x = 0, y = 0;
        for (size_t m = 0; m <= SkXfermode::kLastMode; m++) {
            SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(m);
            SkXfermode* xm = SkXfermode::Create(mode);
            SkAutoUnref aur(xm);

            canvas->save();

            canvas->translate(x, y);
            SkPaint p;
            p.setAntiAlias(false);
            p.setStyle(SkPaint::kFill_Style);
            p.setShader(fBG);
            SkRect r = SkRect::MakeWH(w, h);
            canvas->drawRect(r, p);

            canvas->saveLayer(&r, NULL);

            p.setShader(fDst);
            canvas->drawRect(r, p);
            p.setShader(fSrc);
            p.setXfermode(xm);
            canvas->drawRect(r, p);

            canvas->restore();

            r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
            p.setStyle(SkPaint::kStroke_Style);
            p.setShader(NULL);
            p.setXfermode(NULL);
            canvas->drawRect(r, p);

            canvas->restore();

#if 1
            canvas->drawText(SkXfermode::ModeName(mode), strlen(SkXfermode::ModeName(mode)),
                             x + w/2, y - labelP.getTextSize()/2, labelP);
#endif
            x += w + SkIntToScalar(10);
            if ((m % W) == W - 1) {
                x = 0;
                y += h + SkIntToScalar(30);
            }
        }
    }

private:
    void onOnceBeforeDraw() override {
        static const uint32_t kCheckData[] = {
            SkPackARGB32(0xFF, 0x40, 0x40, 0x40),
            SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0),
            SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0),
            SkPackARGB32(0xFF, 0x40, 0x40, 0x40)
        };
        SkBitmap bg;
        bg.allocN32Pixels(2, 2, true);
        memcpy(bg.getPixels(), kCheckData, sizeof(kCheckData));

        SkMatrix lm;
        lm.setScale(SkIntToScalar(16), SkIntToScalar(16));
        fBG.reset(SkShader::CreateBitmapShader(bg,
                                               SkShader::kRepeat_TileMode,
                                               SkShader::kRepeat_TileMode,
                                               &lm));

        SkBitmap srcBmp;
        srcBmp.allocN32Pixels(kSize, kSize);
        SkPMColor* pixels = reinterpret_cast<SkPMColor*>(srcBmp.getPixels());

        for (int y = 0; y < kSize; ++y) {
            int c = y * (1 << kShift);
            SkPMColor rowColor = SkPackARGB32(c, c, 0, c/2);
            for (int x = 0; x < kSize; ++x) {
                pixels[kSize * y + x] = rowColor;
            }
        }
        fSrc.reset(SkShader::CreateBitmapShader(srcBmp,
                                                SkShader::kClamp_TileMode,
                                                SkShader::kClamp_TileMode));
        SkBitmap dstBmp;
        dstBmp.allocN32Pixels(kSize, kSize);
        pixels = reinterpret_cast<SkPMColor*>(dstBmp.getPixels());

        for (int x = 0; x < kSize; ++x) {
            int c = x * (1 << kShift);
            SkPMColor colColor = SkPackARGB32(c, 0, c, c/2);
            for (int y = 0; y < kSize; ++y) {
                pixels[kSize * y + x] = colColor;
            }
        }
        fDst.reset(SkShader::CreateBitmapShader(dstBmp,
                                                SkShader::kClamp_TileMode,
                                                SkShader::kClamp_TileMode));
    }

    enum {
        kShift = 2,
        kSize = 256 >> kShift,
    };

    SkAutoTUnref<SkShader> fBG;
    SkAutoTUnref<SkShader> fSrc;
    SkAutoTUnref<SkShader> fDst;

    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static GM* MyFactory(void*) { return new Xfermodes2GM; }
static GMRegistry reg(MyFactory);

}
<|endoftext|>


<commit_before>#include "SQLiteQueryExecutor.h"
#include "Logger.h"
#include "sqlite_orm.h"

#include <sqlite3.h>
#include <memory>
#include <sstream>
#include <string>

namespace comm {

using namespace sqlite_orm;

std::string SQLiteQueryExecutor::sqliteFilePath;

void SQLiteQueryExecutor::migrate() {
  sqlite3 *conn;
  sqlite3_open(SQLiteQueryExecutor::sqliteFilePath.c_str(), &conn);
  char *error;
  sqlite3_exec(
      conn,
      "ALTER TABLE drafts RENAME COLUMN `threadID` TO `key`",
      nullptr,
      nullptr,
      &error);
  if (error) {
    std::ostringstream stringStream;
    stringStream << "Error occurred renaming threadID column in drafts table "
                 << "to key: " << error;
    Logger::log(stringStream.str());
    sqlite3_free(error);
  }
  sqlite3_close(conn);
}

auto SQLiteQueryExecutor::getStorage() {
  static auto storage = make_storage(
      SQLiteQueryExecutor::sqliteFilePath,
      make_table(
          "drafts",
          make_column("key", &Draft::key, unique(), primary_key()),
          make_column("text", &Draft::text)));
  return storage;
}

SQLiteQueryExecutor::SQLiteQueryExecutor() {
  this->migrate();
  SQLiteQueryExecutor::getStorage().sync_schema(true);
}

std::string SQLiteQueryExecutor::getDraft(std::string key) const {
  std::unique_ptr<Draft> draft =
      SQLiteQueryExecutor::getStorage().get_pointer<Draft>(key);
  return (draft == nullptr) ? "" : draft->text;
}

void SQLiteQueryExecutor::updateDraft(std::string key, std::string text) const {
  Draft draft = {key, text};
  SQLiteQueryExecutor::getStorage().replace(draft);
}

bool SQLiteQueryExecutor::moveDraft(std::string oldKey, std::string newKey)
    const {
  std::unique_ptr<Draft> draft =
      SQLiteQueryExecutor::getStorage().get_pointer<Draft>(oldKey);
  if (draft == nullptr) {
    return false;
  }
  draft->key = newKey;
  SQLiteQueryExecutor::getStorage().replace(*draft);
  SQLiteQueryExecutor::getStorage().remove<Draft>(oldKey);
  return true;
}

std::vector<Draft> SQLiteQueryExecutor::getAllDrafts() const {
  return SQLiteQueryExecutor::getStorage().get_all<Draft>();
}

void SQLiteQueryExecutor::removeAllDrafts() const {
  SQLiteQueryExecutor::getStorage().remove_all<Draft>();
}

} // namespace comm
<commit_msg>[native] remove `sqlite_orm:sync_schema` usage<commit_after>#include "SQLiteQueryExecutor.h"
#include "Logger.h"
#include "sqlite_orm.h"

#include <sqlite3.h>
#include <memory>
#include <sstream>
#include <string>

namespace comm {

using namespace sqlite_orm;

std::string SQLiteQueryExecutor::sqliteFilePath;

void SQLiteQueryExecutor::migrate() {
  sqlite3 *conn;
  sqlite3_open(SQLiteQueryExecutor::sqliteFilePath.c_str(), &conn);
  char *error;
  sqlite3_exec(
      conn,
      "ALTER TABLE drafts RENAME COLUMN `threadID` TO `key`",
      nullptr,
      nullptr,
      &error);
  if (error) {
    std::ostringstream stringStream;
    stringStream << "Error occurred renaming threadID column in drafts table "
                 << "to key: " << error;
    Logger::log(stringStream.str());
    sqlite3_free(error);
  }
  sqlite3_close(conn);
}

auto SQLiteQueryExecutor::getStorage() {
  static auto storage = make_storage(
      SQLiteQueryExecutor::sqliteFilePath,
      make_table(
          "drafts",
          make_column("key", &Draft::key, unique(), primary_key()),
          make_column("text", &Draft::text)));
  return storage;
}

SQLiteQueryExecutor::SQLiteQueryExecutor() {
  this->migrate();
}

std::string SQLiteQueryExecutor::getDraft(std::string key) const {
  std::unique_ptr<Draft> draft =
      SQLiteQueryExecutor::getStorage().get_pointer<Draft>(key);
  return (draft == nullptr) ? "" : draft->text;
}

void SQLiteQueryExecutor::updateDraft(std::string key, std::string text) const {
  Draft draft = {key, text};
  SQLiteQueryExecutor::getStorage().replace(draft);
}

bool SQLiteQueryExecutor::moveDraft(std::string oldKey, std::string newKey)
    const {
  std::unique_ptr<Draft> draft =
      SQLiteQueryExecutor::getStorage().get_pointer<Draft>(oldKey);
  if (draft == nullptr) {
    return false;
  }
  draft->key = newKey;
  SQLiteQueryExecutor::getStorage().replace(*draft);
  SQLiteQueryExecutor::getStorage().remove<Draft>(oldKey);
  return true;
}

std::vector<Draft> SQLiteQueryExecutor::getAllDrafts() const {
  return SQLiteQueryExecutor::getStorage().get_all<Draft>();
}

void SQLiteQueryExecutor::removeAllDrafts() const {
  SQLiteQueryExecutor::getStorage().remove_all<Draft>();
}

} // namespace comm
<|endoftext|>


<commit_before>//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "nanoFramework_hardware_esp32_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Logging::NativeSetLogLevel___STATIC__VOID__STRING__I4,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTimer___STATIC__nanoFrameworkHardwareEsp32EspNativeError__U8,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByPin___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__I4,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByMultiPins___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__nanoFrameworkHardwareEsp32SleepWakeupMode,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartLightSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartDeepSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupCause___STATIC__nanoFrameworkHardwareEsp32SleepWakeupCause,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupGpioPin___STATIC__nanoFrameworkHardwareEsp32SleepWakeupGpioPin,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeEspTimerCreate___I4,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeEspTimerDispose___VOID,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStop___VOID,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStartOneShot___VOID__U8,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStartPeriodic___VOID__U8,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeGetCurrent___STATIC__U8,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Esp32 =
{
    "nanoFramework.Hardware.Esp32",
    0xF8079179,
    method_lookup,
    { 1, 0, 5, 3 }
};
<commit_msg>Update nanoFramework.Hardware.Esp32 version to 1.0.7 ***NO_CI***<commit_after>//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "nanoFramework_hardware_esp32_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Logging::NativeSetLogLevel___STATIC__VOID__STRING__I4,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTimer___STATIC__nanoFrameworkHardwareEsp32EspNativeError__U8,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByPin___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__I4,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByMultiPins___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__nanoFrameworkHardwareEsp32SleepWakeupMode,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartLightSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartDeepSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupCause___STATIC__nanoFrameworkHardwareEsp32SleepWakeupCause,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupGpioPin___STATIC__nanoFrameworkHardwareEsp32SleepWakeupGpioPin,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeEspTimerCreate___I4,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeEspTimerDispose___VOID,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStop___VOID,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStartOneShot___VOID__U8,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStartPeriodic___VOID__U8,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeGetCurrent___STATIC__U8,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Esp32 =
{
    "nanoFramework.Hardware.Esp32",
    0xF8079179,
    method_lookup,
    { 1, 0, 7, 3 }
};
<|endoftext|>


<commit_before>/**
 * @file minimizer_test.cpp
 * @brief Minimize Draft code test version
 */

#include "minimizer.h"
#include <SQ_sampler.h>

/**
 * @function main
 */
int main( int argc, char* argv[] ) {

    // 0. Initialize random seed
    std::random_device rd;
    std::mt19937 gen( rd() );
    std::uniform_real_distribution<> dis(-0.01, 0.015 );

    // 1. Sample a SQ (pick any parameters)
    SQ_params par;
    par.a = 0.5; par.b = 0.35; par.c = 0.2;
    par.e1 = 0.8; par.e2 = 0.8;
    par.px = 0.1; par.py = 0.9; par.pz = 0.4;
    par.ra = 0.5; par.pa = 0.7; par.ya = 0.5;

    SQ_sampler sqs;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud( new pcl::PointCloud<pcl::PointXYZ>());
    cloud = sqs.sampleSQ_naive( par );

    // 1.a. Let's add some error and see how bad it goes (error-related)
    for( int i = 0; i < cloud->points.size(); ++i ) {
	cloud->points[i].x += dis(gen);
  	cloud->points[i].y += dis(gen);
	cloud->points[i].z += dis(gen);
    }
    cloud->height = 1;
    cloud->width = cloud->points.size();
    pcl::io::savePCDFileASCII ("test_pcd.pcd", *cloud);
    minimizer mM;
    mM.loadPoints( cloud );
    mM.visualizePoints();

    SQ_params par_in, par_out;
    par_in = par;
    par_in.a += 0.01;
    par_in.c -= 0.02;
    par_in.py += 0.03;
    par_in.e1 = 0.75;
    par_in.e2 = 0.75;

    if( mM.minimize(par_in, par_out) ) {
	std::cout << "\t SUCCESS!"<< std::endl;

    } else {
	std::cout << "\t FAILURE!"<< std::endl;
    }

    return 0;
}
<commit_msg>Tested MATLAB code for J and Hess, it RUN LIKE THE WIND<commit_after>/**
 * @file minimizer_test.cpp
 * @brief Minimize Draft code test version
 */

#include "minimizer.h"
#include <SQ_sampler.h>

/**
 * @function main
 */
int main( int argc, char* argv[] ) {

    // 0. Initialize random seed
    std::random_device rd;
    std::mt19937 gen( rd() );
    std::uniform_real_distribution<> dis(-0.01, 0.015 );

    // 1. Sample a SQ (pick any parameters)
    SQ_params par;
    par.a = 0.5; par.b = 0.35; par.c = 0.2;
    par.e1 = 0.8; par.e2 = 0.8;
    par.px = 0.1; par.py = 0.9; par.pz = 0.4;
    par.ra = 0.5; par.pa = 0.7; par.ya = 0.5;

    SQ_sampler sqs;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud( new pcl::PointCloud<pcl::PointXYZ>());
    cloud = sqs.sampleSQ_naive( par );

    // 1.a. Let's add some error and see how bad it goes (error-related)
    for( int i = 0; i < cloud->points.size(); ++i ) {
	cloud->points[i].x += dis(gen);
  	cloud->points[i].y += dis(gen);
	cloud->points[i].z += dis(gen);
    }
    cloud->height = 1;
    cloud->width = cloud->points.size();
    pcl::io::savePCDFileASCII ("test_pcd.pcd", *cloud);
    minimizer mM;
    mM.loadPoints( cloud );
    mM.visualizePoints();

    SQ_params par_in, par_out;
    par_in = par;
    par_in.a += 0.01;
    par_in.c -= 0.02;
    par_in.py += 0.03;
    par_in.e1 = 0.6;
    par_in.e2 = 0.6;

    if( mM.minimize(par_in, par_out) ) {
	std::cout << "\t SUCCESS!"<< std::endl;

    } else {
	std::cout << "\t FAILURE!"<< std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2007-2015 QReal Research Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "languageInfo.h"

using namespace qReal::text;

QList<LanguageInfo> Languages::mUserDefinedLanguages;

QList<LanguageInfo> Languages::knownLanguages()
{
	return mUserDefinedLanguages + QList<LanguageInfo>({
			// Append here all languages declared in Languages class
			c(), russianC(), python(), qtScript(), fSharp()
	});
}

void Languages::registerLanguage(const LanguageInfo &language)
{
	mUserDefinedLanguages << language;
}

LanguageInfo Languages::pickByExtension(const QString &extension)
{
	for (const LanguageInfo &language : knownLanguages()) {
		if (language.extension == extension) {
			return language;
		}
	}

	return textFileInfo(extension);
}
<commit_msg>*.js added to main open file dialog filters<commit_after>/* Copyright 2007-2015 QReal Research Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "languageInfo.h"

using namespace qReal::text;

QList<LanguageInfo> Languages::mUserDefinedLanguages;

QList<LanguageInfo> Languages::knownLanguages()
{
	return mUserDefinedLanguages + QList<LanguageInfo>({
			// Append here all languages declared in Languages class
			c(), russianC(), python(), qtScript(), javaScript(), fSharp()
	});
}

void Languages::registerLanguage(const LanguageInfo &language)
{
	mUserDefinedLanguages << language;
}

LanguageInfo Languages::pickByExtension(const QString &extension)
{
	for (const LanguageInfo &language : knownLanguages()) {
		if (language.extension == extension) {
			return language;
		}
	}

	return textFileInfo(extension);
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright (c) 2009, Howard Butler
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following
 * conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of the Martin Isenburg or Iowa Department
 *       of Natural Resources nor the names of its contributors may be
 *       used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 ****************************************************************************/

#include <pdal/SpatialReference.hpp>

#include <boost/concept_check.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/concept_check.hpp> // ignore_unused_variable_warning

#include <boost/algorithm/string/trim.hpp>

// gdal
#ifdef PDAL_HAVE_GDAL
#include <ogr_spatialref.h>
#include <cpl_conv.h>
#endif

#include <pdal/Utils.hpp>

namespace pdal
{

SpatialReference::SpatialReference()
    : m_wkt("")
{
    return;
}

SpatialReference::SpatialReference(const std::string& s)
    : m_wkt("")
{
    this->setFromUserInput(s);
    return;
}

SpatialReference::SpatialReference(SpatialReference const& rhs)
    : m_wkt(rhs.m_wkt)
{
    return;
}

SpatialReference& SpatialReference::operator=(SpatialReference const& rhs)
{
    if (&rhs != this)
    {
        m_wkt = rhs.m_wkt;
    }
    return *this;
}

SpatialReference::~SpatialReference()
{
    return;
}

bool SpatialReference::empty() const
{
    return (getWKT() == "");
}

std::string SpatialReference::getWKT(WKTModeFlag mode_flag) const
{
    return getWKT(mode_flag, false);
}

/// Fetch the SRS as WKT
std::string SpatialReference::getWKT(WKTModeFlag mode_flag , bool pretty) const
{
#ifndef PDAL_SRS_ENABLED
    boost::ignore_unused_variable_warning(mode_flag);
    boost::ignore_unused_variable_warning(pretty);

    // we don't have a way of making this pretty, or of stripping the compound wrapper.
    return m_wkt;
#else

    std::string result_wkt = m_wkt;

    if ((mode_flag == eHorizontalOnly
            && strstr(result_wkt.c_str(),"COMPD_CS") != NULL)
            || pretty)
    {
        OGRSpatialReference* poSRS = (OGRSpatialReference*) OSRNewSpatialReference(result_wkt.c_str());
        char *pszWKT = NULL;

        if (mode_flag == eHorizontalOnly)
            poSRS->StripVertical();

        if (pretty)
            poSRS->exportToPrettyWkt(&pszWKT, FALSE);
        else
            poSRS->exportToWkt(&pszWKT);

        OSRDestroySpatialReference(poSRS);

        result_wkt = pszWKT;
        CPLFree(pszWKT);
    }

    return result_wkt;
#endif
}

void SpatialReference::setFromUserInput(std::string const& v)
{
#ifdef PDAL_SRS_ENABLED

    char* poWKT = 0;
    const char* input = v.c_str();

    // OGRSpatialReference* poSRS = (OGRSpatialReference*) OSRNewSpatialReference(NULL);
    OGRSpatialReference srs(NULL);
    OGRErr err = srs.SetFromUserInput(const_cast<char *>(input));
    if (err != OGRERR_NONE)
    {
        throw std::invalid_argument("could not import coordinate system into OSRSpatialReference SetFromUserInput");
    }

    srs.exportToWkt(&poWKT);

    std::string tmp(poWKT);
    CPLFree(poWKT);

    setWKT(tmp);
#else
    boost::ignore_unused_variable_warning(v);
    throw std::runtime_error("GDAL is not available, SpatialReference could not be set from WKT");
#endif
}

void SpatialReference::setWKT(std::string const& v)
{
    m_wkt = v;

    return;
}

std::string SpatialReference::getProj4() const
{
#ifdef PDAL_SRS_ENABLED

    std::string wkt = getWKT(eCompoundOK);
    const char* poWKT = wkt.c_str();

    OGRSpatialReference srs(NULL);
    if (OGRERR_NONE != srs.importFromWkt(const_cast<char **>(&poWKT)))
    {
        return std::string();
    }

    char* proj4 = 0;
    srs.exportToProj4(&proj4);
    std::string tmp(proj4);
    CPLFree(proj4);

    boost::algorithm::trim(tmp);
    return tmp;

#else

    // By default or if we have neither GDAL nor proj.4, we can't do squat
    return std::string();
#endif
}

void SpatialReference::setProj4(std::string const& v)
{
#ifdef PDAL_SRS_ENABLED
    char* poWKT = 0;
    const char* poProj4 = v.c_str();

    OGRSpatialReference srs(NULL);
    if (OGRERR_NONE != srs.importFromProj4(const_cast<char *>(poProj4)))
    {
        throw std::invalid_argument("could not import proj4 into OSRSpatialReference SetProj4");
    }

    srs.exportToWkt(&poWKT);

    std::string tmp(poWKT);
    CPLFree(poWKT);

    m_wkt = tmp;

#else
    boost::ignore_unused_variable_warning(v);
#endif

    return;
}

bool SpatialReference::equals(const SpatialReference& input) const
{
#ifdef PDAL_SRS_ENABLED

    OGRSpatialReferenceH current = OSRNewSpatialReference(getWKT(eCompoundOK, false).c_str());
    OGRSpatialReferenceH other = OSRNewSpatialReference(input.getWKT(eCompoundOK, false).c_str());

    int output = OSRIsSame(current, other);

    OSRDestroySpatialReference(current);
    OSRDestroySpatialReference(other);

    return (output==1);

#else
    boost::ignore_unused_variable_warning(input);
    throw pdal_error("SpatialReference equality testing not available without GDAL+libgeotiff support");
#endif

}

bool SpatialReference::operator==(const SpatialReference& input) const
{
    return this->equals(input);
}

bool SpatialReference::operator!=(const SpatialReference& input) const
{
    return !(this->equals(input));
}

const std::string& SpatialReference::getName() const
{
    static std::string name("pdal.spatialreference");
    return name;
}

bool SpatialReference::isGeographic() const
{
#ifdef PDAL_SRS_ENABLED

    OGRSpatialReferenceH current = OSRNewSpatialReference(getWKT(eCompoundOK, false).c_str());

    bool geog = static_cast<bool>(OSRIsGeographic(current));

    OSRDestroySpatialReference(current);

    return geog;
#else
    throw std::runtime_error("GDAL is not available, SpatialReference could not determine if isGeographic");
#endif
}

boost::property_tree::ptree SpatialReference::toPTree() const
{
    using boost::property_tree::ptree;
    ptree srs;

#ifdef PDAL_SRS_ENABLED
    srs.put("proj4", getProj4());
    srs.put("prettywkt", getWKT(SpatialReference::eHorizontalOnly, true));
    srs.put("wkt", getWKT(SpatialReference::eHorizontalOnly, false));
    srs.put("compoundwkt", getWKT(eCompoundOK, false));
    srs.put("prettycompoundwkt", getWKT(eCompoundOK, true));

#else

    std::string message;
    if (m_wkt.size() == 0)
    {
        message = "Reference defined with VLR keys, but GeoTIFF and GDAL support are not available to produce definition";
    }
    else if (m_wkt.size() > 0)
    {
        message = "Reference defined with WKT, but GeoTIFF and GDAL support are not available to produce definition";
    }
    else
    {
        message = "None";
    }

    srs.put("proj4", message);
    srs.put("prettywkt", message);
    srs.put("wkt", message);
    srs.put("compoundwkt", message);
    srs.put("prettycompoundwkt", message);
    srs.put("gtiff", message);
#endif

    return srs;
}

void SpatialReference::dump() const
{
    std::cout << *this;
}

std::ostream& operator<<(std::ostream& ostr, const SpatialReference& srs)
{

#ifdef PDAL_SRS_ENABLED

    std::string wkt = srs.toPTree().get<std::string>("prettycompoundwkt");
    ostr << wkt;

    return ostr;

#else
    boost::ignore_unused_variable_warning(ostr);
    boost::ignore_unused_variable_warning(srs);
    ostr << "SpatialReference data is not available without GDAL+libgeotiff support";
    return ostr;
#endif
}

std::istream& operator>>(std::istream& istr, SpatialReference& srs)
{

#ifdef PDAL_SRS_ENABLED

    SpatialReference ref;

    std::ostringstream oss;
    oss << istr.rdbuf();

    std::string wkt = oss.str();
    ref.setFromUserInput(wkt.c_str());

    srs = ref;
    return istr;

#else
    boost::ignore_unused_variable_warning(istr);
    boost::ignore_unused_variable_warning(srs);
    throw pdal_error("SpatialReference io operator>> is not available without GDAL+libgeotiff support");
#endif
}

} // namespace pdal
<commit_msg>silence bool conversion warning<commit_after>/******************************************************************************
 * Copyright (c) 2009, Howard Butler
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following
 * conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of the Martin Isenburg or Iowa Department
 *       of Natural Resources nor the names of its contributors may be
 *       used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 ****************************************************************************/

#include <pdal/SpatialReference.hpp>

#include <boost/concept_check.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/concept_check.hpp> // ignore_unused_variable_warning

#include <boost/algorithm/string/trim.hpp>

// gdal
#ifdef PDAL_HAVE_GDAL
#include <ogr_spatialref.h>
#include <cpl_conv.h>
#endif

#include <pdal/Utils.hpp>

namespace pdal
{

SpatialReference::SpatialReference()
    : m_wkt("")
{
    return;
}

SpatialReference::SpatialReference(const std::string& s)
    : m_wkt("")
{
    this->setFromUserInput(s);
    return;
}

SpatialReference::SpatialReference(SpatialReference const& rhs)
    : m_wkt(rhs.m_wkt)
{
    return;
}

SpatialReference& SpatialReference::operator=(SpatialReference const& rhs)
{
    if (&rhs != this)
    {
        m_wkt = rhs.m_wkt;
    }
    return *this;
}

SpatialReference::~SpatialReference()
{
    return;
}

bool SpatialReference::empty() const
{
    return (getWKT() == "");
}

std::string SpatialReference::getWKT(WKTModeFlag mode_flag) const
{
    return getWKT(mode_flag, false);
}

/// Fetch the SRS as WKT
std::string SpatialReference::getWKT(WKTModeFlag mode_flag , bool pretty) const
{
#ifndef PDAL_SRS_ENABLED
    boost::ignore_unused_variable_warning(mode_flag);
    boost::ignore_unused_variable_warning(pretty);

    // we don't have a way of making this pretty, or of stripping the compound wrapper.
    return m_wkt;
#else

    std::string result_wkt = m_wkt;

    if ((mode_flag == eHorizontalOnly
            && strstr(result_wkt.c_str(),"COMPD_CS") != NULL)
            || pretty)
    {
        OGRSpatialReference* poSRS = (OGRSpatialReference*) OSRNewSpatialReference(result_wkt.c_str());
        char *pszWKT = NULL;

        if (mode_flag == eHorizontalOnly)
            poSRS->StripVertical();

        if (pretty)
            poSRS->exportToPrettyWkt(&pszWKT, FALSE);
        else
            poSRS->exportToWkt(&pszWKT);

        OSRDestroySpatialReference(poSRS);

        result_wkt = pszWKT;
        CPLFree(pszWKT);
    }

    return result_wkt;
#endif
}

void SpatialReference::setFromUserInput(std::string const& v)
{
#ifdef PDAL_SRS_ENABLED

    char* poWKT = 0;
    const char* input = v.c_str();

    // OGRSpatialReference* poSRS = (OGRSpatialReference*) OSRNewSpatialReference(NULL);
    OGRSpatialReference srs(NULL);
    OGRErr err = srs.SetFromUserInput(const_cast<char *>(input));
    if (err != OGRERR_NONE)
    {
        throw std::invalid_argument("could not import coordinate system into OSRSpatialReference SetFromUserInput");
    }

    srs.exportToWkt(&poWKT);

    std::string tmp(poWKT);
    CPLFree(poWKT);

    setWKT(tmp);
#else
    boost::ignore_unused_variable_warning(v);
    throw std::runtime_error("GDAL is not available, SpatialReference could not be set from WKT");
#endif
}

void SpatialReference::setWKT(std::string const& v)
{
    m_wkt = v;

    return;
}

std::string SpatialReference::getProj4() const
{
#ifdef PDAL_SRS_ENABLED

    std::string wkt = getWKT(eCompoundOK);
    const char* poWKT = wkt.c_str();

    OGRSpatialReference srs(NULL);
    if (OGRERR_NONE != srs.importFromWkt(const_cast<char **>(&poWKT)))
    {
        return std::string();
    }

    char* proj4 = 0;
    srs.exportToProj4(&proj4);
    std::string tmp(proj4);
    CPLFree(proj4);

    boost::algorithm::trim(tmp);
    return tmp;

#else

    // By default or if we have neither GDAL nor proj.4, we can't do squat
    return std::string();
#endif
}

void SpatialReference::setProj4(std::string const& v)
{
#ifdef PDAL_SRS_ENABLED
    char* poWKT = 0;
    const char* poProj4 = v.c_str();

    OGRSpatialReference srs(NULL);
    if (OGRERR_NONE != srs.importFromProj4(const_cast<char *>(poProj4)))
    {
        throw std::invalid_argument("could not import proj4 into OSRSpatialReference SetProj4");
    }

    srs.exportToWkt(&poWKT);

    std::string tmp(poWKT);
    CPLFree(poWKT);

    m_wkt = tmp;

#else
    boost::ignore_unused_variable_warning(v);
#endif

    return;
}

bool SpatialReference::equals(const SpatialReference& input) const
{
#ifdef PDAL_SRS_ENABLED

    OGRSpatialReferenceH current = OSRNewSpatialReference(getWKT(eCompoundOK, false).c_str());
    OGRSpatialReferenceH other = OSRNewSpatialReference(input.getWKT(eCompoundOK, false).c_str());

    int output = OSRIsSame(current, other);

    OSRDestroySpatialReference(current);
    OSRDestroySpatialReference(other);

    return (output==1);

#else
    boost::ignore_unused_variable_warning(input);
    throw pdal_error("SpatialReference equality testing not available without GDAL+libgeotiff support");
#endif

}

bool SpatialReference::operator==(const SpatialReference& input) const
{
    return this->equals(input);
}

bool SpatialReference::operator!=(const SpatialReference& input) const
{
    return !(this->equals(input));
}

const std::string& SpatialReference::getName() const
{
    static std::string name("pdal.spatialreference");
    return name;
}

bool SpatialReference::isGeographic() const
{
#ifdef PDAL_SRS_ENABLED

    OGRSpatialReferenceH current = OSRNewSpatialReference(getWKT(eCompoundOK, false).c_str());

    int isGeog = OSRIsGeographic(current);
    bool output(false);

    if (isGeog == 0)
        output = false;
    else
        output = true;

    OSRDestroySpatialReference(current);

    return output;
#else
    throw std::runtime_error("GDAL is not available, SpatialReference could not determine if isGeographic");
#endif
}

boost::property_tree::ptree SpatialReference::toPTree() const
{
    using boost::property_tree::ptree;
    ptree srs;

#ifdef PDAL_SRS_ENABLED
    srs.put("proj4", getProj4());
    srs.put("prettywkt", getWKT(SpatialReference::eHorizontalOnly, true));
    srs.put("wkt", getWKT(SpatialReference::eHorizontalOnly, false));
    srs.put("compoundwkt", getWKT(eCompoundOK, false));
    srs.put("prettycompoundwkt", getWKT(eCompoundOK, true));

#else

    std::string message;
    if (m_wkt.size() == 0)
    {
        message = "Reference defined with VLR keys, but GeoTIFF and GDAL support are not available to produce definition";
    }
    else if (m_wkt.size() > 0)
    {
        message = "Reference defined with WKT, but GeoTIFF and GDAL support are not available to produce definition";
    }
    else
    {
        message = "None";
    }

    srs.put("proj4", message);
    srs.put("prettywkt", message);
    srs.put("wkt", message);
    srs.put("compoundwkt", message);
    srs.put("prettycompoundwkt", message);
    srs.put("gtiff", message);
#endif

    return srs;
}

void SpatialReference::dump() const
{
    std::cout << *this;
}

std::ostream& operator<<(std::ostream& ostr, const SpatialReference& srs)
{

#ifdef PDAL_SRS_ENABLED

    std::string wkt = srs.toPTree().get<std::string>("prettycompoundwkt");
    ostr << wkt;

    return ostr;

#else
    boost::ignore_unused_variable_warning(ostr);
    boost::ignore_unused_variable_warning(srs);
    ostr << "SpatialReference data is not available without GDAL+libgeotiff support";
    return ostr;
#endif
}

std::istream& operator>>(std::istream& istr, SpatialReference& srs)
{

#ifdef PDAL_SRS_ENABLED

    SpatialReference ref;

    std::ostringstream oss;
    oss << istr.rdbuf();

    std::string wkt = oss.str();
    ref.setFromUserInput(wkt.c_str());

    srs = ref;
    return istr;

#else
    boost::ignore_unused_variable_warning(istr);
    boost::ignore_unused_variable_warning(srs);
    throw pdal_error("SpatialReference io operator>> is not available without GDAL+libgeotiff support");
#endif
}

} // namespace pdal
<|endoftext|>


<commit_before><commit_msg>Wrote tests for Repeater::fire_next(). Tests pass.<commit_after><|endoftext|>


<commit_before>
#include <cstdio>
#include <thread>

int main(int /*argc*/, char** /*argv*/)
{
    printf("test\n");
    std::this_thread::sleep_for(std::chrono::seconds(10));
}

<commit_msg>Add basic sound recording scheme and .wav file read/write<commit_after>
#include <cstdio>
#include <thread>

#include <windows.h>

#include <fstream>
#include <cstdlib>
#include <mmsystem.h>

#include <assert.h> // debugging

#include <cstdlib>

int NUM_CHANNELS = 1; // mono audio (stereo would need 2 channels)
int SAMPLES_PER_SEC = 11025;
int BITS_PER_SAMPLE = 8;

#define INP_BUFFER_SIZE SAMPLES_PER_SEC * 10

/* Declare procedures */
void SaveWavFile(char* filename, PWAVEHDR pWaveHdr);
void ReadWavFile(char* filename);

int main(int /*argc*/, char** /*argv*/)
{
    printf("test\n");

    WAVEHDR waveHdr;
    PBYTE buffer;
    HWAVEIN hWaveIn;

    /* begin sound capture */
    buffer = reinterpret_cast<PBYTE>(malloc(INP_BUFFER_SIZE));
    if (!buffer)
    {
        printf("Failed to allocate buffers\n");
        return 1;
    }

    // Open waveform audio for input
    WAVEFORMATEX waveform;
    waveform.wFormatTag = WAVE_FORMAT_PCM;
    waveform.nChannels = NUM_CHANNELS;
    waveform.nSamplesPerSec = SAMPLES_PER_SEC;
    waveform.nAvgBytesPerSec = SAMPLES_PER_SEC;
    waveform.nBlockAlign = 1;
    waveform.wBitsPerSample = BITS_PER_SAMPLE;
    waveform.cbSize = 0;

    MMRESULT result = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveform, NULL, NULL, CALLBACK_WINDOW);

    if (result)
    {
        // todo: properly print this error - WCHAR is unicode garbage
        /*
        WCHAR fault[256];
        waveInGetErrorText(result, fault, 256);
        printf("Failed to open waveform input device (fault: %s)", result);
        */

        printf("Failed to open waveform input device\n", result);
        return 1;
    }

    // Set up headers and prepare them
    waveHdr.lpData = reinterpret_cast<CHAR*>(buffer);
    waveHdr.dwBufferLength = INP_BUFFER_SIZE;
    waveHdr.dwBytesRecorded = 0;
    waveHdr.dwUser = 0;
    waveHdr.dwFlags = 0;
    waveHdr.dwLoops = 1;
    waveHdr.lpNext = NULL;
    waveHdr.reserved = 0;

    waveInPrepareHeader(hWaveIn, &waveHdr, sizeof(WAVEHDR));

    // Insert a wave input buffer
    result = waveInAddBuffer(hWaveIn, &waveHdr, sizeof(WAVEHDR));
    if (result)
    {
        printf("Failed to read block from device\n");
        return 1;
    }

    // Commence sampling input
    result = waveInStart(hWaveIn);
    if (result)
    {
        printf("Failed to start recording\n");
        return 1;
    }

    // Wait until finished recording
    do { } while (waveInUnprepareHeader(hWaveIn, &waveHdr, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING);

    waveInClose(hWaveIn);

    SaveWavFile("temp.wav", &waveHdr);

    return 0;
}

// Read the temporary wav file
void ReadWavFile(char* filename)
{
    // random variables used throughout the function
    int length, byte_samp, byte_sec;
    bool mono = TRUE;

    FILE* file;
    // open filepointer readonly
    fopen_s(&file, filename, "r");
    if (file == NULL)
        printf("Wav:: Could not open file: %s", filename);
    else
    {
        // declare a char buff to store some values in
        char *buff = new char[5];
        buff[4] = '\0';
        // read the first 4 bytes
        fread((void *)buff, 1, 4, file);
        // the first four bytes should be 'RIFF'
        if (strcmp((char *)buff, "RIFF") == 0)
        {
            // read byte 8,9,10 and 11
            fseek(file, 4, SEEK_CUR);
            fread((void *)buff, 1, 4, file);
            // this should read "WAVE"
            if (strcmp((char *)buff, "WAVE") == 0)
            {
                // read byte 12,13,14,15
                fread((void *)buff, 1, 4, file);
                // this should read "fmt "
                if (strcmp((char *)buff, "fmt ") == 0)
                {
                    fseek(file, 20, SEEK_CUR);
                    // final one read byte 36,37,38,39
                    fread((void *)buff, 1, 4, file);
                    if (strcmp((char *)buff, "data") == 0)
                    {
                        // Now we know it is a wav file, rewind the stream
                        rewind(file);
                        // now is it mono or stereo ?
                        fseek(file, 22, SEEK_CUR);
                        fread((void *)buff, 1, 2, file);

                        // bool isMono = (buff[0] & 0x02 == 0);

                        // read the sample rate
                        fread((void *)&SAMPLES_PER_SEC, 1, 4, file);
                        fread((void *)&byte_sec, 1, 4, file);
                        byte_samp = 0;
                        fread((void *)&byte_samp, 1, 2, file);

                        fread((void *)&BITS_PER_SAMPLE, 1, 2, file);
                        fseek(file, 4, SEEK_CUR);
                        fread((void *)&length, 1, 4, file);
                    }
                }
            }
        }

        delete buff;
    }
}

void SaveWavFile(char* filename, PWAVEHDR pWaveHdr)
{
    std::fstream file(filename, std::fstream::out | std::fstream::binary);

    int pcmsize = sizeof(PCMWAVEFORMAT);
    int audioFormat = WAVE_FORMAT_PCM;

    int subchunk1size = 16;
    int byteRate = SAMPLES_PER_SEC * NUM_CHANNELS * BITS_PER_SAMPLE / 8;
    int blockAlign = NUM_CHANNELS * BITS_PER_SAMPLE / 8;
    int subchunk2size = pWaveHdr->dwBufferLength * NUM_CHANNELS;
    int chunksize = (36 + subchunk2size);
    // write the wav file per the wav file format
    file.seekp(0, std::ios::beg);
    file.write("RIFF", 4);                      // chunk id
    file.write((char*)&chunksize, 4);           // chunk size (36 + SubChunk2Size))
    file.write("WAVE", 4);                      // format
    file.write("fmt ", 4);                      // subchunk1ID
    file.write((char*)&subchunk1size, 4);       // subchunk1size (16 for PCM)
    file.write((char*)&audioFormat, 2);         // AudioFormat (1 for PCM)
    file.write((char*)&NUM_CHANNELS, 2);        // NumChannels
    file.write((char*)&SAMPLES_PER_SEC, 4);     // sample rate
    file.write((char*)&byteRate, 4);            // byte rate (SampleRate * NumChannels * BitsPerSample/8)
    file.write((char*)&blockAlign, 2);          // block align (NumChannels * BitsPerSample/8)
    file.write((char*)&BITS_PER_SAMPLE, 2);     // bits per sample
    file.write("data", 4);                      // subchunk2ID
    file.write((char*)&subchunk2size, 4);       // subchunk2size (NumSamples * NumChannels * BitsPerSample/8)

    file.write(pWaveHdr->lpData, pWaveHdr->dwBufferLength); // data
    file.close();
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	メニュー・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2019 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <functional>
#include "graphics/widget.hpp"
#include "common/string_utils.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	メニュー・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct menu : public widget {

		typedef menu value_type;

		static const int16_t round_radius = 6;  // round radius
		static const int16_t item_height  = 28;	// ITEM height

		typedef std::function<void(uint32_t pos, uint32_t num)> SELECT_FUNC_TYPE;

	private:

		SELECT_FUNC_TYPE	select_func_;
		vtx::spos			item_size_;
		uint32_t			num_;
		uint32_t			select_pos_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	loc		ロケーション
			@param[in]	str		ボタン文字列
		*/
		//-----------------------------------------------------------------//
		menu(const vtx::srect& loc = vtx::srect(0), const char* str = "") noexcept :
			widget(loc, str),
			select_func_(), item_size_(0),
			num_(utils::str::get_words(str, ',')), select_pos_(num_)
		{
			if(loc.size.y <= 0) {
				at_location().size.y = num_ * item_height;
				item_size_.y = item_height;
			} else {
				item_size_.y = loc.size.y / num_;
			}
			insert_widget(this);
		}

		menu(const menu& th) = delete;
		menu& operator = (const menu& th) = delete;

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクタ
		*/
		//-----------------------------------------------------------------//
		virtual ~menu() noexcept { remove_widget(this); }

		//-----------------------------------------------------------------//
		/*!
			@brief	型整数を取得
			@return 型整数
		*/
		//-----------------------------------------------------------------//
		const char* get_name() const noexcept override { return "Menu"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ID を取得
			@return ID
		*/
		//-----------------------------------------------------------------//
		ID get_id() const noexcept override { return ID::MENU; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void init() noexcept override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ判定を更新
			@param[in]	pos		判定位置
			@param[in]	num		タッチ数
		*/
		//-----------------------------------------------------------------//
		void update_touch(const vtx::spos& pos, uint16_t num) noexcept override
		{
			update_touch_def(pos, num, false);
			const auto& st = get_touch_state();
			if(st.level_) {
				select_pos_ = st.relative_.y / item_size_.y;
			}
			if(st.negative_) {
				if(!get_focus()) {
					select_pos_ = num_;
				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	選択推移
			@param[in]	inva	無効状態にする場合「true」
		*/
		//-----------------------------------------------------------------//
		void exec_select(bool inva) noexcept override
		{
			if(select_func_) {
				select_func_(select_pos_, num_);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	許可・不許可
			@param[in]	ena		不許可の場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool ena = true) noexcept override
		{
			if(ena) {
				set_state(STATE::ENABLE);
			} else {
				set_state(STATE::DISABLE);
				reset_touch_state();
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト位置の取得
			@return	セレクト位置
		*/
		//-----------------------------------------------------------------//
		uint32_t get_select_pos() const noexcept { return select_pos_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト位置の文字取得
			@param[in]	dst		文字列バッファ
			@param[in]	len		文字列バッファサイズ
			@return	セレクト位置
		*/
		//-----------------------------------------------------------------//
		uint32_t get_select_text(char* dst, uint32_t len) const noexcept {
			utils::str::get_word(get_title(), select_pos_, dst, len, ',');
			return select_pos_;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト関数への参照
			@return	セレクト関数
		*/
		//-----------------------------------------------------------------//
		SELECT_FUNC_TYPE& at_select_func() noexcept { return select_func_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	描画
		*/
		//-----------------------------------------------------------------//
		template<class RDR>
		void draw(RDR& rdr) noexcept
		{
			auto r = vtx::srect(get_final_position(), get_location().size);
			r.size.y /= num_;
			for(uint32_t i = 0; i < num_; ++i) {
				uint8_t inten = 64;
				if(get_touch_state().level_ && select_pos_ == i) {
//					rdr.set_fore_color(graphics::def_color::Silver);
					inten = 192;
				} else {
					if(i & 1) {
//						rdr.set_fore_color(graphics::def_color::Midgray);
						inten = 96;
					} else {
//						rdr.set_fore_color(graphics::def_color::Gray);
						inten = 128;
					}
				}
				graphics::share_color sh(0, 0, 0);
				sh.set_color(get_base_color().rgba8, inten);
				rdr.set_fore_color(sh);
				bool up = false;
				bool dn = false;
				if(i == 0) up = true;
				if(i == (num_ - 1)) dn = true;
				rdr.round_box(r, round_radius, up, dn);

				char tmp[32];
				if(utils::str::get_word(get_title(), i, tmp, sizeof(tmp), ',')) {
					auto sz = rdr.at_font().get_text_size(tmp);
					rdr.set_fore_color(get_font_color());
					rdr.draw_text(r.org + (r.size - sz) / 2, tmp);
				}
				r.org.y += r.size.y;
			}
		}
	};
}
<commit_msg>Update: title management<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	メニュー・クラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2019 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <functional>
#include "graphics/widget.hpp"
#include "common/string_utils.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	メニュー・クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct menu : public widget {

		typedef menu value_type;

		static const int16_t round_radius = 6;  ///< round radius
		static const int16_t item_height  = 28;	///< ITEM height
		static const int16_t check_size   = 6;	///< check sign width/height

		typedef std::function<void(uint32_t pos, uint32_t num)> SELECT_FUNC_TYPE;

	private:

		SELECT_FUNC_TYPE	select_func_;
		vtx::spos			item_size_;
		uint32_t			num_;
		uint32_t			select_pos_;
		bool				check_draw_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	loc		ロケーション
			@param[in]	str		ボタン文字列
			@param[in]	chd		チェック描画を行わない場合「false」
		*/
		//-----------------------------------------------------------------//
		menu(const vtx::srect& loc = vtx::srect(0), const char* str = "", bool chd = true)
			noexcept :
			widget(loc, str),
			select_func_(), item_size_(0),
			num_(utils::str::get_words(str, ',')), select_pos_(0), check_draw_(chd)
		{
			if(loc.size.y <= 0) {
				at_location().size.y = num_ * item_height;
				item_size_.y = item_height;
			} else {
				item_size_.y = loc.size.y / num_;
			}
			insert_widget(this);
		}

		menu(const menu& th) = delete;
		menu& operator = (const menu& th) = delete;

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクタ
		*/
		//-----------------------------------------------------------------//
		virtual ~menu() noexcept { remove_widget(this); }

		//-----------------------------------------------------------------//
		/*!
			@brief	型整数を取得
			@return 型整数
		*/
		//-----------------------------------------------------------------//
		const char* get_name() const noexcept override { return "Menu"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ID を取得
			@return ID
		*/
		//-----------------------------------------------------------------//
		ID get_id() const noexcept override { return ID::MENU; }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void init() noexcept override { }

		//-----------------------------------------------------------------//
		/*!
			@brief	タッチ判定を更新
			@param[in]	pos		判定位置
			@param[in]	num		タッチ数
		*/
		//-----------------------------------------------------------------//
		void update_touch(const vtx::spos& pos, uint16_t num) noexcept override
		{
			update_touch_def(pos, num, false);
			const auto& st = get_touch_state();
			if(st.level_) {
				if(get_focus()) {
					auto newpos = st.relative_.y / item_size_.y;
					if(newpos >= static_cast<int16_t>(num_)) newpos = num_ - 1;
					else if(newpos < 0) newpos = 0;
					select_pos_ = newpos;
				}
			}
//			if(st.negative_) {
//				if(!get_focus()) {
//					select_pos_ = num_;
//				}
//			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	選択推移
			@param[in]	inva	無効状態にする場合「true」
		*/
		//-----------------------------------------------------------------//
		void exec_select(bool inva) noexcept override
		{
			if(select_func_) {
				select_func_(select_pos_, num_);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	タイトル更新時処理
		*/
		//-----------------------------------------------------------------//
		void update_title() noexcept override
		{
			num_ = utils::str::get_words(get_title(), ',');
			at_location().size.y = num_ * item_size_.y;
			if(select_pos_ >= num_) {
				select_pos_ = num_ - 1;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	許可・不許可
			@param[in]	ena		不許可の場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool ena = true) noexcept override
		{
			if(ena) {
				set_state(STATE::ENABLE);
			} else {
				set_state(STATE::DISABLE);
				reset_touch_state();
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アイテム数の取得
			@return	アイテム数
		*/
		//-----------------------------------------------------------------//
		uint32_t get_item_num() const noexcept { return num_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト位置の取得
			@return	セレクト位置
		*/
		//-----------------------------------------------------------------//
		uint32_t get_select_pos() const noexcept { return select_pos_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト位置の設定
			@param[in]	pos	セレクト位置
		*/
		//-----------------------------------------------------------------//
		void set_select_pos(uint32_t pos) noexcept { select_pos_ = pos; }

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト位置の文字取得
			@param[in]	dst		文字列バッファ
			@param[in]	len		文字列バッファサイズ
			@return	セレクト位置
		*/
		//-----------------------------------------------------------------//
		uint32_t get_select_text(char* dst, uint32_t len) const noexcept {
			utils::str::get_word(get_title(), select_pos_, dst, len, ',');
			return select_pos_;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	セレクト関数への参照
			@return	セレクト関数
		*/
		//-----------------------------------------------------------------//
		SELECT_FUNC_TYPE& at_select_func() noexcept { return select_func_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	描画
		*/
		//-----------------------------------------------------------------//
		template<class RDR>
		void draw(RDR& rdr) noexcept
		{
			if(num_ == 0 || get_title() == nullptr) return;

			auto r = vtx::srect(get_final_position(), get_location().size);
			r.size.y /= num_;
			for(uint32_t i = 0; i < num_; ++i) {
				uint8_t inten = 64;
				if(get_touch_state().level_ && select_pos_ == i) {
					inten = 192;
				} else {
					if(i & 1) {
						inten = 96;
					} else {
						inten = 128;
					}
				}
				graphics::share_color sh(0, 0, 0);
				sh.set_color(get_base_color().rgba8, inten);
				rdr.set_fore_color(sh);
				bool up = false;
				bool dn = false;
				if(i == 0) up = true;
				if(i == (num_ - 1)) dn = true;
				rdr.round_box(r, round_radius, up, dn);

				if(check_draw_ && i == select_pos_) {
					rdr.set_fore_color(get_base_color());
					rdr.fill_box(
						vtx::srect(r.org.x + check_size, r.org.y + (r.size.y - check_size) / 2,
						check_size, check_size));
				}

				char tmp[32];
				if(utils::str::get_word(get_title(), i, tmp, sizeof(tmp), ',')) {
					auto sz = rdr.at_font().get_text_size(tmp);
					rdr.set_fore_color(get_font_color());
					rdr.draw_text(r.org + (r.size - sz) / 2, tmp);
				}
				r.org.y += r.size.y;
			}
		}
	};
}
<|endoftext|>