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

#include "chart2uno.hxx"
#include "miscuno.hxx"
#include "docsh.hxx"
#include "unoguard.hxx"
#include "cell.hxx"

#ifndef _COM_SUN_STAR_BEANS_UNKNOWNPROPERTYEXCEPTION_HDL_
#include <com/sun/star/beans/UnknownPropertyException.hpp>
#endif

SC_SIMPLE_SERVICE_INFO( ScChart2DataProvider, "ScChart2DataProvider",
        "com.sun.star.chart2.DataProvider")
SC_SIMPLE_SERVICE_INFO( ScChart2DataSource, "ScChart2DataSource",
        "com.sun.star.chart2.DataSource")
SC_SIMPLE_SERVICE_INFO( ScChart2DataSequence, "ScChart2DataSequence",
        "com.sun.star.chart2.DataSequence")

using namespace ::com::sun::star;

// DataProvider ==============================================================

ScChart2DataProvider::ScChart2DataProvider( ScDocShell* pDocSh)
    : pDocShell( pDocSh)
{
    if ( pDocShell )
        pDocShell->GetDocument()->AddUnoObject( *this);
}

ScChart2DataProvider::~ScChart2DataProvider()
{
    if ( pDocShell )
        pDocShell->GetDocument()->RemoveUnoObject( *this);
}

void ScChart2DataProvider::Notify( SfxBroadcaster& rBC, const SfxHint& rHint)
{
    if ( rHint.ISA( SfxSimpleHint ) &&
            ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    {
        pDocShell = NULL;
    }
}

uno::Reference< chart2::XDataSource> SAL_CALL
ScChart2DataProvider::getDataByRangeRepresentation(
        const ::rtl::OUString& rRangeRepresentation)
            throw( lang::IllegalArgumentException, uno::RuntimeException)
{
    // FIXME: every call a new object?!? Or create hash of rRangeRepresentation?
    if ( pDocShell )
    {
        ScUnoGuard aGuard;
        ScRangeList aRangeList;
        USHORT nValid = aRangeList.Parse( rRangeRepresentation,
                pDocShell->GetDocument());
        if ( (nValid & SCA_VALID) == SCA_VALID )
        {
            // FIXME: add glue mechanism similar to ScChartArray::GlueState(),
            // for now this is a simple join
            ScRangeListRef xRanges = new ScRangeList;
            for ( ScRangePtr p = aRangeList.First(); p; p = aRangeList.Next())
            {
                xRanges->Join( *p );
            }
            return new ScChart2DataSource( pDocShell, xRanges);
        }
        throw lang::IllegalArgumentException();
    }
    throw uno::RuntimeException();
    return 0;
}

uno::Reference< chart2::XDataSequence> SAL_CALL
ScChart2DataProvider::getDataSequenceByRangeIdentifier(
        const ::rtl::OUString& rRangeIdentifier)
            throw( lang::IllegalArgumentException, uno::RuntimeException)
{
    // FIXME: find and return data sequence that matches rRangeIdentifier
    throw uno::RuntimeException();
    return 0;
}

uno::Reference< chart2::XDataSequence> SAL_CALL
ScChart2DataProvider::replaceRange(
        const uno::Reference< chart2::XDataSequence>& rSeq)
            throw( lang::IllegalArgumentException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
    return 0;
}

void SAL_CALL ScChart2DataProvider::addDataChangeListener(
        const uno::Reference< chart2::XDataChangeListener>& rListener,
        const uno::Reference< chart2::XDataSource>& rData)
            throw( uno::RuntimeException)
{
    // FIXME: real implementation, reuse ScChartListener
    throw uno::RuntimeException();
}

void SAL_CALL ScChart2DataProvider::removeDataChangeListener(
        const uno::Reference< chart2::XDataChangeListener>& rListener,
        const uno::Reference< chart2::XDataSource>& rData)
            throw( lang::IllegalArgumentException, uno::RuntimeException)
{
    // FIXME: real implementation, reuse ScChartListener
    throw uno::RuntimeException();
}

// DataSource ================================================================

ScChart2DataSource::ScChart2DataSource( ScDocShell* pDocSh,
        const ScRangeListRef& rRangeList)
    : pDocShell( pDocSh)
    , xRanges( rRangeList)
{
    if ( pDocShell )
        pDocShell->GetDocument()->AddUnoObject( *this);
}

ScChart2DataSource::~ScChart2DataSource()
{
    if ( pDocShell )
        pDocShell->GetDocument()->RemoveUnoObject( *this);
}

void ScChart2DataSource::Notify( SfxBroadcaster& rBC, const SfxHint& rHint)
{
    if ( rHint.ISA( SfxSimpleHint ) &&
            ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    {
        pDocShell = NULL;
    }
}

uno::Sequence< uno::Reference< chart2::XDataSequence> > SAL_CALL
ScChart2DataSource::getDataSequences() throw ( uno::RuntimeException)
{
    ScUnoGuard aGuard;
    typedef ::std::vector< chart2::XDataSequence *> tVec;
    tVec aVec;
    // split into columns - FIXME: different if GlueState() is used
    for ( ScRangePtr p = xRanges->First(); p; p = xRanges->Next())
    {
        for ( SCCOL nCol = p->aStart.Col(); nCol <= p->aEnd.Col(); ++nCol)
        {
            ScRangeListRef aColRanges = new ScRangeList;
            // one single sheet selected assumed for now
            aColRanges->Append( ScRange( nCol, p->aStart.Row(),
                        p->aStart.Tab(), nCol, p->aEnd.Row(),
                        p->aStart.Tab()));
            // TODO: create pure Numerical and Text sequences if possible
            aVec.push_back( new ScChart2DataSequence( pDocShell,
                        aColRanges));
        }
    }
    uno::Sequence< uno::Reference< chart2::XDataSequence> > aSequences(
            aVec.size());
    uno::Reference< chart2::XDataSequence> * pArr = aSequences.getArray();
    sal_Int32 j = 0;
    for ( tVec::const_iterator iSeq = aVec.begin(); iSeq != aVec.end();
            ++iSeq, ++j)
    {
        pArr[j] = *iSeq;
    }
    return aSequences;
}

// DataSequence ==============================================================

ScChart2DataSequence::ScChart2DataSequence( ScDocShell* pDocSh,
        const ScRangeListRef& rRangeList)
    : bHidden( sal_False)
    , xRanges( rRangeList)
    , pDocShell( pDocSh)
{
    if ( pDocShell )
        pDocShell->GetDocument()->AddUnoObject( *this);
    // FIXME: real implementation of identifier and it's mapping to ranges.
    // Reuse ScChartListener?
    aIdentifier = ::rtl::OUString::createFromAscii( "ScChart2DataSequence_dummy_ID_");
    static sal_Int32 nID = 0;
    aIdentifier += ::rtl::OUString::valueOf( ++nID);
}

ScChart2DataSequence::~ScChart2DataSequence()
{
    if ( pDocShell )
        pDocShell->GetDocument()->RemoveUnoObject( *this);
}

void ScChart2DataSequence::Notify( SfxBroadcaster& rBC, const SfxHint& rHint)
{
    if ( rHint.ISA( SfxSimpleHint ) &&
            ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    {
        pDocShell = NULL;
    }
}

uno::Sequence< uno::Any> SAL_CALL ScChart2DataSequence::getData()
            throw ( uno::RuntimeException)
{
    if ( !pDocShell)
        throw uno::RuntimeException();

    ScUnoGuard aGuard;
    const ScDocument* pDoc = pDocShell->GetDocument();
    sal_Int32 nCount = 0;
    ScRangePtr p;
    for ( p = xRanges->First(); p; p = xRanges->Next())
    {
        nCount += sal_Int32(p->aEnd.Col() - p->aStart.Col() + 1) *
            (p->aEnd.Row() - p->aStart.Row() + 1) * (p->aEnd.Tab() -
                                                     p->aStart.Tab() + 1);
    }
    uno::Sequence< uno::Any> aSeq( nCount);
    uno::Any * pArr = aSeq.getArray();
    nCount = 0;
    for ( p = xRanges->First(); p; p = xRanges->Next())
    {
        // TODO: use DocIter?
        ScAddress aAdr( p->aStart);
        for ( SCTAB nTab = p->aStart.Tab(); nTab <= p->aEnd.Tab(); ++nTab)
        {
            aAdr.SetTab( nTab);
            for ( SCCOL nCol = p->aStart.Col(); nCol <= p->aEnd.Col(); ++nCol)
            {
                aAdr.SetCol( nCol);
                for ( SCROW nRow = p->aStart.Row(); nRow <= p->aEnd.Row();
                        ++nRow)
                {
                    aAdr.SetRow( nRow);
                    ScBaseCell* pCell = pDoc->GetCell( aAdr);
                    if ( pCell)
                    {
                        switch ( pCell->GetCellType())
                        {
                            case CELLTYPE_VALUE:
                                pArr[nCount] <<= static_cast< ScValueCell*>(
                                        pCell)->GetValue();
                            break;
                            case CELLTYPE_FORMULA:
                            {
                                ScFormulaCell* pFCell = static_cast<
                                    ScFormulaCell*>( pCell);
                                USHORT nErr = pFCell->GetErrCode();
                                if  ( !nErr)
                                {
                                    if ( pFCell->HasValueData())
                                        pArr[nCount] <<= pFCell->GetValue();
                                    else
                                    {
                                        String aStr;
                                        pFCell->GetString( aStr);
                                        pArr[nCount] <<= ::rtl::OUString(
                                                aStr);
                                    }
                                }
                            }
                            default:
                            {
                                if ( pCell->HasStringData())
                                    pArr[nCount] <<= ::rtl::OUString(
                                            pCell->GetStringData());
                            }
                        }
                    }
                    ++nCount;
                }
            }
        }
    }
    return aSeq;
}

::rtl::OUString SAL_CALL ScChart2DataSequence::getSourceIdentifier()
            throw ( uno::RuntimeException)
{
    return aIdentifier;
}

// DataSequence XPropertySet -------------------------------------------------

uno::Reference< beans::XPropertySetInfo> SAL_CALL
ScChart2DataSequence::getPropertySetInfo() throw( uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
    return 0;
}

void SAL_CALL ScChart2DataSequence::setPropertyValue(
        const ::rtl::OUString& rPropertyName, const uno::Any& rValue)
            throw( beans::UnknownPropertyException,
                    beans::PropertyVetoException,
                    lang::IllegalArgumentException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Role")))
    {
        if ( !(rValue >>= aRole))
            throw lang::IllegalArgumentException();
    }
    else if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Hidden")))
    {
        if ( !(rValue >>= bHidden))
            throw lang::IllegalArgumentException();
    }
    else
        throw beans::UnknownPropertyException();
    // TODO: support optional properties
}

uno::Any SAL_CALL ScChart2DataSequence::getPropertyValue(
        const ::rtl::OUString& rPropertyName)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    uno::Any aRet;
    if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Role")))
        aRet <<= aRole;
    else if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Hidden")))
        aRet <<= bHidden;
    else
        throw beans::UnknownPropertyException();
    // TODO: support optional properties
    return aRet;
}

void SAL_CALL ScChart2DataSequence::addPropertyChangeListener(
        const ::rtl::OUString& rPropertyName,
        const uno::Reference< beans::XPropertyChangeListener>& xListener)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
}

void SAL_CALL ScChart2DataSequence::removePropertyChangeListener(
        const ::rtl::OUString& rPropertyName,
        const uno::Reference< beans::XPropertyChangeListener>& rListener)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
}

void SAL_CALL ScChart2DataSequence::addVetoableChangeListener(
        const ::rtl::OUString& rPropertyName,
        const uno::Reference< beans::XVetoableChangeListener>& rListener)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
}

void SAL_CALL ScChart2DataSequence::removeVetoableChangeListener(
        const ::rtl::OUString& rPropertyName,
        const uno::Reference< beans::XVetoableChangeListener>& rListener)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.450); FILE MERGED 2005/09/05 15:08:49 rt 1.3.450.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: chart2uno.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 22:43:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "chart2uno.hxx"
#include "miscuno.hxx"
#include "docsh.hxx"
#include "unoguard.hxx"
#include "cell.hxx"

#ifndef _COM_SUN_STAR_BEANS_UNKNOWNPROPERTYEXCEPTION_HDL_
#include <com/sun/star/beans/UnknownPropertyException.hpp>
#endif

SC_SIMPLE_SERVICE_INFO( ScChart2DataProvider, "ScChart2DataProvider",
        "com.sun.star.chart2.DataProvider")
SC_SIMPLE_SERVICE_INFO( ScChart2DataSource, "ScChart2DataSource",
        "com.sun.star.chart2.DataSource")
SC_SIMPLE_SERVICE_INFO( ScChart2DataSequence, "ScChart2DataSequence",
        "com.sun.star.chart2.DataSequence")

using namespace ::com::sun::star;

// DataProvider ==============================================================

ScChart2DataProvider::ScChart2DataProvider( ScDocShell* pDocSh)
    : pDocShell( pDocSh)
{
    if ( pDocShell )
        pDocShell->GetDocument()->AddUnoObject( *this);
}

ScChart2DataProvider::~ScChart2DataProvider()
{
    if ( pDocShell )
        pDocShell->GetDocument()->RemoveUnoObject( *this);
}

void ScChart2DataProvider::Notify( SfxBroadcaster& rBC, const SfxHint& rHint)
{
    if ( rHint.ISA( SfxSimpleHint ) &&
            ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    {
        pDocShell = NULL;
    }
}

uno::Reference< chart2::XDataSource> SAL_CALL
ScChart2DataProvider::getDataByRangeRepresentation(
        const ::rtl::OUString& rRangeRepresentation)
            throw( lang::IllegalArgumentException, uno::RuntimeException)
{
    // FIXME: every call a new object?!? Or create hash of rRangeRepresentation?
    if ( pDocShell )
    {
        ScUnoGuard aGuard;
        ScRangeList aRangeList;
        USHORT nValid = aRangeList.Parse( rRangeRepresentation,
                pDocShell->GetDocument());
        if ( (nValid & SCA_VALID) == SCA_VALID )
        {
            // FIXME: add glue mechanism similar to ScChartArray::GlueState(),
            // for now this is a simple join
            ScRangeListRef xRanges = new ScRangeList;
            for ( ScRangePtr p = aRangeList.First(); p; p = aRangeList.Next())
            {
                xRanges->Join( *p );
            }
            return new ScChart2DataSource( pDocShell, xRanges);
        }
        throw lang::IllegalArgumentException();
    }
    throw uno::RuntimeException();
    return 0;
}

uno::Reference< chart2::XDataSequence> SAL_CALL
ScChart2DataProvider::getDataSequenceByRangeIdentifier(
        const ::rtl::OUString& rRangeIdentifier)
            throw( lang::IllegalArgumentException, uno::RuntimeException)
{
    // FIXME: find and return data sequence that matches rRangeIdentifier
    throw uno::RuntimeException();
    return 0;
}

uno::Reference< chart2::XDataSequence> SAL_CALL
ScChart2DataProvider::replaceRange(
        const uno::Reference< chart2::XDataSequence>& rSeq)
            throw( lang::IllegalArgumentException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
    return 0;
}

void SAL_CALL ScChart2DataProvider::addDataChangeListener(
        const uno::Reference< chart2::XDataChangeListener>& rListener,
        const uno::Reference< chart2::XDataSource>& rData)
            throw( uno::RuntimeException)
{
    // FIXME: real implementation, reuse ScChartListener
    throw uno::RuntimeException();
}

void SAL_CALL ScChart2DataProvider::removeDataChangeListener(
        const uno::Reference< chart2::XDataChangeListener>& rListener,
        const uno::Reference< chart2::XDataSource>& rData)
            throw( lang::IllegalArgumentException, uno::RuntimeException)
{
    // FIXME: real implementation, reuse ScChartListener
    throw uno::RuntimeException();
}

// DataSource ================================================================

ScChart2DataSource::ScChart2DataSource( ScDocShell* pDocSh,
        const ScRangeListRef& rRangeList)
    : pDocShell( pDocSh)
    , xRanges( rRangeList)
{
    if ( pDocShell )
        pDocShell->GetDocument()->AddUnoObject( *this);
}

ScChart2DataSource::~ScChart2DataSource()
{
    if ( pDocShell )
        pDocShell->GetDocument()->RemoveUnoObject( *this);
}

void ScChart2DataSource::Notify( SfxBroadcaster& rBC, const SfxHint& rHint)
{
    if ( rHint.ISA( SfxSimpleHint ) &&
            ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    {
        pDocShell = NULL;
    }
}

uno::Sequence< uno::Reference< chart2::XDataSequence> > SAL_CALL
ScChart2DataSource::getDataSequences() throw ( uno::RuntimeException)
{
    ScUnoGuard aGuard;
    typedef ::std::vector< chart2::XDataSequence *> tVec;
    tVec aVec;
    // split into columns - FIXME: different if GlueState() is used
    for ( ScRangePtr p = xRanges->First(); p; p = xRanges->Next())
    {
        for ( SCCOL nCol = p->aStart.Col(); nCol <= p->aEnd.Col(); ++nCol)
        {
            ScRangeListRef aColRanges = new ScRangeList;
            // one single sheet selected assumed for now
            aColRanges->Append( ScRange( nCol, p->aStart.Row(),
                        p->aStart.Tab(), nCol, p->aEnd.Row(),
                        p->aStart.Tab()));
            // TODO: create pure Numerical and Text sequences if possible
            aVec.push_back( new ScChart2DataSequence( pDocShell,
                        aColRanges));
        }
    }
    uno::Sequence< uno::Reference< chart2::XDataSequence> > aSequences(
            aVec.size());
    uno::Reference< chart2::XDataSequence> * pArr = aSequences.getArray();
    sal_Int32 j = 0;
    for ( tVec::const_iterator iSeq = aVec.begin(); iSeq != aVec.end();
            ++iSeq, ++j)
    {
        pArr[j] = *iSeq;
    }
    return aSequences;
}

// DataSequence ==============================================================

ScChart2DataSequence::ScChart2DataSequence( ScDocShell* pDocSh,
        const ScRangeListRef& rRangeList)
    : bHidden( sal_False)
    , xRanges( rRangeList)
    , pDocShell( pDocSh)
{
    if ( pDocShell )
        pDocShell->GetDocument()->AddUnoObject( *this);
    // FIXME: real implementation of identifier and it's mapping to ranges.
    // Reuse ScChartListener?
    aIdentifier = ::rtl::OUString::createFromAscii( "ScChart2DataSequence_dummy_ID_");
    static sal_Int32 nID = 0;
    aIdentifier += ::rtl::OUString::valueOf( ++nID);
}

ScChart2DataSequence::~ScChart2DataSequence()
{
    if ( pDocShell )
        pDocShell->GetDocument()->RemoveUnoObject( *this);
}

void ScChart2DataSequence::Notify( SfxBroadcaster& rBC, const SfxHint& rHint)
{
    if ( rHint.ISA( SfxSimpleHint ) &&
            ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
    {
        pDocShell = NULL;
    }
}

uno::Sequence< uno::Any> SAL_CALL ScChart2DataSequence::getData()
            throw ( uno::RuntimeException)
{
    if ( !pDocShell)
        throw uno::RuntimeException();

    ScUnoGuard aGuard;
    const ScDocument* pDoc = pDocShell->GetDocument();
    sal_Int32 nCount = 0;
    ScRangePtr p;
    for ( p = xRanges->First(); p; p = xRanges->Next())
    {
        nCount += sal_Int32(p->aEnd.Col() - p->aStart.Col() + 1) *
            (p->aEnd.Row() - p->aStart.Row() + 1) * (p->aEnd.Tab() -
                                                     p->aStart.Tab() + 1);
    }
    uno::Sequence< uno::Any> aSeq( nCount);
    uno::Any * pArr = aSeq.getArray();
    nCount = 0;
    for ( p = xRanges->First(); p; p = xRanges->Next())
    {
        // TODO: use DocIter?
        ScAddress aAdr( p->aStart);
        for ( SCTAB nTab = p->aStart.Tab(); nTab <= p->aEnd.Tab(); ++nTab)
        {
            aAdr.SetTab( nTab);
            for ( SCCOL nCol = p->aStart.Col(); nCol <= p->aEnd.Col(); ++nCol)
            {
                aAdr.SetCol( nCol);
                for ( SCROW nRow = p->aStart.Row(); nRow <= p->aEnd.Row();
                        ++nRow)
                {
                    aAdr.SetRow( nRow);
                    ScBaseCell* pCell = pDoc->GetCell( aAdr);
                    if ( pCell)
                    {
                        switch ( pCell->GetCellType())
                        {
                            case CELLTYPE_VALUE:
                                pArr[nCount] <<= static_cast< ScValueCell*>(
                                        pCell)->GetValue();
                            break;
                            case CELLTYPE_FORMULA:
                            {
                                ScFormulaCell* pFCell = static_cast<
                                    ScFormulaCell*>( pCell);
                                USHORT nErr = pFCell->GetErrCode();
                                if  ( !nErr)
                                {
                                    if ( pFCell->HasValueData())
                                        pArr[nCount] <<= pFCell->GetValue();
                                    else
                                    {
                                        String aStr;
                                        pFCell->GetString( aStr);
                                        pArr[nCount] <<= ::rtl::OUString(
                                                aStr);
                                    }
                                }
                            }
                            default:
                            {
                                if ( pCell->HasStringData())
                                    pArr[nCount] <<= ::rtl::OUString(
                                            pCell->GetStringData());
                            }
                        }
                    }
                    ++nCount;
                }
            }
        }
    }
    return aSeq;
}

::rtl::OUString SAL_CALL ScChart2DataSequence::getSourceIdentifier()
            throw ( uno::RuntimeException)
{
    return aIdentifier;
}

// DataSequence XPropertySet -------------------------------------------------

uno::Reference< beans::XPropertySetInfo> SAL_CALL
ScChart2DataSequence::getPropertySetInfo() throw( uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
    return 0;
}

void SAL_CALL ScChart2DataSequence::setPropertyValue(
        const ::rtl::OUString& rPropertyName, const uno::Any& rValue)
            throw( beans::UnknownPropertyException,
                    beans::PropertyVetoException,
                    lang::IllegalArgumentException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Role")))
    {
        if ( !(rValue >>= aRole))
            throw lang::IllegalArgumentException();
    }
    else if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Hidden")))
    {
        if ( !(rValue >>= bHidden))
            throw lang::IllegalArgumentException();
    }
    else
        throw beans::UnknownPropertyException();
    // TODO: support optional properties
}

uno::Any SAL_CALL ScChart2DataSequence::getPropertyValue(
        const ::rtl::OUString& rPropertyName)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    uno::Any aRet;
    if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Role")))
        aRet <<= aRole;
    else if ( rPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Hidden")))
        aRet <<= bHidden;
    else
        throw beans::UnknownPropertyException();
    // TODO: support optional properties
    return aRet;
}

void SAL_CALL ScChart2DataSequence::addPropertyChangeListener(
        const ::rtl::OUString& rPropertyName,
        const uno::Reference< beans::XPropertyChangeListener>& xListener)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
}

void SAL_CALL ScChart2DataSequence::removePropertyChangeListener(
        const ::rtl::OUString& rPropertyName,
        const uno::Reference< beans::XPropertyChangeListener>& rListener)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
}

void SAL_CALL ScChart2DataSequence::addVetoableChangeListener(
        const ::rtl::OUString& rPropertyName,
        const uno::Reference< beans::XVetoableChangeListener>& rListener)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
}

void SAL_CALL ScChart2DataSequence::removeVetoableChangeListener(
        const ::rtl::OUString& rPropertyName,
        const uno::Reference< beans::XVetoableChangeListener>& rListener)
            throw( beans::UnknownPropertyException,
                    lang::WrappedTargetException, uno::RuntimeException)
{
    // FIXME: real implementation
    throw uno::RuntimeException();
}

<|endoftext|>


<commit_before>#include "HgTexture.h"
#include <glew.h>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

#include <vector>

HgTexture::gpuUpdateTextureFunction HgTexture::updateTextureFunc;
AssetManager<HgTexture> HgTexture::imageMap;

HgTexture::TexturePtr HgTexture::acquire(const std::string& path, TextureType type) {
	bool isNew = false;
	auto ptr = imageMap.get(path, &isNew);
	if (ptr == nullptr) {
		fprintf(stderr, "Could not open image \"%s\"", path.c_str());
	}
	if (isNew) {
		ptr->setType(type);
	}
	return std::move( ptr );
}
/*
void HgTexture::release(HgTexture* t) {
	if (imageMap.isValid()) { //make sure map hasn't been destroyed (when program exiting)
		imageMap.remove(t->m_path);
	}
	delete t;
}
*/
HgTexture::HgTexture()
{
	data = nullptr;
	gpuId = 0;
	m_type = DIFFUSE;
	m_uniqueId = 0;
}

HgTexture::~HgTexture()
{
	if (gpuId > 0) glDeleteTextures(1,&gpuId); //FIXME abstract this
	SAFE_FREE(data);
}

bool HgTexture::stb_load(FILE* f) {
	int x, y, fileChannels;
//	stbi_set_flip_vertically_on_load(1);
	data = stbi_load_from_file(f, &x, &y, &fileChannels, 0);
	m_properties.format = (HgTexture::format)fileChannels;
	m_properties.width = x;
	m_properties.height = y;
	fclose(f);

	return data != NULL;
}

struct DDS_PIXELFORMAT {
	uint32_t size;
	uint32_t flags;
	uint32_t fourCC;
	uint32_t RGBBitCount;
	uint32_t RBitMask;
	uint32_t GBitMask;
	uint32_t BBitMask;
	uint32_t ABitMask;
};

typedef struct {
	uint32_t size;
	uint32_t flags;
	uint32_t height;
	uint32_t width;
	uint32_t pitchOrLinearSize;
	uint32_t depth;
	uint32_t mipMapCount;
	uint32_t reserved[11];
	DDS_PIXELFORMAT ddspf;
	uint32_t caps;
	uint32_t caps2;
	uint32_t caps3;
	uint32_t caps4;
	uint32_t reserved2;
} DDS_HEADER;

typedef struct {
	uint32_t dxgiFormat;
	uint32_t resourceDimension;
	uint32_t miscFlag;
	uint32_t arraySize;
	uint32_t miscFlags2;
} DDS_HEADER_DXT10;

#define DDPF_FOURCC 0x4
#define DX10 0x30315844

bool HgTexture::dds_load(FILE* f) {
	DDS_HEADER header;
	DDS_HEADER_DXT10 dx10Header;

	fread(&header, 124, 1, f);

	if (header.ddspf.flags == DDPF_FOURCC && header.ddspf.fourCC == DX10)
	{
		fread(&dx10Header, 20, 1, f);
	}

	Properties p;

	p.height = header.height;
	p.width = header.width;
	p.mipMapCount = header.mipMapCount;
	p.format = (HgTexture::format)header.ddspf.fourCC;
	m_properties = p;

	const auto linearSize = header.pitchOrLinearSize;
	const uint32_t size = p.mipMapCount > 1 ? linearSize * 2 : linearSize;

	data = (unsigned char*)malloc(size);
	fread(data, 1, size, f);
	fclose(f);

	return true;
}

bool HgTexture::load(const std::string& path) {
	bool r = load_internal(path);
	if (r) {
		setNeedsGPUUpdate(true);
	}
	return r;
}

bool HgTexture::load_internal(std::string path) {
	std::hash<std::string> hashFunc;
	m_uniqueId = hashFunc(path);

	char filecode[4];
	FILE *f = fopen(path.c_str(), "rb");
	if (f == nullptr) {
		fprintf(stderr, "Unable to open file \"%s\"", path.c_str());
		return false;
	}

	m_path = std::move(path);

	fread(filecode, 1, 4, f);
	if (strncmp(filecode, "DDS ", 4) != 0) {
		fseek(f, 0, SEEK_SET);
		return stb_load(f);
	}

	return dds_load(f);
}

void HgTexture::sendToGPU()
{
//	gpuId = updateTextureFunc(m_width, m_height, m_channels, data);
	setNeedsGPUUpdate(false);
	gpuId = updateTextureFunc(this);
	SAFE_FREE(data);
}
<commit_msg>check for dds magic word first<commit_after>#include "HgTexture.h"
#include <glew.h>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

#include <vector>

HgTexture::gpuUpdateTextureFunction HgTexture::updateTextureFunc;
AssetManager<HgTexture> HgTexture::imageMap;

HgTexture::TexturePtr HgTexture::acquire(const std::string& path, TextureType type) {
	bool isNew = false;
	auto ptr = imageMap.get(path, &isNew);
	if (ptr == nullptr) {
		fprintf(stderr, "Could not open image \"%s\"", path.c_str());
	}
	if (isNew) {
		ptr->setType(type);
	}
	return std::move( ptr );
}
/*
void HgTexture::release(HgTexture* t) {
	if (imageMap.isValid()) { //make sure map hasn't been destroyed (when program exiting)
		imageMap.remove(t->m_path);
	}
	delete t;
}
*/
HgTexture::HgTexture()
{
	data = nullptr;
	gpuId = 0;
	m_type = DIFFUSE;
	m_uniqueId = 0;
}

HgTexture::~HgTexture()
{
	if (gpuId > 0) glDeleteTextures(1,&gpuId); //FIXME abstract this
	SAFE_FREE(data);
}

bool HgTexture::stb_load(FILE* f) {
	int x, y, fileChannels;
//	stbi_set_flip_vertically_on_load(1);
	data = stbi_load_from_file(f, &x, &y, &fileChannels, 0);
	m_properties.format = (HgTexture::format)fileChannels;
	m_properties.width = x;
	m_properties.height = y;
	fclose(f);

	return data != NULL;
}

struct DDS_PIXELFORMAT {
	uint32_t size;
	uint32_t flags;
	uint32_t fourCC;
	uint32_t RGBBitCount;
	uint32_t RBitMask;
	uint32_t GBitMask;
	uint32_t BBitMask;
	uint32_t ABitMask;
};

typedef struct {
	uint32_t size;
	uint32_t flags;
	uint32_t height;
	uint32_t width;
	uint32_t pitchOrLinearSize;
	uint32_t depth;
	uint32_t mipMapCount;
	uint32_t reserved[11];
	DDS_PIXELFORMAT ddspf;
	uint32_t caps;
	uint32_t caps2;
	uint32_t caps3;
	uint32_t caps4;
	uint32_t reserved2;
} DDS_HEADER;

typedef struct {
	uint32_t dxgiFormat;
	uint32_t resourceDimension;
	uint32_t miscFlag;
	uint32_t arraySize;
	uint32_t miscFlags2;
} DDS_HEADER_DXT10;

#define DDPF_FOURCC 0x4
#define DX10 0x30315844

bool HgTexture::dds_load(FILE* f) {
	DDS_HEADER header;
	DDS_HEADER_DXT10 dx10Header;

	fread(&header, 124, 1, f);

	if (header.ddspf.flags == DDPF_FOURCC && header.ddspf.fourCC == DX10)
	{
		fread(&dx10Header, 20, 1, f);
	}

	Properties p;

	p.height = header.height;
	p.width = header.width;
	p.mipMapCount = header.mipMapCount;
	p.format = (HgTexture::format)header.ddspf.fourCC;
	m_properties = p;

	const auto linearSize = header.pitchOrLinearSize;
	const uint32_t size = p.mipMapCount > 1 ? linearSize * 2 : linearSize;

	data = (unsigned char*)malloc(size);
	fread(data, 1, size, f);
	fclose(f);

	return true;
}

bool HgTexture::load(const std::string& path) {
	bool r = load_internal(path);
	if (r) {
		setNeedsGPUUpdate(true);
	}
	return r;
}

bool HgTexture::load_internal(std::string path) {
	std::hash<std::string> hashFunc;
	m_uniqueId = hashFunc(path);

	char filecode[4];
	FILE *f = fopen(path.c_str(), "rb");
	if (f == nullptr) {
		fprintf(stderr, "Unable to open file \"%s\"", path.c_str());
		return false;
	}

	m_path = std::move(path);

	fread(filecode, 1, 4, f);
	if (strncmp(filecode, "DDS ", 4) == 0)
	{
		return dds_load(f);
	}

	fseek(f, 0, SEEK_SET);
	return stb_load(f);
}

void HgTexture::sendToGPU()
{
//	gpuId = updateTextureFunc(m_width, m_height, m_channels, data);
	setNeedsGPUUpdate(false);
	gpuId = updateTextureFunc(this);
	SAFE_FREE(data);
}
<|endoftext|>


<commit_before>/* Copyright 2013 Roman Kurbatov
 *
 * 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.
 *
 * This file was modified by Yurii Litvinov to make it comply with the requirements of trikRuntime
 * project. See git revision history for detailed changes. */

#include "trikGuiApplication.h"

#include <QtGui/QKeyEvent>
#include <QtCore/QProcess>
#include <QtWidgets/QWidget>

#include "backgroundWidget.h"

using namespace trikGui;

TrikGuiApplication::TrikGuiApplication(int &argc, char **argv)
	: QApplication(argc, argv)
{
	connect(&mPowerButtonPressedTimer, &QTimer::timeout, this, &TrikGuiApplication::shutdownSoon);
	connect(&mShutdownDelayTimer, &QTimer::timeout, this, &TrikGuiApplication::shutdown);
	mPowerButtonPressedTimer.setSingleShot(true);
	mShutdownDelayTimer.setSingleShot(true);
}

static bool isTrikPowerOffKey(Qt::Key key) {
	return key == Qt::Key_PowerOff || ( key == Qt::Key_W && (QApplication::keyboardModifiers() & Qt::ControlModifier));
}

bool TrikGuiApplication::notify(QObject *receiver, QEvent *event)
{
	if (event->type() == QEvent::KeyPress) {
		QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event);
		if (isTrikPowerOffKey(static_cast<Qt::Key>(keyEvent->key()))) {
			if (keyEvent->isAutoRepeat()) {
				//	if (!mPowerButtonPressedTimer.isActive()) {
				//	mPowerButtonPressedTimer.start(2000);
				//	}
			} else {
				if (!mPowerButtonPressedTimer.isActive()) {
					mPowerButtonPressedTimer.start(2000);
				}
				mIsShutdownRequested = true;
				refreshWidgets(); // refresh display if not auto-repeat
			}
			static QKeyEvent evntKeyPowerOff(QEvent::KeyPress, Qt::Key_PowerOff, Qt::NoModifier);
			event = &evntKeyPowerOff;
		}
	} else if (event->type() == QEvent::KeyRelease) {
		QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event);
		if (isTrikPowerOffKey(static_cast<Qt::Key>(keyEvent->key()))) {
			if (!keyEvent->isAutoRepeat()) {
				mIsShutdownRequested = false;
//				if (mPowerButtonPressedTimer.isActive()) {
//					mPowerButtonPressedTimer.stop();
//				}
			} else {
			}
			static QKeyEvent evntKeyPowerOff(QEvent::KeyRelease, Qt::Key_PowerOff, Qt::NoModifier);
			event = &evntKeyPowerOff;
		}
	}

	return QApplication::notify(receiver, event);
}

void TrikGuiApplication::refreshWidgets()
{
	if (dynamic_cast<BackgroundWidget *>(QApplication::activeWindow())) {
		for (const auto widget : QApplication::allWidgets()) {
			widget->update();
		}
	}
}

void TrikGuiApplication::shutdown()
{
	if(!mIsShutdownRequested) {
		setStyleSheet(mSavedStyleSheet);
		return;
	}

	QProcess::startDetached("/sbin/shutdown", {"-h", "-P", "now" });
	QCoreApplication::quit();
}

void TrikGuiApplication::shutdownSoon()
{
	if(mShutdownDelayTimer.isActive() || !mIsShutdownRequested) {
		return;
	}

	mSavedStyleSheet = styleSheet();
	setStyleSheet(mSavedStyleSheet + " QWidget { background-color:red; } ");
	mShutdownDelayTimer.start(2000);
}
<commit_msg>Reduce delay before shutdown<commit_after>/* Copyright 2013 Roman Kurbatov
 *
 * 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.
 *
 * This file was modified by Yurii Litvinov to make it comply with the requirements of trikRuntime
 * project. See git revision history for detailed changes. */

#include "trikGuiApplication.h"

#include <QtGui/QKeyEvent>
#include <QtCore/QProcess>
#include <QtWidgets/QWidget>

#include "backgroundWidget.h"

using namespace trikGui;

TrikGuiApplication::TrikGuiApplication(int &argc, char **argv)
	: QApplication(argc, argv)
{
	connect(&mPowerButtonPressedTimer, &QTimer::timeout, this, &TrikGuiApplication::shutdownSoon);
	connect(&mShutdownDelayTimer, &QTimer::timeout, this, &TrikGuiApplication::shutdown);
	mPowerButtonPressedTimer.setSingleShot(true);
	mShutdownDelayTimer.setSingleShot(true);
}

static bool isTrikPowerOffKey(Qt::Key key) {
	return key == Qt::Key_PowerOff || ( key == Qt::Key_W && (QApplication::keyboardModifiers() & Qt::ControlModifier));
}

bool TrikGuiApplication::notify(QObject *receiver, QEvent *event)
{
	if (event->type() == QEvent::KeyPress) {
		QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event);
		if (isTrikPowerOffKey(static_cast<Qt::Key>(keyEvent->key()))) {
			if (keyEvent->isAutoRepeat()) {
				//	if (!mPowerButtonPressedTimer.isActive()) {
				//	mPowerButtonPressedTimer.start(2000);
				//	}
			} else {
				if (!mPowerButtonPressedTimer.isActive()) {
					mPowerButtonPressedTimer.start(1500);
				}
				mIsShutdownRequested = true;
				refreshWidgets(); // refresh display if not auto-repeat
			}
			static QKeyEvent evntKeyPowerOff(QEvent::KeyPress, Qt::Key_PowerOff, Qt::NoModifier);
			event = &evntKeyPowerOff;
		}
	} else if (event->type() == QEvent::KeyRelease) {
		QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event);
		if (isTrikPowerOffKey(static_cast<Qt::Key>(keyEvent->key()))) {
			if (!keyEvent->isAutoRepeat()) {
				mIsShutdownRequested = false;
//				if (mPowerButtonPressedTimer.isActive()) {
//					mPowerButtonPressedTimer.stop();
//				}
			} else {
			}
			static QKeyEvent evntKeyPowerOff(QEvent::KeyRelease, Qt::Key_PowerOff, Qt::NoModifier);
			event = &evntKeyPowerOff;
		}
	}

	return QApplication::notify(receiver, event);
}

void TrikGuiApplication::refreshWidgets()
{
	if (dynamic_cast<BackgroundWidget *>(QApplication::activeWindow())) {
		for (const auto widget : QApplication::allWidgets()) {
			widget->update();
		}
	}
}

void TrikGuiApplication::shutdown()
{
	if(!mIsShutdownRequested) {
		setStyleSheet(mSavedStyleSheet);
		return;
	}

	QProcess::startDetached("/sbin/shutdown", {"-h", "-P", "now" });
	QCoreApplication::quit();
}

void TrikGuiApplication::shutdownSoon()
{
	if(mShutdownDelayTimer.isActive() || !mIsShutdownRequested) {
		return;
	}

	mSavedStyleSheet = styleSheet();
	setStyleSheet(mSavedStyleSheet + " QWidget { background-color:red; } ");
	mShutdownDelayTimer.start(1500);
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_resource_protocols.h"

#include "base/files/file_path.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_file_job.h"

namespace {

class ExtensionResourcesJob : public net::URLRequestFileJob {
 public:
  ExtensionResourcesJob(net::URLRequest* request,
                        net::NetworkDelegate* network_delegate)
    : net::URLRequestFileJob(request, network_delegate, base::FilePath()),
      thread_id_(content::BrowserThread::UI) {
  }

  virtual void Start() OVERRIDE;

 protected:
  virtual ~ExtensionResourcesJob() {}

  void ResolvePath();
  void ResolvePathDone();

 private:
  content::BrowserThread::ID thread_id_;
};

void ExtensionResourcesJob::Start() {
  bool result =
      content::BrowserThread::GetCurrentThreadIdentifier(&thread_id_);
  CHECK(result) << "Can not get thread id.";
  content::BrowserThread::PostTask(
      content::BrowserThread::FILE, FROM_HERE,
      base::Bind(&ExtensionResourcesJob::ResolvePath, this));
}

void ExtensionResourcesJob::ResolvePath() {
  base::FilePath root_path;
  PathService::Get(chrome::DIR_RESOURCES_EXTENSION, &root_path);
  file_path_ = extension_file_util::ExtensionResourceURLToFilePath(
      request()->url(), root_path);
  content::BrowserThread::PostTask(
      thread_id_, FROM_HERE,
      base::Bind(&ExtensionResourcesJob::ResolvePathDone, this));
}

void ExtensionResourcesJob::ResolvePathDone() {
  net::URLRequestFileJob::Start();
}

class ExtensionResourceProtocolHandler
    : public net::URLRequestJobFactory::ProtocolHandler {
 public:
  ExtensionResourceProtocolHandler() {}
  virtual ~ExtensionResourceProtocolHandler() {}

  virtual net::URLRequestJob* MaybeCreateJob(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const OVERRIDE;

 private:
  DISALLOW_COPY_AND_ASSIGN(ExtensionResourceProtocolHandler);
};

// Creates URLRequestJobs for chrome-extension-resource:// URLs.
net::URLRequestJob*
ExtensionResourceProtocolHandler::MaybeCreateJob(
    net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
  return new ExtensionResourcesJob(request, network_delegate);
}

}  // namespace

net::URLRequestJobFactory::ProtocolHandler*
CreateExtensionResourceProtocolHandler() {
  return new ExtensionResourceProtocolHandler();
}
<commit_msg>Fix a rare crash in ExtensionResourcesJob::ResolvePath.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_resource_protocols.h"

#include "base/files/file_path.h"
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
#include "base/threading/thread_checker.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_file_job.h"

namespace {

base::FilePath ResolvePath(const GURL& url) {
  base::FilePath root_path;
  PathService::Get(chrome::DIR_RESOURCES_EXTENSION, &root_path);
  return extension_file_util::ExtensionResourceURLToFilePath(url, root_path);
}

class ExtensionResourcesJob : public net::URLRequestFileJob {
 public:
  ExtensionResourcesJob(net::URLRequest* request,
                        net::NetworkDelegate* network_delegate)
    : net::URLRequestFileJob(request, network_delegate, base::FilePath()),
      weak_ptr_factory_(this) {
  }

  virtual void Start() OVERRIDE;

 protected:
  virtual ~ExtensionResourcesJob() {}

  void ResolvePathDone(const base::FilePath& resolved_path);

 private:
  base::WeakPtrFactory<ExtensionResourcesJob> weak_ptr_factory_;

  base::ThreadChecker thread_checker_;

  DISALLOW_COPY_AND_ASSIGN(ExtensionResourcesJob);
};

void ExtensionResourcesJob::Start() {
  DCHECK(thread_checker_.CalledOnValidThread());
  content::BrowserThread::PostTaskAndReplyWithResult(
      content::BrowserThread::FILE, FROM_HERE,
      base::Bind(&ResolvePath, request()->url()),
      base::Bind(&ExtensionResourcesJob::ResolvePathDone,
          weak_ptr_factory_.GetWeakPtr()));
}

void ExtensionResourcesJob::ResolvePathDone(
    const base::FilePath& resolved_path) {
  DCHECK(thread_checker_.CalledOnValidThread());
  file_path_ = resolved_path;
  net::URLRequestFileJob::Start();
}

class ExtensionResourceProtocolHandler
    : public net::URLRequestJobFactory::ProtocolHandler {
 public:
  ExtensionResourceProtocolHandler() {}
  virtual ~ExtensionResourceProtocolHandler() {}

  virtual net::URLRequestJob* MaybeCreateJob(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const OVERRIDE;

 private:
  DISALLOW_COPY_AND_ASSIGN(ExtensionResourceProtocolHandler);
};

// Creates URLRequestJobs for chrome-extension-resource:// URLs.
net::URLRequestJob*
ExtensionResourceProtocolHandler::MaybeCreateJob(
    net::URLRequest* request, net::NetworkDelegate* network_delegate) const {
  return new ExtensionResourcesJob(request, network_delegate);
}

}  // namespace

net::URLRequestJobFactory::ProtocolHandler*
CreateExtensionResourceProtocolHandler() {
  return new ExtensionResourceProtocolHandler();
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// Name:      app.cpp
// Purpose:   Implementation of classes for syncodbcquery
// Author:    Anton van Wezenbeek
// Copyright: (c) 2014 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/aboutdlg.h>
#include <wx/config.h>
#include <wx/regex.h>
#include <wx/stockitem.h>
#include <wx/tokenzr.h>
#include <wx/extension/filedlg.h>
#include <wx/extension/grid.h>
#include <wx/extension/shell.h>
#include <wx/extension/toolbar.h>
#include <wx/extension/util.h>
#include <wx/extension/version.h>
#include <wx/extension/report/defs.h>
#include <wx/extension/report/stc.h>
#include <wx/extension/report/util.h>
#include "app.h"

#ifndef __WXMSW__
#include "app.xpm"
#endif

wxIMPLEMENT_APP(App);

bool App::OnInit()
{
  SetAppName("syncodbcquery");

  if (!wxExApp::OnInit())
  {
    return false;
  }

  Frame *frame = new Frame();
  frame->Show(true);

  return true;
}

BEGIN_EVENT_TABLE(Frame, wxExFrameWithHistory)
  EVT_CLOSE(Frame::OnClose)
  EVT_MENU(wxID_ABOUT, Frame::OnCommand)
  EVT_MENU(wxID_EXECUTE, Frame::OnCommand)
  EVT_MENU(wxID_EXIT, Frame::OnCommand)
  EVT_MENU(wxID_STOP, Frame::OnCommand)
  EVT_MENU(ID_SHELL_COMMAND, Frame::OnCommand)
  EVT_MENU(ID_SHELL_COMMAND_STOP, Frame::OnCommand)
  EVT_MENU_RANGE(wxID_CUT, wxID_CLEAR, Frame::OnCommand)
  EVT_MENU_RANGE(ID_FIRST, ID_LAST, Frame::OnCommand)
  EVT_UPDATE_UI(wxID_SAVE, Frame::OnUpdateUI)
  EVT_UPDATE_UI(wxID_SAVEAS, Frame::OnUpdateUI)
  EVT_UPDATE_UI(wxID_STOP, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_DATABASE_CLOSE, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_DATABASE_OPEN, Frame::OnUpdateUI)
  EVT_UPDATE_UI(wxID_EXECUTE, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_RECENTFILE_MENU, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_VIEW_QUERY, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_VIEW_RESULTS, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_VIEW_STATISTICS, Frame::OnUpdateUI)
END_EVENT_TABLE()

Frame::Frame()
  : wxExFrameWithHistory(NULL, wxID_ANY, wxTheApp->GetAppDisplayName())
  , m_Running(false)
  , m_Stopped(false)
{
  SetIcon(wxICON(app));

  wxExMenu* menuFile = new wxExMenu;
  menuFile->Append(wxID_NEW);
  menuFile->Append(wxID_OPEN);
  UseFileHistory(ID_RECENTFILE_MENU, menuFile);
  menuFile->AppendSeparator();
  menuFile->Append(wxID_SAVE);
  menuFile->Append(wxID_SAVEAS);
  menuFile->AppendSeparator();
  menuFile->Append(wxID_EXIT);

  wxExMenu* menuDatabase = new wxExMenu;
  menuDatabase->Append(ID_DATABASE_OPEN, wxExEllipsed(_("&Open")));
  menuDatabase->Append(ID_DATABASE_CLOSE, _("&Close"));

  wxExMenu* menuQuery = new wxExMenu;
  menuQuery->Append(wxID_EXECUTE);
  menuQuery->Append(wxID_STOP);

  wxMenu* menuOptions = new wxMenu();
  menuOptions->Append(wxID_PREFERENCES);

  wxExMenu* menuView = new wxExMenu();
  menuView->AppendBars();
  menuView->AppendSeparator();
  menuView->AppendCheckItem(ID_VIEW_QUERY, _("Query"));
  menuView->AppendCheckItem(ID_VIEW_RESULTS, _("Results"));
  menuView->AppendCheckItem(ID_VIEW_STATISTICS, _("Statistics"));

  wxMenu* menuHelp = new wxMenu();
  menuHelp->Append(wxID_ABOUT);

  wxMenuBar *menubar = new wxMenuBar;
  menubar->Append(menuFile, wxGetStockLabel(wxID_FILE));
  menubar->Append(menuView, _("&View"));
  menubar->Append(menuDatabase, _("&Connection"));
  menubar->Append(menuQuery, _("&Query"));
  menubar->Append(menuOptions, _("&Options"));
  menubar->Append(menuHelp, wxGetStockLabel(wxID_HELP));
  SetMenuBar(menubar);

  m_Query = new wxExSTCWithFrame(this, this);
  m_Query->SetLexer("sql");

  m_Results = new wxExGrid(this);
  m_Results->CreateGrid(0, 0);
  m_Results->EnableEditing(false); // this is a read-only grid

  m_Shell = new wxExSTCShell(this, ">", ";", true, 50);
  m_Shell->SetFocus();

#if wxUSE_STATUSBAR
  std::vector<wxExStatusBarPane> panes;
  panes.push_back(wxExStatusBarPane());
  panes.push_back(wxExStatusBarPane("PaneInfo", 100, _("Lines")));
  SetupStatusBar(panes);
#endif

  GetManager().AddPane(m_Shell,
    wxAuiPaneInfo().
      Name("CONSOLE").
      CenterPane());

  GetManager().AddPane(m_Results,
    wxAuiPaneInfo().
      Name("RESULTS").
      Caption(_("Results")).
      CloseButton(true).
      MaximizeButton(true));

  GetManager().AddPane(m_Query,
    wxAuiPaneInfo().
      Name("QUERY").
      Caption(_("Query")).
      CloseButton(true).
      MaximizeButton(true));

  GetManager().AddPane(m_Statistics.Show(this),
    wxAuiPaneInfo().Left().
      MaximizeButton(true).
      Caption(_("Statistics")).
      Name("STATISTICS"));

  GetManager().LoadPerspective(wxConfigBase::Get()->Read("Perspective"));
  GetManager().GetPane("QUERY").Show(false);

  GetManager().Update();
}

void Frame::OnClose(wxCloseEvent& event)
{
  wxExFileDialog dlg(this, &m_Query->GetFile());

  if (dlg.ShowModalIfChanged()  == wxID_CANCEL)
  {
    return;
  }

  wxConfigBase::Get()->Write("Perspective", GetManager().SavePerspective());

  event.Skip();
}

void Frame::OnCommand(wxCommandEvent& event)
{
  switch (event.GetId())
  {
  case wxID_ABOUT:
    {
    wxAboutDialogInfo info;
    info.SetIcon(GetIcon());
    info.SetDescription(_("This program offers a general ODBC query."));
    info.SetVersion(wxExGetVersionInfo().GetVersionOnlyString());
    info.SetCopyright(wxExGetVersionInfo().GetCopyright());
    info.AddDeveloper(wxExOTL::VersionInfo().GetVersionString());
    wxAboutBox(info);
    }
    break;

  case wxID_EXECUTE:
    m_Stopped = false;
    RunQueries(m_Query->GetText());
    break;

  case wxID_EXIT:
    Close(true);
    break;

  case wxID_NEW:
    m_Query->GetFile().FileNew(wxExFileName());
    m_Query->SetLexer("sql");
    m_Query->SetFocus();
    GetManager().GetPane("QUERY").Show();
    GetManager().Update();
    break;

  case wxID_OPEN:
    wxExOpenFilesDialog(
      this,
      wxFD_OPEN | wxFD_CHANGE_DIR,
      "sql files (*.sql) | *.sql",
      true);
    break;

  case wxID_SAVE:
    m_Query->GetFile().FileSave();
    break;

  case wxID_SAVEAS:
    {
      wxExFileDialog dlg(
        this,
        &m_Query->GetFile(),
        wxGetStockLabel(wxID_SAVEAS),
        wxFileSelectorDefaultWildcardStr,
        wxFD_SAVE);

      if (dlg.ShowModal() == wxID_OK)
      {
         m_Query->GetFile().FileSave(dlg.GetPath());
      }
    }
    break;

  case wxID_STOP:
    m_Running = false;
    m_Stopped = true;
    break;

  case ID_DATABASE_CLOSE:
    if (m_otl.Logoff())
    {
      m_Shell->SetPrompt(">");
    }
    break;

  case ID_DATABASE_OPEN:
    if (m_otl.Logon(this))
    {
      m_Shell->SetPrompt(m_otl.Datasource() + ">");
    }
    break;

  case ID_SHELL_COMMAND:
    if (m_otl.IsConnected())
    {
      try
      {
        const wxString input(event.GetString());

        if (!input.empty())
        {
          const wxString query = input.substr(
            0,
            input.length() - 1);

          m_Stopped = false;
          RunQuery(query, true);
        }
      }
      catch (otl_exception& p)
      {
        if (m_Results->IsShown())
        {
          m_Results->EndBatch();
        }

        m_Shell->AppendText(_("\nerror: ") + wxExQuoted(p.msg));
      }
    }
    else
    {
      m_Shell->AppendText(_("\nnot connected"));
    }

    m_Shell->Prompt();
    break;

  case ID_SHELL_COMMAND_STOP:
    m_Stopped = true;
    m_Shell->Prompt(_("cancelled"));
    break;

  case ID_VIEW_QUERY: TogglePane("QUERY"); break;
  case ID_VIEW_RESULTS: TogglePane("RESULTS"); break;
  case ID_VIEW_STATISTICS: TogglePane("STATISTICS"); break;

  default:
    wxFAIL;
  }
}

void Frame::OnCommandConfigDialog(
  wxWindowID dialogid,
  int commandid)
{
  if (dialogid == wxID_PREFERENCES)
  {
    m_Query->ConfigGet();
    m_Shell->ConfigGet();
  }
  else
  {
    wxExFrameWithHistory::OnCommandConfigDialog(dialogid, commandid);
  }
}

void Frame::OnUpdateUI(wxUpdateUIEvent& event)
{
  switch (event.GetId())
  {
  case wxID_EXECUTE:
    // If we have a query, you can hide it, but still run it.
    event.Enable(m_Query->GetLength() > 0 && m_otl.IsConnected());
    break;

  case wxID_SAVE:
    event.Enable(m_Query->GetModify());
    break;

  case wxID_SAVEAS:
    event.Enable(m_Query->GetLength() > 0);
    break;

  case wxID_STOP:
    event.Enable(m_Running);
    break;

  case ID_DATABASE_CLOSE:
    event.Enable(m_otl.IsConnected());
    break;

  case ID_DATABASE_OPEN:
    event.Enable(!m_otl.IsConnected());
    break;

  case ID_RECENTFILE_MENU:
    event.Enable(!GetRecentFile().empty());
    break;

  case ID_VIEW_QUERY:
    event.Check(GetManager().GetPane("QUERY").IsShown());
    break;

  case ID_VIEW_RESULTS:
    event.Check(GetManager().GetPane("RESULTS").IsShown());
    break;

  case ID_VIEW_STATISTICS:
    event.Check(GetManager().GetPane("STATISTICS").IsShown());
    break;

  default:
    wxFAIL;
  }
}

bool Frame::OpenFile(
  const wxExFileName& filename,
  int line_number,
  const wxString& match,
  int col_number,
  long flags)
{
  if (m_Query->Open(filename, line_number, match, col_number, flags))
  {
    GetManager().GetPane("QUERY").Show(true);
    GetManager().Update();

    SetRecentFile(filename.GetFullPath());
  }
  else
  {
    return false;
  }
}

void Frame::RunQuery(const wxString& query, bool empty_results)
{
  wxStopWatch sw;

  const wxString query_lower = query.Lower();

  // Query functions supported by ODBC
  // $SQLTables, $SQLColumns, etc.
  // $SQLTables $1:'%'
  // allow you to get database schema.
  if (query_lower.StartsWith("select") ||
      query_lower.StartsWith("describe") ||
      query_lower.StartsWith("show") ||
      query_lower.StartsWith("explain") ||
      query_lower.StartsWith("$sql"))
  {
    long rpc;

    if (m_Results->IsShown())
    {
      rpc = m_otl.Query(query, m_Results, m_Stopped, empty_results);
    }
    else
    {
      rpc = m_otl.Query(query, m_Shell, m_Stopped);
    }

    sw.Pause();

    UpdateStatistics(sw.Time(), rpc);
  }
  else
  {
    const auto rpc = m_otl.Query(query);

    sw.Pause();

    UpdateStatistics(sw.Time(), rpc);
  }

  m_Shell->DocumentEnd();
}

void Frame::RunQueries(const wxString& text)
{
  if (text.empty())
  {
    return;
  }

  if (m_Results->IsShown())
  {
    m_Results->ClearGrid();
  }

  // Skip sql comments.
  wxString output = text;
  wxRegEx("--.*$", wxRE_NEWLINE).ReplaceAll(&output, "");

  // Queries are seperated by ; character.
  wxStringTokenizer tkz(output, ";");
  int no_queries = 0;

  wxStopWatch sw;
  m_Running = true;

  // Run all queries.
  while (tkz.HasMoreTokens() && !m_Stopped)
  {
    wxString query = tkz.GetNextToken();
    query.Trim(true);
    query.Trim(false);

    if (!query.empty())
    {
      try
      {
        RunQuery(query, no_queries == 0);
        no_queries++;
      }
      catch (otl_exception& p)
      {
        m_Statistics.Inc(_("Number of query errors"));
        m_Shell->AppendText(
          _("\nerror: ") +  wxExQuoted(p.msg) +
          _(" in: ") + wxExQuoted(query));
      }
    }
  }

  m_Shell->Prompt(wxString::Format(_("\n%d queries (%.3f seconds)"),
    no_queries,
    (float)sw.Time() / (float)1000));

  m_Running = false;
}

void Frame::UpdateStatistics(long time, long rpc)
{
  m_Shell->AppendText(wxString::Format(_("\n%ld rows processed (%.3f seconds)"),
    rpc,
    (float)time / (float)1000));

  m_Statistics.Set(_("Rows processed"), rpc);
  m_Statistics.Set(_("Query runtime"), time);

  m_Statistics.Inc(_("Total number of queries run"));
  m_Statistics.Inc(_("Total query runtime"), time);
  m_Statistics.Inc(_("Total rows processed"), rpc);
}
<commit_msg>added missing commands to event table<commit_after>////////////////////////////////////////////////////////////////////////////////
// Name:      app.cpp
// Purpose:   Implementation of classes for syncodbcquery
// Author:    Anton van Wezenbeek
// Copyright: (c) 2014 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/aboutdlg.h>
#include <wx/config.h>
#include <wx/regex.h>
#include <wx/stockitem.h>
#include <wx/tokenzr.h>
#include <wx/extension/filedlg.h>
#include <wx/extension/grid.h>
#include <wx/extension/shell.h>
#include <wx/extension/toolbar.h>
#include <wx/extension/util.h>
#include <wx/extension/version.h>
#include <wx/extension/report/defs.h>
#include <wx/extension/report/stc.h>
#include <wx/extension/report/util.h>
#include "app.h"

#ifndef __WXMSW__
#include "app.xpm"
#endif

wxIMPLEMENT_APP(App);

bool App::OnInit()
{
  SetAppName("syncodbcquery");

  if (!wxExApp::OnInit())
  {
    return false;
  }

  Frame *frame = new Frame();
  frame->Show(true);

  return true;
}

BEGIN_EVENT_TABLE(Frame, wxExFrameWithHistory)
  EVT_CLOSE(Frame::OnClose)
  EVT_MENU(wxID_ABOUT, Frame::OnCommand)
  EVT_MENU(wxID_EXECUTE, Frame::OnCommand)
  EVT_MENU(wxID_EXIT, Frame::OnCommand)
  EVT_MENU(wxID_NEW, Frame::OnCommand)
  EVT_MENU(wxID_OPEN, Frame::OnCommand)
  EVT_MENU(wxID_SAVE, Frame::OnCommand)
  EVT_MENU(wxID_SAVEAS, Frame::OnCommand)
  EVT_MENU(wxID_STOP, Frame::OnCommand)
  EVT_MENU(ID_SHELL_COMMAND, Frame::OnCommand)
  EVT_MENU(ID_SHELL_COMMAND_STOP, Frame::OnCommand)
  EVT_MENU_RANGE(wxID_CUT, wxID_CLEAR, Frame::OnCommand)
  EVT_MENU_RANGE(ID_FIRST, ID_LAST, Frame::OnCommand)
  EVT_UPDATE_UI(wxID_SAVE, Frame::OnUpdateUI)
  EVT_UPDATE_UI(wxID_SAVEAS, Frame::OnUpdateUI)
  EVT_UPDATE_UI(wxID_STOP, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_DATABASE_CLOSE, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_DATABASE_OPEN, Frame::OnUpdateUI)
  EVT_UPDATE_UI(wxID_EXECUTE, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_RECENTFILE_MENU, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_VIEW_QUERY, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_VIEW_RESULTS, Frame::OnUpdateUI)
  EVT_UPDATE_UI(ID_VIEW_STATISTICS, Frame::OnUpdateUI)
END_EVENT_TABLE()

Frame::Frame()
  : wxExFrameWithHistory(NULL, wxID_ANY, wxTheApp->GetAppDisplayName())
  , m_Running(false)
  , m_Stopped(false)
{
  SetIcon(wxICON(app));

  wxExMenu* menuFile = new wxExMenu;
  menuFile->Append(wxID_NEW);
  menuFile->Append(wxID_OPEN);
  UseFileHistory(ID_RECENTFILE_MENU, menuFile);
  menuFile->AppendSeparator();
  menuFile->Append(wxID_SAVE);
  menuFile->Append(wxID_SAVEAS);
  menuFile->AppendSeparator();
  menuFile->Append(wxID_EXIT);

  wxExMenu* menuDatabase = new wxExMenu;
  menuDatabase->Append(ID_DATABASE_OPEN, wxExEllipsed(_("&Open")));
  menuDatabase->Append(ID_DATABASE_CLOSE, _("&Close"));

  wxExMenu* menuQuery = new wxExMenu;
  menuQuery->Append(wxID_EXECUTE);
  menuQuery->Append(wxID_STOP);

  wxMenu* menuOptions = new wxMenu();
  menuOptions->Append(wxID_PREFERENCES);

  wxExMenu* menuView = new wxExMenu();
  menuView->AppendBars();
  menuView->AppendSeparator();
  menuView->AppendCheckItem(ID_VIEW_QUERY, _("Query"));
  menuView->AppendCheckItem(ID_VIEW_RESULTS, _("Results"));
  menuView->AppendCheckItem(ID_VIEW_STATISTICS, _("Statistics"));

  wxMenu* menuHelp = new wxMenu();
  menuHelp->Append(wxID_ABOUT);

  wxMenuBar *menubar = new wxMenuBar;
  menubar->Append(menuFile, wxGetStockLabel(wxID_FILE));
  menubar->Append(menuView, _("&View"));
  menubar->Append(menuDatabase, _("&Connection"));
  menubar->Append(menuQuery, _("&Query"));
  menubar->Append(menuOptions, _("&Options"));
  menubar->Append(menuHelp, wxGetStockLabel(wxID_HELP));
  SetMenuBar(menubar);

  m_Query = new wxExSTCWithFrame(this, this);
  m_Query->SetLexer("sql");

  m_Results = new wxExGrid(this);
  m_Results->CreateGrid(0, 0);
  m_Results->EnableEditing(false); // this is a read-only grid

  m_Shell = new wxExSTCShell(this, ">", ";", true, 50);
  m_Shell->SetFocus();

#if wxUSE_STATUSBAR
  std::vector<wxExStatusBarPane> panes;
  panes.push_back(wxExStatusBarPane());
  panes.push_back(wxExStatusBarPane("PaneInfo", 100, _("Lines")));
  SetupStatusBar(panes);
#endif

  GetManager().AddPane(m_Shell,
    wxAuiPaneInfo().
      Name("CONSOLE").
      CenterPane());

  GetManager().AddPane(m_Results,
    wxAuiPaneInfo().
      Name("RESULTS").
      Caption(_("Results")).
      CloseButton(true).
      MaximizeButton(true));

  GetManager().AddPane(m_Query,
    wxAuiPaneInfo().
      Name("QUERY").
      Caption(_("Query")).
      CloseButton(true).
      MaximizeButton(true));

  GetManager().AddPane(m_Statistics.Show(this),
    wxAuiPaneInfo().Left().
      MaximizeButton(true).
      Caption(_("Statistics")).
      Name("STATISTICS"));

  GetManager().LoadPerspective(wxConfigBase::Get()->Read("Perspective"));
  GetManager().GetPane("QUERY").Show(false);

  GetManager().Update();
}

void Frame::OnClose(wxCloseEvent& event)
{
  wxExFileDialog dlg(this, &m_Query->GetFile());

  if (dlg.ShowModalIfChanged()  == wxID_CANCEL)
  {
    return;
  }

  wxConfigBase::Get()->Write("Perspective", GetManager().SavePerspective());

  event.Skip();
}

void Frame::OnCommand(wxCommandEvent& event)
{
  switch (event.GetId())
  {
  case wxID_ABOUT:
    {
    wxAboutDialogInfo info;
    info.SetIcon(GetIcon());
    info.SetDescription(_("This program offers a general ODBC query."));
    info.SetVersion(wxExGetVersionInfo().GetVersionOnlyString());
    info.SetCopyright(wxExGetVersionInfo().GetCopyright());
    info.AddDeveloper(wxExOTL::VersionInfo().GetVersionString());
    wxAboutBox(info);
    }
    break;

  case wxID_EXECUTE:
    m_Stopped = false;
    RunQueries(m_Query->GetText());
    break;

  case wxID_EXIT:
    Close(true);
    break;

  case wxID_NEW:
    m_Query->GetFile().FileNew(wxExFileName());
    m_Query->SetLexer("sql");
    m_Query->SetFocus();
    GetManager().GetPane("QUERY").Show();
    GetManager().Update();
    break;

  case wxID_OPEN:
    wxExOpenFilesDialog(
      this,
      wxFD_OPEN | wxFD_CHANGE_DIR,
      "sql files (*.sql)|*.sql",
      true);
    break;

  case wxID_SAVE:
    m_Query->GetFile().FileSave();
    break;

  case wxID_SAVEAS:
    {
      wxExFileDialog dlg(
        this,
        &m_Query->GetFile(),
        wxGetStockLabel(wxID_SAVEAS),
        wxFileSelectorDefaultWildcardStr,
        wxFD_SAVE);

      if (dlg.ShowModal() == wxID_OK)
      {
         m_Query->GetFile().FileSave(dlg.GetPath());
      }
    }
    break;

  case wxID_STOP:
    m_Running = false;
    m_Stopped = true;
    break;

  case ID_DATABASE_CLOSE:
    if (m_otl.Logoff())
    {
      m_Shell->SetPrompt(">");
    }
    break;

  case ID_DATABASE_OPEN:
    if (m_otl.Logon(this))
    {
      m_Shell->SetPrompt(m_otl.Datasource() + ">");
    }
    break;

  case ID_SHELL_COMMAND:
    if (m_otl.IsConnected())
    {
      try
      {
        const wxString input(event.GetString());

        if (!input.empty())
        {
          const wxString query = input.substr(
            0,
            input.length() - 1);

          m_Stopped = false;
          RunQuery(query, true);
        }
      }
      catch (otl_exception& p)
      {
        if (m_Results->IsShown())
        {
          m_Results->EndBatch();
        }

        m_Shell->AppendText(_("\nerror: ") + wxExQuoted(p.msg));
      }
    }
    else
    {
      m_Shell->AppendText(_("\nnot connected"));
    }

    m_Shell->Prompt();
    break;

  case ID_SHELL_COMMAND_STOP:
    m_Stopped = true;
    m_Shell->Prompt(_("cancelled"));
    break;

  case ID_VIEW_QUERY: TogglePane("QUERY"); break;
  case ID_VIEW_RESULTS: TogglePane("RESULTS"); break;
  case ID_VIEW_STATISTICS: TogglePane("STATISTICS"); break;

  default:
    wxFAIL;
  }
}

void Frame::OnCommandConfigDialog(
  wxWindowID dialogid,
  int commandid)
{
  if (dialogid == wxID_PREFERENCES)
  {
    m_Query->ConfigGet();
    m_Shell->ConfigGet();
  }
  else
  {
    wxExFrameWithHistory::OnCommandConfigDialog(dialogid, commandid);
  }
}

void Frame::OnUpdateUI(wxUpdateUIEvent& event)
{
  switch (event.GetId())
  {
  case wxID_EXECUTE:
    // If we have a query, you can hide it, but still run it.
    event.Enable(m_Query->GetLength() > 0 && m_otl.IsConnected());
    break;

  case wxID_SAVE:
    event.Enable(m_Query->GetModify());
    break;

  case wxID_SAVEAS:
    event.Enable(m_Query->GetLength() > 0);
    break;

  case wxID_STOP:
    event.Enable(m_Running);
    break;

  case ID_DATABASE_CLOSE:
    event.Enable(m_otl.IsConnected());
    break;

  case ID_DATABASE_OPEN:
    event.Enable(!m_otl.IsConnected());
    break;

  case ID_RECENTFILE_MENU:
    event.Enable(!GetRecentFile().empty());
    break;

  case ID_VIEW_QUERY:
    event.Check(GetManager().GetPane("QUERY").IsShown());
    break;

  case ID_VIEW_RESULTS:
    event.Check(GetManager().GetPane("RESULTS").IsShown());
    break;

  case ID_VIEW_STATISTICS:
    event.Check(GetManager().GetPane("STATISTICS").IsShown());
    break;

  default:
    wxFAIL;
  }
}

bool Frame::OpenFile(
  const wxExFileName& filename,
  int line_number,
  const wxString& match,
  int col_number,
  long flags)
{
  if (m_Query->Open(filename, line_number, match, col_number, flags))
  {
    GetManager().GetPane("QUERY").Show(true);
    GetManager().Update();

    SetRecentFile(filename.GetFullPath());
  }
  else
  {
    return false;
  }
}

void Frame::RunQuery(const wxString& query, bool empty_results)
{
  wxStopWatch sw;

  const wxString query_lower = query.Lower();

  // Query functions supported by ODBC
  // $SQLTables, $SQLColumns, etc.
  // $SQLTables $1:'%'
  // allow you to get database schema.
  if (query_lower.StartsWith("select") ||
      query_lower.StartsWith("describe") ||
      query_lower.StartsWith("show") ||
      query_lower.StartsWith("explain") ||
      query_lower.StartsWith("$sql"))
  {
    long rpc;

    if (m_Results->IsShown())
    {
      rpc = m_otl.Query(query, m_Results, m_Stopped, empty_results);
    }
    else
    {
      rpc = m_otl.Query(query, m_Shell, m_Stopped);
    }

    sw.Pause();

    UpdateStatistics(sw.Time(), rpc);
  }
  else
  {
    const auto rpc = m_otl.Query(query);

    sw.Pause();

    UpdateStatistics(sw.Time(), rpc);
  }

  m_Shell->DocumentEnd();
}

void Frame::RunQueries(const wxString& text)
{
  if (text.empty())
  {
    return;
  }

  if (m_Results->IsShown())
  {
    m_Results->ClearGrid();
  }

  // Skip sql comments.
  wxString output = text;
  wxRegEx("--.*$", wxRE_NEWLINE).ReplaceAll(&output, "");

  // Queries are seperated by ; character.
  wxStringTokenizer tkz(output, ";");
  int no_queries = 0;

  wxStopWatch sw;
  m_Running = true;

  // Run all queries.
  while (tkz.HasMoreTokens() && !m_Stopped)
  {
    wxString query = tkz.GetNextToken();
    query.Trim(true);
    query.Trim(false);

    if (!query.empty())
    {
      try
      {
        RunQuery(query, no_queries == 0);
        no_queries++;
      }
      catch (otl_exception& p)
      {
        m_Statistics.Inc(_("Number of query errors"));
        m_Shell->AppendText(
          _("\nerror: ") +  wxExQuoted(p.msg) +
          _(" in: ") + wxExQuoted(query));
      }
    }
  }

  m_Shell->Prompt(wxString::Format(_("\n%d queries (%.3f seconds)"),
    no_queries,
    (float)sw.Time() / (float)1000));

  m_Running = false;
}

void Frame::UpdateStatistics(long time, long rpc)
{
  m_Shell->AppendText(wxString::Format(_("\n%ld rows processed (%.3f seconds)"),
    rpc,
    (float)time / (float)1000));

  m_Statistics.Set(_("Rows processed"), rpc);
  m_Statistics.Set(_("Query runtime"), time);

  m_Statistics.Inc(_("Total number of queries run"));
  m_Statistics.Inc(_("Total query runtime"), time);
  m_Statistics.Inc(_("Total rows processed"), rpc);
}
<|endoftext|>


<commit_before>#include "wasm-binary.h"
#include "wasm-s-parser.h"

using namespace std;

namespace {

string wast2wasm(string input, bool debug = false) {
  wasm::Module wasm;

  try {
    if (debug) std::cerr << "s-parsing..." << std::endl;
    wasm::SExpressionParser parser(const_cast<char*>(input.c_str()));
    wasm::Element& root = *parser.root;
    if (debug) std::cerr << "w-parsing..." << std::endl;
    wasm::SExpressionWasmBuilder builder(wasm, *root[0]);
  } catch (wasm::ParseException& p) {
    p.dump(std::cerr);
    wasm::Fatal() << "error in parsing input";
  }

  // FIXME: perhaps call validate() here?

  if (debug) std::cerr << "binarification..." << std::endl;
  wasm::BufferWithRandomAccess buffer(debug);
  wasm::WasmBinaryWriter writer(&wasm, buffer, debug);
  writer.write();

  if (debug) std::cerr << "writing to output..." << std::endl;

  ostringstream output;
  buffer.writeTo(output);

  if (debug) std::cerr << "Done." << std::endl;

  return output.str();
}

}

int main(int argc, char **argv) {
  cout << wast2wasm("(module (func $test (i64.const 1)))") << endl;
}
<commit_msg>Add C++ skeleton<commit_after>#include "wasm-binary.h"
#include "wasm-s-parser.h"

using namespace std;

namespace {

string wast2wasm(string input, bool debug = false) {
  wasm::Module wasm;

  try {
    if (debug) std::cerr << "s-parsing..." << std::endl;
    wasm::SExpressionParser parser(const_cast<char*>(input.c_str()));
    wasm::Element& root = *parser.root;
    if (debug) std::cerr << "w-parsing..." << std::endl;
    wasm::SExpressionWasmBuilder builder(wasm, *root[0]);
  } catch (wasm::ParseException& p) {
    p.dump(std::cerr);
    wasm::Fatal() << "error in parsing input";
  }

  // FIXME: perhaps call validate() here?

  if (debug) std::cerr << "binarification..." << std::endl;
  wasm::BufferWithRandomAccess buffer(debug);
  wasm::WasmBinaryWriter writer(&wasm, buffer, debug);
  writer.write();

  if (debug) std::cerr << "writing to output..." << std::endl;

  ostringstream output;
  buffer.writeTo(output);

  if (debug) std::cerr << "Done." << std::endl;

  return output.str();
}

string evm2wast(string input) {
  // FIXME: do evm magic here
}

string evm2wasm(string input) {
  return wast2wasm(evm2wast(input));
}

}

int main(int argc, char **argv) {
  cout << wast2wasm("(module (func $test (i64.const 1)))") << endl;
  cout << evm2wast("600160020200") << endl;
}
<|endoftext|>


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

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cql3/user_types.hh"

#include "cql3/cql3_type.hh"

#include <boost/range/adaptor/transformed.hpp>
#include <boost/algorithm/cxx11/any_of.hpp>
#include <boost/range/algorithm/count.hpp>

#include "types/user.hh"

namespace cql3 {

shared_ptr<column_specification> user_types::field_spec_of(shared_ptr<column_specification> column, size_t field) {
    auto&& ut = static_pointer_cast<const user_type_impl>(column->type);
    auto&& name = ut->field_name(field);
    auto&& sname = sstring(reinterpret_cast<const char*>(name.data()), name.size());
    return make_shared<column_specification>(
                                   column->ks_name,
                                   column->cf_name,
                                   make_shared<column_identifier>(column->name->to_string() + "." + sname, true),
                                   ut->field_type(field));
}

user_types::literal::literal(elements_map_type entries)
        : _entries(std::move(entries)) {
}

shared_ptr<term> user_types::literal::prepare(database& db, const sstring& keyspace, shared_ptr<column_specification> receiver) {
    validate_assignable_to(db, keyspace, receiver);
    auto&& ut = static_pointer_cast<const user_type_impl>(receiver->type);
    bool all_terminal = true;
    std::vector<shared_ptr<term>> values;
    values.reserve(_entries.size());
    size_t found_values = 0;
    for (size_t i = 0; i < ut->size(); ++i) {
        auto&& field = column_identifier(to_bytes(ut->field_name(i)), utf8_type);
        auto iraw = _entries.find(field);
        shared_ptr<term::raw> raw;
        if (iraw == _entries.end()) {
            raw = cql3::constants::NULL_LITERAL;
        } else {
            raw = iraw->second;
            ++found_values;
        }
        auto&& value = raw->prepare(db, keyspace, field_spec_of(receiver, i));

        if (dynamic_cast<non_terminal*>(value.get())) {
            all_terminal = false;
        }

        values.push_back(std::move(value));
    }
    if (found_values != _entries.size()) {
        // We had some field that are not part of the type
        for (auto&& id_val : _entries) {
            auto&& id = id_val.first;
            if (!boost::range::count(ut->field_names(), id.bytes_)) {
                throw exceptions::invalid_request_exception(format("Unknown field '{}' in value of user defined type {}", id, ut->get_name_as_string()));
            }
        }
    }

    delayed_value value(ut, values);
    if (all_terminal) {
        return value.bind(query_options::DEFAULT);
    } else {
        return make_shared(std::move(value));
    }
}

void user_types::literal::validate_assignable_to(database& db, const sstring& keyspace, shared_ptr<column_specification> receiver) {
    auto&& ut = dynamic_pointer_cast<const user_type_impl>(receiver->type);
    if (!ut) {
        throw exceptions::invalid_request_exception(format("Invalid user type literal for {} of type {}", receiver->name, receiver->type->as_cql3_type()));
    }

    for (size_t i = 0; i < ut->size(); i++) {
        column_identifier field(to_bytes(ut->field_name(i)), utf8_type);
        if (_entries.count(field) == 0) {
            continue;
        }
        shared_ptr<term::raw> value = _entries[field];
        auto&& field_spec = field_spec_of(receiver, i);
        if (!assignment_testable::is_assignable(value->test_assignment(db, keyspace, field_spec))) {
            throw exceptions::invalid_request_exception(format("Invalid user type literal for {}: field {} is not of type {}", receiver->name, field, field_spec->type->as_cql3_type()));
        }
    }
}

assignment_testable::test_result user_types::literal::test_assignment(database& db, const sstring& keyspace, shared_ptr<column_specification> receiver) {
    try {
        validate_assignable_to(db, keyspace, receiver);
        return assignment_testable::test_result::WEAKLY_ASSIGNABLE;
    } catch (exceptions::invalid_request_exception& e) {
        return assignment_testable::test_result::NOT_ASSIGNABLE;
    }
}

sstring user_types::literal::assignment_testable_source_context() const {
    return to_string();
}

sstring user_types::literal::to_string() const {
    auto kv_to_str = [] (auto&& kv) { return format("{}:{}", kv.first, kv.second); };
    return format("{{{}}}", ::join(", ", _entries | boost::adaptors::transformed(kv_to_str)));
}

user_types::delayed_value::delayed_value(user_type type, std::vector<shared_ptr<term>> values)
        : _type(std::move(type)), _values(std::move(values)) {
}
bool user_types::delayed_value::uses_function(const sstring& ks_name, const sstring& function_name) const {
    return boost::algorithm::any_of(_values,
                std::bind(&term::uses_function, std::placeholders::_1, std::cref(ks_name), std::cref(function_name)));
}
bool user_types::delayed_value::contains_bind_marker() const {
    return boost::algorithm::any_of(_values, std::mem_fn(&term::contains_bind_marker));
}

void user_types::delayed_value::collect_marker_specification(shared_ptr<variable_specifications> bound_names) {
    for (auto&& v : _values) {
        v->collect_marker_specification(bound_names);
    }
}

std::vector<cql3::raw_value> user_types::delayed_value::bind_internal(const query_options& options) {
    auto sf = options.get_cql_serialization_format();
    std::vector<cql3::raw_value> buffers;
    for (size_t i = 0; i < _type->size(); ++i) {
        const auto& value = _values[i]->bind_and_get(options);
        if (!_type->is_multi_cell() && value.is_unset_value()) {
            throw exceptions::invalid_request_exception(format("Invalid unset value for field '{}' of user defined type {}", _type->field_name_as_string(i), _type->get_name_as_string()));
        }
        buffers.push_back(cql3::raw_value::make_value(value));
        // Inside UDT values, we must force the serialization of collections to v3 whatever protocol
        // version is in use since we're going to store directly that serialized value.
        if (!sf.collection_format_unchanged() && _type->field_type(i)->is_collection() && buffers.back()) {
            auto&& ctype = static_pointer_cast<const collection_type_impl>(_type->field_type(i));
            buffers.back() = cql3::raw_value::make_value(
                    ctype->reserialize(sf, cql_serialization_format::latest(), bytes_view(*buffers.back())));
        }
    }
    return buffers;
}

shared_ptr<terminal> user_types::delayed_value::bind(const query_options& options) {
    return ::make_shared<constants::value>(cql3::raw_value::make_value((bind_and_get(options))));
}

cql3::raw_value_view user_types::delayed_value::bind_and_get(const query_options& options) {
    return options.make_temporary(cql3::raw_value::make_value(user_type_impl::build_value(bind_internal(options))));
}

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

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cql3/user_types.hh"

#include "cql3/cql3_type.hh"

#include <boost/range/adaptor/transformed.hpp>
#include <boost/algorithm/cxx11/any_of.hpp>
#include <boost/range/algorithm/count.hpp>

#include "types/user.hh"

namespace cql3 {

shared_ptr<column_specification> user_types::field_spec_of(shared_ptr<column_specification> column, size_t field) {
    auto&& ut = static_pointer_cast<const user_type_impl>(column->type);
    auto&& name = ut->field_name(field);
    auto&& sname = sstring(reinterpret_cast<const char*>(name.data()), name.size());
    return make_shared<column_specification>(
                                   column->ks_name,
                                   column->cf_name,
                                   make_shared<column_identifier>(column->name->to_string() + "." + sname, true),
                                   ut->field_type(field));
}

user_types::literal::literal(elements_map_type entries)
        : _entries(std::move(entries)) {
}

shared_ptr<term> user_types::literal::prepare(database& db, const sstring& keyspace, shared_ptr<column_specification> receiver) {
    validate_assignable_to(db, keyspace, receiver);
    auto&& ut = static_pointer_cast<const user_type_impl>(receiver->type);
    bool all_terminal = true;
    std::vector<shared_ptr<term>> values;
    values.reserve(_entries.size());
    size_t found_values = 0;
    for (size_t i = 0; i < ut->size(); ++i) {
        auto&& field = column_identifier(to_bytes(ut->field_name(i)), utf8_type);
        auto iraw = _entries.find(field);
        shared_ptr<term::raw> raw;
        if (iraw == _entries.end()) {
            raw = cql3::constants::NULL_LITERAL;
        } else {
            raw = iraw->second;
            ++found_values;
        }
        auto&& value = raw->prepare(db, keyspace, field_spec_of(receiver, i));

        if (dynamic_cast<non_terminal*>(value.get())) {
            all_terminal = false;
        }

        values.push_back(std::move(value));
    }
    if (found_values != _entries.size()) {
        // We had some field that are not part of the type
        for (auto&& id_val : _entries) {
            auto&& id = id_val.first;
            if (!boost::range::count(ut->field_names(), id.bytes_)) {
                throw exceptions::invalid_request_exception(format("Unknown field '{}' in value of user defined type {}", id, ut->get_name_as_string()));
            }
        }
    }

    delayed_value value(ut, values);
    if (all_terminal) {
        return value.bind(query_options::DEFAULT);
    } else {
        return make_shared(std::move(value));
    }
}

void user_types::literal::validate_assignable_to(database& db, const sstring& keyspace, shared_ptr<column_specification> receiver) {
    if (!receiver->type->is_user_type()) {
        throw exceptions::invalid_request_exception(format("Invalid user type literal for {} of type {}", receiver->name, receiver->type->as_cql3_type()));
    }

    auto ut = static_pointer_cast<const user_type_impl>(receiver->type);
    for (size_t i = 0; i < ut->size(); i++) {
        column_identifier field(to_bytes(ut->field_name(i)), utf8_type);
        if (_entries.count(field) == 0) {
            continue;
        }
        shared_ptr<term::raw> value = _entries[field];
        auto&& field_spec = field_spec_of(receiver, i);
        if (!assignment_testable::is_assignable(value->test_assignment(db, keyspace, field_spec))) {
            throw exceptions::invalid_request_exception(format("Invalid user type literal for {}: field {} is not of type {}", receiver->name, field, field_spec->type->as_cql3_type()));
        }
    }
}

assignment_testable::test_result user_types::literal::test_assignment(database& db, const sstring& keyspace, shared_ptr<column_specification> receiver) {
    try {
        validate_assignable_to(db, keyspace, receiver);
        return assignment_testable::test_result::WEAKLY_ASSIGNABLE;
    } catch (exceptions::invalid_request_exception& e) {
        return assignment_testable::test_result::NOT_ASSIGNABLE;
    }
}

sstring user_types::literal::assignment_testable_source_context() const {
    return to_string();
}

sstring user_types::literal::to_string() const {
    auto kv_to_str = [] (auto&& kv) { return format("{}:{}", kv.first, kv.second); };
    return format("{{{}}}", ::join(", ", _entries | boost::adaptors::transformed(kv_to_str)));
}

user_types::delayed_value::delayed_value(user_type type, std::vector<shared_ptr<term>> values)
        : _type(std::move(type)), _values(std::move(values)) {
}
bool user_types::delayed_value::uses_function(const sstring& ks_name, const sstring& function_name) const {
    return boost::algorithm::any_of(_values,
                std::bind(&term::uses_function, std::placeholders::_1, std::cref(ks_name), std::cref(function_name)));
}
bool user_types::delayed_value::contains_bind_marker() const {
    return boost::algorithm::any_of(_values, std::mem_fn(&term::contains_bind_marker));
}

void user_types::delayed_value::collect_marker_specification(shared_ptr<variable_specifications> bound_names) {
    for (auto&& v : _values) {
        v->collect_marker_specification(bound_names);
    }
}

std::vector<cql3::raw_value> user_types::delayed_value::bind_internal(const query_options& options) {
    auto sf = options.get_cql_serialization_format();
    std::vector<cql3::raw_value> buffers;
    for (size_t i = 0; i < _type->size(); ++i) {
        const auto& value = _values[i]->bind_and_get(options);
        if (!_type->is_multi_cell() && value.is_unset_value()) {
            throw exceptions::invalid_request_exception(format("Invalid unset value for field '{}' of user defined type {}", _type->field_name_as_string(i), _type->get_name_as_string()));
        }
        buffers.push_back(cql3::raw_value::make_value(value));
        // Inside UDT values, we must force the serialization of collections to v3 whatever protocol
        // version is in use since we're going to store directly that serialized value.
        if (!sf.collection_format_unchanged() && _type->field_type(i)->is_collection() && buffers.back()) {
            auto&& ctype = static_pointer_cast<const collection_type_impl>(_type->field_type(i));
            buffers.back() = cql3::raw_value::make_value(
                    ctype->reserialize(sf, cql_serialization_format::latest(), bytes_view(*buffers.back())));
        }
    }
    return buffers;
}

shared_ptr<terminal> user_types::delayed_value::bind(const query_options& options) {
    return ::make_shared<constants::value>(cql3::raw_value::make_value((bind_and_get(options))));
}

cql3::raw_value_view user_types::delayed_value::bind_and_get(const query_options& options) {
    return options.make_temporary(cql3::raw_value::make_value(user_type_impl::build_value(bind_internal(options))));
}

}
<|endoftext|>