<commit_before>#define DEBUG 1
/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 11/9/2019, 9:10:42 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{1000000007LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

int main()
{
  int N;
  cin >> N;
  vector<int> A(N), B(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < N; i++)
  {
    cin >> B[i];
  }
  vector<int> old_A{A}, old_B{B};
  sort(A.begin(), A.end());
  sort(B.begin(), B.end());
  for (auto i = 0; i < N; i++)
  {
    if (A[i] > B[i])
    {
      No();
    }
  }
  vector<bool> C(N, true);
  for (auto i = 1; i < N; i++)
  {
    C[i] = (A[i] <= B[i - 1]);
  }
  for (auto k = 0; k < N; k++)
  {
    int x{old_A[k]};
    int y{old_B[k]};
    if (x > y)
    {
      continue;
    }
    auto it_a{upper_bound(A.begin(), A.end(), x)};
    --it_a;
    assert(*it_a == x);
    auto it_b{lower_bound(B.begin(), B.end(), y)};
    assert(*it_b == y);
    int num_a(it_a - A.begin());
    int num_b(it_b - B.begin());
    if (num_b <= num_a)
    {
      Yes();
    }
    else
    {
      bool ok{true};
      for (auto i = num_a + 1; i <= num_b; i++)
      {
        if (!C[i])
        {
          ok = false;
          break;
        }
      }
      if (ok)
      {
        Yes();
      }
    }
  }
  for (auto i = 0; i < N; i++)
  {
    if (old_A[i] == A[i])
    {
      Yes();
    }
  }
  vector<int> V(N, -1);
  for (auto i = 0; i < N; i++)
  {
    auto it{lower_bound(A.begin(), A.end(), old_A[i])};
    int num(it - A.begin());
    V[num] = i;
  }
  assert(false);
  for (auto i = 0; i < N; i++)
  {
    if (V[i] == -1)
    {
      Yes();
    }
  }
  vector<bool> used(N, false);
  int now{0};
  int cnt{0};
  while (cnt < N)
  {
    if (used[now])
    {
      Yes();
    }
    used[now] = true;
    cnt++;
    now = V[now];
  }
  No();
}<commit_msg>submit C.cpp to 'C - Swaps' (nikkei2019-2-qual) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1
/**
 * File    : C.cpp
 * Author  : Kazune Takahashi
 * Created : 11/9/2019, 9:10:42 PM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
using ll = long long;
constexpr ll MOD{1000000007LL};
constexpr ll MAX_SIZE{3000010LL};
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{x % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// for C++14
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// constexpr double epsilon = 1e-10;
// constexpr ll infty = 1000000000000000LL;
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

int main()
{
  int N;
  cin >> N;
  vector<int> A(N), B(N);
  for (auto i = 0; i < N; i++)
  {
    cin >> A[i];
  }
  for (auto i = 0; i < N; i++)
  {
    cin >> B[i];
  }
  vector<int> old_A{A}, old_B{B};
  sort(A.begin(), A.end());
  sort(B.begin(), B.end());
  for (auto i = 0; i < N; i++)
  {
    if (A[i] > B[i])
    {
      No();
    }
  }
  vector<bool> C(N, true);
  for (auto i = 1; i < N; i++)
  {
    C[i] = (A[i] <= B[i - 1]);
  }
  for (auto k = 0; k < N; k++)
  {
    int x{old_A[k]};
    int y{old_B[k]};
    if (x > y)
    {
      continue;
    }
    auto it_a{upper_bound(A.begin(), A.end(), x)};
    --it_a;
    assert(*it_a == x);
    auto it_b{lower_bound(B.begin(), B.end(), y)};
    assert(*it_b == y);
    int num_a(it_a - A.begin());
    int num_b(it_b - B.begin());
    if (num_b <= num_a)
    {
      Yes();
    }
    else
    {
      bool ok{true};
      for (auto i = num_a + 1; i <= num_b; i++)
      {
        if (!C[i])
        {
          ok = false;
          break;
        }
      }
      if (ok)
      {
        Yes();
      }
    }
  }
  for (auto i = 0; i < N; i++)
  {
    if (old_A[i] == A[i])
    {
      Yes();
    }
  }
  vector<int> V(N, -1);
  for (auto i = 0; i < N; i++)
  {
    auto it{lower_bound(A.begin(), A.end(), old_A[i])};
    int num(it - A.begin());
    V[num] = i;
  }
  for (auto i = 0; i < N; i++)
  {
    if (V[i] == -1)
    {
      Yes();
    }
  }
  assert(false);
  vector<bool> used(N, false);
  int now{0};
  int cnt{0};
  while (cnt < N)
  {
    if (used[now])
    {
      Yes();
    }
    used[now] = true;
    cnt++;
    now = V[now];
  }
  No();
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fedesc.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 03:37:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif

#ifndef _REF_HXX
#include <tools/ref.hxx>
#endif

#ifndef _FESH_HXX
#include <fesh.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _PAGEFRM_HXX
#include <pagefrm.hxx>
#endif
#ifndef _ROOTFRM_HXX
#include <rootfrm.hxx>
#endif
#ifndef _CNTFRM_HXX
#include <cntfrm.hxx>
#endif
#ifndef _PAM_HXX
#include <pam.hxx>
#endif
#ifndef _NODE_HXX
#include <node.hxx>
#endif
#ifndef _FMTPDSC_HXX //autogen
#include <fmtpdsc.hxx>
#endif
#ifndef _PAGEDESC_HXX
#include <pagedesc.hxx>
#endif
#ifndef _TABFRM_HXX
#include <tabfrm.hxx>
#endif
#ifndef _EDIMP_HXX
#include <edimp.hxx>
#endif
#ifndef _SWSTYLENAMEMAPPER_HXX
#include <SwStyleNameMapper.hxx>
#endif
/*************************************************************************
|*
|*  SwFEShell::GetPageDescCnt()
|*
|*  Ersterstellung      MA 25. Jan. 93
|*  Letzte Aenderung    MA 25. Jan. 93
|*
|*************************************************************************/

USHORT SwFEShell::GetPageDescCnt() const
{
    return GetDoc()->GetPageDescCnt();
}

/*************************************************************************
|*
|*  SwFEShell::ChgCurPageDesc()
|*
|*  Ersterstellung      ST ??
|*  Letzte Aenderung    MA 01. Aug. 94
|*
|*************************************************************************/

void SwFEShell::ChgCurPageDesc( const SwPageDesc& rDesc )
{
#ifndef PRODUCT
    //Die SS veraendert keinen PageDesc, sondern setzt nur das Attribut.
    //Der Pagedesc muss im Dokument vorhanden sein!
    BOOL bFound = FALSE;
    for ( USHORT nTst = 0; nTst < GetPageDescCnt(); ++nTst )
        if ( &rDesc == &GetPageDesc( nTst ) )
            bFound = TRUE;
    ASSERT( bFound, "ChgCurPageDesc mit ungueltigem Descriptor." );
#endif

    StartAllAction();

    SwPageFrm *pPage = GetCurrFrm()->FindPageFrm();
    const SwFrm *pFlow;
    USHORT nPageNmOffset = 0;

    ASSERT( !GetCrsr()->HasMark(), "ChgCurPageDesc nur ohne Selektion!");

    SET_CURR_SHELL( this );
    while ( pPage )
    {
        pFlow = pPage->FindFirstBodyCntnt();
        if ( pFlow )
        {
            if ( pFlow->IsInTab() )
                pFlow = pFlow->FindTabFrm();
            const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
            if( rPgDesc.GetPageDesc() )
            {
                // wir haben ihn den Schlingel
                nPageNmOffset = rPgDesc.GetNumOffset();
                break;
            }
        }
        pPage = (SwPageFrm*) pPage->GetPrev();
    }
    if ( !pPage )
    {
        pPage = (SwPageFrm*) (GetLayout()->Lower());
        pFlow = pPage->FindFirstBodyCntnt();
        if ( !pFlow )
        {
            pPage   = (SwPageFrm*)pPage->GetNext();
            pFlow = pPage->FindFirstBodyCntnt();
            ASSERT( pFlow, "Dokuemnt ohne Inhalt?!?" );
        }
    }

    // Seitennummer mitnehmen
    SwFmtPageDesc aNew( &rDesc );
    aNew.SetNumOffset( nPageNmOffset );

    if ( pFlow->IsInTab() )
        GetDoc()->SetAttr( aNew, *(SwFmt*)pFlow->FindTabFrm()->GetFmt() );
    else
    {
        SwPaM aPaM( *((SwCntntFrm*)pFlow)->GetNode() );
        GetDoc()->Insert( aPaM, aNew );
    }
    EndAllActionAndCall();
}

/*************************************************************************
|*
|*  SwFEShell::ChgPageDesc()
|*
|*  Ersterstellung      MA 25. Jan. 93
|*  Letzte Aenderung    MA 24. Jan. 95
|*
|*************************************************************************/

void SwFEShell::ChgPageDesc( USHORT i, const SwPageDesc &rChged )
{
    StartAllAction();
    SET_CURR_SHELL( this );
    GetDoc()->ChgPageDesc( i, rChged );
    EndAllActionAndCall();
}

/*************************************************************************
|*
|*  SwFEShell::GetPageDesc(), GetCurPageDesc()
|*
|*  Ersterstellung      MA 25. Jan. 93
|*  Letzte Aenderung    MA 23. Apr. 93
|
|*************************************************************************/

const SwPageDesc& SwFEShell::GetPageDesc( USHORT i ) const
{
    return const_cast<const SwDoc *>(GetDoc())->GetPageDesc( i );
}

SwPageDesc* SwFEShell::FindPageDescByName( const String& rName,
                                            BOOL bGetFromPool,
                                            USHORT* pPos )
{
    SwPageDesc* pDesc = GetDoc()->FindPageDescByName( rName, pPos );
    if( !pDesc && bGetFromPool )
    {
        USHORT nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( rName, GET_POOLID_PAGEDESC );
        if( USHRT_MAX != nPoolId &&
            0 != (pDesc = GetDoc()->GetPageDescFromPool( nPoolId ))
            && pPos )
                // werden immer hinten angehaengt
            *pPos = GetDoc()->GetPageDescCnt() - 1 ;
    }
    return pDesc;
}

USHORT SwFEShell::GetMousePageDesc( const Point &rPt ) const
{
    if( GetLayout() )
    {
        const SwPageFrm* pPage =
            static_cast<const SwPageFrm*>( GetLayout()->Lower() );
        if( pPage )
        {
            while( pPage->GetNext() && rPt.Y() > pPage->Frm().Bottom() )
                pPage = static_cast<const SwPageFrm*>( pPage->GetNext() );
            SwDoc *pDoc = GetDoc();
            for ( USHORT i = 0; i < GetDoc()->GetPageDescCnt(); ++i )
            {
                if ( pPage->GetPageDesc() == &const_cast<const SwDoc *>(pDoc)
                     ->GetPageDesc(i) )
                    return i;
            }
        }
    }
    return 0;
}

USHORT SwFEShell::GetCurPageDesc( const BOOL bCalcFrm ) const
{
    const SwFrm *pFrm = GetCurrFrm( bCalcFrm );
    if ( pFrm )
    {
        const SwPageFrm *pPage = pFrm->FindPageFrm();
        if ( pPage )
        {
            SwDoc *pDoc = GetDoc();
            for ( USHORT i = 0; i < GetDoc()->GetPageDescCnt(); ++i )
            {
                if ( pPage->GetPageDesc() == &const_cast<const SwDoc *>(pDoc)
                     ->GetPageDesc(i) )
                    return i;
            }
        }
    }
    return 0;
}

// if inside all selection only one PageDesc, return this.
// Otherwise return 0 pointer
const SwPageDesc* SwFEShell::GetSelectedPageDescs() const
{
    const SwCntntNode* pCNd;
    const SwFrm* pMkFrm, *pPtFrm;
    const SwPageDesc* pFnd, *pRetDesc = (SwPageDesc*)0xffffffff;
    const Point aNulPt;

    FOREACHPAM_START(this)

        if( 0 != (pCNd = PCURCRSR->GetCntntNode() ) &&
            0 != ( pPtFrm = pCNd->GetFrm( &aNulPt, 0, FALSE )) )
            pPtFrm = pPtFrm->FindPageFrm();
        else
            pPtFrm = 0;

        if( PCURCRSR->HasMark() &&
            0 != (pCNd = PCURCRSR->GetCntntNode( FALSE ) ) &&
            0 != ( pMkFrm = pCNd->GetFrm( &aNulPt, 0, FALSE )) )
            pMkFrm = pMkFrm->FindPageFrm();
        else
            pMkFrm = pPtFrm;

        if( !pMkFrm || !pPtFrm )
            pFnd = 0;
        else if( pMkFrm == pPtFrm )
            pFnd = ((SwPageFrm*)pMkFrm)->GetPageDesc();
        else
        {
            // swap pointer if PtFrm before MkFrm
            if( ((SwPageFrm*)pMkFrm)->GetPhyPageNum() >
                ((SwPageFrm*)pPtFrm)->GetPhyPageNum() )
            {
                const SwFrm* pTmp = pMkFrm; pMkFrm = pPtFrm; pPtFrm = pTmp;
            }

            // now check from MkFrm to PtFrm for equal PageDescs
            pFnd = ((SwPageFrm*)pMkFrm)->GetPageDesc();
            while( pFnd && pMkFrm != pPtFrm )
            {
                pMkFrm = pMkFrm->GetNext();
                if( !pMkFrm || pFnd != ((SwPageFrm*)pMkFrm)->GetPageDesc() )
                    pFnd = 0;
            }
        }

        if( (SwPageDesc*)0xffffffff == pRetDesc )
            pRetDesc = pFnd;
        else if( pFnd != pRetDesc )
        {
            pRetDesc = 0;
            break;
        }

    FOREACHPAM_END()

    return pRetDesc;
}

<commit_msg>INTEGRATION: CWS swstability02 (1.6.320); FILE MERGED 2006/04/27 12:36:38 ama 1.6.320.1: Fix #i64842#: Copying page descriptor before calling ChgPageDesc (Undo!)<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fedesc.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2006-04-28 15:00:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif

#ifndef _REF_HXX
#include <tools/ref.hxx>
#endif

#ifndef _FESH_HXX
#include <fesh.hxx>
#endif
#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _PAGEFRM_HXX
#include <pagefrm.hxx>
#endif
#ifndef _ROOTFRM_HXX
#include <rootfrm.hxx>
#endif
#ifndef _CNTFRM_HXX
#include <cntfrm.hxx>
#endif
#ifndef _PAM_HXX
#include <pam.hxx>
#endif
#ifndef _NODE_HXX
#include <node.hxx>
#endif
#ifndef _FMTPDSC_HXX //autogen
#include <fmtpdsc.hxx>
#endif
#ifndef _PAGEDESC_HXX
#include <pagedesc.hxx>
#endif
#ifndef _TABFRM_HXX
#include <tabfrm.hxx>
#endif
#ifndef _EDIMP_HXX
#include <edimp.hxx>
#endif
#ifndef _SWSTYLENAMEMAPPER_HXX
#include <SwStyleNameMapper.hxx>
#endif
/*************************************************************************
|*
|*  SwFEShell::GetPageDescCnt()
|*
|*  Ersterstellung      MA 25. Jan. 93
|*  Letzte Aenderung    MA 25. Jan. 93
|*
|*************************************************************************/

USHORT SwFEShell::GetPageDescCnt() const
{
    return GetDoc()->GetPageDescCnt();
}

/*************************************************************************
|*
|*  SwFEShell::ChgCurPageDesc()
|*
|*  Ersterstellung      ST ??
|*  Letzte Aenderung    MA 01. Aug. 94
|*
|*************************************************************************/

void SwFEShell::ChgCurPageDesc( const SwPageDesc& rDesc )
{
#ifndef PRODUCT
    //Die SS veraendert keinen PageDesc, sondern setzt nur das Attribut.
    //Der Pagedesc muss im Dokument vorhanden sein!
    BOOL bFound = FALSE;
    for ( USHORT nTst = 0; nTst < GetPageDescCnt(); ++nTst )
        if ( &rDesc == &GetPageDesc( nTst ) )
            bFound = TRUE;
    ASSERT( bFound, "ChgCurPageDesc mit ungueltigem Descriptor." );
#endif

    StartAllAction();

    SwPageFrm *pPage = GetCurrFrm()->FindPageFrm();
    const SwFrm *pFlow;
    USHORT nPageNmOffset = 0;

    ASSERT( !GetCrsr()->HasMark(), "ChgCurPageDesc nur ohne Selektion!");

    SET_CURR_SHELL( this );
    while ( pPage )
    {
        pFlow = pPage->FindFirstBodyCntnt();
        if ( pFlow )
        {
            if ( pFlow->IsInTab() )
                pFlow = pFlow->FindTabFrm();
            const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
            if( rPgDesc.GetPageDesc() )
            {
                // wir haben ihn den Schlingel
                nPageNmOffset = rPgDesc.GetNumOffset();
                break;
            }
        }
        pPage = (SwPageFrm*) pPage->GetPrev();
    }
    if ( !pPage )
    {
        pPage = (SwPageFrm*) (GetLayout()->Lower());
        pFlow = pPage->FindFirstBodyCntnt();
        if ( !pFlow )
        {
            pPage   = (SwPageFrm*)pPage->GetNext();
            pFlow = pPage->FindFirstBodyCntnt();
            ASSERT( pFlow, "Dokuemnt ohne Inhalt?!?" );
        }
    }

    // Seitennummer mitnehmen
    SwFmtPageDesc aNew( &rDesc );
    aNew.SetNumOffset( nPageNmOffset );

    if ( pFlow->IsInTab() )
        GetDoc()->SetAttr( aNew, *(SwFmt*)pFlow->FindTabFrm()->GetFmt() );
    else
    {
        SwPaM aPaM( *((SwCntntFrm*)pFlow)->GetNode() );
        GetDoc()->Insert( aPaM, aNew );
    }
    EndAllActionAndCall();
}

/*************************************************************************
|*
|*  SwFEShell::ChgPageDesc()
|*
|*  Ersterstellung      MA 25. Jan. 93
|*  Letzte Aenderung    MA 24. Jan. 95
|*
|*************************************************************************/

void SwFEShell::ChgPageDesc( USHORT i, const SwPageDesc &rChged )
{
    StartAllAction();
    SET_CURR_SHELL( this );
    //Fix i64842: because Undo has a very special way to handle header/footer content
    // we have to copy the page descriptor before calling ChgPageDesc.
    const sal_Bool bDoesUndo( GetDoc()->DoesUndo() );
    SwPageDesc aDesc( rChged );
    GetDoc()->DoUndo( sal_False );
    GetDoc()->CopyPageDesc(rChged, aDesc);
    GetDoc()->DoUndo( bDoesUndo );
    GetDoc()->ChgPageDesc( i, aDesc );
    EndAllActionAndCall();
}

/*************************************************************************
|*
|*  SwFEShell::GetPageDesc(), GetCurPageDesc()
|*
|*  Ersterstellung      MA 25. Jan. 93
|*  Letzte Aenderung    MA 23. Apr. 93
|
|*************************************************************************/

const SwPageDesc& SwFEShell::GetPageDesc( USHORT i ) const
{
    return const_cast<const SwDoc *>(GetDoc())->GetPageDesc( i );
}

SwPageDesc* SwFEShell::FindPageDescByName( const String& rName,
                                            BOOL bGetFromPool,
                                            USHORT* pPos )
{
    SwPageDesc* pDesc = GetDoc()->FindPageDescByName( rName, pPos );
    if( !pDesc && bGetFromPool )
    {
        USHORT nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( rName, GET_POOLID_PAGEDESC );
        if( USHRT_MAX != nPoolId &&
            0 != (pDesc = GetDoc()->GetPageDescFromPool( nPoolId ))
            && pPos )
                // werden immer hinten angehaengt
            *pPos = GetDoc()->GetPageDescCnt() - 1 ;
    }
    return pDesc;
}

USHORT SwFEShell::GetMousePageDesc( const Point &rPt ) const
{
    if( GetLayout() )
    {
        const SwPageFrm* pPage =
            static_cast<const SwPageFrm*>( GetLayout()->Lower() );
        if( pPage )
        {
            while( pPage->GetNext() && rPt.Y() > pPage->Frm().Bottom() )
                pPage = static_cast<const SwPageFrm*>( pPage->GetNext() );
            SwDoc *pDoc = GetDoc();
            for ( USHORT i = 0; i < GetDoc()->GetPageDescCnt(); ++i )
            {
                if ( pPage->GetPageDesc() == &const_cast<const SwDoc *>(pDoc)
                     ->GetPageDesc(i) )
                    return i;
            }
        }
    }
    return 0;
}

USHORT SwFEShell::GetCurPageDesc( const BOOL bCalcFrm ) const
{
    const SwFrm *pFrm = GetCurrFrm( bCalcFrm );
    if ( pFrm )
    {
        const SwPageFrm *pPage = pFrm->FindPageFrm();
        if ( pPage )
        {
            SwDoc *pDoc = GetDoc();
            for ( USHORT i = 0; i < GetDoc()->GetPageDescCnt(); ++i )
            {
                if ( pPage->GetPageDesc() == &const_cast<const SwDoc *>(pDoc)
                     ->GetPageDesc(i) )
                    return i;
            }
        }
    }
    return 0;
}

// if inside all selection only one PageDesc, return this.
// Otherwise return 0 pointer
const SwPageDesc* SwFEShell::GetSelectedPageDescs() const
{
    const SwCntntNode* pCNd;
    const SwFrm* pMkFrm, *pPtFrm;
    const SwPageDesc* pFnd, *pRetDesc = (SwPageDesc*)0xffffffff;
    const Point aNulPt;

    FOREACHPAM_START(this)

        if( 0 != (pCNd = PCURCRSR->GetCntntNode() ) &&
            0 != ( pPtFrm = pCNd->GetFrm( &aNulPt, 0, FALSE )) )
            pPtFrm = pPtFrm->FindPageFrm();
        else
            pPtFrm = 0;

        if( PCURCRSR->HasMark() &&
            0 != (pCNd = PCURCRSR->GetCntntNode( FALSE ) ) &&
            0 != ( pMkFrm = pCNd->GetFrm( &aNulPt, 0, FALSE )) )
            pMkFrm = pMkFrm->FindPageFrm();
        else
            pMkFrm = pPtFrm;

        if( !pMkFrm || !pPtFrm )
            pFnd = 0;
        else if( pMkFrm == pPtFrm )
            pFnd = ((SwPageFrm*)pMkFrm)->GetPageDesc();
        else
        {
            // swap pointer if PtFrm before MkFrm
            if( ((SwPageFrm*)pMkFrm)->GetPhyPageNum() >
                ((SwPageFrm*)pPtFrm)->GetPhyPageNum() )
            {
                const SwFrm* pTmp = pMkFrm; pMkFrm = pPtFrm; pPtFrm = pTmp;
            }

            // now check from MkFrm to PtFrm for equal PageDescs
            pFnd = ((SwPageFrm*)pMkFrm)->GetPageDesc();
            while( pFnd && pMkFrm != pPtFrm )
            {
                pMkFrm = pMkFrm->GetNext();
                if( !pMkFrm || pFnd != ((SwPageFrm*)pMkFrm)->GetPageDesc() )
                    pFnd = 0;
            }
        }

        if( (SwPageDesc*)0xffffffff == pRetDesc )
            pRetDesc = pFnd;
        else if( pFnd != pRetDesc )
        {
            pRetDesc = 0;
            break;
        }

    FOREACHPAM_END()

    return pRetDesc;
}

<|endoftext|>


<commit_before>#include <cstdio>

using namespace std;

struct complex
{
	double re, im;
	complex(double _re = 0, double _im = 0) : re(_re), im(_im) { }
};

complex operator + (const complex &x, const complex &y)
{
	return complex(x.re + y.re, x.im + y.im);
}

complex operator - (const complex &x, const complex &y)
{
	return complex(x.re - y.re, x.im - y.im);
}

complex operator * (const complex &x, const complex &y)
{
	return complex(x.re * y.re - x.im * y.im, x.re * y.re + x.im * y.im);
}

complex operator / (const complex &x, const complex &y)
{
	return complex((x.re * y.re + x.im * y.im) / (y.re * y.re + y.im * y.im), (x.im * y.re - x.re * y.im) / (y.re * y.re + y.im * y.im));
}

int main()
{
	complex x, y, res;
	char op;
	while (true)
	{
		scanf("%lf%lf %c %lf%lf", &x.re, &x.im, &op, &y.re, &y.im);
		switch (op)
		{
		case '+':
			res = x + y;
			break;
		case '-':
			res = x - y;
			break;
		case '*':
			res = x * y;
			break;
		case '/':
			res = x / y;
			break;
		default:
			continue;
		}
		printf("(%.2lf + (%.2lf)i) %c (%.2lf + (%.2lf)i) = %.2lf + (%.2lf)i\n", x.re, x.im, op, y.re, y.im, res.re, res.im);
	}
	return 0;
}
<commit_msg>修正错误的复数乘法<commit_after>#include <cstdio>

using namespace std;

struct complex
{
	double re, im;
	complex(double _re = 0, double _im = 0) : re(_re), im(_im) { }
};

complex operator + (const complex &x, const complex &y)
{
	return complex(x.re + y.re, x.im + y.im);
}

complex operator - (const complex &x, const complex &y)
{
	return complex(x.re - y.re, x.im - y.im);
}

complex operator * (const complex &x, const complex &y)
{
	return complex(x.re * y.re - x.im * y.im, x.re * y.im + x.im * y.re);
}

complex operator / (const complex &x, const complex &y)
{
	return complex((x.re * y.re + x.im * y.im) / (y.re * y.re + y.im * y.im), (x.im * y.re - x.re * y.im) / (y.re * y.re + y.im * y.im));
}

int main()
{
	complex x, y, res;
	char op;
	while (true)
	{
		scanf("%lf%lf %c %lf%lf", &x.re, &x.im, &op, &y.re, &y.im);
		switch (op)
		{
		case '+':
			res = x + y;
			break;
		case '-':
			res = x - y;
			break;
		case '*':
			res = x * y;
			break;
		case '/':
			res = x / y;
			break;
		default:
			continue;
		}
		printf("(%.2lf + (%.2lf)i) %c (%.2lf + (%.2lf)i) = %.2lf + (%.2lf)i\n", x.re, x.im, op, y.re, y.im, res.re, res.im);
	}
	return 0;
}
<|endoftext|>


<commit_before>#include <fstream>
#include <sstream>
#include <stdexcept>
#include <string>

#include "drake/Path.h"
#include "drake/common/drake_assert.h"
#include "drake/thirdParty/tinydir/tinydir.h"
#include "drake/util/drakeGeometryUtil.h"
#include "xmlUtil.h"

using namespace std;
using namespace Eigen;
using namespace tinyxml2;

void ParseThreeVectorValue(const char* strval, Eigen::Vector3d* val) {
  if (val == nullptr) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter \"val\" is null.");
  }

  // Handles the case where strval is a nullptr.
  if (!strval) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter \"strval\" is null.");
  }

  // Handles the case where strval is an empty strval.
  if (std::string(strval) == "") {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter \"strval\" is empty.");
  }

  std::stringstream ss(strval);
  std::string token;
  ss >> token;

  (*val)[0] = StringToDouble(token);

  // Handles the case where strval is a single scalar value.
  if (!ss.good()) {
    (*val)[1] = (*val)[0];
    (*val)[2] = (*val)[0];
    return;
  }

  ss >> token;
  (*val)[1] = StringToDouble(token);

  // Handles the case where strval is a 2 vector.
  if (!ss.good()) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: A 2 vector was supplied.");
  }

  ss >> token;
  (*val)[2] = StringToDouble(token);

  // Handles the case where strval is vector that's longer than 3.
  if (ss.good()) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: A vector with more than three "
        "elements was supplied.");
  }
}

double StringToDouble(const string& str) {
  std::size_t num_chars = 0;
  double result = std::stod(str, &num_chars);

  // Verifies that there are no additional characters after the double value.
  if (str.size() != num_chars) {
    throw std::invalid_argument(
        "ERROR: Double value contained additional characters after the "
        "number.");
  }

  return result;
}

void ParseThreeVectorValue(const tinyxml2::XMLElement* node,
                           Eigen::Vector3d* val) {
  if (node) {
    ParseThreeVectorValue(node->FirstChild()->Value(), val);
  } else {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter "
        "\"node\" is null.");
  }
}

void ParseThreeVectorValue(const tinyxml2::XMLElement* node,
                           const char* element_name, Eigen::Vector3d* val) {
  if (!node || !element_name) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter"
        "\"node\" and/or parameter \"element_name\" is null.");
  } else {
    const tinyxml2::XMLElement* child_node =
        node->FirstChildElement(element_name);
    if (child_node == nullptr) {
      throw std::invalid_argument("ERROR: ParseThreeVectorValue: Element \"" +
                                  std::string(element_name) + "\" not found.");
    }
    ParseThreeVectorValue(child_node, val);
  }
}

void ParseThreeVectorAttribute(const tinyxml2::XMLElement* node,
                               const char* attribute_name,
                               Eigen::Vector3d* val) {
  if (!node || !attribute_name) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorAttribute: Parameter"
        "\"node\" and/or parameter \"attribute_name\" is null.");
  } else {
    const char* scale = node->Attribute(attribute_name);
    if (scale == nullptr) {
      throw std::invalid_argument(
          "ERROR: ParseThreeVectorAttribute: Attribute \"" +
          std::string(attribute_name) + "\" not found.");
    }
    ParseThreeVectorValue(scale, val);
  }
}

// only writes values if they exist
bool parseVectorAttribute(const tinyxml2::XMLElement* node,
                          const char* attribute_name, Eigen::Vector3d& val) {
  const char* attr = node->Attribute(attribute_name);
  if (attr) {
    std::stringstream s(attr);
    s >> val(0) >> val(1) >> val(2);
    return true;
  }
  return false;
}

bool parseVectorAttribute(const tinyxml2::XMLElement* node,
                          const char* attribute_name, Eigen::Vector4d& val) {
  const char* attr = node->Attribute(attribute_name);
  if (attr) {
    std::stringstream s(attr);
    s >> val(0) >> val(1) >> val(2) >> val(3);
    return true;
  }
  return false;
}

bool parseVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                      Eigen::Vector3d& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    std::stringstream s(elnode->FirstChild()->Value());
    s >> val(0) >> val(1) >> val(2);
    return true;
  }
  return false;
}

bool parseVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                      Eigen::Vector4d& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    std::stringstream s(elnode->FirstChild()->Value());
    s >> val(0) >> val(1) >> val(2) >> val(3);
    return true;
  }
  return false;
}

bool parseStringValue(tinyxml2::XMLElement* node, const char* element_name,
                      std::string& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    val = elnode->FirstChild()->Value();
    return true;
  }
  return false;
}

void originAttributesToTransform(tinyxml2::XMLElement* node,
                                 Eigen::Isometry3d& T) {
  Eigen::Vector3d rpy = Eigen::Vector3d::Zero(), xyz = Eigen::Vector3d::Zero();

  parseVectorAttribute(node, "xyz", xyz);
  parseVectorAttribute(node, "rpy", rpy);

  T.matrix() << rpy2rotmat(rpy), xyz, 0, 0, 0, 1;
}

void poseValueToTransform(tinyxml2::XMLElement* node, const PoseMap& pose_map,
                          Eigen::Isometry3d& T,
                          const Eigen::Isometry3d& T_default_frame) {
  Eigen::Vector3d rpy = Eigen::Vector3d::Zero(), xyz = Eigen::Vector3d::Zero();
  const char* strval = node->FirstChild()->Value();
  if (strval) {
    std::stringstream s(strval);
    s >> xyz(0) >> xyz(1) >> xyz(2) >> rpy(0) >> rpy(1) >> rpy(2);
  }

  T.matrix() << rpy2rotmat(rpy), xyz, 0, 0, 0, 1;

  const char* attr = node->Attribute("frame");
  if (attr && strlen(attr) > 0) {
    std::string frame;
    std::stringstream s(attr);
    s >> frame;
    // This could cause problems with the default pose assumptions in
    // the sdf parser, which I simply had to guess.
    DRAKE_ASSERT(0 && "this has not been tested yet");
    Eigen::Isometry3d T_frame =
        pose_map.at(frame);  // will throw an exception if the frame is not
                             // found.  that is the desired behavior.
    T = T_frame * T;
  } else {
    T = T_default_frame * T;
  }
}

namespace {
void searchDirectory(map<string, string>& package_map, string path) {
#if defined(WIN32) || defined(WIN64)
  const char pathsep = ';';
#else
  const char pathsep = ':';
#endif

  string token, t;
  istringstream iss(path);
  const std::string target_filename("package.xml");

  while (getline(iss, token, pathsep)) {
    tinydir_dir dir;
    if (tinydir_open(&dir, token.c_str()) < 0) {
      std::cerr << "Unable to open directory: " << token << std::endl;
      continue;
    }

    while (dir.has_next) {
      tinydir_file file;
      tinydir_readfile(&dir, &file);

      // Skip hidden directories (including, importantly, "." and "..").
      if (file.is_dir && (file.name[0] != '.')) {
        searchDirectory(package_map, file.path);
      } else if (file.name == target_filename) {
        spruce::path mypath_s(file.path);
        auto path_split = mypath_s.split();
        if (path_split.size() > 2) {
          string package = path_split.at(path_split.size() - 2);
          auto package_iter = package_map.find(package);
          // Don't overwrite entries in the map
          if (package_iter == package_map.end()) {
            package_map.insert(make_pair(package, mypath_s.root().append("/")));
          }
        }
      }
      tinydir_next(&dir);
    }
    tinydir_close(&dir);
  }
}
}

void populatePackageMap(map<string, string>& package_map) {
  searchDirectory(package_map, Drake::getDrakePath());

  char* cstrpath = getenv("ROS_ROOT");
  if (cstrpath) searchDirectory(package_map, cstrpath);

  cstrpath = getenv("ROS_PACKAGE_PATH");
  if (cstrpath) searchDirectory(package_map, cstrpath);
}

namespace {
bool rospack(const string& package, const map<string, string>& package_map,
             string& package_path) {
  // my own quick and dirty implementation of the rospack algorithm (based on my
  // matlab version in rospack.m)
  auto iter = package_map.find(package);
  if (iter != package_map.end()) {
    package_path = iter->second;
    return true;
  } else {
    cerr << "Warning: Couldn't find package '" << package
         << "' in ROS_ROOT, ROS_PACKAGE_PATH, or user supplied package map"
         << endl;
    return false;
  }
}
}

string resolveFilename(const string& filename,
                       const map<string, string>& package_map,
                       const string& root_dir) {
  spruce::path mesh_filename_s;
  spruce::path raw_filename_s(filename);

  auto split_filename = raw_filename_s.split();

  if (split_filename.front() == "package:") {
    string package_path_string;
    if (rospack(split_filename.at(2), package_map, package_path_string)) {
      spruce::path package_path_s = spruce::path(package_path_string);
      mesh_filename_s = package_path_s;

      auto split_raw = raw_filename_s.split();
      for (int i = 1; i < split_raw.size() - 2; ++i) {
        mesh_filename_s.append(split_raw.at(i + 2));
      }
    } else {
      cerr << "Warning: Mesh '" << filename
           << "' could not be resolved and will be ignored by Drake." << endl;
      return string();
    }
  } else {
    std::string normalized_root_dir = spruce::path(root_dir).getStr();

// if root_dir is a relative path then convert it to absolute
#ifdef _WIN32
    bool dirIsRelative = !(normalized_root_dir.size() >= 2 &&
                           std::isalpha(normalized_root_dir[0]) &&
                           normalized_root_dir[1] == ':');
#else
    bool dirIsRelative =
        !(normalized_root_dir.size() >= 1 && normalized_root_dir[0] == '/');
#endif
    if (dirIsRelative) {
      mesh_filename_s = spruce::path();
      mesh_filename_s.setAsCurrent();
      mesh_filename_s.append(normalized_root_dir);
    } else {
      mesh_filename_s = spruce::path(normalized_root_dir);
    }

    mesh_filename_s.append(filename);
  }
  if (!mesh_filename_s.exists()) {
    cerr << "Warning: File '" << mesh_filename_s.getStr()
         << "' could not be found." << endl;
    cerr << "Warning: Mesh '" << filename
         << "' could not be resolved and will be ignored by Drake." << endl;
    return string();
  }
  return mesh_filename_s.getStr();
}
<commit_msg>Fixed testXmlUtil.testPopulatePackageMap unit test.<commit_after>#include <fstream>
#include <sstream>
#include <stdexcept>
#include <string>

#include "drake/Path.h"
#include "drake/common/drake_assert.h"
#include "drake/thirdParty/tinydir/tinydir.h"
#include "drake/util/drakeGeometryUtil.h"
#include "xmlUtil.h"

using namespace std;
using namespace Eigen;
using namespace tinyxml2;

void ParseThreeVectorValue(const char* strval, Eigen::Vector3d* val) {
  if (val == nullptr) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter \"val\" is null.");
  }

  // Handles the case where strval is a nullptr.
  if (!strval) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter \"strval\" is null.");
  }

  // Handles the case where strval is an empty strval.
  if (std::string(strval) == "") {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter \"strval\" is empty.");
  }

  std::stringstream ss(strval);
  std::string token;
  ss >> token;

  (*val)[0] = StringToDouble(token);

  // Handles the case where strval is a single scalar value.
  if (!ss.good()) {
    (*val)[1] = (*val)[0];
    (*val)[2] = (*val)[0];
    return;
  }

  ss >> token;
  (*val)[1] = StringToDouble(token);

  // Handles the case where strval is a 2 vector.
  if (!ss.good()) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: A 2 vector was supplied.");
  }

  ss >> token;
  (*val)[2] = StringToDouble(token);

  // Handles the case where strval is vector that's longer than 3.
  if (ss.good()) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: A vector with more than three "
        "elements was supplied.");
  }
}

double StringToDouble(const string& str) {
  std::size_t num_chars = 0;
  double result = std::stod(str, &num_chars);

  // Verifies that there are no additional characters after the double value.
  if (str.size() != num_chars) {
    throw std::invalid_argument(
        "ERROR: Double value contained additional characters after the "
        "number.");
  }

  return result;
}

void ParseThreeVectorValue(const tinyxml2::XMLElement* node,
                           Eigen::Vector3d* val) {
  if (node) {
    ParseThreeVectorValue(node->FirstChild()->Value(), val);
  } else {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter "
        "\"node\" is null.");
  }
}

void ParseThreeVectorValue(const tinyxml2::XMLElement* node,
                           const char* element_name, Eigen::Vector3d* val) {
  if (!node || !element_name) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorValue: Parameter"
        "\"node\" and/or parameter \"element_name\" is null.");
  } else {
    const tinyxml2::XMLElement* child_node =
        node->FirstChildElement(element_name);
    if (child_node == nullptr) {
      throw std::invalid_argument("ERROR: ParseThreeVectorValue: Element \"" +
                                  std::string(element_name) + "\" not found.");
    }
    ParseThreeVectorValue(child_node, val);
  }
}

void ParseThreeVectorAttribute(const tinyxml2::XMLElement* node,
                               const char* attribute_name,
                               Eigen::Vector3d* val) {
  if (!node || !attribute_name) {
    throw std::invalid_argument(
        "ERROR: ParseThreeVectorAttribute: Parameter"
        "\"node\" and/or parameter \"attribute_name\" is null.");
  } else {
    const char* scale = node->Attribute(attribute_name);
    if (scale == nullptr) {
      throw std::invalid_argument(
          "ERROR: ParseThreeVectorAttribute: Attribute \"" +
          std::string(attribute_name) + "\" not found.");
    }
    ParseThreeVectorValue(scale, val);
  }
}

// only writes values if they exist
bool parseVectorAttribute(const tinyxml2::XMLElement* node,
                          const char* attribute_name, Eigen::Vector3d& val) {
  const char* attr = node->Attribute(attribute_name);
  if (attr) {
    std::stringstream s(attr);
    s >> val(0) >> val(1) >> val(2);
    return true;
  }
  return false;
}

bool parseVectorAttribute(const tinyxml2::XMLElement* node,
                          const char* attribute_name, Eigen::Vector4d& val) {
  const char* attr = node->Attribute(attribute_name);
  if (attr) {
    std::stringstream s(attr);
    s >> val(0) >> val(1) >> val(2) >> val(3);
    return true;
  }
  return false;
}

bool parseVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                      Eigen::Vector3d& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    std::stringstream s(elnode->FirstChild()->Value());
    s >> val(0) >> val(1) >> val(2);
    return true;
  }
  return false;
}

bool parseVectorValue(tinyxml2::XMLElement* node, const char* element_name,
                      Eigen::Vector4d& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    std::stringstream s(elnode->FirstChild()->Value());
    s >> val(0) >> val(1) >> val(2) >> val(3);
    return true;
  }
  return false;
}

bool parseStringValue(tinyxml2::XMLElement* node, const char* element_name,
                      std::string& val) {
  XMLElement* elnode = node->FirstChildElement(element_name);
  if (elnode && elnode->FirstChild()) {
    val = elnode->FirstChild()->Value();
    return true;
  }
  return false;
}

void originAttributesToTransform(tinyxml2::XMLElement* node,
                                 Eigen::Isometry3d& T) {
  Eigen::Vector3d rpy = Eigen::Vector3d::Zero(), xyz = Eigen::Vector3d::Zero();

  parseVectorAttribute(node, "xyz", xyz);
  parseVectorAttribute(node, "rpy", rpy);

  T.matrix() << rpy2rotmat(rpy), xyz, 0, 0, 0, 1;
}

void poseValueToTransform(tinyxml2::XMLElement* node, const PoseMap& pose_map,
                          Eigen::Isometry3d& T,
                          const Eigen::Isometry3d& T_default_frame) {
  Eigen::Vector3d rpy = Eigen::Vector3d::Zero(), xyz = Eigen::Vector3d::Zero();
  const char* strval = node->FirstChild()->Value();
  if (strval) {
    std::stringstream s(strval);
    s >> xyz(0) >> xyz(1) >> xyz(2) >> rpy(0) >> rpy(1) >> rpy(2);
  }

  T.matrix() << rpy2rotmat(rpy), xyz, 0, 0, 0, 1;

  const char* attr = node->Attribute("frame");
  if (attr && strlen(attr) > 0) {
    std::string frame;
    std::stringstream s(attr);
    s >> frame;
    // This could cause problems with the default pose assumptions in
    // the sdf parser, which I simply had to guess.
    DRAKE_ASSERT(0 && "this has not been tested yet");
    Eigen::Isometry3d T_frame =
        pose_map.at(frame);  // will throw an exception if the frame is not
                             // found.  that is the desired behavior.
    T = T_frame * T;
  } else {
    T = T_default_frame * T;
  }
}

namespace {
void searchDirectory(map<string, string>& package_map, string path) {
#if defined(WIN32) || defined(WIN64)
  const char pathsep = ';';
#else
  const char pathsep = ':';
#endif

  string token, t;
  istringstream iss(path);
  const std::string target_filename("package.xml");

  while (getline(iss, token, pathsep)) {
    tinydir_dir dir;
    if (tinydir_open(&dir, token.c_str()) < 0) {
      std::cerr << "Unable to open directory: " << token << std::endl;
      continue;
    }

    while (dir.has_next) {
      tinydir_file file;
      tinydir_readfile(&dir, &file);

      // Skip hidden directories (including, importantly, "." and "..").
      if (file.is_dir && (file.name[0] != '.')) {
        searchDirectory(package_map, file.path);
      } else if (file.name == target_filename) {
        spruce::path mypath_s(file.path);
        auto path_split = mypath_s.split();
        if (path_split.size() > 2) {
          string package = path_split.at(path_split.size() - 2);
          auto package_iter = package_map.find(package);
          // Don't overwrite entries in the map
          if (package_iter == package_map.end()) {
            package_map.insert(make_pair(package, mypath_s.root().append("/")));
          }
        }
      }
      tinydir_next(&dir);
    }
    tinydir_close(&dir);
  }
}
}

void populatePackageMap(map<string, string>& package_map) {
  // Since Drake's package.xml file is located at its super-build level,
  // remove the last "drake" directory from the drake path. Also omit the
  // trailing slash.
  std::string drake_path = Drake::getDrakePath();
  std::string drake_path_parent = drake_path.substr(0,
    drake_path.find_last_of("drake") - std::string("drake").size());
  searchDirectory(package_map, drake_path_parent);

  char* cstrpath = getenv("ROS_ROOT");
  if (cstrpath) searchDirectory(package_map, cstrpath);

  cstrpath = getenv("ROS_PACKAGE_PATH");
  if (cstrpath) searchDirectory(package_map, cstrpath);
}

namespace {
bool rospack(const string& package, const map<string, string>& package_map,
             string& package_path) {
  // my own quick and dirty implementation of the rospack algorithm (based on my
  // matlab version in rospack.m)
  auto iter = package_map.find(package);
  if (iter != package_map.end()) {
    package_path = iter->second;
    return true;
  } else {
    cerr << "Warning: Couldn't find package '" << package
         << "' in ROS_ROOT, ROS_PACKAGE_PATH, or user supplied package map"
         << endl;
    return false;
  }
}
}

string resolveFilename(const string& filename,
                       const map<string, string>& package_map,
                       const string& root_dir) {
  spruce::path mesh_filename_s;
  spruce::path raw_filename_s(filename);

  auto split_filename = raw_filename_s.split();

  if (split_filename.front() == "package:") {
    string package_path_string;
    if (rospack(split_filename.at(2), package_map, package_path_string)) {
      spruce::path package_path_s = spruce::path(package_path_string);
      mesh_filename_s = package_path_s;

      auto split_raw = raw_filename_s.split();
      for (int i = 1; i < split_raw.size() - 2; ++i) {
        mesh_filename_s.append(split_raw.at(i + 2));
      }
    } else {
      cerr << "Warning: Mesh '" << filename
           << "' could not be resolved and will be ignored by Drake." << endl;
      return string();
    }
  } else {
    std::string normalized_root_dir = spruce::path(root_dir).getStr();

// if root_dir is a relative path then convert it to absolute
#ifdef _WIN32
    bool dirIsRelative = !(normalized_root_dir.size() >= 2 &&
                           std::isalpha(normalized_root_dir[0]) &&
                           normalized_root_dir[1] == ':');
#else
    bool dirIsRelative =
        !(normalized_root_dir.size() >= 1 && normalized_root_dir[0] == '/');
#endif
    if (dirIsRelative) {
      mesh_filename_s = spruce::path();
      mesh_filename_s.setAsCurrent();
      mesh_filename_s.append(normalized_root_dir);
    } else {
      mesh_filename_s = spruce::path(normalized_root_dir);
    }

    mesh_filename_s.append(filename);
  }
  if (!mesh_filename_s.exists()) {
    cerr << "Warning: File '" << mesh_filename_s.getStr()
         << "' could not be found." << endl;
    cerr << "Warning: Mesh '" << filename
         << "' could not be resolved and will be ignored by Drake." << endl;
    return string();
  }
  return mesh_filename_s.getStr();
}
<|endoftext|>


<commit_before>#include "server_https.hpp"
#include "client_https.hpp"

//Added for the json-example
#define BOOST_SPIRIT_THREADSAFE
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

//Added for the default_resource example
#include <fstream>
#include <boost/filesystem.hpp>
#include <vector>
#include <algorithm>

using namespace std;
//Added for the json-example:
using namespace boost::property_tree;

typedef SimpleWeb::Server<SimpleWeb::HTTPS> HttpsServer;
typedef SimpleWeb::Client<SimpleWeb::HTTPS> HttpsClient;

//Added for the default_resource example
void default_resource_send(const HttpsServer &server, const shared_ptr<HttpsServer::Response> &response,
                           const shared_ptr<ifstream> &ifs);

int main() {
    //HTTPS-server at port 8080 using 1 thread
    //Unless you do more heavy non-threaded processing in the resources,
    //1 thread is usually faster than several threads
    HttpsServer server(8080, 1, "server.crt", "server.key");

    //Add resources using path-regex and method-string, and an anonymous function
    //POST-example for the path /string, responds the posted string
    server.resource["^/string$"]["POST"]=[](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        //Retrieve string:
        auto content=request->content.string();
        //request->content.string() is a convenience function for:
        //stringstream ss;
        //ss << request->content.rdbuf();
        //string content=ss.str();

        *response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
    };

    //POST-example for the path /json, responds firstName+" "+lastName from the posted json
    //Responds with an appropriate error message if the posted json is not valid, or if firstName or lastName is missing
    //Example posted json:
    //{
    //  "firstName": "John",
    //  "lastName": "Smith",
    //  "age": 25
    //}
    server.resource["^/json$"]["POST"]=[](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        try {
            ptree pt;
            read_json(request->content, pt);

            string name=pt.get<string>("firstName")+" "+pt.get<string>("lastName");

            *response << "HTTP/1.1 200 OK\r\n"
                      << "Content-Type: application/json\r\n"
                      << "Content-Length: " << name.length() << "\r\n\r\n"
                      << name;
        }
        catch(exception& e) {
            *response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << strlen(e.what()) << "\r\n\r\n" << e.what();
        }
    };

    //GET-example for the path /info
    //Responds with request-information
    server.resource["^/info$"]["GET"]=[](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        stringstream content_stream;
        content_stream << "
Request from " << request->remote_endpoint_address << " (" << request->remote_endpoint_port << ")
";
        content_stream << request->method << " " << request->path << " HTTP/" << request->http_version << "
";
        for(auto& header: request->header) {
            content_stream << header.first << ": " << header.second << "
";
        }

        //find length of content_stream (length received using content_stream.tellp())
        content_stream.seekp(0, ios::end);

        *response <<  "HTTP/1.1 200 OK\r\nContent-Length: " << content_stream.tellp() << "\r\n\r\n" << content_stream.rdbuf();
    };

    //GET-example for the path /match/[number], responds with the matched string in path (number)
    //For instance a request GET /match/123 will receive: 123
    server.resource["^/match/([0-9]+)$"]["GET"]=[&server](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        string number=request->path_match[1];
        *response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
    };

    //Get example simulating heavy work in a separate thread
    server.resource["^/work$"]["GET"]=[&server](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> /*request*/) {
        thread work_thread([response] {
            this_thread::sleep_for(chrono::seconds(5));
            string message="Work done";
            *response << "HTTP/1.1 200 OK\r\nContent-Length: " << message.length() << "\r\n\r\n" << message;
        });
        work_thread.detach();
    };

    //Default GET-example. If no other matches, this anonymous function will be called.
    //Will respond with content in the web/-directory, and its subdirectories.
    //Default file: index.html
    //Can for instance be used to retrieve an HTML 5 client that uses REST-resources on this server
    server.default_resource["GET"]=[&server](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        try {
            auto web_root_path=boost::filesystem::canonical("web");
            auto path=boost::filesystem::canonical(web_root_path/request->path);
            //Check if path is within web_root_path
            if(distance(web_root_path.begin(), web_root_path.end())>distance(path.begin(), path.end()) ||
               !equal(web_root_path.begin(), web_root_path.end(), path.begin()))
                throw invalid_argument("path must be within root path");
            if(boost::filesystem::is_directory(path))
                path/="index.html";
            if(!(boost::filesystem::exists(path) && boost::filesystem::is_regular_file(path)))
                throw invalid_argument("file does not exist");

            auto ifs=make_shared<ifstream>();
            ifs->open(path.string(), ifstream::in | ios::binary);

            if(*ifs) {
                ifs->seekg(0, ios::end);
                auto length=ifs->tellg();

                ifs->seekg(0, ios::beg);

                *response << "HTTP/1.1 200 OK\r\nContent-Length: " << length << "\r\n\r\n";
                default_resource_send(server, response, ifs);
            }
            else
                throw invalid_argument("could not read file");
        }
        catch(const exception &e) {
            string content="Could not open path "+request->path+": "+e.what();
            *response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
        }
    };

    thread server_thread([&server](){
        //Start server
        server.start();
    });

    //Wait for server to start so that the client can connect
    this_thread::sleep_for(chrono::seconds(1));

    //Client examples
    //Second Client() parameter set to false: no certificate verification
    HttpsClient client("localhost:8080", false);
    auto r1=client.request("GET", "/match/123");
    cout << r1->content.rdbuf() << endl;

    string json_string="{\"firstName\": \"John\",\"lastName\": \"Smith\",\"age\": 25}";
    auto r2=client.request("POST", "/string", json_string);
    cout << r2->content.rdbuf() << endl;

    auto r3=client.request("POST", "/json", json_string);
    cout << r3->content.rdbuf() << endl;

    server_thread.join();

    return 0;
}

void default_resource_send(const HttpsServer &server, const shared_ptr<HttpsServer::Response> &response,
                           const shared_ptr<ifstream> &ifs) {
    //read and send 128 KB at a time
    static vector<char> buffer(131072); // Safe when server is running on one thread
    streamsize read_length;
    if((read_length=ifs->read(&buffer[0], buffer.size()).gcount())>0) {
        response->write(&buffer[0], read_length);
        if(read_length==static_cast<streamsize>(buffer.size())) {
            server.send(response, [&server, response, ifs](const boost::system::error_code &ec) {
                if(!ec)
                    default_resource_send(server, response, ifs);
                else
                    cerr << "Connection interrupted" << endl;
            });
        }
    }
}
<commit_msg>Added support for HTTP caching in the https example<commit_after>#include "server_https.hpp"
#include "client_https.hpp"
#include "crypto.hpp"

//Added for the json-example
#define BOOST_SPIRIT_THREADSAFE
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

//Added for the default_resource example
#include <fstream>
#include <boost/filesystem.hpp>
#include <vector>
#include <algorithm>

using namespace std;
//Added for the json-example:
using namespace boost::property_tree;

typedef SimpleWeb::Server<SimpleWeb::HTTPS> HttpsServer;
typedef SimpleWeb::Client<SimpleWeb::HTTPS> HttpsClient;

//Added for the default_resource example
void default_resource_send(const HttpsServer &server, const shared_ptr<HttpsServer::Response> &response,
                           const shared_ptr<ifstream> &ifs);
std::string build_hash(const std::string full_file_name);
int main() {
    //HTTPS-server at port 8080 using 1 thread
    //Unless you do more heavy non-threaded processing in the resources,
    //1 thread is usually faster than several threads
    HttpsServer server(8080, 1, "server.crt", "server.key");

    //Add resources using path-regex and method-string, and an anonymous function
    //POST-example for the path /string, responds the posted string
    server.resource["^/string$"]["POST"]=[](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        //Retrieve string:
        auto content=request->content.string();
        //request->content.string() is a convenience function for:
        //stringstream ss;
        //ss << request->content.rdbuf();
        //string content=ss.str();

        *response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
    };

    //POST-example for the path /json, responds firstName+" "+lastName from the posted json
    //Responds with an appropriate error message if the posted json is not valid, or if firstName or lastName is missing
    //Example posted json:
    //{
    //  "firstName": "John",
    //  "lastName": "Smith",
    //  "age": 25
    //}
    server.resource["^/json$"]["POST"]=[](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        try {
            ptree pt;
            read_json(request->content, pt);

            string name=pt.get<string>("firstName")+" "+pt.get<string>("lastName");

            *response << "HTTP/1.1 200 OK\r\n"
                      << "Content-Type: application/json\r\n"
                      << "Content-Length: " << name.length() << "\r\n\r\n"
                      << name;
        }
        catch(exception& e) {
            *response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << strlen(e.what()) << "\r\n\r\n" << e.what();
        }
    };

    //GET-example for the path /info
    //Responds with request-information
    server.resource["^/info$"]["GET"]=[](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        stringstream content_stream;
        content_stream << "
Request from " << request->remote_endpoint_address << " (" << request->remote_endpoint_port << ")
";
        content_stream << request->method << " " << request->path << " HTTP/" << request->http_version << "
";
        for(auto& header: request->header) {
            content_stream << header.first << ": " << header.second << "
";
        }

        //find length of content_stream (length received using content_stream.tellp())
        content_stream.seekp(0, ios::end);

        *response <<  "HTTP/1.1 200 OK\r\nContent-Length: " << content_stream.tellp() << "\r\n\r\n" << content_stream.rdbuf();
    };

    //GET-example for the path /match/[number], responds with the matched string in path (number)
    //For instance a request GET /match/123 will receive: 123
    server.resource["^/match/([0-9]+)$"]["GET"]=[&server](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        string number=request->path_match[1];
        *response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
    };

    //Get example simulating heavy work in a separate thread
    server.resource["^/work$"]["GET"]=[&server](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> /*request*/) {
        thread work_thread([response] {
            this_thread::sleep_for(chrono::seconds(5));
            string message="Work done";
            *response << "HTTP/1.1 200 OK\r\nContent-Length: " << message.length() << "\r\n\r\n" << message;
        });
        work_thread.detach();
    };

    //Default GET-example. If no other matches, this anonymous function will be called.
    //Will respond with content in the web/-directory, and its subdirectories.
    //Default file: index.html
    //Can for instance be used to retrieve an HTML 5 client that uses REST-resources on this server
    server.default_resource["GET"]=[&server](shared_ptr<HttpsServer::Response> response, shared_ptr<HttpsServer::Request> request) {
        try {
            auto web_root_path=boost::filesystem::canonical("web");
            auto path=boost::filesystem::canonical(web_root_path/request->path);
            //Check if path is within web_root_path
            if(distance(web_root_path.begin(), web_root_path.end())>distance(path.begin(), path.end()) ||
               !equal(web_root_path.begin(), web_root_path.end(), path.begin()))
                throw invalid_argument("path must be within root path");
            if(boost::filesystem::is_directory(path))
                path/="index.html";
            if(!(boost::filesystem::exists(path) && boost::filesystem::is_regular_file(path)))
                throw invalid_argument("file does not exist");

	    //Support for HTTP Cache
	    std::string hash = build_hash(path.string());
	    auto it=request->header.find("If-None-Match");
	    if(it!=request->header.end()) {
		if (it->second == "\""+hash+"\"") {
		    *response << "HTTP/1.1 304 Not Modified\r\nCache-Control: max-age=86400\r\nETag: \""+hash+"\"\r\n\r\n";
		    return;
		}
	    }

            auto ifs=make_shared<ifstream>();
            ifs->open(path.string(), ifstream::in | ios::binary);

            if(*ifs) {
                ifs->seekg(0, ios::end);
                auto length=ifs->tellg();

                ifs->seekg(0, ios::beg);

                *response << "HTTP/1.1 200 OK\r\nCache-Control: max-age=86400\r\nETag: \""+hash+"\"\r\nContent-Length: " << length << "\r\n\r\n";
                default_resource_send(server, response, ifs);
            }
            else
                throw invalid_argument("could not read file");
        }
        catch(const exception &e) {
            string content="Could not open path "+request->path+": "+e.what();
            *response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
        }
    };

    thread server_thread([&server](){
        //Start server
        server.start();
    });

    //Wait for server to start so that the client can connect
    this_thread::sleep_for(chrono::seconds(1));

    //Client examples
    //Second Client() parameter set to false: no certificate verification
    HttpsClient client("localhost:8080", false);
    auto r1=client.request("GET", "/match/123");
    cout << r1->content.rdbuf() << endl;

    string json_string="{\"firstName\": \"John\",\"lastName\": \"Smith\",\"age\": 25}";
    auto r2=client.request("POST", "/string", json_string);
    cout << r2->content.rdbuf() << endl;

    auto r3=client.request("POST", "/json", json_string);
    cout << r3->content.rdbuf() << endl;

    server_thread.join();

    return 0;
}

void default_resource_send(const HttpsServer &server, const shared_ptr<HttpsServer::Response> &response,
                           const shared_ptr<ifstream> &ifs) {
    //read and send 128 KB at a time
    static vector<char> buffer(131072); // Safe when server is running on one thread
    streamsize read_length;
    if((read_length=ifs->read(&buffer[0], buffer.size()).gcount())>0) {
        response->write(&buffer[0], read_length);
        if(read_length==static_cast<streamsize>(buffer.size())) {
            server.send(response, [&server, response, ifs](const boost::system::error_code &ec) {
                if(!ec)
                    default_resource_send(server, response, ifs);
                else
                    cerr << "Connection interrupted" << endl;
            });
        }
    }
}

std::string build_hash(const std::string full_file_name) {
    std::string ret = "";
    std::ifstream file(full_file_name, std::ios::binary | std::ios::ate);
    std::streamsize size = file.tellg();
    file.seekg(0, std::ios::beg);
    std::vector<char> buffer(size);
    if (!file.read(buffer.data(), size))
        return ret;
    ret = reinterpret_cast<char*> (&buffer[0]);
    return SimpleWeb::Crypto::md5(ret,1);
}
<|endoftext|>


<commit_before>/*
	This file is part of the E_Rendering library.
	Copyright (C) 2009-2012 Benjamin Eikel <benjamin@eikel.org>
	Copyright (C) 2009-2012 Claudius Jähn <claudius@uni-paderborn.de>
	Copyright (C) 2009-2012 Ralf Petring <ralf@petring.net>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "ELibRendering.h"
#include <sstream>

#include "E_BufferObject.h"
#include "E_Draw.h"
#include "E_FBO.h"
#include "E_OcclusionQuery.h"
#include "E_ParameterStructs.h"
#include "E_RenderingContext.h"
#include "E_StatisticsQuery.h"
#include "E_TextRenderer.h"
#include "Mesh/E_Mesh.h"
#include "Mesh/E_VertexAccessor.h"
#include "Mesh/E_VertexAttributeAccessors.h"
#include "Mesh/E_VertexAttribute.h"
#include "Mesh/E_VertexDescription.h"
#include "MeshUtils/E_MeshBuilder.h"
#include "MeshUtils/E_MeshUtils.h"
#include "MeshUtils/E_PlatonicSolids.h"
#include "MeshUtils/E_PrimitiveShapes.h"
#include "MeshUtils/E_TriangleAccessor.h"
#include "MeshUtils/E_ConnectivityAccessor.h"
#include "MeshUtils/E_WireShapes.h"
#include "Shader/E_Shader.h"
#include "Shader/E_Uniform.h"
#include "Texture/E_Texture.h"
#include "Texture/E_TextureUtils.h"

#include <Rendering/Mesh/MeshDataStrategy.h>
#include <Rendering/Helper.h>
#include <Rendering/Serialization/StreamerXYZ.h>
#include <Rendering/Serialization/Serialization.h>
#include <Rendering/Texture/Texture.h>
#include <Rendering/Texture/TextureUtils.h>
#include <Util/IO/FileName.h>

#include <EScript/Basics.h>
#include <EScript/StdObjects.h>

#include <iostream>

namespace E_Rendering{

using namespace EScript;
using namespace Rendering;
//using namespace E_Geometry;
using namespace Geometry;
//using namespace E_Util;

//! E_MeshDataStrategy ---> EScript::ReferenceObject<MeshDataStrategy *>
struct E_MeshDataStrategy:public EScript::ReferenceObject<MeshDataStrategy *>{
	ES_PROVIDES_TYPE_NAME(MeshDataStrategy)
public:

	E_MeshDataStrategy(MeshDataStrategy * s):EScript::ReferenceObject<MeshDataStrategy *>(s){}
	virtual ~E_MeshDataStrategy()			{}

	MeshDataStrategy * get() const	{	return ref();	}
};

// ---------------------------------------------------------

void init(EScript::Namespace * globals) {
	Namespace * lib=new Namespace();
	declareConstant(globals,"Rendering",lib);

	//! @defgroup draw Draw
	//! @{
	E_Draw::init(*lib);
	E_TextRenderer::init(*lib);
	//! @}

	//! @defgroup mesh Meshes
	//! @{
	E_Mesh::init(*lib);
	E_MeshBuilder::init(*lib);
	E_PlatonicSolids::init(lib);
	E_PrimitiveShapes::init(lib);
	E_WireShapes::init(lib);
	E_VertexAccessor::init(*lib);
	E_VertexAttributeAccessor::init(*lib);
	E_VertexAttribute::init(*lib);
	E_VertexDescription::init(*lib);
	E_TriangleAccessor::init(*lib);
	E_ConnectivityAccessor::init(*lib);
	E_MeshUtils::init(lib);
	//! @}

	//! @defgroup context Rendering Context
	//! @{
	E_RenderingContext::init(*lib);
	E_ParameterStructs::init(*lib);
	E_BufferObject::init(*lib);
	E_FBO::init(*lib);
	//! @}

	//! @defgroup rendering_helper Helper
	//! @{
	E_OcclusionQuery::init(*lib);
	E_StatisticsQuery::init(*lib);
	//! @}

	//! @defgroup shader Shaders
	//! @{
	E_Shader::init(*lib);
	E_Uniform::init(*lib);
	//! @}

	//! @defgroup texture Textures
	//! @{
	E_Texture::init(*lib);
	E_TextureUtils::init(lib);
	//! @}

	// -----------------------------------------------------------------------------------------------------
	// -----------------------------------------------------------------------------------------------------
	// MeshDataStrategy
	//! @addtogroup mesh
	//! @{

	//! [ESF] void Rendering.setDefaultMeshDataStrategy(MeshDataStrategy)
	ES_FUN(lib,"setDefaultMeshDataStrategy",1,1,(
		MeshDataStrategy::setDefaultStrategy(EScript::assertType<E_MeshDataStrategy>(rt,parameter[0])->get()),EScript::create(nullptr)))

	//! MeshDataStrategy Rendering.getDefaultMeshDataStrategy()
	ES_FUN(lib,"getDefaultMeshDataStrategy",0,0,new E_MeshDataStrategy(MeshDataStrategy::getDefaultStrategy()))

	//! MeshDataStrategy Rendering.getPureLocalStrategy()
	ES_FUN(lib,"getPureLocalStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getPureLocalStrategy()))

	//! MeshDataStrategy Rendering.getDebugStrategy()
	ES_FUN(lib,"getDebugStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getDebugStrategy()))

	//! MeshDataStrategy Rendering.getStaticDrawReleaseLocalStrategy()
	ES_FUN(lib,"getStaticDrawReleaseLocalStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getStaticDrawReleaseLocalStrategy()))

	//! MeshDataStrategy Rendering.getStaticDrawPreserveLocalStrategy()
	ES_FUN(lib,"getStaticDrawPreserveLocalStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getStaticDrawPreserveLocalStrategy()))

	//! MeshDataStrategy Rendering.getDynamicVertexStrategy()
	ES_FUN(lib,"getDynamicVertexStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getDynamicVertexStrategy()))
	//! @}

	// -----------------------------------------------------------------------------------------------------
	// -----------------------------------------------------------------------------------------------------

	//! @addtogroup rendering_helper
	//! @{

	//! [ESF] Void Rendering.enableGLErrorChecking()
	ES_FUN(lib, "enableGLErrorChecking", 0, 0, (Rendering::enableGLErrorChecking(), EScript::create(nullptr)))

	//! [ESF] Void Rendering.disableGLErrorChecking()
	ES_FUN(lib, "disableGLErrorChecking", 0, 0, (Rendering::disableGLErrorChecking(), EScript::create(nullptr)))

	//! [ESF] Void Rendering.checkGLError()
	ES_FUN(lib, "checkGLError", 0, 0, (Rendering::checkGLError(rt.getCurrentFile().c_str(), rt.getCurrentLine()), EScript::create(nullptr)))

	//! [ESF] String Rendering.getGLTypeString(Number)
	ES_FUN(lib, "getGLTypeString", 1, 1, Rendering::getGLTypeString(parameter[0].to<uint32_t>(rt)))

	//! [ESF] Void Rendering.outputGLInformation()
	ES_FUN(lib, "outputGLInformation", 0, 0, (Rendering::outputGLInformation(std::cout), EScript::create(nullptr)))

	//! [ESF] Number Rendering.readDepthValue(Number x, Number y)
	ES_FUN(lib, "readDepthValue", 2, 2, Rendering::readDepthValue(parameter[0].to<int32_t>(rt), parameter[1].to<int32_t>(rt)))

	//! [ESF] Void Rendering.enableDebugOutput()
	ES_FUN(lib, "enableDebugOutput", 0, 0, (Rendering::enableDebugOutput(), EScript::create(nullptr)))

	//! [ESF] Void Rendering.disableDebugOutput()
	ES_FUN(lib, "disableDebugOutput", 0, 0, (Rendering::disableDebugOutput(), EScript::create(nullptr)))

	//! [ESF] Void Rendering.clusterPoints(file,count)
	ES_FUN(lib, "clusterPoints", 2, 2, (Rendering::StreamerXYZ::clusterPoints(Util::FileName(parameter[0].toString()),
																					parameter[1].to<uint32_t>(rt)),EScript::create(nullptr)))

	//! [ESF] void Rendering.startCapture()
	ES_FUN(lib, "startCapture", 0, 0, (Rendering::startCapture(), nullptr))

	//! [ESF] void Rendering.endCapture()
	ES_FUN(lib, "endCapture", 0, 0, (Rendering::endCapture(), nullptr))

	//! [ESF] void Rendering.pushDebugGroup(String name)
	ES_FUN(lib, "pushDebugGroup", 1, 1, (Rendering::pushDebugGroup(parameter[0].toString()), nullptr))

	//! [ESF] void Rendering.popDebugGroup()
	ES_FUN(lib, "popDebugGroup", 0, 0, (Rendering::popDebugGroup(), nullptr))

	//! [ESF] void Rendering.triggerCapture()
	ES_FUN(lib, "triggerCapture", 0, 0, 		(Rendering::triggerCapture(), nullptr))
	//! @}
}
}
<commit_msg>Adapted to changes in Rendering<commit_after>/*
	This file is part of the E_Rendering library.
	Copyright (C) 2009-2012 Benjamin Eikel <benjamin@eikel.org>
	Copyright (C) 2009-2012 Claudius Jähn <claudius@uni-paderborn.de>
	Copyright (C) 2009-2012 Ralf Petring <ralf@petring.net>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "ELibRendering.h"
#include <sstream>

#include "E_BufferObject.h"
#include "E_Draw.h"
#include "E_FBO.h"
#include "E_OcclusionQuery.h"
#include "E_ParameterStructs.h"
#include "E_RenderingContext.h"
#include "E_StatisticsQuery.h"
#include "E_TextRenderer.h"
#include "Mesh/E_Mesh.h"
#include "Mesh/E_VertexAccessor.h"
#include "Mesh/E_VertexAttributeAccessors.h"
#include "Mesh/E_VertexAttribute.h"
#include "Mesh/E_VertexDescription.h"
#include "MeshUtils/E_MeshBuilder.h"
#include "MeshUtils/E_MeshUtils.h"
#include "MeshUtils/E_PlatonicSolids.h"
#include "MeshUtils/E_PrimitiveShapes.h"
#include "MeshUtils/E_TriangleAccessor.h"
#include "MeshUtils/E_ConnectivityAccessor.h"
#include "MeshUtils/E_WireShapes.h"
#include "Shader/E_Shader.h"
#include "Shader/E_Uniform.h"
#include "Texture/E_Texture.h"
#include "Texture/E_TextureUtils.h"

#include <Rendering/Mesh/MeshDataStrategy.h>
#include <Rendering/Helper.h>
#include <Rendering/Serialization/StreamerXYZ.h>
#include <Rendering/Serialization/Serialization.h>
#include <Rendering/Texture/Texture.h>
#include <Rendering/Texture/TextureUtils.h>
#include <Util/IO/FileName.h>

#include <EScript/Basics.h>
#include <EScript/StdObjects.h>

#include <iostream>

namespace E_Rendering{

using namespace EScript;
using namespace Rendering;
//using namespace E_Geometry;
using namespace Geometry;
//using namespace E_Util;

//! E_MeshDataStrategy ---> EScript::ReferenceObject<MeshDataStrategy *>
struct E_MeshDataStrategy:public EScript::ReferenceObject<MeshDataStrategy *>{
	ES_PROVIDES_TYPE_NAME(MeshDataStrategy)
public:

	E_MeshDataStrategy(MeshDataStrategy * s):EScript::ReferenceObject<MeshDataStrategy *>(s){}
	virtual ~E_MeshDataStrategy()			{}

	MeshDataStrategy * get() const	{	return ref();	}
};

// ---------------------------------------------------------

void init(EScript::Namespace * globals) {
	Namespace * lib=new Namespace();
	declareConstant(globals,"Rendering",lib);

	//! @defgroup draw Draw
	//! @{
	E_Draw::init(*lib);
	E_TextRenderer::init(*lib);
	//! @}

	//! @defgroup mesh Meshes
	//! @{
	E_Mesh::init(*lib);
	E_MeshBuilder::init(*lib);
	E_PlatonicSolids::init(lib);
	E_PrimitiveShapes::init(lib);
	E_WireShapes::init(lib);
	E_VertexAccessor::init(*lib);
	E_VertexAttributeAccessor::init(*lib);
	E_VertexAttribute::init(*lib);
	E_VertexDescription::init(*lib);
	E_TriangleAccessor::init(*lib);
	E_ConnectivityAccessor::init(*lib);
	E_MeshUtils::init(lib);
	//! @}

	//! @defgroup context Rendering Context
	//! @{
	E_RenderingContext::init(*lib);
	E_ParameterStructs::init(*lib);
	E_BufferObject::init(*lib);
	E_FBO::init(*lib);
	//! @}

	//! @defgroup rendering_helper Helper
	//! @{
	E_OcclusionQuery::init(*lib);
	E_StatisticsQuery::init(*lib);
	//! @}

	//! @defgroup shader Shaders
	//! @{
	E_Shader::init(*lib);
	E_Uniform::init(*lib);
	//! @}

	//! @defgroup texture Textures
	//! @{
	E_Texture::init(*lib);
	E_TextureUtils::init(lib);
	//! @}

	// -----------------------------------------------------------------------------------------------------
	// -----------------------------------------------------------------------------------------------------
	// MeshDataStrategy
	//! @addtogroup mesh
	//! @{

	//! [ESF] void Rendering.setDefaultMeshDataStrategy(MeshDataStrategy)
	ES_FUN(lib,"setDefaultMeshDataStrategy",1,1,(
		MeshDataStrategy::setDefaultStrategy(EScript::assertType<E_MeshDataStrategy>(rt,parameter[0])->get()),EScript::create(nullptr)))

	//! MeshDataStrategy Rendering.getDefaultMeshDataStrategy()
	ES_FUN(lib,"getDefaultMeshDataStrategy",0,0,new E_MeshDataStrategy(MeshDataStrategy::getDefaultStrategy()))

	//! MeshDataStrategy Rendering.getPureLocalStrategy()
	ES_FUN(lib,"getPureLocalStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getPureLocalStrategy()))

	//! MeshDataStrategy Rendering.getDebugStrategy()
	ES_FUN(lib,"getDebugStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getDebugStrategy()))

	//! MeshDataStrategy Rendering.getStaticDrawReleaseLocalStrategy()
	ES_FUN(lib,"getStaticDrawReleaseLocalStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getStaticDrawReleaseLocalStrategy()))

	//! MeshDataStrategy Rendering.getStaticDrawPreserveLocalStrategy()
	ES_FUN(lib,"getStaticDrawPreserveLocalStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getStaticDrawPreserveLocalStrategy()))

	//! MeshDataStrategy Rendering.getDynamicVertexStrategy()
	ES_FUN(lib,"getDynamicVertexStrategy",0,0,
			new E_MeshDataStrategy(SimpleMeshDataStrategy::getDynamicVertexStrategy()))
	//! @}

	// -----------------------------------------------------------------------------------------------------
	// -----------------------------------------------------------------------------------------------------

	//! @addtogroup rendering_helper
	//! @{

	//! [ESF] Void Rendering.enableGLErrorChecking()
	ES_FUN(lib, "enableGLErrorChecking", 0, 0, (Rendering::enableGLErrorChecking(), EScript::create(nullptr)))

	//! [ESF] Void Rendering.disableGLErrorChecking()
	ES_FUN(lib, "disableGLErrorChecking", 0, 0, (Rendering::disableGLErrorChecking(), EScript::create(nullptr)))

	//! [ESF] Void Rendering.checkGLError()
	ES_FUN(lib, "checkGLError", 0, 0, (Rendering::checkGLError(rt.getCurrentFile().c_str(), rt.getCurrentLine()), EScript::create(nullptr)))

	//! [ESF] String Rendering.getGLTypeString(Number)
	ES_FUN(lib, "getGLTypeString", 1, 1, Rendering::getGLTypeString(parameter[0].to<uint32_t>(rt)))

	//! [ESF] Void Rendering.outputGLInformation()
	ES_FUN(lib, "outputGLInformation", 0, 0, (Rendering::outputGLInformation(std::cout), EScript::create(nullptr)))

	//! [ESF] Number Rendering.readDepthValue(Number x, Number y)
	ES_FUN(lib, "readDepthValue", 2, 2, Rendering::readDepthValue(parameter[0].to<int32_t>(rt), parameter[1].to<int32_t>(rt)))

	//! [ESF] Void Rendering.enableDebugOutput()
	ES_FUN(lib, "enableDebugOutput", 0, 0, (Rendering::enableDebugOutput(), EScript::create(nullptr)))

	//! [ESF] Void Rendering.disableDebugOutput()
	ES_FUN(lib, "disableDebugOutput", 0, 0, (Rendering::disableDebugOutput(), EScript::create(nullptr)))

	//! [ESF] Void Rendering.clusterPoints(file,count)
	ES_FUN(lib, "clusterPoints", 2, 2, (Rendering::Serialization::StreamerXYZ::clusterPoints(Util::FileName(parameter[0].toString()),
																					parameter[1].to<uint32_t>(rt)),EScript::create(nullptr)))

	//! [ESF] void Rendering.startCapture()
	ES_FUN(lib, "startCapture", 0, 0, (Rendering::startCapture(), nullptr))

	//! [ESF] void Rendering.endCapture()
	ES_FUN(lib, "endCapture", 0, 0, (Rendering::endCapture(), nullptr))

	//! [ESF] void Rendering.pushDebugGroup(String name)
	ES_FUN(lib, "pushDebugGroup", 1, 1, (Rendering::pushDebugGroup(parameter[0].toString()), nullptr))

	//! [ESF] void Rendering.popDebugGroup()
	ES_FUN(lib, "popDebugGroup", 0, 0, (Rendering::popDebugGroup(), nullptr))

	//! [ESF] void Rendering.triggerCapture()
	ES_FUN(lib, "triggerCapture", 0, 0, 		(Rendering::triggerCapture(), nullptr))
	//! @}
}
}
<|endoftext|>