<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 "listviewitems.hxx"
//........................................................................
namespace dbaui
{
//........................................................................

    //========================================================================
    // class OBoldListboxString
    //========================================================================
    //------------------------------------------------------------------------
    void OBoldListboxString::InitViewData( SvTreeListBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* _pViewData)
    {
        SvLBoxString::InitViewData( pView, pEntry, _pViewData );
        if ( !m_bEmphasized )
            return;
        if (!_pViewData)
            _pViewData = pView->GetViewDataItem( pEntry, this );
        pView->Push(PUSH_ALL);
        Font aFont( pView->GetFont());
        aFont.SetWeight(WEIGHT_BOLD);
        pView->SetFont( aFont );
        _pViewData->aSize = Size(pView->GetTextWidth(GetText()), pView->GetTextHeight());
        pView->Pop();
    }

    //------------------------------------------------------------------------
    sal_uInt16 OBoldListboxString::IsA()
    {
        return SV_ITEM_ID_BOLDLBSTRING;
    }

    //------------------------------------------------------------------------
    void OBoldListboxString::Paint(const Point& rPos, SvTreeListBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry )
    {
        if (m_bEmphasized)
        {
            rDev.Push(PUSH_ALL);
            Font aFont( rDev.GetFont());
            aFont.SetWeight(WEIGHT_BOLD);
            rDev.SetFont( aFont );
            Point aPos(rPos);
            rDev.DrawText( aPos, GetText() );
            rDev.Pop();
        }
        else
            SvLBoxString::Paint(rPos, rDev, nFlags, pEntry);
    }

//........................................................................
}   // namespace dbaui
//........................................................................

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Prevent infinite recursion during make 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 "listviewitems.hxx"
//........................................................................
namespace dbaui
{
//........................................................................

    //========================================================================
    // class OBoldListboxString
    //========================================================================
    //------------------------------------------------------------------------
    void OBoldListboxString::InitViewData( SvTreeListBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* _pViewData)
    {
        SvLBoxString::InitViewData( pView, pEntry, _pViewData );
        if ( !m_bEmphasized )
            return;
        if (!_pViewData)
            _pViewData = pView->GetViewDataItem( pEntry, this );
        pView->Push(PUSH_ALL);
        Font aFont( pView->GetFont());
        aFont.SetWeight(WEIGHT_BOLD);
        pView->Control::SetFont( aFont );
        _pViewData->aSize = Size(pView->GetTextWidth(GetText()), pView->GetTextHeight());
        pView->Pop();
    }

    //------------------------------------------------------------------------
    sal_uInt16 OBoldListboxString::IsA()
    {
        return SV_ITEM_ID_BOLDLBSTRING;
    }

    //------------------------------------------------------------------------
    void OBoldListboxString::Paint(const Point& rPos, SvTreeListBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry )
    {
        if (m_bEmphasized)
        {
            rDev.Push(PUSH_ALL);
            Font aFont( rDev.GetFont());
            aFont.SetWeight(WEIGHT_BOLD);
            rDev.SetFont( aFont );
            Point aPos(rPos);
            rDev.DrawText( aPos, GetText() );
            rDev.Pop();
        }
        else
            SvLBoxString::Paint(rPos, rDev, nFlags, pEntry);
    }

//........................................................................
}   // namespace dbaui
//........................................................................

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


<commit_before>/*************************************************************************
 *
 *  $RCSfile: TableUndo.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-19 17:53:05 $
 *
 *  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 DBAUI_TABLEUNDO_HXX
#define DBAUI_TABLEUNDO_HXX

#ifndef DBAUI_GENERALUNDO_HXX
#include "GeneralUndo.hxx"
#endif
#ifndef _SV_MULTISEL_HXX
#include <tools/multisel.hxx>
#endif

#include <vector>

#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif
#ifndef DBAUI_TYPEINFO_HXX
#include "TypeInfo.hxx"
#endif

namespace dbaui
{
    //========================================================================
    class OTableRowView;
    class OTableRow;
    class OTableDesignUndoAct : public OCommentUndoAction
    {
    protected:
        OTableRowView* m_pTabDgnCtrl;

        virtual void    Undo();
        virtual void    Redo();
    public:
        OTableDesignUndoAct( OTableRowView* pOwner ,USHORT nCommentID);
        virtual ~OTableDesignUndoAct();
    };

    //========================================================================
    class OTableEditorCtrl;
    class OTableEditorUndoAct : public OTableDesignUndoAct
    {
    protected:
        OTableEditorCtrl* pTabEdCtrl;

    public:
        OTableEditorUndoAct( OTableEditorCtrl* pOwner,USHORT nCommentID );
        virtual ~OTableEditorUndoAct();
    };

    //========================================================================
    class OTableDesignCellUndoAct : public OTableDesignUndoAct
    {
    protected:
        USHORT  m_nCol;
        long    m_nRow;
        ::com::sun::star::uno::Any  m_sOldText;
        ::com::sun::star::uno::Any  m_sNewText;

        virtual void    Undo();
        virtual void    Redo();
    public:
        OTableDesignCellUndoAct( OTableRowView* pOwner, long nRowID, USHORT nColumn );
        virtual ~OTableDesignCellUndoAct();
    };

    class OTypeInfo;
    //========================================================================
    class OTableEditorTypeSelUndoAct : public OTableEditorUndoAct
    {
    protected:
        USHORT          m_nCol;
        long            m_nRow;
        TOTypeInfoSP    m_pOldType;
        TOTypeInfoSP    m_pNewType;

        virtual void    Undo();
        virtual void    Redo();
    public:
        OTableEditorTypeSelUndoAct( OTableEditorCtrl* pOwner, long nRowID, USHORT nColumn, const TOTypeInfoSP& _pOldType );
        virtual ~OTableEditorTypeSelUndoAct();
    };

    //========================================================================
    class OTableEditorDelUndoAct : public OTableEditorUndoAct
    {
    protected:
        ::std::vector<OTableRow*>   m_aDeletedRows;

        virtual void    Undo();
        virtual void    Redo();
    public:
        OTableEditorDelUndoAct( OTableEditorCtrl* pOwner );
        virtual ~OTableEditorDelUndoAct();
    };

    //========================================================================
    class OTableEditorInsUndoAct : public OTableEditorUndoAct
    {
    protected:
        ::std::vector<OTableRow*>   m_vInsertedRows;
        long                        m_nInsPos;

        virtual void    Undo();
        virtual void    Redo();
    public:
        OTableEditorInsUndoAct( OTableEditorCtrl* pOwner,
                                long nInsertPosition,
                                const ::std::vector< OTableRow*>& _vInsertedRows);
        virtual ~OTableEditorInsUndoAct();
    };

    //========================================================================
    class OTableEditorInsNewUndoAct : public OTableEditorUndoAct
    {
    protected:
        long m_nInsPos;
        long m_nInsRows;

        virtual void    Undo();
        virtual void    Redo();
    public:
        OTableEditorInsNewUndoAct( OTableEditorCtrl* pOwner, long nInsertPosition, long nInsertedRows );
        virtual ~OTableEditorInsNewUndoAct();
    };

    //========================================================================
    class OPrimKeyUndoAct : public OTableEditorUndoAct
    {
    protected:
        MultiSelection      m_aDelKeys,
                            m_aInsKeys;
        BOOL                m_bActPrimKeySet;
        OTableEditorCtrl* m_pEditorCtrl;

        virtual void    Undo();
        virtual void    Redo();
    public:
        OPrimKeyUndoAct( OTableEditorCtrl* pOwner, MultiSelection aDeletedKeys, MultiSelection aInsertedKeys );
        virtual ~OPrimKeyUndoAct();
    };
}
#endif // DBAUI_TABLEUNDO_HXX

<commit_msg>INTEGRATION: CWS dba09 (1.4.172); FILE MERGED 2004/03/18 10:20:35 fs 1.4.172.1: #i24876# +TYPEINFO<commit_after>/*************************************************************************
 *
 *  $RCSfile: TableUndo.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2004-05-10 13:09:33 $
 *
 *  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 DBAUI_TABLEUNDO_HXX
#define DBAUI_TABLEUNDO_HXX

#ifndef DBAUI_GENERALUNDO_HXX
#include "GeneralUndo.hxx"
#endif
#ifndef _SV_MULTISEL_HXX
#include <tools/multisel.hxx>
#endif

#include <vector>

#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif
#ifndef DBAUI_TYPEINFO_HXX
#include "TypeInfo.hxx"
#endif

namespace dbaui
{
    //========================================================================
    class OTableRowView;
    class OTableRow;
    class OTableDesignUndoAct : public OCommentUndoAction
    {
    protected:
        OTableRowView* m_pTabDgnCtrl;

        virtual void    Undo();
        virtual void    Redo();
    public:
        TYPEINFO();
        OTableDesignUndoAct( OTableRowView* pOwner ,USHORT nCommentID);
        virtual ~OTableDesignUndoAct();
    };

    //========================================================================
    class OTableEditorCtrl;
    class OTableEditorUndoAct : public OTableDesignUndoAct
    {
    protected:
        OTableEditorCtrl* pTabEdCtrl;

    public:
        TYPEINFO();
        OTableEditorUndoAct( OTableEditorCtrl* pOwner,USHORT nCommentID );
        virtual ~OTableEditorUndoAct();
    };

    //========================================================================
    class OTableDesignCellUndoAct : public OTableDesignUndoAct
    {
    protected:
        USHORT  m_nCol;
        long    m_nRow;
        ::com::sun::star::uno::Any  m_sOldText;
        ::com::sun::star::uno::Any  m_sNewText;

        virtual void    Undo();
        virtual void    Redo();
    public:
        TYPEINFO();
        OTableDesignCellUndoAct( OTableRowView* pOwner, long nRowID, USHORT nColumn );
        virtual ~OTableDesignCellUndoAct();
    };

    class OTypeInfo;
    //========================================================================
    class OTableEditorTypeSelUndoAct : public OTableEditorUndoAct
    {
    protected:
        USHORT          m_nCol;
        long            m_nRow;
        TOTypeInfoSP    m_pOldType;
        TOTypeInfoSP    m_pNewType;

        virtual void    Undo();
        virtual void    Redo();
    public:
        TYPEINFO();
        OTableEditorTypeSelUndoAct( OTableEditorCtrl* pOwner, long nRowID, USHORT nColumn, const TOTypeInfoSP& _pOldType );
        virtual ~OTableEditorTypeSelUndoAct();
    };

    //========================================================================
    class OTableEditorDelUndoAct : public OTableEditorUndoAct
    {
    protected:
        ::std::vector<OTableRow*>   m_aDeletedRows;

        virtual void    Undo();
        virtual void    Redo();
    public:
        TYPEINFO();
        OTableEditorDelUndoAct( OTableEditorCtrl* pOwner );
        virtual ~OTableEditorDelUndoAct();
    };

    //========================================================================
    class OTableEditorInsUndoAct : public OTableEditorUndoAct
    {
    protected:
        ::std::vector<OTableRow*>   m_vInsertedRows;
        long                        m_nInsPos;

        virtual void    Undo();
        virtual void    Redo();
    public:
        TYPEINFO();
        OTableEditorInsUndoAct( OTableEditorCtrl* pOwner,
                                long nInsertPosition,
                                const ::std::vector< OTableRow*>& _vInsertedRows);
        virtual ~OTableEditorInsUndoAct();
    };

    //========================================================================
    class OTableEditorInsNewUndoAct : public OTableEditorUndoAct
    {
    protected:
        long m_nInsPos;
        long m_nInsRows;

        virtual void    Undo();
        virtual void    Redo();
    public:
        TYPEINFO();
        OTableEditorInsNewUndoAct( OTableEditorCtrl* pOwner, long nInsertPosition, long nInsertedRows );
        virtual ~OTableEditorInsNewUndoAct();
    };

    //========================================================================
    class OPrimKeyUndoAct : public OTableEditorUndoAct
    {
    protected:
        MultiSelection      m_aDelKeys,
                            m_aInsKeys;
        BOOL                m_bActPrimKeySet;
        OTableEditorCtrl* m_pEditorCtrl;

        virtual void    Undo();
        virtual void    Redo();
    public:
        TYPEINFO();
        OPrimKeyUndoAct( OTableEditorCtrl* pOwner, MultiSelection aDeletedKeys, MultiSelection aInsertedKeys );
        virtual ~OPrimKeyUndoAct();
    };
}
#endif // DBAUI_TABLEUNDO_HXX

<|endoftext|>


<commit_before>#include <stdio.h>
#include "longnum_engine.h"
#include <queue>
using namespace std;

int main () {
    unsigned int input;
    std::queue <longnum >q;
    longnum result, tmp;

    do {
        printf("Enter num : ");
        scanf("%u", &input);

        if (input != 0) {
           tmp = int_to_longnum(input);
           q.push(tmp);
        }
    } while (input != 0);

    result = longnum_multinum_sum(q);
    printf("\n");
    longnum_print(result);
    printf("\n");
    longnum_free(result);

    return 0;
}
<commit_msg>Edit longnum_engine-multinum-sum demo program to use new interface of longnum_multinum_sum.<commit_after>#include <stdio.h>
#include "longnum_engine.h"
//#include <queue>
//using namespace std;
#include <stdlib.h>

int main () {
    unsigned int input;
    //std::queue <longnum >q;
    longnum *sum_numbers = NULL;
    unsigned sum_numbers_amount = 0, sum_numbers_limit=0;
    longnum result, tmp;

    sum_numbers_limit = 4;
    sum_numbers = (longnum *) malloc(sum_numbers_limit * sizeof(longnum));

    do {
        printf("Enter num : ");
        scanf("%u", &input);

        if (input != 0) {
           tmp = int_to_longnum(input);
           //q.push(tmp);
           if (sum_numbers_amount == sum_numbers_limit) {
             sum_numbers_limit *= 2;
             sum_numbers = (longnum *) realloc(sum_numbers, sum_numbers_limit * sizeof(longnum));
           }
           sum_numbers[sum_numbers_amount] = tmp;
           sum_numbers_amount++;
        }
    } while (input != 0);

    result = longnum_multinum_sum(/*q*/sum_numbers, sum_numbers_amount);
    printf("\n");
    longnum_print(result);
    printf("\n");
    longnum_free(result);

    return 0;
}
<|endoftext|>


<commit_before>#include "testing/testing.hpp"

#include "partners_api/partners_api_tests/async_gui_thread.hpp"

#include "partners_api/taxi_engine.hpp"
#include "partners_api/uber_api.hpp"
#include "partners_api/yandex_api.hpp"

#include "platform/gui_thread.hpp"

#include "geometry/latlon.hpp"

#include "base/scope_guard.hpp"
#include "base/stl_add.hpp"
#include "base/worker_thread.hpp"

using namespace partners_api;

namespace
{
class BelarusMinskDelegate : public taxi::Delegate
{
public:
  storage::TCountriesVec GetCountryIds(ms::LatLon const & latlon) override { return {"Belarus"}; }

  std::string GetCityName(ms::LatLon const & latlon) override { return "Minsk"; }
};

class UkraineOdessaDelegate : public taxi::Delegate
{
public:
  storage::TCountriesVec GetCountryIds(ms::LatLon const & latlon) override { return {"Ukraine"}; }

  std::string GetCityName(ms::LatLon const & latlon) override { return "Odessa"; }
};

class UsaDelegate : public taxi::Delegate
{
public:
  storage::TCountriesVec GetCountryIds(ms::LatLon const & latlon) override
  {
    return {"United States of America"};
  }

  std::string GetCityName(ms::LatLon const & latlon) override { return ""; }
};

class RussiaKonetsDelegate : public taxi::Delegate
{
public:
  storage::TCountriesVec GetCountryIds(ms::LatLon const & latlon) override
  {
    return {"Russian Federation"};
  }

  std::string GetCityName(ms::LatLon const & latlon) override { return "Konets"; }
};

std::vector<taxi::Product> GetUberSynchronous(ms::LatLon const & from, ms::LatLon const & to,
                                              std::string const & url)
{
  std::string times;
  std::string prices;

  TEST(taxi::uber::RawApi::GetEstimatedTime(from, times, url), ());
  TEST(taxi::uber::RawApi::GetEstimatedPrice(from, to, prices, url), ());

  size_t reqId = 0;
  taxi::uber::ProductMaker maker;
  std::vector<taxi::Product> uberProducts;

  maker.Reset(reqId);
  maker.SetTimes(reqId, times);
  maker.SetPrices(reqId, prices);
  maker.MakeProducts(
      reqId, [&uberProducts](vector<taxi::Product> const & products) { uberProducts = products; },
      [](taxi::ErrorCode const code) { TEST(false, (code)); });

  return uberProducts;
}

std::vector<taxi::Product> GetYandexSynchronous(ms::LatLon const & from, ms::LatLon const & to,
                                                std::string const & url)
{
  std::string yandexAnswer;
  std::vector<taxi::Product> yandexProducts;

  TEST(taxi::yandex::RawApi::GetTaxiInfo(from, to, yandexAnswer, url), ());

  taxi::yandex::MakeFromJson(yandexAnswer, yandexProducts);

  return yandexProducts;
}

taxi::ProvidersContainer GetProvidersSynchronous(taxi::Engine const & engine,
                                                 ms::LatLon const & from, ms::LatLon const & to,
                                                 std::string const & url)
{
  taxi::ProvidersContainer providers;

  for (auto const provider : engine.GetProvidersAtPos(from))
  {
    switch (provider)
    {
    case taxi::Provider::Type::Uber:
      providers.emplace_back(taxi::Provider::Type::Uber, GetUberSynchronous(from, to, url));
      break;
    case taxi::Provider::Type::Yandex:
      providers.emplace_back(taxi::Provider::Type::Yandex, GetYandexSynchronous(from, to, url));
      break;
    }
  }

  return providers;
}

bool CompareProviders(taxi::ProvidersContainer const & lhs, taxi::ProvidersContainer const & rhs)
{
  TEST_EQUAL(rhs.size(), lhs.size(), ());

  auto const Match = [](taxi::Provider const & lhs, taxi::Provider const & rhs) -> bool {
    if (lhs.GetType() != rhs.GetType())
      return false;

    auto const & lps = lhs.GetProducts();
    auto const & rps = rhs.GetProducts();

    TEST_EQUAL(lps.size(), rps.size(), ());

    for (auto const & lp : lps)
    {
      auto const it = std::find_if(rps.cbegin(), rps.cend(), [&lp](taxi::Product const & rp) {
        return lp.m_productId == rp.m_productId && lp.m_name == rp.m_name &&
               lp.m_price == rp.m_price;
      });

      if (it == rps.cend())
        return false;
    }

    return true;
  };

  auto const m = lhs.size();

  vector<bool> used(m);
  // TODO (@y) Change it to algorithm, based on bipartite graphs.
  for (auto const & rItem : rhs)
  {
    bool isMatched = false;
    for (size_t i = 0; i < m; ++i)
    {
      if (used[i])
        continue;

      if (Match(rItem, lhs[i]))
      {
        used[i] = true;
        isMatched = true;
        break;
      }
    }

    if (!isMatched)
      return false;
  }
  return true;
}

UNIT_CLASS_TEST(AsyncGuiThread, TaxiEngine_ResultMaker)
{
  taxi::ResultMaker maker;
  uint64_t reqId = 1;
  taxi::ProvidersContainer providers;
  taxi::ErrorsContainer errors;

  auto const successCallback = [&reqId, &providers](taxi::ProvidersContainer const & products,
                                                    uint64_t const requestId) {
    TEST_EQUAL(reqId, requestId, ());
    providers = products;
    testing::Notify();
  };

  auto const successNotPossibleCallback =
      [&reqId, &providers](taxi::ProvidersContainer const & products, uint64_t const requestId) {
        TEST(false, ("successNotPossibleCallback", requestId));
      };

  auto const errorCallback = [&reqId, &errors](taxi::ErrorsContainer const e,
                                               uint64_t const requestId) {
    TEST_EQUAL(reqId, requestId, ());
    errors = e;
    testing::Notify();
  };

  auto const errorNotPossibleCallback = [&reqId](taxi::ErrorsContainer const errors,
                                                 uint64_t const requestId) {
    TEST(false, ("errorNotPossibleCallback", requestId, errors));
  };

  // Try to image what products1 and products2 are lists of products for different taxi providers.
  // Only product id is important for us, all other fields are empty.
  std::vector<taxi::Product> products1 =
  {
    {"1", "", "", "", ""},
    {"2", "", "", "", ""},
    {"3", "", "", "", ""},
  };

  std::vector<taxi::Product> products2 =
  {
    {"4", "", "", "", ""},
    {"5", "", "", "", ""},
    {"6", "", "", "", ""},
  };

  maker.Reset(reqId, 2, successCallback, errorNotPossibleCallback);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Uber, products1);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Yandex, products2);

  TEST(providers.empty(), ());
  TEST(errors.empty(), ());

  maker.Reset(reqId, 3, successCallback, errorNotPossibleCallback);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Uber, products1);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Yandex, products2);
  maker.DecrementRequestCount(reqId);
  maker.MakeResult(reqId);

  testing::Wait();

  TEST_EQUAL(providers.size(), 2, ());
  TEST_EQUAL(providers[0].GetType(), taxi::Provider::Type::Uber, ());
  TEST_EQUAL(providers[1].GetType(), taxi::Provider::Type::Yandex, ());
  TEST_EQUAL(providers[0][0].m_productId, "1", ());
  TEST_EQUAL(providers[0][1].m_productId, "2", ());
  TEST_EQUAL(providers[0][2].m_productId, "3", ());
  TEST_EQUAL(providers[1][0].m_productId, "4", ());
  TEST_EQUAL(providers[1][1].m_productId, "5", ());
  TEST_EQUAL(providers[1][2].m_productId, "6", ());

  maker.Reset(reqId, 2, successCallback, errorNotPossibleCallback);
  maker.ProcessError(reqId, taxi::Provider::Type::Uber, taxi::ErrorCode::NoProducts);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Yandex, products2);
  maker.MakeResult(reqId);

  testing::Wait();

  TEST_EQUAL(providers.size(), 1, ());
  TEST_EQUAL(providers[0].GetType(), taxi::Provider::Type::Yandex, ());
  TEST_EQUAL(providers[0][0].m_productId, "4", ());
  TEST_EQUAL(providers[0][1].m_productId, "5", ());
  TEST_EQUAL(providers[0][2].m_productId, "6", ());

  maker.Reset(reqId, 2, successNotPossibleCallback, errorCallback);
  maker.ProcessError(reqId, taxi::Provider::Type::Uber, taxi::ErrorCode::NoProducts);
  maker.ProcessError(reqId, taxi::Provider::Type::Yandex, taxi::ErrorCode::RemoteError);
  maker.MakeResult(reqId);

  testing::Wait();

  TEST_EQUAL(errors.size(), 2, ());
  TEST_EQUAL(errors[0].m_type, taxi::Provider::Type::Uber, ());
  TEST_EQUAL(errors[0].m_code, taxi::ErrorCode::NoProducts, ());
  TEST_EQUAL(errors[1].m_type, taxi::Provider::Type::Yandex, ());
  TEST_EQUAL(errors[1].m_code, taxi::ErrorCode::RemoteError, ());

  maker.Reset(reqId, 2, successCallback, errorNotPossibleCallback);
  maker.DecrementRequestCount(reqId);
  maker.DecrementRequestCount(reqId);
  maker.MakeResult(reqId);

  testing::Wait();
}

UNIT_CLASS_TEST(AsyncGuiThread, TaxiEngine_Smoke)
{
  // Used to synchronize access into GetAvailableProducts callback method.
  std::mutex resultsMutex;
  size_t reqId = 1;
  taxi::ProvidersContainer providersContainer;
  ms::LatLon const from(38.897724, -77.036531);
  ms::LatLon const to(38.862416, -76.883316);
  std::string const kTesturl = "http://localhost:34568/partners";

  auto const errorCallback = [](taxi::ErrorsContainer const & errors, uint64_t const requestId) {
    TEST(false, ());
  };

  auto const errorPossibleCallback = [](taxi::ErrorsContainer const & errors,
                                        uint64_t const requestId) {
    for (auto const & error : errors)
      TEST(error.m_code == taxi::ErrorCode::NoProducts, ());
  };

  auto const standardCallback = [&reqId, &providersContainer, &resultsMutex](
                                    taxi::ProvidersContainer const & providers,
                                    uint64_t const requestId) {
    std::lock_guard<std::mutex> lock(resultsMutex);

    if (reqId == requestId)
      providersContainer = providers;
  };

  auto const lastCallback = [&standardCallback](taxi::ProvidersContainer const & products,
                                                uint64_t const requestId) {
    standardCallback(products, requestId);
    testing::StopEventLoop();
  };

  taxi::Engine engine(
      {{taxi::Provider::Type::Uber, kTesturl}, {taxi::Provider::Type::Yandex, kTesturl}});

  engine.SetDelegate(my::make_unique<BelarusMinskDelegate>());

  taxi::ProvidersContainer const synchronousProviders =
      GetProvidersSynchronous(engine, from, to, kTesturl);

  TEST(!synchronousProviders.empty(), ());

  {
    {
      lock_guard<mutex> lock(resultsMutex);
      reqId = engine.GetAvailableProducts(ms::LatLon(55.753960, 37.624513),
                                          ms::LatLon(55.765866, 37.661270), standardCallback,
                                          errorPossibleCallback);
    }
    {
      lock_guard<mutex> lock(resultsMutex);
      reqId = engine.GetAvailableProducts(ms::LatLon(59.922445, 30.367201),
                                          ms::LatLon(59.943675, 30.361123), standardCallback,
                                          errorPossibleCallback);
    }
    {
      lock_guard<mutex> lock(resultsMutex);
      reqId = engine.GetAvailableProducts(ms::LatLon(52.509621, 13.450067),
                                          ms::LatLon(52.510811, 13.409490), standardCallback,
                                          errorPossibleCallback);
    }
    {
      lock_guard<mutex> lock(resultsMutex);
      reqId = engine.GetAvailableProducts(from, to, lastCallback, errorCallback);
    }
  }

  testing::RunEventLoop();

  TEST(!providersContainer.empty(), ());
  TEST(CompareProviders(providersContainer, synchronousProviders), ());
}

UNIT_TEST(TaxiEngine_GetProvidersAtPos)
{
  taxi::Engine engine;
  // Lat lon is no needed for this test.
  ms::LatLon latlon(0.0, 0.0);
  std::vector<taxi::Provider::Type> providers;

  engine.SetDelegate(my::make_unique<BelarusMinskDelegate>());
  providers = engine.GetProvidersAtPos(latlon);
  TEST_EQUAL(providers.size(), 1, ());
  TEST_EQUAL(providers[0], taxi::Provider::Type::Yandex, ());

  engine.SetDelegate(my::make_unique<UkraineOdessaDelegate>());
  providers = engine.GetProvidersAtPos(latlon);
  TEST_EQUAL(providers.size(), 1, ());
  TEST_EQUAL(providers[0], taxi::Provider::Type::Uber, ());

  engine.SetDelegate(my::make_unique<UsaDelegate>());
  providers = engine.GetProvidersAtPos(latlon);
  TEST_EQUAL(providers.size(), 1, ());
  TEST_EQUAL(providers[0], taxi::Provider::Type::Uber, ());

  engine.SetDelegate(my::make_unique<RussiaKonetsDelegate>());
  providers = engine.GetProvidersAtPos(latlon);
  TEST(providers.empty(), (providers));
}
}  // namespace
<commit_msg>[partners_api] taxi engine test fix<commit_after>#include "testing/testing.hpp"

#include "partners_api/partners_api_tests/async_gui_thread.hpp"

#include "partners_api/taxi_engine.hpp"
#include "partners_api/uber_api.hpp"
#include "partners_api/yandex_api.hpp"

#include "platform/gui_thread.hpp"

#include "geometry/latlon.hpp"

#include "base/scope_guard.hpp"
#include "base/stl_add.hpp"
#include "base/worker_thread.hpp"

using namespace partners_api;

namespace
{
class BelarusMinskDelegate : public taxi::Delegate
{
public:
  storage::TCountriesVec GetCountryIds(ms::LatLon const & latlon) override { return {"Belarus"}; }

  std::string GetCityName(ms::LatLon const & latlon) override { return "Minsk"; }
};

class UkraineOdessaDelegate : public taxi::Delegate
{
public:
  storage::TCountriesVec GetCountryIds(ms::LatLon const & latlon) override { return {"Ukraine"}; }

  std::string GetCityName(ms::LatLon const & latlon) override { return "Odessa"; }
};

class BulgariaSofiaDelegate : public taxi::Delegate
{
public:
  storage::TCountriesVec GetCountryIds(ms::LatLon const & latlon) override { return {"Bulgaria"}; }

  std::string GetCityName(ms::LatLon const & latlon) override { return "Sofia"; }
};

class UsaDelegate : public taxi::Delegate
{
public:
  storage::TCountriesVec GetCountryIds(ms::LatLon const & latlon) override
  {
    return {"United States of America"};
  }

  std::string GetCityName(ms::LatLon const & latlon) override { return ""; }
};

class RussiaKonetsDelegate : public taxi::Delegate
{
public:
  storage::TCountriesVec GetCountryIds(ms::LatLon const & latlon) override
  {
    return {"Russian Federation"};
  }

  std::string GetCityName(ms::LatLon const & latlon) override { return "Konets"; }
};

std::vector<taxi::Product> GetUberSynchronous(ms::LatLon const & from, ms::LatLon const & to,
                                              std::string const & url)
{
  std::string times;
  std::string prices;

  TEST(taxi::uber::RawApi::GetEstimatedTime(from, times, url), ());
  TEST(taxi::uber::RawApi::GetEstimatedPrice(from, to, prices, url), ());

  size_t reqId = 0;
  taxi::uber::ProductMaker maker;
  std::vector<taxi::Product> uberProducts;

  maker.Reset(reqId);
  maker.SetTimes(reqId, times);
  maker.SetPrices(reqId, prices);
  maker.MakeProducts(
      reqId, [&uberProducts](vector<taxi::Product> const & products) { uberProducts = products; },
      [](taxi::ErrorCode const code) { TEST(false, (code)); });

  return uberProducts;
}

std::vector<taxi::Product> GetYandexSynchronous(ms::LatLon const & from, ms::LatLon const & to,
                                                std::string const & url)
{
  std::string yandexAnswer;
  std::vector<taxi::Product> yandexProducts;

  TEST(taxi::yandex::RawApi::GetTaxiInfo(from, to, yandexAnswer, url), ());

  taxi::yandex::MakeFromJson(yandexAnswer, yandexProducts);

  return yandexProducts;
}

taxi::ProvidersContainer GetProvidersSynchronous(taxi::Engine const & engine,
                                                 ms::LatLon const & from, ms::LatLon const & to,
                                                 std::string const & url)
{
  taxi::ProvidersContainer providers;

  for (auto const provider : engine.GetProvidersAtPos(from))
  {
    switch (provider)
    {
    case taxi::Provider::Type::Uber:
      providers.emplace_back(taxi::Provider::Type::Uber, GetUberSynchronous(from, to, url));
      break;
    case taxi::Provider::Type::Yandex:
      providers.emplace_back(taxi::Provider::Type::Yandex, GetYandexSynchronous(from, to, url));
      break;
    }
  }

  return providers;
}

bool CompareProviders(taxi::ProvidersContainer const & lhs, taxi::ProvidersContainer const & rhs)
{
  TEST_EQUAL(rhs.size(), lhs.size(), ());

  auto const Match = [](taxi::Provider const & lhs, taxi::Provider const & rhs) -> bool {
    if (lhs.GetType() != rhs.GetType())
      return false;

    auto const & lps = lhs.GetProducts();
    auto const & rps = rhs.GetProducts();

    TEST_EQUAL(lps.size(), rps.size(), ());

    for (auto const & lp : lps)
    {
      auto const it = std::find_if(rps.cbegin(), rps.cend(), [&lp](taxi::Product const & rp) {
        return lp.m_productId == rp.m_productId && lp.m_name == rp.m_name &&
               lp.m_price == rp.m_price;
      });

      if (it == rps.cend())
        return false;
    }

    return true;
  };

  auto const m = lhs.size();

  vector<bool> used(m);
  // TODO (@y) Change it to algorithm, based on bipartite graphs.
  for (auto const & rItem : rhs)
  {
    bool isMatched = false;
    for (size_t i = 0; i < m; ++i)
    {
      if (used[i])
        continue;

      if (Match(rItem, lhs[i]))
      {
        used[i] = true;
        isMatched = true;
        break;
      }
    }

    if (!isMatched)
      return false;
  }
  return true;
}

UNIT_CLASS_TEST(AsyncGuiThread, TaxiEngine_ResultMaker)
{
  taxi::ResultMaker maker;
  uint64_t reqId = 1;
  taxi::ProvidersContainer providers;
  taxi::ErrorsContainer errors;

  auto const successCallback = [&reqId, &providers](taxi::ProvidersContainer const & products,
                                                    uint64_t const requestId) {
    TEST_EQUAL(reqId, requestId, ());
    providers = products;
    testing::Notify();
  };

  auto const successNotPossibleCallback =
      [&reqId, &providers](taxi::ProvidersContainer const & products, uint64_t const requestId) {
        TEST(false, ("successNotPossibleCallback", requestId));
      };

  auto const errorCallback = [&reqId, &errors](taxi::ErrorsContainer const e,
                                               uint64_t const requestId) {
    TEST_EQUAL(reqId, requestId, ());
    errors = e;
    testing::Notify();
  };

  auto const errorNotPossibleCallback = [&reqId](taxi::ErrorsContainer const errors,
                                                 uint64_t const requestId) {
    TEST(false, ("errorNotPossibleCallback", requestId, errors));
  };

  // Try to image what products1 and products2 are lists of products for different taxi providers.
  // Only product id is important for us, all other fields are empty.
  std::vector<taxi::Product> products1 =
  {
    {"1", "", "", "", ""},
    {"2", "", "", "", ""},
    {"3", "", "", "", ""},
  };

  std::vector<taxi::Product> products2 =
  {
    {"4", "", "", "", ""},
    {"5", "", "", "", ""},
    {"6", "", "", "", ""},
  };

  maker.Reset(reqId, 2, successCallback, errorNotPossibleCallback);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Uber, products1);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Yandex, products2);

  TEST(providers.empty(), ());
  TEST(errors.empty(), ());

  maker.Reset(reqId, 3, successCallback, errorNotPossibleCallback);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Uber, products1);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Yandex, products2);
  maker.DecrementRequestCount(reqId);
  maker.MakeResult(reqId);

  testing::Wait();

  TEST_EQUAL(providers.size(), 2, ());
  TEST_EQUAL(providers[0].GetType(), taxi::Provider::Type::Uber, ());
  TEST_EQUAL(providers[1].GetType(), taxi::Provider::Type::Yandex, ());
  TEST_EQUAL(providers[0][0].m_productId, "1", ());
  TEST_EQUAL(providers[0][1].m_productId, "2", ());
  TEST_EQUAL(providers[0][2].m_productId, "3", ());
  TEST_EQUAL(providers[1][0].m_productId, "4", ());
  TEST_EQUAL(providers[1][1].m_productId, "5", ());
  TEST_EQUAL(providers[1][2].m_productId, "6", ());

  maker.Reset(reqId, 2, successCallback, errorNotPossibleCallback);
  maker.ProcessError(reqId, taxi::Provider::Type::Uber, taxi::ErrorCode::NoProducts);
  maker.ProcessProducts(reqId, taxi::Provider::Type::Yandex, products2);
  maker.MakeResult(reqId);

  testing::Wait();

  TEST_EQUAL(providers.size(), 1, ());
  TEST_EQUAL(providers[0].GetType(), taxi::Provider::Type::Yandex, ());
  TEST_EQUAL(providers[0][0].m_productId, "4", ());
  TEST_EQUAL(providers[0][1].m_productId, "5", ());
  TEST_EQUAL(providers[0][2].m_productId, "6", ());

  maker.Reset(reqId, 2, successNotPossibleCallback, errorCallback);
  maker.ProcessError(reqId, taxi::Provider::Type::Uber, taxi::ErrorCode::NoProducts);
  maker.ProcessError(reqId, taxi::Provider::Type::Yandex, taxi::ErrorCode::RemoteError);
  maker.MakeResult(reqId);

  testing::Wait();

  TEST_EQUAL(errors.size(), 2, ());
  TEST_EQUAL(errors[0].m_type, taxi::Provider::Type::Uber, ());
  TEST_EQUAL(errors[0].m_code, taxi::ErrorCode::NoProducts, ());
  TEST_EQUAL(errors[1].m_type, taxi::Provider::Type::Yandex, ());
  TEST_EQUAL(errors[1].m_code, taxi::ErrorCode::RemoteError, ());

  maker.Reset(reqId, 2, successCallback, errorNotPossibleCallback);
  maker.DecrementRequestCount(reqId);
  maker.DecrementRequestCount(reqId);
  maker.MakeResult(reqId);

  testing::Wait();
}

UNIT_CLASS_TEST(AsyncGuiThread, TaxiEngine_Smoke)
{
  // Used to synchronize access into GetAvailableProducts callback method.
  std::mutex resultsMutex;
  size_t reqId = 1;
  taxi::ProvidersContainer providersContainer;
  ms::LatLon const from(38.897724, -77.036531);
  ms::LatLon const to(38.862416, -76.883316);
  std::string const kTesturl = "http://localhost:34568/partners";

  auto const errorCallback = [](taxi::ErrorsContainer const & errors, uint64_t const requestId) {
    TEST(false, ());
  };

  auto const errorPossibleCallback = [](taxi::ErrorsContainer const & errors,
                                        uint64_t const requestId) {
    for (auto const & error : errors)
      TEST(error.m_code == taxi::ErrorCode::NoProducts, ());
  };

  auto const standardCallback = [&reqId, &providersContainer, &resultsMutex](
                                    taxi::ProvidersContainer const & providers,
                                    uint64_t const requestId) {
    std::lock_guard<std::mutex> lock(resultsMutex);

    if (reqId == requestId)
      providersContainer = providers;
  };

  auto const lastCallback = [&standardCallback](taxi::ProvidersContainer const & products,
                                                uint64_t const requestId) {
    standardCallback(products, requestId);
    testing::StopEventLoop();
  };

  taxi::Engine engine(
      {{taxi::Provider::Type::Uber, kTesturl}, {taxi::Provider::Type::Yandex, kTesturl}});

  engine.SetDelegate(my::make_unique<BelarusMinskDelegate>());

  taxi::ProvidersContainer const synchronousProviders =
      GetProvidersSynchronous(engine, from, to, kTesturl);

  TEST(!synchronousProviders.empty(), ());

  {
    {
      lock_guard<mutex> lock(resultsMutex);
      reqId = engine.GetAvailableProducts(ms::LatLon(55.753960, 37.624513),
                                          ms::LatLon(55.765866, 37.661270), standardCallback,
                                          errorPossibleCallback);
    }
    {
      lock_guard<mutex> lock(resultsMutex);
      reqId = engine.GetAvailableProducts(ms::LatLon(59.922445, 30.367201),
                                          ms::LatLon(59.943675, 30.361123), standardCallback,
                                          errorPossibleCallback);
    }
    {
      lock_guard<mutex> lock(resultsMutex);
      reqId = engine.GetAvailableProducts(ms::LatLon(52.509621, 13.450067),
                                          ms::LatLon(52.510811, 13.409490), standardCallback,
                                          errorPossibleCallback);
    }
    {
      lock_guard<mutex> lock(resultsMutex);
      reqId = engine.GetAvailableProducts(from, to, lastCallback, errorCallback);
    }
  }

  testing::RunEventLoop();

  TEST(!providersContainer.empty(), ());
  TEST(CompareProviders(providersContainer, synchronousProviders), ());
}

UNIT_TEST(TaxiEngine_GetProvidersAtPos)
{
  taxi::Engine engine;
  // Lat lon is no needed for this test.
  ms::LatLon latlon(0.0, 0.0);
  std::vector<taxi::Provider::Type> providers;

  engine.SetDelegate(my::make_unique<BelarusMinskDelegate>());
  providers = engine.GetProvidersAtPos(latlon);
  TEST_EQUAL(providers.size(), 1, ());
  TEST_EQUAL(providers[0], taxi::Provider::Type::Yandex, ());

  engine.SetDelegate(my::make_unique<UkraineOdessaDelegate>());
  providers = engine.GetProvidersAtPos(latlon);
  TEST_EQUAL(providers.size(), 1, ());
  TEST_EQUAL(providers[0], taxi::Provider::Type::Yandex, ());

  engine.SetDelegate(my::make_unique<BulgariaSofiaDelegate>());
  providers = engine.GetProvidersAtPos(latlon);
  TEST_EQUAL(providers.size(), 1, ());
  TEST_EQUAL(providers[0], taxi::Provider::Type::Uber, ());

  engine.SetDelegate(my::make_unique<UsaDelegate>());
  providers = engine.GetProvidersAtPos(latlon);
  TEST_EQUAL(providers.size(), 1, ());
  TEST_EQUAL(providers[0], taxi::Provider::Type::Uber, ());

  engine.SetDelegate(my::make_unique<RussiaKonetsDelegate>());
  providers = engine.GetProvidersAtPos(latlon);
  TEST(providers.empty(), (providers));
}
}  // namespace
<|endoftext|>


<commit_before>/*------------------------------------------------------------------------------
 *
 *  This file is part of rendermq
 *
 *  Author: matt.amos@mapquest.com
 *
 *  Copyright 2010-1 Mapquest, Inc.  All Rights reserved.
 *
 *
 * 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.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *-----------------------------------------------------------------------------*/

#include "common.hpp"
#include "../logging/logger.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <stdexcept>
#include <iomanip>
#include <iostream>

#ifdef HAVE_BLACKBOX
#include <logging/bb_logger.hpp>
#endif

using boost::function;
using std::runtime_error;
using std::exception;
using std::cout;
using std::clog;
using std::cerr;
using std::endl;
using std::setw;
using std::flush;
using std::string;
using std::vector;
namespace fs = boost::filesystem;

#define TEST_NAME_WIDTH (45)

namespace {

void run_with_output_redirected_to(const string &name, function<void ()> test) {
  // create a file for the output to go to.
  string file_name = string("log/") + name + ".testlog";

#ifdef HAVE_BLACKBOX
  ::blackbox::logging::log::configure(conf);
#endif

  // run the test
  test();
}

}

namespace test {

int run(const string &name, function<void ()> test) {
  cout << setw(TEST_NAME_WIDTH) << name << flush;
  try {
    run_with_output_redirected_to(name, test);
    cout << "  [PASS]" << endl;
    return 0;

  } catch (const exception &ex) {
    cout << "  [FAIL: " << ex.what() << "]" << endl;
    return 1;

  } catch (...) {
    cerr << "  [FAIL: Unexpected error]" << endl;
    throw;
  }
}

json::json() : m_type(json::type_NONE) {}
json::json(const json &j) : m_type(j.m_type), m_buf(j.m_buf.str()) {}

std::ostream &operator<<(std::ostream &out, const json &j) {
   if (j.m_type == json::type_NONE) {
      out << "null";

   } else {
      out << j.m_buf.str();
      if (j.m_type == json::type_DICT) {
         out << "}";
      } else {
         out << "]";
      }
   }
   return out;
}

void json::quote(const json &j) { m_buf << j; }
void json::quote(const std::string &s) { m_buf << "\"" << s << "\""; }
void json::quote(int i) { m_buf << i; }
void json::quote(double d) { m_buf << d; }

temp_dir::temp_dir()
   : m_path(fs::temp_directory_path() / fs::unique_path("nms-test-%%%%-%%%%-%%%%-%%%%")) {
   fs::create_directories(m_path);
}

temp_dir::~temp_dir() {
   // files might be deleted by other things while this is running
   // (0MQ context thread, i'm looking at you), and this isn't
   // necessarily an error as far as this code is concerned - it
   // just wants to delete everything underneath the temporary
   // directory.
   boost::system::error_code err;

   // catch all errors - we don't want to throw in the destructor
   try {
      // but loop while the path exists and the errors are
      // ignorable.
      while (fs::exists(m_path)) {
         fs::remove_all(m_path, err);

         // for any non-ignorable error, there's not much we can
         // do from the destructor except complain loudly.
         if (err && (err != boost::system::errc::no_such_file_or_directory)) {
            LOG_WARNING(boost::format("Unable to remove temporary "
                                      "directory %1%: %2%")
                        % m_path % err.message());
            break;
         }
      }

   } catch (const std::exception &e) {
      LOG_ERROR(boost::format("Exception caught while trying to remove "
                              "temporary directory %1%: %2%")
                % m_path % e.what());

   } catch (...) {
      LOG_ERROR(boost::format("Unknown exception caught while trying to "
                              "remove temporary directory %1%")
                % m_path);
   }
}

}
<commit_msg>Remove blackbox references from logging common<commit_after>/*------------------------------------------------------------------------------
 *
 *  This file is part of avecado
 *
 *  Author: matt.amos@mapquest.com
 *
 *  Copyright 2010-1 Mapquest, Inc.  All Rights reserved.
 *
 *
 * 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.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *-----------------------------------------------------------------------------*/

#include "common.hpp"
#include "../logging/logger.hpp"
#include <boost/property_tree/ptree.hpp>
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <stdexcept>
#include <iomanip>
#include <iostream>

using boost::function;
using std::runtime_error;
using std::exception;
using std::cout;
using std::clog;
using std::cerr;
using std::endl;
using std::setw;
using std::flush;
using std::string;
using std::vector;
namespace fs = boost::filesystem;

#define TEST_NAME_WIDTH (45)

namespace {

void run_with_output_redirected_to(const string &name, function<void ()> test) {
  // create a file for the output to go to.
  string file_name = string("log/") + name + ".testlog";

  // run the test
  test();
}

}

namespace test {

int run(const string &name, function<void ()> test) {
  cout << setw(TEST_NAME_WIDTH) << name << flush;
  try {
    run_with_output_redirected_to(name, test);
    cout << "  [PASS]" << endl;
    return 0;

  } catch (const exception &ex) {
    cout << "  [FAIL: " << ex.what() << "]" << endl;
    return 1;

  } catch (...) {
    cerr << "  [FAIL: Unexpected error]" << endl;
    throw;
  }
}

json::json() : m_type(json::type_NONE) {}
json::json(const json &j) : m_type(j.m_type), m_buf(j.m_buf.str()) {}

std::ostream &operator<<(std::ostream &out, const json &j) {
   if (j.m_type == json::type_NONE) {
      out << "null";

   } else {
      out << j.m_buf.str();
      if (j.m_type == json::type_DICT) {
         out << "}";
      } else {
         out << "]";
      }
   }
   return out;
}

void json::quote(const json &j) { m_buf << j; }
void json::quote(const std::string &s) { m_buf << "\"" << s << "\""; }
void json::quote(int i) { m_buf << i; }
void json::quote(double d) { m_buf << d; }

temp_dir::temp_dir()
   : m_path(fs::temp_directory_path() / fs::unique_path("nms-test-%%%%-%%%%-%%%%-%%%%")) {
   fs::create_directories(m_path);
}

temp_dir::~temp_dir() {
   // files might be deleted by other things while this is running
   // (0MQ context thread, i'm looking at you), and this isn't
   // necessarily an error as far as this code is concerned - it
   // just wants to delete everything underneath the temporary
   // directory.
   boost::system::error_code err;

   // catch all errors - we don't want to throw in the destructor
   try {
      // but loop while the path exists and the errors are
      // ignorable.
      while (fs::exists(m_path)) {
         fs::remove_all(m_path, err);

         // for any non-ignorable error, there's not much we can
         // do from the destructor except complain loudly.
         if (err && (err != boost::system::errc::no_such_file_or_directory)) {
            LOG_WARNING(boost::format("Unable to remove temporary "
                                      "directory %1%: %2%")
                        % m_path % err.message());
            break;
         }
      }

   } catch (const std::exception &e) {
      LOG_ERROR(boost::format("Exception caught while trying to remove "
                              "temporary directory %1%: %2%")
                % m_path % e.what());

   } catch (...) {
      LOG_ERROR(boost::format("Unknown exception caught while trying to "
                              "remove temporary directory %1%")
                % m_path);
   }
}

}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2016 Couchbase, Inc.
 *
 *   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 "config.h"
#include "subdocument_context.h"
#include "debug_helpers.h"
#include "mc_time.h"
#include "protocol/mcbp/engine_wrapper.h"
#include "subdocument.h"

#include <utilities/logtags.h>
#include <xattr/blob.h>

#include <iomanip>
#include <random>
#include <sstream>
#include <utilities/string_utilities.h>

SubdocCmdContext::OperationSpec::OperationSpec(SubdocCmdTraits traits_,
                                               protocol_binary_subdoc_flag flags_,
                                               cb::const_char_buffer path_)
    : SubdocCmdContext::OperationSpec::OperationSpec(traits_, flags_, path_,
                                                     {nullptr, 0}) {
}

SubdocCmdContext::OperationSpec::OperationSpec(SubdocCmdTraits traits_,
                                               protocol_binary_subdoc_flag flags_,
                                               cb::const_char_buffer path_,
                                               cb::const_char_buffer value_)
    : traits(traits_),
      flags(flags_),
      path(path_),
      value(value_),
      status(PROTOCOL_BINARY_RESPONSE_EINTERNAL) {
    if (flags & SUBDOC_FLAG_MKDIR_P) {
        traits.subdocCommand = Subdoc::Command(traits.subdocCommand |
                                               Subdoc::Command::FLAG_MKDIR_P);
    }
}

SubdocCmdContext::OperationSpec::OperationSpec(OperationSpec&& other)
    : traits(other.traits),
      flags(other.flags),
      path(std::move(other.path)),
      value(std::move(other.value)) {}

uint64_t SubdocCmdContext::getOperationValueBytesTotal() const {
    uint64_t result = 0;
    for (auto& ops : operations) {
        for (auto& op : ops) {
            result += op.value.len;
        }
    }
    return result;
}

template <typename T>
std::string SubdocCmdContext::macroToString(T macroValue) {
    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    ss << "\"0x" << std::setw(sizeof(T) * 2) << macroValue << "\"";
    return ss.str();
}

ENGINE_ERROR_CODE SubdocCmdContext::pre_link_document(item_info& info) {
    if (do_macro_expansion) {
        auto bodyoffset = cb::xattr::get_body_offset(
            {static_cast<const char*>(info.value[0].iov_base),
             info.value[0].iov_len});

        cb::byte_buffer blob_buffer{
            static_cast<uint8_t*>(info.value[0].iov_base),
            bodyoffset};

        cb::xattr::Blob xattr_blob(blob_buffer);
        auto value = xattr_blob.get(xattr_key);
        if (value.len == 0) {
            // The segment is no longer there (we may have had another
            // subdoc command which rewrote the segment where we injected
            // the macro.
            return ENGINE_SUCCESS;
        }

        // Replace the CAS
        if (std::any_of(std::begin(paddedMacros),
                        std::end(paddedMacros),
                        [](const MacroPair& m) {
                            return m.first == cb::xattr::macros::CAS;
                        })) {
            substituteMacro(cb::xattr::macros::CAS,
                            macroToString(htonll(info.cas)),
                            value);
        }

        // Replace the Seqno
        if (std::any_of(std::begin(paddedMacros),
                        std::end(paddedMacros),
                        [](const MacroPair& m) {
                            return m.first == cb::xattr::macros::SEQNO;
                        })) {
            substituteMacro(
                    cb::xattr::macros::SEQNO, macroToString(info.seqno), value);
        }
    }

    return ENGINE_SUCCESS;
}

void SubdocCmdContext::substituteMacro(cb::const_char_buffer macroName,
                                       const std::string& macroValue,
                                       cb::byte_buffer& value) {
    // Do an in-place substitution of the real macro value where we
    // wrote the padded macro string.
    uint8_t* root = value.buf;
    uint8_t* end = value.buf + value.len;
    auto& macro = std::find_if(std::begin(paddedMacros),
                               std::end(paddedMacros),
                               [macroName](const MacroPair& m) {
                                   return m.first == macroName;
                               })
                          ->second;
    auto* needle = macro.data();
    auto* needle_end = macro.data() + macro.length();

    // This replaces ALL instances of the padded string
    while ((root = std::search(root, end, needle, needle_end)) != end) {
        std::copy(macroValue.data(),
                  macroValue.data() + macroValue.length(),
                  root);
        root += macroValue.length();
    }
}

cb::const_char_buffer SubdocCmdContext::get_padded_macro(
        cb::const_char_buffer macro) {
    return std::find_if(
                   std::begin(paddedMacros),
                   std::end(paddedMacros),
                   [macro](const MacroPair& a) { return a.first == macro; })
            ->second;
}

static inline std::string to_hex_string(uint64_t value) {
    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    ss << "0x" << std::setw(16) << value;
    return ss.str();
}

void SubdocCmdContext::generate_macro_padding(cb::const_char_buffer payload,
                                              cb::const_char_buffer macro) {
    if (!do_macro_expansion) {
        // macro expansion is not needed
        return;
    }

    bool unique = false;
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<uint64_t> dis;

    while (!unique) {
        unique = true;
        uint64_t ii = dis(gen);
        const std::string candidate = "\"" + to_hex_string(ii) + "\"";

        for (auto& op : getOperations(Phase::XATTR)) {
            if (cb::strnstr(op.value.buf, candidate.c_str(), op.value.len)) {
                unique = false;
                break;
            }
        }

        if (unique) {
            if (cb::strnstr(payload.buf, candidate.c_str(), payload.len)) {
                unique = false;
            } else {
                paddedMacros.push_back(std::make_pair(macro, candidate));
            }
        }
    }
}

void SubdocCmdContext::setMutationSemantics(mcbp::subdoc::doc_flag docFlags) {
    if (docFlags == mcbp::subdoc::doc_flag::Add) {
        mutationSemantics = MutationSemantics::Add;
    } else if (docFlags == mcbp::subdoc::doc_flag::Mkdoc) {
        mutationSemantics = MutationSemantics::Set;
    } else {
        mutationSemantics = MutationSemantics::Replace;
    }
}

cb::const_char_buffer SubdocCmdContext::get_document_vattr() {
    if (document_vattr.empty()) {
        // @todo we can optimize this by building the json in a more efficient
        //       way, but for now just do it by using cJSON...
        unique_cJSON_ptr doc(cJSON_CreateObject());

        cJSON_AddStringToObject(
                doc.get(), "CAS", to_hex_string(input_item_info.cas).c_str());

        cJSON_AddStringToObject(
                doc.get(),
                "vbucket_uuid",
                to_hex_string(input_item_info.vbucket_uuid).c_str());

        cJSON_AddStringToObject(doc.get(),
                                "seqno",
                                to_hex_string(input_item_info.seqno).c_str());

        cJSON_AddNumberToObject(doc.get(), "exptime", input_item_info.exptime);

        // The flags are kept internally in network byte order...
        cJSON_AddNumberToObject(
                doc.get(), "flags", ntohl(input_item_info.flags));

        if (mcbp::datatype::is_xattr(input_item_info.datatype)) {
            // strip off xattr
            auto bodyoffset = cb::xattr::get_body_offset(
                    {static_cast<const char*>(
                             input_item_info.value[0].iov_base),
                     input_item_info.value[0].iov_len});
            cJSON_AddNumberToObject(doc.get(),
                                    "value_bytes",
                                    input_item_info.nbytes - bodyoffset);
        } else {
            cJSON_AddNumberToObject(
                    doc.get(), "value_bytes", input_item_info.nbytes);
        }

        unique_cJSON_ptr array(cJSON_CreateArray());
        auto datatypes = split_string(
            mcbp::datatype::to_string(input_item_info.datatype), ",");
        for (const auto& d : datatypes) {
            cJSON_AddItemToArray(array.get(), cJSON_CreateString(d.c_str()));
        }

        cJSON_AddItemToObject(doc.get(), "datatype", array.release());

        cJSON_AddBoolToObject(
                doc.get(),
                "deleted",
                input_item_info.document_state == DocumentState::Deleted);

        if (input_item_info.cas_is_hlc) {
            // convert nanoseconds CAS into seconds and ensure u64 before cJSON
            // converts to a double internally.
            std::chrono::nanoseconds ns(input_item_info.cas);
            cJSON_AddStringToObject(
                    doc.get(),
                    "last_modified",
                    std::to_string(uint64_t(std::chrono::duration_cast<
                                                    std::chrono::seconds>(ns)
                                                    .count()))
                            .c_str());
        }
        unique_cJSON_ptr root(cJSON_CreateObject());
        cJSON_AddItemToObject(root.get(), "$document", doc.release());
        document_vattr = to_string(root, false);
    }

    return cb::const_char_buffer(document_vattr.data(), document_vattr.size());
}

cb::const_char_buffer SubdocCmdContext::get_xtoc_vattr() {
    if (!mcbp::datatype::is_xattr(in_datatype)) {
        xtoc_vattr = R"({"$XTOC":[]})";
        return cb::const_char_buffer(xtoc_vattr.data(), xtoc_vattr.size());
    }
    if (xtoc_vattr.empty()) {
        unique_cJSON_ptr doc(cJSON_CreateObject());

        const auto bodyoffset = cb::xattr::get_body_offset(in_doc);
        cb::byte_buffer blob_buffer{(uint8_t*)in_doc.buf, (size_t)bodyoffset};
        cb::xattr::Blob xattr_blob(blob_buffer);

        unique_cJSON_ptr array(cJSON_CreateArray());
        for (const std::pair<cb::const_byte_buffer, cb::const_byte_buffer>&
                     kvPair : xattr_blob) {
            bool isSystemXattr = cb::xattr::is_system_xattr(
                    const_cast<cb::const_byte_buffer&>(kvPair.first));

            if (xtocSemantics == XtocSemantics::All ||
                (isSystemXattr && (xtocSemantics == XtocSemantics::System)) ||
                (!isSystemXattr && (xtocSemantics == XtocSemantics::User))) {
                cJSON_AddItemToArray(
                        array.get(),
                        cJSON_CreateString(to_string(kvPair.first).c_str()));
            }
        }

        cJSON_AddItemToObject(doc.get(), "$XTOC", array.release());
        xtoc_vattr = to_string(doc, false);
    }
    return cb::const_char_buffer(xtoc_vattr.data(), xtoc_vattr.size());
}

protocol_binary_response_status SubdocCmdContext::get_document_for_searching(
        uint64_t client_cas) {
    item_info& info = getInputItemInfo();
    auto& c = connection;

    if (!bucket_get_item_info(cookie, fetchedItem.get(), &info)) {
        LOG_WARNING(&c, "%u: Failed to get item info", c.getId());
        return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
    }

    if (info.cas == -1ull) {
        // Check that item is not locked:
        if (client_cas == 0 || client_cas == -1ull) {
            if (c.remapErrorCode(ENGINE_LOCKED_TMPFAIL) ==
                ENGINE_LOCKED_TMPFAIL) {
                return PROTOCOL_BINARY_RESPONSE_LOCKED;
            } else {
                return PROTOCOL_BINARY_RESPONSE_ETMPFAIL;
            }
        }
        // If the user *did* supply the CAS, we will validate it later on
        // when the mutation is actually applied. In any event, we don't
        // run the following branch on locked documents.
    } else if ((client_cas != 0) && client_cas != info.cas) {
        // Check CAS matches (if specified by the user).
        return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
    }

    in_flags = info.flags;
    in_cas = client_cas ? client_cas : info.cas;
    in_doc.buf = static_cast<char*>(info.value[0].iov_base);
    in_doc.len = info.value[0].iov_len;
    in_datatype = info.datatype;
    in_document_state = info.document_state;

    if (mcbp::datatype::is_snappy(info.datatype)) {
        // Need to expand before attempting to extract from it.
        try {
            using namespace cb::compression;
            if (!inflate(Algorithm::Snappy,
                         in_doc,
                         inflated_doc_buffer)) {
                char clean_key[KEY_MAX_LENGTH + 32];
                if (buf_to_printable_buffer(clean_key,
                                            sizeof(clean_key),
                                            static_cast<const char*>(info.key),
                                            info.nkey) != -1) {
                    LOG_WARNING(&c,
                                "<%u ERROR: Failed to determine inflated body"
                                " size. Key: '%s' may have an "
                                "incorrect datatype of COMPRESSED_JSON.",
                                c.getId(),
                                cb::logtags::tagUserData(clean_key).c_str());
                }

                return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
            }
        } catch (const std::bad_alloc&) {
            return PROTOCOL_BINARY_RESPONSE_ENOMEM;
        }

        // Update document to point to the uncompressed version in the buffer.
        in_doc = inflated_doc_buffer;
        in_datatype &= ~PROTOCOL_BINARY_DATATYPE_SNAPPY;
    }

    return PROTOCOL_BINARY_RESPONSE_SUCCESS;
}
<commit_msg>Replace local impl of conversion to hex string with lib version<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2016 Couchbase, Inc.
 *
 *   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 "config.h"
#include "subdocument_context.h"
#include "debug_helpers.h"
#include "mc_time.h"
#include "protocol/mcbp/engine_wrapper.h"
#include "subdocument.h"

#include <platform/string.h>
#include <utilities/logtags.h>
#include <xattr/blob.h>

#include <iomanip>
#include <random>
#include <sstream>
#include <utilities/string_utilities.h>

SubdocCmdContext::OperationSpec::OperationSpec(SubdocCmdTraits traits_,
                                               protocol_binary_subdoc_flag flags_,
                                               cb::const_char_buffer path_)
    : SubdocCmdContext::OperationSpec::OperationSpec(traits_, flags_, path_,
                                                     {nullptr, 0}) {
}

SubdocCmdContext::OperationSpec::OperationSpec(SubdocCmdTraits traits_,
                                               protocol_binary_subdoc_flag flags_,
                                               cb::const_char_buffer path_,
                                               cb::const_char_buffer value_)
    : traits(traits_),
      flags(flags_),
      path(path_),
      value(value_),
      status(PROTOCOL_BINARY_RESPONSE_EINTERNAL) {
    if (flags & SUBDOC_FLAG_MKDIR_P) {
        traits.subdocCommand = Subdoc::Command(traits.subdocCommand |
                                               Subdoc::Command::FLAG_MKDIR_P);
    }
}

SubdocCmdContext::OperationSpec::OperationSpec(OperationSpec&& other)
    : traits(other.traits),
      flags(other.flags),
      path(std::move(other.path)),
      value(std::move(other.value)) {}

uint64_t SubdocCmdContext::getOperationValueBytesTotal() const {
    uint64_t result = 0;
    for (auto& ops : operations) {
        for (auto& op : ops) {
            result += op.value.len;
        }
    }
    return result;
}

template <typename T>
std::string SubdocCmdContext::macroToString(T macroValue) {
    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    ss << "\"0x" << std::setw(sizeof(T) * 2) << macroValue << "\"";
    return ss.str();
}

ENGINE_ERROR_CODE SubdocCmdContext::pre_link_document(item_info& info) {
    if (do_macro_expansion) {
        auto bodyoffset = cb::xattr::get_body_offset(
            {static_cast<const char*>(info.value[0].iov_base),
             info.value[0].iov_len});

        cb::byte_buffer blob_buffer{
            static_cast<uint8_t*>(info.value[0].iov_base),
            bodyoffset};

        cb::xattr::Blob xattr_blob(blob_buffer);
        auto value = xattr_blob.get(xattr_key);
        if (value.len == 0) {
            // The segment is no longer there (we may have had another
            // subdoc command which rewrote the segment where we injected
            // the macro.
            return ENGINE_SUCCESS;
        }

        // Replace the CAS
        if (std::any_of(std::begin(paddedMacros),
                        std::end(paddedMacros),
                        [](const MacroPair& m) {
                            return m.first == cb::xattr::macros::CAS;
                        })) {
            substituteMacro(cb::xattr::macros::CAS,
                            macroToString(htonll(info.cas)),
                            value);
        }

        // Replace the Seqno
        if (std::any_of(std::begin(paddedMacros),
                        std::end(paddedMacros),
                        [](const MacroPair& m) {
                            return m.first == cb::xattr::macros::SEQNO;
                        })) {
            substituteMacro(
                    cb::xattr::macros::SEQNO, macroToString(info.seqno), value);
        }
    }

    return ENGINE_SUCCESS;
}

void SubdocCmdContext::substituteMacro(cb::const_char_buffer macroName,
                                       const std::string& macroValue,
                                       cb::byte_buffer& value) {
    // Do an in-place substitution of the real macro value where we
    // wrote the padded macro string.
    uint8_t* root = value.buf;
    uint8_t* end = value.buf + value.len;
    auto& macro = std::find_if(std::begin(paddedMacros),
                               std::end(paddedMacros),
                               [macroName](const MacroPair& m) {
                                   return m.first == macroName;
                               })
                          ->second;
    auto* needle = macro.data();
    auto* needle_end = macro.data() + macro.length();

    // This replaces ALL instances of the padded string
    while ((root = std::search(root, end, needle, needle_end)) != end) {
        std::copy(macroValue.data(),
                  macroValue.data() + macroValue.length(),
                  root);
        root += macroValue.length();
    }
}

cb::const_char_buffer SubdocCmdContext::get_padded_macro(
        cb::const_char_buffer macro) {
    return std::find_if(
                   std::begin(paddedMacros),
                   std::end(paddedMacros),
                   [macro](const MacroPair& a) { return a.first == macro; })
            ->second;
}

void SubdocCmdContext::generate_macro_padding(cb::const_char_buffer payload,
                                              cb::const_char_buffer macro) {
    if (!do_macro_expansion) {
        // macro expansion is not needed
        return;
    }

    bool unique = false;
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<uint64_t> dis;

    while (!unique) {
        unique = true;
        uint64_t ii = dis(gen);
        const std::string candidate = "\"" + cb::to_hex(ii) + "\"";

        for (auto& op : getOperations(Phase::XATTR)) {
            if (cb::strnstr(op.value.buf, candidate.c_str(), op.value.len)) {
                unique = false;
                break;
            }
        }

        if (unique) {
            if (cb::strnstr(payload.buf, candidate.c_str(), payload.len)) {
                unique = false;
            } else {
                paddedMacros.push_back(std::make_pair(macro, candidate));
            }
        }
    }
}

void SubdocCmdContext::setMutationSemantics(mcbp::subdoc::doc_flag docFlags) {
    if (docFlags == mcbp::subdoc::doc_flag::Add) {
        mutationSemantics = MutationSemantics::Add;
    } else if (docFlags == mcbp::subdoc::doc_flag::Mkdoc) {
        mutationSemantics = MutationSemantics::Set;
    } else {
        mutationSemantics = MutationSemantics::Replace;
    }
}

cb::const_char_buffer SubdocCmdContext::get_document_vattr() {
    if (document_vattr.empty()) {
        // @todo we can optimize this by building the json in a more efficient
        //       way, but for now just do it by using cJSON...
        unique_cJSON_ptr doc(cJSON_CreateObject());

        cJSON_AddStringToObject(
                doc.get(), "CAS", cb::to_hex(input_item_info.cas).c_str());

        cJSON_AddStringToObject(
                doc.get(),
                "vbucket_uuid",
                cb::to_hex(input_item_info.vbucket_uuid).c_str());

        cJSON_AddStringToObject(
                doc.get(), "seqno", cb::to_hex(input_item_info.seqno).c_str());

        cJSON_AddNumberToObject(doc.get(), "exptime", input_item_info.exptime);

        // The flags are kept internally in network byte order...
        cJSON_AddNumberToObject(
                doc.get(), "flags", ntohl(input_item_info.flags));

        if (mcbp::datatype::is_xattr(input_item_info.datatype)) {
            // strip off xattr
            auto bodyoffset = cb::xattr::get_body_offset(
                    {static_cast<const char*>(
                             input_item_info.value[0].iov_base),
                     input_item_info.value[0].iov_len});
            cJSON_AddNumberToObject(doc.get(),
                                    "value_bytes",
                                    input_item_info.nbytes - bodyoffset);
        } else {
            cJSON_AddNumberToObject(
                    doc.get(), "value_bytes", input_item_info.nbytes);
        }

        unique_cJSON_ptr array(cJSON_CreateArray());
        auto datatypes = split_string(
            mcbp::datatype::to_string(input_item_info.datatype), ",");
        for (const auto& d : datatypes) {
            cJSON_AddItemToArray(array.get(), cJSON_CreateString(d.c_str()));
        }

        cJSON_AddItemToObject(doc.get(), "datatype", array.release());

        cJSON_AddBoolToObject(
                doc.get(),
                "deleted",
                input_item_info.document_state == DocumentState::Deleted);

        if (input_item_info.cas_is_hlc) {
            // convert nanoseconds CAS into seconds and ensure u64 before cJSON
            // converts to a double internally.
            std::chrono::nanoseconds ns(input_item_info.cas);
            cJSON_AddStringToObject(
                    doc.get(),
                    "last_modified",
                    std::to_string(uint64_t(std::chrono::duration_cast<
                                                    std::chrono::seconds>(ns)
                                                    .count()))
                            .c_str());
        }
        unique_cJSON_ptr root(cJSON_CreateObject());
        cJSON_AddItemToObject(root.get(), "$document", doc.release());
        document_vattr = to_string(root, false);
    }

    return cb::const_char_buffer(document_vattr.data(), document_vattr.size());
}

cb::const_char_buffer SubdocCmdContext::get_xtoc_vattr() {
    if (!mcbp::datatype::is_xattr(in_datatype)) {
        xtoc_vattr = R"({"$XTOC":[]})";
        return cb::const_char_buffer(xtoc_vattr.data(), xtoc_vattr.size());
    }
    if (xtoc_vattr.empty()) {
        unique_cJSON_ptr doc(cJSON_CreateObject());

        const auto bodyoffset = cb::xattr::get_body_offset(in_doc);
        cb::byte_buffer blob_buffer{(uint8_t*)in_doc.buf, (size_t)bodyoffset};
        cb::xattr::Blob xattr_blob(blob_buffer);

        unique_cJSON_ptr array(cJSON_CreateArray());
        for (const std::pair<cb::const_byte_buffer, cb::const_byte_buffer>&
                     kvPair : xattr_blob) {
            bool isSystemXattr = cb::xattr::is_system_xattr(
                    const_cast<cb::const_byte_buffer&>(kvPair.first));

            if (xtocSemantics == XtocSemantics::All ||
                (isSystemXattr && (xtocSemantics == XtocSemantics::System)) ||
                (!isSystemXattr && (xtocSemantics == XtocSemantics::User))) {
                cJSON_AddItemToArray(
                        array.get(),
                        cJSON_CreateString(to_string(kvPair.first).c_str()));
            }
        }

        cJSON_AddItemToObject(doc.get(), "$XTOC", array.release());
        xtoc_vattr = to_string(doc, false);
    }
    return cb::const_char_buffer(xtoc_vattr.data(), xtoc_vattr.size());
}

protocol_binary_response_status SubdocCmdContext::get_document_for_searching(
        uint64_t client_cas) {
    item_info& info = getInputItemInfo();
    auto& c = connection;

    if (!bucket_get_item_info(cookie, fetchedItem.get(), &info)) {
        LOG_WARNING(&c, "%u: Failed to get item info", c.getId());
        return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
    }

    if (info.cas == -1ull) {
        // Check that item is not locked:
        if (client_cas == 0 || client_cas == -1ull) {
            if (c.remapErrorCode(ENGINE_LOCKED_TMPFAIL) ==
                ENGINE_LOCKED_TMPFAIL) {
                return PROTOCOL_BINARY_RESPONSE_LOCKED;
            } else {
                return PROTOCOL_BINARY_RESPONSE_ETMPFAIL;
            }
        }
        // If the user *did* supply the CAS, we will validate it later on
        // when the mutation is actually applied. In any event, we don't
        // run the following branch on locked documents.
    } else if ((client_cas != 0) && client_cas != info.cas) {
        // Check CAS matches (if specified by the user).
        return PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS;
    }

    in_flags = info.flags;
    in_cas = client_cas ? client_cas : info.cas;
    in_doc.buf = static_cast<char*>(info.value[0].iov_base);
    in_doc.len = info.value[0].iov_len;
    in_datatype = info.datatype;
    in_document_state = info.document_state;

    if (mcbp::datatype::is_snappy(info.datatype)) {
        // Need to expand before attempting to extract from it.
        try {
            using namespace cb::compression;
            if (!inflate(Algorithm::Snappy,
                         in_doc,
                         inflated_doc_buffer)) {
                char clean_key[KEY_MAX_LENGTH + 32];
                if (buf_to_printable_buffer(clean_key,
                                            sizeof(clean_key),
                                            static_cast<const char*>(info.key),
                                            info.nkey) != -1) {
                    LOG_WARNING(&c,
                                "<%u ERROR: Failed to determine inflated body"
                                " size. Key: '%s' may have an "
                                "incorrect datatype of COMPRESSED_JSON.",
                                c.getId(),
                                cb::logtags::tagUserData(clean_key).c_str());
                }

                return PROTOCOL_BINARY_RESPONSE_EINTERNAL;
            }
        } catch (const std::bad_alloc&) {
            return PROTOCOL_BINARY_RESPONSE_ENOMEM;
        }

        // Update document to point to the uncompressed version in the buffer.
        in_doc = inflated_doc_buffer;
        in_datatype &= ~PROTOCOL_BINARY_DATATYPE_SNAPPY;
    }

    return PROTOCOL_BINARY_RESPONSE_SUCCESS;
}
<|endoftext|>


<commit_before>the #include <iostream>
#include <string>
#include <vector>

using namespace std;
vector <string> Census;

/*We're leaving together,
But still it's farewell
And maybe we'll come back
To earth, who can tell?
I guess there is no one to blame
We're leaving ground (leaving ground)
Will things ever be the same again?

It's the final countdown
The final countdown

Oh

We're heading for Venus (Venus)
And still we stand tall
'Cause maybe they've seen us (seen us)
And welcome us all, yeah
With so many light years to go
And things to be found (to be found)
I'm sure that we'll all miss her so

It's the final countdown
The final countdown
The final countdown
The final countdown
Oh

The final countdown,oh
It's the final count down
The final countdown
The final countdown
The final countdown
Oh
It's the final count down
We're leaving together
The final count down
We'll all miss her so
It's the final countdown
It's the final countdown
Oh
It's the final countdown, yeah
void Census2017(){
  // Census.push_back("Name @ GitHub link");
  Census.push_back("Allen Comp Sci @ https://github.com/AllenCompSci");
  Census.push_back("Mr. Hudson @ https://github.com/theshrewedshrew");
  Census.push_back("BEST Team 58 @ https://github.com/BESTTeam58");
  Census.push_back("TexasSnow @ https://github.com/TexasSnow");
  Census.push_back("hotdogshabab @ https://github.com/hotdogshabab");
  Census.push_back("alansunglee @ https://github.com/alansunglee");
  Census.push_back("Rahultheman12 @ https://github.com/Rahultheman12");
  Census.push_back("spicyboi @ https://github.com/spicyboi");
  Census.push_back("John Nguyen @ https://github.com/jawnlovesfreestuff");
  Census.push_back("CodeTimesTen @ https://github.com/CodeTimesTen");
  Census.push_back("YourFriendlyNeighborhoodSpiderman @ https://github.com/YourFriendlyNeighborhoodSpiderman");
  Census.push_back("Devin Petersen @ https://github.com/DevinPetersen");
  Census.push_back("Cameron Mathis @ https://github.com/Phylux");
  Census.push_back("Samuel Woon @ https://github.com/samuel-w");
  Census.push_back("JustinV10 @ https://github.com/JustinV10");
  Census.push_back("Kyleaustin36 @ https://github.com/kyleaustin36");
  Census.push_back("Maaz Kamal @ https://github.com/Maze-Camel");
  Census.push_back("bingood4ever @ https://github.com/bingood4ever");
  Census.push_back("Gainz101 @ https://github.com/Gainz101");
  Census.push_back("zachdogg @ https://github.com/Zachdogg1");
*/

}
void printCensus(){
  for(int i = 0; i < (int)Census.size(); i++){
    cout << "Hello World from "Your name" + Census[i] << "\n";

  }
}
//test
void main(){
  Census2017();
  printCensus();
}
<commit_msg>Update HelloWorld.cpp<commit_after>#include <iostream>
#include <string>
#include <vector>

using namespace std;
vector <string> Census;

/*We're leaving together,
But still it's farewell
And maybe we'll come back
To earth, who can tell?
I guess there is no one to blame
We're leaving ground (leaving ground)
Will things ever be the same again?

It's the final countdown
The final countdown

Oh

We're heading for Venus (Venus)
And still we stand tall
'Cause maybe they've seen us (seen us)
And welcome us all, yeah
With so many light years to go
And things to be found (to be found)
I'm sure that we'll all miss her so

It's the final countdown
The final countdown
The final countdown
The final countdown
Oh

The final countdown,oh
It's the final count down
The final countdown
The final countdown
The final countdown
Oh
It's the final count down
We're leaving together
The final count down
We'll all miss her so
It's the final countdown
It's the final countdown
Oh
It's the final countdown, yeah
void Census2017(){
  // Census.push_back("Name @ GitHub link");
  Census.push_back("Allen Comp Sci @ https://github.com/AllenCompSci");
  Census.push_back("Mr. Hudson @ https://github.com/theshrewedshrew");
  Census.push_back("BEST Team 58 @ https://github.com/BESTTeam58");
  Census.push_back("TexasSnow @ https://github.com/TexasSnow");
  Census.push_back("hotdogshabab @ https://github.com/hotdogshabab");
  Census.push_back("alansunglee @ https://github.com/alansunglee");
  Census.push_back("Rahultheman12 @ https://github.com/Rahultheman12");
  Census.push_back("spicyboi @ https://github.com/spicyboi");
  Census.push_back("John Nguyen @ https://github.com/jawnlovesfreestuff");
  Census.push_back("CodeTimesTen @ https://github.com/CodeTimesTen");
  Census.push_back("YourFriendlyNeighborhoodSpiderman @ https://github.com/YourFriendlyNeighborhoodSpiderman");
  Census.push_back("Devin Petersen @ https://github.com/DevinPetersen");
  Census.push_back("Cameron Mathis @ https://github.com/Phylux");
  Census.push_back("Samuel Woon @ https://github.com/samuel-w");
  Census.push_back("JustinV10 @ https://github.com/JustinV10");
  Census.push_back("Kyleaustin36 @ https://github.com/kyleaustin36");
  Census.push_back("Maaz Kamal @ https://github.com/Maze-Camel");
  Census.push_back("bingood4ever @ https://github.com/bingood4ever");
  Census.push_back("Gainz101 @ https://github.com/Gainz101");
  Census.push_back("zachdogg @ https://github.com/Zachdogg1");
*/

}
void printCensus(){
  for(int i = 0; i < (int)Census.size(); i++){
    cout << "Hello World from "Your name" + Census[i] << "\n";

  }
}
//test
void main(){
  Census2017();
  printCensus();
}
<|endoftext|>


<commit_before>#include "ma.h"
#include <apf.h>
#include <gmi_mesh.h>
#include <apfMDS.h>
#include <apfShape.h>
#include <PCU.h>

class Linear : public ma::IsotropicFunction
{
  public:
    Linear(ma::Mesh* m)
    {
      mesh = m;
      average = ma::getAverageEdgeLength(m);
      ma::getBoundingBox(m,lower,upper);
    }
    virtual double getValue(ma::Entity* v)
    {
      ma::Vector p = ma::getPosition(mesh,v);
      double x = (p[0] - lower[0])/(upper[0] - lower[0]);
      return average*(3*x+1)/2;
    }
  private:
    ma::Mesh* mesh;
    double average;
    ma::Vector lower;
    ma::Vector upper;
};

int main(int argc, char** argv)
{
  assert(argc==3);
  const char* modelFile = argv[1];
  const char* meshFile = argv[2];
  MPI_Init(&argc,&argv);
  PCU_Comm_Init();
  gmi_register_mesh();
  ma::Mesh* m = apf::loadMdsMesh(modelFile,meshFile);
  m->verify();
  Linear sf(m);
  ma::Input* in = ma::configure(m, &sf);
  in->shouldRunPreZoltan = true;
  in->shouldRunMidDiffusion = true;
  in->shouldRunPostDiffusion = true;
  ma::adapt(in);
  m->verify();
  apf::writeVtkFiles("after",m);
  m->destroyNative();
  apf::destroyMesh(m);
  PCU_Comm_Free();
  MPI_Finalize();
}

<commit_msg>adjusting size formula to reduce test refinement<commit_after>#include "ma.h"
#include <apf.h>
#include <gmi_mesh.h>
#include <apfMDS.h>
#include <apfShape.h>
#include <PCU.h>

class Linear : public ma::IsotropicFunction
{
  public:
    Linear(ma::Mesh* m)
    {
      mesh = m;
      average = ma::getAverageEdgeLength(m);
      ma::getBoundingBox(m,lower,upper);
    }
    virtual double getValue(ma::Entity* v)
    {
      ma::Vector p = ma::getPosition(mesh,v);
      double x = (p[0] - lower[0])/(upper[0] - lower[0]);
      return average*(4*x+2)/3;
    }
  private:
    ma::Mesh* mesh;
    double average;
    ma::Vector lower;
    ma::Vector upper;
};

int main(int argc, char** argv)
{
  assert(argc==3);
  const char* modelFile = argv[1];
  const char* meshFile = argv[2];
  MPI_Init(&argc,&argv);
  PCU_Comm_Init();
  gmi_register_mesh();
  ma::Mesh* m = apf::loadMdsMesh(modelFile,meshFile);
  m->verify();
  Linear sf(m);
  ma::Input* in = ma::configure(m, &sf);
  in->shouldRunPreZoltan = true;
  in->shouldRunMidDiffusion = true;
  in->shouldRunPostDiffusion = true;
  ma::adapt(in);
  m->verify();
  apf::writeVtkFiles("after",m);
  m->destroyNative();
  apf::destroyMesh(m);
  PCU_Comm_Free();
  MPI_Finalize();
}

<|endoftext|>