<commit_before>#include "cmbNucLattice.h"
#include "cmbNucPartDefinition.h"

Lattice::Lattice()
{
  this->enGeometryType = RECTILINEAR;
  this->SetDimensions(4, 4);
  subType = FLAT | ANGLE_360;
}

Lattice::Lattice( Lattice const& other )
{
  setUpGrid(other);
  this->subType = other.subType;
  this->enGeometryType = other.enGeometryType;
  this->FullCellMode = Lattice::HEX_FULL;
}

Lattice::~Lattice()
{
  Grid.clear();
  for(std::map<std::string, LatticeCell*>::iterator i = LabelToCell.begin(); i != LabelToCell.end(); ++i)
  {
    delete i->second;
    i->second = NULL;
  }
  LabelToCell.clear();
}

Lattice& Lattice::operator=(Lattice const& other)
{
  //TODO update grid
  setUpGrid(other);
  this->subType = other.subType;
  this->enGeometryType = other.enGeometryType;
  this->FullCellMode = other.FullCellMode;
  return *this;
}

void Lattice::setUpGrid(Lattice const & other)
{
  for(std::map<std::string, LatticeCell*>::const_iterator i = other.LabelToCell.begin();
      i != other.LabelToCell.end(); ++i)
  {
    if(LabelToCell[i->first]!= NULL) delete LabelToCell[i->first];
    LabelToCell[i->first] = new LatticeCell(*(i->second));
  }
  //TODO update grid
  this->Grid.resize(other.Grid.size());
  for(unsigned int i = 0; i < other.Grid.size(); ++i)
  {
    this->Grid[i].resize(other.Grid[i].size());
    for(unsigned j = 0; j < other.Grid[i].size(); ++j)
    {
      this->Grid[i][j].setCell(this->getCell(other.Grid[i][j].getCell()->label));
    }
  }
  this->computeValidRange();
}

std::string Lattice::getLabel()
{ return "Lattice"; }

std::string Lattice::getTitle(){ return "Lattice"; }

void Lattice::setInvalidCells()
{
  LatticeCell * invalid = this->getCell("");
  invalid->setInvalid();
  for(size_t i = 0; i < this->Grid.size(); i++)
  {
    size_t start = (subType & FLAT)?(i):(i-(i)/2);
    size_t cols = ((subType & FLAT)?(i+1):(((i+1)-(i+2)%2)))+start;
    if(subType & ANGLE_30)
    {
      start = 2*i - i/2;
      cols = (i%2 ? (i+1)/2 :(i+2)/2) + start;
    }
    for(unsigned int j = 0; j < start; ++j)
    {
      this->Grid[i][j].setCell(invalid);
    }
    for( size_t j = cols; j < this->Grid[i].size(); j++)
    {
      this->Grid[i][j].setCell(invalid);
    }
  }
}

void Lattice::SetDimensions(int iin, int jin, bool reset)
{
  LatticeCell * invalid = this->getCell("");
  invalid->setInvalid();
  LatticeCell * XX = this->getCell("xx");
  XX->color = Qt::white;
  XX->valid = true;
  if(this->enGeometryType == RECTILINEAR)
  {
    this->Grid.resize(iin);
    for(int k = 0; k < iin; k++)
    {
      this->Grid[k].resize(jin);
      for(int r = 0; r < jin; ++r)
      {
        this->Grid[k][r].setCell(XX);
      }
    }
  }
  else if(this->enGeometryType == HEXAGONAL)
  {
    int current = reset ? 0 : this->Grid.size();
    if(current == iin)
    {
      return;
    }

    this->Grid.resize(iin);

    this->computeValidRange();

    if(iin > current)
    {
      for(int k = current; k < iin; k++)
      {
        if(k == 0)
        {
          this->Grid[k].resize(1);
          this->Grid[k][0].setCell(XX);
        }
        else
        {
          // for each layer, we need 6*Layer cells
          int cols = 6*k;
          this->Grid[k].resize(cols);
          int start, end;
          getValidRange(k, start, end);
          for(int c = 0; c < cols; c++)
          {
            if(start <= c && c <= end)
            {
              this->Grid[k][c].setCell(XX);
            }
            else
            {
              this->Grid[k][c].setCell(invalid);
            }
          }
        }
      }
    }
  }
}

bool Lattice::getValidRange(int layer, int & start, int & end) const
{
  if(this->enGeometryType == HEXAGONAL)
  {
    start = this->validRange[layer].first;
    end = this->validRange[layer].second;
    return true;
  }
  return false;
}

void Lattice::computeValidRange()
{
  if(this->enGeometryType == HEXAGONAL)
  {
    this->validRange.resize(Grid.size());
    for( int layer = 0; layer < Grid.size(); ++layer)
    {
      this->validRange[layer].first = 0;
      this->validRange[layer].second = 6*layer-1;
      if(subType != 0 && !(subType & ANGLE_360))
      {
        this->validRange[layer].first = (subType & FLAT)?(layer):(layer-(layer)/2);
        this->validRange[layer].second = ((subType & FLAT)?(layer+1):
                                                           (((layer+1)-(layer+2)%2)))+this->validRange[layer].first-1;
        if(subType & ANGLE_30)
        {
          this->validRange[layer].first = 2*layer - layer/2;
          this->validRange[layer].second = (layer%2 ? (layer+1)/2 :(layer+2)/2) + this->validRange[layer].first - 1;
        }
      }
    }
  }
}

std::pair<int, int> Lattice::GetDimensions() const
{
  if(this->Grid.size() == 0) return std::make_pair(0,0);
  if(this->enGeometryType == RECTILINEAR)
  {
    return std::make_pair(static_cast<int>(this->Grid.size()),
                          static_cast<int>(this->Grid[0].size()));
  }
  else
  {
    return std::make_pair(static_cast<int>(this->Grid.size()), 6);
  }
}

void Lattice::SetCell(int i, int j, const std::string &name,
                      const QColor& color, bool valid)
{
  LatticeCell * cr = this->getCell(name);
  cr->color = color;
  cr->valid = valid;
  this->Grid[i][j].setCell(cr);
}

void Lattice::SetCell(int i, int j, const std::string &name)
{
  LatticeCell * cr = this->getCell(name);
  this->Grid[i][j].setCell(cr);
}

void Lattice::SetCellColor(const std::string &name, const QColor& color)
{
  LatticeCell * cr = this->getCell(name);
  cr->color = color;
}

void Lattice::setAsInvalid(int i, int j)
{
  LatticeCell * cr = this->getCell("");
  cr->setInvalid();
  this->Grid[i][j].setCell(cr);
}

Lattice::LatticeCell Lattice::GetCell(int i, int j) const
{
  return *(this->Grid[i][j].getCell());
}

Lattice::LatticeCell Lattice::GetCell(int i) const
{
  // Convert to j,k
  int s = static_cast<int>(this->Grid.size());
  // For Hex type, This is different
  if(this->enGeometryType == HEXAGONAL)
  {
    int j = 0, k = 0;
    int totalNum = 0, preTotal;
    for(int layer = 0; layer < s; layer++)
    {
      preTotal = totalNum;
      // totalNum += (6*layer);
      totalNum = 1 + 3*layer*(layer+1);
      if(i < totalNum)
      {
        j = layer;
        k = i-preTotal;
        break;
      }
    }
    return this->GetCell(j,k);
  }
  else
  {
    int size = static_cast<int>(this->Grid[0].size());
    int j = i / size;
    int k = i - (j*size);
    assert(j < static_cast<int>(this->Grid.size()));
    assert(k < static_cast<int>(this->Grid[j].size()));

    return this->GetCell(j,k);
  }
}

void Lattice::ClearCell(int i, int j)
{
  LatticeCell * cr = this->getCell("xx");
  this->Grid[i][j].setCell(cr);
}

bool Lattice::ClearCell(const std::string &label)
{
  bool r = false;
  for(size_t i = 0; i < this->Grid.size(); i++)
  {
    for(size_t j = 0; j < this->Grid[i].size(); j++)
    {
      if(this->GetCell(i, j).label == label)
      {
        r = true;
        this->ClearCell(i, j);
      }
    }
  }
  return r;
}

bool Lattice::replaceLabel(const std::string &oldL, const std::string &newL)
{
  std::map<std::string, LatticeCell *>::iterator iter = LabelToCell.find(oldL);
  if(iter == LabelToCell.end() || iter->second->getCount() == 0)
  {
    return false;
  }
  std::map<std::string, LatticeCell *>::iterator newI = LabelToCell.find(newL);
  if(newI == LabelToCell.end()) //easy
  {
    iter->second->label = newL;
    LabelToCell[newL] = iter->second;
    LabelToCell.erase(iter);
    return true;
  }
  //harder
  for(size_t i = 0; i < this->Grid.size(); i++)
  {
    for(size_t j = 0; j < this->Grid[i].size(); j++)
    {
      if(this->Grid[i][j].getCell() == iter->second)
      {
        this->Grid[i][j].setCell(newI->second);
      }
    }
  }
  return true;
}

enumNucPartsType Lattice::GetType() const
{ return CMBNUC_ASSY_LATTICE;}

int Lattice::GetNumberOfCells()
{
  if(this->Grid.size() == 0)
  {
    return 0;
  }
  if(this->enGeometryType == HEXAGONAL)
  {
    int tmp = static_cast<int>(this->Grid.size());
    return 1 + 3*tmp*(tmp - 1);
  }
  else
  {
    return static_cast<int>(this->Grid.size()*this->Grid[0].size());
  }
}

void Lattice::SetGeometryType(enumGeometryType type)
{
  if(this->enGeometryType == type) return;
  this->enGeometryType = type;
  if(type == RECTILINEAR) this->SetDimensions(4, 4);
  else this->SetDimensions(1, 1, true);
}

enumGeometryType Lattice::GetGeometryType()
{ return this->enGeometryType; }

void Lattice::SetGeometrySubType(int type)
{subType = type;}

int Lattice::GetGeometrySubType() const
{ return subType; }

bool Lattice::labelUsed(const std::string &l) const
{
  std::map<std::string, LatticeCell *>::const_iterator iter = LabelToCell.find(l);
  if(iter == LabelToCell.end())
  {
    return false;
  }
  return iter->second->getCount() != 0;
}

Lattice::LatticeCell * Lattice::getCell(std::string label)
{
  LatticeCell * result = NULL;
  std::map<std::string, LatticeCell *>::iterator iter = LabelToCell.find(label);
  if(iter == LabelToCell.end())
  {
    result = new LatticeCell;
    result->label = label;
    LabelToCell[label] = result;
  }
  else
  {
    result = iter->second;
  }
  return result;
}

Lattice::CellDrawMode Lattice::getDrawMode(int index, int layer) const
{
  if(this->enGeometryType == RECTILINEAR) return Lattice::RECT;
  int start, end;
  this->getValidRange(layer, start, end);
  if(layer == 0)
  {
    if(this->subType & ANGLE_360)
    {
      return this->getFullCellMode();
    }
    else if(this->subType & ANGLE_60 && this->subType & FLAT)
    {
      return Lattice::HEX_SIXTH_FLAT_CENTER;
    }
    else if(this->subType & ANGLE_60 && this->subType & VERTEX)
    {
      return Lattice::HEX_SIXTH_VERT_CENTER;
    }
    else if(this->subType & ANGLE_30)
    {
      return Lattice::HEX_TWELFTH_CENTER;
    }
  }
  else if(this->subType & ANGLE_360)
  {
    return FullCellMode;
  }
  else if( this->subType & ANGLE_60 && this->subType & FLAT )
  {
    if(index == start)
    {
      return Lattice::HEX_SIXTH_FLAT_TOP;
    }
    else if(index == end)
    {
      return Lattice::HEX_SIXTH_FLAT_BOTTOM;
    }
    else
    {
      return Lattice::HEX_FULL;
    }
  }
  else if( this->subType & ANGLE_60 && this->subType & VERTEX )
  {
    if(index == start && layer % 2 == 0) return Lattice::HEX_SIXTH_VERT_TOP;
    else if(index == end && layer % 2 == 0) return Lattice::HEX_SIXTH_VERT_BOTTOM;
    return Lattice::HEX_FULL_30;
  }
  else if(this->subType & ANGLE_30)
  {
    if(index == end) return Lattice::HEX_TWELFTH_BOTTOM;
    else if(index == start && layer % 2 == 0) return Lattice::HEX_TWELFTH_TOP;
  }
  return Lattice::HEX_FULL;
}

std::string Lattice::generate_string(std::string in, CellDrawMode mode)
{
  switch(mode)
  {
    case RECT:
    case HEX_FULL:
    case HEX_FULL_30:
      return in;
    case HEX_SIXTH_FLAT_BOTTOM:
    case HEX_SIXTH_VERT_BOTTOM:
    case HEX_TWELFTH_BOTTOM:
      return in+"_bottom";
    case HEX_SIXTH_FLAT_CENTER:
    case HEX_SIXTH_VERT_CENTER:
    case HEX_TWELFTH_CENTER:
      return in + "_center";
    case HEX_SIXTH_FLAT_TOP:
    case HEX_SIXTH_VERT_TOP:
    case HEX_TWELFTH_TOP:
      return in + "_top";
  }
}
<commit_msg>fix resize of rect lattice<commit_after>#include "cmbNucLattice.h"
#include "cmbNucPartDefinition.h"

Lattice::Lattice()
{
  this->enGeometryType = RECTILINEAR;
  this->SetDimensions(4, 4);
  subType = FLAT | ANGLE_360;
}

Lattice::Lattice( Lattice const& other )
{
  setUpGrid(other);
  this->subType = other.subType;
  this->enGeometryType = other.enGeometryType;
  this->FullCellMode = Lattice::HEX_FULL;
}

Lattice::~Lattice()
{
  Grid.clear();
  for(std::map<std::string, LatticeCell*>::iterator i = LabelToCell.begin(); i != LabelToCell.end(); ++i)
  {
    delete i->second;
    i->second = NULL;
  }
  LabelToCell.clear();
}

Lattice& Lattice::operator=(Lattice const& other)
{
  //TODO update grid
  setUpGrid(other);
  this->subType = other.subType;
  this->enGeometryType = other.enGeometryType;
  this->FullCellMode = other.FullCellMode;
  return *this;
}

void Lattice::setUpGrid(Lattice const & other)
{
  for(std::map<std::string, LatticeCell*>::const_iterator i = other.LabelToCell.begin();
      i != other.LabelToCell.end(); ++i)
  {
    if(LabelToCell[i->first]!= NULL) delete LabelToCell[i->first];
    LabelToCell[i->first] = new LatticeCell(*(i->second));
  }
  //TODO update grid
  this->Grid.resize(other.Grid.size());
  for(unsigned int i = 0; i < other.Grid.size(); ++i)
  {
    this->Grid[i].resize(other.Grid[i].size());
    for(unsigned j = 0; j < other.Grid[i].size(); ++j)
    {
      this->Grid[i][j].setCell(this->getCell(other.Grid[i][j].getCell()->label));
    }
  }
  this->computeValidRange();
}

std::string Lattice::getLabel()
{ return "Lattice"; }

std::string Lattice::getTitle(){ return "Lattice"; }

void Lattice::setInvalidCells()
{
  LatticeCell * invalid = this->getCell("");
  invalid->setInvalid();
  for(size_t i = 0; i < this->Grid.size(); i++)
  {
    size_t start = (subType & FLAT)?(i):(i-(i)/2);
    size_t cols = ((subType & FLAT)?(i+1):(((i+1)-(i+2)%2)))+start;
    if(subType & ANGLE_30)
    {
      start = 2*i - i/2;
      cols = (i%2 ? (i+1)/2 :(i+2)/2) + start;
    }
    for(unsigned int j = 0; j < start; ++j)
    {
      this->Grid[i][j].setCell(invalid);
    }
    for( size_t j = cols; j < this->Grid[i].size(); j++)
    {
      this->Grid[i][j].setCell(invalid);
    }
  }
}

void Lattice::SetDimensions(int iin, int jin, bool reset)
{
  LatticeCell * invalid = this->getCell("");
  invalid->setInvalid();
  LatticeCell * XX = this->getCell("xx");
  XX->color = Qt::white;
  XX->valid = true;
  if(this->enGeometryType == RECTILINEAR)
  {
    this->Grid.resize(iin);
    for(int k = 0; k < iin; k++)
    {
      int old = reset?0:this->Grid[k].size();
      this->Grid[k].resize(jin);
      for(int r = old; r < jin; ++r)
      {
        this->Grid[k][r].setCell(XX);
      }
    }
  }
  else if(this->enGeometryType == HEXAGONAL)
  {
    int current = reset ? 0 : this->Grid.size();
    if(current == iin)
    {
      return;
    }

    this->Grid.resize(iin);

    this->computeValidRange();

    if(iin > current)
    {
      for(int k = current; k < iin; k++)
      {
        if(k == 0)
        {
          this->Grid[k].resize(1);
          this->Grid[k][0].setCell(XX);
        }
        else
        {
          // for each layer, we need 6*Layer cells
          int cols = 6*k;
          this->Grid[k].resize(cols);
          int start, end;
          getValidRange(k, start, end);
          for(int c = 0; c < cols; c++)
          {
            if(start <= c && c <= end)
            {
              this->Grid[k][c].setCell(XX);
            }
            else
            {
              this->Grid[k][c].setCell(invalid);
            }
          }
        }
      }
    }
  }
}

bool Lattice::getValidRange(int layer, int & start, int & end) const
{
  if(this->enGeometryType == HEXAGONAL)
  {
    start = this->validRange[layer].first;
    end = this->validRange[layer].second;
    return true;
  }
  return false;
}

void Lattice::computeValidRange()
{
  if(this->enGeometryType == HEXAGONAL)
  {
    this->validRange.resize(Grid.size());
    for( int layer = 0; layer < Grid.size(); ++layer)
    {
      this->validRange[layer].first = 0;
      this->validRange[layer].second = 6*layer-1;
      if(subType != 0 && !(subType & ANGLE_360))
      {
        this->validRange[layer].first = (subType & FLAT)?(layer):(layer-(layer)/2);
        this->validRange[layer].second = ((subType & FLAT)?(layer+1):
                                                           (((layer+1)-(layer+2)%2)))+this->validRange[layer].first-1;
        if(subType & ANGLE_30)
        {
          this->validRange[layer].first = 2*layer - layer/2;
          this->validRange[layer].second = (layer%2 ? (layer+1)/2 :(layer+2)/2) + this->validRange[layer].first - 1;
        }
      }
    }
  }
}

std::pair<int, int> Lattice::GetDimensions() const
{
  if(this->Grid.size() == 0) return std::make_pair(0,0);
  if(this->enGeometryType == RECTILINEAR)
  {
    return std::make_pair(static_cast<int>(this->Grid.size()),
                          static_cast<int>(this->Grid[0].size()));
  }
  else
  {
    return std::make_pair(static_cast<int>(this->Grid.size()), 6);
  }
}

void Lattice::SetCell(int i, int j, const std::string &name,
                      const QColor& color, bool valid)
{
  LatticeCell * cr = this->getCell(name);
  cr->color = color;
  cr->valid = valid;
  this->Grid[i][j].setCell(cr);
}

void Lattice::SetCell(int i, int j, const std::string &name)
{
  LatticeCell * cr = this->getCell(name);
  this->Grid[i][j].setCell(cr);
}

void Lattice::SetCellColor(const std::string &name, const QColor& color)
{
  LatticeCell * cr = this->getCell(name);
  cr->color = color;
}

void Lattice::setAsInvalid(int i, int j)
{
  LatticeCell * cr = this->getCell("");
  cr->setInvalid();
  this->Grid[i][j].setCell(cr);
}

Lattice::LatticeCell Lattice::GetCell(int i, int j) const
{
  return *(this->Grid[i][j].getCell());
}

Lattice::LatticeCell Lattice::GetCell(int i) const
{
  // Convert to j,k
  int s = static_cast<int>(this->Grid.size());
  // For Hex type, This is different
  if(this->enGeometryType == HEXAGONAL)
  {
    int j = 0, k = 0;
    int totalNum = 0, preTotal;
    for(int layer = 0; layer < s; layer++)
    {
      preTotal = totalNum;
      // totalNum += (6*layer);
      totalNum = 1 + 3*layer*(layer+1);
      if(i < totalNum)
      {
        j = layer;
        k = i-preTotal;
        break;
      }
    }
    return this->GetCell(j,k);
  }
  else
  {
    int size = static_cast<int>(this->Grid[0].size());
    int j = i / size;
    int k = i - (j*size);
    assert(j < static_cast<int>(this->Grid.size()));
    assert(k < static_cast<int>(this->Grid[j].size()));

    return this->GetCell(j,k);
  }
}

void Lattice::ClearCell(int i, int j)
{
  LatticeCell * cr = this->getCell("xx");
  this->Grid[i][j].setCell(cr);
}

bool Lattice::ClearCell(const std::string &label)
{
  bool r = false;
  for(size_t i = 0; i < this->Grid.size(); i++)
  {
    for(size_t j = 0; j < this->Grid[i].size(); j++)
    {
      if(this->GetCell(i, j).label == label)
      {
        r = true;
        this->ClearCell(i, j);
      }
    }
  }
  return r;
}

bool Lattice::replaceLabel(const std::string &oldL, const std::string &newL)
{
  std::map<std::string, LatticeCell *>::iterator iter = LabelToCell.find(oldL);
  if(iter == LabelToCell.end() || iter->second->getCount() == 0)
  {
    return false;
  }
  std::map<std::string, LatticeCell *>::iterator newI = LabelToCell.find(newL);
  if(newI == LabelToCell.end()) //easy
  {
    iter->second->label = newL;
    LabelToCell[newL] = iter->second;
    LabelToCell.erase(iter);
    return true;
  }
  //harder
  for(size_t i = 0; i < this->Grid.size(); i++)
  {
    for(size_t j = 0; j < this->Grid[i].size(); j++)
    {
      if(this->Grid[i][j].getCell() == iter->second)
      {
        this->Grid[i][j].setCell(newI->second);
      }
    }
  }
  return true;
}

enumNucPartsType Lattice::GetType() const
{ return CMBNUC_ASSY_LATTICE;}

int Lattice::GetNumberOfCells()
{
  if(this->Grid.size() == 0)
  {
    return 0;
  }
  if(this->enGeometryType == HEXAGONAL)
  {
    int tmp = static_cast<int>(this->Grid.size());
    return 1 + 3*tmp*(tmp - 1);
  }
  else
  {
    return static_cast<int>(this->Grid.size()*this->Grid[0].size());
  }
}

void Lattice::SetGeometryType(enumGeometryType type)
{
  if(this->enGeometryType == type) return;
  this->enGeometryType = type;
  if(type == RECTILINEAR) this->SetDimensions(4, 4);
  else this->SetDimensions(1, 1, true);
}

enumGeometryType Lattice::GetGeometryType()
{ return this->enGeometryType; }

void Lattice::SetGeometrySubType(int type)
{subType = type;}

int Lattice::GetGeometrySubType() const
{ return subType; }

bool Lattice::labelUsed(const std::string &l) const
{
  std::map<std::string, LatticeCell *>::const_iterator iter = LabelToCell.find(l);
  if(iter == LabelToCell.end())
  {
    return false;
  }
  return iter->second->getCount() != 0;
}

Lattice::LatticeCell * Lattice::getCell(std::string label)
{
  LatticeCell * result = NULL;
  std::map<std::string, LatticeCell *>::iterator iter = LabelToCell.find(label);
  if(iter == LabelToCell.end())
  {
    result = new LatticeCell;
    result->label = label;
    LabelToCell[label] = result;
  }
  else
  {
    result = iter->second;
  }
  return result;
}

Lattice::CellDrawMode Lattice::getDrawMode(int index, int layer) const
{
  if(this->enGeometryType == RECTILINEAR) return Lattice::RECT;
  int start, end;
  this->getValidRange(layer, start, end);
  if(layer == 0)
  {
    if(this->subType & ANGLE_360)
    {
      return this->getFullCellMode();
    }
    else if(this->subType & ANGLE_60 && this->subType & FLAT)
    {
      return Lattice::HEX_SIXTH_FLAT_CENTER;
    }
    else if(this->subType & ANGLE_60 && this->subType & VERTEX)
    {
      return Lattice::HEX_SIXTH_VERT_CENTER;
    }
    else if(this->subType & ANGLE_30)
    {
      return Lattice::HEX_TWELFTH_CENTER;
    }
  }
  else if(this->subType & ANGLE_360)
  {
    return FullCellMode;
  }
  else if( this->subType & ANGLE_60 && this->subType & FLAT )
  {
    if(index == start)
    {
      return Lattice::HEX_SIXTH_FLAT_TOP;
    }
    else if(index == end)
    {
      return Lattice::HEX_SIXTH_FLAT_BOTTOM;
    }
    else
    {
      return Lattice::HEX_FULL;
    }
  }
  else if( this->subType & ANGLE_60 && this->subType & VERTEX )
  {
    if(index == start && layer % 2 == 0) return Lattice::HEX_SIXTH_VERT_TOP;
    else if(index == end && layer % 2 == 0) return Lattice::HEX_SIXTH_VERT_BOTTOM;
    return Lattice::HEX_FULL_30;
  }
  else if(this->subType & ANGLE_30)
  {
    if(index == end) return Lattice::HEX_TWELFTH_BOTTOM;
    else if(index == start && layer % 2 == 0) return Lattice::HEX_TWELFTH_TOP;
  }
  return Lattice::HEX_FULL;
}

std::string Lattice::generate_string(std::string in, CellDrawMode mode)
{
  switch(mode)
  {
    case RECT:
    case HEX_FULL:
    case HEX_FULL_30:
      return in;
    case HEX_SIXTH_FLAT_BOTTOM:
    case HEX_SIXTH_VERT_BOTTOM:
    case HEX_TWELFTH_BOTTOM:
      return in+"_bottom";
    case HEX_SIXTH_FLAT_CENTER:
    case HEX_SIXTH_VERT_CENTER:
    case HEX_TWELFTH_CENTER:
      return in + "_center";
    case HEX_SIXTH_FLAT_TOP:
    case HEX_SIXTH_VERT_TOP:
    case HEX_TWELFTH_TOP:
      return in + "_top";
  }
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// boost
#include <boost/version.hpp>
#include <mapnik/json/geojson_generator.hpp>

#if BOOST_VERSION >= 104700

#include <mapnik/json/feature_generator_grammar.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <boost/spirit/include/karma.hpp>

namespace  mapnik { namespace json {

    feature_generator::feature_generator()
        : grammar_(new feature_generator_grammar<sink_type>()) {}

    feature_generator::~feature_generator() {}

    bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
    {
        sink_type sink(geojson);
        return karma::generate(sink, *grammar_,f);
    }

    geometry_generator::geometry_generator()
        : grammar_(new multi_geometry_generator_grammar<sink_type>()) {}

    geometry_generator::~geometry_generator() {}

    bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
    {
        sink_type sink(geojson);
        return karma::generate(sink, *grammar_,g);
    }

    }}

#else

#include <string>
#include <sstream>
#include <exception>

namespace  mapnik { namespace json {

    bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
    {
        std::ostringstream s;
        s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000  << "." << BOOST_VERSION % 100;
        throw std::runtime_error("feature_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
        return false;
    }

    bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
    {
        std::ostringstream s;
        s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000  << "." << BOOST_VERSION % 100;
        throw std::runtime_error("geometry_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
        return false;
    }

    }}

#endif
<commit_msg>+ ident<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

// boost
#include <boost/version.hpp>
#include <mapnik/json/geojson_generator.hpp>

#if BOOST_VERSION >= 104700

#include <mapnik/json/feature_generator_grammar.hpp>
#include <mapnik/json/geometry_generator_grammar.hpp>
#include <boost/spirit/include/karma.hpp>

namespace  mapnik { namespace json {

feature_generator::feature_generator()
    : grammar_(new feature_generator_grammar<sink_type>()) {}

feature_generator::~feature_generator() {}

bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
{
    sink_type sink(geojson);
    return karma::generate(sink, *grammar_,f);
}

geometry_generator::geometry_generator()
    : grammar_(new multi_geometry_generator_grammar<sink_type>()) {}

geometry_generator::~geometry_generator() {}

bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
{
    sink_type sink(geojson);
    return karma::generate(sink, *grammar_,g);
}

}}

#else

#include <string>
#include <sstream>
#include <exception>

namespace  mapnik { namespace json {

bool feature_generator::generate(std::string & geojson, mapnik::Feature const& f)
{
    std::ostringstream s;
    s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000  << "." << BOOST_VERSION % 100;
    throw std::runtime_error("feature_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
    return false;
}

bool geometry_generator::generate(std::string & geojson, mapnik::geometry_container const& g)
{
    std::ostringstream s;
    s << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000  << "." << BOOST_VERSION % 100;
    throw std::runtime_error("geometry_generator::generate() requires at least boost 1.47 while your build was compiled against boost " + s.str());
    return false;
}

}}

#endif
<|endoftext|>


<commit_before>#include "headers/mainwindow.h"
#include "headers/cryptogame.h"
#include "ui_mainwindow.h"
#include "QPushButton"
#include <QLayoutItem>
#include <QMessageBox>
#include <QtConcurrent/QtConcurrent>
#include <QFuture>
#include "headers/buttonarray.h"
#include "headers/labelarray.h"
#include <QtWebKit>
#include <QUrl>

#include "iostream" //for debugging

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    connect(&threadCrack, SIGNAL(finished()), this, SLOT(update_crack_result()));
    connect(&threadFactor, SIGNAL(finished()), this, SLOT(update_factor_result()));
    connect(&threadCrackData, SIGNAL(finished()), this, SLOT(update_crack_graph()));
    connect(&threadFactorData, SIGNAL(finished()), this, SLOT(update_factor_graph()));
    ui->setupUi(this);

    QAction *act = new QAction(QString("Help"), this);

    connect(act, &QAction::triggered, this, &MainWindow::on_HELPBUTTONCLICKED);

    ui->menuBar->addAction(act);

}

MainWindow::~MainWindow()
{
    delete ui;

    if(threadCrack.isRunning()) {
        threadCrack.quit();
    }
    if(threadFactor.isRunning()) {
        threadFactor.quit();
    }

    if(factorAlg != NULL) {
        delete factorAlg;
    }
    if(hashAlg != NULL) {
        delete hashAlg;
    }

    if(fg != NULL) {
        delete fg;
    }
    if(cg != NULL) {
        delete cg;
    }
}

void MainWindow::on_pushButton_clicked()
{

    //Delete all buttons in the and labels in the gameGrid
   for(int i=0; i<ui->gameGrid->columnCount(); i++){
       for(int j = 0; j<ui->gameGrid->rowCount(); j++){

       QLayoutItem *button = ui->gameGrid->itemAtPosition(j,i);
       if(button){
           ui->gameGrid->removeItem(button);
          delete button->widget();
       }

        QLayoutItem *label = ui->gameGrid->itemAtPosition(j,i);
        if(label){
            ui->gameGrid->removeItem(label);

            delete label->widget();
        }

       }

    }

    agame = new cryptogame();
    QString q = QString::fromStdString(agame->getEncryptedMessage());
    //ui->label->setText(q);
    LabelArray *lptr = new LabelArray(q, ui->tabWidget);
    ButtonArray *buttonPtrs = new ButtonArray(q, ui->tabWidget, agame);
    int j = 0;
    int i = 0;
    int counter = 0;
    while(counter < q.length()){
        if(i >= 3 && q.at(counter) == ' '){
            j += 2;
            i = 0;
        } else {
        ui->gameGrid->addWidget(lptr->get(counter), j, i);
        ui->gameGrid->addWidget(buttonPtrs->get(counter), j+1, i);
        i++;
        }
        counter++;
    }

}

void MainWindow::on_pushButton_3_clicked()
{
    //Give a hint to the player
    QMessageBox hintMessage;
    hintMessage.setText(QString::fromStdString(agame->getHint()));
    hintMessage.exec();
}

void MainWindow::on_factorPrimesButton_clicked()
{
    //reset label text
    ui->resultLabel->setText(QString::fromStdString("Result:"));
    ui->timeLabel->setText(QString::fromStdString("Time: "));
    ui->resultLabel->repaint();
    ui->timeLabel->repaint();

    //set algorithm
    int algChoice = ui->factorAlgChooser->currentIndex();

    switch(algChoice) {
    case 0:{
        factorAlg = new BruteForceFactor();
        break;}
    case 1:{
        factorAlg = new QSFactor();
        std::cout<<"Quadratic sieve feature is in progress!"<<std::endl;
        break;}
    }

    mpz_class composite;
    string s = ui->compositeTextField->text().toStdString();
    composite.set_str(s, 10);

    threadFactor.setFactor(factorAlg, composite);
    threadFactor.work();

    ui->factorPrimesButton->setDisabled(true);
}

void MainWindow::update_factor_result() {

    long elapsed = threadFactor.getResult();
    Factor* pf = threadFactor.getFactor();

    string s = "Time: " + std::to_string(elapsed) + " ms";
    ui->timeLabel->setText(QString::fromStdString(s));

    s = "Result: " + pf->p1.get_str(10) + " * " + pf->p2.get_str(10);
    ui->resultLabel->setText(QString::fromStdString(s));

    ui->factorPrimesButton->setDisabled(false);
}

void MainWindow::on_random_composite_clicked()
{
    mpz_class composite, p, q;
    GeneratePrimes gp = GeneratePrimes();
    p = gp.readRandomPrime((char*)"primes.txt");
    q = gp.readRandomPrime((char*)"primes.txt");
    composite = p * q;
    string s = composite.get_str(10);
    ui->compositeTextField->setText(QString::fromStdString(s));
}

void MainWindow::on_hashButton_clicked()
{
    switch(ui->hashComboBox->currentIndex()) {
    case 0:
        hashAlg = new Md5();
        break;
    case 1:
        hashAlg = new Sha512();
        break;
    case 2:
        hashAlg = new Pbkdf2();
        break;
    }

    hashAlg->setPlaintext(ui->plaintextField->text());

    if(ui->saltField->text() != "") { //if not empty
        hashAlg->setSalt(ui->saltField->text());
    }
    hashAlg->compute();
    digest = hashAlg->getDigest();
    ui->digestField->setText(digest);

    //Perhaps make this an option?
    //hashAlg->salt = "";
}

void MainWindow::on_randomSaltButton_clicked()
{
    Hash h;
    h.generateSalt(16);
    ui->saltField->setText(h.getSalt());
}

void MainWindow::on_crackButton_clicked()
{
    //reset label text
    ui->crackTimeLabel->setText("Time: ");
    ui->crackTimeLabel->repaint();
    ui->crackedField->setText("");
    ui->crackedField->repaint();

    Crack* c = new Crack();
    if(hashAlg == NULL) {
    	return;
    }

    switch(ui->crackTabWidget->currentIndex()) {
    case 0:
        {int maxLength = ui->charCountSpinBox->text().toInt();
        c = new BruteForceCrack(hashAlg,bruteForceAlphabet(), maxLength);
        break;}

    case 1:
        {c = new DictionaryCrack(hashAlg, "../dictionary.txt");
        dictionaryOptions(c);
        break;}
    }

    c->setDigest(digest);

    threadCrack.setCrackType(c);
    threadCrack.work();

    ui->crackButton->setDisabled(true);
}

void MainWindow::update_crack_result() {

    long elapsed;
    bool success;

    elapsed = threadCrack.getResult();
    Crack* c = threadCrack.getCrack();
    success = c->getPlaintext().length();

    if(success) {
        ui->crackedField->setText(threadCrack.getCrack()->getPlaintext());
    } else {
        ui->crackedField->setText("\"Uncrackable!!\"");
    }

    string s = "Time: " + std::to_string(elapsed) + " ms";
    ui->crackTimeLabel->setText(QString::fromStdString(s));

    ui->crackButton->setDisabled(false);
}

std::string MainWindow::bruteForceAlphabet() {

    std::string alph = " ";//weird bug "fix"

    if(ui->customCheckBox->isChecked()) {
        return ui->alphabetField->text().toStdString();
    }
    if(ui->lettersCheckBox->isChecked()) {
        alph += "abcdefghijklmnopqrstuvwxyz";
    }
    if(ui->upCaseCheckBox->isChecked()) {
        alph += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    }
    if(ui->numbersCheckBox->isChecked()) {
        alph += "1234567890";
    }
    if(ui->symbolsCheckBox->isChecked()) {
        alph += "`~!@#$%^&*()_+-=,.<>/?'[]{}";
    }
    return alph;
}

void MainWindow::dictionaryOptions(Crack* d) {

    unsigned int numWords = ui->wordCountSpinBox->text().toInt();
    unsigned int appendedDigits = 0;
    if(ui->appendCheckBox->isChecked()) {
        appendedDigits = ui->digitCountSpinBox->text().toInt();
    }
    unsigned int prependedDigits = 0;
    if(ui->prependCheckBox->isChecked()) {
        prependedDigits = ui->digitCountSpinBox->text().toInt();
    }

    bool cap = ui->capCheckBox->isChecked();
    bool symbols = ui->dictSymbolsCheckBox->isChecked();
    bool complete = ui->completeModeCheckBox->isChecked();

    d->setOptions(numWords,appendedDigits,prependedDigits,symbols,cap,complete);
}

void MainWindow::on_drawFactoring_clicked()
{
    //set algorithm
    int algChoice = ui->factorAlgChooser->currentIndex();

    switch(algChoice) {
    case 0:
        factorAlg = new BruteForceFactor();
        break;
    case 1:
        //Quadratic sieve here
        std::cout<<"Quadratic sieve feature is in progress!"<<std::endl;
        return;
        break;
    }

    //generate data
    int beginDigits = ui->startDigitsSpinBox->text().toInt();
    unsigned int count = ui->dataPointsSpinBox->text().toInt();

    threadFactorData.factorData(beginDigits, count, factorAlg);

    ui->drawFactoring->setDisabled(true);
}

void MainWindow::update_factor_graph() {

    factorDataPoints = threadFactorData.getResult();

    //draw points
    fg = new GraphWindow(ui->factoringGraphicsView, factorDataPoints);
    fg->vSize = 600;
    fg->hSize = 600;

    if(ui->factorLogScaleCheckBox->isChecked()) {
        fg->logScaleDraw();
    } else {
        fg->draw();
    }
    fg->addLabels("Milliseconds", "Number of digits");

    fg->view->show();

    ui->drawFactoring->setDisabled(false);
}

void MainWindow::on_plotCrackButton_clicked()
{
    //grab hashing and cracking algorithms

    switch(ui->hashComboBox->currentIndex()) {
    case 0:
        hashAlg = new Md5();
        break;
    case 1:
        hashAlg = new Sha512();
        break;
    case 2:
        hashAlg = new Pbkdf2();
        break;
    }

    Crack* c = new Crack();
    if(hashAlg == NULL) {
        return;
    }

    switch(ui->crackTabWidget->currentIndex()) {
    case 0:
        {int maxLength = ui->charCountSpinBox->text().toInt();
        c = new BruteForceCrack(hashAlg,bruteForceAlphabet(), maxLength);
        break;}

    case 1:
        {c = new DictionaryCrack(hashAlg, "../dictionary.txt");
        break;}
    }

    //generate data
    int beginChars = ui->charCountSpinBox_2->text().toInt();
    int count = ui->crackPointCountSpinBox->text().toInt();

    threadCrackData.crackData(beginChars, count, hashAlg, c);

    ui->plotCrackButton->setEnabled(false);
}

void MainWindow::update_crack_graph() {

    crackDataPoints = threadCrackData.getResult();

    //begin graphing
    cg = new GraphWindow(ui->crackGraphicsView, crackDataPoints);
    cg->vSize = 600;
    cg->hSize = 600;

    if(ui->hashLogScaleCheckBox->isChecked()) {
        cg->logScaleDraw();
    } else {
        cg->draw();
    }
    cg->addLabels("Milliseconds", "Number of characters");

    cg->view->show();

    ui->plotCrackButton->setEnabled(true);
}

void MainWindow::on_hashLogScaleCheckBox_clicked()
{
    if(cg == NULL) {
        std::cout << "graphwindow object not initialized. No action to take." << std::endl;
        return;
    }
    if(crackDataPoints.size() == 0) {
        std::cout << "No points to graph." << std::endl;
        return;
    }

    cg = new GraphWindow(ui->crackGraphicsView, crackDataPoints);
    cg->vSize = 600;
    cg->hSize = 600;

    if(ui->hashLogScaleCheckBox->isChecked()) {
        cg->logScaleDraw();
    } else {
        cg->draw();
    }
    cg->addLabels("Milliseconds", "Number of characters");

    cg->view->show();
}

void MainWindow::on_factorLogScaleCheckBox_clicked()
{
    if(fg == NULL) {
        std::cout << "graphwindow object not initialized. No action to take." << std::endl;
        return;
    }
    if(factorDataPoints.size() == 0) {
        std::cout << "No points to graph." << std::endl;
        return;
    }

    fg = new GraphWindow(ui->factoringGraphicsView, factorDataPoints);
    fg->vSize = 600;
    fg->hSize = 600;

    if(ui->factorLogScaleCheckBox->isChecked()) {
        fg->logScaleDraw();
    } else {
        fg->draw();
    }
    fg->addLabels("Milliseconds", "Number of characters");

    fg->view->show();
}

void MainWindow::on_cancelCrackButton_clicked()
{
    threadCrack.stop();
}

void MainWindow::on_stopFactorPushButton_clicked()
{
    threadFactor.stop();
}

void MainWindow::on_HELPBUTTONCLICKED(){
    bool hi = QDesktopServices::openUrl(QUrl("https://www.google.com"));
}
<commit_msg>Changed the address to our herokuapp<commit_after>#include "headers/mainwindow.h"
#include "headers/cryptogame.h"
#include "ui_mainwindow.h"
#include "QPushButton"
#include <QLayoutItem>
#include <QMessageBox>
#include <QtConcurrent/QtConcurrent>
#include <QFuture>
#include "headers/buttonarray.h"
#include "headers/labelarray.h"
#include <QtWebKit>
#include <QUrl>

#include "iostream" //for debugging

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    connect(&threadCrack, SIGNAL(finished()), this, SLOT(update_crack_result()));
    connect(&threadFactor, SIGNAL(finished()), this, SLOT(update_factor_result()));
    connect(&threadCrackData, SIGNAL(finished()), this, SLOT(update_crack_graph()));
    connect(&threadFactorData, SIGNAL(finished()), this, SLOT(update_factor_graph()));
    ui->setupUi(this);

    QAction *act = new QAction(QString("Help"), this);

    connect(act, &QAction::triggered, this, &MainWindow::on_HELPBUTTONCLICKED);

    ui->menuBar->addAction(act);

}

MainWindow::~MainWindow()
{
    delete ui;

    if(threadCrack.isRunning()) {
        threadCrack.quit();
    }
    if(threadFactor.isRunning()) {
        threadFactor.quit();
    }

    if(factorAlg != NULL) {
        delete factorAlg;
    }
    if(hashAlg != NULL) {
        delete hashAlg;
    }

    if(fg != NULL) {
        delete fg;
    }
    if(cg != NULL) {
        delete cg;
    }
}

void MainWindow::on_pushButton_clicked()
{

    //Delete all buttons in the and labels in the gameGrid
   for(int i=0; i<ui->gameGrid->columnCount(); i++){
       for(int j = 0; j<ui->gameGrid->rowCount(); j++){

       QLayoutItem *button = ui->gameGrid->itemAtPosition(j,i);
       if(button){
           ui->gameGrid->removeItem(button);
          delete button->widget();
       }

        QLayoutItem *label = ui->gameGrid->itemAtPosition(j,i);
        if(label){
            ui->gameGrid->removeItem(label);

            delete label->widget();
        }

       }

    }

    agame = new cryptogame();
    QString q = QString::fromStdString(agame->getEncryptedMessage());
    //ui->label->setText(q);
    LabelArray *lptr = new LabelArray(q, ui->tabWidget);
    ButtonArray *buttonPtrs = new ButtonArray(q, ui->tabWidget, agame);
    int j = 0;
    int i = 0;
    int counter = 0;
    while(counter < q.length()){
        if(i >= 3 && q.at(counter) == ' '){
            j += 2;
            i = 0;
        } else {
        ui->gameGrid->addWidget(lptr->get(counter), j, i);
        ui->gameGrid->addWidget(buttonPtrs->get(counter), j+1, i);
        i++;
        }
        counter++;
    }

}

void MainWindow::on_pushButton_3_clicked()
{
    //Give a hint to the player
    QMessageBox hintMessage;
    hintMessage.setText(QString::fromStdString(agame->getHint()));
    hintMessage.exec();
}

void MainWindow::on_factorPrimesButton_clicked()
{
    //reset label text
    ui->resultLabel->setText(QString::fromStdString("Result:"));
    ui->timeLabel->setText(QString::fromStdString("Time: "));
    ui->resultLabel->repaint();
    ui->timeLabel->repaint();

    //set algorithm
    int algChoice = ui->factorAlgChooser->currentIndex();

    switch(algChoice) {
    case 0:{
        factorAlg = new BruteForceFactor();
        break;}
    case 1:{
        factorAlg = new QSFactor();
        std::cout<<"Quadratic sieve feature is in progress!"<<std::endl;
        break;}
    }

    mpz_class composite;
    string s = ui->compositeTextField->text().toStdString();
    composite.set_str(s, 10);

    threadFactor.setFactor(factorAlg, composite);
    threadFactor.work();

    ui->factorPrimesButton->setDisabled(true);
}

void MainWindow::update_factor_result() {

    long elapsed = threadFactor.getResult();
    Factor* pf = threadFactor.getFactor();

    string s = "Time: " + std::to_string(elapsed) + " ms";
    ui->timeLabel->setText(QString::fromStdString(s));

    s = "Result: " + pf->p1.get_str(10) + " * " + pf->p2.get_str(10);
    ui->resultLabel->setText(QString::fromStdString(s));

    ui->factorPrimesButton->setDisabled(false);
}

void MainWindow::on_random_composite_clicked()
{
    mpz_class composite, p, q;
    GeneratePrimes gp = GeneratePrimes();
    p = gp.readRandomPrime((char*)"primes.txt");
    q = gp.readRandomPrime((char*)"primes.txt");
    composite = p * q;
    string s = composite.get_str(10);
    ui->compositeTextField->setText(QString::fromStdString(s));
}

void MainWindow::on_hashButton_clicked()
{
    switch(ui->hashComboBox->currentIndex()) {
    case 0:
        hashAlg = new Md5();
        break;
    case 1:
        hashAlg = new Sha512();
        break;
    case 2:
        hashAlg = new Pbkdf2();
        break;
    }

    hashAlg->setPlaintext(ui->plaintextField->text());

    if(ui->saltField->text() != "") { //if not empty
        hashAlg->setSalt(ui->saltField->text());
    }
    hashAlg->compute();
    digest = hashAlg->getDigest();
    ui->digestField->setText(digest);

    //Perhaps make this an option?
    //hashAlg->salt = "";
}

void MainWindow::on_randomSaltButton_clicked()
{
    Hash h;
    h.generateSalt(16);
    ui->saltField->setText(h.getSalt());
}

void MainWindow::on_crackButton_clicked()
{
    //reset label text
    ui->crackTimeLabel->setText("Time: ");
    ui->crackTimeLabel->repaint();
    ui->crackedField->setText("");
    ui->crackedField->repaint();

    Crack* c = new Crack();
    if(hashAlg == NULL) {
    	return;
    }

    switch(ui->crackTabWidget->currentIndex()) {
    case 0:
        {int maxLength = ui->charCountSpinBox->text().toInt();
        c = new BruteForceCrack(hashAlg,bruteForceAlphabet(), maxLength);
        break;}

    case 1:
        {c = new DictionaryCrack(hashAlg, "../dictionary.txt");
        dictionaryOptions(c);
        break;}
    }

    c->setDigest(digest);

    threadCrack.setCrackType(c);
    threadCrack.work();

    ui->crackButton->setDisabled(true);
}

void MainWindow::update_crack_result() {

    long elapsed;
    bool success;

    elapsed = threadCrack.getResult();
    Crack* c = threadCrack.getCrack();
    success = c->getPlaintext().length();

    if(success) {
        ui->crackedField->setText(threadCrack.getCrack()->getPlaintext());
    } else {
        ui->crackedField->setText("\"Uncrackable!!\"");
    }

    string s = "Time: " + std::to_string(elapsed) + " ms";
    ui->crackTimeLabel->setText(QString::fromStdString(s));

    ui->crackButton->setDisabled(false);
}

std::string MainWindow::bruteForceAlphabet() {

    std::string alph = " ";//weird bug "fix"

    if(ui->customCheckBox->isChecked()) {
        return ui->alphabetField->text().toStdString();
    }
    if(ui->lettersCheckBox->isChecked()) {
        alph += "abcdefghijklmnopqrstuvwxyz";
    }
    if(ui->upCaseCheckBox->isChecked()) {
        alph += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    }
    if(ui->numbersCheckBox->isChecked()) {
        alph += "1234567890";
    }
    if(ui->symbolsCheckBox->isChecked()) {
        alph += "`~!@#$%^&*()_+-=,.<>/?'[]{}";
    }
    return alph;
}

void MainWindow::dictionaryOptions(Crack* d) {

    unsigned int numWords = ui->wordCountSpinBox->text().toInt();
    unsigned int appendedDigits = 0;
    if(ui->appendCheckBox->isChecked()) {
        appendedDigits = ui->digitCountSpinBox->text().toInt();
    }
    unsigned int prependedDigits = 0;
    if(ui->prependCheckBox->isChecked()) {
        prependedDigits = ui->digitCountSpinBox->text().toInt();
    }

    bool cap = ui->capCheckBox->isChecked();
    bool symbols = ui->dictSymbolsCheckBox->isChecked();
    bool complete = ui->completeModeCheckBox->isChecked();

    d->setOptions(numWords,appendedDigits,prependedDigits,symbols,cap,complete);
}

void MainWindow::on_drawFactoring_clicked()
{
    //set algorithm
    int algChoice = ui->factorAlgChooser->currentIndex();

    switch(algChoice) {
    case 0:
        factorAlg = new BruteForceFactor();
        break;
    case 1:
        //Quadratic sieve here
        std::cout<<"Quadratic sieve feature is in progress!"<<std::endl;
        return;
        break;
    }

    //generate data
    int beginDigits = ui->startDigitsSpinBox->text().toInt();
    unsigned int count = ui->dataPointsSpinBox->text().toInt();

    threadFactorData.factorData(beginDigits, count, factorAlg);

    ui->drawFactoring->setDisabled(true);
}

void MainWindow::update_factor_graph() {

    factorDataPoints = threadFactorData.getResult();

    //draw points
    fg = new GraphWindow(ui->factoringGraphicsView, factorDataPoints);
    fg->vSize = 600;
    fg->hSize = 600;

    if(ui->factorLogScaleCheckBox->isChecked()) {
        fg->logScaleDraw();
    } else {
        fg->draw();
    }
    fg->addLabels("Milliseconds", "Number of digits");

    fg->view->show();

    ui->drawFactoring->setDisabled(false);
}

void MainWindow::on_plotCrackButton_clicked()
{
    //grab hashing and cracking algorithms

    switch(ui->hashComboBox->currentIndex()) {
    case 0:
        hashAlg = new Md5();
        break;
    case 1:
        hashAlg = new Sha512();
        break;
    case 2:
        hashAlg = new Pbkdf2();
        break;
    }

    Crack* c = new Crack();
    if(hashAlg == NULL) {
        return;
    }

    switch(ui->crackTabWidget->currentIndex()) {
    case 0:
        {int maxLength = ui->charCountSpinBox->text().toInt();
        c = new BruteForceCrack(hashAlg,bruteForceAlphabet(), maxLength);
        break;}

    case 1:
        {c = new DictionaryCrack(hashAlg, "../dictionary.txt");
        break;}
    }

    //generate data
    int beginChars = ui->charCountSpinBox_2->text().toInt();
    int count = ui->crackPointCountSpinBox->text().toInt();

    threadCrackData.crackData(beginChars, count, hashAlg, c);

    ui->plotCrackButton->setEnabled(false);
}

void MainWindow::update_crack_graph() {

    crackDataPoints = threadCrackData.getResult();

    //begin graphing
    cg = new GraphWindow(ui->crackGraphicsView, crackDataPoints);
    cg->vSize = 600;
    cg->hSize = 600;

    if(ui->hashLogScaleCheckBox->isChecked()) {
        cg->logScaleDraw();
    } else {
        cg->draw();
    }
    cg->addLabels("Milliseconds", "Number of characters");

    cg->view->show();

    ui->plotCrackButton->setEnabled(true);
}

void MainWindow::on_hashLogScaleCheckBox_clicked()
{
    if(cg == NULL) {
        std::cout << "graphwindow object not initialized. No action to take." << std::endl;
        return;
    }
    if(crackDataPoints.size() == 0) {
        std::cout << "No points to graph." << std::endl;
        return;
    }

    cg = new GraphWindow(ui->crackGraphicsView, crackDataPoints);
    cg->vSize = 600;
    cg->hSize = 600;

    if(ui->hashLogScaleCheckBox->isChecked()) {
        cg->logScaleDraw();
    } else {
        cg->draw();
    }
    cg->addLabels("Milliseconds", "Number of characters");

    cg->view->show();
}

void MainWindow::on_factorLogScaleCheckBox_clicked()
{
    if(fg == NULL) {
        std::cout << "graphwindow object not initialized. No action to take." << std::endl;
        return;
    }
    if(factorDataPoints.size() == 0) {
        std::cout << "No points to graph." << std::endl;
        return;
    }

    fg = new GraphWindow(ui->factoringGraphicsView, factorDataPoints);
    fg->vSize = 600;
    fg->hSize = 600;

    if(ui->factorLogScaleCheckBox->isChecked()) {
        fg->logScaleDraw();
    } else {
        fg->draw();
    }
    fg->addLabels("Milliseconds", "Number of characters");

    fg->view->show();
}

void MainWindow::on_cancelCrackButton_clicked()
{
    threadCrack.stop();
}

void MainWindow::on_stopFactorPushButton_clicked()
{
    threadFactor.stop();
}

void MainWindow::on_HELPBUTTONCLICKED(){
    bool hi = QDesktopServices::openUrl(QUrl("https://cryptowiki.herokuapp.com/"));
}
<|endoftext|>


<commit_before>#include "generic.h"

generic_device::generic_device(std::vector<gen_source_event>& inevents, int fd, bool watch, slot_manager* slot_man, device_manager* manager, input_source::devtype type) : input_source(slot_man, manager, type) {
  this->fd = fd;
  for (int i = 0; i < inevents.size(); i++) {
    source_event ev;
    input_absinfo     abs;
    memset(&abs, 0, sizeof(abs));
    ev.id = i;
    ev.name = inevents.at(i).name.c_str();
    ev.descr = inevents.at(i).descr.c_str();
    ev.type = inevents.at(i).type;
    ev.value = 0;
    ev.trans = nullptr;
    register_event(ev);

    int type = EV_KEY;
    if (ev.type == DEV_AXIS) type = EV_ABS;
    if (ev.type == DEV_REL)  type = EV_REL;

    evcode code(type, inevents.at(i).id);
    if (ev.type == DEV_AXIS) {
      if (ioctl(fd, EVIOCGABS(inevents.at(i).id), &abs)) {
        perror("evdev EVIOCGABS ioctl");
      }
    }
    decodedevent decoded(i, abs);
    eventcodes.insert(std::pair<evcode, decodedevent>(code, decoded));
  }

  if (watch) watch_file(fd, &fd);
}

generic_device::~generic_device() {
  if (node) udev_device_unref(node);
  free(nameptr);
}

int generic_device::set_player(int player_num) {};

void generic_device::list_events(cat_list& list) {
  struct category cat;
  struct name_descr info;

  cat.name = "Generic";
  for (int i = 0; i < events.size(); i++) {
    info.name = events[i].name;
    info.descr = events[i].descr;
    info.data = events[i].type;
    cat.entries.push_back(info);
  }

  list.push_back(cat);
  cat.entries.clear();
}

void generic_device::list_options(name_list& list) {};

void generic_device::update_option(const char* opname, const char* value) {};

enum entry_type generic_device::entry_type(const char* name) {
  auto alias = aliases.find(std::string(name));
  if (alias != aliases.end())
    name = alias->second.c_str();
  for (auto ev : events) {
    if (!strcmp(ev.name, name)) return ev.type;
  }
  return NO_ENTRY;
}

void generic_device::process(void* tag) {
  struct input_event ev;
  int file = fd;
  if (pipe_read >= 0 && tag == &pipe_read) {
    file = pipe_read;
  };
  int ret = read(file, &ev, sizeof(ev));
  if (ret > 0) {
    if (ev.type == EV_SYN && out_dev) {
      out_dev->take_event(ev);
      return;
    }
    evcode code(ev.type, ev.code);
    auto it = eventcodes.find(code);
    if (it == eventcodes.end()) return;
    decodedevent decoded = it->second;
    int id = decoded.first;
    if (ev.type == EV_KEY) {
      send_value(id, ev.value);
    }
    if (ev.type == EV_ABS) {
      //do some ABS rescaling.
      //currently ignoring old deadzone ("flat")
      input_absinfo info = decoded.second;
      int value = ev.value;
      int oldscale = info.maximum - info.minimum;
      if (oldscale == 0) {
        send_value(id, value);
        return;
      }
      int newscale = 2 * ABS_RANGE;
      long long int scaledvalue = -ABS_RANGE + (value - info.minimum) * newscale / oldscale;
      send_value(id, scaledvalue);
    }
  }
}

int generic_device::get_pipe() {
  if (pipe_write >= 0) return pipe_write;
  int internal[2];
  pipe(internal);
  watch_file(internal[0], &pipe_read);
  pipe_write = internal[1];
  pipe_read = internal[0];

  return pipe_write;
}

<commit_msg>hotfix to avoid some gendev overflow<commit_after>#include "generic.h"

generic_device::generic_device(std::vector<gen_source_event>& inevents, int fd, bool watch, slot_manager* slot_man, device_manager* manager, input_source::devtype type) : input_source(slot_man, manager, type) {
  this->fd = fd;
  for (int i = 0; i < inevents.size(); i++) {
    source_event ev;
    input_absinfo     abs;
    memset(&abs, 0, sizeof(abs));
    ev.id = i;
    ev.name = inevents.at(i).name.c_str();
    ev.descr = inevents.at(i).descr.c_str();
    ev.type = inevents.at(i).type;
    ev.value = 0;
    ev.trans = nullptr;
    register_event(ev);

    int type = EV_KEY;
    if (ev.type == DEV_AXIS) type = EV_ABS;
    if (ev.type == DEV_REL)  type = EV_REL;

    evcode code(type, inevents.at(i).id);
    if (ev.type == DEV_AXIS) {
      if (ioctl(fd, EVIOCGABS(inevents.at(i).id), &abs)) {
        perror("evdev EVIOCGABS ioctl");
      }
    }
    decodedevent decoded(i, abs);
    eventcodes.insert(std::pair<evcode, decodedevent>(code, decoded));
  }

  if (watch) watch_file(fd, &fd);
}

generic_device::~generic_device() {
  if (node) udev_device_unref(node);
  free(nameptr);
}

int generic_device::set_player(int player_num) {};

void generic_device::list_events(cat_list& list) {
  struct category cat;
  struct name_descr info;

  cat.name = "Generic";
  for (int i = 0; i < events.size(); i++) {
    info.name = events[i].name;
    info.descr = events[i].descr;
    info.data = events[i].type;
    cat.entries.push_back(info);
  }

  list.push_back(cat);
  cat.entries.clear();
}

void generic_device::list_options(name_list& list) {};

void generic_device::update_option(const char* opname, const char* value) {};

enum entry_type generic_device::entry_type(const char* name) {
  auto alias = aliases.find(std::string(name));
  if (alias != aliases.end())
    name = alias->second.c_str();
  for (auto ev : events) {
    if (!strcmp(ev.name, name)) return ev.type;
  }
  return NO_ENTRY;
}

void generic_device::process(void* tag) {
  struct input_event ev;
  int file = fd;
  if (pipe_read >= 0 && tag == &pipe_read) {
    file = pipe_read;
  };
  int ret = read(file, &ev, sizeof(ev));
  if (ret > 0) {
    if (ev.type == EV_SYN && out_dev) {
      out_dev->take_event(ev);
      return;
    }
    evcode code(ev.type, ev.code);
    auto it = eventcodes.find(code);
    if (it == eventcodes.end()) return;
    decodedevent decoded = it->second;
    int id = decoded.first;
    if (ev.type == EV_KEY) {
      send_value(id, ev.value);
    }
    if (ev.type == EV_ABS) {
      //do some ABS rescaling.
      //currently ignoring old deadzone ("flat")
      input_absinfo info = decoded.second;
      int value = ev.value;
      long long int oldscale = info.maximum - info.minimum;
      if (oldscale == 0) {
        send_value(id, value);
        return;
      }
      long long int newscale = 2 * ABS_RANGE;
      long long int scaledvalue = -ABS_RANGE + (value - info.minimum) * newscale / oldscale;
      send_value(id, scaledvalue);
    }
  }
}

int generic_device::get_pipe() {
  if (pipe_write >= 0) return pipe_write;
  int internal[2];
  pipe(internal);
  watch_file(internal[0], &pipe_read);
  pipe_write = internal[1];
  pipe_read = internal[0];

  return pipe_write;
}

<|endoftext|>


<commit_before>/*
* GCM Mode Encryption
* (C) 2013,2015 Jack Lloyd
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/gcm.h>
#include <botan/ghash.h>
#include <botan/block_cipher.h>
#include <botan/ctr.h>

namespace Botan {

/*
* GCM_Mode Constructor
*/
GCM_Mode::GCM_Mode(BlockCipher* cipher, size_t tag_size) :
   m_tag_size(tag_size),
   m_cipher_name(cipher->name())
   {
   if(cipher->block_size() != GCM_BS)
      throw Invalid_Argument("Invalid block cipher for GCM");

   m_ghash.reset(new GHASH);

   m_ctr.reset(new CTR_BE(cipher, 4)); // CTR_BE takes ownership of cipher

   /* We allow any of the values 128, 120, 112, 104, or 96 bits as a tag size */
   /* 64 bit tag is still supported but deprecated and will be removed in the future */
   if(m_tag_size != 8 && (m_tag_size < 12 || m_tag_size > 16))
      throw Invalid_Argument(name() + ": Bad tag size " + std::to_string(m_tag_size));
   }

GCM_Mode::~GCM_Mode() { /* for unique_ptr */ }

void GCM_Mode::clear()
   {
   m_ctr->clear();
   m_ghash->clear();
   reset();
   }

void GCM_Mode::reset()
   {
   m_ghash->reset();
   }

std::string GCM_Mode::name() const
   {
   return (m_cipher_name + "/GCM(" + std::to_string(tag_size()) + ")");
   }

std::string GCM_Mode::provider() const
   {
   return m_ghash->provider();
   }

size_t GCM_Mode::update_granularity() const
   {
   return GCM_BS * std::max<size_t>(2, BOTAN_BLOCK_CIPHER_PAR_MULT);
   }

bool GCM_Mode::valid_nonce_length(size_t len) const
   {
   // GCM does not support empty nonces
   return (len > 0);
   }

Key_Length_Specification GCM_Mode::key_spec() const
   {
   return m_ctr->key_spec();
   }

void GCM_Mode::key_schedule(const uint8_t key[], size_t keylen)
   {
   m_ctr->set_key(key, keylen);

   const std::vector<uint8_t> zeros(GCM_BS);
   m_ctr->set_iv(zeros.data(), zeros.size());

   secure_vector<uint8_t> H(GCM_BS);
   m_ctr->encipher(H);
   m_ghash->set_key(H);
   }

void GCM_Mode::set_associated_data(const uint8_t ad[], size_t ad_len)
   {
   m_ghash->set_associated_data(ad, ad_len);
   }

void GCM_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
   {
   if(!valid_nonce_length(nonce_len))
      throw Invalid_IV_Length(name(), nonce_len);

   m_y0.resize(GCM_BS);

   if(nonce_len == 12)
      {
      copy_mem(m_y0.data(), nonce, nonce_len);
      m_y0[15] = 1;
      }
   else
      {
      m_ghash->nonce_hash(m_y0, nonce, nonce_len);
      }

   m_ctr->set_iv(m_y0.data(), m_y0.size());

   zeroise(m_y0);
   m_ctr->encipher(m_y0);

   m_ghash->start(m_y0.data(), m_y0.size());
   m_y0.clear();
   }

size_t GCM_Encryption::process(uint8_t buf[], size_t sz)
   {
   BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid buffer size");
   m_ctr->cipher(buf, buf, sz);
   m_ghash->update(buf, sz);
   return sz;
   }

void GCM_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
   {
   BOTAN_ARG_CHECK(offset <= buffer.size(), "Invalid offset");
   const size_t sz = buffer.size() - offset;
   uint8_t* buf = buffer.data() + offset;

   m_ctr->cipher(buf, buf, sz);
   m_ghash->update(buf, sz);

   uint8_t mac[16] = { 0 };
   m_ghash->final(mac, tag_size());
   buffer += std::make_pair(mac, tag_size());
   }

size_t GCM_Decryption::process(uint8_t buf[], size_t sz)
   {
   BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid buffer size");
   m_ghash->update(buf, sz);
   m_ctr->cipher(buf, buf, sz);
   return sz;
   }

void GCM_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
   {
   BOTAN_ARG_CHECK(offset <= buffer.size(), "Invalid offset");
   const size_t sz = buffer.size() - offset;
   uint8_t* buf = buffer.data() + offset;

   if(sz < tag_size())
      throw Decoding_Error("Insufficient input for GCM decryption, tag missing");

   const size_t remaining = sz - tag_size();

   // handle any final input before the tag
   if(remaining)
      {
      m_ghash->update(buf, remaining);
      m_ctr->cipher(buf, buf, remaining);
      }

   uint8_t mac[16] = { 0 };
   m_ghash->final(mac, tag_size());

   const uint8_t* included_tag = &buffer[remaining+offset];

   if(!constant_time_compare(mac, included_tag, tag_size()))
      throw Invalid_Authentication_Tag("GCM tag check failed");

   buffer.resize(offset + remaining);
   }

}
<commit_msg>Very minor GCM optimization<commit_after>/*
* GCM Mode Encryption
* (C) 2013,2015 Jack Lloyd
* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/gcm.h>
#include <botan/ghash.h>
#include <botan/block_cipher.h>
#include <botan/ctr.h>

namespace Botan {

/*
* GCM_Mode Constructor
*/
GCM_Mode::GCM_Mode(BlockCipher* cipher, size_t tag_size) :
   m_tag_size(tag_size),
   m_cipher_name(cipher->name())
   {
   if(cipher->block_size() != GCM_BS)
      throw Invalid_Argument("Invalid block cipher for GCM");

   m_ghash.reset(new GHASH);

   m_ctr.reset(new CTR_BE(cipher, 4)); // CTR_BE takes ownership of cipher

   /* We allow any of the values 128, 120, 112, 104, or 96 bits as a tag size */
   /* 64 bit tag is still supported but deprecated and will be removed in the future */
   if(m_tag_size != 8 && (m_tag_size < 12 || m_tag_size > 16))
      throw Invalid_Argument(name() + ": Bad tag size " + std::to_string(m_tag_size));
   }

GCM_Mode::~GCM_Mode() { /* for unique_ptr */ }

void GCM_Mode::clear()
   {
   m_ctr->clear();
   m_ghash->clear();
   reset();
   }

void GCM_Mode::reset()
   {
   m_ghash->reset();
   }

std::string GCM_Mode::name() const
   {
   return (m_cipher_name + "/GCM(" + std::to_string(tag_size()) + ")");
   }

std::string GCM_Mode::provider() const
   {
   return m_ghash->provider();
   }

size_t GCM_Mode::update_granularity() const
   {
   return GCM_BS * std::max<size_t>(2, BOTAN_BLOCK_CIPHER_PAR_MULT);
   }

bool GCM_Mode::valid_nonce_length(size_t len) const
   {
   // GCM does not support empty nonces
   return (len > 0);
   }

Key_Length_Specification GCM_Mode::key_spec() const
   {
   return m_ctr->key_spec();
   }

void GCM_Mode::key_schedule(const uint8_t key[], size_t keylen)
   {
   m_ctr->set_key(key, keylen);

   const std::vector<uint8_t> zeros(GCM_BS);
   m_ctr->set_iv(zeros.data(), zeros.size());

   secure_vector<uint8_t> H(GCM_BS);
   m_ctr->encipher(H);
   m_ghash->set_key(H);
   }

void GCM_Mode::set_associated_data(const uint8_t ad[], size_t ad_len)
   {
   m_ghash->set_associated_data(ad, ad_len);
   }

void GCM_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
   {
   if(!valid_nonce_length(nonce_len))
      throw Invalid_IV_Length(name(), nonce_len);

   if(m_y0.size() != GCM_BS)
      m_y0.resize(GCM_BS);

   clear_mem(m_y0.data(), m_y0.size());

   if(nonce_len == 12)
      {
      copy_mem(m_y0.data(), nonce, nonce_len);
      m_y0[15] = 1;
      }
   else
      {
      m_ghash->nonce_hash(m_y0, nonce, nonce_len);
      }

   m_ctr->set_iv(m_y0.data(), m_y0.size());

   clear_mem(m_y0.data(), m_y0.size());
   m_ctr->encipher(m_y0);

   m_ghash->start(m_y0.data(), m_y0.size());
   clear_mem(m_y0.data(), m_y0.size());
   }

size_t GCM_Encryption::process(uint8_t buf[], size_t sz)
   {
   BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid buffer size");
   m_ctr->cipher(buf, buf, sz);
   m_ghash->update(buf, sz);
   return sz;
   }

void GCM_Encryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
   {
   BOTAN_ARG_CHECK(offset <= buffer.size(), "Invalid offset");
   const size_t sz = buffer.size() - offset;
   uint8_t* buf = buffer.data() + offset;

   m_ctr->cipher(buf, buf, sz);
   m_ghash->update(buf, sz);

   uint8_t mac[16] = { 0 };
   m_ghash->final(mac, tag_size());
   buffer += std::make_pair(mac, tag_size());
   }

size_t GCM_Decryption::process(uint8_t buf[], size_t sz)
   {
   BOTAN_ARG_CHECK(sz % update_granularity() == 0, "Invalid buffer size");
   m_ghash->update(buf, sz);
   m_ctr->cipher(buf, buf, sz);
   return sz;
   }

void GCM_Decryption::finish(secure_vector<uint8_t>& buffer, size_t offset)
   {
   BOTAN_ARG_CHECK(offset <= buffer.size(), "Invalid offset");
   const size_t sz = buffer.size() - offset;
   uint8_t* buf = buffer.data() + offset;

   if(sz < tag_size())
      throw Decoding_Error("Insufficient input for GCM decryption, tag missing");

   const size_t remaining = sz - tag_size();

   // handle any final input before the tag
   if(remaining)
      {
      m_ghash->update(buf, remaining);
      m_ctr->cipher(buf, buf, remaining);
      }

   uint8_t mac[16] = { 0 };
   m_ghash->final(mac, tag_size());

   const uint8_t* included_tag = &buffer[remaining+offset];

   if(!constant_time_compare(mac, included_tag, tag_size()))
      throw Invalid_Authentication_Tag("GCM tag check failed");

   buffer.resize(offset + remaining);
   }

}
<|endoftext|>


<commit_before>/*
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <algorithm>
#include "kernel/type_checker.h"
#include "kernel/replace_fn.h"
#include "library/locals.h"
#include "library/placeholder.h"
#include "library/module.h"
#include "library/trace.h"
#include "library/aux_definition.h"
#include "library/unfold_macros.h"
#include "library/replace_visitor_with_tc.h"

namespace lean {
level closure_helper::collect(level const & l) {
    lean_assert(!m_finalized_collection);
    return replace(l, [&](level const & l) {
            if (is_meta(l)) {
                name const & id = meta_id(l);
                if (auto r = m_univ_meta_to_param.find(id)) {
                    return some_level(*r);
                } else {
                    name n      = m_prefix.append_after(m_next_idx);
                    m_next_idx++;
                    level new_r = mk_param_univ(n);
                    m_univ_meta_to_param.insert(id, new_r);
                    m_univ_meta_to_param_inv.insert(n, l);
                    m_level_params.push_back(n);
                    return some_level(new_r);
                }
            } else if (is_param(l)) {
                lean_assert(!is_placeholder(l));
                name const & id = param_id(l);
                if (!m_found_univ_params.contains(id)) {
                    m_found_univ_params.insert(id);
                    m_level_params.push_back(id);
                }
            }
            return none_level();
        });
}

levels closure_helper::collect(levels const & ls) {
    lean_assert(!m_finalized_collection);
    bool modified = false;
    buffer<level> r;
    for (level const & l : ls) {
        level new_l = collect(l);
        if (new_l != l) modified = true;
        r.push_back(new_l);
    }
    if (!modified)
        return ls;
    else
        return to_list(r);
}

expr closure_helper::collect(expr const & e) {
    lean_assert(!m_finalized_collection);
    return replace(e, [&](expr const & e, unsigned) {
            if (is_metavar(e)) {
                name const & id = mlocal_name(e);
                if (auto r = m_meta_to_param.find(id)) {
                    return some_expr(*r);
                } else {
                    expr type  = m_ctx.infer(e);
                    expr x     = m_ctx.push_local("_x", type);
                    m_meta_to_param.insert(id, x);
                    m_meta_to_param_inv.insert(mlocal_name(x), e);
                    m_params.push_back(x);
                    return some_expr(x);
                }
            } else if (is_local(e)) {
                name const & id = mlocal_name(e);
                if (!m_found_local.contains(id)) {
                    m_found_local.insert(id);
                    m_params.push_back(e);
                }
            } else if (is_sort(e)) {
                return some_expr(update_sort(e, collect(sort_level(e))));
            } else if (is_constant(e)) {
                return some_expr(update_constant(e, collect(const_levels(e))));
            }
            return none_expr();
        });
}

void closure_helper::finalize_collection() {
    lean_assert(!m_finalized_collection);
    name_map<expr> new_types;
    for (unsigned i = 0; i < m_params.size(); i++) {
        expr x = m_params[i];
        expr new_type = collect(zeta_expand(m_ctx.lctx(), m_ctx.instantiate_mvars(m_ctx.infer(x))));
        new_types.insert(mlocal_name(x), new_type);
    }
    local_context const & lctx = m_ctx.lctx();
    std::sort(m_params.begin(), m_params.end(), [&](expr const & l1, expr const & l2) {
            return lctx.get_local_decl(l1).get_idx() < lctx.get_local_decl(l2).get_idx();
        });
    for (unsigned i = 0; i < m_params.size(); i++) {
        expr x         = m_params[i];
        expr type      = *new_types.find(mlocal_name(x));
        expr new_type  = replace_locals(type, i, m_params.data(), m_norm_params.data());
        expr new_param = m_ctx.push_local(mlocal_pp_name(x), new_type, local_info(x));
        m_norm_params.push_back(new_param);
    }
    m_finalized_collection = true;
}

expr closure_helper::mk_pi_closure(expr const & e) {
    lean_assert(m_finalized_collection);
    expr new_e  = replace_locals(e, m_params, m_norm_params);
    return m_ctx.mk_pi(m_norm_params, new_e);
}

expr closure_helper::mk_lambda_closure(expr const & e) {
    lean_assert(m_finalized_collection);
    expr new_e  = replace_locals(e, m_params, m_norm_params);
    return m_ctx.mk_lambda(m_norm_params, new_e);
}

void closure_helper::get_level_closure(buffer<level> & ls) {
    lean_assert(m_finalized_collection);
    for (name const & n : m_level_params) {
        if (level const * l = m_univ_meta_to_param_inv.find(n))
            ls.push_back(*l);
        else
            ls.push_back(mk_param_univ(n));
    }
}

void closure_helper::get_expr_closure(buffer<expr> & ps) {
    lean_assert(m_finalized_collection);
    for (expr const & x : m_params) {
        if (expr const * m = m_meta_to_param_inv.find(mlocal_name(x)))
            ps.push_back(*m);
        else
            ps.push_back(x);
    }
}

buffer<expr> const & closure_helper::get_norm_closure_params() const {
    lean_assert(m_finalized_collection);
    return m_norm_params;
}

struct mk_aux_definition_fn : public closure_helper {
    mk_aux_definition_fn(type_context & ctx):closure_helper(ctx) {}

    pair<environment, expr> operator()(name const & c, expr const & type, expr const & value, bool is_lemma, optional<bool> const & is_meta) {
        lean_assert(!is_lemma || is_meta);
        lean_assert(!is_lemma || *is_meta == false);
        expr new_type  = collect(ctx().instantiate_mvars(type));
        expr new_value = collect(ctx().instantiate_mvars(value));
        environment env = ctx().env();
        finalize_collection();
        expr def_type  = mk_pi_closure(new_type);
        expr def_value = mk_lambda_closure(new_value);
        bool untrusted = false;
        if (is_meta)
            untrusted = *is_meta;
        else
            untrusted = use_untrusted(env, def_type) || use_untrusted(env, def_value);
        if (!untrusted) {
            def_type  = unfold_untrusted_macros(env, def_type);
            def_value = unfold_untrusted_macros(env, def_value);
        }
        declaration d;
        if (is_lemma) {
            d = mk_theorem(c, get_norm_level_names(), def_type, def_value);
        } else {
            bool use_self_opt = true;
            d = mk_definition(env, c, get_norm_level_names(), def_type, def_value, use_self_opt, !untrusted);
        }
        environment new_env = module::add(env, check(env, d, true));
        buffer<level> ls;
        get_level_closure(ls);
        buffer<expr> ps;
        get_expr_closure(ps);
        expr r = mk_app(mk_constant(c, to_list(ls)), ps);
        return mk_pair(new_env, r);
    }
};

pair<environment, expr> mk_aux_definition(environment const & env, metavar_context const & mctx, local_context const & lctx,
                                          name const & c, expr const & type, expr const & value, optional<bool> const & is_meta) {
    type_context ctx(env, options(), mctx, lctx, transparency_mode::All);
    bool is_lemma = false;
    return mk_aux_definition_fn(ctx)(c, type, value, is_lemma, is_meta);
}

pair<environment, expr> mk_aux_definition(environment const & env, metavar_context const & mctx, local_context const & lctx,
                                          name const & c, expr const & value, optional<bool> const & is_meta) {
    type_context ctx(env, options(), mctx, lctx, transparency_mode::All);
    expr type     = ctx.infer(value);
    bool is_lemma = false;
    return mk_aux_definition_fn(ctx)(c, type, value, is_lemma, is_meta);
}

pair<environment, expr> mk_aux_lemma(environment const & env, metavar_context const & mctx, local_context const & lctx,
                                     name const & c, expr const & type, expr const & value) {
    type_context ctx(env, options(), mctx, lctx, transparency_mode::All);
    bool is_lemma = true;
    optional<bool> is_meta(false);
    return mk_aux_definition_fn(ctx)(c, type, value, is_lemma, is_meta);
}

struct abstract_nested_proofs_fn : public replace_visitor_with_tc {
    name     m_base_name;
    unsigned m_idx{1};

    abstract_nested_proofs_fn(type_context & ctx, name const & b):
        replace_visitor_with_tc(ctx),
        m_base_name(b, "_proof") {
    }

    static bool is_atomic(expr const & e) {
        return is_constant(e) || is_local(e);
    }

    name mk_name() {
        environment env = m_ctx.env();
        while (true) {
            name curr = m_base_name.append_after(m_idx);
            m_idx++;
            if (!env.find(curr)) {
                m_ctx.set_env(env);
                return curr;
            }
        }
    }

    optional<expr> is_non_trivial_proof(expr const & e) {
        if (is_atomic(e))
            return none_expr();
        if (is_pi(e) || is_sort(e))
            return none_expr();
        expr type = m_ctx.infer(e);
        if (!m_ctx.is_prop(type))
            return none_expr();
        if (is_app(e)) {
            buffer<expr> args;
            expr const & fn = get_app_args(e, args);
            if (!is_atomic(fn))
                return some_expr(type);
            for (expr const & arg : args) {
                if (!is_atomic(arg))
                    return some_expr(type);
            }
            return none_expr();
        } else {
            return some_expr(type);
        }
    }

    virtual expr visit_mlocal(expr const & e) override {
        return e;
    }

    virtual expr visit(expr const & e) override {
        if (auto type = is_non_trivial_proof(e)) {
            expr new_e = zeta_expand(m_ctx.lctx(), e);
            if (e != new_e) {
                *type = m_ctx.infer(new_e);
            }
            name n = mk_name();
            auto new_env_new_e = mk_aux_lemma(m_ctx.env(), m_ctx.mctx(), m_ctx.lctx(), n, *type, new_e);
            m_ctx.set_env(new_env_new_e.first);
            return new_env_new_e.second;
        } else {
            return replace_visitor_with_tc::visit(e);
        }
    }

    pair<environment, expr> operator()(expr const & e) {
        expr new_e = replace_visitor_with_tc::operator()(e);
        return mk_pair(m_ctx.env(), new_e);
    }
};

pair<environment, expr> abstract_nested_proofs(environment const & env, metavar_context const & mctx, local_context const & lctx, name const & base_name, expr const & e) {
    type_context ctx(env, options(), mctx, lctx, transparency_mode::Semireducible);
    return abstract_nested_proofs_fn(ctx, base_name)(e);
}

pair<environment, expr> abstract_nested_proofs(environment const & env, name const & base_name, expr const & e) {
    lean_assert(!has_metavar(e));
    return abstract_nested_proofs(env, metavar_context(), local_context(), base_name, e);
}
}
<commit_msg>fix(library/aux_definition): make sure aux_definition level params are sorted<commit_after>/*
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <algorithm>
#include "kernel/type_checker.h"
#include "kernel/replace_fn.h"
#include "library/locals.h"
#include "library/placeholder.h"
#include "library/module.h"
#include "library/trace.h"
#include "library/aux_definition.h"
#include "library/unfold_macros.h"
#include "library/replace_visitor_with_tc.h"

namespace lean {
level closure_helper::collect(level const & l) {
    lean_assert(!m_finalized_collection);
    return replace(l, [&](level const & l) {
            if (is_meta(l)) {
                name const & id = meta_id(l);
                if (auto r = m_univ_meta_to_param.find(id)) {
                    return some_level(*r);
                } else {
                    name n      = m_prefix.append_after(m_next_idx);
                    m_next_idx++;
                    level new_r = mk_param_univ(n);
                    m_univ_meta_to_param.insert(id, new_r);
                    m_univ_meta_to_param_inv.insert(n, l);
                    m_level_params.push_back(n);
                    return some_level(new_r);
                }
            } else if (is_param(l)) {
                lean_assert(!is_placeholder(l));
                name const & id = param_id(l);
                if (!m_found_univ_params.contains(id)) {
                    m_found_univ_params.insert(id);
                    m_level_params.push_back(id);
                }
            }
            return none_level();
        });
}

levels closure_helper::collect(levels const & ls) {
    lean_assert(!m_finalized_collection);
    bool modified = false;
    buffer<level> r;
    for (level const & l : ls) {
        level new_l = collect(l);
        if (new_l != l) modified = true;
        r.push_back(new_l);
    }
    if (!modified)
        return ls;
    else
        return to_list(r);
}

expr closure_helper::collect(expr const & e) {
    lean_assert(!m_finalized_collection);
    return replace(e, [&](expr const & e, unsigned) {
            if (is_metavar(e)) {
                name const & id = mlocal_name(e);
                if (auto r = m_meta_to_param.find(id)) {
                    return some_expr(*r);
                } else {
                    expr type  = m_ctx.infer(e);
                    expr x     = m_ctx.push_local("_x", type);
                    m_meta_to_param.insert(id, x);
                    m_meta_to_param_inv.insert(mlocal_name(x), e);
                    m_params.push_back(x);
                    return some_expr(x);
                }
            } else if (is_local(e)) {
                name const & id = mlocal_name(e);
                if (!m_found_local.contains(id)) {
                    m_found_local.insert(id);
                    m_params.push_back(e);
                }
            } else if (is_sort(e)) {
                return some_expr(update_sort(e, collect(sort_level(e))));
            } else if (is_constant(e)) {
                return some_expr(update_constant(e, collect(const_levels(e))));
            }
            return none_expr();
        });
}

void closure_helper::finalize_collection() {
    lean_assert(!m_finalized_collection);
    std::sort(m_level_params.begin(), m_level_params.end());
    name_map<expr> new_types;
    for (unsigned i = 0; i < m_params.size(); i++) {
        expr x = m_params[i];
        expr new_type = collect(zeta_expand(m_ctx.lctx(), m_ctx.instantiate_mvars(m_ctx.infer(x))));
        new_types.insert(mlocal_name(x), new_type);
    }
    local_context const & lctx = m_ctx.lctx();
    std::sort(m_params.begin(), m_params.end(), [&](expr const & l1, expr const & l2) {
            return lctx.get_local_decl(l1).get_idx() < lctx.get_local_decl(l2).get_idx();
        });
    for (unsigned i = 0; i < m_params.size(); i++) {
        expr x         = m_params[i];
        expr type      = *new_types.find(mlocal_name(x));
        expr new_type  = replace_locals(type, i, m_params.data(), m_norm_params.data());
        expr new_param = m_ctx.push_local(mlocal_pp_name(x), new_type, local_info(x));
        m_norm_params.push_back(new_param);
    }
    m_finalized_collection = true;
}

expr closure_helper::mk_pi_closure(expr const & e) {
    lean_assert(m_finalized_collection);
    expr new_e  = replace_locals(e, m_params, m_norm_params);
    return m_ctx.mk_pi(m_norm_params, new_e);
}

expr closure_helper::mk_lambda_closure(expr const & e) {
    lean_assert(m_finalized_collection);
    expr new_e  = replace_locals(e, m_params, m_norm_params);
    return m_ctx.mk_lambda(m_norm_params, new_e);
}

void closure_helper::get_level_closure(buffer<level> & ls) {
    lean_assert(m_finalized_collection);
    for (name const & n : m_level_params) {
        if (level const * l = m_univ_meta_to_param_inv.find(n))
            ls.push_back(*l);
        else
            ls.push_back(mk_param_univ(n));
    }
}

void closure_helper::get_expr_closure(buffer<expr> & ps) {
    lean_assert(m_finalized_collection);
    for (expr const & x : m_params) {
        if (expr const * m = m_meta_to_param_inv.find(mlocal_name(x)))
            ps.push_back(*m);
        else
            ps.push_back(x);
    }
}

buffer<expr> const & closure_helper::get_norm_closure_params() const {
    lean_assert(m_finalized_collection);
    return m_norm_params;
}

struct mk_aux_definition_fn : public closure_helper {
    mk_aux_definition_fn(type_context & ctx):closure_helper(ctx) {}

    pair<environment, expr> operator()(name const & c, expr const & type, expr const & value, bool is_lemma, optional<bool> const & is_meta) {
        lean_assert(!is_lemma || is_meta);
        lean_assert(!is_lemma || *is_meta == false);
        expr new_type  = collect(ctx().instantiate_mvars(type));
        expr new_value = collect(ctx().instantiate_mvars(value));
        environment env = ctx().env();
        finalize_collection();
        expr def_type  = mk_pi_closure(new_type);
        expr def_value = mk_lambda_closure(new_value);
        bool untrusted = false;
        if (is_meta)
            untrusted = *is_meta;
        else
            untrusted = use_untrusted(env, def_type) || use_untrusted(env, def_value);
        if (!untrusted) {
            def_type  = unfold_untrusted_macros(env, def_type);
            def_value = unfold_untrusted_macros(env, def_value);
        }
        declaration d;
        if (is_lemma) {
            d = mk_theorem(c, get_norm_level_names(), def_type, def_value);
        } else {
            bool use_self_opt = true;
            d = mk_definition(env, c, get_norm_level_names(), def_type, def_value, use_self_opt, !untrusted);
        }
        environment new_env = module::add(env, check(env, d, true));
        buffer<level> ls;
        get_level_closure(ls);
        buffer<expr> ps;
        get_expr_closure(ps);
        expr r = mk_app(mk_constant(c, to_list(ls)), ps);
        return mk_pair(new_env, r);
    }
};

pair<environment, expr> mk_aux_definition(environment const & env, metavar_context const & mctx, local_context const & lctx,
                                          name const & c, expr const & type, expr const & value, optional<bool> const & is_meta) {
    type_context ctx(env, options(), mctx, lctx, transparency_mode::All);
    bool is_lemma = false;
    return mk_aux_definition_fn(ctx)(c, type, value, is_lemma, is_meta);
}

pair<environment, expr> mk_aux_definition(environment const & env, metavar_context const & mctx, local_context const & lctx,
                                          name const & c, expr const & value, optional<bool> const & is_meta) {
    type_context ctx(env, options(), mctx, lctx, transparency_mode::All);
    expr type     = ctx.infer(value);
    bool is_lemma = false;
    return mk_aux_definition_fn(ctx)(c, type, value, is_lemma, is_meta);
}

pair<environment, expr> mk_aux_lemma(environment const & env, metavar_context const & mctx, local_context const & lctx,
                                     name const & c, expr const & type, expr const & value) {
    type_context ctx(env, options(), mctx, lctx, transparency_mode::All);
    bool is_lemma = true;
    optional<bool> is_meta(false);
    return mk_aux_definition_fn(ctx)(c, type, value, is_lemma, is_meta);
}

struct abstract_nested_proofs_fn : public replace_visitor_with_tc {
    name     m_base_name;
    unsigned m_idx{1};

    abstract_nested_proofs_fn(type_context & ctx, name const & b):
        replace_visitor_with_tc(ctx),
        m_base_name(b, "_proof") {
    }

    static bool is_atomic(expr const & e) {
        return is_constant(e) || is_local(e);
    }

    name mk_name() {
        environment env = m_ctx.env();
        while (true) {
            name curr = m_base_name.append_after(m_idx);
            m_idx++;
            if (!env.find(curr)) {
                m_ctx.set_env(env);
                return curr;
            }
        }
    }

    optional<expr> is_non_trivial_proof(expr const & e) {
        if (is_atomic(e))
            return none_expr();
        if (is_pi(e) || is_sort(e))
            return none_expr();
        expr type = m_ctx.infer(e);
        if (!m_ctx.is_prop(type))
            return none_expr();
        if (is_app(e)) {
            buffer<expr> args;
            expr const & fn = get_app_args(e, args);
            if (!is_atomic(fn))
                return some_expr(type);
            for (expr const & arg : args) {
                if (!is_atomic(arg))
                    return some_expr(type);
            }
            return none_expr();
        } else {
            return some_expr(type);
        }
    }

    virtual expr visit_mlocal(expr const & e) override {
        return e;
    }

    virtual expr visit(expr const & e) override {
        if (auto type = is_non_trivial_proof(e)) {
            expr new_e = zeta_expand(m_ctx.lctx(), e);
            if (e != new_e) {
                *type = m_ctx.infer(new_e);
            }
            name n = mk_name();
            auto new_env_new_e = mk_aux_lemma(m_ctx.env(), m_ctx.mctx(), m_ctx.lctx(), n, *type, new_e);
            m_ctx.set_env(new_env_new_e.first);
            return new_env_new_e.second;
        } else {
            return replace_visitor_with_tc::visit(e);
        }
    }

    pair<environment, expr> operator()(expr const & e) {
        expr new_e = replace_visitor_with_tc::operator()(e);
        return mk_pair(m_ctx.env(), new_e);
    }
};

pair<environment, expr> abstract_nested_proofs(environment const & env, metavar_context const & mctx, local_context const & lctx, name const & base_name, expr const & e) {
    type_context ctx(env, options(), mctx, lctx, transparency_mode::Semireducible);
    return abstract_nested_proofs_fn(ctx, base_name)(e);
}

pair<environment, expr> abstract_nested_proofs(environment const & env, name const & base_name, expr const & e) {
    lean_assert(!has_metavar(e));
    return abstract_nested_proofs(env, metavar_context(), local_context(), base_name, e);
}
}
<|endoftext|>