<commit_before>/* brushlib - The MyPaint Brush Library
 * Copyright (C) 2008 Martin Renold <martinxyz@gmx.ch>
 *
 * 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 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. See the COPYING file for more details.
 */

// surface interface required by brush.hpp
class Surface {
public:
  virtual bool draw_dab (float x, float y,
                         float radius,
                         float color_r, float color_g, float color_b,
                         float opaque, float hardness = 0.5,
                         float alpha_eraser = 1.0,
               			 float aspect_ratio = 1.0, float angle = 0.0
                         ) = 0;

  virtual void get_color (float x, float y,
                          float radius,
                          float * color_r, float * color_g, float * color_b, float * color_a
                          ) = 0;
};
<commit_msg>brushlib: virtual destructor<commit_after>/* brushlib - The MyPaint Brush Library
 * Copyright (C) 2008 Martin Renold <martinxyz@gmx.ch>
 *
 * 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 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. See the COPYING file for more details.
 */

// surface interface required by brush.hpp
class Surface {
public:

  virtual ~Surface() {}

  virtual bool draw_dab (float x, float y,
                         float radius,
                         float color_r, float color_g, float color_b,
                         float opaque, float hardness = 0.5,
                         float alpha_eraser = 1.0,
               			 float aspect_ratio = 1.0, float angle = 0.0
                         ) = 0;

  virtual void get_color (float x, float y,
                          float radius,
                          float * color_r, float * color_g, float * color_b, float * color_a
                          ) = 0;
};
<|endoftext|>


<commit_before>/*
* Copyright (C) 2007-2014 German Aerospace Center (DLR/SC)
*
* Created: 2014-02-10 Tobias Stollenwerk <tobias.stollenwerk@dlr.de>
*
* 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.
*/
/**
* @file
* @brief  Implementation of CPACS guide curve container handling routines
*/

#include "CCPACSGuideCurves.h"
#include "CCPACSGuideCurve.h"

namespace tigl
{

CCPACSGuideCurves::CCPACSGuideCurves(CCPACSFuselageSegment* parent, CTiglUIDManager* uidMgr)
    : generated::CPACSGuideCurves(parent, uidMgr) {}

CCPACSGuideCurves::CCPACSGuideCurves(CCPACSWingSegment* parent, CTiglUIDManager* uidMgr)
    : generated::CPACSGuideCurves(parent, uidMgr) {}

void CCPACSGuideCurves::ReadCPACS(const TixiDocumentHandle& tixiHandle, const std::string& xpath) {
    generated::CPACSGuideCurves::ReadCPACS(tixiHandle, xpath);

    // sort by uid as some unit tests rely on this (TODO: should we fix the tests?)
    // WARN: this destroys the order of the guide curves as stored in the CPACS file
    std::sort(m_guideCurves.begin(), m_guideCurves.end(), [](const std::unique_ptr<CCPACSGuideCurve>& a, const std::unique_ptr<CCPACSGuideCurve>& b) {
        return a->GetUID() < b->GetUID();
    });
}

// Returns the total count of guide curves in this configuration
int CCPACSGuideCurves::GetGuideCurveCount() const
{
    return static_cast<int>(m_guideCurves.size());
}

// Returns the guide curve for a given index
const CCPACSGuideCurve& CCPACSGuideCurves::GetGuideCurve(int index) const
{
    index--;
    if (index < 0 || index >= GetGuideCurveCount()) {
        throw CTiglError("Invalid index in CCPACSGuideCurves::GetGuideCurve", TIGL_INDEX_ERROR);
    }
    return *m_guideCurves[index];
}

// Returns the guide curve for a given index
CCPACSGuideCurve& CCPACSGuideCurves::GetGuideCurve(int index)
{
    return const_cast<CCPACSGuideCurve&>(static_cast<const CCPACSGuideCurves*>(this)->GetGuideCurve(index));
}

// Returns the guide curve for a given uid.
const CCPACSGuideCurve& CCPACSGuideCurves::GetGuideCurve(std::string uid) const
{
    for (std::size_t i = 0; i < m_guideCurves.size(); i++) {
        if (m_guideCurves[i]->GetUID() == uid) {
            return *m_guideCurves[i];
        }
    }
    throw CTiglError("CCPACSGuideCurve::GetGuideCurve: Guide curve \"" + uid + "\" not found in CPACS file!", TIGL_UID_ERROR);
}

// Returns the guide curve for a given uid.
CCPACSGuideCurve& CCPACSGuideCurves::GetGuideCurve(std::string uid)
{
    return const_cast<CCPACSGuideCurve&>(static_cast<const CCPACSGuideCurves*>(this)->GetGuideCurve(uid));
}

// Returns the guide curve for a given uid.
bool CCPACSGuideCurves::GuideCurveExists(std::string uid) const
{
    for (std::size_t i = 0; i < m_guideCurves.size(); i++) {
        if (m_guideCurves[i]->GetUID() == uid) {
            return true;
        }
    }
    return false;
}

std::vector<double> CCPACSGuideCurves::GetRelativeCircumferenceParameters() const
{
    std::vector<double> relCircs;
    for (int iguide = 1; iguide <=  GetGuideCurveCount(); ++iguide) {
        const CCPACSGuideCurve* root = GetGuideCurve(iguide).GetRootCurve();
        relCircs.push_back(*root->GetFromRelativeCircumference_choice2());
    }

    std::sort(relCircs.begin(), relCircs.end());

    double eps = 1e-10;
    if ( relCircs.back() < 1.0 - eps ) {
        relCircs.push_back(1.0);
    }

    return relCircs;
}

void CCPACSGuideCurves::GetRelativeCircumferenceRange(double relCirc,
                                                      double& relCircStart,
                                                      double& relCircEnd,
                                                      int& idx) const
{
    std::vector<double> relCircs = GetRelativeCircumferenceParameters();

    // probably best to assert for performance reasons...
    assert( relCircs.size() > 0 );
    assert( relCirc >= relCircs[0] );
    assert( relCirc <= relCircs.back() );

    for (size_t i = 1; i < relCircs.size(); ++i ) {
        if (relCircs[i] >= relCirc ) {
            relCircStart = relCircs[i-1];
            relCircEnd = relCircs[i];
            idx = static_cast<int>(i-1);
            break;
        }
    }
}

} // end namespace tigl

<commit_msg>Changed code to comply with tolerance at other places<commit_after>/*
* Copyright (C) 2007-2014 German Aerospace Center (DLR/SC)
*
* Created: 2014-02-10 Tobias Stollenwerk <tobias.stollenwerk@dlr.de>
*
* 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.
*/
/**
* @file
* @brief  Implementation of CPACS guide curve container handling routines
*/

#include "CCPACSGuideCurves.h"
#include "CCPACSGuideCurve.h"

namespace tigl
{

CCPACSGuideCurves::CCPACSGuideCurves(CCPACSFuselageSegment* parent, CTiglUIDManager* uidMgr)
    : generated::CPACSGuideCurves(parent, uidMgr) {}

CCPACSGuideCurves::CCPACSGuideCurves(CCPACSWingSegment* parent, CTiglUIDManager* uidMgr)
    : generated::CPACSGuideCurves(parent, uidMgr) {}

void CCPACSGuideCurves::ReadCPACS(const TixiDocumentHandle& tixiHandle, const std::string& xpath) {
    generated::CPACSGuideCurves::ReadCPACS(tixiHandle, xpath);

    // sort by uid as some unit tests rely on this (TODO: should we fix the tests?)
    // WARN: this destroys the order of the guide curves as stored in the CPACS file
    std::sort(m_guideCurves.begin(), m_guideCurves.end(), [](const std::unique_ptr<CCPACSGuideCurve>& a, const std::unique_ptr<CCPACSGuideCurve>& b) {
        return a->GetUID() < b->GetUID();
    });
}

// Returns the total count of guide curves in this configuration
int CCPACSGuideCurves::GetGuideCurveCount() const
{
    return static_cast<int>(m_guideCurves.size());
}

// Returns the guide curve for a given index
const CCPACSGuideCurve& CCPACSGuideCurves::GetGuideCurve(int index) const
{
    index--;
    if (index < 0 || index >= GetGuideCurveCount()) {
        throw CTiglError("Invalid index in CCPACSGuideCurves::GetGuideCurve", TIGL_INDEX_ERROR);
    }
    return *m_guideCurves[index];
}

// Returns the guide curve for a given index
CCPACSGuideCurve& CCPACSGuideCurves::GetGuideCurve(int index)
{
    return const_cast<CCPACSGuideCurve&>(static_cast<const CCPACSGuideCurves*>(this)->GetGuideCurve(index));
}

// Returns the guide curve for a given uid.
const CCPACSGuideCurve& CCPACSGuideCurves::GetGuideCurve(std::string uid) const
{
    for (std::size_t i = 0; i < m_guideCurves.size(); i++) {
        if (m_guideCurves[i]->GetUID() == uid) {
            return *m_guideCurves[i];
        }
    }
    throw CTiglError("CCPACSGuideCurve::GetGuideCurve: Guide curve \"" + uid + "\" not found in CPACS file!", TIGL_UID_ERROR);
}

// Returns the guide curve for a given uid.
CCPACSGuideCurve& CCPACSGuideCurves::GetGuideCurve(std::string uid)
{
    return const_cast<CCPACSGuideCurve&>(static_cast<const CCPACSGuideCurves*>(this)->GetGuideCurve(uid));
}

// Returns the guide curve for a given uid.
bool CCPACSGuideCurves::GuideCurveExists(std::string uid) const
{
    for (std::size_t i = 0; i < m_guideCurves.size(); i++) {
        if (m_guideCurves[i]->GetUID() == uid) {
            return true;
        }
    }
    return false;
}

std::vector<double> CCPACSGuideCurves::GetRelativeCircumferenceParameters() const
{
    std::vector<double> relCircs;
    for (int iguide = 1; iguide <=  GetGuideCurveCount(); ++iguide) {
        const CCPACSGuideCurve* root = GetGuideCurve(iguide).GetRootCurve();
        relCircs.push_back(*root->GetFromRelativeCircumference_choice2());
    }

    std::sort(relCircs.begin(), relCircs.end());

    if (std::abs(relCircs.back() - 1.0) >= 1e-3 ) {
        relCircs.push_back(1.0);
    }

    return relCircs;
}

void CCPACSGuideCurves::GetRelativeCircumferenceRange(double relCirc,
                                                      double& relCircStart,
                                                      double& relCircEnd,
                                                      int& idx) const
{
    std::vector<double> relCircs = GetRelativeCircumferenceParameters();

    // probably best to assert for performance reasons...
    assert( relCircs.size() > 0 );
    assert( relCirc >= relCircs[0] );
    assert( relCirc <= relCircs.back() );

    for (size_t i = 1; i < relCircs.size(); ++i ) {
        if (relCircs[i] >= relCirc ) {
            relCircStart = relCircs[i-1];
            relCircEnd = relCircs[i];
            idx = static_cast<int>(i-1);
            break;
        }
    }
}

} // end namespace tigl

<|endoftext|>


<commit_before>#include "Variant.h"
#include "split.h"
#include "cdflib.hpp"
#include "pdflib.hpp"
#include "var.hpp"

#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <getopt.h>

using namespace std;
using namespace vcf;
void printVersion(void){
	    cerr << "INFO: version 1.1.0 ; date: April 2014 ; author: Zev Kronenberg; email : zev.kronenberg@utah.edu " << endl;
	    exit(1);

}

void printHelp(void){
  cerr << endl << endl;
  cerr << "INFO: help" << endl;
  cerr << "INFO: description:" << endl;
  cerr << "     iHS calculates the integrated ratio of haplotype decay between the reference and non-reference allele. " << endl;
  cerr << "     This implementation of iHS integrates over a SNP index, NOT a physical distance or genetic distance.   " << endl << endl;

  cerr << "Output : 4 columns :                  "    << endl;
  cerr << "     1. seqid                         "    << endl;
  cerr << "     2. position                      "    << endl;
  cerr << "     3. target allele frequency       "    << endl;
  cerr << "     4. integrated EHH (alternative)  "    << endl;
  cerr << "     5. integrated EHH (reference)    "    << endl;
  cerr << "     6. iHS log(iEHHalt/iEHHref)      "    << endl  << endl;

  cerr << "INFO: iHS  --target 0,1,2,3,4,5,6,7 --file my.phased.vcf  --region chr1:1-1000 " << endl << endl;

  cerr << "INFO: required: t,target  -- argument: a zero base comma separated list of target individuals corrisponding to VCF columns " << endl;
  cerr << "INFO: required: f,file    -- argument: proper formatted and phased VCF.                                                    " << endl;
  cerr << "INFO: required: y,type    -- argument: genotype likelihood format: PL,GL,GP                                                " << endl;
  cerr << "INFO: optional: r,region  -- argument: a tabix compliant genomic range : \"seqid:start-end\" or \"seqid\"                  " << endl;
  cerr << endl;

  printVersion();

  exit(1);
}

void clearHaplotypes(string haplotypes[][2], int ntarget){
  for(int i= 0; i < ntarget; i++){
    haplotypes[i][0].clear();
    haplotypes[i][1].clear();
  }
}

void loadIndices(map<int, int> & index, string set){

  vector<string>  indviduals = split(set, ",");
  vector<string>::iterator it = indviduals.begin();

  for(; it != indviduals.end(); it++){
    index[ atoi( (*it).c_str() ) ] = 1;
  }
}

void calc(string haplotypes[][2], int nhaps, vector<double> afs, vector<long int> pos, vector<int> & target, vector<int> & background, string seqid){

   //cerr << "about to calc" << endl;
   //cerr << "nhap:        " << nhaps << endl;

  for(int snp = 0; snp < haplotypes[0][0].length(); snp++){

    double ehhA = 1;
    double ehhR = 1;

    double iHSA = 1;
    double iHSR = 1;

    int start = snp;
    int end   = snp;
    int core  = snp;

    while( ehhA > 0.05 && ehhR > 0.05 ) {

      start -= 1;
      end   += 1;

      if(start == -1){
	break;
      }
      if(end == haplotypes[0][0].length() - 1){
	break;
      }

      map<string , int> targetH;

      double sumrT = 0;
      double sumaT = 0;
      double nrefT = 0;
      double naltT = 0;

      for(int i = 0; i < nhaps; i++){
	targetH[ haplotypes[i][0].substr(start, (end - start)) ]++;
	targetH[ haplotypes[i][1].substr(start, (end - start)) ]++;
      }
      for( map<string, int>::iterator th = targetH.begin(); th != targetH.end(); th++){
	if( (*th).first.substr((end-start)/2, 1) == "1"){
	   sumaT += r8_choose(th->second, 2);
	   naltT += th->second;
	}
	else{
	  sumrT += r8_choose(th->second, 2);
	  nrefT += th->second;
	}
      }

      ehhA = sumaT / (r8_choose(naltT, 2));
      ehhR = sumrT / (r8_choose(nrefT, 2));

      iHSA += ehhA;
      iHSR += ehhR;
    }
    if(isnan(iHSA) || isnan(iHSR)){
      continue;
    }
    cout << seqid << "\t" << pos[snp] << "\t" << afs[snp] << "\t" << iHSA << "\t" << iHSR << "\t" << log(iHSA/iHSR) << endl;
  }
}

double EHH(string haplotypes[][2], int nhaps){

  map<string , int> hapcounts;

  for(int i = 0; i < nhaps; i++){
    hapcounts[ haplotypes[i][0] ]++;
    hapcounts[ haplotypes[i][1] ]++;
  }

  double sum = 0;
  double nh  = 0;

  for( map<string, int>::iterator it = hapcounts.begin(); it != hapcounts.end(); it++){
    nh  += it->second;
    sum += r8_choose(it->second, 2);
  }

  double max = (sum /  r8_choose(nh, 2));

  return max;

}

void loadPhased(string haplotypes[][2], genotype * pop, int ntarget){

  int indIndex = 0;

  for(vector<string>::iterator ind = pop->gts.begin(); ind != pop->gts.end(); ind++){
    string g = (*ind);
    vector< string > gs = split(g, "|");
    haplotypes[indIndex][0].append(gs[0]);
    haplotypes[indIndex][1].append(gs[1]);
    indIndex += 1;
  }
}

int main(int argc, char** argv) {

  // set the random seed for MCMC

  srand((unsigned)time(NULL));

  // the filename

  string filename = "NA";

  // set region to scaffold

  string region = "NA";

  // using vcflib; thanks to Erik Garrison

  VariantCallFile variantFile;

  // zero based index for the target and background indivudals

  map<int, int> it, ib;

  // deltaaf is the difference of allele frequency we bother to look at

  // ancestral state is set to zero by default

  int counts = 0;

  // phased

  int phased = 0;

  string type = "NA";

    const struct option longopts[] =
      {
	{"version"   , 0, 0, 'v'},
	{"help"      , 0, 0, 'h'},
        {"file"      , 1, 0, 'f'},
	{"target"    , 1, 0, 't'},
	{"region"    , 1, 0, 'r'},
	{"type"      , 1, 0, 'y'},
	{0,0,0,0}
      };

    int findex;
    int iarg=0;

    while(iarg != -1)
      {
	iarg = getopt_long(argc, argv, "y:r:d:t:b:f:hv", longopts, &findex);

	switch (iarg)
	  {
	  case 'h':
	    printHelp();
	  case 'v':
	    printVersion();
	  case 'y':
	    type = optarg;
	    break;
	  case 't':
	    loadIndices(it, optarg);
	    cerr << "INFO: there are " << it.size() << " individuals in the target" << endl;
	    cerr << "INFO: target ids: " << optarg << endl;
	    break;
	  case 'f':
	    cerr << "INFO: file: " << optarg  <<  endl;
	    filename = optarg;
	    break;
	  case 'r':
            cerr << "INFO: set seqid region to : " << optarg << endl;
	    region = optarg;
	    break;
	  default:
	    break;
	  }
      }

    map<string, int> okayGenotypeLikelihoods;
    okayGenotypeLikelihoods["PL"] = 1;
    okayGenotypeLikelihoods["GL"] = 1;
    okayGenotypeLikelihoods["GP"] = 1;
    okayGenotypeLikelihoods["GT"] = 1;

    if(type == "NA"){
      cerr << "FATAL: failed to specify genotype likelihood format : PL or GL" << endl;
      printHelp();
      return 1;
    }
    if(okayGenotypeLikelihoods.find(type) == okayGenotypeLikelihoods.end()){
      cerr << "FATAL: genotype likelihood is incorrectly formatted, only use: PL or GL" << endl;
      printHelp();
      return 1;
    }

    if(filename == "NA"){
      cerr << "FATAL: did not specify a file" << endl;
      printHelp();
      return(1);
    }

    if(it.size() < 2){
      cerr << "FATAL: target option is required -- or -- less than two individuals in target\n";
      printHelp();
      return(1);
    }

    variantFile.open(filename);

    if(region != "NA"){
      if(! variantFile.setRegion(region)){
	cerr <<"FATAL: unable to set region" << endl;
	return 1;
      }
    }

    if (!variantFile.is_open()) {
        return 1;
    }

    Variant var(variantFile);

    vector<int> target_h, background_h;

    int index   = 0;
    int  indexi = 0;

    vector<string> samples = variantFile.sampleNames;
    int nsamples = samples.size();

    for(vector<string>::iterator samp = samples.begin(); samp != samples.end(); samp++){

      string sampleName = (*samp);

      if(it.find(index) != it.end() ){
	target_h.push_back(indexi);
	indexi++;
      }
      index++;
    }

    // cerr << "n in target : " << target_h.size() << endl;

    vector<long int> positions;

    vector<double> afs;

    string haplotypes [target_h.size()][2];

    string currentSeqid = "NA";

    // cerr << "about to loop variants" << endl;

    while (variantFile.getNextVariant(var)) {

      if(!var.isPhased()){
	cerr << "FATAL: Found an unphased variant. All genotypes must be phased!" << endl;
	return(1);
      }

      if(var.alt.size() > 1){
	continue;
      }

      if(currentSeqid != var.sequenceName){
	if(haplotypes[0][0].length() > 10){
	  calc(haplotypes, target_h.size(), afs, positions, target_h, background_h, currentSeqid);
	}
	clearHaplotypes(haplotypes, target_h.size());
	positions.clear();
	currentSeqid = var.sequenceName;
	afs.clear();
      }

      vector < map< string, vector<string> > > target, background, total;

      int sindex = 0;

      for(int nsamp = 0; nsamp < nsamples; nsamp++){

	map<string, vector<string> > sample = var.samples[ samples[nsamp]];

	if(it.find(sindex) != it.end() ){
	  target.push_back(sample);
	}
	sindex += 1;
      }

      genotype * populationTarget    ;

      if(type == "PL"){
	populationTarget     = new pl();
      }
      if(type == "GL"){
	populationTarget     = new gl();
      }
      if(type == "GP"){
	populationTarget     = new gp();
      }
      if(type == "GT"){
	populationTarget     = new gt();
      }

      populationTarget->loadPop(target, var.sequenceName, var.position);

      if(populationTarget->af == 1 || populationTarget->af == 0){
	delete populationTarget;
	continue;
      }
      positions.push_back(var.position);
      afs.push_back(populationTarget->af);
      loadPhased(haplotypes, populationTarget, populationTarget->gts.size());

      populationTarget = NULL;
      delete populationTarget;
    }

    calc(haplotypes, target_h.size(), afs, positions, target_h, background_h, currentSeqid);

    return 0;
}
<commit_msg>updated iHS<commit_after>#include "Variant.h"
#include "split.h"
#include "cdflib.hpp"
#include "pdflib.hpp"
#include "var.hpp"

#include <string>
#include <iostream>
#include <math.h>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <getopt.h>

using namespace std;
using namespace vcf;
void printVersion(void){
	    cerr << "INFO: version 1.1.0 ; date: April 2014 ; author: Zev Kronenberg; email : zev.kronenberg@utah.edu " << endl;
	    exit(1);

}

void printHelp(void){
  cerr << endl << endl;
  cerr << "INFO: help" << endl;
  cerr << "INFO: description:" << endl;
  cerr << "     iHS calculates the integrated ratio of haplotype decay between the reference and non-reference allele. " << endl;
  cerr << "     This implementation of iHS integrates over a SNP index, NOT a physical distance or genetic distance.   " << endl << endl;

  cerr << "Output : 4 columns :                  "    << endl;
  cerr << "     1. seqid                         "    << endl;
  cerr << "     2. position                      "    << endl;
  cerr << "     3. target allele frequency       "    << endl;
  cerr << "     4. integrated EHH (alternative)  "    << endl;
  cerr << "     5. integrated EHH (reference)    "    << endl;
  cerr << "     6. iHS log(iEHHalt/iEHHref)      "    << endl  << endl;

  cerr << "INFO: iHS  --target 0,1,2,3,4,5,6,7 --file my.phased.vcf  --region chr1:1-1000 " << endl << endl;

  cerr << "INFO: required: t,target  -- argument: a zero base comma separated list of target individuals corrisponding to VCF columns " << endl;
  cerr << "INFO: required: f,file    -- argument: proper formatted and phased VCF.                                                    " << endl;
  cerr << "INFO: required: y,type    -- argument: genotype likelihood format: PL,GL,GP                                                " << endl;
  cerr << "INFO: optional: r,region  -- argument: a tabix compliant genomic range : \"seqid:start-end\" or \"seqid\"                  " << endl;
  cerr << endl;

  printVersion();

  exit(1);
}

void clearHaplotypes(string haplotypes[][2], int ntarget){
  for(int i= 0; i < ntarget; i++){
    haplotypes[i][0].clear();
    haplotypes[i][1].clear();
  }
}

void loadIndices(map<int, int> & index, string set){

  vector<string>  indviduals = split(set, ",");
  vector<string>::iterator it = indviduals.begin();

  for(; it != indviduals.end(); it++){
    index[ atoi( (*it).c_str() ) ] = 1;
  }
}

void calc(string haplotypes[][2], int nhaps, vector<double> afs, vector<long int> pos, vector<int> & target, vector<int> & background, string seqid){

   //cerr << "about to calc" << endl;
   //cerr << "nhap:        " << nhaps << endl;

  for(int snp = 0; snp < haplotypes[0][0].length(); snp++){

    int breakflag = 1;
    int count     = 0;

    double ehhA = 1;
    double ehhR = 1;

    double iHSA = 0;
    double iHSR = 0;

    int start = snp;
    int end   = snp;
    int core  = snp;

    while( breakflag ) {

      if(count > 0){
	start -= 1;
	end   += 1;
      }
      if(start == -1){
	break;
      }
      if(end == haplotypes[0][0].length() - 1){
	break;
      }
      count += 1;

      map<string , int> targetH;

      double sumrT = 0;
      double sumaT = 0;
      double nrefT = 0;
      double naltT = 0;

      for(int i = 0; i < nhaps; i++){
	targetH[ haplotypes[i][0].substr(start, (end - start)) ]++;
	targetH[ haplotypes[i][1].substr(start, (end - start)) ]++;
      }
      for( map<string, int>::iterator th = targetH.begin(); th != targetH.end(); th++){
	if( (*th).first.substr((end-start)/2, 1) == "1"){
	  sumaT += r8_choose(th->second, 2);
	  naltT += th->second;
	}
	else{
	  sumrT += r8_choose(th->second, 2);
	  nrefT += th->second;
	}
      }
      cerr << pos[snp] << " " << naltT  << " " << nrefT << endl;

      double ehhAC = sumaT / (r8_choose(naltT, 2));
      double ehhRC = sumrT / (r8_choose(nrefT, 2));

      if(count == 1){
	ehhA = ehhAC;
	ehhR = ehhRC;
	continue;
      }

      iHSA += (ehhA + ehhAC) / 2;
      iHSR += (ehhR + ehhRC) / 2;

      ehhA = ehhAC;
      ehhR = ehhRC;

      if(ehhA < 0.05 && ehhR < 0.05){
	breakflag = 0;
      }
    }

    cout << seqid << "\t" << pos[snp] << "\t" << afs[snp] << "\t" << iHSA << "\t" << iHSR << "\t" << log(iHSA/iHSR) << endl;
  }
}

double EHH(string haplotypes[][2], int nhaps){

  map<string , int> hapcounts;

  for(int i = 0; i < nhaps; i++){
    hapcounts[ haplotypes[i][0] ]++;
    hapcounts[ haplotypes[i][1] ]++;
  }

  double sum = 0;
  double nh  = 0;

  for( map<string, int>::iterator it = hapcounts.begin(); it != hapcounts.end(); it++){
    nh  += it->second;
    sum += r8_choose(it->second, 2);
  }

  double max = (sum /  r8_choose(nh, 2));

  return max;

}

void loadPhased(string haplotypes[][2], genotype * pop, int ntarget){

  int indIndex = 0;

  for(vector<string>::iterator ind = pop->gts.begin(); ind != pop->gts.end(); ind++){
    string g = (*ind);
    vector< string > gs = split(g, "|");
    haplotypes[indIndex][0].append(gs[0]);
    haplotypes[indIndex][1].append(gs[1]);
    indIndex += 1;
  }
}

int main(int argc, char** argv) {

  // set the random seed for MCMC

  srand((unsigned)time(NULL));

  // the filename

  string filename = "NA";

  // set region to scaffold

  string region = "NA";

  // using vcflib; thanks to Erik Garrison

  VariantCallFile variantFile;

  // zero based index for the target and background indivudals

  map<int, int> it, ib;

  // deltaaf is the difference of allele frequency we bother to look at

  // ancestral state is set to zero by default

  int counts = 0;

  // phased

  int phased = 0;

  string type = "NA";

    const struct option longopts[] =
      {
	{"version"   , 0, 0, 'v'},
	{"help"      , 0, 0, 'h'},
        {"file"      , 1, 0, 'f'},
	{"target"    , 1, 0, 't'},
	{"region"    , 1, 0, 'r'},
	{"type"      , 1, 0, 'y'},
	{0,0,0,0}
      };

    int findex;
    int iarg=0;

    while(iarg != -1)
      {
	iarg = getopt_long(argc, argv, "y:r:d:t:b:f:hv", longopts, &findex);

	switch (iarg)
	  {
	  case 'h':
	    printHelp();
	  case 'v':
	    printVersion();
	  case 'y':
	    type = optarg;
	    break;
	  case 't':
	    loadIndices(it, optarg);
	    cerr << "INFO: there are " << it.size() << " individuals in the target" << endl;
	    cerr << "INFO: target ids: " << optarg << endl;
	    break;
	  case 'f':
	    cerr << "INFO: file: " << optarg  <<  endl;
	    filename = optarg;
	    break;
	  case 'r':
            cerr << "INFO: set seqid region to : " << optarg << endl;
	    region = optarg;
	    break;
	  default:
	    break;
	  }
      }

    map<string, int> okayGenotypeLikelihoods;
    okayGenotypeLikelihoods["PL"] = 1;
    okayGenotypeLikelihoods["GL"] = 1;
    okayGenotypeLikelihoods["GP"] = 1;
    okayGenotypeLikelihoods["GT"] = 1;

    if(type == "NA"){
      cerr << "FATAL: failed to specify genotype likelihood format : PL or GL" << endl;
      printHelp();
      return 1;
    }
    if(okayGenotypeLikelihoods.find(type) == okayGenotypeLikelihoods.end()){
      cerr << "FATAL: genotype likelihood is incorrectly formatted, only use: PL or GL" << endl;
      printHelp();
      return 1;
    }

    if(filename == "NA"){
      cerr << "FATAL: did not specify a file" << endl;
      printHelp();
      return(1);
    }

    if(it.size() < 2){
      cerr << "FATAL: target option is required -- or -- less than two individuals in target\n";
      printHelp();
      return(1);
    }

    variantFile.open(filename);

    if(region != "NA"){
      if(! variantFile.setRegion(region)){
	cerr <<"FATAL: unable to set region" << endl;
	return 1;
      }
    }

    if (!variantFile.is_open()) {
        return 1;
    }

    Variant var(variantFile);

    vector<int> target_h, background_h;

    int index   = 0;
    int  indexi = 0;

    vector<string> samples = variantFile.sampleNames;
    int nsamples = samples.size();

    for(vector<string>::iterator samp = samples.begin(); samp != samples.end(); samp++){

      string sampleName = (*samp);

      if(it.find(index) != it.end() ){
	target_h.push_back(indexi);
	indexi++;
      }
      index++;
    }

    // cerr << "n in target : " << target_h.size() << endl;

    vector<long int> positions;

    vector<double> afs;

    string haplotypes [target_h.size()][2];

    string currentSeqid = "NA";

    // cerr << "about to loop variants" << endl;

    while (variantFile.getNextVariant(var)) {

      if(!var.isPhased()){
	cerr << "FATAL: Found an unphased variant. All genotypes must be phased!" << endl;
	return(1);
      }

      if(var.alt.size() > 1){
	continue;
      }

      if(currentSeqid != var.sequenceName){
	if(haplotypes[0][0].length() > 10){
	  calc(haplotypes, target_h.size(), afs, positions, target_h, background_h, currentSeqid);
	}
	clearHaplotypes(haplotypes, target_h.size());
	positions.clear();
	currentSeqid = var.sequenceName;
	afs.clear();
      }

      vector < map< string, vector<string> > > target, background, total;

      int sindex = 0;

      for(int nsamp = 0; nsamp < nsamples; nsamp++){

	map<string, vector<string> > sample = var.samples[ samples[nsamp]];

	if(it.find(sindex) != it.end() ){
	  target.push_back(sample);
	}
	sindex += 1;
      }

      genotype * populationTarget    ;

      if(type == "PL"){
	populationTarget     = new pl();
      }
      if(type == "GL"){
	populationTarget     = new gl();
      }
      if(type == "GP"){
	populationTarget     = new gp();
      }
      if(type == "GT"){
	populationTarget     = new gt();
      }

      populationTarget->loadPop(target, var.sequenceName, var.position);

      if(populationTarget->af > 0.95 || populationTarget->af < 0.05){
	delete populationTarget;
	continue;
      }
      positions.push_back(var.position);
      afs.push_back(populationTarget->af);
      loadPhased(haplotypes, populationTarget, populationTarget->gts.size());

      populationTarget = NULL;
      delete populationTarget;
    }

    calc(haplotypes, target_h.size(), afs, positions, target_h, background_h, currentSeqid);

    return 0;
}
<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/sigtools.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct SetundefWorker
{
	int next_bit_mode;
	uint32_t next_bit_state;

	RTLIL::State next_bit()
	{
		if (next_bit_mode == 0)
			return RTLIL::State::S0;

		if (next_bit_mode == 1)
			return RTLIL::State::S1;

		// xorshift32
		next_bit_state ^= next_bit_state << 13;
		next_bit_state ^= next_bit_state >> 17;
		next_bit_state ^= next_bit_state << 5;
		log_assert(next_bit_state != 0);

		return ((next_bit_state >> (next_bit_state & 15)) & 16) ? RTLIL::State::S0 : RTLIL::State::S1;
	}

	void operator()(RTLIL::SigSpec &sig)
	{
		for (auto &bit : sig)
			if (bit.wire == NULL && bit.data > RTLIL::State::S1)
				bit = next_bit();
	}
};

struct SetundefPass : public Pass {
	SetundefPass() : Pass("setundef", "replace undef values with defined constants") { }
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    setundef [options] [selection]\n");
		log("\n");
		log("This command replaced undef (x) constants with defined (0/1) constants.\n");
		log("\n");
		log("    -undriven\n");
		log("        also set undriven nets to constant values\n");
		log("\n");
		log("    -zero\n");
		log("        replace with bits cleared (0)\n");
		log("\n");
		log("    -one\n");
		log("        replace with bits set (1)\n");
		log("\n");
		log("    -random <seed>\n");
		log("        replace with random bits using the specified integer als seed\n");
		log("        value for the random number generator.\n");
		log("\n");
		log("    -init\n");
		log("        also create/update init values for flip-flops\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
	{
		bool got_value = false;
		bool undriven_mode = false;
		bool init_mode = false;
		SetundefWorker worker;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-undriven") {
				undriven_mode = true;
				continue;
			}
			if (args[argidx] == "-zero") {
				got_value = true;
				worker.next_bit_mode = 0;
				continue;
			}
			if (args[argidx] == "-one") {
				got_value = true;
				worker.next_bit_mode = 1;
				continue;
			}
			if (args[argidx] == "-init") {
				init_mode = true;
				continue;
			}
			if (args[argidx] == "-random" && !got_value && argidx+1 < args.size()) {
				got_value = true;
				worker.next_bit_mode = 2;
				worker.next_bit_state = atoi(args[++argidx].c_str()) + 1;
				for (int i = 0; i < 10; i++)
					worker.next_bit();
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		if (!got_value)
			log_cmd_error("One of the options -zero, -one, or -random <seed> must be specified.\n");

		for (auto module : design->selected_modules())
		{
			if (undriven_mode)
			{
				if (!module->processes.empty())
					log_error("The 'setundef' command can't operate in -undriven mode on modules with processes. Run 'proc' first.\n");

				SigMap sigmap(module);
				SigPool undriven_signals;

				for (auto &it : module->wires_)
					if (!it.second->port_input)
						undriven_signals.add(sigmap(it.second));

				CellTypes ct(design);
				for (auto &it : module->cells_)
				for (auto &conn : it.second->connections())
					if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first))
						undriven_signals.del(sigmap(conn.second));

				RTLIL::SigSpec sig = undriven_signals.export_all();
				for (auto &c : sig.chunks()) {
					RTLIL::SigSpec bits;
					for (int i = 0; i < c.width; i++)
						bits.append(worker.next_bit());
					module->connect(RTLIL::SigSig(c, bits));
				}
			}

			if (init_mode)
			{
				SigMap sigmap(module);
				pool<SigBit> ffbits;
				pool<Wire*> initwires;

				pool<IdString> fftypes;
				fftypes.insert("$dff");
				fftypes.insert("$dffe");
				fftypes.insert("$dffsr");
				fftypes.insert("$adff");

				std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};

				for (auto c1 : list_np)
					fftypes.insert(stringf("$_DFF_%c_", c1));

				for (auto c1 : list_np)
				for (auto c2 : list_np)
					fftypes.insert(stringf("$_DFFE_%c%c_", c1, c2));

				for (auto c1 : list_np)
				for (auto c2 : list_np)
				for (auto c3 : list_01)
					fftypes.insert(stringf("$_DFF_%c%c%c_", c1, c2, c3));

				for (auto c1 : list_np)
				for (auto c2 : list_np)
				for (auto c3 : list_np)
					fftypes.insert(stringf("$_DFFSR_%c%c%c_", c1, c2, c3));

				for (auto cell : module->cells())
				{
					if (!fftypes.count(cell->type))
						continue;

					for (auto bit : sigmap(cell->getPort("\\Q")))
						ffbits.insert(bit);
				}

				for (auto wire : module->wires())
				{
					if (!wire->attributes.count("\\init"))
						continue;

					for (auto bit : sigmap(wire))
						ffbits.erase(bit);

					initwires.insert(wire);
				}

				for (int wire_types = 0; wire_types < 2; wire_types++)
					for (auto wire : module->wires())
					{
						if (wire->name[0] == (wire_types ? '\\' : '$'))
					next_wire:
							continue;

						for (auto bit : sigmap(wire))
							if (!ffbits.count(bit))
								goto next_wire;

						for (auto bit : sigmap(wire))
							ffbits.erase(bit);

						initwires.insert(wire);
					}

				for (auto wire : initwires)
				{
					Const &initval = wire->attributes["\\init"];

					for (int i = 0; i < GetSize(wire); i++)
						if (GetSize(initval) <= i)
							initval.bits.push_back(worker.next_bit());
						else if (initval.bits[i] == State::Sx)
							initval.bits[i] = worker.next_bit();
				}
			}

			module->rewrite_sigspecs(worker);
		}
	}
} SetundefPass;

PRIVATE_NAMESPACE_END
<commit_msg>Bugfix in "setundef" pass<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/sigtools.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct SetundefWorker
{
	int next_bit_mode;
	uint32_t next_bit_state;

	RTLIL::State next_bit()
	{
		if (next_bit_mode == 0)
			return RTLIL::State::S0;

		if (next_bit_mode == 1)
			return RTLIL::State::S1;

		// xorshift32
		next_bit_state ^= next_bit_state << 13;
		next_bit_state ^= next_bit_state >> 17;
		next_bit_state ^= next_bit_state << 5;
		log_assert(next_bit_state != 0);

		return ((next_bit_state >> (next_bit_state & 15)) & 16) ? RTLIL::State::S0 : RTLIL::State::S1;
	}

	void operator()(RTLIL::SigSpec &sig)
	{
		for (auto &bit : sig)
			if (bit.wire == NULL && bit.data > RTLIL::State::S1)
				bit = next_bit();
	}
};

struct SetundefPass : public Pass {
	SetundefPass() : Pass("setundef", "replace undef values with defined constants") { }
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    setundef [options] [selection]\n");
		log("\n");
		log("This command replaced undef (x) constants with defined (0/1) constants.\n");
		log("\n");
		log("    -undriven\n");
		log("        also set undriven nets to constant values\n");
		log("\n");
		log("    -zero\n");
		log("        replace with bits cleared (0)\n");
		log("\n");
		log("    -one\n");
		log("        replace with bits set (1)\n");
		log("\n");
		log("    -random <seed>\n");
		log("        replace with random bits using the specified integer als seed\n");
		log("        value for the random number generator.\n");
		log("\n");
		log("    -init\n");
		log("        also create/update init values for flip-flops\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
	{
		bool got_value = false;
		bool undriven_mode = false;
		bool init_mode = false;
		SetundefWorker worker;

		log_header(design, "Executing SETUNDEF pass (replace undef values with defined constants).\n");

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++)
		{
			if (args[argidx] == "-undriven") {
				undriven_mode = true;
				continue;
			}
			if (args[argidx] == "-zero") {
				got_value = true;
				worker.next_bit_mode = 0;
				continue;
			}
			if (args[argidx] == "-one") {
				got_value = true;
				worker.next_bit_mode = 1;
				continue;
			}
			if (args[argidx] == "-init") {
				init_mode = true;
				continue;
			}
			if (args[argidx] == "-random" && !got_value && argidx+1 < args.size()) {
				got_value = true;
				worker.next_bit_mode = 2;
				worker.next_bit_state = atoi(args[++argidx].c_str()) + 1;
				for (int i = 0; i < 10; i++)
					worker.next_bit();
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		if (!got_value)
			log_cmd_error("One of the options -zero, -one, or -random <seed> must be specified.\n");

		for (auto module : design->selected_modules())
		{
			if (undriven_mode)
			{
				if (!module->processes.empty())
					log_error("The 'setundef' command can't operate in -undriven mode on modules with processes. Run 'proc' first.\n");

				SigMap sigmap(module);
				SigPool undriven_signals;

				for (auto &it : module->wires_)
					undriven_signals.add(sigmap(it.second));

				for (auto &it : module->wires_)
					if (it.second->port_input)
						undriven_signals.del(sigmap(it.second));

				CellTypes ct(design);
				for (auto &it : module->cells_)
				for (auto &conn : it.second->connections())
					if (!ct.cell_known(it.second->type) || ct.cell_output(it.second->type, conn.first))
						undriven_signals.del(sigmap(conn.second));

				RTLIL::SigSpec sig = undriven_signals.export_all();
				for (auto &c : sig.chunks()) {
					RTLIL::SigSpec bits;
					for (int i = 0; i < c.width; i++)
						bits.append(worker.next_bit());
					module->connect(RTLIL::SigSig(c, bits));
				}
			}

			if (init_mode)
			{
				SigMap sigmap(module);
				pool<SigBit> ffbits;
				pool<Wire*> initwires;

				pool<IdString> fftypes;
				fftypes.insert("$dff");
				fftypes.insert("$dffe");
				fftypes.insert("$dffsr");
				fftypes.insert("$adff");

				std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};

				for (auto c1 : list_np)
					fftypes.insert(stringf("$_DFF_%c_", c1));

				for (auto c1 : list_np)
				for (auto c2 : list_np)
					fftypes.insert(stringf("$_DFFE_%c%c_", c1, c2));

				for (auto c1 : list_np)
				for (auto c2 : list_np)
				for (auto c3 : list_01)
					fftypes.insert(stringf("$_DFF_%c%c%c_", c1, c2, c3));

				for (auto c1 : list_np)
				for (auto c2 : list_np)
				for (auto c3 : list_np)
					fftypes.insert(stringf("$_DFFSR_%c%c%c_", c1, c2, c3));

				for (auto cell : module->cells())
				{
					if (!fftypes.count(cell->type))
						continue;

					for (auto bit : sigmap(cell->getPort("\\Q")))
						ffbits.insert(bit);
				}

				for (auto wire : module->wires())
				{
					if (!wire->attributes.count("\\init"))
						continue;

					for (auto bit : sigmap(wire))
						ffbits.erase(bit);

					initwires.insert(wire);
				}

				for (int wire_types = 0; wire_types < 2; wire_types++)
					for (auto wire : module->wires())
					{
						if (wire->name[0] == (wire_types ? '\\' : '$'))
					next_wire:
							continue;

						for (auto bit : sigmap(wire))
							if (!ffbits.count(bit))
								goto next_wire;

						for (auto bit : sigmap(wire))
							ffbits.erase(bit);

						initwires.insert(wire);
					}

				for (auto wire : initwires)
				{
					Const &initval = wire->attributes["\\init"];

					for (int i = 0; i < GetSize(wire); i++)
						if (GetSize(initval) <= i)
							initval.bits.push_back(worker.next_bit());
						else if (initval.bits[i] == State::Sx)
							initval.bits[i] = worker.next_bit();
				}
			}

			module->rewrite_sigspecs(worker);
		}
	}
} SetundefPass;

PRIVATE_NAMESPACE_END
<|endoftext|>


<commit_before>#include "hmac.h"

Persistent<FunctionTemplate> Hmac::constructor;

void Hmac::Initialize(Handle<Object> target) {
  HandleScope scope;

  constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(Hmac::New));
  constructor->InstanceTemplate()->SetInternalFieldCount(1);
  constructor->SetClassName(String::NewSymbol("Hmac"));

  NODE_SET_PROTOTYPE_METHOD(constructor, "init", HmacInit);
  NODE_SET_PROTOTYPE_METHOD(constructor, "update", HmacUpdate);
  NODE_SET_PROTOTYPE_METHOD(constructor, "digest", HmacDigest);
  Local<ObjectTemplate> proto = constructor->PrototypeTemplate();

  target->Set(String::NewSymbol("Hmac"), constructor->GetFunction());
}

bool Hmac::HmacInit(char* hashType, char* key, int key_len) {
  md = EVP_get_digestbyname(hashType);
  if(!md) {
    fprintf(stderr, "node-crypto : Unknown message digest %s\n", hashType);
    return false;
  }

  HMAC_CTX_init(&ctx2);
  // HMAC_Init(ctx, key, key_len, md);
  HMAC_Init_ex(&ctx2, key, key_len, md, NULL);
  initialised_ = true;
  return true;
}

Handle<Value> Hmac::HmacInit(const Arguments& args) {
  Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());

  HandleScope scope;

  if (args.Length() == 0 || !args[0]->IsString()) {
    return ThrowException(Exception::Error(String::New(
      "Must give hashtype string as argument")));
  }

  ASSERT_IS_STRING_OR_BUFFER(args[1]);
  ssize_t len = DecodeBytes(args[1], BINARY);

  if (len < 0) {
    Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
    return ThrowException(exception);
  }

  char* buf = new char[len];
  ssize_t written = DecodeWrite(buf, len, args[1], BINARY);
  assert(written == len);

  String::Utf8Value hashType(args[0]->ToString());

  bool r = hmac->HmacInit(*hashType, buf, len);

  delete [] buf;

  if (!r) {
    return ThrowException(Exception::Error(String::New("hmac error")));
  }

  return args.This();
}

int Hmac::HmacUpdate(char* data, int len) {
  if (!initialised_) return 0;
  HMAC_Update(&ctx2, (unsigned char*)data, len);
  return 1;
}

Handle<Value> Hmac::HmacUpdate(const Arguments& args) {
  Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());

  HandleScope scope;

  ASSERT_IS_STRING_OR_BUFFER(args[0]);
  enum encoding enc = ParseEncoding(args[1]);
  ssize_t len = DecodeBytes(args[0], enc);

  if (len < 0) {
    Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
    return ThrowException(exception);
  }

  int r;

  if(Buffer::HasInstance(args[0])) {
    Local<Object> buffer_obj = args[0]->ToObject();
    char *buffer_data = Buffer::Data(buffer_obj);
    size_t buffer_length = Buffer::Length(buffer_obj);

    r = hmac->HmacUpdate(buffer_data, buffer_length);
  } else {
    char* buf = new char[len];
    ssize_t written = DecodeWrite(buf, len, args[0], enc);
    assert(written == len);
    r = hmac->HmacUpdate(buf, len);
    delete [] buf;
  }

  if (!r) {
    Local<Value> exception = Exception::TypeError(String::New("HmacUpdate fail"));
    return ThrowException(exception);
  }

  return args.This();
}

Handle<Value> Hmac::HmacDigest(const Arguments& args) {
  Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());

  HandleScope scope;

  unsigned char* md_value;
  unsigned int md_len;
  char* md_hexdigest;
  int md_hex_len;
  Local<Value> outString ;

  int r = hmac->HmacDigest(&md_value, &md_len);

  if (md_len == 0 || r == 0) {
    return scope.Close(String::New(""));
  }

  if (args.Length() == 0 || !args[0]->IsString()) {
    // Binary
    outString = Encode(md_value, md_len, BINARY);
  } else {
    String::Utf8Value encoding(args[0]->ToString());
    if (strcasecmp(*encoding, "hex") == 0) {
      // Hex encoding
      HexEncode(md_value, md_len, &md_hexdigest, &md_hex_len);
      outString = Encode(md_hexdigest, md_hex_len, BINARY);
      delete [] md_hexdigest;
    } else if (strcasecmp(*encoding, "base64") == 0) {
      base64(md_value, md_len, &md_hexdigest, &md_hex_len);
      outString = Encode(md_hexdigest, md_hex_len, BINARY);
      delete [] md_hexdigest;
    } else if (strcasecmp(*encoding, "binary") == 0) {
      outString = Encode(md_value, md_len, BINARY);
    } else {
      fprintf(stderr, "node-crypto : Hmac .digest encoding "
                      "can be binary, hex or base64\n");
    }
  }
  delete [] md_value;
  return scope.Close(outString);
}

int Hmac::HmacDigest(unsigned char** md_value, unsigned int *md_len) {
  if (!initialised_) return 0;
  *md_value = new unsigned char[EVP_MAX_MD_SIZE];
  HMAC_Final(&ctx2, *md_value, md_len);
  HMAC_CTX_cleanup(&ctx2);
  initialised_ = false;
  return 1;
}

Handle<Value> Hmac::New(const Arguments &args) {
  HandleScope scope;

  Hmac *hmac = new Hmac();
  hmac->Wrap(args.This());

  return args.This();
}

Hmac::Hmac() : ObjectWrap() {
  initialised_ = false;
  // HMAC_CTX_init(&ctx2);
  ctx = (HMAC_CTX *)OPENSSL_malloc(sizeof(HMAC_CTX));
  // ctx = &ctx2;
  fprintf(stderr, "%d \n", &ctx2);
  fprintf(stderr, "%d \n", sizeof(HMAC_CTX));
}

Hmac::~Hmac() {
  // OPENSSL_free(&ctx2);
}
<commit_msg>fix the *2 sizeof in HMAC when able<commit_after>#include "hmac.h"

Persistent<FunctionTemplate> Hmac::constructor;

void Hmac::Initialize(Handle<Object> target) {
  HandleScope scope;

  constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(Hmac::New));
  constructor->InstanceTemplate()->SetInternalFieldCount(1);
  constructor->SetClassName(String::NewSymbol("Hmac"));

  NODE_SET_PROTOTYPE_METHOD(constructor, "init", HmacInit);
  NODE_SET_PROTOTYPE_METHOD(constructor, "update", HmacUpdate);
  NODE_SET_PROTOTYPE_METHOD(constructor, "digest", HmacDigest);
  Local<ObjectTemplate> proto = constructor->PrototypeTemplate();

  target->Set(String::NewSymbol("Hmac"), constructor->GetFunction());
}

bool Hmac::HmacInit(char* hashType, char* key, int key_len) {
  md = EVP_get_digestbyname(hashType);
  if(!md) {
    fprintf(stderr, "node-crypto : Unknown message digest %s\n", hashType);
    return false;
  }

  HMAC_CTX_init(ctx);
  HMAC_Init(ctx, key, key_len, md);
  // HMAC_Init_ex(&ctx2, key, key_len, md, NULL);
  initialised_ = true;
  return true;
}

Handle<Value> Hmac::HmacInit(const Arguments& args) {
  Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());

  HandleScope scope;

  if (args.Length() == 0 || !args[0]->IsString()) {
    return ThrowException(Exception::Error(String::New(
      "Must give hashtype string as argument")));
  }

  ASSERT_IS_STRING_OR_BUFFER(args[1]);
  ssize_t len = DecodeBytes(args[1], BINARY);

  if (len < 0) {
    Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
    return ThrowException(exception);
  }

  char* buf = new char[len];
  ssize_t written = DecodeWrite(buf, len, args[1], BINARY);
  assert(written == len);

  String::Utf8Value hashType(args[0]->ToString());

  bool r = hmac->HmacInit(*hashType, buf, len);

  delete [] buf;

  if (!r) {
    return ThrowException(Exception::Error(String::New("hmac error")));
  }

  return args.This();
}

int Hmac::HmacUpdate(char* data, int len) {
  if (!initialised_) return 0;
  HMAC_Update(ctx, (unsigned char*)data, len);
  return 1;
}

Handle<Value> Hmac::HmacUpdate(const Arguments& args) {
  Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());

  HandleScope scope;

  ASSERT_IS_STRING_OR_BUFFER(args[0]);
  enum encoding enc = ParseEncoding(args[1]);
  ssize_t len = DecodeBytes(args[0], enc);

  if (len < 0) {
    Local<Value> exception = Exception::TypeError(String::New("Bad argument"));
    return ThrowException(exception);
  }

  int r;

  if(Buffer::HasInstance(args[0])) {
    Local<Object> buffer_obj = args[0]->ToObject();
    char *buffer_data = Buffer::Data(buffer_obj);
    size_t buffer_length = Buffer::Length(buffer_obj);

    r = hmac->HmacUpdate(buffer_data, buffer_length);
  } else {
    char* buf = new char[len];
    ssize_t written = DecodeWrite(buf, len, args[0], enc);
    assert(written == len);
    r = hmac->HmacUpdate(buf, len);
    delete [] buf;
  }

  if (!r) {
    Local<Value> exception = Exception::TypeError(String::New("HmacUpdate fail"));
    return ThrowException(exception);
  }

  return args.This();
}

Handle<Value> Hmac::HmacDigest(const Arguments& args) {
  Hmac *hmac = ObjectWrap::Unwrap<Hmac>(args.This());

  HandleScope scope;

  unsigned char* md_value;
  unsigned int md_len;
  char* md_hexdigest;
  int md_hex_len;
  Local<Value> outString ;

  int r = hmac->HmacDigest(&md_value, &md_len);

  if (md_len == 0 || r == 0) {
    return scope.Close(String::New(""));
  }

  if (args.Length() == 0 || !args[0]->IsString()) {
    // Binary
    outString = Encode(md_value, md_len, BINARY);
  } else {
    String::Utf8Value encoding(args[0]->ToString());
    if (strcasecmp(*encoding, "hex") == 0) {
      // Hex encoding
      HexEncode(md_value, md_len, &md_hexdigest, &md_hex_len);
      outString = Encode(md_hexdigest, md_hex_len, BINARY);
      delete [] md_hexdigest;
    } else if (strcasecmp(*encoding, "base64") == 0) {
      base64(md_value, md_len, &md_hexdigest, &md_hex_len);
      outString = Encode(md_hexdigest, md_hex_len, BINARY);
      delete [] md_hexdigest;
    } else if (strcasecmp(*encoding, "binary") == 0) {
      outString = Encode(md_value, md_len, BINARY);
    } else {
      fprintf(stderr, "node-crypto : Hmac .digest encoding "
                      "can be binary, hex or base64\n");
    }
  }
  delete [] md_value;
  return scope.Close(outString);
}

int Hmac::HmacDigest(unsigned char** md_value, unsigned int *md_len) {
  if (!initialised_) return 0;
  *md_value = new unsigned char[EVP_MAX_MD_SIZE];
  HMAC_Final(ctx, *md_value, md_len);
  HMAC_CTX_cleanup(ctx);
  initialised_ = false;
  return 1;
}

Handle<Value> Hmac::New(const Arguments &args) {
  HandleScope scope;

  Hmac *hmac = new Hmac();
  hmac->Wrap(args.This());

  return args.This();
}

Hmac::Hmac() : ObjectWrap() {
  initialised_ = false;
  //FIXME
  ctx = (HMAC_CTX *)OPENSSL_malloc(sizeof(HMAC_CTX)*2);
}

Hmac::~Hmac() {
  OPENSSL_free(ctx);
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////

#include "MMFilesRestWalHandler.h"
#include "Basics/VelocyPackHelper.h"
#include "Cluster/ClusterMethods.h"
#include "Cluster/ServerState.h"
#include "MMFiles/MMFilesLogfileManager.h"

using namespace arangodb;
using namespace arangodb::rest;

MMFilesRestWalHandler::MMFilesRestWalHandler(
    GeneralRequest* request, GeneralResponse* response)
    : RestVocbaseBaseHandler(request, response) {}

RestStatus MMFilesRestWalHandler::execute() {
  std::vector<std::string> const& suffixes = _request->suffixes();

  if (suffixes.size() != 1) {
    generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                  "expecting /_admin/wal/<operation>");
    return RestStatus::DONE;
  }

  std::string const& operation = suffixes[0];

  // extract the sub-request type
  auto const type = _request->requestType();

  if (operation == "transactions") {
    if (type == rest::RequestType::GET) {
      transactions();
      return RestStatus::DONE;
    }
  } else if (operation == "flush") {
    if (type == rest::RequestType::PUT) {
      flush();
      return RestStatus::DONE;
    }
  } else if (operation == "properties") {
    if (type == rest::RequestType::GET || type == rest::RequestType::PUT) {
      properties();
      return RestStatus::DONE;
    }
  } else {
    generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                  "expecting /_admin/wal/<operation>");
    return RestStatus::DONE;
  }

  generateError(rest::ResponseCode::METHOD_NOT_ALLOWED,
                TRI_ERROR_HTTP_METHOD_NOT_ALLOWED);
  return RestStatus::DONE;
}

void MMFilesRestWalHandler::properties() {
  auto l = MMFilesLogfileManager::instance();

  if (_request->requestType() == rest::RequestType::PUT) {
    std::shared_ptr<VPackBuilder> parsedRequest;
    VPackSlice slice;
    try {
      slice = _request->payload();
    } catch (...) {
      generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                    "invalid body value. expecting object");
      return;
    }
    if (!slice.isObject()) {
      generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                    "invalid body value. expecting object");
    }

    if (slice.hasKey("allowOversizeEntries")) {
      bool value = slice.get("allowOversizeEntries").getBoolean();
      l->allowOversizeEntries(value);
    }

    if (slice.hasKey("logfileSize")) {
      uint32_t value = slice.get("logfileSize").getNumericValue<uint32_t>();
      l->filesize(value);
    }

    if (slice.hasKey("historicLogfiles")) {
      uint32_t value = slice.get("historicLogfiles").getNumericValue<uint32_t>();
      l->historicLogfiles(value);
    }

    if (slice.hasKey("reserveLogfiles")) {
      uint32_t value = slice.get("reserveLogfiles").getNumericValue<uint32_t>();
      l->reserveLogfiles(value);
    }

    if (slice.hasKey("throttleWait")) {
      uint64_t value = slice.get("throttleWait").getNumericValue<uint64_t>();
      l->maxThrottleWait(value);
    }

    if (slice.hasKey("throttleWhenPending")) {
      uint64_t value = slice.get("throttleWhenPending").getNumericValue<uint64_t>();
      l->throttleWhenPending(value);
    }
  }

  VPackBuilder builder;
  builder.openObject();
  builder.add("allowOversizeEntries", VPackValue(l->allowOversizeEntries()));
  builder.add("logfileSize", VPackValue(l->filesize()));
  builder.add("historicLogfiles", VPackValue(l->historicLogfiles()));
  builder.add("reserveLogfiles", VPackValue(l->reserveLogfiles()));
  builder.add("syncInterval", VPackValue(l->syncInterval()));
  builder.add("throttleWait", VPackValue(l->maxThrottleWait()));
  builder.add("throttleWhenPending", VPackValue(l->throttleWhenPending()));

  builder.close();
  generateResult(rest::ResponseCode::OK, builder.slice());
}

void MMFilesRestWalHandler::flush() {
  std::shared_ptr<VPackBuilder> parsedRequest;
  VPackSlice slice;
  try {
    slice = _request->payload();
  } catch (...) {
    generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                  "invalid body value. expecting object");
    return;
  }
  if (!slice.isObject() && !slice.isNone()) {
    generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                  "invalid body value. expecting object");
  }

  bool waitForSync = false;
  bool waitForCollector = false;

  if (slice.isObject()) {
    // got a request body
    VPackSlice value = slice.get("waitForSync");
    if (value.isString()) {
      waitForSync = (value.copyString() == "true");
    } else if (value.isBoolean()) {
      waitForSync = value.getBoolean();
    }

    value = slice.get("waitForCollector");
    if (value.isString()) {
      waitForCollector = (value.copyString() == "true");
    } else if (value.isBoolean()) {
      waitForCollector = value.getBoolean();
    }
  } else {
    // no request body
    bool found;
    {
      std::string const& v = _request->value("waitForSync", found);
      if (found) {
        waitForSync = (v == "1" || v == "true");
      }
    }
    {
      std::string const& v = _request->value("waitForCollector", found);
      if (found) {
        waitForCollector = (v == "1" || v == "true");
      }
    }
  }

  int res;
  if (ServerState::instance()->isCoordinator()) {
    res = flushWalOnAllDBServers(waitForSync, waitForCollector);
  } else {
    res = MMFilesLogfileManager::instance()->flush(
        waitForSync, waitForCollector, false);
  }

  if (res != TRI_ERROR_NO_ERROR) {
    THROW_ARANGO_EXCEPTION(res);
  }

  generateResult(rest::ResponseCode::OK, basics::VelocyPackHelper::EmptyObjectValue());
}

void MMFilesRestWalHandler::transactions() {
  auto const& info =
      MMFilesLogfileManager::instance()->runningTransactions();

  VPackBuilder builder;
  builder.openObject();
  builder.add("runningTransactions", VPackValue(static_cast<double>(std::get<0>(info))));

  // lastCollectedId
  {
    auto value = std::get<1>(info);
    if (value == UINT64_MAX) {
      builder.add("minLastCollected", VPackValue(VPackValueType::Null));
    } else {
      builder.add("minLastCollected", VPackValue(value));
    }
  }

  // lastSealedId
  {
    auto value = std::get<2>(info);
    if (value == UINT64_MAX) {
      builder.add("minLastSealed", VPackValue(VPackValueType::Null));
    } else {
      builder.add("minLastSealed", VPackValue(value));
    }
  }

  builder.close();

  generateResult(rest::ResponseCode::OK, builder.slice());
}
<commit_msg>issue #2505<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////

#include "MMFilesRestWalHandler.h"
#include "Basics/VelocyPackHelper.h"
#include "Cluster/ClusterMethods.h"
#include "Cluster/ServerState.h"
#include "MMFiles/MMFilesLogfileManager.h"

using namespace arangodb;
using namespace arangodb::rest;

MMFilesRestWalHandler::MMFilesRestWalHandler(
    GeneralRequest* request, GeneralResponse* response)
    : RestVocbaseBaseHandler(request, response) {}

RestStatus MMFilesRestWalHandler::execute() {
  std::vector<std::string> const& suffixes = _request->suffixes();

  if (suffixes.size() != 1) {
    generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                  "expecting /_admin/wal/<operation>");
    return RestStatus::DONE;
  }

  std::string const& operation = suffixes[0];

  // extract the sub-request type
  auto const type = _request->requestType();

  if (operation == "transactions") {
    if (type == rest::RequestType::GET) {
      transactions();
      return RestStatus::DONE;
    }
  } else if (operation == "flush") {
    if (type == rest::RequestType::PUT) {
      flush();
      return RestStatus::DONE;
    }
  } else if (operation == "properties") {
    if (type == rest::RequestType::GET || type == rest::RequestType::PUT) {
      properties();
      return RestStatus::DONE;
    }
  } else {
    generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                  "expecting /_admin/wal/<operation>");
    return RestStatus::DONE;
  }

  generateError(rest::ResponseCode::METHOD_NOT_ALLOWED,
                TRI_ERROR_HTTP_METHOD_NOT_ALLOWED);
  return RestStatus::DONE;
}

void MMFilesRestWalHandler::properties() {
  auto l = MMFilesLogfileManager::instance();

  if (_request->requestType() == rest::RequestType::PUT) {
    std::shared_ptr<VPackBuilder> parsedRequest;
    VPackSlice slice;
    try {
      slice = _request->payload();
    } catch (...) {
      generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                    "invalid body value. expecting object");
      return;
    }
    if (!slice.isObject()) {
      generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                    "invalid body value. expecting object");
      return;
    }

    if (slice.hasKey("allowOversizeEntries")) {
      bool value = slice.get("allowOversizeEntries").getBoolean();
      l->allowOversizeEntries(value);
    }

    if (slice.hasKey("logfileSize")) {
      uint32_t value = slice.get("logfileSize").getNumericValue<uint32_t>();
      l->filesize(value);
    }

    if (slice.hasKey("historicLogfiles")) {
      uint32_t value = slice.get("historicLogfiles").getNumericValue<uint32_t>();
      l->historicLogfiles(value);
    }

    if (slice.hasKey("reserveLogfiles")) {
      uint32_t value = slice.get("reserveLogfiles").getNumericValue<uint32_t>();
      l->reserveLogfiles(value);
    }

    if (slice.hasKey("throttleWait")) {
      uint64_t value = slice.get("throttleWait").getNumericValue<uint64_t>();
      l->maxThrottleWait(value);
    }

    if (slice.hasKey("throttleWhenPending")) {
      uint64_t value = slice.get("throttleWhenPending").getNumericValue<uint64_t>();
      l->throttleWhenPending(value);
    }
  }

  VPackBuilder builder;
  builder.openObject();
  builder.add("allowOversizeEntries", VPackValue(l->allowOversizeEntries()));
  builder.add("logfileSize", VPackValue(l->filesize()));
  builder.add("historicLogfiles", VPackValue(l->historicLogfiles()));
  builder.add("reserveLogfiles", VPackValue(l->reserveLogfiles()));
  builder.add("syncInterval", VPackValue(l->syncInterval()));
  builder.add("throttleWait", VPackValue(l->maxThrottleWait()));
  builder.add("throttleWhenPending", VPackValue(l->throttleWhenPending()));

  builder.close();
  generateResult(rest::ResponseCode::OK, builder.slice());
}

void MMFilesRestWalHandler::flush() {
  std::shared_ptr<VPackBuilder> parsedRequest;
  VPackSlice slice;
  try {
    slice = _request->payload();
  } catch (...) {
    generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                  "invalid body value. expecting object");
    return;
  }
  if (!slice.isObject() && !slice.isNone()) {
    generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
                  "invalid body value. expecting object");
  }

  bool waitForSync = false;
  bool waitForCollector = false;

  if (slice.isObject()) {
    // got a request body
    VPackSlice value = slice.get("waitForSync");
    if (value.isString()) {
      waitForSync = (value.copyString() == "true");
    } else if (value.isBoolean()) {
      waitForSync = value.getBoolean();
    }

    value = slice.get("waitForCollector");
    if (value.isString()) {
      waitForCollector = (value.copyString() == "true");
    } else if (value.isBoolean()) {
      waitForCollector = value.getBoolean();
    }
  } else {
    // no request body
    bool found;
    {
      std::string const& v = _request->value("waitForSync", found);
      if (found) {
        waitForSync = (v == "1" || v == "true");
      }
    }
    {
      std::string const& v = _request->value("waitForCollector", found);
      if (found) {
        waitForCollector = (v == "1" || v == "true");
      }
    }
  }

  int res;
  if (ServerState::instance()->isCoordinator()) {
    res = flushWalOnAllDBServers(waitForSync, waitForCollector);
  } else {
    res = MMFilesLogfileManager::instance()->flush(
        waitForSync, waitForCollector, false);
  }

  if (res != TRI_ERROR_NO_ERROR) {
    THROW_ARANGO_EXCEPTION(res);
  }

  generateResult(rest::ResponseCode::OK, basics::VelocyPackHelper::EmptyObjectValue());
}

void MMFilesRestWalHandler::transactions() {
  auto const& info =
      MMFilesLogfileManager::instance()->runningTransactions();

  VPackBuilder builder;
  builder.openObject();
  builder.add("runningTransactions", VPackValue(static_cast<double>(std::get<0>(info))));

  // lastCollectedId
  {
    auto value = std::get<1>(info);
    if (value == UINT64_MAX) {
      builder.add("minLastCollected", VPackValue(VPackValueType::Null));
    } else {
      builder.add("minLastCollected", VPackValue(value));
    }
  }

  // lastSealedId
  {
    auto value = std::get<2>(info);
    if (value == UINT64_MAX) {
      builder.add("minLastSealed", VPackValue(VPackValueType::Null));
    } else {
      builder.add("minLastSealed", VPackValue(value));
    }
  }

  builder.close();

  generateResult(rest::ResponseCode::OK, builder.slice());
}
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file EthashAux.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "EthashAux.h"

#include <boost/detail/endian.hpp>
#include <boost/filesystem.hpp>
#include <chrono>
#include <array>
#include <random>
#include <thread>
#include <libdevcore/Common.h>
#include <libdevcore/Guards.h>
#include <libdevcore/Log.h>
#include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcrypto/FileSystem.h>
#include <libethash/internal.h>
#include "BlockInfo.h"
#include "Exceptions.h"
using namespace std;
using namespace chrono;
using namespace dev;
using namespace eth;

EthashAux* dev::eth::EthashAux::s_this = nullptr;

EthashAux::~EthashAux()
{
}

uint64_t EthashAux::cacheSize(BlockInfo const& _header)
{
	return ethash_get_cachesize((uint64_t)_header.number);
}

h256 EthashAux::seedHash(unsigned _number)
{
	unsigned epoch = _number / ETHASH_EPOCH_LENGTH;
	Guard l(get()->x_epochs);
	if (epoch >= get()->m_seedHashes.size())
	{
		h256 ret;
		unsigned n = 0;
		if (!get()->m_seedHashes.empty())
		{
			ret = get()->m_seedHashes.back();
			n = get()->m_seedHashes.size() - 1;
		}
		get()->m_seedHashes.resize(epoch + 1);
//		cdebug << "Searching for seedHash of epoch " << epoch;
		for (; n <= epoch; ++n, ret = sha3(ret))
		{
			get()->m_seedHashes[n] = ret;
//			cdebug << "Epoch" << n << "is" << ret;
		}
	}
	return get()->m_seedHashes[epoch];
}

void EthashAux::killCache(h256 const& _s)
{
	RecursiveGuard l(x_this);
	m_lights.erase(_s);
}

EthashAux::LightType EthashAux::light(BlockInfo const& _header)
{
	return light((uint64_t)_header.number);
}

EthashAux::LightType EthashAux::light(uint64_t _blockNumber)
{
	RecursiveGuard l(get()->x_this);
	h256 seedHash = EthashAux::seedHash(_blockNumber);
	LightType ret = get()->m_lights[seedHash];
	return ret ? ret : (get()->m_lights[seedHash] = make_shared<LightAllocation>(_blockNumber));
}

EthashAux::LightAllocation::LightAllocation(uint64_t _blockNumber)
{
	light = ethash_light_new(_blockNumber);
	size = ethash_get_cachesize(_blockNumber);
}

EthashAux::LightAllocation::~LightAllocation()
{
	ethash_light_delete(light);
}

bytesConstRef EthashAux::LightAllocation::data() const
{
	return bytesConstRef((byte const*)light->cache, size);
}

EthashAux::FullAllocation::FullAllocation(ethash_light_t _light, ethash_callback_t _cb)
{
	full = ethash_full_new(_light, _cb);
}

EthashAux::FullAllocation::~FullAllocation()
{
	ethash_full_delete(full);
}

bytesConstRef EthashAux::FullAllocation::data() const
{
	return bytesConstRef((byte const*)ethash_full_dag(full), size());
}

EthashAux::FullType EthashAux::full(BlockInfo const& _header)
{
	return full((uint64_t) _header.number);
}

EthashAux::FullType EthashAux::full(uint64_t _blockNumber)
{
	RecursiveGuard l(get()->x_this);
	h256 seedHash = EthashAux::seedHash(_blockNumber);
	FullType ret;
	if ((ret = get()->m_fulls[seedHash].lock()))
	{
		get()->m_lastUsedFull = ret;
		return ret;
	}
	ret = get()->m_lastUsedFull = make_shared<FullAllocation>(light(_blockNumber)->light, nullptr);
	get()->m_fulls[seedHash] = ret;
	return ret;
}

Ethash::Result EthashAux::FullAllocation::compute(h256 const& _headerHash, Nonce const& _nonce) const
{
	ethash_return_value_t r = ethash_full_compute(full, *(ethash_h256_t*)_headerHash.data(), (uint64_t)(u64)_nonce);
	if (!r.success)
		BOOST_THROW_EXCEPTION(DAGCreationFailure());
	return Ethash::Result{h256((uint8_t*)&r.result, h256::ConstructFromPointer), h256((uint8_t*)&r.mix_hash, h256::ConstructFromPointer)};
}

Ethash::Result EthashAux::LightAllocation::compute(h256 const& _headerHash, Nonce const& _nonce) const
{
	ethash_return_value r = ethash_light_compute(light, *(ethash_h256_t*)_headerHash.data(), (uint64_t)(u64)_nonce);
	if (!r.success)
		BOOST_THROW_EXCEPTION(DAGCreationFailure());
	return Ethash::Result{h256((uint8_t*)&r.result, h256::ConstructFromPointer), h256((uint8_t*)&r.mix_hash, h256::ConstructFromPointer)};
}

Ethash::Result EthashAux::eval(BlockInfo const& _header, Nonce const& _nonce)
{
	return eval((uint64_t)_header.number, _header.headerHash(WithoutNonce), _nonce);
}

Ethash::Result EthashAux::eval(uint64_t _blockNumber, h256 const& _headerHash, Nonce const& _nonce)
{
	h256 seedHash = EthashAux::seedHash(_blockNumber);
	if (FullType dag = get()->m_fulls[seedHash].lock())
		return dag->compute(_headerHash, _nonce);
	return EthashAux::get()->light(_blockNumber)->compute(_headerHash, _nonce);
}
<commit_msg>Add simple callback for DAG generation progress reporting<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file EthashAux.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 */

#include "EthashAux.h"

#include <boost/detail/endian.hpp>
#include <boost/filesystem.hpp>
#include <chrono>
#include <array>
#include <random>
#include <thread>
#include <libdevcore/Common.h>
#include <libdevcore/Guards.h>
#include <libdevcore/Log.h>
#include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcrypto/FileSystem.h>
#include <libethash/internal.h>
#include "BlockInfo.h"
#include "Exceptions.h"
using namespace std;
using namespace chrono;
using namespace dev;
using namespace eth;

EthashAux* dev::eth::EthashAux::s_this = nullptr;

EthashAux::~EthashAux()
{
}

uint64_t EthashAux::cacheSize(BlockInfo const& _header)
{
	return ethash_get_cachesize((uint64_t)_header.number);
}

h256 EthashAux::seedHash(unsigned _number)
{
	unsigned epoch = _number / ETHASH_EPOCH_LENGTH;
	Guard l(get()->x_epochs);
	if (epoch >= get()->m_seedHashes.size())
	{
		h256 ret;
		unsigned n = 0;
		if (!get()->m_seedHashes.empty())
		{
			ret = get()->m_seedHashes.back();
			n = get()->m_seedHashes.size() - 1;
		}
		get()->m_seedHashes.resize(epoch + 1);
//		cdebug << "Searching for seedHash of epoch " << epoch;
		for (; n <= epoch; ++n, ret = sha3(ret))
		{
			get()->m_seedHashes[n] = ret;
//			cdebug << "Epoch" << n << "is" << ret;
		}
	}
	return get()->m_seedHashes[epoch];
}

void EthashAux::killCache(h256 const& _s)
{
	RecursiveGuard l(x_this);
	m_lights.erase(_s);
}

EthashAux::LightType EthashAux::light(BlockInfo const& _header)
{
	return light((uint64_t)_header.number);
}

EthashAux::LightType EthashAux::light(uint64_t _blockNumber)
{
	RecursiveGuard l(get()->x_this);
	h256 seedHash = EthashAux::seedHash(_blockNumber);
	LightType ret = get()->m_lights[seedHash];
	return ret ? ret : (get()->m_lights[seedHash] = make_shared<LightAllocation>(_blockNumber));
}

EthashAux::LightAllocation::LightAllocation(uint64_t _blockNumber)
{
	light = ethash_light_new(_blockNumber);
	size = ethash_get_cachesize(_blockNumber);
}

EthashAux::LightAllocation::~LightAllocation()
{
	ethash_light_delete(light);
}

bytesConstRef EthashAux::LightAllocation::data() const
{
	return bytesConstRef((byte const*)light->cache, size);
}

EthashAux::FullAllocation::FullAllocation(ethash_light_t _light, ethash_callback_t _cb)
{
	full = ethash_full_new(_light, _cb);
}

EthashAux::FullAllocation::~FullAllocation()
{
	ethash_full_delete(full);
}

bytesConstRef EthashAux::FullAllocation::data() const
{
	return bytesConstRef((byte const*)ethash_full_dag(full), size());
}

EthashAux::FullType EthashAux::full(BlockInfo const& _header)
{
	return full((uint64_t) _header.number);
}

struct DAGChannel: public LogChannel { static const char* name(); static const int verbosity = 0; };
const char* DAGChannel::name() { return EthGreen "DAG"; }
static int ethash_callback(unsigned int _progress)
{
    clog(DAGChannel) << "Generating DAG file. Progress: " << toString(_progress) << "%";
    return 0;
}

EthashAux::FullType EthashAux::full(uint64_t _blockNumber)
{
	RecursiveGuard l(get()->x_this);
	h256 seedHash = EthashAux::seedHash(_blockNumber);
	FullType ret;
	if ((ret = get()->m_fulls[seedHash].lock()))
	{
		get()->m_lastUsedFull = ret;
		return ret;
	}
	ret = get()->m_lastUsedFull = make_shared<FullAllocation>(light(_blockNumber)->light, ethash_callback);
	get()->m_fulls[seedHash] = ret;
	return ret;
}

Ethash::Result EthashAux::FullAllocation::compute(h256 const& _headerHash, Nonce const& _nonce) const
{
	ethash_return_value_t r = ethash_full_compute(full, *(ethash_h256_t*)_headerHash.data(), (uint64_t)(u64)_nonce);
	if (!r.success)
		BOOST_THROW_EXCEPTION(DAGCreationFailure());
	return Ethash::Result{h256((uint8_t*)&r.result, h256::ConstructFromPointer), h256((uint8_t*)&r.mix_hash, h256::ConstructFromPointer)};
}

Ethash::Result EthashAux::LightAllocation::compute(h256 const& _headerHash, Nonce const& _nonce) const
{
	ethash_return_value r = ethash_light_compute(light, *(ethash_h256_t*)_headerHash.data(), (uint64_t)(u64)_nonce);
	if (!r.success)
		BOOST_THROW_EXCEPTION(DAGCreationFailure());
	return Ethash::Result{h256((uint8_t*)&r.result, h256::ConstructFromPointer), h256((uint8_t*)&r.mix_hash, h256::ConstructFromPointer)};
}

Ethash::Result EthashAux::eval(BlockInfo const& _header, Nonce const& _nonce)
{
	return eval((uint64_t)_header.number, _header.headerHash(WithoutNonce), _nonce);
}

Ethash::Result EthashAux::eval(uint64_t _blockNumber, h256 const& _headerHash, Nonce const& _nonce)
{
	h256 seedHash = EthashAux::seedHash(_blockNumber);
	if (FullType dag = get()->m_fulls[seedHash].lock())
		return dag->compute(_headerHash, _nonce);
	return EthashAux::get()->light(_blockNumber)->compute(_headerHash, _nonce);
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <fcntl.h>
#include <iostream>
#include <vector>
#include <string>
#include <termios.h>
#include <unistd.h>
#ifndef OFILL
#define OFILL   0000100
#endif
#ifndef OFDEL
#define OFDEL   0000200
#endif
#ifndef NLDLY
#define NLDLY   0000400
#endif
#ifndef CRDLY
#define CRDLY   0003000
#endif
#ifndef BSDLY
#define BSDLY   0020000
#endif
#ifndef VTDLY
#define VTDLY   0040000
#endif
#ifndef FFDLY
#define FFDLY   0100000
#endif

#include "Crc16.h"
#include "Command.h"

class Display {
    public:
        Display(std::string devName, speed_t baud = B115200) {
            _devName = devName;
            _baud = baud;
            std::cout << "Init device: " << _devName.c_str() << std::endl;

            _fd = open(_devName.c_str(), O_NOCTTY | O_NONBLOCK | O_RDWR );
            if (_fd == -1) {
                std::perror("Display():open");
            }

            struct termios term;
            tcgetattr(_fd, &term);

            term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL
                    |IXON|IXOFF);
            term.c_iflag |= IGNPAR;

            //output modes
            term.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONOCR|ONLRET|OFILL
                    |OFDEL|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);

            //control modes
            term.c_cflag &= ~(CSIZE|PARENB|PARODD|HUPCL|CRTSCTS);
            term.c_cflag |= CREAD|CS8|CSTOPB|CLOCAL;

            //local modes
            term.c_lflag &= ~(ISIG|ICANON|IEXTEN|ECHO);
            term.c_lflag |= NOFLSH;

            cfsetospeed(&term, baud);
            cfsetispeed(&term, baud);

            //set new device settings
            if(tcsetattr(_fd, TCSANOW, &term) == -1) {
                std::perror("Display():tcsetattr");
            }

        }

        ~Display() {
            close(_fd);
            _fd = -1;
        }

        void clear() {
            uint8_t data[4] = { 0 };
            data[0] = 0x06;
            data[1] = 0;

            uint16_t crc = Crc16::compute(data, 2);
            data[3] = (0xFF00 & crc) >> 8;
            data[2] = 0x00FF & crc;

            write(_fd, data, 4);

        }

        void text() {
            std::string text("hello world!");
            uint8_t data[1 + 1 + 22 + 2] = { 0 };
            data[0] = 0x1F;
            data[1] = text.length() + 2;
            data[2] = 0;
            data[3] = 1;
            std::copy(text.begin(), text.end(), &data[4]);
            uint16_t crc = Crc16::compute(data, data[1] + 2);
            printf("crc: %x\n", crc);
            data[16] = 0xFF & crc;
            data[17] = (0xFF00 & crc) >> 8;

            write(_fd, data, 18);

        }

        void setLedState() {
            Command cmd;
            cmd.type = 0x22;
            cmd.length = 2;
            cmd.data[0] = 5;
            cmd.data[1] = 100;
            cmd.crc = Crc16::compute((uint8_t *) &cmd, cmd.length + 2);

            //write(_fd, (uint8_t *) &cmd, cmd.length + 2 + 2);
            send(cmd);
        }

        void send(Command &cmd) {
            uint16_t crc = Crc16::compute(cmd);
            cmd.data[cmd.length] = Crc16::compute(cmd);
            write(_fd, &cmd, sizeof(uint8_t) * (4 + cmd.length));
            printf("CRC: %x\n", crc);

        }

    private:
        int _fd;
        std::string _devName;
        speed_t _baud;

};

int main (int argc, char *argv[]) {

    Display d("/dev/ttyU0");
    d.clear();
    d.text();
    d.setLedState();
    Command cmd;
    cmd.type = 0x1F;
    cmd.length = 14;
    cmd.data[0] = 0;
    cmd.data[1] = 1;
    std::string msg("hello cool world!");
    std::copy(msg.begin(), msg.end(), &cmd.data[2]);
    d.send(cmd);

}

<commit_msg>Single-write() send method with error checking<commit_after>#include <cstdio>
#include <fcntl.h>
#include <iostream>
#include <vector>
#include <string>
#include <termios.h>
#include <unistd.h>
#ifndef OFILL
#define OFILL   0000100
#endif
#ifndef OFDEL
#define OFDEL   0000200
#endif
#ifndef NLDLY
#define NLDLY   0000400
#endif
#ifndef CRDLY
#define CRDLY   0003000
#endif
#ifndef BSDLY
#define BSDLY   0020000
#endif
#ifndef VTDLY
#define VTDLY   0040000
#endif
#ifndef FFDLY
#define FFDLY   0100000
#endif

#include "Crc16.h"
#include "Command.h"
#include <string.h>

class Display {
    public:
        Display(std::string devName, speed_t baud = B115200) {
            _devName = devName;
            _baud = baud;
            std::cout << "Init device: " << _devName.c_str() << std::endl;

            _fd = open(_devName.c_str(), O_NOCTTY | O_NONBLOCK | O_RDWR );
            if (_fd == -1) {
                std::perror("Display():open");
            }

            struct termios term;
            tcgetattr(_fd, &term);

            term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL
                    |IXON|IXOFF);
            term.c_iflag |= IGNPAR;

            //output modes
            term.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONOCR|ONLRET|OFILL
                    |OFDEL|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);

            //control modes
            term.c_cflag &= ~(CSIZE|PARENB|PARODD|HUPCL|CRTSCTS);
            term.c_cflag |= CREAD|CS8|CSTOPB|CLOCAL;

            //local modes
            term.c_lflag &= ~(ISIG|ICANON|IEXTEN|ECHO);
            term.c_lflag |= NOFLSH;

            cfsetospeed(&term, baud);
            cfsetispeed(&term, baud);

            //set new device settings
            if(tcsetattr(_fd, TCSANOW, &term) == -1) {
                std::perror("Display():tcsetattr");
            }

        }

        ~Display() {
            close(_fd);
            _fd = -1;
        }

        void clear() {
            uint8_t data[4] = { 0 };
            data[0] = 0x06;
            data[1] = 0;

            uint16_t crc = Crc16::compute(data, 2);
            data[3] = (0xFF00 & crc) >> 8;
            data[2] = 0x00FF & crc;

            write(_fd, data, 4);

        }

        void text() {
            std::string text("hello world!");
            uint8_t data[1 + 1 + 22 + 2] = { 0 };
            data[0] = 0x1F;
            data[1] = text.length() + 2;
            data[2] = 0;
            data[3] = 1;
            std::copy(text.begin(), text.end(), &data[4]);
            uint16_t crc = Crc16::compute(data, data[1] + 2);
            printf("crc: %x\n", crc);
            data[16] = 0xFF & crc;
            data[17] = (0xFF00 & crc) >> 8;

            write(_fd, data, 18);

        }

        void setLedState() {
            Command cmd;
            cmd.type = 0x22;
            cmd.length = 2;
            cmd.data[0] = 5;
            cmd.data[1] = 100;
            cmd.crc = Crc16::compute((uint8_t *) &cmd, cmd.length + 2);

            //write(_fd, (uint8_t *) &cmd, cmd.length + 2 + 2);
            send(cmd);
        }

        ssize_t send(Command &cmd) {
            if (cmd.length > MAX_COMMAND_LEN) {
                return -1;
            }

            uint16_t crc = Crc16::compute(cmd);
            memcpy(&cmd.data[cmd.length], &crc, sizeof(crc));
            size_t numBytes = sizeof(cmd.data) * (cmd.length + 2) + sizeof(crc);
            ssize_t out = write(_fd, &cmd, numBytes);
            if (out == -1) {
                std::perror("Display::send()");
            }
            return out;
        }

    private:
        int _fd;
        std::string _devName;
        speed_t _baud;

};

int main (int argc, char *argv[]) {

    Display d("/dev/ttyU0");
    d.clear();
    d.text();
    d.setLedState();
    Command cmd;
    cmd.type = 0x1F;
    cmd.length = 14;
    cmd.data[0] = 0;
    cmd.data[1] = 1;
    std::string msg("hello cool world!");
    std::copy(msg.begin(), msg.end(), &cmd.data[2]);
    d.send(cmd);

}

<|endoftext|>