<commit_before>#include "NLTProjector.h"
#include "ReveManager.h"
#include "NLTBases.h"

#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include <TVirtualPad.h>
#include <TVirtualViewer3D.h>

#include <list>

using namespace Reve;

ClassImp(Reve::NLTProjection)

Float_t NLTProjection::fgEps = 0.005f;

NLTProjection::NLTProjection(Vector& center) :
  fType(PT_Unknown),
  fGeoMode(GM_Unknown),
  fName(0),
  fCenter(center.x, center.y, center.z),
  fDistortion(0.0f),
  fFixedRadius(300),
  fScale(1.0f)
{}

//______________________________________________________________________________
void NLTProjection::ProjectVector(Vector& v)
{
  ProjectPoint(v.x, v.y, v.z);
}

//______________________________________________________________________________
Vector* NLTProjection::Project(Vector* origPnts, Int_t Npnts, Bool_t copy)
{
  Vector* pnts = 0;
  if(copy)
  {
    pnts = new Vector[Npnts];
    memcpy(pnts, origPnts, Npnts*sizeof(Vector));
  }
  else
  {
    pnts =  origPnts;
  }

  for(Int_t i = 0; i<Npnts; i++)
  {
    ProjectPoint(pnts[i].x, pnts[i].y, pnts[i].z);
  }
  return pnts;
}

//______________________________________________________________________________
void NLTProjection::UpdateLimit()
{
  if ( fDistortion == 0.0f )
    return;

  Float_t lim =  1.0f/fDistortion + fFixedRadius;
  Float_t* c = GetProjectedCenter();
  fUpLimit.Set(lim + c[0], lim + c[1], c[2]);
  fLowLimit.Set(-lim + c[0], -lim + c[1], c[2]);
}

//______________________________________________________________________________
void NLTProjection::SetDistortion(Float_t d)
{
  // Prevent scaling down whole projected scene.
  // Point at fixe distance shold be on constant screen coorinate.

  fDistortion=d;
  fScale = 1+fFixedRadius*fDistortion;
  UpdateLimit();
}

//______________________________________________________________________________
void NLTProjection::SetFixedRadius(Float_t r)
{

  fFixedRadius=r;
  fScale = 1+fFixedRadius*fDistortion;
  UpdateLimit();
}

//______________________________________________________________________________
void NLTProjection::SetDirectionalVector(Int_t screenAxis, Vector& vec)
{
  for(Int_t i=0; i<3; i++)
  {
    vec[i] = (i==screenAxis) ? 1. : 0.;
  }
}

//______________________________________________________________________________
Float_t NLTProjection::GetValForScreenPos(Int_t i, Float_t sv)
{
  // move on unprojected axis, find when projected value is geiven screen values(sv)
  static const Exc_t eH("NLTProjector::GetValForScreenPos ");

  Float_t xL, xM, xR;
  Vector V, DirVec;
  SetDirectionalVector(i, DirVec);
  if((sv > 0 && sv > fUpLimit[i]) || (sv < 0 && sv < fLowLimit[i]) )
    throw(eH + Form("screen value '%f' out of limit '%f'.", sv, sv > 0 ? fUpLimit[i] : fLowLimit[i]));

  Vector zero; ProjectVector(zero);
  // printf("NLTProjection::GetValForScreenPos %d sv %f , zero %f\n",i,  sv, zero[i]);
  // search from -/+ infinity according to sign of screen value
  if (sv > zero[i])
  {
    xL = 0; xR = 1000;
    while (1)
    {
      V.Mult(DirVec, xR); ProjectVector(V);
      // printf("positive projected %f, value %f,xL, xR ( %f, %f)\n", V[i], sv, xL, xR);
      if (V[i] > sv || V[i] == sv) break;
      xL = xR; xR *= 2;
    }
  }
  else if (sv < zero[i])
  {
    xR = 0; xL = -1000;
    while (1)
    {
      V.Mult(DirVec, xL); ProjectVector(V);
      // printf("negative projected %f, value %f,xL, xR ( %f, %f)\n", V[i], sv, xL, xR);
      if (V[i] < sv || V[i] == sv) break;
      xR = xL; xL *= 2;
    }
  }
  else
  {
    return 0.0f;
  }

  // printf("start bisection %f %f sv %f\n", xL, xR, sv);
  do
  {
    xM = 0.5f * (xL + xR);
    V.Mult(DirVec, xM);
    ProjectVector(V);
    if (V[i] > sv)
      xR = xM;
    else
      xL = xM;
  } while(TMath::Abs(V[i] - sv) >= fgEps);

  return xM;
}

//______________________________________________________________________________
Float_t NLTProjection::GetScreenVal(Int_t i, Float_t x)
{
  Vector dv;
  SetDirectionalVector(i, dv); dv = dv*x;
  ProjectVector(dv);
  return dv[i];
}

/**************************************************************************/
/**************************************************************************/

ClassImp(Reve::RhoZ)

//______________________________________________________________________________
void RhoZ::SetCenter(Vector& v)
{
  fCenter = v;

  fCenterR = TMath::Sqrt(v.x*v.x+v.y*v.y);
  fProjectedCenter.x = fCenter.z;
  fProjectedCenter.y = TMath::Sign(fCenterR, fCenter.y);
  fProjectedCenter.z = 0;
  UpdateLimit();
}

//______________________________________________________________________________
void RhoZ::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,  PProc_e proc )
{
  using namespace TMath;

  if(proc == PP_Plane || proc == PP_Full)
  {
    // project
    y = Sign((Float_t)Sqrt(x*x+y*y), y);
    x = z;
  }
  if(proc == PP_Distort || proc == PP_Full)
  {
    // move to center
    x -= fProjectedCenter.x;
    y -= fProjectedCenter.y;
    // distort
    y = (y*fScale) / (1.0f + Abs(y)*fDistortion);
    x = (x*fScale) / (1.0f + Abs(x)*fDistortion);
    // move back from center
    x += fProjectedCenter.x;
    y += fProjectedCenter.y;
  }
  z = 0.0f;
}

//______________________________________________________________________________
void RhoZ::SetDirectionalVector(Int_t screenAxis, Vector& vec)
{
  if(screenAxis == 0)
    vec.Set(0., 0., 1);
  else
    vec.Set(0., 1., 0);

}
//______________________________________________________________________________
Bool_t RhoZ::AcceptSegment(Vector& v1, Vector& v2, Float_t tolerance)
{
  Float_t a = fProjectedCenter.y;

  Bool_t val = kTRUE;
  //  printf("accept segment y1:: %f, y2:: %f, center:: %f \n", v1.y ,v2.y, a);
  if((v1.y <  a && v2.y > a) || (v1.y > a && v2.y < a))
  {
    val = kFALSE;
    if (tolerance > 0)
    {
      Float_t a1 = TMath::Abs(v1.y - a), a2 = TMath::Abs(v2.y - a);
      if (a1 < a2)
      {
	if (a1 < tolerance) { v1.y = a; val = kTRUE; }
      }
      else
      {
	if (a2 < tolerance) { v2.y = a; val = kTRUE; }
      }
    }
  }
  // printf("accept segment y1:: %f, y2:: %f, VAL %d \n", v1.y ,v2.y, val);
  return val;
}

/**************************************************************************/
/**************************************************************************/
ClassImp(Reve:: CircularFishEye)
//______________________________________________________________________________
void  CircularFishEye::ProjectPoint(Float_t& x, Float_t& y, Float_t& z, PProc_e proc)
{
  // point look at from external origin
  using namespace TMath;

  if(proc !=  PP_Plane)
  {
    x -= fCenter.x;
    y -= fCenter.y;
    Float_t phi = x == 0.0 && y == 0.0 ? 0.0 : ATan2(y,x);
    Float_t R = Sqrt(x*x+y*y);
    // distort
    Float_t NR = (R*fScale) / (1.0f + R*fDistortion);
    x = NR*Cos(phi) + fCenter.x;
    y = NR*Sin(phi) + fCenter.y;
  }
  z = 0.0f;
}

/**************************************************************************/
/**************************************************************************/
//______________________________________________________________________
// NLTProjector
//

ClassImp(NLTProjector)

NLTProjector::NLTProjector():
  RenderElementList("NLTProjector",""),

  fProjection (0),

  fDrawCenter(kFALSE),
  fDrawOrigin(kFALSE),

  fSplitInfoMode(0),
  fSplitInfoLevel(1),
  fAxisColor(0),

  fCurrentDepth(0)
{
  SetProjection(NLTProjection::PT_CFishEye, 0);
}

//______________________________________________________________________________
NLTProjector::~NLTProjector()
{
  if(fProjection) delete fProjection;
}

//______________________________________________________________________________
void NLTProjector::UpdateName()
{
  SetName(Form ("%s (%3.1f)", fProjection->GetName(), fProjection->GetDistortion()*1000));
  UpdateItems();
}

//______________________________________________________________________________
void NLTProjector::SetProjection(NLTProjection::PType_e type, Float_t distort)
{
  static const Exc_t eH("NLTProjector::SetProjection ");

  delete fProjection;
  fProjection = 0;

  switch (type)
  {
    case NLTProjection::PT_CFishEye:
    {
      fProjection  = new CircularFishEye(fCenter);
      break;
    }
    case NLTProjection::PT_RhoZ:
    {
      fProjection  = new RhoZ(fCenter);
      break;
    }
    default:
      throw(eH + "projection type not valid.");
      break;
  }
  fProjection->SetDistortion(distort);
  UpdateName();
}

//______________________________________________________________________________
void NLTProjector::SetProjection(NLTProjection* p)
{
  delete fProjection;
  fProjection = p;
  UpdateName();
}

//______________________________________________________________________________
void NLTProjector::SetCenter(Float_t x, Float_t y, Float_t z)
{
  fCenter.Set(x, y, z);

  // update projection
  fProjection->SetCenter(fCenter);

  // rebuild the scene
  ProjectChildren();
}

//______________________________________________________________________________
Bool_t NLTProjector::HandleElementPaste(RenderElement* el)
{
  size_t n_children  = fChildren.size();
  ImportElements(el);
  return n_children != fChildren.size();
}

//______________________________________________________________________________
Bool_t NLTProjector::ShouldImport(RenderElement* rnr_el)
{
  if (rnr_el->IsA()->InheritsFrom(NLTProjectable::Class()))
    return kTRUE;
  for (List_i i=rnr_el->BeginChildren(); i!=rnr_el->EndChildren(); ++i)
    if (ShouldImport(*i))
      return kTRUE;
  return kFALSE;
}

//______________________________________________________________________________
void NLTProjector::ImportElementsRecurse(RenderElement* rnr_el, RenderElement* parent)
{
  if (ShouldImport(rnr_el))
  {
    RenderElement  *new_re = 0;
    NLTProjected   *new_pr = 0;
    NLTProjectable *pble   = dynamic_cast<NLTProjectable*>(rnr_el);
    if (pble)
    {
      new_re = (RenderElement*) pble->ProjectedClass()->New();
      new_pr = dynamic_cast<NLTProjected*>(new_re);
      new_pr->SetProjection(this, pble);
      new_pr->SetDepth(fCurrentDepth);
    }
    else
    {
      new_re = new RenderElementList;
    }
    TObject *tobj   = rnr_el->GetObject();
    new_re->SetRnrElNameTitle(Form("NLT %s", tobj->GetName()),
			      tobj->GetTitle());
    new_re->SetRnrSelf     (rnr_el->GetRnrSelf());
    new_re->SetRnrChildren(rnr_el->GetRnrChildren());
    gReve->AddRenderElement(new_re, parent);

    for (List_i i=rnr_el->BeginChildren(); i!=rnr_el->EndChildren(); ++i)
      ImportElementsRecurse(*i, new_re);
  }

}

//______________________________________________________________________________
void NLTProjector::ImportElements(RenderElement* rnr_el)
{
  ImportElementsRecurse(rnr_el, this);
  ProjectChildren();
}

//______________________________________________________________________________
void NLTProjector::ProjectChildrenRecurse(RenderElement* rnr_el)
{
  NLTProjected* pted = dynamic_cast<NLTProjected*>(rnr_el);
  if (pted)
  {
    pted->UpdateProjection();
    TAttBBox* bb = dynamic_cast<TAttBBox*>(pted);
    if(bb)
    {
      Float_t* b = bb->AssertBBox();
      BBoxCheckPoint(b[0], b[2], b[4]);
      BBoxCheckPoint(b[1], b[3], b[5]);
    }
    rnr_el->ElementChanged(kFALSE);
  }

  for (List_i i=rnr_el->BeginChildren(); i!=rnr_el->EndChildren(); ++i)
    ProjectChildrenRecurse(*i);
}

//______________________________________________________________________________
void NLTProjector::ProjectChildren()
{
  BBoxZero();
  ProjectChildrenRecurse(this);
  AssertBBoxExtents(0.1);
  {
    using namespace TMath;
    fBBox[0] = 10.0f * Floor(fBBox[0]/10.0f);
    fBBox[1] = 10.0f * Ceil (fBBox[1]/10.0f);
    fBBox[2] = 10.0f * Floor(fBBox[2]/10.0f);
    fBBox[3] = 10.0f * Ceil (fBBox[3]/10.0f);
  }

  List_t scenes;
  CollectSceneParentsFromChildren(scenes, 0);
  gReve->ScenesChanged(scenes);
}

//______________________________________________________________________________
void NLTProjector::Paint(Option_t* /*option*/)
{
  static const Exc_t eH("NLTProjector::Paint ");
  TBuffer3D buff(TBuffer3DTypes::kGeneric);

  // Section kCore
  buff.fID           = this;
  buff.fColor        = fAxisColor;
  buff.fTransparency = 0;
  buff.SetSectionsValid(TBuffer3D::kCore);

  Int_t reqSections = gPad->GetViewer3D()->AddObject(buff);
  if (reqSections != TBuffer3D::kNone)
    Error(eH, "only direct GL rendering supported.");
}

//______________________________________________________________________________
void NLTProjector::ComputeBBox()
{
  // Fill bounding-box information in base-class TAttBBox (virtual method).

  static const Exc_t eH("NLTProjector::ComputeBBox ");

  if(GetNChildren() == 0) {
    BBoxZero();
    return;
  }

  BBoxInit();
}

<commit_msg>Bugfix: in GetValForScreenPos() check if distortion exist before checking the limit.<commit_after>#include "NLTProjector.h"
#include "ReveManager.h"
#include "NLTBases.h"

#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include <TVirtualPad.h>
#include <TVirtualViewer3D.h>

#include <list>

using namespace Reve;

ClassImp(Reve::NLTProjection)

Float_t NLTProjection::fgEps = 0.005f;

NLTProjection::NLTProjection(Vector& center) :
  fType(PT_Unknown),
  fGeoMode(GM_Unknown),
  fName(0),
  fCenter(center.x, center.y, center.z),
  fDistortion(0.0f),
  fFixedRadius(300),
  fScale(1.0f)
{}

//______________________________________________________________________________
void NLTProjection::ProjectVector(Vector& v)
{
  ProjectPoint(v.x, v.y, v.z);
}

//______________________________________________________________________________
Vector* NLTProjection::Project(Vector* origPnts, Int_t Npnts, Bool_t copy)
{
  Vector* pnts = 0;
  if(copy)
  {
    pnts = new Vector[Npnts];
    memcpy(pnts, origPnts, Npnts*sizeof(Vector));
  }
  else
  {
    pnts =  origPnts;
  }

  for(Int_t i = 0; i<Npnts; i++)
  {
    ProjectPoint(pnts[i].x, pnts[i].y, pnts[i].z);
  }
  return pnts;
}

//______________________________________________________________________________
void NLTProjection::UpdateLimit()
{
  if ( fDistortion == 0.0f )
    return;

  Float_t lim =  1.0f/fDistortion + fFixedRadius;
  Float_t* c = GetProjectedCenter();
  fUpLimit.Set(lim + c[0], lim + c[1], c[2]);
  fLowLimit.Set(-lim + c[0], -lim + c[1], c[2]);
}

//______________________________________________________________________________
void NLTProjection::SetDistortion(Float_t d)
{
  // Prevent scaling down whole projected scene.
  // Point at fixe distance shold be on constant screen coorinate.

  fDistortion=d;
  fScale = 1+fFixedRadius*fDistortion;
  UpdateLimit();
}

//______________________________________________________________________________
void NLTProjection::SetFixedRadius(Float_t r)
{

  fFixedRadius=r;
  fScale = 1+fFixedRadius*fDistortion;
  UpdateLimit();
}

//______________________________________________________________________________
void NLTProjection::SetDirectionalVector(Int_t screenAxis, Vector& vec)
{
  for (Int_t i=0; i<3; i++)
  {
    vec[i] = (i==screenAxis) ? 1. : 0.;
  }
}

//______________________________________________________________________________
Float_t NLTProjection::GetValForScreenPos(Int_t i, Float_t sv)
{
  // move on unprojected axis, find when projected value is geiven screen values(sv)
  static const Exc_t eH("NLTProjector::GetValForScreenPos ");

  Float_t xL, xM, xR;
  Vector V, DirVec;
  SetDirectionalVector(i, DirVec);
  if (fDistortion > 0.0f && ((sv > 0 && sv > fUpLimit[i]) || (sv < 0 && sv < fLowLimit[i])))
    throw(eH + Form("screen value '%f' out of limit '%f'.", sv, sv > 0 ? fUpLimit[i] : fLowLimit[i]));

  Vector zero; ProjectVector(zero);
  // printf("NLTProjection::GetValForScreenPos %d sv %f , zero %f\n",i,  sv, zero[i]);
  // search from -/+ infinity according to sign of screen value
  if (sv > zero[i])
  {
    xL = 0; xR = 1000;
    while (1)
    {
      V.Mult(DirVec, xR); ProjectVector(V);
      // printf("positive projected %f, value %f,xL, xR ( %f, %f)\n", V[i], sv, xL, xR);
      if (V[i] > sv || V[i] == sv) break;
      xL = xR; xR *= 2;
    }
  }
  else if (sv < zero[i])
  {
    xR = 0; xL = -1000;
    while (1)
    {
      V.Mult(DirVec, xL); ProjectVector(V);
      // printf("negative projected %f, value %f,xL, xR ( %f, %f)\n", V[i], sv, xL, xR);
      if (V[i] < sv || V[i] == sv) break;
      xR = xL; xL *= 2;
    }
  }
  else
  {
    return 0.0f;
  }

  // printf("start bisection %f %f sv %f\n", xL, xR, sv);
  do
  {
    xM = 0.5f * (xL + xR);
    V.Mult(DirVec, xM);
    ProjectVector(V);
    if (V[i] > sv)
      xR = xM;
    else
      xL = xM;
  } while(TMath::Abs(V[i] - sv) >= fgEps);

  return xM;
}

//______________________________________________________________________________
Float_t NLTProjection::GetScreenVal(Int_t i, Float_t x)
{
  Vector dv;
  SetDirectionalVector(i, dv); dv = dv*x;
  ProjectVector(dv);
  return dv[i];
}

/**************************************************************************/
/**************************************************************************/

ClassImp(Reve::RhoZ)

//______________________________________________________________________________
void RhoZ::SetCenter(Vector& v)
{
  fCenter = v;

  fCenterR = TMath::Sqrt(v.x*v.x+v.y*v.y);
  fProjectedCenter.x = fCenter.z;
  fProjectedCenter.y = TMath::Sign(fCenterR, fCenter.y);
  fProjectedCenter.z = 0;
  UpdateLimit();
}

//______________________________________________________________________________
void RhoZ::ProjectPoint(Float_t& x, Float_t& y, Float_t& z,  PProc_e proc )
{
  using namespace TMath;

  if(proc == PP_Plane || proc == PP_Full)
  {
    // project
    y = Sign((Float_t)Sqrt(x*x+y*y), y);
    x = z;
  }
  if(proc == PP_Distort || proc == PP_Full)
  {
    // move to center
    x -= fProjectedCenter.x;
    y -= fProjectedCenter.y;
    // distort
    y = (y*fScale) / (1.0f + Abs(y)*fDistortion);
    x = (x*fScale) / (1.0f + Abs(x)*fDistortion);
    // move back from center
    x += fProjectedCenter.x;
    y += fProjectedCenter.y;
  }
  z = 0.0f;
}

//______________________________________________________________________________
void RhoZ::SetDirectionalVector(Int_t screenAxis, Vector& vec)
{
  if(screenAxis == 0)
    vec.Set(0., 0., 1);
  else
    vec.Set(0., 1., 0);

}
//______________________________________________________________________________
Bool_t RhoZ::AcceptSegment(Vector& v1, Vector& v2, Float_t tolerance)
{
  Float_t a = fProjectedCenter.y;

  Bool_t val = kTRUE;
  //  printf("accept segment y1:: %f, y2:: %f, center:: %f \n", v1.y ,v2.y, a);
  if((v1.y <  a && v2.y > a) || (v1.y > a && v2.y < a))
  {
    val = kFALSE;
    if (tolerance > 0)
    {
      Float_t a1 = TMath::Abs(v1.y - a), a2 = TMath::Abs(v2.y - a);
      if (a1 < a2)
      {
	if (a1 < tolerance) { v1.y = a; val = kTRUE; }
      }
      else
      {
	if (a2 < tolerance) { v2.y = a; val = kTRUE; }
      }
    }
  }
  // printf("accept segment y1:: %f, y2:: %f, VAL %d \n", v1.y ,v2.y, val);
  return val;
}

/**************************************************************************/
/**************************************************************************/
ClassImp(Reve:: CircularFishEye)
//______________________________________________________________________________
void  CircularFishEye::ProjectPoint(Float_t& x, Float_t& y, Float_t& z, PProc_e proc)
{
  // point look at from external origin
  using namespace TMath;

  if(proc !=  PP_Plane)
  {
    x -= fCenter.x;
    y -= fCenter.y;
    Float_t phi = x == 0.0 && y == 0.0 ? 0.0 : ATan2(y,x);
    Float_t R = Sqrt(x*x+y*y);
    // distort
    Float_t NR = (R*fScale) / (1.0f + R*fDistortion);
    x = NR*Cos(phi) + fCenter.x;
    y = NR*Sin(phi) + fCenter.y;
  }
  z = 0.0f;
}

/**************************************************************************/
/**************************************************************************/
//______________________________________________________________________
// NLTProjector
//

ClassImp(NLTProjector)

NLTProjector::NLTProjector():
  RenderElementList("NLTProjector",""),

  fProjection (0),

  fDrawCenter(kFALSE),
  fDrawOrigin(kFALSE),

  fSplitInfoMode(0),
  fSplitInfoLevel(1),
  fAxisColor(0),

  fCurrentDepth(0)
{
  SetProjection(NLTProjection::PT_CFishEye, 0);
}

//______________________________________________________________________________
NLTProjector::~NLTProjector()
{
  if(fProjection) delete fProjection;
}

//______________________________________________________________________________
void NLTProjector::UpdateName()
{
  SetName(Form ("%s (%3.1f)", fProjection->GetName(), fProjection->GetDistortion()*1000));
  UpdateItems();
}

//______________________________________________________________________________
void NLTProjector::SetProjection(NLTProjection::PType_e type, Float_t distort)
{
  static const Exc_t eH("NLTProjector::SetProjection ");

  delete fProjection;
  fProjection = 0;

  switch (type)
  {
    case NLTProjection::PT_CFishEye:
    {
      fProjection  = new CircularFishEye(fCenter);
      break;
    }
    case NLTProjection::PT_RhoZ:
    {
      fProjection  = new RhoZ(fCenter);
      break;
    }
    default:
      throw(eH + "projection type not valid.");
      break;
  }
  fProjection->SetDistortion(distort);
  UpdateName();
}

//______________________________________________________________________________
void NLTProjector::SetProjection(NLTProjection* p)
{
  delete fProjection;
  fProjection = p;
  UpdateName();
}

//______________________________________________________________________________
void NLTProjector::SetCenter(Float_t x, Float_t y, Float_t z)
{
  fCenter.Set(x, y, z);

  // update projection
  fProjection->SetCenter(fCenter);

  // rebuild the scene
  ProjectChildren();
}

//______________________________________________________________________________
Bool_t NLTProjector::HandleElementPaste(RenderElement* el)
{
  size_t n_children  = fChildren.size();
  ImportElements(el);
  return n_children != fChildren.size();
}

//______________________________________________________________________________
Bool_t NLTProjector::ShouldImport(RenderElement* rnr_el)
{
  if (rnr_el->IsA()->InheritsFrom(NLTProjectable::Class()))
    return kTRUE;
  for (List_i i=rnr_el->BeginChildren(); i!=rnr_el->EndChildren(); ++i)
    if (ShouldImport(*i))
      return kTRUE;
  return kFALSE;
}

//______________________________________________________________________________
void NLTProjector::ImportElementsRecurse(RenderElement* rnr_el, RenderElement* parent)
{
  if (ShouldImport(rnr_el))
  {
    RenderElement  *new_re = 0;
    NLTProjected   *new_pr = 0;
    NLTProjectable *pble   = dynamic_cast<NLTProjectable*>(rnr_el);
    if (pble)
    {
      new_re = (RenderElement*) pble->ProjectedClass()->New();
      new_pr = dynamic_cast<NLTProjected*>(new_re);
      new_pr->SetProjection(this, pble);
      new_pr->SetDepth(fCurrentDepth);
    }
    else
    {
      new_re = new RenderElementList;
    }
    TObject *tobj   = rnr_el->GetObject();
    new_re->SetRnrElNameTitle(Form("NLT %s", tobj->GetName()),
			      tobj->GetTitle());
    new_re->SetRnrSelf     (rnr_el->GetRnrSelf());
    new_re->SetRnrChildren(rnr_el->GetRnrChildren());
    gReve->AddRenderElement(new_re, parent);

    for (List_i i=rnr_el->BeginChildren(); i!=rnr_el->EndChildren(); ++i)
      ImportElementsRecurse(*i, new_re);
  }

}

//______________________________________________________________________________
void NLTProjector::ImportElements(RenderElement* rnr_el)
{
  ImportElementsRecurse(rnr_el, this);
  ProjectChildren();
}

//______________________________________________________________________________
void NLTProjector::ProjectChildrenRecurse(RenderElement* rnr_el)
{
  NLTProjected* pted = dynamic_cast<NLTProjected*>(rnr_el);
  if (pted)
  {
    pted->UpdateProjection();
    TAttBBox* bb = dynamic_cast<TAttBBox*>(pted);
    if(bb)
    {
      Float_t* b = bb->AssertBBox();
      BBoxCheckPoint(b[0], b[2], b[4]);
      BBoxCheckPoint(b[1], b[3], b[5]);
    }
    rnr_el->ElementChanged(kFALSE);
  }

  for (List_i i=rnr_el->BeginChildren(); i!=rnr_el->EndChildren(); ++i)
    ProjectChildrenRecurse(*i);
}

//______________________________________________________________________________
void NLTProjector::ProjectChildren()
{
  BBoxZero();
  ProjectChildrenRecurse(this);
  AssertBBoxExtents(0.1);
  {
    using namespace TMath;
    fBBox[0] = 10.0f * Floor(fBBox[0]/10.0f);
    fBBox[1] = 10.0f * Ceil (fBBox[1]/10.0f);
    fBBox[2] = 10.0f * Floor(fBBox[2]/10.0f);
    fBBox[3] = 10.0f * Ceil (fBBox[3]/10.0f);
  }

  List_t scenes;
  CollectSceneParentsFromChildren(scenes, 0);
  gReve->ScenesChanged(scenes);
}

//______________________________________________________________________________
void NLTProjector::Paint(Option_t* /*option*/)
{
  static const Exc_t eH("NLTProjector::Paint ");
  TBuffer3D buff(TBuffer3DTypes::kGeneric);

  // Section kCore
  buff.fID           = this;
  buff.fColor        = fAxisColor;
  buff.fTransparency = 0;
  buff.SetSectionsValid(TBuffer3D::kCore);

  Int_t reqSections = gPad->GetViewer3D()->AddObject(buff);
  if (reqSections != TBuffer3D::kNone)
    Error(eH, "only direct GL rendering supported.");
}

//______________________________________________________________________________
void NLTProjector::ComputeBBox()
{
  // Fill bounding-box information in base-class TAttBBox (virtual method).

  static const Exc_t eH("NLTProjector::ComputeBBox ");

  if(GetNChildren() == 0) {
    BBoxZero();
    return;
  }

  BBoxInit();
}

<|endoftext|>


<commit_before>// CommonFunc.cpp -- source file
/*
 *
 * Author: septimomend (Ivan Chapkailo)
 *
 * 02.07.2017
 *
 */

#include "stdafx.h"
#include "CommonFunc.h"

Common::Common(AllControllers* all) : m_pCnfg(all->getConfigObj())
{
}

void Common::setChar(int ch)
{
  if (m_pCnfg->configY == m_pCnfg->rowCount)  // if this is last line
  {
    setRow(m_pCnfg->rowCount, "", 0);         // set new row with zero position and empty
  }
  setRowChar(&m_pCnfg->pRowObj[m_pCnfg->configY], m_pCnfg->configX, ch); // set char to last position in last row
  m_pCnfg->configX++;                         // and increment row lenght for cursor
}
void Common::setNewline()
{
  // TODO
}

void Common::deleteChar()
{
  // TODO
}

void Common::save()
{
  // TODO
}

void Common::find()
{
  // TODO
}

void Common::drawRows(Adbfr* abfr);
{
  // TODO
}

void Common::drawStatusBar(Adbfr* abfr)
{
  // TODO
}

void Common::drawMessageBar(Adbfr* abfr)
{
  // TODO
}

void Common::scrolling()
{
  // TODO
}

void Common::statusMsg(const char *fmt, ...)
{
  va_list arg;         // for unknown number of parameters
  va_start(arg, fmt);  // initialize arg
  vsnprintf(cnfg.statusMessage, sizeof(cnfg.statusMessage), fmt, arg); // output parameters to statusMessage
  va_end(arg); // end
  cnfg.statusMessageTime = time(NULL); // gets time
}

void Common::updateScreen()
{
  scrolling();

  m_abfr = ADBFR_IMPL; // implement to NULL

  m_abfr.reallocateBfr("\x1b[?25l", 6); // reallocate data
  m_abfr.reallocateBfr("\x1b[H", 3);    // reallocate data

  /*
   * draw rows, message bar and status bar
   */
  drawRows(&m_abfr);
  drawStatusBar(&m_abfr);
  drawMessageBar(&m_abfr);

  /*
   * write to buff cursor | position
   */
  char buff[32];
  snprintf(buff, sizeof(buff), "\x1b[%d;%dH", (m_pCnfg->configY - m_pCnfg->disableRow) + 1, (m_pCnfg->rowX - m_pCnfg->disableClr) + 1);
  m_abfr.reallocateBfr(buff, strlen(buff));

  m_abfr.reallocateBfr("\x1b[?25h", 6);

  /*
   * update screen
   */
  write(STDOUT_FILENO, ab.b, ab.len);
  m_abfr.freeBfr(); // free memory
}

char* Common::callPrompt(char *prompt, void (*callback)(char*, int))
{
  size_t buffsize = 128;
  char* bfr = malloc(buffsize); // allocate memory

  size_t bufflen = 0;           // lenght
  bfr[0] = '\0';

  while (1)
  {
    statusMsg(prompt, bfr); // set prompt
    updateScreen();         // and update screen

    int key = tml.whatKey();  // read key

    if (key == DELETE_KEY || key == CTRL_KEY('h') || key == BACKSPACE)
    {
      if (bufflen != 0)         // if buffer is not empty
        bfr[--bufflen] = '\0';  // set end of row
    }
    else if (key == '\x1b')     // if this is ESC
    {
      statusMsg("");          // erase
      if (callback)           // if callback is not NULL
        callback(bfr, key);   // call func for callback which pointed by callback()
      free(bfr);              // free memory
      return NULL;            // and cancel
    }
    else if (key == '\r')     // if carriage return (move the cursor at the start of the line)
    {
      if (bufflen != 0)       // and bufflen is not empty
      {
        statusMsg("");        // clean message
        if (callback)
          callback(bfr, key); // and get callback
        return bfr;           // returning of buffer
      }
    }
    else if (!iscntrl(key) && key < 128) // checks, whether the argument, transmitted via the parameter сharacter, control character
    {
      /*
       * reallocation of buffer if needs
       */
      if (bufflen == buffsize - 1)
      {
        buffsize *= 2;
        bfr = realloc(bfr, buffsize);
      }
      bfr[bufflen++] = key; // write this key to buffer
      bfr[bufflen] = '\0';  // and end of row
    }

    if (callback)
      callback(bfr, key);   // call of callback
  }
}

void Common::moveCursor(int key)
{
  // instancing RowController
  // if empty - to zero position, else to the end of row
  //
  RowController* pRowctrl = (m_pCnfg->configY >= m_pCnfg->rowCount) ? NULL : &m_pCnfg->pRowObj[m_pCnfg->configY];

  switch (key)
  {
    case ARROW_LEFT:
      if (m_pCnfg->configX != 0)                                    // if horizontal position isn't zero
      {
        m_pCnfg->configX--;                                         // move left
      }
      else if (m_pCnfg->configY > 0)                                // else if there is at least 1 row
      {
        m_pCnfg->configY--;                                         // move to that row
        m_pCnfg->configX = m_pCnfg->pRowObj[m_pCnfg->configY].size; // and to the end of that row
      }
      break;
    case ARROW_RIGHT:
      if (pRowctrl && m_pCnfg->configX < pRowctrl->size)            // if there is row and if cursor is not in the end of row
      {
        m_pCnfg->configX++;                                         // move cursor right along of row
      }
      else if (pRowctrl && m_pCnfg->configX == pRowctrl->size)      // if there is row and cursor in the end of this row
      {
        m_pCnfg->configY++;                                         // move to next row
        E.cx = 0;                                                   // on zero position
      }
      break;
    case ARROW_UP:
      if (m_pCnfg->configY != 0)                                    // if there is at least 1 row
      {
        m_pCnfg->configY--;                                         // move up
      }
      break;
    case ARROW_DOWN:
      if (m_pCnfg->configY < m_pCnfg->rowCount)                     // if cursor is not on last row
      {
        m_pCnfg->configY++;                                         // move down
      }
      break;
  }
}

void Common::processingKeypress()
{
  static int sQuitCounter = EDITORRMEND_QUIT_COUNTER;                // counter clicking for exit

  int key = whatKey();                                               // read key

  switch (key)
  {
    case '\r':                                                       // if carriage return (Enter key)
      setNewline();                                                   // set newline
      break;

    case CTRL_KEY('q'):
      if (m_pCnfg->smear && sQuitCounter > 0)                        // if there is any changes and counter > 0
      {
        statusMsg("! File was changed and unsaved and data can be lost after exiting. "
                  "Press Ctrl-Q %d more times to exit.", sQuitCounter);
        sQuitCounter--;                                              // counter decrement
        return;
      }
      write(STDOUT_FILENO, "\x1b[2J", 4);
      write(STDOUT_FILENO, "\x1b[H", 3);
      exit(0);
      break;

    case CTRL_KEY('s'):
      save();                                                       // TODO: save changes
      break;

    case HOME_KEY:
    m_pCnfg->configX = 0;                                           // to the row beginning
      break;

    case END_KEY:
      if (m_pCnfg->configY < m_pCnfg->rowCount)                     // if not last row
        m_pCnfg->configX = m_pCnfg->pRowObj[m_pCnfg->configY].size; // to the end of row
      break;

    case CTRL_KEY('f'):
      find();                                                       // find func
      break;

    case BACKSPACE:
    case CTRL_KEY('h'):
    case DELETE_KEY:
      if (key == DELETE_KEY)
        moveCursor(ARROW_RIGHT);                                    // move cursor right
      deleteChar();                                                 // delete char
      break;

    // page up/down
    //
    case PAGE_UP:
    case PAGE_DOWN:
      {
        if (key == PAGE_UP)
        {
          m_pCnfg->configY = m_pCnfg->disableRow;                    // move page up
        }
        else if (key == PAGE_DOWN)
        {
          m_pCnfg->configY = m_pCnfg->disableRow + m_pCnfg->enableRow - 1; // move page down
          if (m_pCnfg->configY > m_pCnfg->rowCount)
            m_pCnfg->configY = m_pCnfg->rowCount;
        }

        int times = m_pCnfg->enableRow;
        while (times--)
          moveCursor(key == PAGE_UP ? ARROW_UP : ARROW_DOWN);
      }
      break;

    case ARROW_UP:
    case ARROW_DOWN:
    case ARROW_LEFT:
    case ARROW_RIGHT:
      moveCursor(key);
      break;

    case CTRL_KEY('l'):
    case '\x1b':
      break;

    default:
      setChar(key);   // just write chars
      break;
  }

  sQuitCounter = EDITORRMEND_QUIT_COUNTER;
}
<commit_msg>defined setRow() func<commit_after>// CommonFunc.cpp -- source file
/*
 *
 * Author: septimomend (Ivan Chapkailo)
 *
 * 02.07.2017
 *
 */

#include "stdafx.h"
#include "CommonFunc.h"

Common::Common(AllControllers* all) : m_pCnfg(all->getConfigObj())
{
}

void Common::setRow(int num, char *str, size_t sz)
{
  if (num < 0 || num > m_pCnfg->rowCount)  // if number is out of row numbers range
    return;                                // error

  // reallocation of memory
  // сhange the size of the rows to add a new row
  //
  m_pCnfg->pRowObj = realloc(m_pCnfg->pRowObj, sizeof(RowController) * (m_pCnfg->rowCount + 1));

  // copy size bytes of rows to the same object incremented by 1
  //
  memmove(&m_pCnfg->pRowObj[num + 1], &m_pCnfg->pRowObj[num], sizeof(RowController) * (m_pCnfg->rowCount - num));

  for (int i = num + 1; i <= m_pCnfg->rowCount; i++)
    m_pCnfg->pRowObj[i].index++;           // increase index

  m_pCnfg->pRowObj[num].index = num;       // set index
  m_pCnfg->pRowObj[num].size = sz;         // set size
  m_pCnfg->pRowObj[num].pLetter = malloc(sz + 1); // allocate memory for sz+1 bytes
  memcpy(m_pCnfg->pRowObj[num].pLetter, str, sz); // copy size bytes of string to pLetter (example: str is "s" - copy s to pLetter)
  m_pCnfg->pRowObj[num].pLetter[sz] = '\0';       // set EOF of row

  m_pCnfg->pRowObj[num].sizeRow = 0;              // zero size of row
  m_pCnfg->pRowObj[num].pVisualize = NULL;        // no visualize
  m_pCnfg->pRowObj[num].pClr = NULL;              // no colour
  m_pCnfg->pRowObj[num].commentClr = 0;           // no comment colour

  updateRow(&m_pCnfg->pRowObj[num]);

  m_pCnfg->rowCount++;                            // add 1 to rows number
  m_pCnfg->smear++;                               // new changes
}

void Common::setRowChar(RowController *row, int to, int ch)
{

}

void Common::setChar(int ch)
{
  if (m_pCnfg->configY == m_pCnfg->rowCount)  // if this is last line
  {
    setRow(m_pCnfg->rowCount, "", 0);         // set new row with zero position and empty
  }
  setRowChar(&m_pCnfg->pRowObj[m_pCnfg->configY], m_pCnfg->configX, ch); // set char to last position in last row
  m_pCnfg->configX++;                         // and increment row lenght for cursor
}
void Common::setNewline()
{
  // TODO
}

void Common::deleteChar()
{
  // TODO
}

void Common::save()
{
  // TODO
}

void Common::find()
{
  // TODO
}

void Common::drawRows(Adbfr* abfr);
{
  // TODO
}

void Common::drawStatusBar(Adbfr* abfr)
{
  // TODO
}

void Common::drawMessageBar(Adbfr* abfr)
{
  // TODO
}

void Common::scrolling()
{
  // TODO
}

void Common::statusMsg(const char *fmt, ...)
{
  va_list arg;         // for unknown number of parameters
  va_start(arg, fmt);  // initialize arg
  vsnprintf(cnfg.statusMessage, sizeof(cnfg.statusMessage), fmt, arg); // output parameters to statusMessage
  va_end(arg); // end
  cnfg.statusMessageTime = time(NULL); // gets time
}

void Common::updateScreen()
{
  scrolling();

  m_abfr = ADBFR_IMPL; // implement to NULL

  m_abfr.reallocateBfr("\x1b[?25l", 6); // reallocate data
  m_abfr.reallocateBfr("\x1b[H", 3);    // reallocate data

  /*
   * draw rows, message bar and status bar
   */
  drawRows(&m_abfr);
  drawStatusBar(&m_abfr);
  drawMessageBar(&m_abfr);

  /*
   * write to buff cursor | position
   */
  char buff[32];
  snprintf(buff, sizeof(buff), "\x1b[%d;%dH", (m_pCnfg->configY - m_pCnfg->disableRow) + 1, (m_pCnfg->rowX - m_pCnfg->disableClr) + 1);
  m_abfr.reallocateBfr(buff, strlen(buff));

  m_abfr.reallocateBfr("\x1b[?25h", 6);

  /*
   * update screen
   */
  write(STDOUT_FILENO, ab.b, ab.len);
  m_abfr.freeBfr(); // free memory
}

char* Common::callPrompt(char *prompt, void (*callback)(char*, int))
{
  size_t buffsize = 128;
  char* bfr = malloc(buffsize); // allocate memory

  size_t bufflen = 0;           // lenght
  bfr[0] = '\0';

  while (1)
  {
    statusMsg(prompt, bfr); // set prompt
    updateScreen();         // and update screen

    int key = tml.whatKey();  // read key

    if (key == DELETE_KEY || key == CTRL_KEY('h') || key == BACKSPACE)
    {
      if (bufflen != 0)         // if buffer is not empty
        bfr[--bufflen] = '\0';  // set end of row
    }
    else if (key == '\x1b')     // if this is ESC
    {
      statusMsg("");          // erase
      if (callback)           // if callback is not NULL
        callback(bfr, key);   // call func for callback which pointed by callback()
      free(bfr);              // free memory
      return NULL;            // and cancel
    }
    else if (key == '\r')     // if carriage return (move the cursor at the start of the line)
    {
      if (bufflen != 0)       // and bufflen is not empty
      {
        statusMsg("");        // clean message
        if (callback)
          callback(bfr, key); // and get callback
        return bfr;           // returning of buffer
      }
    }
    else if (!iscntrl(key) && key < 128) // checks, whether the argument, transmitted via the parameter сharacter, control character
    {
      /*
       * reallocation of buffer if needs
       */
      if (bufflen == buffsize - 1)
      {
        buffsize *= 2;
        bfr = realloc(bfr, buffsize);
      }
      bfr[bufflen++] = key; // write this key to buffer
      bfr[bufflen] = '\0';  // and end of row
    }

    if (callback)
      callback(bfr, key);   // call of callback
  }
}

void Common::moveCursor(int key)
{
  // instancing RowController
  // if empty - to zero position, else to the end of row
  //
  RowController* pRowctrl = (m_pCnfg->configY >= m_pCnfg->rowCount) ? NULL : &m_pCnfg->pRowObj[m_pCnfg->configY];

  switch (key)
  {
    case ARROW_LEFT:
      if (m_pCnfg->configX != 0)                                    // if horizontal position isn't zero
      {
        m_pCnfg->configX--;                                         // move left
      }
      else if (m_pCnfg->configY > 0)                                // else if there is at least 1 row
      {
        m_pCnfg->configY--;                                         // move to that row
        m_pCnfg->configX = m_pCnfg->pRowObj[m_pCnfg->configY].size; // and to the end of that row
      }
      break;
    case ARROW_RIGHT:
      if (pRowctrl && m_pCnfg->configX < pRowctrl->size)            // if there is row and if cursor is not in the end of row
      {
        m_pCnfg->configX++;                                         // move cursor right along of row
      }
      else if (pRowctrl && m_pCnfg->configX == pRowctrl->size)      // if there is row and cursor in the end of this row
      {
        m_pCnfg->configY++;                                         // move to next row
        E.cx = 0;                                                   // on zero position
      }
      break;
    case ARROW_UP:
      if (m_pCnfg->configY != 0)                                    // if there is at least 1 row
      {
        m_pCnfg->configY--;                                         // move up
      }
      break;
    case ARROW_DOWN:
      if (m_pCnfg->configY < m_pCnfg->rowCount)                     // if cursor is not on last row
      {
        m_pCnfg->configY++;                                         // move down
      }
      break;
  }
}

void Common::processingKeypress()
{
  static int sQuitCounter = EDITORRMEND_QUIT_COUNTER;                // counter clicking for exit

  int key = whatKey();                                               // read key

  switch (key)
  {
    case '\r':                                                       // if carriage return (Enter key)
      setNewline();                                                   // set newline
      break;

    case CTRL_KEY('q'):
      if (m_pCnfg->smear && sQuitCounter > 0)                        // if there is any changes and counter > 0
      {
        statusMsg("! File was changed and unsaved and data can be lost after exiting. "
                  "Press Ctrl-Q %d more times to exit.", sQuitCounter);
        sQuitCounter--;                                              // counter decrement
        return;
      }
      write(STDOUT_FILENO, "\x1b[2J", 4);
      write(STDOUT_FILENO, "\x1b[H", 3);
      exit(0);
      break;

    case CTRL_KEY('s'):
      save();                                                       // TODO: save changes
      break;

    case HOME_KEY:
    m_pCnfg->configX = 0;                                           // to the row beginning
      break;

    case END_KEY:
      if (m_pCnfg->configY < m_pCnfg->rowCount)                     // if not last row
        m_pCnfg->configX = m_pCnfg->pRowObj[m_pCnfg->configY].size; // to the end of row
      break;

    case CTRL_KEY('f'):
      find();                                                       // find func
      break;

    case BACKSPACE:
    case CTRL_KEY('h'):
    case DELETE_KEY:
      if (key == DELETE_KEY)
        moveCursor(ARROW_RIGHT);                                    // move cursor right
      deleteChar();                                                 // delete char
      break;

    // page up/down
    //
    case PAGE_UP:
    case PAGE_DOWN:
      {
        if (key == PAGE_UP)
        {
          m_pCnfg->configY = m_pCnfg->disableRow;                    // move page up
        }
        else if (key == PAGE_DOWN)
        {
          m_pCnfg->configY = m_pCnfg->disableRow + m_pCnfg->enableRow - 1; // move page down
          if (m_pCnfg->configY > m_pCnfg->rowCount)
            m_pCnfg->configY = m_pCnfg->rowCount;
        }

        int times = m_pCnfg->enableRow;
        while (times--)
          moveCursor(key == PAGE_UP ? ARROW_UP : ARROW_DOWN);
      }
      break;

    case ARROW_UP:
    case ARROW_DOWN:
    case ARROW_LEFT:
    case ARROW_RIGHT:
      moveCursor(key);
      break;

    case CTRL_KEY('l'):
    case '\x1b':
      break;

    default:
      setChar(key);   // just write chars
      break;
  }

  sQuitCounter = EDITORRMEND_QUIT_COUNTER;
}
<|endoftext|>


<commit_before>#include "cnn/shadow-params.h"
#include "cnn/tensor.h"
#include "cnn/aligned-mem-pool.h"
#include "cnn/model.h"

using namespace std;

namespace cnn {

ShadowParameters::ShadowParameters(const Parameters& p) : h(p.values) {
  h.v = (cnn::real*)cnn_mm_malloc(h.d.size() * sizeof(cnn::real), CNN_ALIGN);
  TensorTools::Zero(h);
}

ShadowLookupParameters::ShadowLookupParameters(const LookupParameters& lp) : h(lp.values) {
  for (auto& t : h) {
      t.v = (cnn::real*)cnn_mm_malloc(t.d.size() * sizeof(cnn::real), CNN_ALIGN);
    TensorTools::Zero(t);
  }
}

vector<ShadowParameters> AllocateShadowParameters(const Model& m) {
  vector<ShadowParameters> v;
  v.reserve(m.parameters_list().size());
  for (auto& p : m.parameters_list())
    v.emplace_back(*p);
  return v;
}

vector<ShadowLookupParameters> AllocateShadowLookupParameters(const Model& m) {
  vector<ShadowLookupParameters> v;
  v.reserve(m.lookup_parameters_list().size());
  for (auto& p : m.lookup_parameters_list())
    v.emplace_back(*p);
  return v;
}

} // namespace cnn

<commit_msg>shadow parameters for lookup table is changed to use temp variables in GPU<commit_after>#include "cnn/shadow-params.h"
#include "cnn/tensor.h"
#include "cnn/aligned-mem-pool.h"
#include "cnn/model.h"
#include "cnn/cnn.h"

using namespace std;

namespace cnn {

ShadowParameters::ShadowParameters(const Parameters& p) : h(p.values) {
  h.v = (cnn::real*)cnn_mm_malloc(h.d.size() * sizeof(cnn::real), CNN_ALIGN);
  TensorTools::Zero(h);
}

ShadowLookupParameters::ShadowLookupParameters(const LookupParameters& lp) : h(lp.values) {
#ifdef USE_CPU_FOR_LOOKUP_PARAM
    bool busecpu = true;
#else
    bool busecpu = false;
#endif
    for (auto& t : h) {
      t.v = (cnn::real*)cnn_mm_malloc(t.d.size() * sizeof(cnn::real), CNN_ALIGN, busecpu);
#ifdef USE_CPU_FOR_LOOKUP_PARAM
      t.m_device_id = CPUDEVICE; /// for cpu
#else
      t.m_device_id = device_id;
#endif
      TensorTools::Zero(t);
  }
}

vector<ShadowParameters> AllocateShadowParameters(const Model& m) {
  vector<ShadowParameters> v;
  v.reserve(m.parameters_list().size());
  for (auto& p : m.parameters_list())
    v.emplace_back(*p);
  return v;
}

vector<ShadowLookupParameters> AllocateShadowLookupParameters(const Model& m) {
  vector<ShadowLookupParameters> v;
  v.reserve(m.lookup_parameters_list().size());
  for (auto& p : m.lookup_parameters_list())
    v.emplace_back(*p);
  return v;
}

} // namespace cnn

<|endoftext|>


<commit_before>/* http_header.cc
   Mathieu Stefani, 19 August 2015

   Implementation of common HTTP headers described by the RFC
*/

#include <stdexcept>
#include <iterator>
#include <cstring>
#include <iostream>

#include <pistache/http_header.h>
#include <pistache/common.h>
#include <pistache/http.h>
#include <pistache/stream.h>

using namespace std;

namespace Pistache {
namespace Http {
namespace Header {

const char* encodingString(Encoding encoding) {
    switch (encoding) {
    case Encoding::Gzip:
        return "gzip";
    case Encoding::Compress:
        return "compress";
    case Encoding::Deflate:
        return "deflate";
    case Encoding::Identity:
        return "identity";
    case Encoding::Chunked:
        return "chunked";
    case Encoding::Unknown:
        return "unknown";
    }

    unreachable();
}

void
Header::parse(const std::string& data) {
    parseRaw(data.c_str(), data.size());
}

void
Header::parseRaw(const char *str, size_t len) {
    parse(std::string(str, len));
}

void
Allow::parseRaw(const char* str, size_t len) {
    UNUSED(str)
    UNUSED(len)
}

void
Allow::write(std::ostream& os) const {
    /* This puts an extra ',' at the end :/
    std::copy(std::begin(methods_), std::end(methods_),
              std::ostream_iterator<Http::Method>(os, ", "));
    */

    for (std::vector<Http::Method>::size_type i = 0; i < methods_.size(); ++i) {
        os << methods_[i];
        if (i < methods_.size() - 1) os << ", ";
    }
}

void
Allow::addMethod(Http::Method method) {
    methods_.push_back(method);
}

void
Allow::addMethods(std::initializer_list<Method> methods) {
    std::copy(std::begin(methods), std::end(methods), std::back_inserter(methods_));
}

void
Allow::addMethods(const std::vector<Http::Method>& methods)
{
    std::copy(std::begin(methods), std::end(methods), std::back_inserter(methods_));
}

CacheControl::CacheControl(Http::CacheDirective directive)
{
    directives_.push_back(directive);
}

void
CacheControl::parseRaw(const char* str, size_t len) {
    using Http::CacheDirective;

    struct DirectiveValue {
        const char* const str;
        const size_t size;
        CacheDirective::Directive repr;
    };

#define VALUE(divStr, enumValue) { divStr, sizeof(divStr) - 1, CacheDirective::enumValue }

    static constexpr DirectiveValue TrivialDirectives[] = {
        VALUE("no-cache"        , NoCache        ),
        VALUE("no-store"        , NoStore        ),
        VALUE("no-transform"    , NoTransform    ),
        VALUE("only-if-cached"  , OnlyIfCached   ),
        VALUE("public"          , Public         ),
        VALUE("private"         , Private        ),
        VALUE("must-revalidate" , MustRevalidate ),
        VALUE("proxy-revalidate", ProxyRevalidate)
    };

    static constexpr DirectiveValue TimedDirectives[] = {
        VALUE("max-age"  , MaxAge  ),
        VALUE("max-stale", MaxStale),
        VALUE("min-fresh", MinFresh),
        VALUE("s-maxage" , SMaxAge )
    };

#undef VALUE

    RawStreamBuf<> buf(const_cast<char *>(str), len);
    StreamCursor cursor(&buf);

    do {

        bool found = false;
        // First scan trivial directives
        for (const auto& d: TrivialDirectives) {
            if (match_raw(d.str, d.size, cursor)) {
                directives_.push_back(CacheDirective(d.repr));
                found = true;
                break;
            }
        }

        // Not found, let's try timed directives
        if (!found) {
            for (const auto& d: TimedDirectives) {
                if (match_raw(d.str, d.size, cursor)) {
                    if (!cursor.advance(1)) {
                        throw std::runtime_error("Invalid caching directive, missing delta-seconds");
                    }

                    char *end;
                    const char* beg = cursor.offset();
                    // @Security: if str is not \0 terminated, there might be a situation
                    // where strtol can overflow. Double-check that it's harmless and fix if not
                    int secs = strtol(beg, &end, 10);
                    cursor.advance(end - beg);
                    if (!cursor.eof() && cursor.current() != ',') {
                        throw std::runtime_error("Invalid caching directive, malformated delta-seconds");
                    }
                    directives_.push_back(CacheDirective(d.repr, std::chrono::seconds(secs)));
                    found = true;
                    break;
                }
            }
        }

        if (!cursor.eof()) {
            if (cursor.current() != ',') {
                throw std::runtime_error("Invalid caching directive, expected a comma");
            }

            int c;
            while ((c = cursor.current()) != StreamCursor::Eof && (c == ',' || c == ' '))
                cursor.advance(1);
        }

    } while (!cursor.eof());

}

void
CacheControl::write(std::ostream& os) const {
    using Http::CacheDirective;

    auto directiveString = [](CacheDirective directive) -> const char* {
        switch (directive.directive()) {
            case CacheDirective::NoCache:
                return "no-cache";
            case CacheDirective::NoStore:
                return "no-store";
            case CacheDirective::NoTransform:
                return "no-transform";
            case CacheDirective::OnlyIfCached:
                return "only-if-cached";
            case CacheDirective::Public:
                return "public";
            case CacheDirective::Private:
                return "private";
            case CacheDirective::MustRevalidate:
                return "must-revalidate";
            case CacheDirective::ProxyRevalidate:
                return "proxy-revalidate";
            case CacheDirective::MaxAge:
                return "max-age";
            case CacheDirective::MaxStale:
                return "max-stale";
            case CacheDirective::MinFresh:
                return "min-fresh";
            case CacheDirective::SMaxAge:
                return "s-maxage";
            case CacheDirective::Ext:
                return "";
            default:
                return "";
        }
        return "";
    };

    auto hasDelta = [](CacheDirective directive) {
        switch (directive.directive()) {
            case CacheDirective::MaxAge:
            case CacheDirective::MaxStale:
            case CacheDirective::MinFresh:
            case CacheDirective::SMaxAge:
                return true;
            default:
                return false;
        }
    };

    for (std::vector<CacheDirective>::size_type i = 0; i < directives_.size(); ++i) {
        const auto& d = directives_[i];
        os << directiveString(d);
        if (hasDelta(d)) {
            auto delta = d.delta();
            if (delta.count() > 0) {
                os << "=" << delta.count();
            }
        }

        if (i < directives_.size() - 1) {
            os << ", ";
        }
    }

}

void
CacheControl::addDirective(Http::CacheDirective directive) {
    directives_.push_back(directive);
}

void
CacheControl::addDirectives(const std::vector<Http::CacheDirective>& directives) {
    std::copy(std::begin(directives), std::end(directives), std::back_inserter(directives_));
}

void
Connection::parseRaw(const char* str, size_t len) {
    char *p = const_cast<char *>(str);
    RawStreamBuf<> buf(p, p + len);
    StreamCursor cursor(&buf);

#define STR(str) \
    str, sizeof(str) - 1

    if (match_string(STR("close"), cursor)) {
        control_ = ConnectionControl::Close;
    }
    else if (match_string(STR("keep-alive"), cursor)) {
        control_ = ConnectionControl::KeepAlive;
    }
    else {
        control_ = ConnectionControl::Ext;
    }
}

void
Connection::write(std::ostream& os) const {
    switch (control_) {
    case ConnectionControl::Close:
        os << "Close";
        break;
    case ConnectionControl::KeepAlive:
        os << "Keep-Alive";
        break;
    case ConnectionControl::Ext:
        os << "Ext";
        break;
    }
}

void
ContentLength::parse(const std::string& data) {
    try {
        size_t pos;
        uint64_t val = std::stoi(data, &pos);
        if (pos != 0) {
        }

        value_ = val;
    } catch (const std::invalid_argument& e) {
    }
}

void
ContentLength::write(std::ostream& os) const {
    os << value_;
}

void
Date::parse(const std::string &str) {
    fullDate_ = FullDate::fromString(str);
}

void
Date::write(std::ostream& os) const {
    UNUSED(os)
}

void
Expect::parseRaw(const char* str, size_t len) {
    if (memcmp(str, "100-continue", len)) {
        expectation_ = Expectation::Continue;
    } else {
        expectation_ = Expectation::Ext;
    }
}

void
Expect::write(std::ostream& os) const {
    if (expectation_ == Expectation::Continue) {
        os << "100-continue";
    }
}

Host::Host(const std::string& data)
    : host_()
    , port_(0)
{
    parse(data);
}

void
Host::parse(const std::string& data) {
    unsigned long pos = data.find(']');
    unsigned long s_pos = data.find('[');
    if (pos != std::string::npos && s_pos != std::string::npos) {
        //IPv6 address
        host_ = data.substr(s_pos+1, pos-1);
        pos++;
    } else {
        //IPv4 address
        pos = data.find(':');
        if (pos == std::string::npos) {
            host_ = data;
            port_ = HTTP_STANDARD_PORT;
        }
        host_ = data.substr(0, pos);
        if (host_ == "*") {
            host_ = "0.0.0.0";
        }
    }
    char *end;
    const std::string portPart = data.substr(pos + 1);
    long port;
    if (portPart.empty()) {
        port = HTTP_STANDARD_PORT;
    }
    else {
        port = strtol(portPart.c_str(), &end, 10);
    }
    if (*end != 0 || port < Port::min() || port > Port::max())
        throw std::invalid_argument("Invalid port");
    port_ = static_cast<uint16_t>(port);
}

void
Host::write(std::ostream& os) const {
    os << host_;
    /* @Clarity @Robustness: maybe a found a literal different than zero
       to represent a null port ?
    */
    if (port_ != 0) {
        os << ":" << port_;
    }
}

Location::Location(const std::string& location)
    : location_(location)
{ }

void
Location::parse(const std::string& data) {
    location_ = data;
}

void
Location::write(std::ostream& os) const {
    os << location_;
}

void
UserAgent::parse(const std::string& data) {
    ua_ = data;
}

void
UserAgent::write(std::ostream& os) const {
    os << ua_;
}

void
Accept::parseRaw(const char *str, size_t len) {

    RawStreamBuf<char> buf(const_cast<char *>(str), len);
    StreamCursor cursor(&buf);

    do {
        int c;
        size_t beg = cursor;
        while ((c = cursor.next()) != StreamCursor::Eof && c != ',')
            cursor.advance(1);

        cursor.advance(1);

        const size_t mimeLen = cursor.diff(beg);

        mediaRange_.push_back(Mime::MediaType::fromRaw(cursor.offset(beg), mimeLen));

        if (!cursor.eof()) {
            if (!cursor.advance(1))
                throw std::runtime_error("Ill-formed Accept header");

            if ((c = cursor.next()) == StreamCursor::Eof || c == ',' || c == 0)
                throw std::runtime_error("Ill-formed Accept header");

            while (!cursor.eof() && cursor.current() == ' ')
                cursor.advance(1);
        }

    } while (!cursor.eof());
}

void
Accept::write(std::ostream& os) const {
    UNUSED(os)
}

void
AccessControlAllowOrigin::parse(const std::string& data) {
  uri_ = data;
}

void
AccessControlAllowOrigin::write(std::ostream& os) const {
  os << uri_;
}

void
AccessControlAllowHeaders::parse(const std::string& data) {
  val_ = data;
}

void
AccessControlAllowHeaders::write(std::ostream& os) const {
  os << val_;
}

void
EncodingHeader::parseRaw(const char* str, size_t len) {
    if (!strncasecmp(str, "gzip", len)) {
        encoding_ = Encoding::Gzip;
    }
    else if (!strncasecmp(str, "deflate", len)) {
        encoding_ = Encoding::Deflate;
    }
    else if (!strncasecmp(str, "compress", len)) {
        encoding_ = Encoding::Compress;
    }
    else if (!strncasecmp(str, "identity", len)) {
        encoding_ = Encoding::Identity;
    }
    else if (!strncasecmp(str, "chunked", len)) {
        encoding_ = Encoding::Chunked;
    }
    else {
        encoding_ = Encoding::Unknown;
    }
}

void
EncodingHeader::write(std::ostream& os) const {
    os << encodingString(encoding_);
}

Server::Server(const std::vector<std::string>& tokens)
    : tokens_(tokens)
{ }

Server::Server(const std::string& token)
    : tokens_()
{
    tokens_.push_back(token);
}

Server::Server(const char* token)
   : tokens_()
{
    tokens_.emplace_back(token);
}

void
Server::parse(const std::string& data)
{
    UNUSED(data)
}

void
Server::write(std::ostream& os) const
{
    std::copy(std::begin(tokens_), std::end(tokens_),
                 std::ostream_iterator<std::string>(os, " "));
}

void
ContentType::parseRaw(const char* str, size_t len)
{
    mime_.parseRaw(str, len);
}

void
ContentType::write(std::ostream& os) const {
    os << mime_.toString();
}

} // namespace Header
} // namespace Http
} // namespace Pistache
<commit_msg>Still attempting to fix "Invalid port" error<commit_after>/* http_header.cc
   Mathieu Stefani, 19 August 2015

   Implementation of common HTTP headers described by the RFC
*/

#include <stdexcept>
#include <iterator>
#include <limits>
#include <cstring>
#include <iostream>

#include <pistache/http_header.h>
#include <pistache/common.h>
#include <pistache/http.h>
#include <pistache/stream.h>

using namespace std;

namespace Pistache {
namespace Http {
namespace Header {

const char* encodingString(Encoding encoding) {
    switch (encoding) {
    case Encoding::Gzip:
        return "gzip";
    case Encoding::Compress:
        return "compress";
    case Encoding::Deflate:
        return "deflate";
    case Encoding::Identity:
        return "identity";
    case Encoding::Chunked:
        return "chunked";
    case Encoding::Unknown:
        return "unknown";
    }

    unreachable();
}

void
Header::parse(const std::string& data) {
    parseRaw(data.c_str(), data.size());
}

void
Header::parseRaw(const char *str, size_t len) {
    parse(std::string(str, len));
}

void
Allow::parseRaw(const char* str, size_t len) {
    UNUSED(str)
    UNUSED(len)
}

void
Allow::write(std::ostream& os) const {
    /* This puts an extra ',' at the end :/
    std::copy(std::begin(methods_), std::end(methods_),
              std::ostream_iterator<Http::Method>(os, ", "));
    */

    for (std::vector<Http::Method>::size_type i = 0; i < methods_.size(); ++i) {
        os << methods_[i];
        if (i < methods_.size() - 1) os << ", ";
    }
}

void
Allow::addMethod(Http::Method method) {
    methods_.push_back(method);
}

void
Allow::addMethods(std::initializer_list<Method> methods) {
    std::copy(std::begin(methods), std::end(methods), std::back_inserter(methods_));
}

void
Allow::addMethods(const std::vector<Http::Method>& methods)
{
    std::copy(std::begin(methods), std::end(methods), std::back_inserter(methods_));
}

CacheControl::CacheControl(Http::CacheDirective directive)
{
    directives_.push_back(directive);
}

void
CacheControl::parseRaw(const char* str, size_t len) {
    using Http::CacheDirective;

    struct DirectiveValue {
        const char* const str;
        const size_t size;
        CacheDirective::Directive repr;
    };

#define VALUE(divStr, enumValue) { divStr, sizeof(divStr) - 1, CacheDirective::enumValue }

    static constexpr DirectiveValue TrivialDirectives[] = {
        VALUE("no-cache"        , NoCache        ),
        VALUE("no-store"        , NoStore        ),
        VALUE("no-transform"    , NoTransform    ),
        VALUE("only-if-cached"  , OnlyIfCached   ),
        VALUE("public"          , Public         ),
        VALUE("private"         , Private        ),
        VALUE("must-revalidate" , MustRevalidate ),
        VALUE("proxy-revalidate", ProxyRevalidate)
    };

    static constexpr DirectiveValue TimedDirectives[] = {
        VALUE("max-age"  , MaxAge  ),
        VALUE("max-stale", MaxStale),
        VALUE("min-fresh", MinFresh),
        VALUE("s-maxage" , SMaxAge )
    };

#undef VALUE

    RawStreamBuf<> buf(const_cast<char *>(str), len);
    StreamCursor cursor(&buf);

    do {

        bool found = false;
        // First scan trivial directives
        for (const auto& d: TrivialDirectives) {
            if (match_raw(d.str, d.size, cursor)) {
                directives_.push_back(CacheDirective(d.repr));
                found = true;
                break;
            }
        }

        // Not found, let's try timed directives
        if (!found) {
            for (const auto& d: TimedDirectives) {
                if (match_raw(d.str, d.size, cursor)) {
                    if (!cursor.advance(1)) {
                        throw std::runtime_error("Invalid caching directive, missing delta-seconds");
                    }

                    char *end;
                    const char* beg = cursor.offset();
                    // @Security: if str is not \0 terminated, there might be a situation
                    // where strtol can overflow. Double-check that it's harmless and fix if not
                    int secs = strtol(beg, &end, 10);
                    cursor.advance(end - beg);
                    if (!cursor.eof() && cursor.current() != ',') {
                        throw std::runtime_error("Invalid caching directive, malformated delta-seconds");
                    }
                    directives_.push_back(CacheDirective(d.repr, std::chrono::seconds(secs)));
                    found = true;
                    break;
                }
            }
        }

        if (!cursor.eof()) {
            if (cursor.current() != ',') {
                throw std::runtime_error("Invalid caching directive, expected a comma");
            }

            int c;
            while ((c = cursor.current()) != StreamCursor::Eof && (c == ',' || c == ' '))
                cursor.advance(1);
        }

    } while (!cursor.eof());

}

void
CacheControl::write(std::ostream& os) const {
    using Http::CacheDirective;

    auto directiveString = [](CacheDirective directive) -> const char* {
        switch (directive.directive()) {
            case CacheDirective::NoCache:
                return "no-cache";
            case CacheDirective::NoStore:
                return "no-store";
            case CacheDirective::NoTransform:
                return "no-transform";
            case CacheDirective::OnlyIfCached:
                return "only-if-cached";
            case CacheDirective::Public:
                return "public";
            case CacheDirective::Private:
                return "private";
            case CacheDirective::MustRevalidate:
                return "must-revalidate";
            case CacheDirective::ProxyRevalidate:
                return "proxy-revalidate";
            case CacheDirective::MaxAge:
                return "max-age";
            case CacheDirective::MaxStale:
                return "max-stale";
            case CacheDirective::MinFresh:
                return "min-fresh";
            case CacheDirective::SMaxAge:
                return "s-maxage";
            case CacheDirective::Ext:
                return "";
            default:
                return "";
        }
        return "";
    };

    auto hasDelta = [](CacheDirective directive) {
        switch (directive.directive()) {
            case CacheDirective::MaxAge:
            case CacheDirective::MaxStale:
            case CacheDirective::MinFresh:
            case CacheDirective::SMaxAge:
                return true;
            default:
                return false;
        }
    };

    for (std::vector<CacheDirective>::size_type i = 0; i < directives_.size(); ++i) {
        const auto& d = directives_[i];
        os << directiveString(d);
        if (hasDelta(d)) {
            auto delta = d.delta();
            if (delta.count() > 0) {
                os << "=" << delta.count();
            }
        }

        if (i < directives_.size() - 1) {
            os << ", ";
        }
    }

}

void
CacheControl::addDirective(Http::CacheDirective directive) {
    directives_.push_back(directive);
}

void
CacheControl::addDirectives(const std::vector<Http::CacheDirective>& directives) {
    std::copy(std::begin(directives), std::end(directives), std::back_inserter(directives_));
}

void
Connection::parseRaw(const char* str, size_t len) {
    char *p = const_cast<char *>(str);
    RawStreamBuf<> buf(p, p + len);
    StreamCursor cursor(&buf);

#define STR(str) \
    str, sizeof(str) - 1

    if (match_string(STR("close"), cursor)) {
        control_ = ConnectionControl::Close;
    }
    else if (match_string(STR("keep-alive"), cursor)) {
        control_ = ConnectionControl::KeepAlive;
    }
    else {
        control_ = ConnectionControl::Ext;
    }
}

void
Connection::write(std::ostream& os) const {
    switch (control_) {
    case ConnectionControl::Close:
        os << "Close";
        break;
    case ConnectionControl::KeepAlive:
        os << "Keep-Alive";
        break;
    case ConnectionControl::Ext:
        os << "Ext";
        break;
    }
}

void
ContentLength::parse(const std::string& data) {
    try {
        size_t pos;
        uint64_t val = std::stoi(data, &pos);
        if (pos != 0) {
        }

        value_ = val;
    } catch (const std::invalid_argument& e) {
    }
}

void
ContentLength::write(std::ostream& os) const {
    os << value_;
}

void
Date::parse(const std::string &str) {
    fullDate_ = FullDate::fromString(str);
}

void
Date::write(std::ostream& os) const {
    UNUSED(os)
}

void
Expect::parseRaw(const char* str, size_t len) {
    if (memcmp(str, "100-continue", len)) {
        expectation_ = Expectation::Continue;
    } else {
        expectation_ = Expectation::Ext;
    }
}

void
Expect::write(std::ostream& os) const {
    if (expectation_ == Expectation::Continue) {
        os << "100-continue";
    }
}

Host::Host(const std::string& data)
    : host_()
    , port_(0)
{
    parse(data);
}

void
Host::parse(const std::string& data) {
    unsigned long pos = data.find(']');
    unsigned long s_pos = data.find('[');
    if (pos != std::string::npos && s_pos != std::string::npos) {
        //IPv6 address
        host_ = data.substr(s_pos+1, pos-1);
        pos++;
    } else {
        //IPv4 address
        pos = data.find(':');
        if (pos == std::string::npos) {
            host_ = data;
            port_ = HTTP_STANDARD_PORT;
        }
        host_ = data.substr(0, pos);
        if (host_ == "*") {
            host_ = "0.0.0.0";
        }
    }
    char *end;
    const std::string portPart = data.substr(pos + 1);
    long port;
    if (pos != std::string::npos) {
        port = strtol(portPart.c_str(), &end, 10);
        if (port < std::numeric_limits<uint16_t>::min()|| port > std::numeric_limits<uint16_t>::max())
            throw std::invalid_argument("Invalid port");
        port_ = static_cast<uint16_t>(port);
    } else {
        port_ = HTTP_STANDARD_PORT;
    }
}

void
Host::write(std::ostream& os) const {
    os << host_;
    /* @Clarity @Robustness: maybe a found a literal different than zero
       to represent a null port ?
    */
    if (port_ != 0) {
        os << ":" << port_;
    }
}

Location::Location(const std::string& location)
    : location_(location)
{ }

void
Location::parse(const std::string& data) {
    location_ = data;
}

void
Location::write(std::ostream& os) const {
    os << location_;
}

void
UserAgent::parse(const std::string& data) {
    ua_ = data;
}

void
UserAgent::write(std::ostream& os) const {
    os << ua_;
}

void
Accept::parseRaw(const char *str, size_t len) {

    RawStreamBuf<char> buf(const_cast<char *>(str), len);
    StreamCursor cursor(&buf);

    do {
        int c;
        size_t beg = cursor;
        while ((c = cursor.next()) != StreamCursor::Eof && c != ',')
            cursor.advance(1);

        cursor.advance(1);

        const size_t mimeLen = cursor.diff(beg);

        mediaRange_.push_back(Mime::MediaType::fromRaw(cursor.offset(beg), mimeLen));

        if (!cursor.eof()) {
            if (!cursor.advance(1))
                throw std::runtime_error("Ill-formed Accept header");

            if ((c = cursor.next()) == StreamCursor::Eof || c == ',' || c == 0)
                throw std::runtime_error("Ill-formed Accept header");

            while (!cursor.eof() && cursor.current() == ' ')
                cursor.advance(1);
        }

    } while (!cursor.eof());
}

void
Accept::write(std::ostream& os) const {
    UNUSED(os)
}

void
AccessControlAllowOrigin::parse(const std::string& data) {
  uri_ = data;
}

void
AccessControlAllowOrigin::write(std::ostream& os) const {
  os << uri_;
}

void
AccessControlAllowHeaders::parse(const std::string& data) {
  val_ = data;
}

void
AccessControlAllowHeaders::write(std::ostream& os) const {
  os << val_;
}

void
EncodingHeader::parseRaw(const char* str, size_t len) {
    if (!strncasecmp(str, "gzip", len)) {
        encoding_ = Encoding::Gzip;
    }
    else if (!strncasecmp(str, "deflate", len)) {
        encoding_ = Encoding::Deflate;
    }
    else if (!strncasecmp(str, "compress", len)) {
        encoding_ = Encoding::Compress;
    }
    else if (!strncasecmp(str, "identity", len)) {
        encoding_ = Encoding::Identity;
    }
    else if (!strncasecmp(str, "chunked", len)) {
        encoding_ = Encoding::Chunked;
    }
    else {
        encoding_ = Encoding::Unknown;
    }
}

void
EncodingHeader::write(std::ostream& os) const {
    os << encodingString(encoding_);
}

Server::Server(const std::vector<std::string>& tokens)
    : tokens_(tokens)
{ }

Server::Server(const std::string& token)
    : tokens_()
{
    tokens_.push_back(token);
}

Server::Server(const char* token)
   : tokens_()
{
    tokens_.emplace_back(token);
}

void
Server::parse(const std::string& data)
{
    UNUSED(data)
}

void
Server::write(std::ostream& os) const
{
    std::copy(std::begin(tokens_), std::end(tokens_),
                 std::ostream_iterator<std::string>(os, " "));
}

void
ContentType::parseRaw(const char* str, size_t len)
{
    mime_.parseRaw(str, len);
}

void
ContentType::write(std::ostream& os) const {
    os << mime_.toString();
}

} // namespace Header
} // namespace Http
} // namespace Pistache
<|endoftext|>


<commit_before>#include "libtest.h"

using namespace std;
#include "../lib/json/json.h"

void test_empty_dict(){

    string message = "{}";

    JsonValue * value = JsonValue::fromString(message);

    ASSERT_NOT_NULL(value, "Parsing null");

    JsonDict* dict_p = JDICT(value);
    ASSERT_NOT_NULL(dict_p, "Dict null");

    ASSERT(dict_p->size() == 0, "Dict not null");
}

void test_dict_one_val(){
    string fix[] = {
        "{\"a\":\"b\"}",
        "{\"a\" :\"b\"}",
        "{\"a\": \"b\"}",
        "{\"a\" : \"b\"}",
        "{  \"a\"  :  \"b\"  }"
    };

    for(int i=0; i < 5; i++){
        string message = fix[i];

        JsonValue * value = JsonValue::fromString(message);

        ASSERT_NOT_NULL(value, "Parsing null");

        JsonDict* dict_p = JDICT(value);
        ASSERT_NOT_NULL(dict_p, "Dict null");

        ASSERT(dict_p->size() == 1, "Dict not null");
        ASSERT_EQUAL((string) *JSTRING((*dict_p)["a"]), "b", "d[a]!=b");
    }
}

void test_empty_list(){
    string message = "[]";

    JsonValue * value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing null");

    JsonList * list_p = JLIST(value);
    ASSERT_NOT_NULL(list_p, "List null");

    ASSERT(list_p->size() == 0, "List not empty");
}

void test_empty_string(){
    string message = "\"\"";

    JsonValue * value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing not null");

    JsonString* string_p = JSTRING(value);
    ASSERT_NOT_NULL(string_p, "String not null");

    ASSERT_EQUAL((string) *string_p, "", "Empty string");
}

void test_true_bool(){
    string message = "true";

    JsonValue* value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing not null");

    JsonBool * bool_p = JBOOL(value);
    ASSERT_NOT_NULL(bool_p, "Cast");

    ASSERT(*bool_p, "Must be true");
}

void test_false_bool(){
    string message = "false";

    JsonValue* value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing not null");

    JsonBool * bool_p = JBOOL(value);
    ASSERT_NOT_NULL(bool_p, "Cast");

    ASSERT_FALSE(*bool_p, "Must be false");
}

void test_null(){
    string message = "null";

    JsonValue* value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing not null");

    JsonNull* null_p = JNULL(value);
    ASSERT_NOT_NULL(null_p, "Cast to null");

    ASSERT_NULL(*null_p, "Is null");

}

#define TESTVEC {T(test_empty_dict), T(test_empty_list), T(test_empty_string), T(test_true_bool), T(test_false_bool), T(test_null), T(test_dict_one_val)}
TEST();
<commit_msg>Aff failing test (while parsing a user model)<commit_after>#include "libtest.h"

using namespace std;
#include "../lib/json/json.h"

void test_empty_dict(){

    string message = "{}";

    JsonValue * value = JsonValue::fromString(message);

    ASSERT_NOT_NULL(value, "Parsing null");

    JsonDict* dict_p = JDICT(value);
    ASSERT_NOT_NULL(dict_p, "Dict null");

    ASSERT(dict_p->size() == 0, "Dict not null");
}

void test_dict_one_val(){
    string fix[] = {
        "{\"a\":\"b\"}",
        "{\"a\" :\"b\"}",
        "{\"a\": \"b\"}",
        "{\"a\" : \"b\"}",
        "{  \"a\"  :  \"b\"  }"
    };

    for(int i=0; i < 5; i++){
        string message = fix[i];

        JsonValue * value = JsonValue::fromString(message);

        ASSERT_NOT_NULL(value, "Parsing null");

        JsonDict* dict_p = JDICT(value);
        ASSERT_NOT_NULL(dict_p, "Dict null");

        ASSERT(dict_p->size() == 1, "Dict not null");
        ASSERT_EQUAL((string) *JSTRING((*dict_p)["a"]), "b", "d[a]!=b");
    }
}

void test_empty_list(){
    string message = "[]";

    JsonValue * value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing null");

    JsonList * list_p = JLIST(value);
    ASSERT_NOT_NULL(list_p, "List null");

    ASSERT(list_p->size() == 0, "List not empty");
}

void test_empty_string(){
    string message = "\"\"";

    JsonValue * value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing not null");

    JsonString* string_p = JSTRING(value);
    ASSERT_NOT_NULL(string_p, "String not null");

    ASSERT_EQUAL((string) *string_p, "", "Empty string");
}

void test_true_bool(){
    string message = "true";

    JsonValue* value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing not null");

    JsonBool * bool_p = JBOOL(value);
    ASSERT_NOT_NULL(bool_p, "Cast");

    ASSERT(*bool_p, "Must be true");
}

void test_false_bool(){
    string message = "false";

    JsonValue* value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing not null");

    JsonBool * bool_p = JBOOL(value);
    ASSERT_NOT_NULL(bool_p, "Cast");

    ASSERT_FALSE(*bool_p, "Must be false");
}

void test_null(){
    string message = "null";

    JsonValue* value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing not null");

    JsonNull* null_p = JNULL(value);
    ASSERT_NOT_NULL(null_p, "Cast to null");

    ASSERT_NULL(*null_p, "Is null");

}

void test_functionnal_user(){
    string message = "{\n    \"username\": \"nikita\",\n    \"name\": \"Nikita Marchant\",\n    \"hash\": \"plop\",\n    \"club\": {\n        \"money\": 10,\n        \"installations\" : [\n            {\"level\": 1},\n            {\"mevel\": 2},\n            {\"wevel\": 3},\n            {\"xevel\": 4},\n            {\"cevel\": 5}\n        ],\n        \"team\": {\n            \"players\" : [null, null, null, null, null, null, null]\n        },\n        \"players\": []\n    }\n}\n\n";
    JsonValue* value = JsonValue::fromString(message);
    ASSERT_NOT_NULL(value, "Parsing not null");
}

#define TESTVEC {T(test_empty_dict), T(test_empty_list), T(test_empty_string), T(test_true_bool), T(test_false_bool), T(test_null), T(test_dict_one_val), T(test_functionnal_user)}
TEST();
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gflags/gflags.h>
#include <glog/logging.h>
#include <sys/times.h>
#include <syscall.h>

#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

#include "pffft_sapi.sapi.h"
#include "sandboxed_api/util/flag.h"
#include "sandboxed_api/vars.h"

ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all);
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all_and_log);

class PffftSapiSandbox : public PffftSandbox {
 public:
  std::unique_ptr<sandbox2::Policy> ModifyPolicy(sandbox2::PolicyBuilder*) {
    return sandbox2::PolicyBuilder()
        .AllowStaticStartup()
        .AllowOpen()
        .AllowRead()
        .AllowWrite()
        .AllowSystemMalloc()
        .AllowExit()
        .AllowSyscalls({
            __NR_futex,
            __NR_close,
            __NR_getrusage,
        })
        .BuildOrDie();
  }
};

// output_format flag determines whether the output shows information in detail
// or not. By default, the flag is set as 0, meaning an elaborate display
// (see ShowOutput method).
static bool ValidateFlag(const char* flagname, int32_t value) {
  if (value >= 0 && value < 32768) {
    return true;
  }

  LOG(ERROR) << "Invalid value for --" << flagname << ".";
  return false;
}

DEFINE_int32(output_format, 0, "Value to specific the output format.");
DEFINE_validator(output_format, &ValidateFlag);

double UclockSec() { return static_cast<double>(clock()) / CLOCKS_PER_SEC; }

void ShowOutput(const char* name, int n, int complex, float flops, float t0,
                float t1, int max_iter) {
  float mflops = flops / 1e6 / (t1 - t0 + 1e-16);
  if (FLAGS_output_format) {
    if (flops != -1) {
      printf("|%9.0f   ", mflops);
    } else
      printf("|      n/a   ");
  } else {
    if (flops != -1) {
      printf("n=%5d, %s %16s : %6.0f MFlops [t=%6.0f ns, %d runs]\n", n,
             (complex ? "CPLX" : "REAL"), name, mflops,
             (t1 - t0) / 2 / max_iter * 1e9, max_iter);
    }
  }
  fflush(stdout);
}

absl::Status PffftMain() {
  LOG(INFO) << "Initializing sandbox...\n";

  PffftSapiSandbox sandbox;
  SAPI_RETURN_IF_ERROR(sandbox.Init());

  PffftApi api(&sandbox);

  // kTransformSizes is a vector keeping the values by which iterates n, its
  // value representing the input length. More concrete, n is the number of data
  // points the caclulus is up to (determinating its accuracy). To show the
  // performance of Fast-Fourier Transformations the program is testing for
  // various values of n.
  constexpr int kTransformSizes[] = {
      64,      96,  128,  160,  192,  256,  384,  5 * 96,   512,   5 * 128,
      3 * 256, 800, 1024, 2048, 2400, 4096, 8192, 9 * 1024, 16384, 32768};

  for (int complex : {0, 1}) {
    for (int n : kTransformSizes) {
      const int n_float = n * (complex ? 2 : 1);
      int n_bytes = n_float * sizeof(float);

      std::vector<float> work(2 * n_float + 15, 0.0);
      sapi::v::Array<float> work_array(&work[0], work.size());

      std::vector<float> x(n_bytes, 0.0);
      sapi::v::Array<float> x_array(&x[0], x.size());

      std::vector<float> y(n_bytes, 0.0);
      sapi::v::Array<float> y_array(&y[0], y.size());

      std::vector<float> z(n_bytes, 0.0);
      sapi::v::Array<float> z_array(&z[0], z.size());

      double t0;
      double t1;
      double flops;

      int max_iter = 5120000 / n * 4;

      for (int k = 0; k < n_float; ++k) {
        x[k] = 0;
      }

      // FFTPack benchmark
      {
        // SIMD_SZ == 4 (returning value of pffft_simd_size())
        int simd_size_iter = max_iter / 4;

        if (simd_size_iter == 0) simd_size_iter = 1;
        if (complex) {
          api.cffti(n, work_array.PtrBoth()).IgnoreError();
        } else {
          api.rffti(n, work_array.PtrBoth()).IgnoreError();
        }
        t0 = UclockSec();

        for (int iter = 0; iter < simd_size_iter; ++iter) {
          if (complex) {
            api.cfftf(n, x_array.PtrBoth(), work_array.PtrBoth()).IgnoreError();
            api.cfftb(n, x_array.PtrBoth(), work_array.PtrBoth()).IgnoreError();
          } else {
            api.rfftf(n, x_array.PtrBoth(), work_array.PtrBoth()).IgnoreError();
            api.rfftb(n, x_array.PtrBoth(), work_array.PtrBoth()).IgnoreError();
          }
        }
        t1 = UclockSec();

        flops = (simd_size_iter * 2) *
                ((complex ? 5 : 2.5) * n * log((double)n) / M_LN2);
        ShowOutput("FFTPack", n, complex, flops, t0, t1, simd_size_iter);
      }

      // PFFFT benchmark
      {
        sapi::StatusOr<PFFFT_Setup*> s =
            api.pffft_new_setup(n, complex ? PFFFT_COMPLEX : PFFFT_REAL);

        LOG(INFO) << "Setup status is: " << s.status().ToString();

        if (!s.ok()) {
          printf("Sandbox failed.\n");
          return s.status();
        }

        sapi::v::RemotePtr s_reg(s.value());

        t0 = UclockSec();
        for (int iter = 0; iter < max_iter; ++iter) {
          api.pffft_transform(&s_reg, x_array.PtrBoth(), z_array.PtrBoth(),
                              y_array.PtrBoth(), PFFFT_FORWARD)
              .IgnoreError();
          api.pffft_transform(&s_reg, x_array.PtrBoth(), z_array.PtrBoth(),
                              y_array.PtrBoth(), PFFFT_FORWARD)
              .IgnoreError();
        }

        t1 = UclockSec();
        api.pffft_destroy_setup(&s_reg).IgnoreError();

        flops = (max_iter * 2) * ((complex ? 5 : 2.5) * static_cast<double>(n) *
                                  log((double)n) / M_LN2);
        ShowOutput("PFFFT", n, complex, flops, t0, t1, max_iter);

        LOG(INFO) << "n = " << n << " SUCCESSFULLY";
      }
    }
  }

  return absl::OkStatus();
}

int main(int argc, char* argv[]) {
  // Initialize Google's logging library.
  google::InitGoogleLogging(argv[0]);

  gflags::ParseCommandLineFlags(&argc, &argv, true);

  if (absl::Status status = PffftMain(); !status.ok()) {
    LOG(ERROR) << "Initialization failed: " << status.ToString();
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}<commit_msg>Setup error handling modified<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gflags/gflags.h>
#include <glog/logging.h>
#include <sys/times.h>
#include <syscall.h>

#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

#include "pffft_sapi.sapi.h"
#include "sandboxed_api/util/flag.h"
#include "sandboxed_api/vars.h"

ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all);
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all_and_log);

class PffftSapiSandbox : public PffftSandbox {
 public:
  std::unique_ptr<sandbox2::Policy> ModifyPolicy(sandbox2::PolicyBuilder*) {
    return sandbox2::PolicyBuilder()
        .AllowStaticStartup()
        .AllowOpen()
        .AllowRead()
        .AllowWrite()
        .AllowSystemMalloc()
        .AllowExit()
        .AllowSyscalls({
            __NR_futex,
            __NR_close,
            __NR_getrusage,
        })
        .BuildOrDie();
  }
};

// output_format flag determines whether the output shows information in detail
// or not. By default, the flag is set as 0, meaning an elaborate display
// (see ShowOutput method).
static bool ValidateFlag(const char* flagname, int32_t value) {
  if (value >= 0 && value < 32768) {
    return true;
  }

  LOG(ERROR) << "Invalid value for --" << flagname << ".";
  return false;
}

DEFINE_int32(output_format, 0, "Value to specific the output format.");
DEFINE_validator(output_format, &ValidateFlag);

double UclockSec() { return static_cast<double>(clock()) / CLOCKS_PER_SEC; }

void ShowOutput(const char* name, int n, int complex, float flops, float t0,
                float t1, int max_iter) {
  float mflops = flops / 1e6 / (t1 - t0 + 1e-16);
  if (FLAGS_output_format) {
    if (flops != -1) {
      printf("|%9.0f   ", mflops);
    } else
      printf("|      n/a   ");
  } else {
    if (flops != -1) {
      printf("n=%5d, %s %16s : %6.0f MFlops [t=%6.0f ns, %d runs]\n", n,
             (complex ? "CPLX" : "REAL"), name, mflops,
             (t1 - t0) / 2 / max_iter * 1e9, max_iter);
    }
  }
  fflush(stdout);
}

absl::Status PffftMain() {
  LOG(INFO) << "Initializing sandbox...\n";

  PffftSapiSandbox sandbox;
  SAPI_RETURN_IF_ERROR(sandbox.Init());

  PffftApi api(&sandbox);

  // kTransformSizes is a vector keeping the values by which iterates n, its
  // value representing the input length. More concrete, n is the number of data
  // points the caclulus is up to (determinating its accuracy). To show the
  // performance of Fast-Fourier Transformations the program is testing for
  // various values of n.
  constexpr int kTransformSizes[] = {
      64,      96,  128,  160,  192,  256,  384,  5 * 96,   512,   5 * 128,
      3 * 256, 800, 1024, 2048, 2400, 4096, 8192, 9 * 1024, 16384, 32768};

  for (int complex : {0, 1}) {
    for (int n : kTransformSizes) {
      const int n_float = n * (complex ? 2 : 1);
      int n_bytes = n_float * sizeof(float);

      std::vector<float> work(2 * n_float + 15, 0.0);
      sapi::v::Array<float> work_array(&work[0], work.size());

      std::vector<float> x(n_bytes, 0.0);
      sapi::v::Array<float> x_array(&x[0], x.size());

      std::vector<float> y(n_bytes, 0.0);
      sapi::v::Array<float> y_array(&y[0], y.size());

      std::vector<float> z(n_bytes, 0.0);
      sapi::v::Array<float> z_array(&z[0], z.size());

      double t0;
      double t1;
      double flops;

      int max_iter = 5120000 / n * 4;

      for (int k = 0; k < n_float; ++k) {
        x[k] = 0;
      }

      // FFTPack benchmark
      {
        // SIMD_SZ == 4 (returning value of pffft_simd_size())
        int simd_size_iter = max_iter / 4;

        if (simd_size_iter == 0) simd_size_iter = 1;
        if (complex) {
          api.cffti(n, work_array.PtrBoth()).IgnoreError();
        } else {
          api.rffti(n, work_array.PtrBoth()).IgnoreError();
        }
        t0 = UclockSec();

        for (int iter = 0; iter < simd_size_iter; ++iter) {
          if (complex) {
            api.cfftf(n, x_array.PtrBoth(), work_array.PtrBoth()).IgnoreError();
            api.cfftb(n, x_array.PtrBoth(), work_array.PtrBoth()).IgnoreError();
          } else {
            api.rfftf(n, x_array.PtrBoth(), work_array.PtrBoth()).IgnoreError();
            api.rfftb(n, x_array.PtrBoth(), work_array.PtrBoth()).IgnoreError();
          }
        }
        t1 = UclockSec();

        flops = (simd_size_iter * 2) *
                ((complex ? 5 : 2.5) * n * log((double)n) / M_LN2);
        ShowOutput("FFTPack", n, complex, flops, t0, t1, simd_size_iter);
      }

      // PFFFT benchmark
      {
        SAPI_ASSIGN_OR_RETURN(
            PFFFT_Setup *s,
            api.pffft_new_setup(n, complex ? PFFFT_COMPLEX : PFFFT_REAL));

        sapi::v::RemotePtr s_reg(s);

        t0 = UclockSec();
        for (int iter = 0; iter < max_iter; ++iter) {
          api.pffft_transform(&s_reg, x_array.PtrBoth(), z_array.PtrBoth(),
                              y_array.PtrBoth(), PFFFT_FORWARD)
              .IgnoreError();
          api.pffft_transform(&s_reg, x_array.PtrBoth(), z_array.PtrBoth(),
                              y_array.PtrBoth(), PFFFT_FORWARD)
              .IgnoreError();
        }

        t1 = UclockSec();
        api.pffft_destroy_setup(&s_reg).IgnoreError();

        flops = (max_iter * 2) * ((complex ? 5 : 2.5) * static_cast<double>(n) *
                                  log((double)n) / M_LN2);
        ShowOutput("PFFFT", n, complex, flops, t0, t1, max_iter);

        LOG(INFO) << "n = " << n << " SUCCESSFULLY";
      }
    }
  }

  return absl::OkStatus();
}

int main(int argc, char* argv[]) {
  // Initialize Google's logging library.
  google::InitGoogleLogging(argv[0]);

  gflags::ParseCommandLineFlags(&argc, &argv, true);

  if (absl::Status status = PffftMain(); !status.ok()) {
    LOG(ERROR) << "Initialization failed: " << status.ToString();
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}<|endoftext|>