<commit_before>#pragma once
#include "diff_patch_common.hpp"
#include "../base/assert.hpp"
#include "../base/base.hpp"
#include "../std/algorithm.hpp"
#include "../std/unordered_map.hpp"
#include "../std/vector.hpp"

namespace diff
{

template <class PatchWriterT, typename SizeT = uint64_t> class PatchCoder
{
public:
  typedef SizeT size_type;

  explicit PatchCoder(PatchWriterT & patchWriter)
    : m_LastOperation(COPY), m_LastOpCode(0), m_PatchWriter(patchWriter)
  {
  }

  void Delete(size_type n)
  {
    if (n != 0)
      Op(DELETE, n);
  }

  void Copy(size_type n)
  {
    if (n != 0)
      Op(COPY, n);
  }

  template <typename TIter> void Insert(TIter it, size_type n)
  {
    if (n != 0)
    {
      Op(INSERT, n);
      m_PatchWriter.WriteData(it, n);
    }
  }

  void Finalize()
  {
    WriteLasOp();
  }

private:
  void Op(Operation op, size_type n)
  {
    if (m_LastOperation == op)
    {
      m_LastOpCode += (n << 1);
      return;
    }
    WriteLasOp();
    m_LastOpCode = (n << 1) | ((m_LastOperation + 1) % 3 == op ? 0 : 1);
    m_LastOperation = op;
  }

  void WriteLasOp()
  {
    if (m_LastOpCode != 0)
      m_PatchWriter.WriteOperation(m_LastOpCode);
    else
      CHECK_EQUAL(m_LastOperation, COPY, ());  // "We were just initialized."
  }

  Operation m_LastOperation;
  size_type m_LastOpCode;
  PatchWriterT & m_PatchWriter;
};

// Find minimal patch, with no more than maxPatchSize edited values, that transforms A into B.
// Returns the length of the minimal patch, or -1 if no such patch found.
// Intermediate information is saved into tmpSink and can be used later to restore
// the resulting patch.
template <
    typename TSignedWord, // Signed word, capable of storing position in text.
    class TSrcVector,     // Source data (A).
    class TDstVector,     // Destination data (B).
    class TTmpFileSink    // Sink to store temporary information.
    >
TSignedWord DiffMyersSimple(TSrcVector const & A,
                            TDstVector const & B,
                            TSignedWord maxPatchSize,
                            TTmpFileSink & tmpSink)
{
  ASSERT_GREATER(maxPatchSize, 0, ());
  vector<TSignedWord> V(2 * maxPatchSize + 1);
  for (TSignedWord d = 0; d <= maxPatchSize; ++d)
  {
    for (TSignedWord k = -d; k <= d; k += 2)
    {
      TSignedWord x;
      if (k == -d || (k != d && V[maxPatchSize + k - 1] < V[maxPatchSize + k + 1]))
        x = V[maxPatchSize + k + 1];
      else
        x = V[maxPatchSize + k - 1] + 1;
      while (x < static_cast<TSignedWord>(A.size()) &&
             x - k < static_cast<TSignedWord>(B.size()) &&
             A[x] == B[x - k])
        ++x;
      V[maxPatchSize + k] = x;
      if (x == static_cast<TSignedWord>(A.size()) && x - k == static_cast<TSignedWord>(B.size()))
        return d;
    }
    tmpSink.Write(&V[maxPatchSize + d], (2 * d + 1) * sizeof(TSignedWord));
  }
  return -1;
}

// Differ that just replaces old with new, with the only optimization of skipping equal values
// at the beginning and at the end.
class SimpleReplaceDiffer
{
public:
  template <typename SrcIterT, typename DstIterT, class PatchCoderT>
  void Diff(SrcIterT srcBeg, SrcIterT srcEnd,
            DstIterT dstBeg, DstIterT dstEnd,
            PatchCoderT & patchCoder)
  {
    typename PatchCoderT::size_type begCopy = 0;
    for (; srcBeg != srcEnd && dstBeg != dstEnd && *srcBeg == *dstBeg; ++srcBeg, ++dstBeg)
      ++begCopy;
    patchCoder.Copy(begCopy);
    typename PatchCoderT::size_type endCopy = 0;
    for (; srcBeg != srcEnd && dstBeg != dstEnd && *(srcEnd-1) == *(dstEnd-1); --srcEnd, --dstEnd)
      ++endCopy;
    patchCoder.Delete(srcEnd - srcBeg);
    patchCoder.Insert(dstBeg, dstEnd - dstBeg);
    patchCoder.Copy(endCopy);
  }
};

// Given FineGrainedDiff and rolling Hasher, DiffWithRollingHash splits the source sequence
// into chunks of size m_BlockSize, finds equal chunks in the destination sequence, using rolling
// hash to find good candidates, writes info about equal chunks into patchCoder and for everything
// between equal chunks, calls FineGrainedDiff::Diff().
template <class FineGrainedDiffT,
          class HasherT,
          class HashPosMultiMapT = unordered_multimap<typename HasherT::hash_type, uint64_t> >
class RollingHashDiffer
{
public:
  explicit RollingHashDiffer(size_t blockSize,
                               FineGrainedDiffT const & fineGrainedDiff = FineGrainedDiffT())
    : m_FineGrainedDiff(fineGrainedDiff), m_BlockSize(blockSize) {}

  template <typename SrcIterT, typename DstIterT, class PatchCoderT>
  void Diff(SrcIterT const srcBeg, SrcIterT const srcEnd,
            DstIterT const dstBeg, DstIterT const dstEnd,
            PatchCoderT & patchCoder)
  {
    if (srcEnd - srcBeg < m_BlockSize || dstEnd - dstBeg < m_BlockSize)
    {
      m_FineGrainedDiff.Diff(srcBeg, srcEnd, dstBeg, dstEnd, patchCoder);
      return;
    }
    HasherT hasher;
    HashPosMultiMapT srcHashes;
    for (SrcIterT src = srcBeg; srcEnd - src >= m_BlockSize; src += m_BlockSize)
      srcHashes.insert(HashPosMultiMapValue(hasher.Init(src, m_BlockSize), src - srcBeg));
    SrcIterT srcLastDiff = srcBeg;
    DstIterT dst = dstBeg, dstNext = dstBeg + m_BlockSize, dstLastDiff = dstBeg;
    hash_type h = hasher.Init(dst, m_BlockSize);
    while (dstNext != dstEnd)
    {
      pair<HashPosMultiMapIterator, HashPosMultiMapIterator> iters = srcHashes.equal_range(h);
      if (iters.first != iters.second)
      {
        pos_type const srcLastDiffPos = srcLastDiff - srcBeg;
        HashPosMultiMapIterator it = srcHashes.end();
        for (HashPosMultiMapIterator i = iters.first; i != iters.second; ++i)
          if (i->second >= srcLastDiffPos &&
              (it == srcHashes.end() || i->second < it->second))
            it = i;
        if (it != srcHashes.end() &&
            equal(srcBeg + it->second, srcBeg + it->second + m_BlockSize, dst))
        {
          pos_type srcBlockEqualPos = it->second;
          m_FineGrainedDiff.Diff(srcLastDiff, srcBeg + srcBlockEqualPos,
                                 dstLastDiff, dst, patchCoder);
          patchCoder.Copy(m_BlockSize);
          srcLastDiff = srcBeg + srcBlockEqualPos + m_BlockSize;
          dst = dstLastDiff = dstNext;
          if (dstEnd - dstNext < m_BlockSize)
            break;
          dstNext = dst + m_BlockSize;
          h = hasher.Init(dst, m_BlockSize);
          continue;
        }
      }
      h = hasher.Scroll(*(dst++), *(dstNext++));
    }
    if (srcLastDiff != srcEnd || dstLastDiff != dstEnd)
      m_FineGrainedDiff.Diff(srcLastDiff, srcEnd, dstLastDiff, dstEnd, patchCoder);
  }
private:
  typedef typename HasherT::hash_type hash_type;
  typedef typename HashPosMultiMapT::value_type::second_type pos_type;
  typedef typename HashPosMultiMapT::const_iterator HashPosMultiMapIterator;
  typedef typename HashPosMultiMapT::value_type HashPosMultiMapValue;

  FineGrainedDiffT m_FineGrainedDiff;
  HasherT m_Hasher;
  size_t m_BlockSize;
};

}
<commit_msg>[coding] Fixed buffer-overflow in MyersSimpleDiff() algorithm.<commit_after>#pragma once
#include "diff_patch_common.hpp"
#include "../base/assert.hpp"
#include "../base/base.hpp"
#include "../std/algorithm.hpp"
#include "../std/unordered_map.hpp"
#include "../std/vector.hpp"

namespace diff
{

template <class PatchWriterT, typename SizeT = uint64_t> class PatchCoder
{
public:
  typedef SizeT size_type;

  explicit PatchCoder(PatchWriterT & patchWriter)
    : m_LastOperation(COPY), m_LastOpCode(0), m_PatchWriter(patchWriter)
  {
  }

  void Delete(size_type n)
  {
    if (n != 0)
      Op(DELETE, n);
  }

  void Copy(size_type n)
  {
    if (n != 0)
      Op(COPY, n);
  }

  template <typename TIter> void Insert(TIter it, size_type n)
  {
    if (n != 0)
    {
      Op(INSERT, n);
      m_PatchWriter.WriteData(it, n);
    }
  }

  void Finalize()
  {
    WriteLasOp();
  }

private:
  void Op(Operation op, size_type n)
  {
    if (m_LastOperation == op)
    {
      m_LastOpCode += (n << 1);
      return;
    }
    WriteLasOp();
    m_LastOpCode = (n << 1) | ((m_LastOperation + 1) % 3 == op ? 0 : 1);
    m_LastOperation = op;
  }

  void WriteLasOp()
  {
    if (m_LastOpCode != 0)
      m_PatchWriter.WriteOperation(m_LastOpCode);
    else
      CHECK_EQUAL(m_LastOperation, COPY, ());  // "We were just initialized."
  }

  Operation m_LastOperation;
  size_type m_LastOpCode;
  PatchWriterT & m_PatchWriter;
};

// Find minimal patch, with no more than maxPatchSize edited values, that transforms A into B.
// Returns the length of the minimal patch, or -1 if no such patch found.
// Intermediate information is saved into tmpSink and can be used later to restore
// the resulting patch.
template <
    typename TSignedWord, // Signed word, capable of storing position in text.
    class TSrcVector,     // Source data (A).
    class TDstVector,     // Destination data (B).
    class TTmpFileSink    // Sink to store temporary information.
    >
TSignedWord DiffMyersSimple(TSrcVector const & A,
                            TDstVector const & B,
                            TSignedWord maxPatchSize,
                            TTmpFileSink & tmpSink)
{
  ASSERT_GREATER(maxPatchSize, 0, ());
  vector<TSignedWord> V(2 * maxPatchSize + 1);
  for (TSignedWord d = 0; d <= maxPatchSize; ++d)
  {
    for (TSignedWord k = -d; k <= d; k += 2)
    {
      TSignedWord x;
      if (k == -d || (k != d && V[maxPatchSize + k - 1] < V[maxPatchSize + k + 1]))
        x = V[maxPatchSize + k + 1];
      else
        x = V[maxPatchSize + k - 1] + 1;
      while (x < static_cast<TSignedWord>(A.size()) &&
             x - k < static_cast<TSignedWord>(B.size()) &&
             A[x] == B[x - k])
        ++x;
      V[maxPatchSize + k] = x;
      if (x == static_cast<TSignedWord>(A.size()) && x - k == static_cast<TSignedWord>(B.size()))
        return d;
    }
    tmpSink.Write(&V[maxPatchSize - d], (2 * d + 1) * sizeof(TSignedWord));
  }
  return -1;
}

// Differ that just replaces old with new, with the only optimization of skipping equal values
// at the beginning and at the end.
class SimpleReplaceDiffer
{
public:
  template <typename SrcIterT, typename DstIterT, class PatchCoderT>
  void Diff(SrcIterT srcBeg, SrcIterT srcEnd,
            DstIterT dstBeg, DstIterT dstEnd,
            PatchCoderT & patchCoder)
  {
    typename PatchCoderT::size_type begCopy = 0;
    for (; srcBeg != srcEnd && dstBeg != dstEnd && *srcBeg == *dstBeg; ++srcBeg, ++dstBeg)
      ++begCopy;
    patchCoder.Copy(begCopy);
    typename PatchCoderT::size_type endCopy = 0;
    for (; srcBeg != srcEnd && dstBeg != dstEnd && *(srcEnd-1) == *(dstEnd-1); --srcEnd, --dstEnd)
      ++endCopy;
    patchCoder.Delete(srcEnd - srcBeg);
    patchCoder.Insert(dstBeg, dstEnd - dstBeg);
    patchCoder.Copy(endCopy);
  }
};

// Given FineGrainedDiff and rolling Hasher, DiffWithRollingHash splits the source sequence
// into chunks of size m_BlockSize, finds equal chunks in the destination sequence, using rolling
// hash to find good candidates, writes info about equal chunks into patchCoder and for everything
// between equal chunks, calls FineGrainedDiff::Diff().
template <class FineGrainedDiffT,
          class HasherT,
          class HashPosMultiMapT = unordered_multimap<typename HasherT::hash_type, uint64_t> >
class RollingHashDiffer
{
public:
  explicit RollingHashDiffer(size_t blockSize,
                               FineGrainedDiffT const & fineGrainedDiff = FineGrainedDiffT())
    : m_FineGrainedDiff(fineGrainedDiff), m_BlockSize(blockSize) {}

  template <typename SrcIterT, typename DstIterT, class PatchCoderT>
  void Diff(SrcIterT const srcBeg, SrcIterT const srcEnd,
            DstIterT const dstBeg, DstIterT const dstEnd,
            PatchCoderT & patchCoder)
  {
    if (srcEnd - srcBeg < m_BlockSize || dstEnd - dstBeg < m_BlockSize)
    {
      m_FineGrainedDiff.Diff(srcBeg, srcEnd, dstBeg, dstEnd, patchCoder);
      return;
    }
    HasherT hasher;
    HashPosMultiMapT srcHashes;
    for (SrcIterT src = srcBeg; srcEnd - src >= m_BlockSize; src += m_BlockSize)
      srcHashes.insert(HashPosMultiMapValue(hasher.Init(src, m_BlockSize), src - srcBeg));
    SrcIterT srcLastDiff = srcBeg;
    DstIterT dst = dstBeg, dstNext = dstBeg + m_BlockSize, dstLastDiff = dstBeg;
    hash_type h = hasher.Init(dst, m_BlockSize);
    while (dstNext != dstEnd)
    {
      pair<HashPosMultiMapIterator, HashPosMultiMapIterator> iters = srcHashes.equal_range(h);
      if (iters.first != iters.second)
      {
        pos_type const srcLastDiffPos = srcLastDiff - srcBeg;
        HashPosMultiMapIterator it = srcHashes.end();
        for (HashPosMultiMapIterator i = iters.first; i != iters.second; ++i)
          if (i->second >= srcLastDiffPos &&
              (it == srcHashes.end() || i->second < it->second))
            it = i;
        if (it != srcHashes.end() &&
            equal(srcBeg + it->second, srcBeg + it->second + m_BlockSize, dst))
        {
          pos_type srcBlockEqualPos = it->second;
          m_FineGrainedDiff.Diff(srcLastDiff, srcBeg + srcBlockEqualPos,
                                 dstLastDiff, dst, patchCoder);
          patchCoder.Copy(m_BlockSize);
          srcLastDiff = srcBeg + srcBlockEqualPos + m_BlockSize;
          dst = dstLastDiff = dstNext;
          if (dstEnd - dstNext < m_BlockSize)
            break;
          dstNext = dst + m_BlockSize;
          h = hasher.Init(dst, m_BlockSize);
          continue;
        }
      }
      h = hasher.Scroll(*(dst++), *(dstNext++));
    }
    if (srcLastDiff != srcEnd || dstLastDiff != dstEnd)
      m_FineGrainedDiff.Diff(srcLastDiff, srcEnd, dstLastDiff, dstEnd, patchCoder);
  }
private:
  typedef typename HasherT::hash_type hash_type;
  typedef typename HashPosMultiMapT::value_type::second_type pos_type;
  typedef typename HashPosMultiMapT::const_iterator HashPosMultiMapIterator;
  typedef typename HashPosMultiMapT::value_type HashPosMultiMapValue;

  FineGrainedDiffT m_FineGrainedDiff;
  HasherT m_Hasher;
  size_t m_BlockSize;
};

}
<|endoftext|>


<commit_before>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
#define NONADAPTIVE
#undef ADAPTIVE

#define _WAVELETTL_USE_TBASIS 1
#define _WAVELETTL_USE_TFRAME 1
#define _DIM 2

#include <iostream>
#include <utils/fixed_array1d.h>
#include <utils/multiindex.h>
#include <numerics/bvp.h>
#include <numerics/corner_singularity.h>
#include <interval/p_basis.h>
#include <interval/pq_frame.h>
#include <Ldomain/ldomain_frame_index.h>
#include <Ldomain/ldomain_frame.h>
#include <Ldomain/ldomain_frame_evaluate.h>
#include <galerkin/ldomain_frame_equation.h>
//#include <galerkin/cached_lproblem.h>

#include <adaptive/compression.h>
#include <adaptive/apply.h>
#include <adaptive/cdd2.h>

#include "ldomain_solutions.h"

using namespace std;
using namespace WaveletTL;

using MathTL::FixedArray1D;

class myRHS
  : public Function<2,double>
{
public:
  virtual ~myRHS() {};
  double value(const Point<2>& p, const unsigned int component = 0) const {
    return 2*M_PI*M_PI*sin(M_PI*p[0])*sin(M_PI*p[1]);
  }
  void vector_value(const Point<2>& p, Vector<double>& values) const {
    values[0] = value(p);
  }
};

class mySolution
  : public Function<2,double>
{
public:
  virtual ~mySolution() {};
  double value(const Point<2>& p, const unsigned int component = 0) const {
    return sin(M_PI*p[0])*sin(M_PI*p[1]);
  }
  void vector_value(const Point<2>& p, Vector<double>& values) const {
    values[0] = value(p);
  }
};
class mySum
  : public Function<2,double>
{
public:
  virtual ~mySum() {};
  double value(const Point<2>& p, const unsigned int component = 0) const {
    return (1+2*M_PI*M_PI)*sin(M_PI*p[0])*sin(M_PI*p[1]);
  }
  void vector_value(const Point<2>& p, Vector<double>& values) const {
    values[0] = value(p);
  }
};

int main(){

    cout << "testing L-domain quarklet frame" << endl;
    const int d  = 3;
    const int dT = 3;
    const int dim = 2;
    const int jmax = 6;
    const int pmax = 0;

    typedef PQFrame<d,dT> Frame1d;
    Frame1d frame1d(false,false);
    typedef LDomainFrame<Frame1d> Frame;
    typedef Frame::Index Index;
    //Frame frame(frame1d);
    Frame frame;
    frame.set_jpmax(jmax,pmax);

    //CornerSingularity uexact1(Point<2>(0,0), 0.5, 1.5);
    mySolution uexact1;
    //CornerSingularityRHS rhs1(Point<2>(0,0), 0.5, 1.5); //Fnorm=0?
    //Vector<double> val(1, "1.0");
    //ConstantFunction<dim> rhs1(val);
    myRHS rhs1;

    PoissonBVP<dim> poisson1(&rhs1);
    LDomainFrameEquation<Frame1d,Frame> eq(&poisson1, false);
    eq.set_jpmax(jmax,pmax,false);

    Index testindex=frame.get_quarklet(71);
#if 0 //plot rhs and exact solution
    Array1D<Point<dim,int> > corners;
    corners.resize(3);
    corners[0][0]=-1;
    corners[0][1]=0;
    corners[1][0]=-1;
    corners[1][1]=-1;
    corners[2][0]=0;
    corners[2][1]=-1;

    std::ofstream osrhs("rhs.m");
    std::ofstream osuexact("uexact.m");
    for(int i=0;i<3;i++){
        Point<2> q0(corners[i][0],corners[i][1]);
        Point<2> q1(corners[i][0]+1,corners[i][1]+1);
        Grid<2> mygrid(q0,q1,100);
        SampledMapping<2> smrhs(mygrid, rhs1);
        SampledMapping<2> smuexact(mygrid, uexact1);
        smrhs.matlab_output(osrhs);
        smuexact.matlab_output(osuexact);
        osrhs << "surf(x,y,z)"<<endl;
        osuexact<<"surf(x,y,z)"<<endl;
        osrhs << "hold on;" << endl;
        osuexact<<"hold on;"<<endl;
    }
    osrhs << "view(30,55);"<<endl;
    osrhs << "hold off;" << endl;
    osuexact << "view(30,55);"<<endl;
    osuexact<<"hold off;"<<endl;
    osrhs.close();
    osuexact.close();
    cout << "rhs and uexact plotted" << endl;
#endif

#if 1
    //setup index set
    //Vector<double> a;
    //a.resize(eq.frame().degrees_of_freedom(),true);
    //setup Index set
    set<Index> Lambda;
    MultiIndex<int,dim> p;p[0]=0;p[1]=0;
    Index lambda = eq.frame().first_generator(eq.frame().j0(), p);
    int zaehler=0;
    for (int l = 0; l < eq.frame().degrees_of_freedom(); l++) {
        //cout << lambda << " : "<<lambda.number()<< endl;
        //cout << lambda << " : " << eq.a(lambda,lambda) << endl;
        //if(multi_degree(lambda.e())<1 && lambda.patch()<4){
            Lambda.insert(lambda);
            ++zaehler;
        //}
        if(lambda==eq.frame().last_quarklet(jmax, p)){
            ++p;
            lambda=eq.frame().first_generator(eq.frame().j0(), p);
        }
        else
        //a(zaehler)=eq.a(eq.frame().get_quarklet(126),lambda);
        ++lambda;

    }
    //a.matlab_output("a","a");

    cout << "size of Lambda: " << zaehler << endl;
#endif

#if 0 //test methods of ldomain_frame_equation
    cout << "testindex: "<<testindex<<endl;
    cout << "a(lambda_0,lambda_0) : "<<eq.a(testindex,testindex) << endl;
    cout << "f(lambda_0): "<<eq.f(testindex)<<endl;
    cout << "D(lambda_0): "<<eq.D(testindex)<<endl;
    //cout << "F_norm: "<<eq.F_norm() << endl;
    //cout << "normA: "<<eq.norm_A() <<endl;
    //cout << "normAinv: "<<eq.norm_Ainv() << endl;

#endif
 #ifdef NONADAPTIVE
    //setup stiffness matrix and rhs
    SparseMatrix<double> A;
    setup_stiffness_matrix(eq,Lambda,A);
    cout << "setup stiffness matrix done" << endl;
    Vector<double> F;
    setup_righthand_side(eq, Lambda, F);
    A.compress(1e-14);
    F.compress(1e-14);
    A.matlab_output("A","A",0,A.row_dimension()-1,A.column_dimension()-1 );
    F.matlab_output("F","F");
    Vector<double> x(Lambda.size());
    x =0;

    //richardson iteration
    unsigned int iterations;
    const int maxiterations = 9999;
    const double omega = 2.0 / (eq.norm_A() + 1.0/eq.norm_Ainv());
    cout << "omega: "<<omega<<endl;
    Richardson(A,F,x,omega,1e-6,maxiterations,iterations);
    //CG(A,F,x,1e-8,maxiterations,iterations);
    cout << "iterations:" << iterations << endl;

    //plot solution
    InfiniteVector<double,Index> u;
    unsigned int i2 = 0;
    for (set<Index>::const_iterator it = Lambda.begin(); it != Lambda.end(); ++it, ++i2){
      u.set_coefficient(*it, x[i2]);
    }
    //u.COARSE(1e-6,v);
    u.scale(&eq, -1);
    Array1D<SampledMapping<dim> > eval(3);
    eval=eq.frame().evaluate(u,6);
    std::ofstream os2("solution_na.m");
    for(int i=0;i<3;i++){
        eval[i].matlab_output(os2);
        os2 << "surf(x,y,z);" << endl;
        os2 << "hold on;" << endl;
    }
    os2 << "view(30,55);"<<endl;
    os2 << "hold off" << endl;
    os2.close();

#endif

#if 1 //test bilinearform
    const int resolution=6;
    Index testindex1(testindex);
    Index testindex2=eq.frame().get_quarklet(192);
    Array1D<SampledMapping<dim> > eval1(3);
    Array1D<SampledMapping<dim> > eval2(3);
    eval1=frame.evaluate(testindex1,resolution);
    eval2=frame.evaluate(testindex2,resolution);
    std::ofstream os("testa.m");
    os<<"Iexakt="<<eq.a(testindex1,testindex2)<<endl;
    os<<"I=0;"<<endl;
    for(int i=0;i<3;i++){
        eval1[i].matlab_output(os);
        os<<"z1=z;"<<endl;
        eval2[i].matlab_output(os);
        os<<"z2=z;"<<endl;
        os<<"xx=x(1,:);"<<endl;
        os<<"yy=y'(1,:);"<<endl;
        os<<"[gx1,gy1]=gradient(z1,2^-"<<resolution<<",2^-"<<resolution<<");"<<endl;
        os<<"[gx2,gy2]=gradient(z2,2^-"<<resolution<<",2^-"<<resolution<<");"<<endl;
        os<<"L=gx1.*gx2.+gy1.*gy2;"<<endl;
        os<<"I=I+trapz(yy,trapz(xx,L,2)');"<<endl;
    }
    os<<"I"<<endl;
    os<<"relative_error=abs(I-Iexakt)/Iexakt"<<endl;
    os.close();
#endif

#if 1 //test rhs
    const int resolution2=6;
    Index testindex3(testindex);
    Array1D<SampledMapping<dim> > eval3(3);
    eval3=frame.evaluate(testindex3, resolution2);
    Array1D<Point<dim,int> > corners;
    corners.resize(3);
    corners[0][0]=-1;
    corners[0][1]=0;
    corners[1][0]=-1;
    corners[1][1]=-1;
    corners[2][0]=0;
    corners[2][1]=-1;

    std::ofstream os3("testf.m");
    os3<<"Iexakt="<<eq.f(testindex)<<endl;
    os3<<"I=0;"<<endl;
    for(int i=0;i<3;i++){
        eval3[i].matlab_output(os3);
        os3<<"zalt=z;"<<endl;
        Point<2> q0(corners[i][0],corners[i][1]);
        Point<2> q1(corners[i][0]+1,corners[i][1]+1);
        Grid<2> mygrid(q0,q1,pow(2,resolution2));
        SampledMapping<2> smf(mygrid, rhs1);
        smf.matlab_output(os3);
        os3<<"z=z.*zalt;"<<endl;
        os3<<"xx=x(1,:);"<<endl;
        os3<<"yy=y'(1,:);"<<endl;
        os3<<"I=I+trapz(yy,trapz(xx,z,2)');"<<endl;
    }
    os3<<"I"<<endl;
    os3<<"relative_error=abs(I-Iexakt)/Iexakt"<<endl;
    os3.close();
#endif

#if 1
    //plot one function
    Array1D<SampledMapping<dim> > evalf(3);
    //Index ind=frame.get_quarklet(159);    //0-26:generatoren auf patches,
                                        //27-32:überlappende generatoren, indiziert mit p=3,4
                                        //33:überlappendes wavelet
                                        //34:nicht-überlappendes wavelet
    cout << "evaluate quarklet with index " << testindex << endl;
    evalf=frame.evaluate(testindex,6);
    std::ofstream osf("Ldomainoutput.m");
    osf << "clf;" << endl;
    osf << "axis([-1 1 -1 1 0 1]);" << endl;
    for(int i=0;i<3;i++){
        evalf[i].matlab_output(osf);
        osf << "surf(x,y,z);" << endl;

        osf << "hold on;" << endl;
    }
    osf << "view(30,55);"<<endl;
    osf << "hold off" << endl;
    osf.close();
#endif

    return 0;
}<commit_msg>added test file<commit_after>/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
#undef NONADAPTIVE
#define ADAPTIVE

#define _WAVELETTL_USE_TBASIS 1
#define _WAVELETTL_USE_TFRAME 1
#define _DIM 2

#include <iostream>
#include <utils/fixed_array1d.h>
#include <utils/multiindex.h>
#include <numerics/bvp.h>
#include <numerics/corner_singularity.h>
#include <interval/p_basis.h>
#include <interval/pq_frame.h>
#include <Ldomain/ldomain_frame_index.h>
#include <Ldomain/ldomain_frame.h>
#include <Ldomain/ldomain_frame_evaluate.h>
#include <galerkin/ldomain_frame_equation.h>
#include <galerkin/cached_quarklet_ldomain_problem.h>

#include <adaptive/compression.h>
#include <adaptive/apply.h>
#include <adaptive/cdd2.h>

#include "ldomain_solutions.h"

using namespace std;
using namespace WaveletTL;

using MathTL::FixedArray1D;

class myRHS
  : public Function<2,double>
{
public:
  virtual ~myRHS() {};
  double value(const Point<2>& p, const unsigned int component = 0) const {
    return 2*M_PI*M_PI*sin(M_PI*p[0])*sin(M_PI*p[1]);
  }
  void vector_value(const Point<2>& p, Vector<double>& values) const {
    values[0] = value(p);
  }
};

class mySolution
  : public Function<2,double>
{
public:
  virtual ~mySolution() {};
  double value(const Point<2>& p, const unsigned int component = 0) const {
    return sin(M_PI*p[0])*sin(M_PI*p[1]);
  }
  void vector_value(const Point<2>& p, Vector<double>& values) const {
    values[0] = value(p);
  }
};
class mySum
  : public Function<2,double>
{
public:
  virtual ~mySum() {};
  double value(const Point<2>& p, const unsigned int component = 0) const {
    return (1+2*M_PI*M_PI)*sin(M_PI*p[0])*sin(M_PI*p[1]);
  }
  void vector_value(const Point<2>& p, Vector<double>& values) const {
    values[0] = value(p);
  }
};

int main(){

    cout << "testing L-domain quarklet frame" << endl;
    const int d  = 3;
    const int dT = 3;
    const int dim = 2;
    const int jmax = 6;
    const int pmax = 0;

    typedef PQFrame<d,dT> Frame1d;
    Frame1d frame1d(false,false);
    typedef LDomainFrame<Frame1d> Frame;
    typedef Frame::Index Index;
    //Frame frame(frame1d);
    Frame frame(frame1d);
    frame.set_jpmax(jmax,pmax);

    //CornerSingularity uexact1(Point<2>(0,0), 0.5, 1.5);
    mySolution uexact1;
    //CornerSingularityRHS rhs1(Point<2>(0,0), 0.5, 1.5); //Fnorm=0?
    //Vector<double> val(1, "1.0");
    //ConstantFunction<dim> rhs1(val);
    myRHS rhs1;

    PoissonBVP<dim> poisson1(&rhs1);
    LDomainFrameEquation<Frame1d,Frame> eq(&poisson1,frame, true);
    eq.set_jpmax(jmax,pmax);

    Index testindex=frame.get_quarklet(71);
#if 0 //plot rhs and exact solution
    Array1D<Point<dim,int> > corners;
    corners.resize(3);
    corners[0][0]=-1;
    corners[0][1]=0;
    corners[1][0]=-1;
    corners[1][1]=-1;
    corners[2][0]=0;
    corners[2][1]=-1;

    std::ofstream osrhs("rhs.m");
    std::ofstream osuexact("uexact.m");
    for(int i=0;i<3;i++){
        Point<2> q0(corners[i][0],corners[i][1]);
        Point<2> q1(corners[i][0]+1,corners[i][1]+1);
        Grid<2> mygrid(q0,q1,100);
        SampledMapping<2> smrhs(mygrid, rhs1);
        SampledMapping<2> smuexact(mygrid, uexact1);
        smrhs.matlab_output(osrhs);
        smuexact.matlab_output(osuexact);
        osrhs << "surf(x,y,z)"<<endl;
        osuexact<<"surf(x,y,z)"<<endl;
        osrhs << "hold on;" << endl;
        osuexact<<"hold on;"<<endl;
    }
    osrhs << "view(30,55);"<<endl;
    osrhs << "hold off;" << endl;
    osuexact << "view(30,55);"<<endl;
    osuexact<<"hold off;"<<endl;
    osrhs.close();
    osuexact.close();
    cout << "rhs and uexact plotted" << endl;
#endif

#if 1
    //setup index set
    //Vector<double> a;
    //a.resize(eq.frame().degrees_of_freedom(),true);
    //setup Index set
    set<Index> Lambda;
    MultiIndex<int,dim> p;p[0]=0;p[1]=0;
    Index lambda = eq.frame().first_generator(eq.frame().j0(), p);
    int zaehler=0;
    for (int l = 0; l < eq.frame().degrees_of_freedom(); l++) {
        //cout << lambda << " : "<<lambda.number()<< endl;
        //cout << lambda << " : " << eq.a(lambda,lambda) << endl;
        //if(multi_degree(lambda.e())<1 && lambda.patch()<4){
            Lambda.insert(lambda);
            ++zaehler;
        //}
        if(lambda==eq.frame().last_quarklet(jmax, p)){
            ++p;
            lambda=eq.frame().first_generator(eq.frame().j0(), p);
        }
        else
        //a(zaehler)=eq.a(eq.frame().get_quarklet(126),lambda);
        ++lambda;

    }
    //a.matlab_output("a","a");

    cout << "size of Lambda: " << zaehler << endl;
#endif

#if 0 //test methods of ldomain_frame_equation
    cout << "testindex: "<<testindex<<endl;
    cout << "a(lambda_0,lambda_0) : "<<eq.a(testindex,testindex) << endl;
    cout << "f(lambda_0): "<<eq.f(testindex)<<endl;
    cout << "D(lambda_0): "<<eq.D(testindex)<<endl;
    //cout << "F_norm: "<<eq.F_norm() << endl;
    //cout << "normA: "<<eq.norm_A() <<endl;
    //cout << "normAinv: "<<eq.norm_Ainv() << endl;

#endif
 #ifdef NONADAPTIVE
    //setup stiffness matrix and rhs
    SparseMatrix<double> A;
    setup_stiffness_matrix(eq,Lambda,A);
    cout << "setup stiffness matrix done" << endl;
    Vector<double> F;
    setup_righthand_side(eq, Lambda, F);
    A.compress(1e-14);
    F.compress(1e-14);
    A.matlab_output("A","A",0,A.row_dimension()-1,A.column_dimension()-1 );
    F.matlab_output("F","F");
    Vector<double> x(Lambda.size());
    x =0;

    //richardson iteration
    unsigned int iterations;
    const int maxiterations = 9999;
    const double omega = 2.0 / (eq.norm_A() + 1.0/eq.norm_Ainv());
    cout << "omega: "<<omega<<endl;
    Richardson(A,F,x,omega,1e-6,maxiterations,iterations);
    //CG(A,F,x,1e-8,maxiterations,iterations);
    cout << "iterations:" << iterations << endl;

    InfiniteVector<double,Index> u;
    unsigned int i2 = 0;
    for (set<Index>::const_iterator it = Lambda.begin(); it != Lambda.end(); ++it, ++i2){
      u.set_coefficient(*it, x[i2]);
    }

    //plot solution
    //u.COARSE(1e-6,v);
    u.scale(&eq, -1);
    Array1D<SampledMapping<dim> > eval(3);
    eval=eq.frame().evaluate(u,6);
    std::ofstream os2("solution_na.m");
    for(int i=0;i<3;i++){
        eval[i].matlab_output(os2);
        os2 << "surf(x,y,z);" << endl;
        os2 << "hold on;" << endl;
    }
    os2 << "view(30,55);"<<endl;
    os2 << "hold off" << endl;
    os2.close();
 #endif

#ifdef ADAPTIVE
    CachedQuarkletLDomainProblem<LDomainFrameEquation<Frame1d,Frame> > cproblem1(&eq);
    InfiniteVector<double, Index> F_eta;
    cproblem1.RHS(1e-6, F_eta);
    const double nu = cproblem1.norm_Ainv() * l2_norm(F_eta);   //benötigt hinreichend großes jmax
    double epsilon = 1e-3;
    InfiniteVector<double, Index> u_epsilon, v;
    const double a=2;
    const double b=2;
    CDD2_QUARKLET_SOLVE(cproblem1, nu, epsilon, u_epsilon, jmax, tensor_simple, pmax, a, b);

    //plot solution
    //u.COARSE(1e-6,v);
    u_epsilon.scale(&cproblem1, -1);
    Array1D<SampledMapping<dim> > eval(3);
    eval=cproblem1.frame().evaluate(u_epsilon,6);
    std::ofstream os2("solution_ad.m");
    for(int i=0;i<3;i++){
        eval[i].matlab_output(os2);
        os2 << "surf(x,y,z);" << endl;
        os2 << "hold on;" << endl;
    }
    os2 << "view(30,55);"<<endl;
    os2 << "hold off" << endl;
    os2.close();
#endif

#if 0 //test bilinearform
    const int resolution=6;
    Index testindex1(testindex);
    Index testindex2=eq.frame().get_quarklet(192);
    Array1D<SampledMapping<dim> > eval1(3);
    Array1D<SampledMapping<dim> > eval2(3);
    eval1=frame.evaluate(testindex1,resolution);
    eval2=frame.evaluate(testindex2,resolution);
    std::ofstream os("testa.m");
    os<<"Iexakt="<<eq.a(testindex1,testindex2)<<endl;
    os<<"I=0;"<<endl;
    for(int i=0;i<3;i++){
        eval1[i].matlab_output(os);
        os<<"z1=z;"<<endl;
        eval2[i].matlab_output(os);
        os<<"z2=z;"<<endl;
        os<<"xx=x(1,:);"<<endl;
        os<<"yy=y'(1,:);"<<endl;
        os<<"[gx1,gy1]=gradient(z1,2^-"<<resolution<<",2^-"<<resolution<<");"<<endl;
        os<<"[gx2,gy2]=gradient(z2,2^-"<<resolution<<",2^-"<<resolution<<");"<<endl;
        os<<"L=gx1.*gx2.+gy1.*gy2;"<<endl;
        os<<"I=I+trapz(yy,trapz(xx,L,2)');"<<endl;
    }
    os<<"I"<<endl;
    os<<"relative_error=abs(I-Iexakt)/Iexakt"<<endl;
    os.close();
#endif

#if 0 //test rhs
    const int resolution2=6;
    Index testindex3(testindex);
    Array1D<SampledMapping<dim> > eval3(3);
    eval3=frame.evaluate(testindex3, resolution2);
    Array1D<Point<dim,int> > corners;
    corners.resize(3);
    corners[0][0]=-1;
    corners[0][1]=0;
    corners[1][0]=-1;
    corners[1][1]=-1;
    corners[2][0]=0;
    corners[2][1]=-1;

    std::ofstream os3("testf.m");
    os3<<"Iexakt="<<eq.f(testindex)<<endl;
    os3<<"I=0;"<<endl;
    for(int i=0;i<3;i++){
        eval3[i].matlab_output(os3);
        os3<<"zalt=z;"<<endl;
        Point<2> q0(corners[i][0],corners[i][1]);
        Point<2> q1(corners[i][0]+1,corners[i][1]+1);
        Grid<2> mygrid(q0,q1,pow(2,resolution2));
        SampledMapping<2> smf(mygrid, rhs1);
        smf.matlab_output(os3);
        os3<<"z=z.*zalt;"<<endl;
        os3<<"xx=x(1,:);"<<endl;
        os3<<"yy=y'(1,:);"<<endl;
        os3<<"I=I+trapz(yy,trapz(xx,z,2)');"<<endl;
    }
    os3<<"I"<<endl;
    os3<<"relative_error=abs(I-Iexakt)/Iexakt"<<endl;
    os3.close();
#endif

#if 0
    //plot one function
    Array1D<SampledMapping<dim> > evalf(3);
    //Index ind=frame.get_quarklet(159);    //0-26:generatoren auf patches,
                                        //27-32:überlappende generatoren, indiziert mit p=3,4
                                        //33:überlappendes wavelet
                                        //34:nicht-überlappendes wavelet
    cout << "evaluate quarklet with index " << testindex << endl;
    evalf=frame.evaluate(testindex,6);
    std::ofstream osf("Ldomainoutput.m");
    osf << "clf;" << endl;
    osf << "axis([-1 1 -1 1 0 1]);" << endl;
    for(int i=0;i<3;i++){
        evalf[i].matlab_output(osf);
        osf << "surf(x,y,z);" << endl;

        osf << "hold on;" << endl;
    }
    osf << "view(30,55);"<<endl;
    osf << "hold off" << endl;
    osf.close();
#endif

    return 0;
}<|endoftext|>


<commit_before>#include "ManualControl.h"
#include <chrono>
#include <thread>

ManualControl::ManualControl(ICommunicationModule *pComModule) :ConfigurableModule("ManualControl"), ThreadedClass("ManualControl")
{
	speed = { 0, 0 };
	rotation = 0;

	m_pComModule = pComModule;

	AddSetting("Turn Left", []{return "r"; }, [this] {this->rotation -= 10; });
	AddSetting("Turn Right", []{return "l"; }, [this]{this->rotation += 10; });

	AddSetting("Move Left", []{return "a"; }, [this] {this->speed.x -= 10; });
	AddSetting("Move Right", []{return "d"; }, [this]{this->speed.x += 10; });

	AddSetting("Move Forward", []{return "w"; }, [this]{this->speed.y += 10; });
	AddSetting("Move Back", []{return "s"; }, [this]{this->speed.y -= 10; });
	AddSetting("Stop (space)", []{return "q"; }, [this]{this->speed = cv::Point2d(0,0); });

//	AddSetting("Rotate Right", []{return ""; }, [this]{this->wheels->Rotate(0, 20); });
//	AddSetting("Rotate Left", []{return ""; }, [this]{this->wheels->Rotate(1, 20); });
	AddSetting("Kick", []{return "k"; }, [this] {this->m_pComModule->Kick(2500); });
	AddSetting("Start tribbler", []{return "z"; }, [this]{this->m_pComModule->ToggleTribbler(100); });
	AddSetting("Stop tribbler", []{return "x"; }, [this]{this->m_pComModule->ToggleTribbler(0); });
	//Start();
}

void ManualControl::Run(){
	speed = { 0, 0 };
	rotation = 0;
	last_tick = boost::posix_time::microsec_clock::local_time();
	while (!stop_thread){
		m_pComModule->Drive(speed, rotation);
		boost::posix_time::ptime time = boost::posix_time::microsec_clock::local_time();
		double dt = (double)((time - last_tick).total_milliseconds())/1000;

		rotation -= sign0(rotation);
		speed.x -= sign0(speed.x)*dt;
		speed.y -= sign0(speed.y)*dt;
		last_tick = time;
		Sleep(100);
	}
}

ManualControl::~ManualControl()
{
}
<commit_msg>Stop rotation on q<commit_after>#include "ManualControl.h"
#include <chrono>
#include <thread>

ManualControl::ManualControl(ICommunicationModule *pComModule) :ConfigurableModule("ManualControl"), ThreadedClass("ManualControl")
{
	speed = { 0, 0 };
	rotation = 0;

	m_pComModule = pComModule;

	AddSetting("Turn Left", []{return "r"; }, [this] {this->rotation -= 10; });
	AddSetting("Turn Right", []{return "l"; }, [this]{this->rotation += 10; });

	AddSetting("Move Left", []{return "a"; }, [this] {this->speed.x -= 10; });
	AddSetting("Move Right", []{return "d"; }, [this]{this->speed.x += 10; });

	AddSetting("Move Forward", []{return "w"; }, [this]{this->speed.y += 10; });
	AddSetting("Move Back", []{return "s"; }, [this]{this->speed.y -= 10; });
	AddSetting("Stop (space)", []{return "q"; }, [this]{this->speed = cv::Point2d(0, 0); this->rotation = 0; });

//	AddSetting("Rotate Right", []{return ""; }, [this]{this->wheels->Rotate(0, 20); });
//	AddSetting("Rotate Left", []{return ""; }, [this]{this->wheels->Rotate(1, 20); });
	AddSetting("Kick", []{return "k"; }, [this] {this->m_pComModule->Kick(2500); });
	AddSetting("Start tribbler", []{return "z"; }, [this]{this->m_pComModule->ToggleTribbler(100); });
	AddSetting("Stop tribbler", []{return "x"; }, [this]{this->m_pComModule->ToggleTribbler(0); });
	//Start();
}

void ManualControl::Run(){
	speed = { 0, 0 };
	rotation = 0;
	last_tick = boost::posix_time::microsec_clock::local_time();
	while (!stop_thread){
		m_pComModule->Drive(speed, rotation);
		boost::posix_time::ptime time = boost::posix_time::microsec_clock::local_time();
		double dt = (double)((time - last_tick).total_milliseconds())/1000;

		rotation -= sign0(rotation);
		speed.x -= sign0(speed.x)*dt;
		speed.y -= sign0(speed.y)*dt;
		last_tick = time;
		Sleep(100);
	}
}

ManualControl::~ManualControl()
{
}
<|endoftext|>


<commit_before>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware 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.txt

  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.

=========================================================================*/

// QT includes
#include <QDebug>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QTabWidget>
#include <QVariant>

// CTK includes
#include "ctkColorDialog.h"

QList<QWidget*> ctkColorDialog::DefaultTabs;
int ctkColorDialog::DefaultTab = -1;
QString ctkColorDialog::LastColorName = QString();

//------------------------------------------------------------------------------
class ctkColorDialogPrivate
{
  Q_DECLARE_PUBLIC(ctkColorDialog);
protected:
  ctkColorDialog* const q_ptr;
public:
  ctkColorDialogPrivate(ctkColorDialog& object);
  void init();
  QTabWidget* LeftTabWidget;
  QWidget*    BasicTab;
  QString ColorName;
};

//------------------------------------------------------------------------------
ctkColorDialogPrivate::ctkColorDialogPrivate(ctkColorDialog& object)
  :q_ptr(&object)
{
  this->LeftTabWidget = 0;
}

//------------------------------------------------------------------------------
void ctkColorDialogPrivate::init()
{
  Q_Q(ctkColorDialog);
  QVBoxLayout* mainLay = qobject_cast<QVBoxLayout*>(q->layout());
  QHBoxLayout* topLay = qobject_cast<QHBoxLayout*>(mainLay->itemAt(0)->layout());
  QVBoxLayout* leftLay = qobject_cast<QVBoxLayout*>(topLay->takeAt(0)->layout());

  leftLay->setParent(0);
  this->BasicTab = new QWidget(q);
  this->BasicTab->setLayout(leftLay);

  this->LeftTabWidget = new QTabWidget(q);
  topLay->insertWidget(0, this->LeftTabWidget);
  this->LeftTabWidget->addTab(this->BasicTab, QObject::tr("Basic"));

  // If you use a ctkColorDialog, it's probably because you have tabs to add
  // into. Which means that you are likely to want to resize the dialog as
  // well.
  q->setSizeGripEnabled(true);
  q->layout()->setSizeConstraint(QLayout::SetDefaultConstraint);

  QObject::connect(q, SIGNAL(currentColorChanged(QColor)),
                   q, SLOT(resetColorName()));
}

//------------------------------------------------------------------------------
ctkColorDialog::ctkColorDialog(QWidget* parent)
  : QColorDialog(parent)
  , d_ptr(new ctkColorDialogPrivate(*this))
{
  Q_D(ctkColorDialog);
  d->init();
}

//------------------------------------------------------------------------------
ctkColorDialog::ctkColorDialog(const QColor& initial, QWidget* parent)
  : QColorDialog(initial, parent)
  , d_ptr(new ctkColorDialogPrivate(*this))
{
  Q_D(ctkColorDialog);
  d->init();
}

//------------------------------------------------------------------------------
ctkColorDialog::~ctkColorDialog()
{
}

//------------------------------------------------------------------------------
void ctkColorDialog::insertTab(int tabIndex, QWidget* widget, const QString& label)
{
  Q_D(ctkColorDialog);
  d->LeftTabWidget->insertTab(tabIndex, widget, label);
}

//------------------------------------------------------------------------------
void ctkColorDialog::setCurrentTab(int index)
{
  Q_D(ctkColorDialog);
  d->LeftTabWidget->setCurrentIndex(index);
}

//------------------------------------------------------------------------------
void ctkColorDialog::removeTab(int index)
{
  Q_D(ctkColorDialog);
  d->LeftTabWidget->removeTab(index);
}

//------------------------------------------------------------------------------
int ctkColorDialog::indexOf(QWidget* widget)const
{
  Q_D(const ctkColorDialog);
  return d->LeftTabWidget->indexOf(widget);
}

//------------------------------------------------------------------------------
QWidget* ctkColorDialog::widget(int index)const
{
  Q_D(const ctkColorDialog);
  return d->LeftTabWidget->widget(index);
}

//------------------------------------------------------------------------------
QColor ctkColorDialog::getColor(const QColor &initial, QWidget *parent, const QString &title,
                              ColorDialogOptions options)
{
  ctkColorDialog dlg(parent);
  if (!title.isEmpty())
    {
    dlg.setWindowTitle(title);
    }
  dlg.setOptions(options | QColorDialog::DontUseNativeDialog);
  dlg.setCurrentColor(initial);
  foreach(QWidget* tab, ctkColorDialog::DefaultTabs)
    {
    dlg.insertTab(tab->property("tabIndex").toInt(), tab, tab->windowTitle());
    if (!tab->property("colorSignal").isNull())
      {
      QObject::connect(tab, tab->property("colorSignal").toString().toLatin1(),
                       &dlg, SLOT(setColor(QColor)));
      }
    if (!tab->property("nameSignal").isNull())
      {
      QObject::connect(tab, tab->property("nameSignal").toString().toLatin1(),
                       &dlg, SLOT(setColorName(QString)));
      }
    }
  dlg.setCurrentTab(ctkColorDialog::DefaultTab);
  dlg.exec();
  foreach(QWidget* tab, ctkColorDialog::DefaultTabs)
    {
    dlg.removeTab(dlg.indexOf(tab));
    if (!tab->property("colorSignal").isNull())
      {
      QObject::disconnect(tab, tab->property("colorSignal").toString().toLatin1(),
                          &dlg, SLOT(setColor(QColor)));
      }
    if (!tab->property("nameSignal").isNull())
      {
      QObject::disconnect(tab, tab->property("nameSignal").toString().toLatin1(),
                          &dlg, SLOT(setColorName(QString)));
      }
    tab->setParent(0);
    tab->hide();
    }
  ctkColorDialog::LastColorName = dlg.colorName();
  return dlg.selectedColor();
}

//------------------------------------------------------------------------------
QString ctkColorDialog::getColorName()
{
  return ctkColorDialog::LastColorName;
}

//------------------------------------------------------------------------------
void ctkColorDialog::insertDefaultTab(int tabIndex, QWidget* widget,
                                      const QString& label,
                                      const char* colorSignal,
                                      const char* nameSignal)
{
  widget->setWindowTitle(label);
  widget->setProperty("colorSignal", colorSignal);
  widget->setProperty("nameSignal", nameSignal);
  widget->setProperty("tabIndex", tabIndex);

  ctkColorDialog::DefaultTabs << widget;
  widget->setParent(0);
}

//------------------------------------------------------------------------------
void ctkColorDialog::setDefaultTab(int index)
{
  ctkColorDialog::DefaultTab = index;
}

//------------------------------------------------------------------------------
void ctkColorDialog::setColor(const QColor& color)
{
  this->QColorDialog::setCurrentColor(color);
}

//------------------------------------------------------------------------------
void ctkColorDialog::setColorName(const QString& name)
{
  Q_D(ctkColorDialog);
  if (d->ColorName == name)
    {
    return;
    }
  d->ColorName = name;
  emit currentColorNameChanged(d->ColorName);
}

//------------------------------------------------------------------------------
QString ctkColorDialog::colorName()const
{
  Q_D(const ctkColorDialog);
  return d->ColorName;
}

//------------------------------------------------------------------------------
void ctkColorDialog::resetColorName()
{
  this->setColorName(QString());
}
<commit_msg>BUG: Fix ctkColorDialog crash on Mac with Qt5<commit_after>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware 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.txt

  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.

=========================================================================*/

// QT includes
#include <QDebug>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QTabWidget>
#include <QVariant>

// CTK includes
#include "ctkColorDialog.h"

QList<QWidget*> ctkColorDialog::DefaultTabs;
int ctkColorDialog::DefaultTab = -1;
QString ctkColorDialog::LastColorName = QString();

//------------------------------------------------------------------------------
class ctkColorDialogPrivate
{
  Q_DECLARE_PUBLIC(ctkColorDialog);
protected:
  ctkColorDialog* const q_ptr;
public:
  ctkColorDialogPrivate(ctkColorDialog& object);
  void init();
  QTabWidget* LeftTabWidget;
  QWidget*    BasicTab;
  QString ColorName;
};

//------------------------------------------------------------------------------
ctkColorDialogPrivate::ctkColorDialogPrivate(ctkColorDialog& object)
  :q_ptr(&object)
{
  this->LeftTabWidget = 0;
}

//------------------------------------------------------------------------------
void ctkColorDialogPrivate::init()
{
  Q_Q(ctkColorDialog);
  QVBoxLayout* mainLay = qobject_cast<QVBoxLayout*>(q->layout());
  QHBoxLayout* topLay = qobject_cast<QHBoxLayout*>(mainLay->itemAt(0)->layout());
  QVBoxLayout* leftLay = qobject_cast<QVBoxLayout*>(topLay->takeAt(0)->layout());

  leftLay->setParent(0);
  this->BasicTab = new QWidget(q);
  this->BasicTab->setLayout(leftLay);

  this->LeftTabWidget = new QTabWidget(q);
  topLay->insertWidget(0, this->LeftTabWidget);
  this->LeftTabWidget->addTab(this->BasicTab, QObject::tr("Basic"));

  // If you use a ctkColorDialog, it's probably because you have tabs to add
  // into. Which means that you are likely to want to resize the dialog as
  // well.
  q->setSizeGripEnabled(true);
  q->layout()->setSizeConstraint(QLayout::SetDefaultConstraint);

  QObject::connect(q, SIGNAL(currentColorChanged(QColor)),
                   q, SLOT(resetColorName()));
}

//------------------------------------------------------------------------------
ctkColorDialog::ctkColorDialog(QWidget* parent)
  : QColorDialog(parent)
  , d_ptr(new ctkColorDialogPrivate(*this))
{
  Q_D(ctkColorDialog);
  // Force using Qt's standard color dialog to support adding new widgets
  setOption(QColorDialog::DontUseNativeDialog);
  d->init();
}

//------------------------------------------------------------------------------
ctkColorDialog::ctkColorDialog(const QColor& initial, QWidget* parent)
  : QColorDialog(initial, parent)
  , d_ptr(new ctkColorDialogPrivate(*this))
{
  Q_D(ctkColorDialog);
  // Force using Qt's standard color dialog to support adding new widgets
  setOption(QColorDialog::DontUseNativeDialog);
  d->init();
}

//------------------------------------------------------------------------------
ctkColorDialog::~ctkColorDialog()
{
}

//------------------------------------------------------------------------------
void ctkColorDialog::insertTab(int tabIndex, QWidget* widget, const QString& label)
{
  Q_D(ctkColorDialog);
  d->LeftTabWidget->insertTab(tabIndex, widget, label);
}

//------------------------------------------------------------------------------
void ctkColorDialog::setCurrentTab(int index)
{
  Q_D(ctkColorDialog);
  d->LeftTabWidget->setCurrentIndex(index);
}

//------------------------------------------------------------------------------
void ctkColorDialog::removeTab(int index)
{
  Q_D(ctkColorDialog);
  d->LeftTabWidget->removeTab(index);
}

//------------------------------------------------------------------------------
int ctkColorDialog::indexOf(QWidget* widget)const
{
  Q_D(const ctkColorDialog);
  return d->LeftTabWidget->indexOf(widget);
}

//------------------------------------------------------------------------------
QWidget* ctkColorDialog::widget(int index)const
{
  Q_D(const ctkColorDialog);
  return d->LeftTabWidget->widget(index);
}

//------------------------------------------------------------------------------
QColor ctkColorDialog::getColor(const QColor &initial, QWidget *parent, const QString &title,
                              ColorDialogOptions options)
{
  ctkColorDialog dlg(parent);
  if (!title.isEmpty())
    {
    dlg.setWindowTitle(title);
    }
  dlg.setOptions(options | QColorDialog::DontUseNativeDialog);
  dlg.setCurrentColor(initial);
  foreach(QWidget* tab, ctkColorDialog::DefaultTabs)
    {
    dlg.insertTab(tab->property("tabIndex").toInt(), tab, tab->windowTitle());
    if (!tab->property("colorSignal").isNull())
      {
      QObject::connect(tab, tab->property("colorSignal").toString().toLatin1(),
                       &dlg, SLOT(setColor(QColor)));
      }
    if (!tab->property("nameSignal").isNull())
      {
      QObject::connect(tab, tab->property("nameSignal").toString().toLatin1(),
                       &dlg, SLOT(setColorName(QString)));
      }
    }
  dlg.setCurrentTab(ctkColorDialog::DefaultTab);
  dlg.exec();
  foreach(QWidget* tab, ctkColorDialog::DefaultTabs)
    {
    dlg.removeTab(dlg.indexOf(tab));
    if (!tab->property("colorSignal").isNull())
      {
      QObject::disconnect(tab, tab->property("colorSignal").toString().toLatin1(),
                          &dlg, SLOT(setColor(QColor)));
      }
    if (!tab->property("nameSignal").isNull())
      {
      QObject::disconnect(tab, tab->property("nameSignal").toString().toLatin1(),
                          &dlg, SLOT(setColorName(QString)));
      }
    tab->setParent(0);
    tab->hide();
    }
  ctkColorDialog::LastColorName = dlg.colorName();
  return dlg.selectedColor();
}

//------------------------------------------------------------------------------
QString ctkColorDialog::getColorName()
{
  return ctkColorDialog::LastColorName;
}

//------------------------------------------------------------------------------
void ctkColorDialog::insertDefaultTab(int tabIndex, QWidget* widget,
                                      const QString& label,
                                      const char* colorSignal,
                                      const char* nameSignal)
{
  widget->setWindowTitle(label);
  widget->setProperty("colorSignal", colorSignal);
  widget->setProperty("nameSignal", nameSignal);
  widget->setProperty("tabIndex", tabIndex);

  ctkColorDialog::DefaultTabs << widget;
  widget->setParent(0);
}

//------------------------------------------------------------------------------
void ctkColorDialog::setDefaultTab(int index)
{
  ctkColorDialog::DefaultTab = index;
}

//------------------------------------------------------------------------------
void ctkColorDialog::setColor(const QColor& color)
{
  this->QColorDialog::setCurrentColor(color);
}

//------------------------------------------------------------------------------
void ctkColorDialog::setColorName(const QString& name)
{
  Q_D(ctkColorDialog);
  if (d->ColorName == name)
    {
    return;
    }
  d->ColorName = name;
  emit currentColorNameChanged(d->ColorName);
}

//------------------------------------------------------------------------------
QString ctkColorDialog::colorName()const
{
  Q_D(const ctkColorDialog);
  return d->ColorName;
}

//------------------------------------------------------------------------------
void ctkColorDialog::resetColorName()
{
  this->setColorName(QString());
}
<|endoftext|>


<commit_before>#include "objLoader.hpp"

#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <map>
#include <set>

using namespace std;
using glm::vec3;

// Function to read input data values
template <typename T>
bool readvals(stringstream &s, const int numvals, T* values) {
    for (int i = 0; i < numvals; i++) {
        s >> values[i];

        if (s.fail()) {
            cout << "Failed reading value " << i << " will skip\n";
            return false;
        }
    }

    return true;
}

//string split helper
vector<string> split(string s, char delim) {
    vector<string> ret;
    ret.reserve(s.length());

    auto idx0 = 0u;
    auto idx1 = s.find(delim);
    while (idx1 != string::npos) {
        ret.push_back(s.substr(idx0, idx1 - idx0));
        idx0 = idx1 + 1;
        idx1 = s.find(delim, idx0);
    }
    ret.push_back(s.substr(idx0));

    return ret;
}

// helper to push float members of a vec3 to a vector
void addToVec(std::vector<const GLfloat> &c, const glm::vec3 &v) {
    c.push_back(v.x);
    c.push_back(v.y);
    c.push_back(v.z);
}

// helper to calculate averaged vertex normal
void addToVec(std::vector<const GLfloat> &c, const set<Face*> &s) {
    vec3 average_normal;
    for (auto f : s)
        average_normal += f->normal;
    average_normal = glm::normalize(average_normal);
    c.push_back(average_normal.x);
    c.push_back(average_normal.y);
    c.push_back(average_normal.z);
}

void loadObj(string obj_file, Obj &obj) {
    // disable syncing with c stdio functions, we only need c++ streams!
    // improves performance of streams a lot!
    ifstream::sync_with_stdio(false);

    ifstream file(obj_file);

    if (file.is_open()) {
        auto& faces    = obj.faces;
        auto& vertices = obj.vertices;

        auto count = std::count(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), '\n');

        // jump back to beginning of file
        file.clear();
        file.seekg(0, ios::beg);

        faces.clear();
        faces.reserve(count);
        vertices.clear();
        vertices.reserve(count);

        // for averaging vertex normals
        map<vec3*, set<Face*>> vtx_triangle_map;

        // read file line by line as long as it's good
        while (file.good()) {
            // read line
            string line;
            getline(file, line);

            if (line.empty())
                continue;

            stringstream ssline(line);

            // extract mode (v, f, vn, ...)
            string mode;
            ssline >> mode;

            // erase mode from input line
            line = string(line.begin()+2, line.end());
            ssline.str(line);

            // interpret mode
            if (mode == "#")
                continue;

            else if (mode == "v") {
                // read vertex data
                vector<float> coords(3, 0.0f);
                if (readvals(ssline, 3, &coords[0])) {
                    vertices.push_back(vec3(coords[0], coords[1], coords[2]));
                }
            }

            else if (mode == "f") {
                // read triangle face, vertices are indexed beginning from 1

                // strip out any normals or texture specification
                auto vertex_indices = split(line, ' ');
                auto stripped_indices = accumulate(begin(vertex_indices),
                                                   end(vertex_indices),
                                                   string(),
                                                   [](string &left, string right) -> string {
                                                       auto spl = split(right, '/');
                                                       return left + " " + spl[0];
                                                   });
                ssline.str(stripped_indices);
                vector<int> idx(3, 0);
                if (readvals(ssline, 3, &idx[0])) {
                    std::transform(begin(idx), end(idx), begin(idx), [](int i) { return --i; });

                    auto& v1 = vertices[idx[0]];
                    auto& v2 = vertices[idx[1]];
                    auto& v3 = vertices[idx[2]];

                    auto face = Face(v1, v2, v3);
                    faces.emplace_back(face);

                    // save the triangle for each vertex for averaging normals
                    vtx_triangle_map[&v1].insert(&faces.back());
                    vtx_triangle_map[&v2].insert(&faces.back());
                    vtx_triangle_map[&v3].insert(&faces.back());

                    face.normal;
                }
            }
        }

        file.close();

        // generate vertex and normal array for fast opengl rendering
        auto& gl_vertices = obj.gl_vertices;
        auto& gl_normals  = obj.gl_normals;
        auto& gl_normals_average  = obj.gl_normals_average;
        gl_vertices.clear();
        gl_vertices.reserve(vertices.size());
        for (auto& face : faces) {
            addToVec(gl_vertices, face.v0);
            addToVec(gl_vertices, face.v1);
            addToVec(gl_vertices, face.v2);

            addToVec(gl_normals, face.normal);
            addToVec(gl_normals, face.normal);
            addToVec(gl_normals, face.normal);

            // generate averaged vertex normals
            addToVec(gl_normals_average, vtx_triangle_map[&face.v0]);
            addToVec(gl_normals_average, vtx_triangle_map[&face.v1]);
            addToVec(gl_normals_average, vtx_triangle_map[&face.v2]);
        }
    }
    else {
        throw std::exception((string("Unable to open file ") + obj_file).c_str());
    }
}<commit_msg>performance gain for converting string to numbers (stringstreams stream operator is totally slow!)<commit_after>#include "objLoader.hpp"

#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <map>
#include <set>

using namespace std;
using glm::vec3;

// Function to read input data values
bool readvals(stringstream &s, const int numvals, GLfloat* values) {
    for (int i = 0; i < numvals; i++) {
        string value;
        s >> value;

        try {
            auto v = std::stof(value);
            values[i] = v;
        }
        catch (std::exception) {
            cout << "Failed reading value " << i << " will skip\n";
            return false;
        }
    }

    return true;
}

bool readvals(stringstream &s, const int numvals, int* values) {
    for (int i = 0; i < numvals; i++) {
        string value;
        s >> value;

        try {
            auto v = std::stoi(value);
            values[i] = v;
        }
        catch (std::exception) {
            cout << "Failed reading value " << i << " will skip\n";
            return false;
        }
    }

    return true;
}

//string split helper
vector<string> split(string s, char delim) {
    vector<string> ret;
    ret.reserve(s.length());

    auto idx0 = 0u;
    auto idx1 = s.find(delim);
    while (idx1 != string::npos) {
        ret.push_back(s.substr(idx0, idx1 - idx0));
        idx0 = idx1 + 1;
        idx1 = s.find(delim, idx0);
    }
    ret.push_back(s.substr(idx0));

    return ret;
}

// helper to push float members of a vec3 to a vector
void addToVec(std::vector<const GLfloat> &c, const glm::vec3 &v) {
    c.push_back(v.x);
    c.push_back(v.y);
    c.push_back(v.z);
}

// helper to calculate averaged vertex normal
void addToVec(std::vector<const GLfloat> &c, const set<Face*> &s) {
    vec3 average_normal;
    for (auto f : s)
        average_normal += f->normal;
    average_normal = glm::normalize(average_normal);
    c.push_back(average_normal.x);
    c.push_back(average_normal.y);
    c.push_back(average_normal.z);
}

void loadObj(string obj_file, Obj &obj) {
    // disable syncing with c stdio functions, we only need c++ streams!
    // improves performance of streams a lot!
    ifstream::sync_with_stdio(false);

    ifstream file(obj_file);

    if (file.is_open()) {
        auto& faces    = obj.faces;
        auto& vertices = obj.vertices;

        auto count = std::count(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), '\n');

        // jump back to beginning of file
        file.clear();
        file.seekg(0, ios::beg);

        faces.clear();
        faces.reserve(count);
        vertices.clear();
        vertices.reserve(count);

        // for averaging vertex normals
        map<vec3*, set<Face*>> vtx_triangle_map;

        // read file line by line as long as it's good
        while (file.good()) {
            // read line
            string line;
            getline(file, line);

            if (line.empty())
                continue;

            stringstream ssline(line);

            // extract mode (v, f, vn, ...)
            string mode;
            ssline >> mode;

            // erase mode from input line
            line = string(line.begin()+2, line.end());
            ssline.str(line);

            // interpret mode
            if (mode == "#")
                continue;

            else if (mode == "v") {
                // read vertex data
                vector<float> coords(3, 0.0f);
                if (readvals(ssline, 3, &coords[0])) {
                    vertices.push_back(vec3(coords[0], coords[1], coords[2]));
                }
            }

            else if (mode == "f") {
                // read triangle face, vertices are indexed beginning from 1

                // strip out any normals or texture specification
                auto vertex_indices = split(line, ' ');
                auto stripped_indices = accumulate(begin(vertex_indices),
                                                   end(vertex_indices),
                                                   string(),
                                                   [](string &left, string right) -> string {
                                                       auto spl = split(right, '/');
                                                       return left + " " + spl[0];
                                                   });
                ssline.str(stripped_indices);
                vector<int> idx(3, 0);
                if (readvals(ssline, 3, &idx[0])) {
                    std::transform(begin(idx), end(idx), begin(idx), [](int i) { return --i; });

                    auto& v1 = vertices[idx[0]];
                    auto& v2 = vertices[idx[1]];
                    auto& v3 = vertices[idx[2]];

                    auto face = Face(v1, v2, v3);
                    faces.emplace_back(face);

                    // save the triangle for each vertex for averaging normals
                    vtx_triangle_map[&v1].insert(&faces.back());
                    vtx_triangle_map[&v2].insert(&faces.back());
                    vtx_triangle_map[&v3].insert(&faces.back());

                    face.normal;
                }
            }
        }

        file.close();

        // generate vertex and normal array for fast opengl rendering
        auto& gl_vertices = obj.gl_vertices;
        auto& gl_normals  = obj.gl_normals;
        auto& gl_normals_average  = obj.gl_normals_average;
        gl_vertices.clear();
        gl_vertices.reserve(vertices.size());
        for (auto& face : faces) {
            addToVec(gl_vertices, face.v0);
            addToVec(gl_vertices, face.v1);
            addToVec(gl_vertices, face.v2);

            addToVec(gl_normals, face.normal);
            addToVec(gl_normals, face.normal);
            addToVec(gl_normals, face.normal);

            // generate averaged vertex normals
            addToVec(gl_normals_average, vtx_triangle_map[&face.v0]);
            addToVec(gl_normals_average, vtx_triangle_map[&face.v1]);
            addToVec(gl_normals_average, vtx_triangle_map[&face.v2]);
        }
    }
    else {
        throw std::exception((string("Unable to open file ") + obj_file).c_str());
    }
}<|endoftext|>


<commit_before>#include "QueryParams.h"

#include <boost/filesystem/fstream.hpp>

#include "Header.h"

using namespace HTTP;

QueryParams::QueryParams() : FMParseState(STATE_HEADERSTART), BoundaryParseCounter(2), CurrFileS(nullptr)
{

}

QueryParams::QueryParams(const FileUploadParams &UploadParams) : FMParseState(STATE_HEADERSTART), BoundaryParseCounter(2),
	FUParams(UploadParams),
	CurrFileS(nullptr)
{

}

bool QueryParams::AddURLEncoded(const char *Begin, const char *End)
{
	enum PARSESTATE
	{
		PS_PARAM_END,
		PS_VALUE_END,
	} CurrState=PS_PARAM_END;

	ParseTmp.reserve(ParseTmp.size());
	ParseTmp.clear();

	std::string *ValStr=nullptr;
	std::string *TargetStr= &ParseTmp;

	while (Begin!=End)
	{
		char CurrVal=*Begin++;

		if (CurrVal=='+')
			TargetStr->append((std::string::size_type)1,' ');
		else if ((CurrVal=='%') && (End-Begin>0))
		{
			TargetStr->append((std::string::size_type)1,(std::string::value_type)(
				(GetHexVal(*Begin) << 4) |
				GetHexVal(*(Begin+1)) ) );
			Begin+=2;
		}
		else
		{
			if (CurrState==PS_PARAM_END)
			{
				if (CurrVal=='=')
				{
					Param &CurrParam=ParamMap[ParseTmp];
					CurrParam.Value.clear();

					ValStr=&CurrParam.Value;

					CurrState=PS_VALUE_END;
					TargetStr=ValStr;
				}
				else
					TargetStr->append((std::string::size_type)1,CurrVal);
			}
			else if (CurrState==PS_VALUE_END)
			{
				if (CurrVal=='&')
				{
					ValStr=nullptr;

					ParseTmp.reserve(ParseTmp.size());
					ParseTmp.clear();

					CurrState=PS_PARAM_END;
					TargetStr=&ParseTmp;
				}
				else
					TargetStr->append((std::string::size_type)1,CurrVal);
			}
		}
	}

	return true;
}

bool QueryParams::AppendFormMultipart(const char *Begin, const char *End)
{
/*Continous boundary detection:
	set content start to start of the input data
	for each input character:
		if the current char equals to the parse position in the boundary string:
			advance the parse position
			if the boundary string is fully matched:
				we have content from content start to the start of the boundary string.
				if the boundary string starts after the end of the input data:
					the bytes in [start of content, start of boundary) are content
				reset the parse position
				set content start to current position + 1
		otherwise:
			the bytes in temporary data are content
			reset the parse position
			clear the temporary data storage
	save the parse position
	the bytes [content start, end-parse position) are content
	store the bytes [end-parse position, end) as temporary data*/

	const char *ContentBegin=Begin;
	while (Begin!=End)
	{
		char CurrVal=*Begin;
		if (CurrVal==BoundaryStr[BoundaryParseCounter])
		{
			if (++BoundaryParseCounter==BoundaryStr.length())
			{
				if (!AppendToCurrentPart(ContentBegin,Begin-BoundaryParseCounter+1))
					return false;
				ContentBegin=Begin + 1;

				BoundaryParseCounter=0;
				StartNewPart();
			}
		}
		else
		{
			if (!ParseTmp.empty())
			{
				if (!AppendToCurrentPart(ParseTmp.data(),ParseTmp.data()+ParseTmp.length()))
					return false;
				ParseTmp.clear();
			}

			BoundaryParseCounter=0;
		}

		Begin++;
	}

	if (!AppendToCurrentPart(ContentBegin,Begin-BoundaryParseCounter))
		return false;
	ParseTmp.append(Begin-BoundaryParseCounter,Begin);

	return true;
}

const QueryParams::Param &QueryParams::Get(const std::string &Name) const
{
	ParamMapType::const_iterator FindI=ParamMap.find(Name);
	if (FindI!=ParamMap.end())
		return FindI->second;
	else
		throw ParameterNotFound();
}

const QueryParams::Param QueryParams::Get(const std::string &Name, const std::string &Default) const
{
	ParamMapType::const_iterator FindI=ParamMap.find(Name);
	if (FindI!=ParamMap.end())
		return FindI->second;
	else
		return Param(Default);
}

void QueryParams::DecodeURLEncoded(std::string &Target, const char *Begin, const char *End)
{
	while (Begin!=End)
	{
		char CurrVal=*Begin++;

		if (CurrVal=='+')
			Target.append((std::string::size_type)1,' ');
		else if ((CurrVal=='%') && (End-Begin>0))
		{
			Target.append((std::string::size_type)1,(std::string::value_type)(
				(GetHexVal(*Begin) << 4) |
				GetHexVal(*(Begin+1)) ) );
			Begin+=2;
		}
		else
			Target.append((std::string::size_type)1,CurrVal);
	}
}

void QueryParams::OnBoundaryParsed()
{
	BoundaryStr="\r\n--" + BoundaryStr;
}

void QueryParams::DeleteUploadedFiles()
{
	for (FileMapType::value_type &CurrFile : FileMap)
	{
		boost::system::error_code DelErr;
		boost::filesystem::remove(CurrFile.second.Path,DelErr);
	}
}

void QueryParams::StartNewPart()
{
	FMParseState=STATE_HEADERSTART;
	FMParseCounter=0;
	HeaderParseTmp.clear();
}

bool QueryParams::AppendToCurrentPart(const char *Begin, const char *End)
{
	if ((Begin>=End) || (FMParseState==STATE_FINISHED))
		return true;

	const char *OrigBegin=Begin;
	while ((Begin!=End) && (FMParseState!=STATE_READ))
	{
		char CurrVal=*Begin;
		switch (FMParseState)
		{
		case STATE_HEADERSTART:
			if (FMParseCounter==0)
			{
				if ((CurrVal=='\r') || (CurrVal=='-'))
					FMParseCounter++;
				else
					return false;
			}
			else if (FMParseCounter==1)
			{
				if (CurrVal=='\n')
				{
					FMParseCounter=0;
					FMParseState=STATE_HEADERS_END;
					OrigBegin=Begin + 1;
				}
				else if (CurrVal=='-')
					FMParseState=STATE_FINISHED;
				else
					return false;
			}
			break;
		case STATE_HEADERS_END:
			if (CurrVal=="\r\n\r\n"[FMParseCounter])
			{
				if (++FMParseCounter==4)
				{
					//End of headers found.
					if (Begin-OrigBegin-4>0)
						HeaderParseTmp.append(OrigBegin,Begin+1);

					if (ParseFMHeaders(HeaderParseTmp.data(),HeaderParseTmp.data()+HeaderParseTmp.length()))
					{
						//Now, we can read the actual content until StartNewPart is called.
						FMParseState=STATE_READ;
						break;
					}
					else
					{
						HeaderParseTmp.clear();
						return false;
					}
				}
			}
			else
				FMParseCounter=0;
			break;
		case STATE_FINISHED:
			if (CurrFileS)
			{
				CurrFileS->close();
				delete CurrFileS;
				CurrFileS=nullptr;
			}
			return true;
		}

		Begin++;
	}

	if (FMParseState==STATE_READ)
	{
		if (IsCurrPartValid())
		{
			if (IsCurrPartFile())
			{
				CurrFileS->write(Begin,End-Begin);
				return !CurrFileS->fail();
			}
			else
			{
				CurrFMPart.TargetParam->Value.append(Begin,End);
				return true;
			}
		}
		else
			return false;
	}
	else if (FMParseState==STATE_HEADERS_END)
	{
		HeaderParseTmp.append(OrigBegin,Begin);
		return true;
	}
	else
		return true;
}

bool QueryParams::ParseFMHeaders(const char *HeadersBegin, const char *HeadersEnd)
{
	std::string Name, FileName;
	const char *ContentTypeVal=nullptr;

	const char *HBegin=HeadersBegin;
	while (HeadersBegin!=HeadersEnd)
	{
		char CurrVal=*HeadersBegin;
		if (CurrVal=='\n')
		{
			//Header in [HBegin,HeadersBegin[ .
			Header CurrHeader((char *)HBegin,(char *)HeadersBegin);
			if (CurrHeader.IntName==HN_CONTENT_DISPOSITION)
				CurrHeader.ParseContentDisposition(Name,FileName);
			else if (CurrHeader.IntName==HN_CONTENT_TYPE)
				ContentTypeVal=CurrHeader.Value;

			HBegin=HeadersBegin+1;
		}

		HeadersBegin++;
	}

	if (!Name.empty())
	{
		if (CurrFileS)
		{
			CurrFileS->close();
			delete CurrFileS;
			CurrFileS=nullptr;
		}

		if (ContentTypeVal)
		{
			try
			{
				boost::filesystem::path TmpFilePath=
					(FUParams.Root.empty() ? boost::filesystem::temp_directory_path() : FUParams.Root) /
					boost::filesystem::unique_path();

				CurrFileS=new boost::filesystem::ofstream(TmpFilePath,std::ios_base::binary);

				CurrFMPart.TargetFile=&FileMap[Name];
				CurrFMPart.TargetFile->MimeType=ContentTypeVal;
				CurrFMPart.TargetFile->OrigFileName=FileName;
				CurrFMPart.TargetFile->Path=TmpFilePath;
			}
			catch (...)
			{
				CurrFMPart.TargetFile=NULL;

				return false;
			}
		}
		else
			CurrFMPart.TargetParam=&ParamMap[Name];

		return true;
	}
	else
	{
		CurrFMPart.TargetFile=NULL;
		return false;
	}
}
<commit_msg>QueryParams::AppendToCurrentPart: switch label warning fix<commit_after>#include "QueryParams.h"

#include <boost/filesystem/fstream.hpp>

#include "Header.h"

using namespace HTTP;

QueryParams::QueryParams() : FMParseState(STATE_HEADERSTART), BoundaryParseCounter(2), CurrFileS(nullptr)
{

}

QueryParams::QueryParams(const FileUploadParams &UploadParams) : FMParseState(STATE_HEADERSTART), BoundaryParseCounter(2),
	FUParams(UploadParams),
	CurrFileS(nullptr)
{

}

bool QueryParams::AddURLEncoded(const char *Begin, const char *End)
{
	enum PARSESTATE
	{
		PS_PARAM_END,
		PS_VALUE_END,
	} CurrState=PS_PARAM_END;

	ParseTmp.reserve(ParseTmp.size());
	ParseTmp.clear();

	std::string *ValStr=nullptr;
	std::string *TargetStr= &ParseTmp;

	while (Begin!=End)
	{
		char CurrVal=*Begin++;

		if (CurrVal=='+')
			TargetStr->append((std::string::size_type)1,' ');
		else if ((CurrVal=='%') && (End-Begin>0))
		{
			TargetStr->append((std::string::size_type)1,(std::string::value_type)(
				(GetHexVal(*Begin) << 4) |
				GetHexVal(*(Begin+1)) ) );
			Begin+=2;
		}
		else
		{
			if (CurrState==PS_PARAM_END)
			{
				if (CurrVal=='=')
				{
					Param &CurrParam=ParamMap[ParseTmp];
					CurrParam.Value.clear();

					ValStr=&CurrParam.Value;

					CurrState=PS_VALUE_END;
					TargetStr=ValStr;
				}
				else
					TargetStr->append((std::string::size_type)1,CurrVal);
			}
			else if (CurrState==PS_VALUE_END)
			{
				if (CurrVal=='&')
				{
					ValStr=nullptr;

					ParseTmp.reserve(ParseTmp.size());
					ParseTmp.clear();

					CurrState=PS_PARAM_END;
					TargetStr=&ParseTmp;
				}
				else
					TargetStr->append((std::string::size_type)1,CurrVal);
			}
		}
	}

	return true;
}

bool QueryParams::AppendFormMultipart(const char *Begin, const char *End)
{
/*Continous boundary detection:
	set content start to start of the input data
	for each input character:
		if the current char equals to the parse position in the boundary string:
			advance the parse position
			if the boundary string is fully matched:
				we have content from content start to the start of the boundary string.
				if the boundary string starts after the end of the input data:
					the bytes in [start of content, start of boundary) are content
				reset the parse position
				set content start to current position + 1
		otherwise:
			the bytes in temporary data are content
			reset the parse position
			clear the temporary data storage
	save the parse position
	the bytes [content start, end-parse position) are content
	store the bytes [end-parse position, end) as temporary data*/

	const char *ContentBegin=Begin;
	while (Begin!=End)
	{
		char CurrVal=*Begin;
		if (CurrVal==BoundaryStr[BoundaryParseCounter])
		{
			if (++BoundaryParseCounter==BoundaryStr.length())
			{
				if (!AppendToCurrentPart(ContentBegin,Begin-BoundaryParseCounter+1))
					return false;
				ContentBegin=Begin + 1;

				BoundaryParseCounter=0;
				StartNewPart();
			}
		}
		else
		{
			if (!ParseTmp.empty())
			{
				if (!AppendToCurrentPart(ParseTmp.data(),ParseTmp.data()+ParseTmp.length()))
					return false;
				ParseTmp.clear();
			}

			BoundaryParseCounter=0;
		}

		Begin++;
	}

	if (!AppendToCurrentPart(ContentBegin,Begin-BoundaryParseCounter))
		return false;
	ParseTmp.append(Begin-BoundaryParseCounter,Begin);

	return true;
}

const QueryParams::Param &QueryParams::Get(const std::string &Name) const
{
	ParamMapType::const_iterator FindI=ParamMap.find(Name);
	if (FindI!=ParamMap.end())
		return FindI->second;
	else
		throw ParameterNotFound();
}

const QueryParams::Param QueryParams::Get(const std::string &Name, const std::string &Default) const
{
	ParamMapType::const_iterator FindI=ParamMap.find(Name);
	if (FindI!=ParamMap.end())
		return FindI->second;
	else
		return Param(Default);
}

void QueryParams::DecodeURLEncoded(std::string &Target, const char *Begin, const char *End)
{
	while (Begin!=End)
	{
		char CurrVal=*Begin++;

		if (CurrVal=='+')
			Target.append((std::string::size_type)1,' ');
		else if ((CurrVal=='%') && (End-Begin>0))
		{
			Target.append((std::string::size_type)1,(std::string::value_type)(
				(GetHexVal(*Begin) << 4) |
				GetHexVal(*(Begin+1)) ) );
			Begin+=2;
		}
		else
			Target.append((std::string::size_type)1,CurrVal);
	}
}

void QueryParams::OnBoundaryParsed()
{
	BoundaryStr="\r\n--" + BoundaryStr;
}

void QueryParams::DeleteUploadedFiles()
{
	for (FileMapType::value_type &CurrFile : FileMap)
	{
		boost::system::error_code DelErr;
		boost::filesystem::remove(CurrFile.second.Path,DelErr);
	}
}

void QueryParams::StartNewPart()
{
	FMParseState=STATE_HEADERSTART;
	FMParseCounter=0;
	HeaderParseTmp.clear();
}

bool QueryParams::AppendToCurrentPart(const char *Begin, const char *End)
{
	if ((Begin>=End) || (FMParseState==STATE_FINISHED))
		return true;

	const char *OrigBegin=Begin;
	while ((Begin!=End) && (FMParseState!=STATE_READ))
	{
		char CurrVal=*Begin;
		switch (FMParseState)
		{
		case STATE_HEADERSTART:
			if (FMParseCounter==0)
			{
				if ((CurrVal=='\r') || (CurrVal=='-'))
					FMParseCounter++;
				else
					return false;
			}
			else if (FMParseCounter==1)
			{
				if (CurrVal=='\n')
				{
					FMParseCounter=0;
					FMParseState=STATE_HEADERS_END;
					OrigBegin=Begin + 1;
				}
				else if (CurrVal=='-')
					FMParseState=STATE_FINISHED;
				else
					return false;
			}
			break;
		case STATE_HEADERS_END:
			if (CurrVal=="\r\n\r\n"[FMParseCounter])
			{
				if (++FMParseCounter==4)
				{
					//End of headers found.
					if (Begin-OrigBegin-4>0)
						HeaderParseTmp.append(OrigBegin,Begin+1);

					if (ParseFMHeaders(HeaderParseTmp.data(),HeaderParseTmp.data()+HeaderParseTmp.length()))
					{
						//Now, we can read the actual content until StartNewPart is called.
						FMParseState=STATE_READ;
						break;
					}
					else
					{
						HeaderParseTmp.clear();
						return false;
					}
				}
			}
			else
				FMParseCounter=0;
			break;
		case STATE_FINISHED:
			if (CurrFileS)
			{
				CurrFileS->close();
				delete CurrFileS;
				CurrFileS=nullptr;
			}
			return true;
		default:
			break;
		}

		Begin++;
	}

	if (FMParseState==STATE_READ)
	{
		if (IsCurrPartValid())
		{
			if (IsCurrPartFile())
			{
				CurrFileS->write(Begin,End-Begin);
				return !CurrFileS->fail();
			}
			else
			{
				CurrFMPart.TargetParam->Value.append(Begin,End);
				return true;
			}
		}
		else
			return false;
	}
	else if (FMParseState==STATE_HEADERS_END)
	{
		HeaderParseTmp.append(OrigBegin,Begin);
		return true;
	}
	else
		return true;
}

bool QueryParams::ParseFMHeaders(const char *HeadersBegin, const char *HeadersEnd)
{
	std::string Name, FileName;
	const char *ContentTypeVal=nullptr;

	const char *HBegin=HeadersBegin;
	while (HeadersBegin!=HeadersEnd)
	{
		char CurrVal=*HeadersBegin;
		if (CurrVal=='\n')
		{
			//Header in [HBegin,HeadersBegin[ .
			Header CurrHeader((char *)HBegin,(char *)HeadersBegin);
			if (CurrHeader.IntName==HN_CONTENT_DISPOSITION)
				CurrHeader.ParseContentDisposition(Name,FileName);
			else if (CurrHeader.IntName==HN_CONTENT_TYPE)
				ContentTypeVal=CurrHeader.Value;

			HBegin=HeadersBegin+1;
		}

		HeadersBegin++;
	}

	if (!Name.empty())
	{
		if (CurrFileS)
		{
			CurrFileS->close();
			delete CurrFileS;
			CurrFileS=nullptr;
		}

		if (ContentTypeVal)
		{
			try
			{
				boost::filesystem::path TmpFilePath=
					(FUParams.Root.empty() ? boost::filesystem::temp_directory_path() : FUParams.Root) /
					boost::filesystem::unique_path();

				CurrFileS=new boost::filesystem::ofstream(TmpFilePath,std::ios_base::binary);

				CurrFMPart.TargetFile=&FileMap[Name];
				CurrFMPart.TargetFile->MimeType=ContentTypeVal;
				CurrFMPart.TargetFile->OrigFileName=FileName;
				CurrFMPart.TargetFile->Path=TmpFilePath;
			}
			catch (...)
			{
				CurrFMPart.TargetFile=NULL;

				return false;
			}
		}
		else
			CurrFMPart.TargetParam=&ParamMap[Name];

		return true;
	}
	else
	{
		CurrFMPart.TargetFile=NULL;
		return false;
	}
}
<|endoftext|>


<commit_before>/*!
	@file
	@author		Albert Semenov
	@date		04/2009
	@module
*/
/*
	This file is part of MyGUI.

	MyGUI 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 3 of the License, or
	(at your option) any later version.

	MyGUI 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 MyGUI.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_Timer.h"

#if MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32
#include <windows.h>
#pragma comment(lib, "winmm.lib")
#endif

namespace MyGUI
{

	void Timer::reset()
	{
		mTimeStart = getCurrentMilliseconds();
	}

	unsigned long Timer::getMilliseconds()
	{
		return getCurrentMilliseconds() - mTimeStart;
	}

	unsigned long Timer::getCurrentMilliseconds()
	{
#if MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32
		/*
		We do this because clock() is not affected by timeBeginPeriod on Win32.
		QueryPerformanceCounter is a little overkill for the amount of precision that
		I consider acceptable. If someone submits a patch that replaces this code
		with QueryPerformanceCounter, I wouldn't complain. Until then, timeGetTime
		gets the results I'm after. -EMS

		See: http://www.geisswerks.com/ryan/FAQS/timing.html
		And: http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323&
		*/
		return timeGetTime();
#else
		return ( unsigned long )(( float )( clock() ) / (( float )CLOCKS_PER_SEC / 1000.0 ) );
#endif
	}

} // namespace MyGUI
<commit_msg>little fix in Timer for code blocks<commit_after>/*!
	@file
	@author		Albert Semenov
	@date		04/2009
	@module
*/
/*
	This file is part of MyGUI.

	MyGUI 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 3 of the License, or
	(at your option) any later version.

	MyGUI 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 MyGUI.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_Timer.h"

#if MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32
#	include <windows.h>
#	ifndef __MINGW32__
#		pragma comment(lib, "winmm.lib")
#	else
#		pragma comment(lib, "libwinmm.a")
#	endif
#endif

namespace MyGUI
{

	void Timer::reset()
	{
		mTimeStart = getCurrentMilliseconds();
	}

	unsigned long Timer::getMilliseconds()
	{
		return getCurrentMilliseconds() - mTimeStart;
	}

	unsigned long Timer::getCurrentMilliseconds()
	{
#if MYGUI_PLATFORM == MYGUI_PLATFORM_WIN32
		/*
		We do this because clock() is not affected by timeBeginPeriod on Win32.
		QueryPerformanceCounter is a little overkill for the amount of precision that
		I consider acceptable. If someone submits a patch that replaces this code
		with QueryPerformanceCounter, I wouldn't complain. Until then, timeGetTime
		gets the results I'm after. -EMS

		See: http://www.geisswerks.com/ryan/FAQS/timing.html
		And: http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323&
		*/
		return timeGetTime();
#else
		return ( unsigned long )(( float )( clock() ) / (( float )CLOCKS_PER_SEC / 1000.0 ) );
#endif
	}

} // namespace MyGUI
<|endoftext|>