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

#ifndef _SC_ACCESSIBLEDOCUMENT_HXX
#include "AccessibleDocument.hxx"
#endif
#ifndef _SC_ACCESSIBLESPREADSHEET_HXX
#include "AccessibleSpreadsheet.hxx"
#endif
#ifndef SC_TABVWSH_HXX
#include "tabvwsh.hxx"
#endif
#ifndef SC_ACCESSIBILITYHINTS_HXX
#include "AccessibilityHints.hxx"
#endif
#ifndef SC_DOCUMENT_HXX
#include "document.hxx"
#endif
#ifndef SC_DRWLAYER_HXX
#include "drwlayer.hxx"
#endif
#ifndef SC_UNOGUARD_HXX
#include "unoguard.hxx"
#endif

#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleEventId.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleStateType.hpp>
#endif

#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
#include <unotools/accessiblestatesethelper.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef _SVDPAGE_HXX
#include <svx/svdpage.hxx>
#endif
#ifndef _SVDOBJ_HXX
#include <svx/svdobj.hxx>
#endif

using namespace ::com::sun::star;
using namespace ::drafts::com::sun::star::accessibility;

    //=====  internal  ========================================================

ScAccessibleDocument::ScAccessibleDocument(
        const uno::Reference<XAccessible>& rxParent,
        ScTabViewShell* pViewShell,
        ScSplitPos eSplitPos)
    : ScAccessibleDocumentBase(rxParent),
    mpViewShell(pViewShell),
    meSplitPos(eSplitPos),
    mpAccessibleSpreadsheet(NULL)
{
    if (pViewShell)
        pViewShell->AddAccessibilityObject(*this);
}

ScAccessibleDocument::~ScAccessibleDocument(void)
{
    FreeAccessibleSpreadsheet();
    if (mpViewShell)
    {
        mpViewShell->RemoveAccessibilityObject(*this);
    }
}

void ScAccessibleDocument::SetDefunc()
{
    FreeAccessibleSpreadsheet();
    if (mpViewShell)
    {
        mpViewShell->RemoveAccessibilityObject(*this);
        mpViewShell = NULL;
    }

    ScAccessibleDocumentBase::SetDefunc();
}

    //=====  SfxListener  =====================================================

void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
    if (rHint.ISA( ScAccGridViewChangeHint ) )
    {
        const ScAccGridViewChangeHint& rRef = (const ScAccGridViewChangeHint&)rHint;
        if ((rRef.GetOldGridWin() == meSplitPos) ||
            (rRef.GetNewGridWin() == meSplitPos))
        {
            awt::FocusEvent aFocusEvent;
            aFocusEvent.Temporary = sal_False;
            if (rRef.GetOldGridWin() == meSplitPos)
            {
                aFocusEvent.NextFocus = rRef.GetNewAccessible();
                CommitFocusLost(aFocusEvent);
            }
            else
            {
                aFocusEvent.NextFocus = rRef.GetOldAccessible();
                CommitFocusGained(aFocusEvent);
            }
        }
    }
    else if (rHint.ISA( SfxSimpleHint ))
    {
        const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
        // only notify if child exist, otherwise it is not necessary
        if ((rRef.GetId() == SC_HINT_ACC_TABLECHANGED) &&
            mpAccessibleSpreadsheet)
        {
            AccessibleEventObject aEvent;
            aEvent.EventId = AccessibleEventId::ACCESSIBLE_CHILD_EVENT;
            aEvent.OldValue <<= GetAccessibleSpreadsheet();

            CommitChange(aEvent); // child is gone - event

            aEvent.OldValue = uno::Any();
            FreeAccessibleSpreadsheet(); // free the spreadsheet after free the reference on this object
            aEvent.NewValue <<= GetAccessibleSpreadsheet();

            CommitChange(aEvent); // there is a new child - event
        }
        else if (rRef.GetId() == SFX_HINT_DYING)
        {
            // it seems the Broadcaster is dying, since the view is dying
            SetDefunc();
        }
    }
}

    //=====  XAccessibleComponent  ============================================

uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAt(
        const awt::Point& rPoint )
        throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    uno::Reference<XAccessible> xAccessible = NULL;
    SdrPage* pDrawPage = GetDrawPage();
    if (pDrawPage)
    {
        DBG_ERROR("not implemented");
    }
    else
        xAccessible = GetAccessibleSpreadsheet();
    return xAccessible;
}

void SAL_CALL ScAccessibleDocument::grabFocus(  )
        throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    if (getAccessibleParent().is())
    {
        uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
        if (xAccessibleComponent.is())
        {
            xAccessibleComponent->grabFocus();
            // grab only focus if it does not have the focus and it is not hidden
            if (mpViewShell && mpViewShell->GetViewData() &&
                (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) &&
                mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
            {
                mpViewShell->ActivatePart(meSplitPos);
            }
        }
    }
}

    //=====  XAccessibleContext  ==============================================

    /// Return the number of currently visible children.
long SAL_CALL
    ScAccessibleDocument::getAccessibleChildCount(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    sal_Int32 nShapes (0);
    SdrPage* pDrawPage = GetDrawPage();
    if (pDrawPage)
    {
        sal_uInt32 nObjCount(pDrawPage->GetObjCount());
        for (sal_uInt32 i = 0; i < nObjCount; i++)
        {
            SdrObject* pObj = pDrawPage->GetObj(i);
            if (pObj && (pObj->GetLayer() != SC_LAYER_INTERN))
                nShapes++;
        }
    }
    return nShapes + 1;
}

    /// Return the specified child or NULL if index is invalid.
uno::Reference<XAccessible> SAL_CALL
    ScAccessibleDocument::getAccessibleChild(long nIndex)
    throw (uno::RuntimeException,
        lang::IndexOutOfBoundsException)
{
    ScUnoGuard aGuard;
    uno::Reference<XAccessible> xAccessible;// = GetChild(nIndex);
    if (!xAccessible.is())
    {
        if (nIndex == 0)
            xAccessible = GetAccessibleSpreadsheet();
        else
        {
            DBG_ERROR("should return other childs here");
            // there is no child with this index at the moment
            throw lang::IndexOutOfBoundsException();
        }

        //SetChild(nIndex, xAccessible);
    }
    return xAccessible;
}

    /// Return the set of current states.
uno::Reference<XAccessibleStateSet> SAL_CALL
    ScAccessibleDocument::getAccessibleStateSet(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    uno::Reference<XAccessibleStateSet> xParentStates;
    if (getAccessibleParent().is())
    {
        uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
        xParentStates = xParentContext->getAccessibleStateSet();
    }
    utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
    if (IsDefunc(xParentStates))
        pStateSet->AddState(AccessibleStateType::DEFUNC);
    if (IsEditable(xParentStates))
        pStateSet->AddState(AccessibleStateType::EDITABLE);
    pStateSet->AddState(AccessibleStateType::ENABLED);
    pStateSet->AddState(AccessibleStateType::OPAQUE);
    if (isShowing())
        pStateSet->AddState(AccessibleStateType::SHOWING);
    if (isVisible())
        pStateSet->AddState(AccessibleStateType::VISIBLE);
    return pStateSet;
}

    //=====  XServiceInfo  ====================================================

::rtl::OUString SAL_CALL
    ScAccessibleDocument::getImplementationName(void)
    throw (uno::RuntimeException)
{
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument"));
}

uno::Sequence< ::rtl::OUString> SAL_CALL
    ScAccessibleDocument::getSupportedServiceNames(void)
        throw (uno::RuntimeException)
{
    uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
    sal_Int32 nOldSize(aSequence.getLength());
    aSequence.realloc(nOldSize + 1);
    ::rtl::OUString* pNames = aSequence.getArray();

    pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("drafts.com.sun.star.AccessibleSpreadsheetDocumentView"));

    return aSequence;
}

//=====  XTypeProvider  =======================================================

uno::Sequence<sal_Int8> SAL_CALL
    ScAccessibleDocument::getImplementationId(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    static uno::Sequence<sal_Int8> aId;
    if (aId.getLength() == 0)
    {
        aId.realloc (16);
        rtl_createUuid ((sal_uInt8 *)aId.getArray(), 0, sal_True);
    }
    return aId;
}

    //=====  internal  ========================================================

::rtl::OUString SAL_CALL
    ScAccessibleDocument::createAccessibleDescription(void)
    throw (uno::RuntimeException)
{
    return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("This is a view of a Spreadsheet Document."));
}

::rtl::OUString SAL_CALL
    ScAccessibleDocument::createAccessibleName(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    rtl::OUString sName(RTL_CONSTASCII_USTRINGPARAM ("Spreadsheet Document View "));
    sal_Int32 nNumber(sal_Int32(meSplitPos) + 1);
    sName += rtl::OUString::valueOf(nNumber);
    return sName;
}

Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen()
    throw (uno::RuntimeException)
{
    Rectangle aRect;
    if (mpViewShell)
    {
        Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
        if (pWindow)
            aRect = pWindow->GetWindowExtentsRelative(NULL);
    }
    return aRect;
}

Rectangle ScAccessibleDocument::GetBoundingBox()
    throw (uno::RuntimeException)
{
    Rectangle aRect;
    if (mpViewShell)
    {
        Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
        if (pWindow)
            aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
    }
    return aRect;
}

sal_uInt16 ScAccessibleDocument::getVisibleTable()
{
    sal_uInt16 nVisibleTable(0);
    if (mpViewShell && mpViewShell->GetViewData())
        nVisibleTable = mpViewShell->GetViewData()->GetTabNo();
    return nVisibleTable;
}

uno::Reference < XAccessible >
    ScAccessibleDocument::GetAccessibleSpreadsheet()
{
    if (!mpAccessibleSpreadsheet && mpViewShell)
    {
        mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos);
        mpAccessibleSpreadsheet->acquire();
        mpAccessibleSpreadsheet->Init();
    }
    return mpAccessibleSpreadsheet;
}

void ScAccessibleDocument::FreeAccessibleSpreadsheet()
{
    if (mpAccessibleSpreadsheet)
    {
        mpAccessibleSpreadsheet->SetDefunc();
        mpAccessibleSpreadsheet->release();
        mpAccessibleSpreadsheet = NULL;
    }
}

SdrPage* ScAccessibleDocument::GetDrawPage()
{
    sal_uInt16 nTab(getVisibleTable());
    SdrPage* pDrawPage = NULL;
    if (mpViewShell && mpViewShell->GetViewData())
    {
        ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
        if (pDoc && pDoc->GetDrawLayer())
        {
            ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
            if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
                pDrawPage = pDrawLayer->GetPage(nTab);
        }
    }
    return pDrawPage;
}

sal_Bool ScAccessibleDocument::IsDefunc(
    const uno::Reference<XAccessibleStateSet>& rxParentStates)
{
    return (mpViewShell == NULL) || !getAccessibleParent().is() ||
        (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
}

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

#ifndef _SC_ACCESSIBLEDOCUMENT_HXX
#include "AccessibleDocument.hxx"
#endif
#ifndef _SC_ACCESSIBLESPREADSHEET_HXX
#include "AccessibleSpreadsheet.hxx"
#endif
#ifndef SC_TABVWSH_HXX
#include "tabvwsh.hxx"
#endif
#ifndef SC_ACCESSIBILITYHINTS_HXX
#include "AccessibilityHints.hxx"
#endif
#ifndef SC_DOCUMENT_HXX
#include "document.hxx"
#endif
#ifndef SC_DRWLAYER_HXX
#include "drwlayer.hxx"
#endif
#ifndef SC_UNOGUARD_HXX
#include "unoguard.hxx"
#endif

#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleEventId.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleStateType.hpp>
#endif

#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
#include <unotools/accessiblestatesethelper.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef _SVDPAGE_HXX
#include <svx/svdpage.hxx>
#endif
#ifndef _SVDOBJ_HXX
#include <svx/svdobj.hxx>
#endif

using namespace ::com::sun::star;
using namespace ::drafts::com::sun::star::accessibility;

    //=====  internal  ========================================================

ScAccessibleDocument::ScAccessibleDocument(
        const uno::Reference<XAccessible>& rxParent,
        ScTabViewShell* pViewShell,
        ScSplitPos eSplitPos)
    : ScAccessibleDocumentBase(rxParent),
    mpViewShell(pViewShell),
    meSplitPos(eSplitPos),
    mpAccessibleSpreadsheet(NULL)
{
    if (pViewShell)
        pViewShell->AddAccessibilityObject(*this);
}

ScAccessibleDocument::~ScAccessibleDocument(void)
{
    FreeAccessibleSpreadsheet();
    if (mpViewShell)
    {
        mpViewShell->RemoveAccessibilityObject(*this);
    }
}

void ScAccessibleDocument::SetDefunc()
{
    FreeAccessibleSpreadsheet();
    if (mpViewShell)
    {
        mpViewShell->RemoveAccessibilityObject(*this);
        mpViewShell = NULL;
    }

    ScAccessibleDocumentBase::SetDefunc();
}

    //=====  SfxListener  =====================================================

void ScAccessibleDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
    if (rHint.ISA( ScAccGridViewChangeHint ) )
    {
        const ScAccGridViewChangeHint& rRef = (const ScAccGridViewChangeHint&)rHint;
        if ((rRef.GetOldGridWin() == meSplitPos) ||
            (rRef.GetNewGridWin() == meSplitPos))
        {
            awt::FocusEvent aFocusEvent;
            aFocusEvent.Temporary = sal_False;
            if (rRef.GetOldGridWin() == meSplitPos)
            {
                aFocusEvent.NextFocus = rRef.GetNewAccessible();
                CommitFocusLost(aFocusEvent);
            }
            else
            {
                aFocusEvent.NextFocus = rRef.GetOldAccessible();
                CommitFocusGained(aFocusEvent);
            }
        }
    }
    else if (rHint.ISA( SfxSimpleHint ))
    {
        const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
        // only notify if child exist, otherwise it is not necessary
        if ((rRef.GetId() == SC_HINT_ACC_TABLECHANGED) &&
            mpAccessibleSpreadsheet)
        {
            AccessibleEventObject aEvent;
            aEvent.EventId = AccessibleEventId::ACCESSIBLE_CHILD_EVENT;
            aEvent.Source = uno::Reference< XAccessible >(this);
            aEvent.OldValue <<= GetAccessibleSpreadsheet();

            CommitChange(aEvent); // child is gone - event

            aEvent.OldValue = uno::Any();
            FreeAccessibleSpreadsheet(); // free the spreadsheet after free the reference on this object
            aEvent.NewValue <<= GetAccessibleSpreadsheet();

            CommitChange(aEvent); // there is a new child - event
        }
        else if (rRef.GetId() == SFX_HINT_DYING)
        {
            // it seems the Broadcaster is dying, since the view is dying
            SetDefunc();
        }
    }
}

    //=====  XAccessibleComponent  ============================================

uno::Reference< XAccessible > SAL_CALL ScAccessibleDocument::getAccessibleAt(
        const awt::Point& rPoint )
        throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    uno::Reference<XAccessible> xAccessible = NULL;
    SdrPage* pDrawPage = GetDrawPage();
    if (pDrawPage)
    {
        DBG_ERROR("not implemented");
    }
    else
        xAccessible = GetAccessibleSpreadsheet();
    return xAccessible;
}

void SAL_CALL ScAccessibleDocument::grabFocus(  )
        throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    if (getAccessibleParent().is())
    {
        uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
        if (xAccessibleComponent.is())
        {
            xAccessibleComponent->grabFocus();
            // grab only focus if it does not have the focus and it is not hidden
            if (mpViewShell && mpViewShell->GetViewData() &&
                (mpViewShell->GetViewData()->GetActivePart() != meSplitPos) &&
                mpViewShell->GetWindowByPos(meSplitPos)->IsVisible())
            {
                mpViewShell->ActivatePart(meSplitPos);
            }
        }
    }
}

    //=====  XAccessibleContext  ==============================================

    /// Return the number of currently visible children.
long SAL_CALL
    ScAccessibleDocument::getAccessibleChildCount(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    sal_Int32 nShapes (0);
    SdrPage* pDrawPage = GetDrawPage();
    if (pDrawPage)
    {
        sal_uInt32 nObjCount(pDrawPage->GetObjCount());
        for (sal_uInt32 i = 0; i < nObjCount; i++)
        {
            SdrObject* pObj = pDrawPage->GetObj(i);
            if (pObj && (pObj->GetLayer() != SC_LAYER_INTERN))
                nShapes++;
        }
    }
    return nShapes + 1;
}

    /// Return the specified child or NULL if index is invalid.
uno::Reference<XAccessible> SAL_CALL
    ScAccessibleDocument::getAccessibleChild(long nIndex)
    throw (uno::RuntimeException,
        lang::IndexOutOfBoundsException)
{
    ScUnoGuard aGuard;
    uno::Reference<XAccessible> xAccessible;// = GetChild(nIndex);
    if (!xAccessible.is())
    {
        if (nIndex == 0)
            xAccessible = GetAccessibleSpreadsheet();
        else
        {
            DBG_ERROR("should return other childs here");
            // there is no child with this index at the moment
            throw lang::IndexOutOfBoundsException();
        }

        //SetChild(nIndex, xAccessible);
    }
    return xAccessible;
}

    /// Return the set of current states.
uno::Reference<XAccessibleStateSet> SAL_CALL
    ScAccessibleDocument::getAccessibleStateSet(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    uno::Reference<XAccessibleStateSet> xParentStates;
    if (getAccessibleParent().is())
    {
        uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
        xParentStates = xParentContext->getAccessibleStateSet();
    }
    utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
    if (IsDefunc(xParentStates))
        pStateSet->AddState(AccessibleStateType::DEFUNC);
    if (IsEditable(xParentStates))
        pStateSet->AddState(AccessibleStateType::EDITABLE);
    pStateSet->AddState(AccessibleStateType::ENABLED);
    pStateSet->AddState(AccessibleStateType::OPAQUE);
    if (isShowing())
        pStateSet->AddState(AccessibleStateType::SHOWING);
    if (isVisible())
        pStateSet->AddState(AccessibleStateType::VISIBLE);
    return pStateSet;
}

    //=====  XServiceInfo  ====================================================

::rtl::OUString SAL_CALL
    ScAccessibleDocument::getImplementationName(void)
    throw (uno::RuntimeException)
{
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleDocument"));
}

uno::Sequence< ::rtl::OUString> SAL_CALL
    ScAccessibleDocument::getSupportedServiceNames(void)
        throw (uno::RuntimeException)
{
    uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
    sal_Int32 nOldSize(aSequence.getLength());
    aSequence.realloc(nOldSize + 1);
    ::rtl::OUString* pNames = aSequence.getArray();

    pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("drafts.com.sun.star.AccessibleSpreadsheetDocumentView"));

    return aSequence;
}

//=====  XTypeProvider  =======================================================

uno::Sequence<sal_Int8> SAL_CALL
    ScAccessibleDocument::getImplementationId(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    static uno::Sequence<sal_Int8> aId;
    if (aId.getLength() == 0)
    {
        aId.realloc (16);
        rtl_createUuid ((sal_uInt8 *)aId.getArray(), 0, sal_True);
    }
    return aId;
}

    //=====  internal  ========================================================

::rtl::OUString SAL_CALL
    ScAccessibleDocument::createAccessibleDescription(void)
    throw (uno::RuntimeException)
{
    return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("This is a view of a Spreadsheet Document."));
}

::rtl::OUString SAL_CALL
    ScAccessibleDocument::createAccessibleName(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    rtl::OUString sName(RTL_CONSTASCII_USTRINGPARAM ("Spreadsheet Document View "));
    sal_Int32 nNumber(sal_Int32(meSplitPos) + 1);
    sName += rtl::OUString::valueOf(nNumber);
    return sName;
}

Rectangle ScAccessibleDocument::GetBoundingBoxOnScreen()
    throw (uno::RuntimeException)
{
    Rectangle aRect;
    if (mpViewShell)
    {
        Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
        if (pWindow)
            aRect = pWindow->GetWindowExtentsRelative(NULL);
    }
    return aRect;
}

Rectangle ScAccessibleDocument::GetBoundingBox()
    throw (uno::RuntimeException)
{
    Rectangle aRect;
    if (mpViewShell)
    {
        Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
        if (pWindow)
            aRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
    }
    return aRect;
}

sal_uInt16 ScAccessibleDocument::getVisibleTable()
{
    sal_uInt16 nVisibleTable(0);
    if (mpViewShell && mpViewShell->GetViewData())
        nVisibleTable = mpViewShell->GetViewData()->GetTabNo();
    return nVisibleTable;
}

uno::Reference < XAccessible >
    ScAccessibleDocument::GetAccessibleSpreadsheet()
{
    if (!mpAccessibleSpreadsheet && mpViewShell)
    {
        mpAccessibleSpreadsheet = new ScAccessibleSpreadsheet(this, mpViewShell, getVisibleTable(), meSplitPos);
        mpAccessibleSpreadsheet->acquire();
        mpAccessibleSpreadsheet->Init();
    }
    return mpAccessibleSpreadsheet;
}

void ScAccessibleDocument::FreeAccessibleSpreadsheet()
{
    if (mpAccessibleSpreadsheet)
    {
        mpAccessibleSpreadsheet->SetDefunc();
        mpAccessibleSpreadsheet->release();
        mpAccessibleSpreadsheet = NULL;
    }
}

SdrPage* ScAccessibleDocument::GetDrawPage()
{
    sal_uInt16 nTab(getVisibleTable());
    SdrPage* pDrawPage = NULL;
    if (mpViewShell && mpViewShell->GetViewData())
    {
        ScDocument* pDoc = mpViewShell->GetViewData()->GetDocument();
        if (pDoc && pDoc->GetDrawLayer())
        {
            ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
            if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
                pDrawPage = pDrawLayer->GetPage(nTab);
        }
    }
    return pDrawPage;
}

sal_Bool ScAccessibleDocument::IsDefunc(
    const uno::Reference<XAccessibleStateSet>& rxParentStates)
{
    return (mpViewShell == NULL) || !getAccessibleParent().is() ||
        (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
}

sal_Bool ScAccessibleDocument::IsEditable(
    const uno::Reference<XAccessibleStateSet>& rxParentStates)
{
    // what is with document protection?
    return sal_True;
}
<|endoftext|>


<commit_before>/*---------------------------------------------------------------------\
|                                                                      |
|                     _     _   _   _     __     _                     |
|                    | |   | | | \_/ |   /  \   | |                    |
|                    | |   | | | |_| |  / /\ \  | |                    |
|                    | |__ | | | | | | / ____ \ | |__                  |
|                    |____||_| |_| |_|/ /    \ \|____|                 |
|                                                                      |
|                             ca-mgm library                           |
|                                                                      |
|                                         (C) SUSE Linux Products GmbH |
\----------------------------------------------------------------------/

  File:       DNObject.cpp

  Author:     <Michael Calmer>     <mc@suse.de>
  Maintainer: <Michael Calmer>     <mc@suse.de>

  Purpose:

/-*/

#include  <limal/ca-mgm/DNObject.hpp>
#include  <limal/ValueRegExCheck.hpp>
#include  <limal/Exception.hpp>
#include  <blocxx/Format.hpp>

#include  "Utils.hpp"

using namespace limal;
using namespace limal::ca_mgm;
using namespace blocxx;

RDNObject::RDNObject()
    : type(String()), value(String())
{
}

RDNObject::RDNObject(const String& type, const String& value)
    : type(type), value(value)
{}

RDNObject::RDNObject(const RDNObject& rdn)
    : type(rdn.type), value(rdn.value)
{}

RDNObject::~RDNObject()
{}

RDNObject&
RDNObject::operator=(const RDNObject& rdn)
{
    if(this == &rdn) return *this;

    type  = rdn.type;
    value = rdn.value;

    return *this;
}

void
RDNObject::setRDN(const String& type, const String& value)
{
    this->type  = type;
    this->value = value;
}

blocxx::String
RDNObject::getType() const
{
    return type;
}

blocxx::String
RDNObject::getValue() const
{
    return value;
}

bool
RDNObject::valid() const
{
    if(type.empty()) {
        LOGIT_DEBUG("type is empty");
        return false;
    }
    if(value.empty()) {
        LOGIT_DEBUG("value is empty");
        return false;
    }
    // FIXME: define and check pre defined types ?

    return true;
}

blocxx::StringArray
RDNObject::verify() const
{
    StringArray result;

    if(type.empty()) {
        result.append("type is empty");
    }
    if(value.empty()) {
        result.append("value is empty");
    }
    // FIXME: define and check pre defined types ?

    LOGIT_DEBUG_STRINGARRAY("RDNObject::verify()", result);

    return result;
}

blocxx::StringArray
RDNObject::dump() const
{
    StringArray result;
    result.append("RDNObject::dump()");

    result.append(type + "=" + value);

    return result;
}

// ######################################################################

DNObject::DNObject()
    : dn(blocxx::List<RDNObject>())
{
}

DNObject::DNObject(const blocxx::List<RDNObject> &dn)
    : dn(dn)
{
    StringArray r = this->verify();
    if(!r.empty()) {
        BLOCXX_THROW(limal::ValueException, r[0].c_str());
    }
}

DNObject::DNObject(const DNObject& dn)
    : dn(dn.dn)
{}

DNObject::~DNObject()
{}

DNObject&
DNObject::operator=(const DNObject& dn)
{
    if(this == &dn) return *this;

    this->dn = dn.dn;

    return *this;
}

void
DNObject::setDN(const blocxx::List<RDNObject> &dn)
{
    StringArray r = checkRDNList(dn);
    if(!r.empty()) {
        LOGIT_ERROR(r[0]);
        BLOCXX_THROW(limal::ValueException, r[0].c_str());
    }
    this->dn = dn;
}

blocxx::List<RDNObject>
DNObject::getDN() const
{
    return dn;
}

bool
DNObject::valid() const
{
    if(dn.empty()) {
        LOGIT_DEBUG("empty DN");
        return false;
    }
    StringArray r = checkRDNList(dn);
    if(!r.empty()) {
        LOGIT_DEBUG(r[0]);
        return false;
    }
    return true;
}

blocxx::StringArray
DNObject::verify() const
{
    StringArray result;

    if(dn.empty()) {
        result.append("empty DN");
    }
    result.appendArray(checkRDNList(dn));

    LOGIT_DEBUG_STRINGARRAY("DNObject::verify()", result);

    return result;
}

blocxx::StringArray
DNObject::checkRDNList(const blocxx::List<RDNObject>& list) const
{
    StringArray result;

    blocxx::List<RDNObject>::const_iterator it = list.begin();
    for(; it != list.end(); ++it) {
        result.appendArray((*it).verify());
    }
    return result;
}

blocxx::StringArray
DNObject::dump() const
{
    StringArray result;
    result.append("DNObject::dump()");

    blocxx::List< RDNObject >::const_iterator it = dn.begin();
    for(; it != dn.end(); ++it) {
        result.appendArray((*it).dump());
    }

    return result;
}
<commit_msg>return default DN list<commit_after>/*---------------------------------------------------------------------\
|                                                                      |
|                     _     _   _   _     __     _                     |
|                    | |   | | | \_/ |   /  \   | |                    |
|                    | |   | | | |_| |  / /\ \  | |                    |
|                    | |__ | | | | | | / ____ \ | |__                  |
|                    |____||_| |_| |_|/ /    \ \|____|                 |
|                                                                      |
|                             ca-mgm library                           |
|                                                                      |
|                                         (C) SUSE Linux Products GmbH |
\----------------------------------------------------------------------/

  File:       DNObject.cpp

  Author:     <Michael Calmer>     <mc@suse.de>
  Maintainer: <Michael Calmer>     <mc@suse.de>

  Purpose:

/-*/

#include  <limal/ca-mgm/DNObject.hpp>
#include  <limal/ValueRegExCheck.hpp>
#include  <limal/Exception.hpp>
#include  <blocxx/Format.hpp>

#include  "Utils.hpp"

using namespace limal;
using namespace limal::ca_mgm;
using namespace blocxx;

RDNObject::RDNObject()
    : type(String()), value(String())
{
}

RDNObject::RDNObject(const String& type, const String& value)
    : type(type), value(value)
{}

RDNObject::RDNObject(const RDNObject& rdn)
    : type(rdn.type), value(rdn.value)
{}

RDNObject::~RDNObject()
{}

RDNObject&
RDNObject::operator=(const RDNObject& rdn)
{
    if(this == &rdn) return *this;

    type  = rdn.type;
    value = rdn.value;

    return *this;
}

void
RDNObject::setRDN(const String& type, const String& value)
{
    this->type  = type;
    this->value = value;
}

blocxx::String
RDNObject::getType() const
{
    return type;
}

blocxx::String
RDNObject::getValue() const
{
    return value;
}

bool
RDNObject::valid() const
{
    if(type.empty()) {
        LOGIT_DEBUG("type is empty");
        return false;
    }
    /*
      if(value.empty()) {
      LOGIT_DEBUG("value is empty");
      return false;
      }
    */
    // FIXME: define and check pre defined types ?

    return true;
}

blocxx::StringArray
RDNObject::verify() const
{
    StringArray result;

    if(type.empty()) {
        result.append("type is empty");
    }
    /*
      if(value.empty()) {
      result.append("value is empty");
      }
    */
    // FIXME: define and check pre defined types ?

    LOGIT_DEBUG_STRINGARRAY("RDNObject::verify()", result);

    return result;
}

blocxx::StringArray
RDNObject::dump() const
{
    StringArray result;
    result.append("RDNObject::dump()");

    result.append(type + "=" + value);

    return result;
}

// ######################################################################

DNObject::DNObject()
    : dn(blocxx::List<RDNObject>())
{
    dn.push_back(RDNObject("countryName", ""));
    dn.push_back(RDNObject("stateOrProvinceName", ""));
    dn.push_back(RDNObject("localityName", ""));
    dn.push_back(RDNObject("organizationName", ""));
    dn.push_back(RDNObject("organizationalUnitName", ""));
    dn.push_back(RDNObject("commonName", ""));
    dn.push_back(RDNObject("emailAddress", ""));
}

DNObject::DNObject(const blocxx::List<RDNObject> &dn)
    : dn(dn)
{
    StringArray r = this->verify();
    if(!r.empty()) {
        BLOCXX_THROW(limal::ValueException, r[0].c_str());
    }
}

DNObject::DNObject(const DNObject& dn)
    : dn(dn.dn)
{}

DNObject::~DNObject()
{}

DNObject&
DNObject::operator=(const DNObject& dn)
{
    if(this == &dn) return *this;

    this->dn = dn.dn;

    return *this;
}

void
DNObject::setDN(const blocxx::List<RDNObject> &dn)
{
    StringArray r = checkRDNList(dn);
    if(!r.empty()) {
        LOGIT_ERROR(r[0]);
        BLOCXX_THROW(limal::ValueException, r[0].c_str());
    }
    this->dn = dn;
}

blocxx::List<RDNObject>
DNObject::getDN() const
{
    return dn;
}

bool
DNObject::valid() const
{
    if(dn.empty()) {
        LOGIT_DEBUG("empty DN");
        return false;
    }
    StringArray r = checkRDNList(dn);
    if(!r.empty()) {
        LOGIT_DEBUG(r[0]);
        return false;
    }
    return true;
}

blocxx::StringArray
DNObject::verify() const
{
    StringArray result;

    if(dn.empty()) {
        result.append("empty DN");
    }
    result.appendArray(checkRDNList(dn));

    LOGIT_DEBUG_STRINGARRAY("DNObject::verify()", result);

    return result;
}

blocxx::StringArray
DNObject::checkRDNList(const blocxx::List<RDNObject>& list) const
{
    StringArray result;

    blocxx::List<RDNObject>::const_iterator it = list.begin();
    for(; it != list.end(); ++it) {
        result.appendArray((*it).verify());
    }
    return result;
}

blocxx::StringArray
DNObject::dump() const
{
    StringArray result;
    result.append("DNObject::dump()");

    blocxx::List< RDNObject >::const_iterator it = dn.begin();
    for(; it != dn.end(); ++it) {
        result.appendArray((*it).dump());
    }

    return result;
}
<|endoftext|>


<commit_before>#include <iostream>

#include "TObjArray.h"
#include "TTimer.h"
#include "TThread.h"
#include "AliEveEventBuffer.h"

//Not needed, only for debug
#include "AliESDEvent.h"

using namespace std;

ClassImp(AliEveEventBuffer)

///_______________________________________________________________________
AliEveEventBuffer::AliEveEventBuffer() :
  fBufferSize(10),
  fPreBuffer(4),
  fBusy(kFALSE),
  fEventBuffer(NULL),
  fCurrentEvent(NULL),
  fBIndex(),
  fTimer(NULL),
  fEventId(),
  fBufferMonStarted(kFALSE)
 {
  // see header file for class documentation
  fEventBuffer = new TObjArray(fBufferSize, 0);
  fEventBuffer->SetOwner(kFALSE);

  for(int id = 0; id < kSize; id++) {
    fBIndex[id] = -1;
  }

  fTimer = new TTimer();
  fTimer->Connect("Timeout()", "AliEveEventBuffer", this, "CreateBufferThread()");

  fEventId = new ULong64_t[fBufferSize];
  for(Int_t id = 0; id < fBufferSize; id++ ) {
    fEventId[id] = -2;
  }

}

///_______________________________________________________________________
AliEveEventBuffer::~AliEveEventBuffer() {
  // see header file for class documentation

  if ( fEventBuffer ) {
    fEventBuffer->Clear();
    delete fEventBuffer;
  }
  fEventBuffer = NULL;

  if(fCurrentEvent)
    delete fCurrentEvent;
  fCurrentEvent = NULL;

}

///___________________________________________________________________________
void AliEveEventBuffer::CreateBufferThread() {
  if(GetBusy()) {
    cout << "Buffer is busy, no thread created"<< endl;
  } else {
    SetBusy(kTRUE);
    if ( (CalculateDifference(fBIndex[kTop],fBIndex[kLast]) < fPreBuffer) ) {
      cout << "CreateBufferThread()"<<endl;
      TThread * fThread = new TThread(AliEveEventBuffer::BufferThread, (void*) this);
      fThread->Run();
      cout << "Started BufferThread"<<endl;
    } else {
      cout << "Buffer is full already"<<endl;
    }
  }
}
///___________________________________________________________________________
void * AliEveEventBuffer::BufferThread(void * buffer) {
  cout <<"BufferThread : " <<endl;
  if(buffer) {
      reinterpret_cast<AliEveEventBuffer*>(buffer)->MonitorBuffer();
  } else {
    cout << "no buffer"<<endl;
  }
  return (void*)0;
}

///_____________________________________________________________________________
void AliEveEventBuffer::MonitorBuffer() {
  cout << "Monitorbuffer() ";
  SetBusy(kTRUE);
  FetchEvent();
  SetBusy(kFALSE);
  cout << "done " << endl;
}

///_______________________________________________________________________________
TObject * AliEveEventBuffer::NextEvent() {
  //See header file for documentation
  cout << "NextEvent()"<<endl;
  TObject * nextEvent = GetNextUnSeen();
  return nextEvent;
}

///______________________________________________________________________________
TObject * AliEveEventBuffer::Back() {
  cout << "go back"<<endl;
  PrintIndeces();
  Int_t prevId = CalculatePrevious(fBIndex[kCurrent]);
  if(prevId == fBIndex[kTop]) {
    cout << "returning NULL" << endl;
    return NULL;
  } else {
    fBIndex[kCurrent] = prevId;
    PrintIndeces();
    cout <<"returning: "<< fBIndex[kCurrent] << " " << fEventBuffer->At(fBIndex[kCurrent]);
    return fEventBuffer->At(fBIndex[kCurrent]);
  }
}

///______________________________________________________________________________
TObject * AliEveEventBuffer::Fwd() {
  PrintIndeces();
  if (fBIndex[kCurrent] == fBIndex[kLast]) {
    cout<<  "returning NULL"<<endl;
    return NULL;
  }

  fBIndex[kCurrent] = CalculateNext(fBIndex[kCurrent]);
  TObject * event = fEventBuffer->At(fBIndex[kCurrent]);
  return event;
}

///________________________________________________________________________________
TObject * AliEveEventBuffer::GetNextUnSeen() {
  //See header file for documentation
  cout << "GetNextUnSeen"<<endl;
  PrintIndeces();
  if(CalculateDifference(fBIndex[kTop], fBIndex[kLast])) {
    fBIndex[kLast] = CalculateNext(fBIndex[kLast]);
    fBIndex[kCurrent] = fBIndex[kLast];
    PrintIndeces();
    return fEventBuffer->At(fBIndex[kCurrent]);
  } else {
    cout << "No new event available, only events in buffer available!"<<endl;
    return NULL;
  }
}
///_________________________________________________________________________________
void AliEveEventBuffer::PrintIndeces() {
  for(Int_t i = 0; i < kSize; i++) {
    cout << i << ": " << fBIndex[i] << endl;
  }
}
///_________________________________________________________________________________
void AliEveEventBuffer::PrintBuffer() {
  for(Int_t i = 0; i < 10; i++) {
    AliESDEvent * event = dynamic_cast<AliESDEvent*>(fEventBuffer->At(i));
    if(event) {
      cout << i << ": " <<event << " " << event->GetEventNumberInFile() << endl;;
    }
  }
}

///____________________________________________________________________________________
void AliEveEventBuffer::FetchEvent() {
  cout << "FetchEvent " << endl;
  TObject * event = GetEventFromSource();
  ULong64_t eventId = GetEventIdFromSource();
  if(event) {
    AddToBuffer(event);
    fEventId[fBIndex[kTop]] = eventId;
  }

  PrintIndeces();
  cout << "FetchedEvent " << endl;

}

///_________________________________________________________________________________
void AliEveEventBuffer::AddToBuffer(TObject * event) {
  cout << "Add to buffer"<<endl;
  if(!event) return;

  fBIndex[kTop] = CalculateNext(fBIndex[kTop]);
  //Delete the event already there (ok to delete as object, not aliesdevent, TList?)
  //TObject * object = fEventBuffer->At(fBIndex[kTop]);
  fEventBuffer->RemoveAt(fBIndex[kTop]);
  //if (object) delete object;
  fEventBuffer->AddAt(event, fBIndex[kTop]);

}

///_____________________________________________________________________________________
Int_t AliEveEventBuffer::CalculateNext(Int_t current) {
  //See header file for documentation
  current++;
  if(current == fBufferSize) current = 0;
  return current;
}

///_____________________________________________________________________________________
Int_t AliEveEventBuffer::CalculatePrevious(Int_t current) {
  //See header file for documentation
  cout << "CalculatePrev:  " << current;
  current--;
  if(current == -1) current += fBufferSize;
  cout << "... " << current << endl;
  return current;
}

///__________________________________________________________________________________
Int_t AliEveEventBuffer::CalculateDifference(Int_t top, Int_t low) {
  //See header file for documentation
  if (top > low) {
    //    cout << "top > low"<<endl;
    return (top - low);
  } else if (top < low) {
    // cout << "low < top"<<endl;
    return (fBufferSize - low + top);
  } else {
    //cout << "calculated to 0"<<endl;
    return 0;
  }
}

///___________________________________________________________________________________
void AliEveEventBuffer::StartBufferMonitor() {
  //cout << "NOT !!! starting buffer mon"<<endl;
  cout << "starting buffer mon"<<endl;
  if(!GetBufferMonStarted()) {
    CreateBufferThread();
    SetBufferMonStarted(kTRUE);
    fTimer->Start(3000);
  } else {
    cout << "Stopping buffer monitor"<<endl;
    fTimer->Stop();
    SetBufferMonStarted(kFALSE);
  }
}
///___________________________________________________________________________________
void AliEveEventBuffer::StopBufferMonitor() {
  cout << "Stopping buffer mon"<<endl;
  SetBufferMonStarted(kFALSE);
  fTimer->Stop();
}

// //_________________________________________________________________________________
// Int_t AliEveEventBuffer::NavigateEventBufferBack() {
//   // see header file for class documentation

//   // -- reached the end of the buffer
//   if ( fNavigateBufferIdx == fBufferLowIdx )
//     return -1;

//   Int_t newIdx = fNavigateBufferIdx - 1;
//   if ( newIdx == -1 )
//     newIdx = BUFFERSIZE-1;

//   fCurrentBufferIdx = fNavigateBufferIdx = newIdx;

//   return newIdx;
// }

// //_______________________________________________________________
// Int_t AliEveEventBuffer::NavigateEventBufferFwd() {
//   // see header file for class documentation

//   // -- reached the top of the buffer
//   if ( fNavigateBufferIdx == fBufferTopIdx )
//     return -1;

//   Int_t newIdx = fNavigateBufferIdx + 1;
//   if ( newIdx == BUFFERSIZE )
//     newIdx = 0;

//   fCurrentBufferIdx = fNavigateBufferIdx = newIdx;

//   return newIdx;
// }

// void AliEveEventBuffer::MonitorBuffer() {
//   //See header file for documentation
//   if( GetNAvailableEvents() < 10) {
//     StopBufferChecker();
//     StartLoop();
//   }
// }

// void AliEveEventBuffer::StartLoop() {
//   //See header file for documentation
//   fTimer->Start(2000);
// }
// void AliEveEventBuffer::StopLoop() {
//   //See header file for documentation
//   fTimer->Stop();
// }

// void AliEveEventBuffer::StartBufferChecker() {
//   //See header file for documentation
//   fBufferTimer->Start(2000);
// }
// void AliEveEventBuffer::StopBufferChecker() {
//   //See header file for documentation
//   fBufferTimer->Stop();
// }

// AliESDEvent * GetNextEvent() {

//   tree->GetEntry(fEvent++);

//   AliESDEvent * event = new AliESDEvent();
//   event->ReadFromTree(fTree);
//   if (event) {
//     return event;
//   } else {
//     cout << "error getting event" << endl;
//     return NULL;
//   }
// }
<commit_msg>Fixed busy error<commit_after>#include <iostream>

#include "TObjArray.h"
#include "TTimer.h"
#include "TThread.h"
#include "AliEveEventBuffer.h"

//Not needed, only for debug
#include "AliESDEvent.h"

using namespace std;

ClassImp(AliEveEventBuffer)

///_______________________________________________________________________
AliEveEventBuffer::AliEveEventBuffer() :
  fBufferSize(10),
  fPreBuffer(4),
  fBusy(kFALSE),
  fEventBuffer(NULL),
  fCurrentEvent(NULL),
  fBIndex(),
  fTimer(NULL),
  fEventId(),
  fBufferMonStarted(kFALSE)
 {
  // see header file for class documentation
  fEventBuffer = new TObjArray(fBufferSize, 0);
  fEventBuffer->SetOwner(kFALSE);

  for(int id = 0; id < kSize; id++) {
    fBIndex[id] = -1;
  }

  fTimer = new TTimer();
  fTimer->Connect("Timeout()", "AliEveEventBuffer", this, "CreateBufferThread()");

  fEventId = new ULong64_t[fBufferSize];
  for(Int_t id = 0; id < fBufferSize; id++ ) {
    fEventId[id] = -2;
  }

}

///_______________________________________________________________________
AliEveEventBuffer::~AliEveEventBuffer() {
  // see header file for class documentation

  if ( fEventBuffer ) {
    fEventBuffer->Clear();
    delete fEventBuffer;
  }
  fEventBuffer = NULL;

  if(fCurrentEvent)
    delete fCurrentEvent;
  fCurrentEvent = NULL;

}

///___________________________________________________________________________
void AliEveEventBuffer::CreateBufferThread() {
  if(GetBusy()) {
    cout << "Buffer is busy, no thread created"<< endl;
  } else {
    if ( (CalculateDifference(fBIndex[kTop],fBIndex[kLast]) < fPreBuffer) ) {
      SetBusy(kTRUE);
      cout << "CreateBufferThread()"<<endl;
      TThread * fThread = new TThread(AliEveEventBuffer::BufferThread, (void*) this);
      fThread->Run();
      cout << "Started BufferThread"<<endl;
    } else {
      cout << "Buffer is full already"<<endl;
    }
  }
}
///___________________________________________________________________________
void * AliEveEventBuffer::BufferThread(void * buffer) {
  cout <<"BufferThread : " <<endl;
  if(buffer) {
      reinterpret_cast<AliEveEventBuffer*>(buffer)->MonitorBuffer();
  } else {
    cout << "no buffer"<<endl;
  }
  return (void*)0;
}

///_____________________________________________________________________________
void AliEveEventBuffer::MonitorBuffer() {
  cout << "Monitorbuffer() ";
  SetBusy(kTRUE);
  FetchEvent();
  SetBusy(kFALSE);
  cout << "done " << endl;
}

///_______________________________________________________________________________
TObject * AliEveEventBuffer::NextEvent() {
  //See header file for documentation
  cout << "NextEvent()"<<endl;
  TObject * nextEvent = GetNextUnSeen();
  return nextEvent;
}

///______________________________________________________________________________
TObject * AliEveEventBuffer::Back() {
  cout << "go back"<<endl;
  PrintIndeces();
  Int_t prevId = CalculatePrevious(fBIndex[kCurrent]);
  if(prevId == fBIndex[kTop]) {
    cout << "returning NULL" << endl;
    return NULL;
  } else {
    fBIndex[kCurrent] = prevId;
    PrintIndeces();
    cout <<"returning: "<< fBIndex[kCurrent] << " " << fEventBuffer->At(fBIndex[kCurrent]);
    return fEventBuffer->At(fBIndex[kCurrent]);
  }
}

///______________________________________________________________________________
TObject * AliEveEventBuffer::Fwd() {
  PrintIndeces();
  if (fBIndex[kCurrent] == fBIndex[kLast]) {
    cout<<  "returning NULL"<<endl;
    return NULL;
  }

  fBIndex[kCurrent] = CalculateNext(fBIndex[kCurrent]);
  TObject * event = fEventBuffer->At(fBIndex[kCurrent]);
  return event;
}

///________________________________________________________________________________
TObject * AliEveEventBuffer::GetNextUnSeen() {
  //See header file for documentation
  cout << "GetNextUnSeen"<<endl;
  PrintIndeces();
  if(CalculateDifference(fBIndex[kTop], fBIndex[kLast])) {
    fBIndex[kLast] = CalculateNext(fBIndex[kLast]);
    fBIndex[kCurrent] = fBIndex[kLast];
    PrintIndeces();
    return fEventBuffer->At(fBIndex[kCurrent]);
  } else {
    cout << "No new event available, only events in buffer available!"<<endl;
    return NULL;
  }
}
///_________________________________________________________________________________
void AliEveEventBuffer::PrintIndeces() {
  for(Int_t i = 0; i < kSize; i++) {
    cout << i << ": " << fBIndex[i] << endl;
  }
}
///_________________________________________________________________________________
void AliEveEventBuffer::PrintBuffer() {
  for(Int_t i = 0; i < 10; i++) {
    AliESDEvent * event = dynamic_cast<AliESDEvent*>(fEventBuffer->At(i));
    if(event) {
      cout << i << ": " <<event << " " << event->GetEventNumberInFile() << endl;;
    }
  }
}

///____________________________________________________________________________________
void AliEveEventBuffer::FetchEvent() {
  cout << "FetchEvent " << endl;
  TObject * event = GetEventFromSource();
  ULong64_t eventId = GetEventIdFromSource();
  if(event) {
    AddToBuffer(event);
    fEventId[fBIndex[kTop]] = eventId;
  }

  PrintIndeces();
  cout << "FetchedEvent " << endl;

}

///_________________________________________________________________________________
void AliEveEventBuffer::AddToBuffer(TObject * event) {
  cout << "Add to buffer"<<endl;
  if(!event) return;

  fBIndex[kTop] = CalculateNext(fBIndex[kTop]);
  //Delete the event already there (ok to delete as object, not aliesdevent, TList?)
  //TObject * object = fEventBuffer->At(fBIndex[kTop]);
  fEventBuffer->RemoveAt(fBIndex[kTop]);
  //if (object) delete object;
  fEventBuffer->AddAt(event, fBIndex[kTop]);

}

///_____________________________________________________________________________________
Int_t AliEveEventBuffer::CalculateNext(Int_t current) {
  //See header file for documentation
  current++;
  if(current == fBufferSize) current = 0;
  return current;
}

///_____________________________________________________________________________________
Int_t AliEveEventBuffer::CalculatePrevious(Int_t current) {
  //See header file for documentation
  cout << "CalculatePrev:  " << current;
  current--;
  if(current == -1) current += fBufferSize;
  cout << "... " << current << endl;
  return current;
}

///__________________________________________________________________________________
Int_t AliEveEventBuffer::CalculateDifference(Int_t top, Int_t low) {
  //See header file for documentation
  if (top > low) {
    //    cout << "top > low"<<endl;
    return (top - low);
  } else if (top < low) {
    // cout << "low < top"<<endl;
    return (fBufferSize - low + top);
  } else {
    //cout << "calculated to 0"<<endl;
    return 0;
  }
}

///___________________________________________________________________________________
void AliEveEventBuffer::StartBufferMonitor() {
  //cout << "NOT !!! starting buffer mon"<<endl;
  cout << "starting buffer mon"<<endl;
  if(!GetBufferMonStarted()) {
    CreateBufferThread();
    SetBufferMonStarted(kTRUE);
    fTimer->Start(3000);
  } else {
    cout << "Stopping buffer monitor"<<endl;
    fTimer->Stop();
    SetBufferMonStarted(kFALSE);
  }
}
///___________________________________________________________________________________
void AliEveEventBuffer::StopBufferMonitor() {
  cout << "Stopping buffer mon"<<endl;
  SetBufferMonStarted(kFALSE);
  fTimer->Stop();
}

// //_________________________________________________________________________________
// Int_t AliEveEventBuffer::NavigateEventBufferBack() {
//   // see header file for class documentation

//   // -- reached the end of the buffer
//   if ( fNavigateBufferIdx == fBufferLowIdx )
//     return -1;

//   Int_t newIdx = fNavigateBufferIdx - 1;
//   if ( newIdx == -1 )
//     newIdx = BUFFERSIZE-1;

//   fCurrentBufferIdx = fNavigateBufferIdx = newIdx;

//   return newIdx;
// }

// //_______________________________________________________________
// Int_t AliEveEventBuffer::NavigateEventBufferFwd() {
//   // see header file for class documentation

//   // -- reached the top of the buffer
//   if ( fNavigateBufferIdx == fBufferTopIdx )
//     return -1;

//   Int_t newIdx = fNavigateBufferIdx + 1;
//   if ( newIdx == BUFFERSIZE )
//     newIdx = 0;

//   fCurrentBufferIdx = fNavigateBufferIdx = newIdx;

//   return newIdx;
// }

// void AliEveEventBuffer::MonitorBuffer() {
//   //See header file for documentation
//   if( GetNAvailableEvents() < 10) {
//     StopBufferChecker();
//     StartLoop();
//   }
// }

// void AliEveEventBuffer::StartLoop() {
//   //See header file for documentation
//   fTimer->Start(2000);
// }
// void AliEveEventBuffer::StopLoop() {
//   //See header file for documentation
//   fTimer->Stop();
// }

// void AliEveEventBuffer::StartBufferChecker() {
//   //See header file for documentation
//   fBufferTimer->Start(2000);
// }
// void AliEveEventBuffer::StopBufferChecker() {
//   //See header file for documentation
//   fBufferTimer->Stop();
// }

// AliESDEvent * GetNextEvent() {

//   tree->GetEntry(fEvent++);

//   AliESDEvent * event = new AliESDEvent();
//   event->ReadFromTree(fTree);
//   if (event) {
//     return event;
//   } else {
//     cout << "error getting event" << endl;
//     return NULL;
//   }
// }
<|endoftext|>


<commit_before><commit_msg>Fixing SPXRatio::Parse: data_stat and data_tot<commit_after><|endoftext|>


<commit_before>#ifndef CV_ADAPTERS_ROWRANGE_HPP
#define	CV_ADAPTERS_ROWRANGE_HPP

#include <iterator>
#include <opencv2/core/core.hpp>

template <typename T>
class RowRangeConstIterator : public std::iterator<std::forward_iterator_tag, T>
    {
    public:
        RowRangeConstIterator()
        : data()
        , row()
        , position()
        {}

        RowRangeConstIterator(const cv::Mat_<T>& m, int index)
        : data(m)
        , position(index)
        {
            CV_DbgAssert(position >= 0 && position <= data.rows + 1);
            if (index != data.rows + 1) {
                row = m.row(index);
            }
        }

        // Dereference
        const cv::Mat_<T>& operator*() const
        {
            return row;
        }

        const cv::Mat_<T>* operator->() const
        {
            return &row;
        }

        // Logical comparison
        bool operator==(const RowRangeConstIterator& that) const
        {
            return this->position == that.position;
        }

        bool operator!=(const RowRangeConstIterator& that) const
        {
            return !(*this == that);
        }

        bool operator<(const RowRangeConstIterator& that) const
        {
            return this->position < that.position;
        }

        bool operator>(const RowRangeConstIterator& that) const
        {
            return this->position > that.position;
        }

        bool operator<=(const RowRangeConstIterator& that) const
        {
            return !(*this > that);
        }

        bool operator>=(const RowRangeConstIterator& that) const
        {
            return !(*this < that);
        }

        // Increment
        RowRangeConstIterator& operator++()
        {
            ++position;
            return *this;
        }

        RowRangeConstIterator operator++(int) const
        {
            RowRangeConstIterator tmp(*this);
            ++(*this);
            return tmp;
        }

    protected:
        cv::Mat_<T> data;
        mutable cv::Mat_<T> row;
        int position;
    };

template <typename T>
class RowRangeIterator : public RowRangeConstIterator<T>
{
public:
    RowRangeIterator()
    : RowRangeConstIterator<T>()
    {}

    RowRangeIterator(const cv::Mat_<T>& m, int index)
    : RowRangeConstIterator<T>(m, index)
    {}

    // Dereference
    cv::Mat_<T>& operator*() const
    {
        return RowRangeConstIterator<T>::row;
    }

    cv::Mat_<T>* operator->() const
    {
        return &RowRangeConstIterator<T>::row;
    }
};

template <typename T>
class RowRange
{
public:
    typedef RowRangeConstIterator<T> const_iterator;
    typedef RowRangeIterator<T> iterator;
    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
    typedef std::reverse_iterator<iterator> reverse_iterator;

    RowRange(cv::Mat m)
    : data(m)
    {
        CV_Assert(m.type() == cv::DataType<T>::type);
    }

    RowRange(cv::Mat_<T> m)
    : data(m) {}

    const_iterator begin() const
    {
        return const_iterator(data, 0);
    }

    iterator begin()
    {
        return iterator(data, 0);
    }

    const_iterator end() const
    {
        return const_iterator(data, data.rows + 1);
    }

    iterator end()
    {
        return iterator(data, data.rows + 1);
    }

    const_iterator cbegin() const
    {
        return begin();
    }

    const_iterator cend() const
    {
        return end();
    }

private:
    cv::Mat_<T> data;
};

template <typename T>
RowRange<T> make_RowRange(cv::Mat_<T> m)
{
    return RowRange<T>(m);
}

#endif	/* CV_ADAPTERS_ROWRANGE_HPP */

<commit_msg>Fixing off-by-one error in iterator bounds.<commit_after>#ifndef CV_ADAPTERS_ROWRANGE_HPP
#define	CV_ADAPTERS_ROWRANGE_HPP

#include <iterator>
#include <opencv2/core/core.hpp>

namespace cv
{

template <typename T>
class RowRangeConstIterator : public std::iterator<std::forward_iterator_tag, T>
    {
    public:
        RowRangeConstIterator()
        : data()
        , row()
        , position()
        {}

        RowRangeConstIterator(const cv::Mat_<T>& m, int index)
        : data(m)
        , row()
        , position(index)
        {
            CV_DbgAssert(position >= 0 && position <= data.rows);
        }

        // Dereference
        const cv::Mat_<T>& operator*() const
        {
            setRow();
            return row;
        }

        const cv::Mat_<T>* operator->() const
        {
            setRow();
            return &row;
        }

        // Logical comparison
        bool operator==(const RowRangeConstIterator& that) const
        {
            return this->position == that.position;
        }

        bool operator!=(const RowRangeConstIterator& that) const
        {
            return !(*this == that);
        }

        bool operator<(const RowRangeConstIterator& that) const
        {
            return this->position < that.position;
        }

        bool operator>(const RowRangeConstIterator& that) const
        {
            return this->position > that.position;
        }

        bool operator<=(const RowRangeConstIterator& that) const
        {
            return !(*this > that);
        }

        bool operator>=(const RowRangeConstIterator& that) const
        {
            return !(*this < that);
        }

        // Increment
        RowRangeConstIterator& operator++()
        {
            ++position;
            return *this;
        }

        RowRangeConstIterator operator++(int) const
        {
            RowRangeConstIterator tmp(*this);
            ++(*this);
            return tmp;
        }

    protected:
        void setRow() const
        {
            row = data.row(position);
        }

        cv::Mat_<T> data;
        mutable cv::Mat_<T> row;
        int position;
    };

template <typename T>
class RowRangeIterator : public RowRangeConstIterator<T>
{
public:
    RowRangeIterator()
    : RowRangeConstIterator<T>()
    {}

    RowRangeIterator(const cv::Mat_<T>& m, int index)
    : RowRangeConstIterator<T>(m, index)
    {}

    // Dereference
    cv::Mat_<T>& operator*() const
    {
        this->setRow();
        return this->row;
    }

    cv::Mat_<T>* operator->() const
    {
        this->setRow();
        return &this->row;
    }
};

template <typename T>
class RowRange
{
public:
    typedef RowRangeConstIterator<T> const_iterator;
    typedef RowRangeIterator<T> iterator;

    RowRange(cv::Mat m)
    : data(m)
    {
        CV_Assert(m.type() == cv::DataType<T>::type);
    }

    RowRange(cv::Mat_<T> m)
    : data(m) {}

    const_iterator begin() const
    {
        return const_iterator(data, 0);
    }

    iterator begin()
    {
        return iterator(data, 0);
    }

    const_iterator end() const
    {
        return const_iterator(data, data.rows);
    }

    iterator end()
    {
        return iterator(data, data.rows);
    }

    const_iterator cbegin() const
    {
        return begin();
    }

    const_iterator cend() const
    {
        return end();
    }

private:
    cv::Mat_<T> data;
};

template <typename T>
RowRange<T> make_RowRange(cv::Mat_<T> m)
{
    return RowRange<T>(m);
}

} // namespace cv

#endif	/* CV_ADAPTERS_ROWRANGE_HPP */

<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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 <curl/curl.h>
#include <map>
#include <zorba/zorba.h>
#include <zorba/serializer.h>
#include <zorba/external_module.h>
#include <zorba/function.h>
#include <zorba/empty_sequence.h>
#include <zorba/user_exception.h>

#include "http_request_handler.h"
#include "request_parser.h"
#include "http_response_handler.h"
#include "http_response_parser.h"

#ifdef WIN32
# include <Windows.h>
# define MAX_BUF_SIZE 2048
#endif

namespace zorba {

  namespace http_client {
#ifdef WIN32
		static void set_cacert(CURL* lCurl, std::string aPath) {
			TCHAR path[MAX_BUF_SIZE];
			int r = GetModuleFileName(NULL, path, 2048);
			if (r == -1)
				return;
#	ifdef UNICODE
			char buf[MAX_BUF_SIZE];
			memset(buf, 0, MAX_BUF_SIZE);
			for (int i = 0; i <= r; ++i) {
				buf[i] = (char) path[i];
			}
			std::string lPath(buf);
#	else
			std::string lPath(path);
#	endif
			aPath = lPath.substr(0, lPath.rfind('\\'));
			aPath += "\\cacert.pem";
      if(GetFileAttributesA(aPath.c_str()) != INVALID_FILE_ATTRIBUTES)
			  curl_easy_setopt(lCurl, CURLOPT_CAINFO, aPath.c_str());
      else
        curl_easy_setopt(lCurl, CURLOPT_SSL_VERIFYPEER, 0L);
		}
#endif //WIN32

    class HttpSendFunction : public ContextualExternalFunction {
    protected:
      const ExternalModule*     theModule;
      ItemFactory*              theFactory;

    public:
      HttpSendFunction(const ExternalModule* aModule)
      : theModule(aModule),
      theFactory(Zorba::getInstance(0)->getItemFactory()) {}

      virtual ~HttpSendFunction() {}

    public:
      virtual String
      getURI() const { return theModule->getURI(); }

      virtual String
      getLocalName() const { return "http-sequential-impl"; }

      virtual ItemSequence_t
      evaluate(const ExternalFunction::Arguments_t& args,
               const StaticContext* aStaticContext, const DynamicContext* aDynamicContext)
      const;
    };

    class HttpReadFunction : public HttpSendFunction {
    public:
      HttpReadFunction(const ExternalModule* aModule)
      : HttpSendFunction(aModule) {}

      virtual ~HttpReadFunction() {}

    public:
      virtual String
      getLocalName() const { return "http-nondeterministic-impl"; }

    };

    class HttpClientModule : public ExternalModule {
    protected:
      class ltstr
      {
      public:
        bool operator()(const String& s1, const String& s2) const
        {
          return s1.compare(s2) < 0;
        }
      };

      typedef std::map<String, ExternalFunction*, ltstr> FuncMap_t;

      FuncMap_t theFunctions;

    public:
      virtual ~HttpClientModule();

      HttpClientModule() : theModuleUri("http://www.zorba-xquery.com/modules/http-client")
      {
        for (FuncMap_t::const_iterator lIter = theFunctions.begin();
             lIter != theFunctions.end(); ++lIter) {
          delete lIter->second;
        }
        theFunctions.clear();
      }

      virtual String
      getURI() const { return theModuleUri; }

      virtual ExternalFunction*
      getExternalFunction(const String& aLocalname)
      {
        ExternalFunction*& lFunc = theFunctions[aLocalname];
        if (!lFunc) {
          if (aLocalname == "http-sequential-impl") {
            lFunc = new HttpSendFunction(this);
          } else if (aLocalname == "http-nondeterministic-impl") {
            lFunc = new HttpReadFunction(this);
          }
        }
        return lFunc;
      }

      virtual void
      destroy()
      {
        if (!dynamic_cast<HttpClientModule*>(this)) {
          return;
        }
        delete this;
      }

    private:
      String theModuleUri;
    };

    ItemSequence_t
    general_evaluate(
        const ExternalFunction::Arguments_t& args,
        const StaticContext* aStaticContext,
        const DynamicContext* aDynamicContext,
        ItemFactory* aFactory)
    {
      CURL* lCURL = curl_easy_init();

      Item lRequest;
      Item lHref;
      Item lContent;

      Iterator_t arg0_iter = args[0]->getIterator();
      arg0_iter->open();
      bool lReqSet = arg0_iter->next(lRequest);
      arg0_iter->close();
      Iterator_t arg1_iter = args[1]->getIterator();
      arg1_iter->open();
      bool lHrefSet = arg1_iter->next(lHref);
      arg1_iter->close();

      std::string lData;

      std::auto_ptr<HttpRequestHandler> lHandler;
      std::auto_ptr<RequestParser> lParser;
      struct curl_slist* lHeaderList = 0;

      ErrorThrower thrower(aFactory, &lHeaderList);

      if (lReqSet) {
        lHandler.reset(new HttpRequestHandler(lCURL, args[2]));
        lParser.reset(new RequestParser(lHandler.get()));
        lParser->parse(lRequest);
      }
      if (lHrefSet) {
        curl_easy_setopt(lCURL, CURLOPT_URL, lHref.getStringValue().c_str());
      }
      curl_easy_setopt(lCURL, CURLOPT_USERAGENT, "libcurl-agent/1.0");
      //curl_easy_setopt(lCURL, CURLOPT_PROXY, "localhost:8888");
#ifdef WIN32
      std::string caCertPath;
      set_cacert(lCURL, caCertPath);
#endif
      HttpResponseHandler lRespHandler(aFactory, lHeaderList);
      String lOverrideContentType;
      if (lHandler.get())
        lHandler->getOverrideContentType(lOverrideContentType);
      bool lStatusOnly =
          lHandler.get() == NULL ? false : (lHandler->isStatusOnly() || lHandler->isHeadRequest());
      // This gives the ownership of lCurl to the HttpResponseParser
      std::auto_ptr<HttpResponseParser> lRespParser(new HttpResponseParser(lRespHandler, lCURL, thrower,
        lOverrideContentType.c_str(), lStatusOnly));
      int lRetCode = lRespParser->parse();

       if (lRetCode) {
        thrower.raiseException("http://expath.org/ns/error", "HC001", "An HTTP error occurred");
      }

      // If the Parser is "self contained", that means it didn't create any
      // objects with a lifecycle longer than itself; therefore we should free
      // it (by letting auto_ptr delete it). If the Parser is not self contained,
      // then it will have arranged for some other memory manager to free it
      // later when appropriate; therefore we should NOT let auto_ptr delete it
      // now.
      if ( ! lRespParser->selfContained()) {
        lRespParser.release();
      }
      return ItemSequence_t(lRespHandler.releaseResult());
    }

    ItemSequence_t
    HttpSendFunction::evaluate(const ExternalFunction::Arguments_t& args,
      const StaticContext* aStaticContext, const DynamicContext* aDynamicContext) const
    {
      return general_evaluate(args, aStaticContext, aDynamicContext, theFactory);
    }

    HttpClientModule::~HttpClientModule()
    {
      for (FuncMap_t::const_iterator lIter = theFunctions.begin();
           lIter != theFunctions.end(); ++lIter) {
        delete lIter->second;
      }
      theFunctions.clear();
    }
  } // namespace http_request
} // namespace zorba

#ifdef WIN32
#  define DLL_EXPORT __declspec(dllexport)
#else
#  define DLL_EXPORT __attribute__ ((visibility("default")))
#endif

extern "C" DLL_EXPORT zorba::ExternalModule* createModule() {
  return new zorba::http_client::HttpClientModule();
}

<commit_msg>Reverted change to http_client<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * 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 <curl/curl.h>
#include <map>
#include <zorba/zorba.h>
#include <zorba/serializer.h>
#include <zorba/external_module.h>
#include <zorba/function.h>
#include <zorba/empty_sequence.h>
#include <zorba/user_exception.h>

#include "http_request_handler.h"
#include "request_parser.h"
#include "http_response_handler.h"
#include "http_response_parser.h"

#ifdef WIN32
# include <Windows.h>
# define MAX_BUF_SIZE 2048
#endif

namespace zorba {

  namespace http_client {
#ifdef WIN32
		static void set_cacert(CURL* lCurl, std::string aPath) {
			TCHAR path[MAX_BUF_SIZE];
			int r = GetModuleFileName(NULL, path, 2048);
			if (r == -1)
				return;
#	ifdef UNICODE
			char buf[MAX_BUF_SIZE];
			memset(buf, 0, MAX_BUF_SIZE);
			for (int i = 0; i <= r; ++i) {
				buf[i] = (char) path[i];
			}
			std::string lPath(buf);
#	else
			std::string lPath(path);
#	endif
			aPath = lPath.substr(0, lPath.rfind('\\'));
			aPath += "\\cacert.pem";
			curl_easy_setopt(lCurl, CURLOPT_CAINFO, aPath.c_str());
		}
#endif //WIN32

    class HttpSendFunction : public ContextualExternalFunction {
    protected:
      const ExternalModule*     theModule;
      ItemFactory*              theFactory;

    public:
      HttpSendFunction(const ExternalModule* aModule)
      : theModule(aModule),
      theFactory(Zorba::getInstance(0)->getItemFactory()) {}

      virtual ~HttpSendFunction() {}

    public:
      virtual String
      getURI() const { return theModule->getURI(); }

      virtual String
      getLocalName() const { return "http-sequential-impl"; }

      virtual ItemSequence_t
      evaluate(const ExternalFunction::Arguments_t& args,
               const StaticContext* aStaticContext, const DynamicContext* aDynamicContext)
      const;
    };

    class HttpReadFunction : public HttpSendFunction {
    public:
      HttpReadFunction(const ExternalModule* aModule)
      : HttpSendFunction(aModule) {}

      virtual ~HttpReadFunction() {}

    public:
      virtual String
      getLocalName() const { return "http-nondeterministic-impl"; }

    };

    class HttpClientModule : public ExternalModule {
    protected:
      class ltstr
      {
      public:
        bool operator()(const String& s1, const String& s2) const
        {
          return s1.compare(s2) < 0;
        }
      };

      typedef std::map<String, ExternalFunction*, ltstr> FuncMap_t;

      FuncMap_t theFunctions;

    public:
      virtual ~HttpClientModule();

      HttpClientModule() : theModuleUri("http://www.zorba-xquery.com/modules/http-client")
      {
        for (FuncMap_t::const_iterator lIter = theFunctions.begin();
             lIter != theFunctions.end(); ++lIter) {
          delete lIter->second;
        }
        theFunctions.clear();
      }

      virtual String
      getURI() const { return theModuleUri; }

      virtual ExternalFunction*
      getExternalFunction(const String& aLocalname)
      {
        ExternalFunction*& lFunc = theFunctions[aLocalname];
        if (!lFunc) {
          if (aLocalname == "http-sequential-impl") {
            lFunc = new HttpSendFunction(this);
          } else if (aLocalname == "http-nondeterministic-impl") {
            lFunc = new HttpReadFunction(this);
          }
        }
        return lFunc;
      }

      virtual void
      destroy()
      {
        if (!dynamic_cast<HttpClientModule*>(this)) {
          return;
        }
        delete this;
      }

    private:
      String theModuleUri;
    };

    ItemSequence_t
    general_evaluate(
        const ExternalFunction::Arguments_t& args,
        const StaticContext* aStaticContext,
        const DynamicContext* aDynamicContext,
        ItemFactory* aFactory)
    {
      CURL* lCURL = curl_easy_init();

      Item lRequest;
      Item lHref;
      Item lContent;

      Iterator_t arg0_iter = args[0]->getIterator();
      arg0_iter->open();
      bool lReqSet = arg0_iter->next(lRequest);
      arg0_iter->close();
      Iterator_t arg1_iter = args[1]->getIterator();
      arg1_iter->open();
      bool lHrefSet = arg1_iter->next(lHref);
      arg1_iter->close();

      std::string lData;

      std::auto_ptr<HttpRequestHandler> lHandler;
      std::auto_ptr<RequestParser> lParser;
      struct curl_slist* lHeaderList = 0;

      ErrorThrower thrower(aFactory, &lHeaderList);

      if (lReqSet) {
        lHandler.reset(new HttpRequestHandler(lCURL, args[2]));
        lParser.reset(new RequestParser(lHandler.get()));
        lParser->parse(lRequest);
      }
      if (lHrefSet) {
        curl_easy_setopt(lCURL, CURLOPT_URL, lHref.getStringValue().c_str());
      }
      curl_easy_setopt(lCURL, CURLOPT_USERAGENT, "libcurl-agent/1.0");
      //curl_easy_setopt(lCURL, CURLOPT_PROXY, "localhost:8888");
#ifdef WIN32
      std::string caCertPath;
      set_cacert(lCURL, caCertPath);
#endif
      HttpResponseHandler lRespHandler(aFactory, lHeaderList);
      String lOverrideContentType;
      if (lHandler.get())
        lHandler->getOverrideContentType(lOverrideContentType);
      bool lStatusOnly =
          lHandler.get() == NULL ? false : (lHandler->isStatusOnly() || lHandler->isHeadRequest());
      // This gives the ownership of lCurl to the HttpResponseParser
      std::auto_ptr<HttpResponseParser> lRespParser(new HttpResponseParser(lRespHandler, lCURL, thrower,
        lOverrideContentType.c_str(), lStatusOnly));
      int lRetCode = lRespParser->parse();

      if (lRetCode) {
        thrower.raiseException("http://expath.org/ns/error", "HC001", "An HTTP error occurred");
      }

      // If the Parser is "self contained", that means it didn't create any
      // objects with a lifecycle longer than itself; therefore we should free
      // it (by letting auto_ptr delete it). If the Parser is not self contained,
      // then it will have arranged for some other memory manager to free it
      // later when appropriate; therefore we should NOT let auto_ptr delete it
      // now.
      if ( ! lRespParser->selfContained()) {
        lRespParser.release();
      }
      return ItemSequence_t(lRespHandler.releaseResult());
    }

    ItemSequence_t
    HttpSendFunction::evaluate(const ExternalFunction::Arguments_t& args,
      const StaticContext* aStaticContext, const DynamicContext* aDynamicContext) const
    {
      return general_evaluate(args, aStaticContext, aDynamicContext, theFactory);
    }

    HttpClientModule::~HttpClientModule()
    {
      for (FuncMap_t::const_iterator lIter = theFunctions.begin();
           lIter != theFunctions.end(); ++lIter) {
        delete lIter->second;
      }
      theFunctions.clear();
    }
  } // namespace http_request
} // namespace zorba

#ifdef WIN32
#  define DLL_EXPORT __declspec(dllexport)
#else
#  define DLL_EXPORT __attribute__ ((visibility("default")))
#endif

extern "C" DLL_EXPORT zorba::ExternalModule* createModule() {
  return new zorba::http_client::HttpClientModule();
}

<|endoftext|>