<commit_before>/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * ClockTest.cpp
 * Unittest for String functions.
 * Copyright (C) 2005-2010 Simon Newton
 */

#include <cppunit/extensions/HelperMacros.h>
#include <string>
#include "ola/Clock.h"

class ClockTest: public CppUnit::TestFixture {
  CPPUNIT_TEST_SUITE(ClockTest);
  CPPUNIT_TEST(testTimeStamp);
  CPPUNIT_TEST_SUITE_END();

  public:
    void testTimeStamp();
};

CPPUNIT_TEST_SUITE_REGISTRATION(ClockTest);

using ola::Clock;
using ola::TimeStamp;
using ola::TimeInterval;
using std::string;

/*
 * Test the TimeStamp class
 */
void ClockTest::testTimeStamp() {
  TimeStamp timestamp, timestamp2;
  CPPUNIT_ASSERT(!timestamp.IsSet());
  CPPUNIT_ASSERT(!timestamp2.IsSet());

  // test assignment & copy constructor
  Clock::CurrentTime(timestamp);
  CPPUNIT_ASSERT(timestamp.IsSet());
  timestamp2 = timestamp;
  CPPUNIT_ASSERT(timestamp2.IsSet());
  TimeStamp timestamp3(timestamp);
  CPPUNIT_ASSERT(timestamp3.IsSet());
  CPPUNIT_ASSERT_EQUAL(timestamp, timestamp2);
  CPPUNIT_ASSERT_EQUAL(timestamp, timestamp3);

  // test equalities
  Clock::CurrentTime(timestamp3);
  CPPUNIT_ASSERT(timestamp3 != timestamp);
  CPPUNIT_ASSERT(timestamp3 > timestamp);
  CPPUNIT_ASSERT(timestamp < timestamp3);

  // test intervals
  TimeInterval interval = timestamp3 - timestamp;
  TimeInterval interval2 = interval;
  TimeInterval interval3(interval);
  CPPUNIT_ASSERT_EQUAL(interval, interval2);
  CPPUNIT_ASSERT_EQUAL(interval, interval3);

  // test subtraction / addition
  timestamp2 = timestamp + interval;
  CPPUNIT_ASSERT_EQUAL(timestamp2, timestamp3);
  timestamp2 -= interval;
  CPPUNIT_ASSERT_EQUAL(timestamp, timestamp2);

  // test toString and AsInt
  TimeInterval one_point_five_seconds(1500);
  CPPUNIT_ASSERT_EQUAL(string("1.500000"), one_point_five_seconds.ToString());
  CPPUNIT_ASSERT_EQUAL(static_cast<int64_t>(1500000),
                       one_point_five_seconds.AsInt());
}
<commit_msg>Make the clock tests pass on windows<commit_after>/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * ClockTest.cpp
 * Unittest for String functions.
 * Copyright (C) 2005-2010 Simon Newton
 */

#include <cppunit/extensions/HelperMacros.h>
#include <unistd.h>
#include <string>
#include "ola/Clock.h"

class ClockTest: public CppUnit::TestFixture {
  CPPUNIT_TEST_SUITE(ClockTest);
  CPPUNIT_TEST(testTimeStamp);
  CPPUNIT_TEST_SUITE_END();

  public:
    void testTimeStamp();
};

CPPUNIT_TEST_SUITE_REGISTRATION(ClockTest);

using ola::Clock;
using ola::TimeStamp;
using ola::TimeInterval;
using std::string;

/*
 * Test the TimeStamp class
 */
void ClockTest::testTimeStamp() {
  TimeStamp timestamp, timestamp2;
  CPPUNIT_ASSERT(!timestamp.IsSet());
  CPPUNIT_ASSERT(!timestamp2.IsSet());

  // test assignment & copy constructor
  Clock::CurrentTime(timestamp);
  CPPUNIT_ASSERT(timestamp.IsSet());
  timestamp2 = timestamp;
  CPPUNIT_ASSERT(timestamp2.IsSet());
  TimeStamp timestamp3(timestamp);
  CPPUNIT_ASSERT(timestamp3.IsSet());
  CPPUNIT_ASSERT_EQUAL(timestamp, timestamp2);
  CPPUNIT_ASSERT_EQUAL(timestamp, timestamp3);

  // test equalities
  // Windows only seems to have ms resolution, to make the tests pass we need
  // to sleep here
  usleep(1000);
  Clock::CurrentTime(timestamp3);
  CPPUNIT_ASSERT(timestamp3 != timestamp);
  CPPUNIT_ASSERT(timestamp3 > timestamp);
  CPPUNIT_ASSERT(timestamp < timestamp3);

  // test intervals
  TimeInterval interval = timestamp3 - timestamp;
  TimeInterval interval2 = interval;
  TimeInterval interval3(interval);
  CPPUNIT_ASSERT_EQUAL(interval, interval2);
  CPPUNIT_ASSERT_EQUAL(interval, interval3);

  // test subtraction / addition
  timestamp2 = timestamp + interval;
  CPPUNIT_ASSERT_EQUAL(timestamp2, timestamp3);
  timestamp2 -= interval;
  CPPUNIT_ASSERT_EQUAL(timestamp, timestamp2);

  // test toString and AsInt
  TimeInterval one_point_five_seconds(1500);
  CPPUNIT_ASSERT_EQUAL(string("1.500000"), one_point_five_seconds.ToString());
  CPPUNIT_ASSERT_EQUAL(static_cast<int64_t>(1500000),
                       one_point_five_seconds.AsInt());
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */

#include <com/sun/star/awt/WindowEvent.hpp>
#include <comphelper/processfactory.hxx>

#include <toolkit/helper/unowrapper.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/convert.hxx>
#include <toolkit/awt/vclxwindow.hxx>
#include <toolkit/awt/vclxwindows.hxx>
#include <toolkit/awt/vclxcontainer.hxx>
#include <toolkit/awt/vclxtopwindow.hxx>
#include <toolkit/awt/vclxgraphics.hxx>

#include "toolkit/dllapi.h"
#include <vcl/svapp.hxx>
#include <vcl/syswin.hxx>
#include <vcl/menu.hxx>

#include <tools/debug.hxx>

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

::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > CreateXWindow( Window* pWindow )
{
    switch ( pWindow->GetType() )
    {
        case WINDOW_IMAGEBUTTON:
        case WINDOW_SPINBUTTON:
        case WINDOW_MENUBUTTON:
        case WINDOW_MOREBUTTON:
        case WINDOW_PUSHBUTTON:
        case WINDOW_HELPBUTTON:
        case WINDOW_OKBUTTON:
        case WINDOW_CANCELBUTTON:   return new VCLXButton;
        case WINDOW_CHECKBOX:       return new VCLXCheckBox;
        // #i95042#
        // A Window of type <MetricBox> is inherited from type <ComboBox>.
        // Thus, it does make more sense to return a <VCLXComboBox> instance
        // instead of only a <VCLXWindow> instance, especially regarding its
        // corresponding accessibility API.
        case WINDOW_METRICBOX:
        case WINDOW_COMBOBOX:       return new VCLXComboBox;
        case WINDOW_SPINFIELD:
        case WINDOW_NUMERICFIELD:
        case WINDOW_CURRENCYFIELD:  return new VCLXNumericField;
        case WINDOW_DATEFIELD:      return new VCLXDateField;
        case WINDOW_MULTILINEEDIT:
        case WINDOW_EDIT:           return new VCLXEdit;
        case WINDOW_METRICFIELD:    return new VCLXSpinField;
        case WINDOW_MESSBOX:
        case WINDOW_INFOBOX:
        case WINDOW_WARNINGBOX:
        case WINDOW_QUERYBOX:
        case WINDOW_ERRORBOX:       return new VCLXMessageBox;
        case WINDOW_FIXEDIMAGE:     return new VCLXImageControl;
        case WINDOW_FIXEDTEXT:      return new VCLXFixedText;
        case WINDOW_MULTILISTBOX:
        case WINDOW_LISTBOX:        return new VCLXListBox;
        case WINDOW_LONGCURRENCYFIELD:  return new VCLXCurrencyField;
        case WINDOW_DIALOG:
        case WINDOW_MODALDIALOG:
        case WINDOW_TABDIALOG:
        case WINDOW_BUTTONDIALOG:
        case WINDOW_MODELESSDIALOG: return new VCLXDialog;
        case WINDOW_PATTERNFIELD:   return new VCLXPatternField;
        case WINDOW_RADIOBUTTON:    return new VCLXRadioButton;
        case WINDOW_SCROLLBAR:      return new VCLXScrollBar;
        case WINDOW_TIMEFIELD:      return new VCLXTimeField;

        case WINDOW_SYSWINDOW:
        case WINDOW_WORKWINDOW:
        case WINDOW_DOCKINGWINDOW:
        case WINDOW_FLOATINGWINDOW:
        case WINDOW_HELPTEXTWINDOW: return new VCLXTopWindow;

        case WINDOW_WINDOW:
        case WINDOW_TABPAGE:        return new VCLXContainer;

        case WINDOW_TOOLBOX:        return new VCLXToolBox;
        case WINDOW_TABCONTROL:     return new VCLXMultiPage;

        // case WINDOW_FIXEDLINE:
        // case WINDOW_FIXEDBITMAP:
        // case WINDOW_DATEBOX:
        // case WINDOW_GROUPBOX:
        // case WINDOW_LONGCURRENCYBOX:
        // case WINDOW_SPLITTER:
        // case WINDOW_STATUSBAR:
        // case WINDOW_TABCONTROL:
        // case WINDOW_NUMERICBOX:
        // case WINDOW_TRISTATEBOX:
        // case WINDOW_TIMEBOX:
        // case WINDOW_SPLITWINDOW:
        // case WINDOW_SCROLLBARBOX:
        // case WINDOW_PATTERNBOX:
        // case WINDOW_CURRENCYBOX:
        default:                    return new VCLXWindow( true );
    }
}

//  ----------------------------------------------------
//  class UnoWrapper
//  ----------------------------------------------------

extern "C" {

TOOLKIT_DLLPUBLIC UnoWrapperBase* CreateUnoWrapper()
{
    return new UnoWrapper( NULL );
}

}   // extern "C"

UnoWrapper::UnoWrapper( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit>& rxToolkit )
{
    mxToolkit = rxToolkit;
}

void UnoWrapper::Destroy()
{
    delete this;
}

UnoWrapper::~UnoWrapper()
{
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit> UnoWrapper::GetVCLToolkit()
{
    if ( !mxToolkit.is() )
        mxToolkit = VCLUnoHelper::CreateToolkit();
    return mxToolkit.get();
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> UnoWrapper::GetWindowInterface( Window* pWindow, sal_Bool bCreate )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer();
    if ( !xPeer.is() && bCreate )
    {
        xPeer = CreateXWindow( pWindow );
        SetWindowInterface( pWindow, xPeer );
    }
    return xPeer;
}

void UnoWrapper::SetWindowInterface( Window* pWindow, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xIFace )
{
    VCLXWindow* pVCLXWindow = VCLXWindow::GetImplementation( xIFace );

    DBG_ASSERT( pVCLXWindow, "SetComponentInterface - unsupported type" );
    if ( pVCLXWindow )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer();
        if( xPeer.is() )
        {
            bool bSameInstance( pVCLXWindow == dynamic_cast< VCLXWindow* >( xPeer.get() ));
            DBG_ASSERT( bSameInstance, "UnoWrapper::SetWindowInterface: there already *is* a WindowInterface for this window!" );
            if ( bSameInstance )
                return;
        }
        pVCLXWindow->SetWindow( pWindow );
        pWindow->SetWindowPeer( xIFace, pVCLXWindow );
    }
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> UnoWrapper::CreateGraphics( OutputDevice* pOutDev )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> xGrf;
    VCLXGraphics* pGrf = new VCLXGraphics;
    xGrf = pGrf;
    pGrf->Init( pOutDev );
    return xGrf;
}

void UnoWrapper::ReleaseAllGraphics( OutputDevice* pOutDev )
{
    VCLXGraphicsList_impl* pLst = pOutDev->GetUnoGraphicsList();
    if ( pLst )
    {
        for ( size_t n = 0; n < pLst->size(); n++ )
        {
            VCLXGraphics* pGrf = (*pLst)[ n ];
            pGrf->SetOutputDevice( NULL );
        }
    }

}

static sal_Bool lcl_ImplIsParent( Window* pParentWindow, Window* pPossibleChild )
{
    Window* pWindow = ( pPossibleChild != pParentWindow ) ? pPossibleChild : NULL;
    while ( pWindow && ( pWindow != pParentWindow ) )
        pWindow = pWindow->GetParent();

    return pWindow ? sal_True : sal_False;
}

void UnoWrapper::WindowDestroyed( Window* pWindow )
{
    // their still might be some children created with ::com::sun::star::loader::Java
    // that would otherwise not be destroyed until the garbage collector cleans up
    Window* pChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
    while ( pChild )
    {
        Window* pNextChild = pChild->GetWindow( WINDOW_NEXT );

        Window* pClient = pChild->GetWindow( WINDOW_CLIENT );
        if ( pClient->GetWindowPeer() )
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( pClient->GetComponentInterface( sal_False ), ::com::sun::star::uno::UNO_QUERY );
            xComp->dispose();
        }

        pChild = pNextChild;
    }

    // ::com::sun::star::chaos::System-Windows suchen...
    Window* pOverlap = pWindow->GetWindow( WINDOW_OVERLAP );
    if ( pOverlap )
    {
        pOverlap = pOverlap->GetWindow( WINDOW_FIRSTOVERLAP );
        while ( pOverlap )
        {
            Window* pNextOverlap = pOverlap->GetWindow( WINDOW_NEXT );
            Window* pClient = pOverlap->GetWindow( WINDOW_CLIENT );

            if ( pClient->GetWindowPeer() && lcl_ImplIsParent( pWindow, pClient ) )
            {
                ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( pClient->GetComponentInterface( sal_False ), ::com::sun::star::uno::UNO_QUERY );
                xComp->dispose();
            }

            pOverlap = pNextOverlap;
        }
    }

    Window* pParent = pWindow->GetParent();
    if ( pParent && pParent->GetWindowPeer() )
        pParent->GetWindowPeer()->notifyWindowRemoved( *pWindow );

    VCLXWindow* pWindowPeer = pWindow->GetWindowPeer();
    uno::Reference< lang::XComponent > xWindowPeerComp( pWindow->GetComponentInterface( sal_False ), uno::UNO_QUERY );
    OSL_ENSURE( ( pWindowPeer != NULL ) == xWindowPeerComp.is(),
        "UnoWrapper::WindowDestroyed: inconsistency in the window's peers!" );
    if ( pWindowPeer )
    {
        pWindowPeer->SetWindow( NULL );
        pWindow->SetWindowPeer( NULL, NULL );
    }
    if ( xWindowPeerComp.is() )
        xWindowPeerComp->dispose();

    // #102132# Iterate over frames after setting Window peer to NULL,
    // because while destroying other frames, we get get into the method again and try
    // to destroy this window again...
    // #i42462#/#116855# no, don't loop: Instead, just ensure that all our top-window-children
    // are disposed, too (which should also be a valid fix for #102132#, but doesn't have the extreme
    // performance penalties)
    if ( pWindow )
    {
        Window* pTopWindowChild = pWindow->GetWindow( WINDOW_FIRSTTOPWINDOWCHILD );
        while ( pTopWindowChild )
        {
            OSL_ENSURE( pTopWindowChild->GetParent() == pWindow,
                        "UnoWrapper::WindowDestroyed: inconsistency in the SystemWindow relationship!" );

            Window* pNextTopChild = pTopWindowChild->GetWindow( WINDOW_NEXTTOPWINDOWSIBLING );

            //the window still could be on the stack, so we have to
            // use lazy delete ( it will automatically
            // disconnect from the currently destroyed parent window )
            pTopWindowChild->doLazyDelete();

            pTopWindowChild = pNextTopChild;
        }
    }
}

// ----------------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > UnoWrapper::CreateAccessible( Menu* pMenu, sal_Bool bIsMenuBar )
{
    return maAccessibleFactoryAccess.getFactory().createAccessible( pMenu, bIsMenuBar );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>coverity#705963 Dereference before null check<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */

#include <com/sun/star/awt/WindowEvent.hpp>
#include <comphelper/processfactory.hxx>

#include <toolkit/helper/unowrapper.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/convert.hxx>
#include <toolkit/awt/vclxwindow.hxx>
#include <toolkit/awt/vclxwindows.hxx>
#include <toolkit/awt/vclxcontainer.hxx>
#include <toolkit/awt/vclxtopwindow.hxx>
#include <toolkit/awt/vclxgraphics.hxx>

#include "toolkit/dllapi.h"
#include <vcl/svapp.hxx>
#include <vcl/syswin.hxx>
#include <vcl/menu.hxx>

#include <tools/debug.hxx>

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

::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > CreateXWindow( Window* pWindow )
{
    switch ( pWindow->GetType() )
    {
        case WINDOW_IMAGEBUTTON:
        case WINDOW_SPINBUTTON:
        case WINDOW_MENUBUTTON:
        case WINDOW_MOREBUTTON:
        case WINDOW_PUSHBUTTON:
        case WINDOW_HELPBUTTON:
        case WINDOW_OKBUTTON:
        case WINDOW_CANCELBUTTON:   return new VCLXButton;
        case WINDOW_CHECKBOX:       return new VCLXCheckBox;
        // #i95042#
        // A Window of type <MetricBox> is inherited from type <ComboBox>.
        // Thus, it does make more sense to return a <VCLXComboBox> instance
        // instead of only a <VCLXWindow> instance, especially regarding its
        // corresponding accessibility API.
        case WINDOW_METRICBOX:
        case WINDOW_COMBOBOX:       return new VCLXComboBox;
        case WINDOW_SPINFIELD:
        case WINDOW_NUMERICFIELD:
        case WINDOW_CURRENCYFIELD:  return new VCLXNumericField;
        case WINDOW_DATEFIELD:      return new VCLXDateField;
        case WINDOW_MULTILINEEDIT:
        case WINDOW_EDIT:           return new VCLXEdit;
        case WINDOW_METRICFIELD:    return new VCLXSpinField;
        case WINDOW_MESSBOX:
        case WINDOW_INFOBOX:
        case WINDOW_WARNINGBOX:
        case WINDOW_QUERYBOX:
        case WINDOW_ERRORBOX:       return new VCLXMessageBox;
        case WINDOW_FIXEDIMAGE:     return new VCLXImageControl;
        case WINDOW_FIXEDTEXT:      return new VCLXFixedText;
        case WINDOW_MULTILISTBOX:
        case WINDOW_LISTBOX:        return new VCLXListBox;
        case WINDOW_LONGCURRENCYFIELD:  return new VCLXCurrencyField;
        case WINDOW_DIALOG:
        case WINDOW_MODALDIALOG:
        case WINDOW_TABDIALOG:
        case WINDOW_BUTTONDIALOG:
        case WINDOW_MODELESSDIALOG: return new VCLXDialog;
        case WINDOW_PATTERNFIELD:   return new VCLXPatternField;
        case WINDOW_RADIOBUTTON:    return new VCLXRadioButton;
        case WINDOW_SCROLLBAR:      return new VCLXScrollBar;
        case WINDOW_TIMEFIELD:      return new VCLXTimeField;

        case WINDOW_SYSWINDOW:
        case WINDOW_WORKWINDOW:
        case WINDOW_DOCKINGWINDOW:
        case WINDOW_FLOATINGWINDOW:
        case WINDOW_HELPTEXTWINDOW: return new VCLXTopWindow;

        case WINDOW_WINDOW:
        case WINDOW_TABPAGE:        return new VCLXContainer;

        case WINDOW_TOOLBOX:        return new VCLXToolBox;
        case WINDOW_TABCONTROL:     return new VCLXMultiPage;

        // case WINDOW_FIXEDLINE:
        // case WINDOW_FIXEDBITMAP:
        // case WINDOW_DATEBOX:
        // case WINDOW_GROUPBOX:
        // case WINDOW_LONGCURRENCYBOX:
        // case WINDOW_SPLITTER:
        // case WINDOW_STATUSBAR:
        // case WINDOW_TABCONTROL:
        // case WINDOW_NUMERICBOX:
        // case WINDOW_TRISTATEBOX:
        // case WINDOW_TIMEBOX:
        // case WINDOW_SPLITWINDOW:
        // case WINDOW_SCROLLBARBOX:
        // case WINDOW_PATTERNBOX:
        // case WINDOW_CURRENCYBOX:
        default:                    return new VCLXWindow( true );
    }
}

//  ----------------------------------------------------
//  class UnoWrapper
//  ----------------------------------------------------

extern "C" {

TOOLKIT_DLLPUBLIC UnoWrapperBase* CreateUnoWrapper()
{
    return new UnoWrapper( NULL );
}

}   // extern "C"

UnoWrapper::UnoWrapper( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit>& rxToolkit )
{
    mxToolkit = rxToolkit;
}

void UnoWrapper::Destroy()
{
    delete this;
}

UnoWrapper::~UnoWrapper()
{
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit> UnoWrapper::GetVCLToolkit()
{
    if ( !mxToolkit.is() )
        mxToolkit = VCLUnoHelper::CreateToolkit();
    return mxToolkit.get();
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> UnoWrapper::GetWindowInterface( Window* pWindow, sal_Bool bCreate )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer();
    if ( !xPeer.is() && bCreate )
    {
        xPeer = CreateXWindow( pWindow );
        SetWindowInterface( pWindow, xPeer );
    }
    return xPeer;
}

void UnoWrapper::SetWindowInterface( Window* pWindow, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xIFace )
{
    VCLXWindow* pVCLXWindow = VCLXWindow::GetImplementation( xIFace );

    DBG_ASSERT( pVCLXWindow, "SetComponentInterface - unsupported type" );
    if ( pVCLXWindow )
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer();
        if( xPeer.is() )
        {
            bool bSameInstance( pVCLXWindow == dynamic_cast< VCLXWindow* >( xPeer.get() ));
            DBG_ASSERT( bSameInstance, "UnoWrapper::SetWindowInterface: there already *is* a WindowInterface for this window!" );
            if ( bSameInstance )
                return;
        }
        pVCLXWindow->SetWindow( pWindow );
        pWindow->SetWindowPeer( xIFace, pVCLXWindow );
    }
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> UnoWrapper::CreateGraphics( OutputDevice* pOutDev )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> xGrf;
    VCLXGraphics* pGrf = new VCLXGraphics;
    xGrf = pGrf;
    pGrf->Init( pOutDev );
    return xGrf;
}

void UnoWrapper::ReleaseAllGraphics( OutputDevice* pOutDev )
{
    VCLXGraphicsList_impl* pLst = pOutDev->GetUnoGraphicsList();
    if ( pLst )
    {
        for ( size_t n = 0; n < pLst->size(); n++ )
        {
            VCLXGraphics* pGrf = (*pLst)[ n ];
            pGrf->SetOutputDevice( NULL );
        }
    }

}

static sal_Bool lcl_ImplIsParent( Window* pParentWindow, Window* pPossibleChild )
{
    Window* pWindow = ( pPossibleChild != pParentWindow ) ? pPossibleChild : NULL;
    while ( pWindow && ( pWindow != pParentWindow ) )
        pWindow = pWindow->GetParent();

    return pWindow ? sal_True : sal_False;
}

void UnoWrapper::WindowDestroyed( Window* pWindow )
{
    // their still might be some children created with ::com::sun::star::loader::Java
    // that would otherwise not be destroyed until the garbage collector cleans up
    Window* pChild = pWindow->GetWindow( WINDOW_FIRSTCHILD );
    while ( pChild )
    {
        Window* pNextChild = pChild->GetWindow( WINDOW_NEXT );

        Window* pClient = pChild->GetWindow( WINDOW_CLIENT );
        if ( pClient->GetWindowPeer() )
        {
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( pClient->GetComponentInterface( sal_False ), ::com::sun::star::uno::UNO_QUERY );
            xComp->dispose();
        }

        pChild = pNextChild;
    }

    // ::com::sun::star::chaos::System-Windows suchen...
    Window* pOverlap = pWindow->GetWindow( WINDOW_OVERLAP );
    if ( pOverlap )
    {
        pOverlap = pOverlap->GetWindow( WINDOW_FIRSTOVERLAP );
        while ( pOverlap )
        {
            Window* pNextOverlap = pOverlap->GetWindow( WINDOW_NEXT );
            Window* pClient = pOverlap->GetWindow( WINDOW_CLIENT );

            if ( pClient->GetWindowPeer() && lcl_ImplIsParent( pWindow, pClient ) )
            {
                ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( pClient->GetComponentInterface( sal_False ), ::com::sun::star::uno::UNO_QUERY );
                xComp->dispose();
            }

            pOverlap = pNextOverlap;
        }
    }

    Window* pParent = pWindow->GetParent();
    if ( pParent && pParent->GetWindowPeer() )
        pParent->GetWindowPeer()->notifyWindowRemoved( *pWindow );

    VCLXWindow* pWindowPeer = pWindow->GetWindowPeer();
    uno::Reference< lang::XComponent > xWindowPeerComp( pWindow->GetComponentInterface( sal_False ), uno::UNO_QUERY );
    OSL_ENSURE( ( pWindowPeer != NULL ) == xWindowPeerComp.is(),
        "UnoWrapper::WindowDestroyed: inconsistency in the window's peers!" );
    if ( pWindowPeer )
    {
        pWindowPeer->SetWindow( NULL );
        pWindow->SetWindowPeer( NULL, NULL );
    }
    if ( xWindowPeerComp.is() )
        xWindowPeerComp->dispose();

    // #102132# Iterate over frames after setting Window peer to NULL,
    // because while destroying other frames, we get get into the method again and try
    // to destroy this window again...
    // #i42462#/#116855# no, don't loop: Instead, just ensure that all our top-window-children
    // are disposed, too (which should also be a valid fix for #102132#, but doesn't have the extreme
    // performance penalties)
    Window* pTopWindowChild = pWindow->GetWindow( WINDOW_FIRSTTOPWINDOWCHILD );
    while ( pTopWindowChild )
    {
        OSL_ENSURE( pTopWindowChild->GetParent() == pWindow,
                    "UnoWrapper::WindowDestroyed: inconsistency in the SystemWindow relationship!" );

        Window* pNextTopChild = pTopWindowChild->GetWindow( WINDOW_NEXTTOPWINDOWSIBLING );

        //the window still could be on the stack, so we have to
        // use lazy delete ( it will automatically
        // disconnect from the currently destroyed parent window )
        pTopWindowChild->doLazyDelete();

        pTopWindowChild = pNextTopChild;
    }
}

// ----------------------------------------------------------------------------
::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > UnoWrapper::CreateAccessible( Menu* pMenu, sal_Bool bIsMenuBar )
{
    return maAccessibleFactoryAccess.getFactory().createAccessible( pMenu, bIsMenuBar );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include "../HierarchicalEA.hpp"
#include "../PopulationNodeFactory.hpp"
#include "../../exception/MismatchedCountsException.hpp"
#pragma once

template<typename NodeType, typename... params>
void HierarchicalEA::addConstructiveLattice(
	PopulationFormula * formula,
	std::vector<std::vector<Locus*>> contextLoci,
	std::vector<ToStringFunction*> toStrings,
	std::vector<std::vector<EndCondition*>> conditions,
	std::vector<std::vector<std::string>> names,
	std::vector<bool> print,
	std::vector<bool> end,
	params... as
) {
	this->addConstructiveLattice<NodeType>(
		formula,
		contextLoci,
		std::vector<std::vector<ObjectiveFunction*>>(
			names.size(),
			std::vector<ObjectiveFunction*>()
		),
		toStrings,
		conditions,
		names,
		print,
		end,
		as...
	);
}

template<typename NodeType, typename... params>
void HierarchicalEA::addConstructiveLattice(
	PopulationFormula * formula,
	std::vector<std::vector<Locus*>> contextLoci,
	ObjectiveFunction * globalObjective,
	std::vector<ToStringFunction*> toStrings,
	std::vector<std::vector<EndCondition*>> conditions,
	std::vector<std::vector<std::string>> names,
	std::vector<bool> print,
	std::vector<bool> end,
	params... as
) {
	this->addConstructiveLattice<NodeType>(
		formula,
		contextLoci,
		std::vector<std::vector<ObjectiveFunction*>>(
			names.size(),
			std::vector<ObjectiveFunction*>(1, globalObjective)
		),
		toStrings,
		conditions,
		names,
		print,
		end,
		as...
	);
}

template<typename NodeType, typename... params>
void HierarchicalEA::addConstructiveLattice(
	PopulationFormula * formula,
	std::vector<std::vector<Locus*>> contextLoci,
	std::vector<std::vector<ObjectiveFunction*>> objectives,
	std::vector<ToStringFunction*> toStrings,
	std::vector<std::vector<EndCondition*>> conditions,
	std::vector<std::vector<std::string>> names,
	std::vector<bool> print,
	std::vector<bool> end,
	params... as
) {
	std::vector<unsigned int> counts;
	for (unsigned int i = 0; i < names.size(); i++)
		counts.push_back(names[i].size());

	this->addConstructiveLattice<NodeType>(
		formula,
		this->wrapForPass(contextLoci, counts),
		this->wrapForPass(objectives, counts),
		this->wrapForPass(toStrings, counts),
		this->wrapForPass(conditions, counts),
		names,
		this->wrapForPass(print, counts),
		this->wrapForPass(end, counts),
		as...
	);
}

template <typename NodeType, typename... params>
void HierarchicalEA::addConstructiveLattice(
	PopulationFormula * formula,
	std::vector<std::vector<std::vector<Locus*>>> contextLoci,
	std::vector<std::vector<std::vector<ObjectiveFunction*>>> objectives,
	std::vector<std::vector<ToStringFunction*>> toStrings,
	std::vector<std::vector<std::vector<EndCondition*>>> conditions,
	std::vector<std::vector<std::string>> names,
	std::vector<std::vector<bool>> print,
	std::vector<std::vector<bool>> end,
	params... as
) {
	if (!this->compareVectorLengths(
		contextLoci,
		objectives,
		toStrings,
		conditions,
		names,
		print,
		end
	)) throw MismatchedCountsException();

	// TODO TODO: Refactor this
	std::vector<Locus*> levelLoci;
	std::vector<PopulationNode*> levelNodes;
	for (unsigned int i = names.size() - 1; i >= 0; i++) {
		if (!this->compareVectorLengths(
			contextLoci[i],
			objectives[i],
			toStrings[i],
			conditions[i],
			names[i],
			print[i],
			end[i]
		)) throw MismatchedCountsException();

		levelNodes.clear();
		std::vector<Locus*> nodeLoci;
		for (unsigned int k = 0; k < names[i].size(); k++) {
			nodeLoci.clear();
			nodeLoci.insert(
				nodeLoci.end(),
				levelLoci.begin(),
				levelLoci.end()
			);
			nodeLoci.insert(
				nodeLoci.end(),
				contextLoci[i][k].begin(),
				contextLoci[i][k].end()
			);

			levelNodes.push_back(
				PopulationNodeFactory::createNode<NodeType>(
					formula->getPopulationSize(
						nodeLoci.size()
					),
					nodeLoci,
					objectives[i][k],
					toStrings[i][k],
					conditions[i][k],
					names[i][k],
					1,
					as...
				)
			);
			levelLoci.push_back(
				new PopulationLocus(levelNodes[k])
			);
		}
		this->addNodes(levelNodes, print[i], end[i]);
		levelNodes.clear();
	}

	// Cleanup - this prevents the nodes at the top of the lattice from
	// having dangling loci pointing to them that won't get dealloc'd later
	for (unsigned int i = 0; i < levelLoci.size(); i++)
		delete(levelLoci[i]);
}
<commit_msg>[HierEA Lattice Factory]: Fixed counter bug<commit_after>#include "../HierarchicalEA.hpp"
#include "../PopulationNodeFactory.hpp"
#include "../../exception/MismatchedCountsException.hpp"
#pragma once

template<typename NodeType, typename... params>
void HierarchicalEA::addConstructiveLattice(
	PopulationFormula * formula,
	std::vector<std::vector<Locus*>> contextLoci,
	std::vector<ToStringFunction*> toStrings,
	std::vector<std::vector<EndCondition*>> conditions,
	std::vector<std::vector<std::string>> names,
	std::vector<bool> print,
	std::vector<bool> end,
	params... as
) {
	this->addConstructiveLattice<NodeType>(
		formula,
		contextLoci,
		std::vector<std::vector<ObjectiveFunction*>>(
			names.size(),
			std::vector<ObjectiveFunction*>()
		),
		toStrings,
		conditions,
		names,
		print,
		end,
		as...
	);
}

template<typename NodeType, typename... params>
void HierarchicalEA::addConstructiveLattice(
	PopulationFormula * formula,
	std::vector<std::vector<Locus*>> contextLoci,
	ObjectiveFunction * globalObjective,
	std::vector<ToStringFunction*> toStrings,
	std::vector<std::vector<EndCondition*>> conditions,
	std::vector<std::vector<std::string>> names,
	std::vector<bool> print,
	std::vector<bool> end,
	params... as
) {
	this->addConstructiveLattice<NodeType>(
		formula,
		contextLoci,
		std::vector<std::vector<ObjectiveFunction*>>(
			names.size(),
			std::vector<ObjectiveFunction*>(1, globalObjective)
		),
		toStrings,
		conditions,
		names,
		print,
		end,
		as...
	);
}

template<typename NodeType, typename... params>
void HierarchicalEA::addConstructiveLattice(
	PopulationFormula * formula,
	std::vector<std::vector<Locus*>> contextLoci,
	std::vector<std::vector<ObjectiveFunction*>> objectives,
	std::vector<ToStringFunction*> toStrings,
	std::vector<std::vector<EndCondition*>> conditions,
	std::vector<std::vector<std::string>> names,
	std::vector<bool> print,
	std::vector<bool> end,
	params... as
) {
	std::vector<unsigned int> counts;
	for (unsigned int i = 0; i < names.size(); i++)
		counts.push_back(names[i].size());

	this->addConstructiveLattice<NodeType>(
		formula,
		this->wrapForPass(contextLoci, counts),
		this->wrapForPass(objectives, counts),
		this->wrapForPass(toStrings, counts),
		this->wrapForPass(conditions, counts),
		names,
		this->wrapForPass(print, counts),
		this->wrapForPass(end, counts),
		as...
	);
}

template <typename NodeType, typename... params>
void HierarchicalEA::addConstructiveLattice(
	PopulationFormula * formula,
	std::vector<std::vector<std::vector<Locus*>>> contextLoci,
	std::vector<std::vector<std::vector<ObjectiveFunction*>>> objectives,
	std::vector<std::vector<ToStringFunction*>> toStrings,
	std::vector<std::vector<std::vector<EndCondition*>>> conditions,
	std::vector<std::vector<std::string>> names,
	std::vector<std::vector<bool>> print,
	std::vector<std::vector<bool>> end,
	params... as
) {
	if (!this->compareVectorLengths(
		contextLoci,
		objectives,
		toStrings,
		conditions,
		names,
		print,
		end
	)) throw MismatchedCountsException();

	// TODO TODO: Refactor this
	std::vector<Locus*> levelLoci;
	std::vector<PopulationNode*> levelNodes;
	for (
		unsigned int i = names.size() - 1;
		i >= 0 && i < names.size(); // Counteracts unsigned overflow
		i--
	) {
		if (!this->compareVectorLengths(
			contextLoci[i],
			objectives[i],
			toStrings[i],
			conditions[i],
			names[i],
			print[i],
			end[i]
		)) throw MismatchedCountsException();

		levelNodes.clear();
		std::vector<Locus*> nodeLoci;
		for (unsigned int k = 0; k < names[i].size(); k++) {
			nodeLoci.clear();
			nodeLoci.insert(
				nodeLoci.end(),
				levelLoci.begin(),
				levelLoci.end()
			);
			nodeLoci.insert(
				nodeLoci.end(),
				contextLoci[i][k].begin(),
				contextLoci[i][k].end()
			);

			levelNodes.push_back(
				PopulationNodeFactory::createNode<NodeType>(
					formula->getPopulationSize(
						nodeLoci.size()
					),
					nodeLoci,
					objectives[i][k],
					toStrings[i][k],
					conditions[i][k],
					names[i][k],
					1,
					as...
				)
			);
			levelLoci.push_back(
				new PopulationLocus(levelNodes[k])
			);
		}
		this->addNodes(levelNodes, print[i], end[i]);
		levelNodes.clear();
	}

	// Cleanup - this prevents the nodes at the top of the lattice from
	// having dangling loci pointing to them that won't get dealloc'd later
	for (unsigned int i = 0; i < levelLoci.size(); i++)
		delete(levelLoci[i]);
}
<|endoftext|>


<commit_before>// [WriteFile Name=OpenExistingMap, Category=Maps]
// [Legal]
// Copyright 2016 Esri.

// 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.
// [Legal]

#include "OpenExistingMap.h"

#include "Map.h"
#include "MapQuickView.h"
#include "Basemap.h"
#include "PortalItem.h"

using namespace Esri::ArcGISRuntime;

OpenExistingMap::OpenExistingMap(QQuickItem* parent) :
    QQuickItem(parent),
    m_mapView(nullptr)
{
}

OpenExistingMap::~OpenExistingMap()
{
}

void OpenExistingMap::componentComplete()
{
    QQuickItem::componentComplete();

    // find QML MapView component
    m_mapView = findChild<MapQuickView*>("mapView");

    // create a new basemap instance
    Basemap* basemap = Basemap::imagery(this);
    // create a new map instance
    Map* map = new Map(basemap, this);
    // set map on the map view
    m_mapView->setMap(map);
}

void OpenExistingMap::openMap(QString itemId)
{
    // create a portal item with the item id
    PortalItem portalItem;
    portalItem.setUrl(QUrl("http://arcgis.com/sharing/rest/content/items/" + itemId));

    // create a new map from the portal item
    Map* map = new Map(portalItem, this);

    // set the map to the map view
    m_mapView->setMap(map);
}
<commit_msg>fix portalItem<commit_after>// [WriteFile Name=OpenExistingMap, Category=Maps]
// [Legal]
// Copyright 2016 Esri.

// 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.
// [Legal]

#include "OpenExistingMap.h"

#include "Map.h"
#include "MapQuickView.h"
#include "Basemap.h"
#include "PortalItem.h"

using namespace Esri::ArcGISRuntime;

OpenExistingMap::OpenExistingMap(QQuickItem* parent) :
    QQuickItem(parent),
    m_mapView(nullptr)
{
}

OpenExistingMap::~OpenExistingMap()
{
}

void OpenExistingMap::componentComplete()
{
    QQuickItem::componentComplete();

    // find QML MapView component
    m_mapView = findChild<MapQuickView*>("mapView");

    // create a new basemap instance
    Basemap* basemap = Basemap::imagery(this);
    // create a new map instance
    Map* map = new Map(basemap, this);
    // set map on the map view
    m_mapView->setMap(map);
}

void OpenExistingMap::openMap(QString itemId)
{
    // create a portal item with the item id
    auto portalItem = new PortalItem(QUrl("http://arcgis.com/sharing/rest/content/items/" + itemId));

    // create a new map from the portal item
    Map* map = new Map(portalItem, this);

    // set the map to the map view
    m_mapView->setMap(map);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2009 Manjeet Dahiya
 *
 * Author:
 *	Manjeet Dahiya
 *
 * Source:
 *	http://code.google.com/p/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 */

#include "QXmppStanza.h"
#include "QXmppUtils.h"
#include "QXmppConstants.h"

#include <QDomElement>
#include <QXmlStreamWriter>

uint QXmppStanza::s_uniqeIdNo = 0;

QXmppStanza::Error::Error():
    m_code(0),
    m_type(static_cast<QXmppStanza::Error::Type>(-1)),
    m_condition(static_cast<QXmppStanza::Error::Condition>(-1)),
    m_text("")
{
}

QXmppStanza::Error::Error(Type type, Condition cond, const QString& text):
    m_code(0),
    m_type(type),
    m_condition(cond),
    m_text(text)
{
}

QXmppStanza::Error::Error(const QString& type, const QString& cond,
                          const QString& text):
    m_code(0),
    m_text(text)
{
    setTypeFromStr(type);
    setConditionFromStr(cond);
}

void QXmppStanza::Error::setText(const QString& text)
{
    m_text = text;
}

void QXmppStanza::Error::setCode(int code)
{
    m_code = code;
}

void QXmppStanza::Error::setCondition(QXmppStanza::Error::Condition cond)
{
    m_condition = cond;
}

void QXmppStanza::Error::setType(QXmppStanza::Error::Type type)
{
    m_type = type;
}

QString QXmppStanza::Error::getText() const
{
    return m_text;
}

int QXmppStanza::Error::getCode() const
{
    return m_code;
}

QXmppStanza::Error::Condition QXmppStanza::Error::getCondition() const
{
    return m_condition;
}

QXmppStanza::Error::Type QXmppStanza::Error::getType() const
{
    return m_type;
}

QString QXmppStanza::Error::getTypeStr() const
{
    switch(m_type)
    {
    case Cancel:
        return "cancel";
    case Continue:
        return "continue";
    case Modify:
        return "modify";
    case Auth:
        return "auth";
    case Wait:
        return "wait";
    default:
        return "";
    }
}

QString QXmppStanza::Error::getConditionStr() const
{
    switch(m_condition)
    {
    case BadRequest:
        return "bad-request";
    case Conflict:
        return "conflict";
    case FeatureNotImplemented:
        return "feature-not-implemented";
    case Forbidden:
        return "forbidden";
    case Gone:
        return "gone";
    case InternalServerError:
        return "internal-server-error";
    case ItemNotFound:
        return "item-not-found";
    case JidMalformed:
        return "jid-malformed";
    case NotAcceptable:
        return "not-acceptable";
    case NotAllowed:
        return "not-allowed";
    case NotAuthorized:
        return "not-authorized";
    case PaymentRequired:
        return "payment-required";
    case RecipientUnavailable:
        return "recipient-unavailable";
    case Redirect:
        return "redirect";
    case RegistrationRequired:
        return "registration-required";
    case RemoteServerNotFound:
        return "remote-server-not-found";
    case RemoteServerTimeout:
        return "remote-server-timeout";
    case ResourceConstraint:
        return "resource-constraint";
    case ServiceUnavailable:
        return "service-unavailable";
    case SubscriptionRequired:
        return "subscription-required";
    case UndefinedCondition:
        return "undefined-condition";
    case UnexpectedRequest:
        return "unexpected-request";
    default:
        return "";
    }
}

void QXmppStanza::Error::setTypeFromStr(const QString& type)
{
    if(type == "cancel")
        setType(Cancel);
    else if(type == "continue")
        setType(Continue);
    else if(type == "modify")
        setType(Modify);
    else if(type == "auth")
        setType(Auth);
    else if(type == "wait")
        setType(Wait);
    else
        setType(static_cast<QXmppStanza::Error::Type>(-1));
}

void QXmppStanza::Error::setConditionFromStr(const QString& type)
{
    if(type == "bad-request")
        setCondition(BadRequest);
    else if(type == "conflict")
        setCondition(Conflict);
    else if(type == "feature-not-implemented")
        setCondition(FeatureNotImplemented);
    else if(type == "forbidden")
        setCondition(Forbidden);
    else if(type == "gone")
        setCondition(Gone);
    else if(type == "internal-server-error")
        setCondition(InternalServerError);
    else if(type == "item-not-found")
        setCondition(ItemNotFound);
    else if(type == "jid-malformed")
        setCondition(JidMalformed);
    else if(type == "not-acceptable")
        setCondition(NotAcceptable);
    else if(type == "not-allowed")
        setCondition(NotAllowed);
    else if(type == "not-authorized")
        setCondition(NotAuthorized);
    else if(type == "payment-required")
        setCondition(PaymentRequired);
    else if(type == "recipient-unavailable")
        setCondition(RecipientUnavailable);
    else if(type == "redirect")
        setCondition(Redirect);
    else if(type == "registration-required")
        setCondition(RegistrationRequired);
    else if(type == "remote-server-not-found")
        setCondition(RemoteServerNotFound);
    else if(type == "remote-server-timeout")
        setCondition(RemoteServerTimeout);
    else if(type == "resource-constraint")
        setCondition(ResourceConstraint);
    else if(type == "service-unavailable")
        setCondition(ServiceUnavailable);
    else if(type == "subscription-required")
        setCondition(SubscriptionRequired);
    else if(type == "undefined-condition")
        setCondition(UndefinedCondition);
    else if(type == "unexpected-request")
        setCondition(UnexpectedRequest);
    else
        setCondition(static_cast<QXmppStanza::Error::Condition>(-1));
}

bool QXmppStanza::Error::isValid()
{
    return !(getTypeStr().isEmpty() && getConditionStr().isEmpty());
}

void QXmppStanza::Error::parse(const QDomElement &errorElement)
{
    setCode(errorElement.attribute("code").toInt());
    setTypeFromStr(errorElement.attribute("type"));

    QString text;
    QString cond;
    QDomElement element = errorElement.firstChildElement();
    while(!element.isNull())
    {
        if(element.tagName() == "text")
            text = element.text();
        else if(element.namespaceURI() == ns_stanza)
        {
            cond = element.tagName();
        }
        element = element.nextSiblingElement();
    }

    setConditionFromStr(cond);
    setText(text);
}

void QXmppStanza::Error::toXml( QXmlStreamWriter *writer ) const
{
    QString cond = getConditionStr();
    QString type = getTypeStr();

    if(cond.isEmpty() && type.isEmpty())
        return;

    writer->writeStartElement("error");
    helperToXmlAddAttribute(writer, "type", type);

    if (m_code > 0)
        helperToXmlAddAttribute(writer, "code", QString::number(m_code));

    if(!cond.isEmpty())
    {
        writer->writeStartElement(cond);
        helperToXmlAddAttribute(writer,"xmlns", ns_stanza);
        writer->writeEndElement();
    }
    if(!m_text.isEmpty())
    {
        writer->writeStartElement("text");
        helperToXmlAddAttribute(writer,"xml:lang", "en");
        helperToXmlAddAttribute(writer,"xmlns", ns_stanza);
        writer->writeCharacters(m_text);
        writer->writeEndElement();
    }

    writer->writeEndElement();
}

QXmppStanza::QXmppStanza(const QString& from, const QString& to) : QXmppPacket(),
m_to(to), m_from(from)
{
}

QXmppStanza::~QXmppStanza()
{
}

QString QXmppStanza::to() const
{
    return m_to;
}

void QXmppStanza::setTo(const QString& to)
{
    m_to = to;
}

QString QXmppStanza::from() const
{
    return m_from;
}

void QXmppStanza::setFrom(const QString& from)
{
    m_from = from;
}

QString QXmppStanza::id() const
{
    return m_id;
}

void QXmppStanza::setId(const QString& id)
{
    m_id = id;
}

QString QXmppStanza::lang() const
{
    return m_lang;
}

void QXmppStanza::setLang(const QString& lang)
{
    m_lang = lang;
}

QXmppStanza::Error QXmppStanza::error() const
{
    return m_error;
}

void QXmppStanza::setError(QXmppStanza::Error& error)
{
    m_error = error;
}

QXmppElementList QXmppStanza::extensions() const
{
    return m_extensions;
}

void QXmppStanza::setExtensions(const QXmppElementList &extensions)
{
    m_extensions = extensions;
}

void QXmppStanza::generateAndSetNextId()
{
    // get back
    ++s_uniqeIdNo;
    m_id = "qxmpp" + QString::number(s_uniqeIdNo);
}

bool QXmppStanza::isErrorStanza()
{
    return m_error.isValid();
}

void QXmppStanza::parse(const QDomElement &element)
{
    m_from = element.attribute("from");
    m_to = element.attribute("to");
    m_id = element.attribute("id");
    m_lang = element.attribute("lang");

    QDomElement errorElement = element.firstChildElement("error");
    if(!errorElement.isNull())
        m_error.parse(errorElement);
}

// deprecated

QString QXmppStanza::getTo() const
{
    return m_to;
}

QString QXmppStanza::getFrom() const
{
    return m_from;
}

QString QXmppStanza::getId() const
{
    return m_id;
}

QString QXmppStanza::getLang() const
{
    return m_lang;
}

QXmppStanza::Error QXmppStanza::getError() const
{
    return m_error;
}

<commit_msg>cleanup QXmppStanza::Error API<commit_after>/*
 * Copyright (C) 2008-2009 Manjeet Dahiya
 *
 * Author:
 *	Manjeet Dahiya
 *
 * Source:
 *	http://code.google.com/p/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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.
 *
 */

#include "QXmppStanza.h"
#include "QXmppUtils.h"
#include "QXmppConstants.h"

#include <QDomElement>
#include <QXmlStreamWriter>

uint QXmppStanza::s_uniqeIdNo = 0;

QXmppStanza::Error::Error():
    m_code(0),
    m_type(static_cast<QXmppStanza::Error::Type>(-1)),
    m_condition(static_cast<QXmppStanza::Error::Condition>(-1)),
    m_text("")
{
}

QXmppStanza::Error::Error(Type type, Condition cond, const QString& text):
    m_code(0),
    m_type(type),
    m_condition(cond),
    m_text(text)
{
}

QXmppStanza::Error::Error(const QString& type, const QString& cond,
                          const QString& text):
    m_code(0),
    m_text(text)
{
    setTypeFromStr(type);
    setConditionFromStr(cond);
}

QString QXmppStanza::Error::text() const
{
    return m_text;
}

void QXmppStanza::Error::setText(const QString& text)
{
    m_text = text;
}

int QXmppStanza::Error::code() const
{
    return m_code;
}

void QXmppStanza::Error::setCode(int code)
{
    m_code = code;
}

QXmppStanza::Error::Condition QXmppStanza::Error::condition() const
{
    return m_condition;
}

void QXmppStanza::Error::setCondition(QXmppStanza::Error::Condition cond)
{
    m_condition = cond;
}

QXmppStanza::Error::Type QXmppStanza::Error::type() const
{
    return m_type;
}

void QXmppStanza::Error::setType(QXmppStanza::Error::Type type)
{
    m_type = type;
}

QString QXmppStanza::Error::getTypeStr() const
{
    switch(m_type)
    {
    case Cancel:
        return "cancel";
    case Continue:
        return "continue";
    case Modify:
        return "modify";
    case Auth:
        return "auth";
    case Wait:
        return "wait";
    default:
        return "";
    }
}

QString QXmppStanza::Error::getConditionStr() const
{
    switch(m_condition)
    {
    case BadRequest:
        return "bad-request";
    case Conflict:
        return "conflict";
    case FeatureNotImplemented:
        return "feature-not-implemented";
    case Forbidden:
        return "forbidden";
    case Gone:
        return "gone";
    case InternalServerError:
        return "internal-server-error";
    case ItemNotFound:
        return "item-not-found";
    case JidMalformed:
        return "jid-malformed";
    case NotAcceptable:
        return "not-acceptable";
    case NotAllowed:
        return "not-allowed";
    case NotAuthorized:
        return "not-authorized";
    case PaymentRequired:
        return "payment-required";
    case RecipientUnavailable:
        return "recipient-unavailable";
    case Redirect:
        return "redirect";
    case RegistrationRequired:
        return "registration-required";
    case RemoteServerNotFound:
        return "remote-server-not-found";
    case RemoteServerTimeout:
        return "remote-server-timeout";
    case ResourceConstraint:
        return "resource-constraint";
    case ServiceUnavailable:
        return "service-unavailable";
    case SubscriptionRequired:
        return "subscription-required";
    case UndefinedCondition:
        return "undefined-condition";
    case UnexpectedRequest:
        return "unexpected-request";
    default:
        return "";
    }
}

void QXmppStanza::Error::setTypeFromStr(const QString& type)
{
    if(type == "cancel")
        setType(Cancel);
    else if(type == "continue")
        setType(Continue);
    else if(type == "modify")
        setType(Modify);
    else if(type == "auth")
        setType(Auth);
    else if(type == "wait")
        setType(Wait);
    else
        setType(static_cast<QXmppStanza::Error::Type>(-1));
}

void QXmppStanza::Error::setConditionFromStr(const QString& type)
{
    if(type == "bad-request")
        setCondition(BadRequest);
    else if(type == "conflict")
        setCondition(Conflict);
    else if(type == "feature-not-implemented")
        setCondition(FeatureNotImplemented);
    else if(type == "forbidden")
        setCondition(Forbidden);
    else if(type == "gone")
        setCondition(Gone);
    else if(type == "internal-server-error")
        setCondition(InternalServerError);
    else if(type == "item-not-found")
        setCondition(ItemNotFound);
    else if(type == "jid-malformed")
        setCondition(JidMalformed);
    else if(type == "not-acceptable")
        setCondition(NotAcceptable);
    else if(type == "not-allowed")
        setCondition(NotAllowed);
    else if(type == "not-authorized")
        setCondition(NotAuthorized);
    else if(type == "payment-required")
        setCondition(PaymentRequired);
    else if(type == "recipient-unavailable")
        setCondition(RecipientUnavailable);
    else if(type == "redirect")
        setCondition(Redirect);
    else if(type == "registration-required")
        setCondition(RegistrationRequired);
    else if(type == "remote-server-not-found")
        setCondition(RemoteServerNotFound);
    else if(type == "remote-server-timeout")
        setCondition(RemoteServerTimeout);
    else if(type == "resource-constraint")
        setCondition(ResourceConstraint);
    else if(type == "service-unavailable")
        setCondition(ServiceUnavailable);
    else if(type == "subscription-required")
        setCondition(SubscriptionRequired);
    else if(type == "undefined-condition")
        setCondition(UndefinedCondition);
    else if(type == "unexpected-request")
        setCondition(UnexpectedRequest);
    else
        setCondition(static_cast<QXmppStanza::Error::Condition>(-1));
}

bool QXmppStanza::Error::isValid()
{
    return !(getTypeStr().isEmpty() && getConditionStr().isEmpty());
}

void QXmppStanza::Error::parse(const QDomElement &errorElement)
{
    setCode(errorElement.attribute("code").toInt());
    setTypeFromStr(errorElement.attribute("type"));

    QString text;
    QString cond;
    QDomElement element = errorElement.firstChildElement();
    while(!element.isNull())
    {
        if(element.tagName() == "text")
            text = element.text();
        else if(element.namespaceURI() == ns_stanza)
        {
            cond = element.tagName();
        }
        element = element.nextSiblingElement();
    }

    setConditionFromStr(cond);
    setText(text);
}

void QXmppStanza::Error::toXml( QXmlStreamWriter *writer ) const
{
    QString cond = getConditionStr();
    QString type = getTypeStr();

    if(cond.isEmpty() && type.isEmpty())
        return;

    writer->writeStartElement("error");
    helperToXmlAddAttribute(writer, "type", type);

    if (m_code > 0)
        helperToXmlAddAttribute(writer, "code", QString::number(m_code));

    if(!cond.isEmpty())
    {
        writer->writeStartElement(cond);
        helperToXmlAddAttribute(writer,"xmlns", ns_stanza);
        writer->writeEndElement();
    }
    if(!m_text.isEmpty())
    {
        writer->writeStartElement("text");
        helperToXmlAddAttribute(writer,"xml:lang", "en");
        helperToXmlAddAttribute(writer,"xmlns", ns_stanza);
        writer->writeCharacters(m_text);
        writer->writeEndElement();
    }

    writer->writeEndElement();
}

QXmppStanza::QXmppStanza(const QString& from, const QString& to) : QXmppPacket(),
m_to(to), m_from(from)
{
}

QXmppStanza::~QXmppStanza()
{
}

QString QXmppStanza::to() const
{
    return m_to;
}

void QXmppStanza::setTo(const QString& to)
{
    m_to = to;
}

QString QXmppStanza::from() const
{
    return m_from;
}

void QXmppStanza::setFrom(const QString& from)
{
    m_from = from;
}

QString QXmppStanza::id() const
{
    return m_id;
}

void QXmppStanza::setId(const QString& id)
{
    m_id = id;
}

QString QXmppStanza::lang() const
{
    return m_lang;
}

void QXmppStanza::setLang(const QString& lang)
{
    m_lang = lang;
}

QXmppStanza::Error QXmppStanza::error() const
{
    return m_error;
}

void QXmppStanza::setError(QXmppStanza::Error& error)
{
    m_error = error;
}

QXmppElementList QXmppStanza::extensions() const
{
    return m_extensions;
}

void QXmppStanza::setExtensions(const QXmppElementList &extensions)
{
    m_extensions = extensions;
}

void QXmppStanza::generateAndSetNextId()
{
    // get back
    ++s_uniqeIdNo;
    m_id = "qxmpp" + QString::number(s_uniqeIdNo);
}

bool QXmppStanza::isErrorStanza()
{
    return m_error.isValid();
}

void QXmppStanza::parse(const QDomElement &element)
{
    m_from = element.attribute("from");
    m_to = element.attribute("to");
    m_id = element.attribute("id");
    m_lang = element.attribute("lang");

    QDomElement errorElement = element.firstChildElement("error");
    if(!errorElement.isNull())
        m_error.parse(errorElement);
}

// deprecated

QString QXmppStanza::Error::getText() const
{
    return m_text;
}

int QXmppStanza::Error::getCode() const
{
    return m_code;
}

QXmppStanza::Error::Condition QXmppStanza::Error::getCondition() const
{
    return m_condition;
}

QXmppStanza::Error::Type QXmppStanza::Error::getType() const
{
    return m_type;
}

QString QXmppStanza::getTo() const
{
    return m_to;
}

QString QXmppStanza::getFrom() const
{
    return m_from;
}

QString QXmppStanza::getId() const
{
    return m_id;
}

QString QXmppStanza::getLang() const
{
    return m_lang;
}

QXmppStanza::Error QXmppStanza::getError() const
{
    return m_error;
}

<|endoftext|>


<commit_before>// Copyright 2006-2009 the V8 project authors. All rights reserved.
//
// Tests of profiler-related functions from log.h

#ifdef ENABLE_LOGGING_AND_PROFILING

#include <stdlib.h>

#include "v8.h"

#include "codegen.h"
#include "log.h"
#include "top.h"
#include "cctest.h"
#include "disassembler.h"
#include "register-allocator-inl.h"

using v8::Function;
using v8::Local;
using v8::Object;
using v8::Script;
using v8::String;
using v8::Value;

using v8::internal::byte;
using v8::internal::Address;
using v8::internal::Handle;
using v8::internal::JSFunction;
using v8::internal::StackTracer;
using v8::internal::TickSample;
using v8::internal::Top;

namespace i = v8::internal;

static v8::Persistent<v8::Context> env;

static struct {
  TickSample* sample;
} trace_env = { NULL };

static void InitTraceEnv(TickSample* sample) {
  trace_env.sample = sample;
}

static void DoTrace(Address fp) {
  trace_env.sample->fp = fp;
  // sp is only used to define stack high bound
  trace_env.sample->sp =
      reinterpret_cast<Address>(trace_env.sample) - 10240;
  StackTracer::Trace(trace_env.sample);
}

// Hide c_entry_fp to emulate situation when sampling is done while
// pure JS code is being executed
static void DoTraceHideCEntryFPAddress(Address fp) {
  v8::internal::Address saved_c_frame_fp = *(Top::c_entry_fp_address());
  CHECK(saved_c_frame_fp);
  *(Top::c_entry_fp_address()) = 0;
  DoTrace(fp);
  *(Top::c_entry_fp_address()) = saved_c_frame_fp;
}

static void CheckRetAddrIsInFunction(const char* func_name,
                                     Address ret_addr,
                                     Address func_start_addr,
                                     unsigned int func_len) {
  printf("CheckRetAddrIsInFunction \"%s\": %p %p %p\n",
         func_name, func_start_addr, ret_addr, func_start_addr + func_len);
  CHECK_GE(ret_addr, func_start_addr);
  CHECK_GE(func_start_addr + func_len, ret_addr);
}

static void CheckRetAddrIsInJSFunction(const char* func_name,
                                       Address ret_addr,
                                       Handle<JSFunction> func) {
  v8::internal::Code* func_code = func->code();
  CheckRetAddrIsInFunction(
      func_name, ret_addr,
      func_code->instruction_start(),
      func_code->ExecutableSize());
}

// --- T r a c e   E x t e n s i o n ---

class TraceExtension : public v8::Extension {
 public:
  TraceExtension() : v8::Extension("v8/trace", kSource) { }
  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
      v8::Handle<String> name);
  static v8::Handle<v8::Value> Trace(const v8::Arguments& args);
  static v8::Handle<v8::Value> JSTrace(const v8::Arguments& args);
  static v8::Handle<v8::Value> JSEntrySP(const v8::Arguments& args);
  static v8::Handle<v8::Value> JSEntrySPLevel2(const v8::Arguments& args);
 private:
  static Address GetFP(const v8::Arguments& args);
  static const char* kSource;
};

const char* TraceExtension::kSource =
    "native function trace();"
    "native function js_trace();"
    "native function js_entry_sp();"
    "native function js_entry_sp_level2();";

v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunction(
    v8::Handle<String> name) {
  if (name->Equals(String::New("trace"))) {
    return v8::FunctionTemplate::New(TraceExtension::Trace);
  } else if (name->Equals(String::New("js_trace"))) {
    return v8::FunctionTemplate::New(TraceExtension::JSTrace);
  } else if (name->Equals(String::New("js_entry_sp"))) {
    return v8::FunctionTemplate::New(TraceExtension::JSEntrySP);
  } else if (name->Equals(String::New("js_entry_sp_level2"))) {
    return v8::FunctionTemplate::New(TraceExtension::JSEntrySPLevel2);
  } else {
    CHECK(false);
    return v8::Handle<v8::FunctionTemplate>();
  }
}

Address TraceExtension::GetFP(const v8::Arguments& args) {
  CHECK_EQ(1, args.Length());
  // CodeGenerator::GenerateGetFramePointer pushes EBP / RBP value
  // on stack. In 64-bit mode we can't use Smi operations code because
  // they check that value is within Smi bounds.
  Address fp = *reinterpret_cast<Address*>(*args[0]);
  printf("Trace: %p\n", fp);
  return fp;
}

v8::Handle<v8::Value> TraceExtension::Trace(const v8::Arguments& args) {
  DoTrace(GetFP(args));
  return v8::Undefined();
}

v8::Handle<v8::Value> TraceExtension::JSTrace(const v8::Arguments& args) {
  DoTraceHideCEntryFPAddress(GetFP(args));
  return v8::Undefined();
}

static Address GetJsEntrySp() {
  CHECK_NE(NULL, Top::GetCurrentThread());
  return Top::js_entry_sp(Top::GetCurrentThread());
}

v8::Handle<v8::Value> TraceExtension::JSEntrySP(const v8::Arguments& args) {
  CHECK_NE(0, GetJsEntrySp());
  return v8::Undefined();
}

v8::Handle<v8::Value> TraceExtension::JSEntrySPLevel2(
    const v8::Arguments& args) {
  v8::HandleScope scope;
  const Address js_entry_sp = GetJsEntrySp();
  CHECK_NE(0, js_entry_sp);
  CompileRun("js_entry_sp();");
  CHECK_EQ(js_entry_sp, GetJsEntrySp());
  return v8::Undefined();
}

static TraceExtension kTraceExtension;
v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension);

static void InitializeVM() {
  if (env.IsEmpty()) {
    v8::HandleScope scope;
    const char* extensions[] = { "v8/trace" };
    v8::ExtensionConfiguration config(1, extensions);
    env = v8::Context::New(&config);
  }
  v8::HandleScope scope;
  env->Enter();
}

static Handle<JSFunction> CompileFunction(const char* source) {
  Handle<JSFunction> result(JSFunction::cast(
      *v8::Utils::OpenHandle(*Script::Compile(String::New(source)))));
  return result;
}

static Local<Value> GetGlobalProperty(const char* name) {
  return env->Global()->Get(String::New(name));
}

static Handle<JSFunction> GetGlobalJSFunction(const char* name) {
  Handle<JSFunction> result(JSFunction::cast(
      *v8::Utils::OpenHandle(*GetGlobalProperty(name))));
  return result;
}

static void CheckRetAddrIsInJSFunction(const char* func_name,
                                               Address ret_addr) {
  CheckRetAddrIsInJSFunction(func_name,
                             ret_addr,
                             GetGlobalJSFunction(func_name));
}

static void SetGlobalProperty(const char* name, Local<Value> value) {
  env->Global()->Set(String::New(name), value);
}

static Handle<v8::internal::String> NewString(const char* s) {
  return i::Factory::NewStringFromAscii(i::CStrVector(s));
}

namespace v8 {
namespace internal {

class CodeGeneratorPatcher {
 public:
  CodeGeneratorPatcher() {
    CodeGenerator::InlineRuntimeLUT genGetFramePointer =
        {&CodeGenerator::GenerateGetFramePointer, "_GetFramePointer", 0};
    // _RandomPositiveSmi is not used in our tests. The one we replace need to
    // have the same number of arguments as the one we put in, which is zero in
    // this case.
    bool result = CodeGenerator::PatchInlineRuntimeEntry(
        NewString("_RandomPositiveSmi"),
        genGetFramePointer, &oldInlineEntry);
    CHECK(result);
  }

  ~CodeGeneratorPatcher() {
    CHECK(CodeGenerator::PatchInlineRuntimeEntry(
        NewString("_GetFramePointer"),
        oldInlineEntry, NULL));
  }

 private:
  CodeGenerator::InlineRuntimeLUT oldInlineEntry;
};

} }  // namespace v8::internal

// Creates a global function named 'func_name' that calls the tracing
// function 'trace_func_name' with an actual EBP register value,
// shifted right to be presented as Smi.
static void CreateTraceCallerFunction(const char* func_name,
                                      const char* trace_func_name) {
  i::EmbeddedVector<char, 256> trace_call_buf;
  i::OS::SNPrintF(trace_call_buf, "%s(%%_GetFramePointer());", trace_func_name);

  // Compile the script.
  i::CodeGeneratorPatcher patcher;
  bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
  i::FLAG_allow_natives_syntax = true;
  Handle<JSFunction> func = CompileFunction(trace_call_buf.start());
  CHECK(!func.is_null());
  i::FLAG_allow_natives_syntax = allow_natives_syntax;

#ifdef DEBUG
  v8::internal::Code* func_code = func->code();
  CHECK(func_code->IsCode());
  func_code->Print();
#endif

  SetGlobalProperty(func_name, v8::ToApi<Value>(func));
  CHECK_EQ(*func, *GetGlobalJSFunction(func_name));
}

TEST(CFromJSStackTrace) {
  TickSample sample;
  InitTraceEnv(&sample);

  InitializeVM();
  v8::HandleScope scope;
  CreateTraceCallerFunction("JSFuncDoTrace", "trace");
  Local<Value> result = CompileRun(
      "function JSTrace() {"
      "         JSFuncDoTrace();"
      "};\n"
      "JSTrace();\n"
      "true;");
  CHECK(!result.IsEmpty());
  CHECK_GT(sample.frames_count, 1);
  // Stack sampling will start from the first JS function, i.e. "JSFuncDoTrace"
  CheckRetAddrIsInJSFunction("JSFuncDoTrace",
                             sample.stack[0]);
  CheckRetAddrIsInJSFunction("JSTrace",
                             sample.stack[1]);
}

TEST(PureJSStackTrace) {
  TickSample sample;
  InitTraceEnv(&sample);

  InitializeVM();
  v8::HandleScope scope;
  CreateTraceCallerFunction("JSFuncDoTrace", "js_trace");
  Local<Value> result = CompileRun(
      "function JSTrace() {"
      "         JSFuncDoTrace();"
      "};\n"
      "function OuterJSTrace() {"
      "         JSTrace();"
      "};\n"
      "OuterJSTrace();\n"
      "true;");
  CHECK(!result.IsEmpty());
  // The last JS function called.
  CHECK_EQ(GetGlobalJSFunction("JSFuncDoTrace")->address(),
           sample.function);
  CHECK_GT(sample.frames_count, 1);
  // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
  CheckRetAddrIsInJSFunction("JSTrace",
                             sample.stack[0]);
  CheckRetAddrIsInJSFunction("OuterJSTrace",
                             sample.stack[1]);
}

static void CFuncDoTrace(byte dummy_parameter) {
  Address fp;
#ifdef __GNUC__
  fp = reinterpret_cast<Address>(__builtin_frame_address(0));
#elif defined _MSC_VER
  // Approximate a frame pointer address. We compile without base pointers,
  // so we can't trust ebp/rbp.
  fp = &dummy_parameter - 2 * sizeof(void*);  // NOLINT
#else
#error Unexpected platform.
#endif
  DoTrace(fp);
}

static int CFunc(int depth) {
  if (depth <= 0) {
    CFuncDoTrace(0);
    return 0;
  } else {
    return CFunc(depth - 1) + 1;
  }
}

TEST(PureCStackTrace) {
  TickSample sample;
  InitTraceEnv(&sample);
  // Check that sampler doesn't crash
  CHECK_EQ(10, CFunc(10));
}

TEST(JsEntrySp) {
  InitializeVM();
  v8::HandleScope scope;
  CHECK_EQ(0, GetJsEntrySp());
  CompileRun("a = 1; b = a + 1;");
  CHECK_EQ(0, GetJsEntrySp());
  CompileRun("js_entry_sp();");
  CHECK_EQ(0, GetJsEntrySp());
  CompileRun("js_entry_sp_level2();");
  CHECK_EQ(0, GetJsEntrySp());
}

#endif  // ENABLE_LOGGING_AND_PROFILING
<commit_msg>Add comments to test-log-stack-tracer.<commit_after>// Copyright 2006-2009 the V8 project authors. All rights reserved.
//
// Tests of profiler-related functions from log.h

#ifdef ENABLE_LOGGING_AND_PROFILING

#include <stdlib.h>

#include "v8.h"

#include "codegen.h"
#include "log.h"
#include "top.h"
#include "cctest.h"
#include "disassembler.h"
#include "register-allocator-inl.h"

using v8::Function;
using v8::Local;
using v8::Object;
using v8::Script;
using v8::String;
using v8::Value;

using v8::internal::byte;
using v8::internal::Address;
using v8::internal::Handle;
using v8::internal::JSFunction;
using v8::internal::StackTracer;
using v8::internal::TickSample;
using v8::internal::Top;

namespace i = v8::internal;

static v8::Persistent<v8::Context> env;

static struct {
  TickSample* sample;
} trace_env = { NULL };

static void InitTraceEnv(TickSample* sample) {
  trace_env.sample = sample;
}

static void DoTrace(Address fp) {
  trace_env.sample->fp = fp;
  // sp is only used to define stack high bound
  trace_env.sample->sp =
      reinterpret_cast<Address>(trace_env.sample) - 10240;
  StackTracer::Trace(trace_env.sample);
}

// Hide c_entry_fp to emulate situation when sampling is done while
// pure JS code is being executed
static void DoTraceHideCEntryFPAddress(Address fp) {
  v8::internal::Address saved_c_frame_fp = *(Top::c_entry_fp_address());
  CHECK(saved_c_frame_fp);
  *(Top::c_entry_fp_address()) = 0;
  DoTrace(fp);
  *(Top::c_entry_fp_address()) = saved_c_frame_fp;
}

static void CheckRetAddrIsInFunction(const char* func_name,
                                     Address ret_addr,
                                     Address func_start_addr,
                                     unsigned int func_len) {
  printf("CheckRetAddrIsInFunction \"%s\": %p %p %p\n",
         func_name, func_start_addr, ret_addr, func_start_addr + func_len);
  CHECK_GE(ret_addr, func_start_addr);
  CHECK_GE(func_start_addr + func_len, ret_addr);
}

static void CheckRetAddrIsInJSFunction(const char* func_name,
                                       Address ret_addr,
                                       Handle<JSFunction> func) {
  v8::internal::Code* func_code = func->code();
  CheckRetAddrIsInFunction(
      func_name, ret_addr,
      func_code->instruction_start(),
      func_code->ExecutableSize());
}

// --- T r a c e   E x t e n s i o n ---

class TraceExtension : public v8::Extension {
 public:
  TraceExtension() : v8::Extension("v8/trace", kSource) { }
  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
      v8::Handle<String> name);
  static v8::Handle<v8::Value> Trace(const v8::Arguments& args);
  static v8::Handle<v8::Value> JSTrace(const v8::Arguments& args);
  static v8::Handle<v8::Value> JSEntrySP(const v8::Arguments& args);
  static v8::Handle<v8::Value> JSEntrySPLevel2(const v8::Arguments& args);
 private:
  static Address GetFP(const v8::Arguments& args);
  static const char* kSource;
};

const char* TraceExtension::kSource =
    "native function trace();"
    "native function js_trace();"
    "native function js_entry_sp();"
    "native function js_entry_sp_level2();";

v8::Handle<v8::FunctionTemplate> TraceExtension::GetNativeFunction(
    v8::Handle<String> name) {
  if (name->Equals(String::New("trace"))) {
    return v8::FunctionTemplate::New(TraceExtension::Trace);
  } else if (name->Equals(String::New("js_trace"))) {
    return v8::FunctionTemplate::New(TraceExtension::JSTrace);
  } else if (name->Equals(String::New("js_entry_sp"))) {
    return v8::FunctionTemplate::New(TraceExtension::JSEntrySP);
  } else if (name->Equals(String::New("js_entry_sp_level2"))) {
    return v8::FunctionTemplate::New(TraceExtension::JSEntrySPLevel2);
  } else {
    CHECK(false);
    return v8::Handle<v8::FunctionTemplate>();
  }
}

Address TraceExtension::GetFP(const v8::Arguments& args) {
  CHECK_EQ(1, args.Length());
  // CodeGenerator::GenerateGetFramePointer pushes EBP / RBP value
  // on stack. In 64-bit mode we can't use Smi operations code because
  // they check that value is within Smi bounds.
  Address fp = *reinterpret_cast<Address*>(*args[0]);
  printf("Trace: %p\n", fp);
  return fp;
}

v8::Handle<v8::Value> TraceExtension::Trace(const v8::Arguments& args) {
  DoTrace(GetFP(args));
  return v8::Undefined();
}

v8::Handle<v8::Value> TraceExtension::JSTrace(const v8::Arguments& args) {
  DoTraceHideCEntryFPAddress(GetFP(args));
  return v8::Undefined();
}

static Address GetJsEntrySp() {
  CHECK_NE(NULL, Top::GetCurrentThread());
  return Top::js_entry_sp(Top::GetCurrentThread());
}

v8::Handle<v8::Value> TraceExtension::JSEntrySP(const v8::Arguments& args) {
  CHECK_NE(0, GetJsEntrySp());
  return v8::Undefined();
}

v8::Handle<v8::Value> TraceExtension::JSEntrySPLevel2(
    const v8::Arguments& args) {
  v8::HandleScope scope;
  const Address js_entry_sp = GetJsEntrySp();
  CHECK_NE(0, js_entry_sp);
  CompileRun("js_entry_sp();");
  CHECK_EQ(js_entry_sp, GetJsEntrySp());
  return v8::Undefined();
}

static TraceExtension kTraceExtension;
v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension);

static void InitializeVM() {
  if (env.IsEmpty()) {
    v8::HandleScope scope;
    const char* extensions[] = { "v8/trace" };
    v8::ExtensionConfiguration config(1, extensions);
    env = v8::Context::New(&config);
  }
  v8::HandleScope scope;
  env->Enter();
}

static Handle<JSFunction> CompileFunction(const char* source) {
  Handle<JSFunction> result(JSFunction::cast(
      *v8::Utils::OpenHandle(*Script::Compile(String::New(source)))));
  return result;
}

static Local<Value> GetGlobalProperty(const char* name) {
  return env->Global()->Get(String::New(name));
}

static Handle<JSFunction> GetGlobalJSFunction(const char* name) {
  Handle<JSFunction> result(JSFunction::cast(
      *v8::Utils::OpenHandle(*GetGlobalProperty(name))));
  return result;
}

static void CheckRetAddrIsInJSFunction(const char* func_name,
                                               Address ret_addr) {
  CheckRetAddrIsInJSFunction(func_name,
                             ret_addr,
                             GetGlobalJSFunction(func_name));
}

static void SetGlobalProperty(const char* name, Local<Value> value) {
  env->Global()->Set(String::New(name), value);
}

static Handle<v8::internal::String> NewString(const char* s) {
  return i::Factory::NewStringFromAscii(i::CStrVector(s));
}

namespace v8 {
namespace internal {

class CodeGeneratorPatcher {
 public:
  CodeGeneratorPatcher() {
    CodeGenerator::InlineRuntimeLUT genGetFramePointer =
        {&CodeGenerator::GenerateGetFramePointer, "_GetFramePointer", 0};
    // _RandomPositiveSmi is not used in our tests. The one we replace need to
    // have the same number of arguments as the one we put in, which is zero in
    // this case.
    bool result = CodeGenerator::PatchInlineRuntimeEntry(
        NewString("_RandomPositiveSmi"),
        genGetFramePointer, &oldInlineEntry);
    CHECK(result);
  }

  ~CodeGeneratorPatcher() {
    CHECK(CodeGenerator::PatchInlineRuntimeEntry(
        NewString("_GetFramePointer"),
        oldInlineEntry, NULL));
  }

 private:
  CodeGenerator::InlineRuntimeLUT oldInlineEntry;
};

} }  // namespace v8::internal

// Creates a global function named 'func_name' that calls the tracing
// function 'trace_func_name' with an actual EBP register value,
// shifted right to be presented as Smi.
static void CreateTraceCallerFunction(const char* func_name,
                                      const char* trace_func_name) {
  i::EmbeddedVector<char, 256> trace_call_buf;
  i::OS::SNPrintF(trace_call_buf, "%s(%%_GetFramePointer());", trace_func_name);

  // Compile the script.
  i::CodeGeneratorPatcher patcher;
  bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
  i::FLAG_allow_natives_syntax = true;
  Handle<JSFunction> func = CompileFunction(trace_call_buf.start());
  CHECK(!func.is_null());
  i::FLAG_allow_natives_syntax = allow_natives_syntax;

#ifdef DEBUG
  v8::internal::Code* func_code = func->code();
  CHECK(func_code->IsCode());
  func_code->Print();
#endif

  SetGlobalProperty(func_name, v8::ToApi<Value>(func));
  CHECK_EQ(*func, *GetGlobalJSFunction(func_name));
}

// This test verifies that stack tracing works when called during
// execution of a native function called from JS code. In this case,
// StackTracer uses Top::c_entry_fp as a starting point for stack
// walking.
TEST(CFromJSStackTrace) {
  TickSample sample;
  InitTraceEnv(&sample);

  InitializeVM();
  v8::HandleScope scope;
  // Create global function JSFuncDoTrace which calls
  // extension function trace() with the current frame pointer value.
  CreateTraceCallerFunction("JSFuncDoTrace", "trace");
  Local<Value> result = CompileRun(
      "function JSTrace() {"
      "         JSFuncDoTrace();"
      "};\n"
      "JSTrace();\n"
      "true;");
  CHECK(!result.IsEmpty());
  // When stack tracer is invoked, the stack should look as follows:
  // script [JS]
  //   JSTrace() [JS]
  //     JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi]
  //       trace(EBP encoded as Smi) [native (extension)]
  //         DoTrace(EBP) [native]
  //           StackTracer::Trace
  CHECK_GT(sample.frames_count, 1);
  // Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
  CheckRetAddrIsInJSFunction("JSFuncDoTrace",
                             sample.stack[0]);
  CheckRetAddrIsInJSFunction("JSTrace",
                             sample.stack[1]);
}

// This test verifies that stack tracing works when called during
// execution of JS code. However, as calling StackTracer requires
// entering native code, we can only emulate pure JS by erasing
// Top::c_entry_fp value. In this case, StackTracer uses passed frame
// pointer value as a starting point for stack walking.
TEST(PureJSStackTrace) {
  TickSample sample;
  InitTraceEnv(&sample);

  InitializeVM();
  v8::HandleScope scope;
  // Create global function JSFuncDoTrace which calls
  // extension function js_trace() with the current frame pointer value.
  CreateTraceCallerFunction("JSFuncDoTrace", "js_trace");
  Local<Value> result = CompileRun(
      "function JSTrace() {"
      "         JSFuncDoTrace();"
      "};\n"
      "function OuterJSTrace() {"
      "         JSTrace();"
      "};\n"
      "OuterJSTrace();\n"
      "true;");
  CHECK(!result.IsEmpty());
  // When stack tracer is invoked, the stack should look as follows:
  // script [JS]
  //   OuterJSTrace() [JS]
  //     JSTrace() [JS]
  //       JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi]
  //         js_trace(EBP encoded as Smi) [native (extension)]
  //           DoTraceHideCEntryFPAddress(EBP) [native]
  //             StackTracer::Trace
  //
  // The last JS function called. It is only visible through
  // sample.function, as its return address is above captured EBP value.
  CHECK_EQ(GetGlobalJSFunction("JSFuncDoTrace")->address(),
           sample.function);
  CHECK_GT(sample.frames_count, 1);
  // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
  CheckRetAddrIsInJSFunction("JSTrace",
                             sample.stack[0]);
  CheckRetAddrIsInJSFunction("OuterJSTrace",
                             sample.stack[1]);
}

static void CFuncDoTrace(byte dummy_parameter) {
  Address fp;
#ifdef __GNUC__
  fp = reinterpret_cast<Address>(__builtin_frame_address(0));
#elif defined _MSC_VER
  // Approximate a frame pointer address. We compile without base pointers,
  // so we can't trust ebp/rbp.
  fp = &dummy_parameter - 2 * sizeof(void*);  // NOLINT
#else
#error Unexpected platform.
#endif
  DoTrace(fp);
}

static int CFunc(int depth) {
  if (depth <= 0) {
    CFuncDoTrace(0);
    return 0;
  } else {
    return CFunc(depth - 1) + 1;
  }
}

// This test verifies that stack tracing doesn't crash when called on
// pure native code. StackTracer only unrolls JS code, so we can't
// get any meaningful info here.
TEST(PureCStackTrace) {
  TickSample sample;
  InitTraceEnv(&sample);
  // Check that sampler doesn't crash
  CHECK_EQ(10, CFunc(10));
}

TEST(JsEntrySp) {
  InitializeVM();
  v8::HandleScope scope;
  CHECK_EQ(0, GetJsEntrySp());
  CompileRun("a = 1; b = a + 1;");
  CHECK_EQ(0, GetJsEntrySp());
  CompileRun("js_entry_sp();");
  CHECK_EQ(0, GetJsEntrySp());
  CompileRun("js_entry_sp_level2();");
  CHECK_EQ(0, GetJsEntrySp());
}

#endif  // ENABLE_LOGGING_AND_PROFILING
<|endoftext|>


<commit_before>#include "common/ceph_crypto.h"

#include "gtest/gtest.h"

class CryptoEnvironment: public ::testing::Environment {
public:
  void SetUp() {
    ceph::crypto::init();
  }
};

::testing::Environment* const crypto_env = ::testing::AddGlobalTestEnvironment(new CryptoEnvironment);

TEST(MD5, DigestSize) {
  int s = ceph::crypto::MD5::DIGESTSIZE;
  ASSERT_EQ(16, s);
}

TEST(MD5, Simple) {
  ceph::crypto::MD5 h;
  h.Update((const byte*)"foo", 3);
  unsigned char digest[ceph::crypto::MD5::DIGESTSIZE];
  h.Final(digest);
  int err;
  unsigned char want_digest[ceph::crypto::MD5::DIGESTSIZE] = {
    0xac, 0xbd, 0x18, 0xdb, 0x4c, 0xc2, 0xf8, 0x5c,
    0xed, 0xef, 0x65, 0x4f, 0xcc, 0xc4, 0xa4, 0xd8,
  };
  err = memcmp(digest, want_digest, ceph::crypto::MD5::DIGESTSIZE);
  ASSERT_EQ(0, err);
}

TEST(MD5, MultiUpdate) {
  ceph::crypto::MD5 h;
  h.Update((const byte*)"", 0);
  h.Update((const byte*)"fo", 2);
  h.Update((const byte*)"", 0);
  h.Update((const byte*)"o", 1);
  h.Update((const byte*)"", 0);
  unsigned char digest[ceph::crypto::MD5::DIGESTSIZE];
  h.Final(digest);
  int err;
  unsigned char want_digest[ceph::crypto::MD5::DIGESTSIZE] = {
    0xac, 0xbd, 0x18, 0xdb, 0x4c, 0xc2, 0xf8, 0x5c,
    0xed, 0xef, 0x65, 0x4f, 0xcc, 0xc4, 0xa4, 0xd8,
  };
  err = memcmp(digest, want_digest, ceph::crypto::MD5::DIGESTSIZE);
  ASSERT_EQ(0, err);
}

TEST(MD5, Restart) {
  ceph::crypto::MD5 h;
  h.Update((const byte*)"bar", 3);
  h.Restart();
  h.Update((const byte*)"foo", 3);
  unsigned char digest[ceph::crypto::MD5::DIGESTSIZE];
  h.Final(digest);
  int err;
  unsigned char want_digest[ceph::crypto::MD5::DIGESTSIZE] = {
    0xac, 0xbd, 0x18, 0xdb, 0x4c, 0xc2, 0xf8, 0x5c,
    0xed, 0xef, 0x65, 0x4f, 0xcc, 0xc4, 0xa4, 0xd8,
  };
  err = memcmp(digest, want_digest, ceph::crypto::MD5::DIGESTSIZE);
  ASSERT_EQ(0, err);
}
<commit_msg>ceph_crypto: Add unittests for the HMAC-SHA1 compatibility shim.<commit_after>#include "common/ceph_crypto.h"

#include "gtest/gtest.h"

class CryptoEnvironment: public ::testing::Environment {
public:
  void SetUp() {
    ceph::crypto::init();
  }
};

::testing::Environment* const crypto_env = ::testing::AddGlobalTestEnvironment(new CryptoEnvironment);

TEST(MD5, DigestSize) {
  int s = ceph::crypto::MD5::DIGESTSIZE;
  ASSERT_EQ(16, s);
}

TEST(MD5, Simple) {
  ceph::crypto::MD5 h;
  h.Update((const byte*)"foo", 3);
  unsigned char digest[ceph::crypto::MD5::DIGESTSIZE];
  h.Final(digest);
  int err;
  unsigned char want_digest[ceph::crypto::MD5::DIGESTSIZE] = {
    0xac, 0xbd, 0x18, 0xdb, 0x4c, 0xc2, 0xf8, 0x5c,
    0xed, 0xef, 0x65, 0x4f, 0xcc, 0xc4, 0xa4, 0xd8,
  };
  err = memcmp(digest, want_digest, ceph::crypto::MD5::DIGESTSIZE);
  ASSERT_EQ(0, err);
}

TEST(MD5, MultiUpdate) {
  ceph::crypto::MD5 h;
  h.Update((const byte*)"", 0);
  h.Update((const byte*)"fo", 2);
  h.Update((const byte*)"", 0);
  h.Update((const byte*)"o", 1);
  h.Update((const byte*)"", 0);
  unsigned char digest[ceph::crypto::MD5::DIGESTSIZE];
  h.Final(digest);
  int err;
  unsigned char want_digest[ceph::crypto::MD5::DIGESTSIZE] = {
    0xac, 0xbd, 0x18, 0xdb, 0x4c, 0xc2, 0xf8, 0x5c,
    0xed, 0xef, 0x65, 0x4f, 0xcc, 0xc4, 0xa4, 0xd8,
  };
  err = memcmp(digest, want_digest, ceph::crypto::MD5::DIGESTSIZE);
  ASSERT_EQ(0, err);
}

TEST(MD5, Restart) {
  ceph::crypto::MD5 h;
  h.Update((const byte*)"bar", 3);
  h.Restart();
  h.Update((const byte*)"foo", 3);
  unsigned char digest[ceph::crypto::MD5::DIGESTSIZE];
  h.Final(digest);
  int err;
  unsigned char want_digest[ceph::crypto::MD5::DIGESTSIZE] = {
    0xac, 0xbd, 0x18, 0xdb, 0x4c, 0xc2, 0xf8, 0x5c,
    0xed, 0xef, 0x65, 0x4f, 0xcc, 0xc4, 0xa4, 0xd8,
  };
  err = memcmp(digest, want_digest, ceph::crypto::MD5::DIGESTSIZE);
  ASSERT_EQ(0, err);
}

TEST(HMACSHA1, DigestSize) {
  int s = ceph::crypto::HMACSHA1::DIGESTSIZE;
  ASSERT_EQ(20, s);
}

TEST(HMACSHA1, Simple) {
  ceph::crypto::HMACSHA1 h((const byte*)"sekrit", 6);
  h.Update((const byte*)"foo", 3);
  unsigned char digest[ceph::crypto::HMACSHA1::DIGESTSIZE];
  h.Final(digest);
  int err;
  unsigned char want_digest[ceph::crypto::HMACSHA1::DIGESTSIZE] = {
    0x04, 0xbc, 0x52, 0x66, 0xb6, 0xff, 0xad, 0xad, 0x9d, 0x57,
    0xce, 0x13, 0xea, 0x8c, 0xf5, 0x6b, 0xf9, 0x95, 0x2f, 0xd6,
  };
  err = memcmp(digest, want_digest, ceph::crypto::HMACSHA1::DIGESTSIZE);
  ASSERT_EQ(0, err);
}

TEST(HMACSHA1, MultiUpdate) {
  ceph::crypto::HMACSHA1 h((const byte*)"sekrit", 6);
  h.Update((const byte*)"", 0);
  h.Update((const byte*)"fo", 2);
  h.Update((const byte*)"", 0);
  h.Update((const byte*)"o", 1);
  h.Update((const byte*)"", 0);
  unsigned char digest[ceph::crypto::HMACSHA1::DIGESTSIZE];
  h.Final(digest);
  int err;
  unsigned char want_digest[ceph::crypto::HMACSHA1::DIGESTSIZE] = {
    0x04, 0xbc, 0x52, 0x66, 0xb6, 0xff, 0xad, 0xad, 0x9d, 0x57,
    0xce, 0x13, 0xea, 0x8c, 0xf5, 0x6b, 0xf9, 0x95, 0x2f, 0xd6,
  };
  err = memcmp(digest, want_digest, ceph::crypto::HMACSHA1::DIGESTSIZE);
  ASSERT_EQ(0, err);
}

TEST(HMACSHA1, Restart) {
  ceph::crypto::HMACSHA1 h((const byte*)"sekrit", 6);
  h.Update((const byte*)"bar", 3);
  h.Restart();
  h.Update((const byte*)"foo", 3);
  unsigned char digest[ceph::crypto::HMACSHA1::DIGESTSIZE];
  h.Final(digest);
  int err;
  unsigned char want_digest[ceph::crypto::HMACSHA1::DIGESTSIZE] = {
    0x04, 0xbc, 0x52, 0x66, 0xb6, 0xff, 0xad, 0xad, 0x9d, 0x57,
    0xce, 0x13, 0xea, 0x8c, 0xf5, 0x6b, 0xf9, 0x95, 0x2f, 0xd6,
  };
  err = memcmp(digest, want_digest, ceph::crypto::HMACSHA1::DIGESTSIZE);
  ASSERT_EQ(0, err);
}
<|endoftext|>