<commit_before>#ifndef matrix_hpp
#define matrix_hpp

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <stdint.h>
#include "util.hpp"
#include "vector.hpp"

#define debug(X) X

#define MATRIX_FOREACH(I, J) \
            for(auto I = 0; I < this->h; I++) \
                for(auto J = 0; J < this->h; J++)
#define MATRIX_SIZE_MATCH(M) \
            ((M)->w != this->w || (M)->h != this->h)
#define MATRIX_SIZE_SHOULD_BE_SAME(M) \
            if(MATRIX_SIZE_MATCH((M))) \
                fatal("matrix size mismatch");
#define MATRIX_WIDTH_VECTOR_SIZE_MATCH_P(V) \
            (this->w == V->size)
using namespace std;

template<class T>
class Matrix
{
    private:
        T *data;

        void allocate_buffer() {
            if(this->h == 0 || this->w == 0)
                fatal("neither `h` or `w` can be zero");

            this->data = new T[this->h * this->w];
            //debug({ fprintf(stderr, "[+] Matrix allocaed at %p, Buffer allocated at %p\n", this, this->data); })
        }

        void free_buffer() {
            if(this->data == NULL)
                fatal("buffer is NULL, can not be freed");
            debug({ fprintf(stderr, "[+] Buffer freed %p\n", this->data); })

            delete [] (char *)this->data;
            this->data = NULL;
        }

    public:
        const uint32_t h, w;

        // constructor and destructor
        Matrix(uint32_t h, uint32_t w) : h(h), w(w)
        {
            this->allocate_buffer();
            this->zero();
        }

        Matrix(Matrix& m) : h(m.h), w(m.w)
        {
            this->allocate_buffer();
            this->copy_from(&m);
        }

        Matrix(Matrix *m) : h(m->h), w(m->w)
        {
            this->allocate_buffer();
            this->copy_from(m);
        }

        ~Matrix() {
            this->free_buffer();
        }

        // data accessor
        T& operator() (int x, int y) {
            return this->data[x * this->h + y];
        }

        T& cell(int x, int y) {
            return this->data[x * this->h + y];
        }

        // data manipulation
        Matrix* copy_from(Matrix *m) {
            MATRIX_SIZE_SHOULD_BE_SAME(m);
            memcpy(&this->cell(0, 0), &m->cell(0, 0), sizeof(T) * this->w * this->h);
            return this;
        }

        Matrix* add(Matrix *m) {
            MATRIX_SIZE_SHOULD_BE_SAME(m);
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) += m->cell(x, y);
            }
            return this;
        }
        Matrix* add(Matrix& m) {
            return this->add(&m);
        }

        Matrix* sub(Matrix *m) {
            MATRIX_SIZE_SHOULD_BE_SAME(m);
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) -= m->cell(x, y);
            }
            return this;
        }
        Matrix* sub(Matrix& m) {
            return this->sub(&m);
        }

        Matrix* mul(Matrix *m) {
            if(this->w != m->h)
                fatal("matrix size mismatch (mul)");

            // result height, result width
            auto r_h = this->h, r_w = m->w, len = this->w;
            Matrix *result = new Matrix(r_h, r_w);
            for(auto x = 0; x < r_h; x++) {
                for(auto y = 0; y < r_w; y++) {
                    T sum = 0;
                    for(auto j = 0; j < len; j++)
                        sum += this->cell(x, j) * m->cell(j, y);
                    result->cell(x, y) = sum;
                }
            }
            return result;
        }
        Matrix* mul(T v) {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) *= v;
            }
            return this;
        }

        Matrix* div(T v) {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) /= v;
            }
            return this;
        }

        // operator overloading, all size check is perfrom in named functions
        Matrix* operator= (const Matrix& m) {
            return this->copy_from(&m);
        }

        Matrix* operator+= (Matrix& m) { return this->add(m); }
        Matrix* operator+= (Matrix *m) { return this->add(m); }

        Matrix* operator-= (Matrix& m) { return this->sub(m); }
        Matrix* operator-= (Matrix *m) { return this->sub(m); }

        // these operator will return new Matrix instance
        Matrix* operator+ (Matrix& m) {
            Matrix *result = new Matrix(this);
            result->add(m);
            return result;
        }

        Matrix* fill(T value) {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) = value;
            }
            return this;
        }

        Matrix* zero() {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) = 0;
            }
            return this;
        }

        Matrix* one() {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) = x == y ? 1 : 0;
            }
            return this;
        }

        string str() {
            stringstream buffer;
            buffer << "Matrix(" << h << ", " << w << ") {\n";
            for(auto x = 0; x < this->h; x++) {
                if(x) buffer << ",\n";
                buffer << "  (";
                for(auto y = 0; y < this->w; y++) {
                    if(y) buffer << ", ";
                    buffer << this->cell(x, y);
                }
                buffer << ")";
            }
            buffer << "\n}";

            return buffer.str();
        }
        //matrix multiply vector
        myVecD * mul(myVecD * v){
            if(!MATRIX_WIDTH_VECTOR_SIZE_MATCH_P(v))
                fatal("matrix's width != vector's length");
            myVecD * result = new myVecD(this->h);
            for (int index = 0; index < this->h; index++) {
                (*result)[index] = 0.0;
            }
            for (int index = 0; index < this->h; index++) {
                for (int indexa = 0; indexa < this->w; indexa ++) {
                    (*result)[index] += (this->cell(index,indexa) * (*v)[indexa]);
                }
            }
            return result;
        }
        myVecD * mul(myVecD & v){
            return this->mul(&v);
        }
        // static method
        static Matrix* one(int h, int w) {
           return (new Matrix(h, w))->one();
        }
    //TODO
    static Matrix<double> * merge_by_vectors(int merge_type, int number, myVecD ** vectors){
        if(number <= 0)
            fatal("invalid number of vectors");
        int size = vectors[0]->size;
        for (int index = 0; index < number; index++) {
            if(vectors[index]->size != size)
                fatal("vectors with different dimension can't be merged to one matrix");
        }
        Matrix<double> * result;
        int column, row;
        switch(merge_type){
            case AS_COLUMN:
                column = number;
                row  = size;
                result = new Matrix<double>(row, column);
                for (int indexa = 0; indexa < column; indexa++) {
                    for (int indexb = 0; indexb < row; indexb++) {
                        (*result)(indexb, indexa) = 1.0;
                    }
                }
                break;
            case AS_ROW:
                break;
            default:
                fatal("invalid merge type");
        }
        return result;
    }
};

#endif<commit_msg>New API, no pointer anymore<commit_after>#ifndef matrix_hpp
#define matrix_hpp

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <stdint.h>
#include "util.hpp"
#include "vector.hpp"

#ifndef debug
#define debug(X) X
#endif

#define MATRIX_FOREACH(I, J) \
            for(auto I = 0; I < this->h; I++) \
                for(auto J = 0; J < this->h; J++)
#define MATRIX_SIZE_MATCH(M) \
            ((M)->w != this->w || (M)->h != this->h)
#define MATRIX_SIZE_SHOULD_BE_SAME(M) \
            if(MATRIX_SIZE_MATCH((M))) \
                fatal("matrix size mismatch");
#define MATRIX_WIDTH_VECTOR_SIZE_MATCH_P(V) \
            (this->w == V->size)
using namespace std;

template<class T>
class Matrix
{
    private:
        T *data;

        void allocate_buffer() {
            if(this->h == 0 || this->w == 0)
                fatal("neither `h` or `w` can be zero");

            this->data = new T[this->h * this->w];
            //debug({ fprintf(stderr, "[+] Matrix allocaed at %p, Buffer allocated at %p\n", this, this->data); })
        }

        void free_buffer() {
            if(this->data == NULL)
                fatal("buffer is NULL, can not be freed");
            debug({ fprintf(stderr, "[+] Buffer freed %p\n", this->data); })

            delete [] (char *)this->data;
            this->data = NULL;
        }

    public:
        const uint32_t h, w;

        // constructor and destructor
        Matrix(uint32_t h, uint32_t w) : h(h), w(w)
        {
            this->allocate_buffer();
            this->zero();
        }

        Matrix(Matrix& m) : h(m.h), w(m.w)
        {
            this->allocate_buffer();
            this->copy_from(&m);
        }

        Matrix(Matrix *m) : h(m->h), w(m->w)
        {
            this->allocate_buffer();
            this->copy_from(m);
        }

        ~Matrix() {
            this->free_buffer();
        }

        void copy_from(Matrix *m) {
            MATRIX_SIZE_SHOULD_BE_SAME(m);
            memcpy(&this->cell(0, 0), &m->cell(0, 0), sizeof(T) * this->w * this->h);
        }

        // data accessor
        T& operator() (int x, int y) {
            return this->data[x * this->h + y];
        }

        T& cell(int x, int y) {
            return this->data[x * this->h + y];
        }

        // data manipulation
        Matrix& add(Matrix &m) {
            MATRIX_SIZE_SHOULD_BE_SAME(&m);
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) += m(x, y);
            }
            return *this;
        }

        Matrix& sub(Matrix &m) {
            MATRIX_SIZE_SHOULD_BE_SAME(&m);
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) -= m(x, y);
            }
            return &this;
        }

        Matrix& mul(Matrix *m) {
            if(this->w != m->h)
                fatal("matrix size mismatch (mul)");

            // result height, result width
            auto r_h = this->h, r_w = m->w, len = this->w;
            Matrix result = Matrix(r_h, r_w);
            for(auto x = 0; x < r_h; x++) {
                for(auto y = 0; y < r_w; y++) {
                    T sum = 0;
                    for(auto j = 0; j < len; j++)
                        sum += this->cell(x, j) * m->cell(j, y);
                    result(x, y) = sum;
                }
            }
            return result;
        }
        Matrix& mul(T v) {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) *= v;
            }
            return *this;
        }

        Matrix& div(T v) {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) /= v;
            }
            return *this;
        }

        // operator overloading, all size check is perfrom in named functions
        Matrix& operator= (const Matrix& m) {
            return *this->copy_from(&m);
        }

        Matrix& operator+= (Matrix& m) { return *this->add(m); }
        Matrix& operator+= (Matrix *m) { return *this->add(m); }

        Matrix& operator-= (Matrix& m) { return *this->sub(m); }
        Matrix& operator-= (Matrix *m) { return *this->sub(m); }

        // these operator will return new Matrix instance
        Matrix& operator+ (Matrix& m) {
            Matrix result(this);
            return result.add(m);
        }

        void fill(T value) {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) = value;
            }
        }

        void zero() {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) = 0;
            }
        }

        void one() {
            MATRIX_FOREACH(x, y) {
                this->cell(x, y) = x == y ? 1 : 0;
            }
        }

        string str() {
            stringstream buffer;
            buffer << "Matrix(" << h << ", " << w << ") {\n";
            for(auto x = 0; x < this->h; x++) {
                if(x) buffer << ",\n";
                buffer << "  (";
                for(auto y = 0; y < this->w; y++) {
                    if(y) buffer << ", ";
                    buffer << this->cell(x, y);
                }
                buffer << ")";
            }
            buffer << "\n}";

            return buffer.str();
        }
        //matrix multiply vector
        myVecD * mul(myVecD * v){
            if(!MATRIX_WIDTH_VECTOR_SIZE_MATCH_P(v))
                fatal("matrix's width != vector's length");
            myVecD * result = new myVecD(this->h);
            for (int index = 0; index < this->h; index++) {
                (*result)[index] = 0.0;
            }
            for (int index = 0; index < this->h; index++) {
                for (int indexa = 0; indexa < this->w; indexa ++) {
                    (*result)[index] += (this->cell(index,indexa) * (*v)[indexa]);
                }
            }
            return result;
        }
        myVecD * mul(myVecD & v){
            return this->mul(&v);
        }

    //TODO
    static Matrix<double> * merge_by_vectors(int merge_type, int number, myVecD ** vectors){
        if(number <= 0)
            fatal("invalid number of vectors");
        int size = vectors[0]->size;
        for (int index = 0; index < number; index++) {
            if(vectors[index]->size != size)
                fatal("vectors with different dimension can't be merged to one matrix");
        }
        Matrix<double> * result;
        int column, row;
        switch(merge_type){
            case AS_COLUMN:
                column = number;
                row  = size;
                result = new Matrix<double>(row, column);
                for (int indexa = 0; indexa < column; indexa++) {
                    for (int indexb = 0; indexb < row; indexb++) {
                        (*result)(indexb, indexa) = 1.0;
                    }
                }
                break;
            case AS_ROW:
                break;
            default:
                fatal("invalid merge type");
        }
        return result;
    }
};

#endif
<|endoftext|>


<commit_before>/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001 Jason Winnebeck (gillius@mail.rit.edu)
 * Project website: http://www.rit.edu/~jpw9607/
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "../../include/gnelib.h"

using namespace GNE;
using namespace Console;

class TimeClass : public TimerCallback {
public:
  TimeClass(int x2, int y2, std::string ourName)
    : lastTime(Timer::getCurrentTime()), callNum(0), x(x2), y(y2), name(ourName) {}

  virtual ~TimeClass() {}

  void timerCallback() {
    Time currTime = Timer::getCurrentTime();
    Time diffTime = currTime - lastTime;
    lastTime = currTime;
    mlprintf(x, y, "(%i)Hello, I'm %s! change: %ius", callNum, name.c_str(), diffTime.getTotaluSec());
    callNum++;
  }

private:
  Time lastTime;
  int callNum;
  int x, y;
  std::string name;
};

class CounterWatcher : public TimerCallback {
public:
  CounterWatcher(int x2, int y2, int counterRate)
    : x(x2), y(y2), timer(&counter, counterRate, false) {
    //false == don't let Timer kill the callback (counter)
    timer.startTimer();
  }

  virtual ~CounterWatcher() {
    timer.stopTimer();
  }

  void timerCallback() {
    mlprintf(x, y, "Count: %i", counter.getCount());
  }

private:
  int x, y;
  Counter counter;
  Timer timer;
};

int main() {
  initGNE(NO_NET, atexit);
  initConsole(atexit);
  setTitle("GNE Timers Example");

  //Doing some tests on Time class
  mprintf("Time class tests:\n");
  Time t(0, 1000000);
  mprintf("%is, %ius\n", t.getSec(), t.getuSec());
  t += 1000001; //add a little over one second
  mprintf("%is, %ius\n", t.getSec(), t.getuSec());
  t.setSec(5);
  mprintf("%is, %ius\n", t.getSec(), t.getuSec());
  t = t + Time(3, 5500000);
  mprintf("%is, %ius\n", t.getSec(), t.getuSec());
  mprintf("Timer class tests, press a key to quit:\n");

  //Create the timers, and pass true to allow our timer objects to
  //also destroy their callbacks when they die.
  Timer t1(new TimeClass(3, 8, "Bob"), 1000, true);
  Timer t2(new TimeClass(5, 10, "Sally"), 1250, true);
  Timer t3(new TimeClass(1, 12, "Joe"), 200, true);
  Timer t4(new CounterWatcher(40, 3, 10), 500, true);

  //Start the timers
  t1.startTimer();
  assert(t1.isRunning());
  t2.startTimer();
  assert(t2.isRunning());
  t3.startTimer();
  assert(t3.isRunning());
  t4.startTimer();
  assert(t4.isRunning());

  getch(); //Wait for a keypress.

  mlprintf(0, 14, "Shutting down timers, please wait...");
  t1.stopTimer();
  t2.stopTimer();
  t3.stopTimer();
  t4.stopTimer();

  return 0;
}

<commit_msg>Updated and added comments due to Timer API changes.<commit_after>/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001 Jason Winnebeck (gillius@mail.rit.edu)
 * Project website: http://www.rit.edu/~jpw9607/
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "../../include/gnelib.h"

using namespace GNE;
using namespace Console;

class TimeClass : public TimerCallback {
public:
  TimeClass(int x2, int y2, std::string ourName)
    : lastTime(Timer::getCurrentTime()), callNum(0), x(x2), y(y2), name(ourName) {}

  virtual ~TimeClass() {}

  void timerCallback() {
    Time currTime = Timer::getCurrentTime();
    Time diffTime = currTime - lastTime;
    lastTime = currTime;
    mlprintf(x, y, "(%i)Hello, I'm %s! change: %ius", callNum, name.c_str(), diffTime.getTotaluSec());
    callNum++;
  }

private:
  Time lastTime;
  int callNum;
  int x, y;
  std::string name;
};

class CounterWatcher : public TimerCallback {
public:
  CounterWatcher(int x2, int y2, int counterRate)
    : x(x2), y(y2), timer(&counter, counterRate, false) {
    //false == don't let Timer kill the callback (counter)
    timer.startTimer();
  }

  virtual ~CounterWatcher() {
    //Setting true here causes stopTimer to wait until the callbacks are
    //done, whereas setting false will not wait.  But at this point the value
    //passed is irrelevant since when timer is destroyed in this function it
    //would block regardless.  See the Timer documentation for more details.
    timer.stopTimer(true);
  }

  void timerCallback() {
    mlprintf(x, y, "Count: %i", counter.getCount());
  }

private:
  int x, y;
  Counter counter;
  Timer timer;
};

int main() {
  initGNE(NO_NET, atexit);
  initConsole(atexit);
  setTitle("GNE Timers Example");

  //Doing some tests on Time class
  mprintf("Time class tests:\n");
  Time t(0, 1000000);
  mprintf("%is, %ius\n", t.getSec(), t.getuSec());
  t += 1000001; //add a little over one second
  mprintf("%is, %ius\n", t.getSec(), t.getuSec());
  t.setSec(5);
  mprintf("%is, %ius\n", t.getSec(), t.getuSec());
  t = t + Time(3, 5500000);
  mprintf("%is, %ius\n", t.getSec(), t.getuSec());
  mprintf("Timer class tests, press a key to quit:\n");

  //Create the timers, and pass true to allow our timer objects to
  //also destroy their callbacks when they die.
  Timer t1(new TimeClass(3, 8, "Bob"), 1000, true);
  Timer t2(new TimeClass(5, 10, "Sally"), 1250, true);
  Timer t3(new TimeClass(1, 12, "Joe"), 200, true);
  Timer t4(new CounterWatcher(40, 3, 10), 500, true);

  //Start the timers
  t1.startTimer();
  assert(t1.isRunning());
  t2.startTimer();
  assert(t2.isRunning());
  t3.startTimer();
  assert(t3.isRunning());
  t4.startTimer();
  assert(t4.isRunning());

  getch(); //Wait for a keypress.

  mlprintf(0, 14, "Shutting down timers, please wait...");
  //Passing false will cause stopTimer to request a shutdown but not wait for
  //the callbacks to finish.  But when t1-t4 are destroyed, they must wait
  //if the calls had not finished, so the shutdown will take as long as the
  //longest timer.  Were we to pass true, the shutdown would take t1+t2+t3+t4
  //amount of time to shutdown, because the request for t2 to shutdown
  //wouldn't start until after t1 had completely finished its final callback.
  t1.stopTimer(false);
  t2.stopTimer(false);
  t3.stopTimer(false);
  t4.stopTimer(false);

  return 0;
}

<|endoftext|>


<commit_before>#include <concurrency/ThreadManager.h>
#include <concurrency/PosixThreadFactory.h>
#include <protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h>
#include <server/TThreadPoolServer.h>
#include <server/TNonblockingServer.h>
#include <transport/TServerSocket.h>
#include <transport/TTransportUtils.h>
#include "ThriftTest.h"

#include <iostream>
#include <stdexcept>
#include <sstream>

using namespace std;

using namespace facebook::thrift;
using namespace facebook::thrift::protocol;
using namespace facebook::thrift::transport;
using namespace facebook::thrift::server;

using namespace thrift::test;

class TestHandler : public ThriftTestIf {
 public:
  TestHandler() {}

  void testVoid() {
    printf("testVoid()\n");
  }

  void testString(string& out, const string &thing) {
    printf("testString(\"%s\")\n", thing.c_str());
    out = thing;
  }

  int8_t testByte(const int8_t thing) {
    printf("testByte(%d)\n", (int)thing);
    return thing;
  }

  int32_t testI32(const int32_t thing) {
    printf("testI32(%d)\n", thing);
    return thing;
  }

  int64_t testI64(const int64_t thing) {
    printf("testI64(%ld)\n", thing);
    return thing;
  }

  double testDouble(const double thing) {
    printf("testDouble(%lf)\n", thing);
    return thing;
  }

  void testStruct(Xtruct& out, const Xtruct &thing) {
    printf("testStruct({\"%s\", %d, %d, %ld})\n", thing.string_thing.c_str(), (int)thing.byte_thing, thing.i32_thing, thing.i64_thing);
    out = thing;
  }

  void testNest(Xtruct2& out, const Xtruct2& nest) {
    const Xtruct &thing = nest.struct_thing;
    printf("testNest({%d, {\"%s\", %d, %d, %ld}, %d})\n", (int)nest.byte_thing, thing.string_thing.c_str(), (int)thing.byte_thing, thing.i32_thing, thing.i64_thing, nest.i32_thing);
    out = nest;
  }

  void testMap(map<int32_t, int32_t> &out, const map<int32_t, int32_t> &thing) {
    printf("testMap({");
    map<int32_t, int32_t>::const_iterator m_iter;
    bool first = true;
    for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%d => %d", m_iter->first, m_iter->second);
    }
    printf("})\n");
    out = thing;
  }

  void testSet(set<int32_t> &out, const set<int32_t> &thing) {
    printf("testSet({");
    set<int32_t>::const_iterator s_iter;
    bool first = true;
    for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%d", *s_iter);
    }
    printf("})\n");
    out = thing;
  }

  void testList(vector<int32_t> &out, const vector<int32_t> &thing) {
    printf("testList({");
    vector<int32_t>::const_iterator l_iter;
    bool first = true;
    for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%d", *l_iter);
    }
    printf("})\n");
    out = thing;
  }

  Numberz testEnum(const Numberz thing) {
    printf("testEnum(%d)\n", thing);
    return thing;
  }

  UserId testTypedef(const UserId thing) {
    printf("testTypedef(%ld)\n", thing);
    return thing;
  }

  void testMapMap(map<int32_t, map<int32_t,int32_t> > &mapmap, const int32_t hello) {
    printf("testMapMap(%d)\n", hello);

    map<int32_t,int32_t> pos;
    map<int32_t,int32_t> neg;
    for (int i = 1; i < 5; i++) {
      pos.insert(make_pair(i,i));
      neg.insert(make_pair(-i,-i));
    }

    mapmap.insert(make_pair(4, pos));
    mapmap.insert(make_pair(-4, neg));

  }

  void testInsanity(map<UserId, map<Numberz,Insanity> > &insane, const Insanity &argument) {
    printf("testInsanity()\n");

    Xtruct hello;
    hello.string_thing = "Hello2";
    hello.byte_thing = 2;
    hello.i32_thing = 2;
    hello.i64_thing = 2;

    Xtruct goodbye;
    goodbye.string_thing = "Goodbye4";
    goodbye.byte_thing = 4;
    goodbye.i32_thing = 4;
    goodbye.i64_thing = 4;

    Insanity crazy;
    crazy.userMap.insert(make_pair(EIGHT, 8));
    crazy.xtructs.push_back(goodbye);

    Insanity looney;
    crazy.userMap.insert(make_pair(FIVE, 5));
    crazy.xtructs.push_back(hello);

    map<Numberz, Insanity> first_map;
    map<Numberz, Insanity> second_map;

    first_map.insert(make_pair(TWO, crazy));
    first_map.insert(make_pair(THREE, crazy));

    second_map.insert(make_pair(SIX, looney));

    insane.insert(make_pair(1, first_map));
    insane.insert(make_pair(2, second_map));

    printf("return");
    printf(" = {");
    map<UserId, map<Numberz,Insanity> >::const_iterator i_iter;
    for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) {
      printf("%ld => {", i_iter->first);
      map<Numberz,Insanity>::const_iterator i2_iter;
      for (i2_iter = i_iter->second.begin();
           i2_iter != i_iter->second.end();
           ++i2_iter) {
        printf("%d => {", i2_iter->first);
        map<Numberz, UserId> userMap = i2_iter->second.userMap;
        map<Numberz, UserId>::const_iterator um;
        printf("{");
        for (um = userMap.begin(); um != userMap.end(); ++um) {
          printf("%d => %ld, ", um->first, um->second);
        }
        printf("}, ");

        vector<Xtruct> xtructs = i2_iter->second.xtructs;
        vector<Xtruct>::const_iterator x;
        printf("{");
        for (x = xtructs.begin(); x != xtructs.end(); ++x) {
          printf("{\"%s\", %d, %d, %ld}, ", x->string_thing.c_str(), (int)x->byte_thing, x->i32_thing, x->i64_thing);
        }
        printf("}");

        printf("}, ");
      }
      printf("}, ");
    }
    printf("}\n");

  }

  void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2, const std::map<int16_t, std::string>  &arg3, const Numberz arg4, const UserId arg5) {
    printf("testMulti()\n");

    hello.string_thing = "Hello2";
    hello.byte_thing = arg0;
    hello.i32_thing = arg1;
    hello.i64_thing = (int64_t)arg2;
  }

  void testException(const std::string &arg) throw(Xception) {
    printf("testException(%s)\n", arg.c_str());
    if (arg.compare("Xception") == 0) {
      Xception e;
      e.errorCode = 1001;
      e.message = "This is an Xception";
      throw e;
    } else {
      Xtruct result;
      result.string_thing = arg;
      return;
    }
  }

  void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) throw(Xception, Xception2) {

    printf("testMultiException(%s, %s)\n", arg0.c_str(), arg1.c_str());

    if (arg0.compare("Xception") == 0) {
      Xception e;
      e.errorCode = 1001;
      e.message = "This is an Xception";
      throw e;
    } else if (arg0.compare("Xception2") == 0) {
      Xception2 e;
      e.errorCode = 2002;
      e.struct_thing.string_thing = "This is an Xception2";
      throw e;
    } else {
      result.string_thing = arg1;
      return;
    }
  }
};

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

  int port = 9090;
  string serverType = "simple";
  string protocolType = "binary";
  size_t workerCount = 4;
  bool frameOutput = true;

  ostringstream usage;

  usage <<
    argv[0] << " [--port=<port number>] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>]" << endl <<

    "\t\tserver-type\t\ttype of server, \"simple\", \"thread-pool\", or \"nonblocking\".  Default is " << serverType << endl <<

    "\t\tprotocol-type\t\ttype of protocol, \"binary\", \"ascii\", or \"xml\".  Default is " << protocolType << endl <<

    "\t\tworkers\t\tNumber of thread pools workers.  Only valid for thread-pool server type.  Default is " << workerCount << endl;

  map<string, string>  args;

  for (int ix = 1; ix < argc; ix++) {
    string arg(argv[ix]);
    if (arg.compare(0,2, "--") == 0) {
      size_t end = arg.find_first_of("=", 2);
      if (end != string::npos) {
	args[string(arg, 2, end - 2)] = string(arg, end + 1);
      } else {
	args[string(arg, 2)] = "true";
      }
    } else {
      throw invalid_argument("Unexcepted command line token: "+arg);
    }
  }

  try {

    if (!args["port"].empty()) {
      port = atoi(args["port"].c_str());
    }

    if (!args["noframe"].empty()) {
      frameOutput = false;
    }

    if (!args["server-type"].empty()) {
      serverType = args["server-type"];
      if (serverType == "simple") {
      } else if (serverType == "thread-pool") {
      } else if (serverType == "nonblocking") {
      } else {
	throw invalid_argument("Unknown server type "+serverType);
      }
    }

    if (!args["protocol-type"].empty()) {
      protocolType = args["protocol-type"];
      if (protocolType == "binary") {
      } else if (protocolType == "ascii") {
	throw invalid_argument("ASCII protocol not supported");
      } else if (protocolType == "xml") {
	throw invalid_argument("XML protocol not supported");
      } else {
	throw invalid_argument("Unknown protocol type "+protocolType);
      }
    }

    if (!args["workers"].empty()) {
      workerCount = atoi(args["workers"].c_str());
    }
  } catch (exception& e) {
    cerr << e.what() << endl;
    cerr << usage;
  }

  // Dispatcher
  shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

  shared_ptr<TestHandler> testHandler(new TestHandler());

  shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));

  // Transport
  shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));

  // Factory
  shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());

  if (serverType == "simple") {

    // Server
    TSimpleServer simpleServer(testProcessor,
			       serverSocket,
                               transportFactory,
                               protocolFactory);

    printf("Starting the server on port %d...\n", port);
    simpleServer.serve();

  } else if (serverType == "thread-pool") {

    shared_ptr<ThreadManager> threadManager =
      ThreadManager::newSimpleThreadManager(workerCount);

    shared_ptr<PosixThreadFactory> threadFactory =
      shared_ptr<PosixThreadFactory>(new PosixThreadFactory());

    threadManager->threadFactory(threadFactory);

    threadManager->start();

    TThreadPoolServer threadPoolServer(testProcessor,
				       serverSocket,
                                       transportFactory,
                                       protocolFactory,
				       threadManager);

    printf("Starting the server on port %d...\n", port);
    threadPoolServer.serve();

  } else if (serverType == "nonblocking") {

    TNonblockingServer nonblockingServer(testProcessor, port);
    nonblockingServer.setFrameResponses(frameOutput);
    if (frameOutput) {
      printf("Using framed output mode\n");
    } else {
      printf("Using non-framed output mode\n");
    }

    printf("Starting the nonblocking server on port %d...\n", port);
    nonblockingServer.serve();

  }

  printf("done.\n");
  return 0;
}
<commit_msg>Fix broken C++ Thrift test<commit_after>#include <concurrency/ThreadManager.h>
#include <concurrency/PosixThreadFactory.h>
#include <protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h>
#include <server/TThreadedServer.h>
#include <server/TThreadPoolServer.h>
#include <server/TNonblockingServer.h>
#include <transport/TServerSocket.h>
#include <transport/TTransportUtils.h>
#include "ThriftTest.h"

#include <iostream>
#include <stdexcept>
#include <sstream>

using namespace std;
using namespace boost;

using namespace facebook::thrift;
using namespace facebook::thrift::concurrency;
using namespace facebook::thrift::protocol;
using namespace facebook::thrift::transport;
using namespace facebook::thrift::server;

using namespace thrift::test;

class TestHandler : public ThriftTestIf {
 public:
  TestHandler() {}

  void testVoid() {
    printf("testVoid()\n");
  }

  void testString(string& out, const string &thing) {
    printf("testString(\"%s\")\n", thing.c_str());
    out = thing;
  }

  int8_t testByte(const int8_t thing) {
    printf("testByte(%d)\n", (int)thing);
    return thing;
  }

  int32_t testI32(const int32_t thing) {
    printf("testI32(%d)\n", thing);
    return thing;
  }

  int64_t testI64(const int64_t thing) {
    printf("testI64(%ld)\n", thing);
    return thing;
  }

  double testDouble(const double thing) {
    printf("testDouble(%lf)\n", thing);
    return thing;
  }

  void testStruct(Xtruct& out, const Xtruct &thing) {
    printf("testStruct({\"%s\", %d, %d, %ld})\n", thing.string_thing.c_str(), (int)thing.byte_thing, thing.i32_thing, thing.i64_thing);
    out = thing;
  }

  void testNest(Xtruct2& out, const Xtruct2& nest) {
    const Xtruct &thing = nest.struct_thing;
    printf("testNest({%d, {\"%s\", %d, %d, %ld}, %d})\n", (int)nest.byte_thing, thing.string_thing.c_str(), (int)thing.byte_thing, thing.i32_thing, thing.i64_thing, nest.i32_thing);
    out = nest;
  }

  void testMap(map<int32_t, int32_t> &out, const map<int32_t, int32_t> &thing) {
    printf("testMap({");
    map<int32_t, int32_t>::const_iterator m_iter;
    bool first = true;
    for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%d => %d", m_iter->first, m_iter->second);
    }
    printf("})\n");
    out = thing;
  }

  void testSet(set<int32_t> &out, const set<int32_t> &thing) {
    printf("testSet({");
    set<int32_t>::const_iterator s_iter;
    bool first = true;
    for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%d", *s_iter);
    }
    printf("})\n");
    out = thing;
  }

  void testList(vector<int32_t> &out, const vector<int32_t> &thing) {
    printf("testList({");
    vector<int32_t>::const_iterator l_iter;
    bool first = true;
    for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) {
      if (first) {
        first = false;
      } else {
        printf(", ");
      }
      printf("%d", *l_iter);
    }
    printf("})\n");
    out = thing;
  }

  Numberz testEnum(const Numberz thing) {
    printf("testEnum(%d)\n", thing);
    return thing;
  }

  UserId testTypedef(const UserId thing) {
    printf("testTypedef(%ld)\n", thing);
    return thing;
  }

  void testMapMap(map<int32_t, map<int32_t,int32_t> > &mapmap, const int32_t hello) {
    printf("testMapMap(%d)\n", hello);

    map<int32_t,int32_t> pos;
    map<int32_t,int32_t> neg;
    for (int i = 1; i < 5; i++) {
      pos.insert(make_pair(i,i));
      neg.insert(make_pair(-i,-i));
    }

    mapmap.insert(make_pair(4, pos));
    mapmap.insert(make_pair(-4, neg));

  }

  void testInsanity(map<UserId, map<Numberz,Insanity> > &insane, const Insanity &argument) {
    printf("testInsanity()\n");

    Xtruct hello;
    hello.string_thing = "Hello2";
    hello.byte_thing = 2;
    hello.i32_thing = 2;
    hello.i64_thing = 2;

    Xtruct goodbye;
    goodbye.string_thing = "Goodbye4";
    goodbye.byte_thing = 4;
    goodbye.i32_thing = 4;
    goodbye.i64_thing = 4;

    Insanity crazy;
    crazy.userMap.insert(make_pair(EIGHT, 8));
    crazy.xtructs.push_back(goodbye);

    Insanity looney;
    crazy.userMap.insert(make_pair(FIVE, 5));
    crazy.xtructs.push_back(hello);

    map<Numberz, Insanity> first_map;
    map<Numberz, Insanity> second_map;

    first_map.insert(make_pair(TWO, crazy));
    first_map.insert(make_pair(THREE, crazy));

    second_map.insert(make_pair(SIX, looney));

    insane.insert(make_pair(1, first_map));
    insane.insert(make_pair(2, second_map));

    printf("return");
    printf(" = {");
    map<UserId, map<Numberz,Insanity> >::const_iterator i_iter;
    for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) {
      printf("%ld => {", i_iter->first);
      map<Numberz,Insanity>::const_iterator i2_iter;
      for (i2_iter = i_iter->second.begin();
           i2_iter != i_iter->second.end();
           ++i2_iter) {
        printf("%d => {", i2_iter->first);
        map<Numberz, UserId> userMap = i2_iter->second.userMap;
        map<Numberz, UserId>::const_iterator um;
        printf("{");
        for (um = userMap.begin(); um != userMap.end(); ++um) {
          printf("%d => %ld, ", um->first, um->second);
        }
        printf("}, ");

        vector<Xtruct> xtructs = i2_iter->second.xtructs;
        vector<Xtruct>::const_iterator x;
        printf("{");
        for (x = xtructs.begin(); x != xtructs.end(); ++x) {
          printf("{\"%s\", %d, %d, %ld}, ", x->string_thing.c_str(), (int)x->byte_thing, x->i32_thing, x->i64_thing);
        }
        printf("}");

        printf("}, ");
      }
      printf("}, ");
    }
    printf("}\n");

  }

  void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2, const std::map<int16_t, std::string>  &arg3, const Numberz arg4, const UserId arg5) {
    printf("testMulti()\n");

    hello.string_thing = "Hello2";
    hello.byte_thing = arg0;
    hello.i32_thing = arg1;
    hello.i64_thing = (int64_t)arg2;
  }

  void testException(const std::string &arg) throw(Xception) {
    printf("testException(%s)\n", arg.c_str());
    if (arg.compare("Xception") == 0) {
      Xception e;
      e.errorCode = 1001;
      e.message = "This is an Xception";
      throw e;
    } else {
      Xtruct result;
      result.string_thing = arg;
      return;
    }
  }

  void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) throw(Xception, Xception2) {

    printf("testMultiException(%s, %s)\n", arg0.c_str(), arg1.c_str());

    if (arg0.compare("Xception") == 0) {
      Xception e;
      e.errorCode = 1001;
      e.message = "This is an Xception";
      throw e;
    } else if (arg0.compare("Xception2") == 0) {
      Xception2 e;
      e.errorCode = 2002;
      e.struct_thing.string_thing = "This is an Xception2";
      throw e;
    } else {
      result.string_thing = arg1;
      return;
    }
  }
};

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

  int port = 9090;
  string serverType = "simple";
  string protocolType = "binary";
  size_t workerCount = 4;
  bool frameOutput = true;

  ostringstream usage;

  usage <<
    argv[0] << " [--port=<port number>] [--server-type=<server-type>] [--protocol-type=<protocol-type>] [--workers=<worker-count>]" << endl <<

    "\t\tserver-type\t\ttype of server, \"simple\", \"thread-pool\", \"threaded\", or \"nonblocking\".  Default is " << serverType << endl <<

    "\t\tprotocol-type\t\ttype of protocol, \"binary\", \"ascii\", or \"xml\".  Default is " << protocolType << endl <<

    "\t\tworkers\t\tNumber of thread pools workers.  Only valid for thread-pool server type.  Default is " << workerCount << endl;

  map<string, string>  args;

  for (int ix = 1; ix < argc; ix++) {
    string arg(argv[ix]);
    if (arg.compare(0,2, "--") == 0) {
      size_t end = arg.find_first_of("=", 2);
      if (end != string::npos) {
	args[string(arg, 2, end - 2)] = string(arg, end + 1);
      } else {
	args[string(arg, 2)] = "true";
      }
    } else {
      throw invalid_argument("Unexcepted command line token: "+arg);
    }
  }

  try {

    if (!args["port"].empty()) {
      port = atoi(args["port"].c_str());
    }

    if (!args["noframe"].empty()) {
      frameOutput = false;
    }

    if (!args["server-type"].empty()) {
      serverType = args["server-type"];
      if (serverType == "simple") {
      } else if (serverType == "thread-pool") {
      } else if (serverType == "threaded") {
      } else if (serverType == "nonblocking") {
      } else {
	throw invalid_argument("Unknown server type "+serverType);
      }
    }

    if (!args["protocol-type"].empty()) {
      protocolType = args["protocol-type"];
      if (protocolType == "binary") {
      } else if (protocolType == "ascii") {
	throw invalid_argument("ASCII protocol not supported");
      } else if (protocolType == "xml") {
	throw invalid_argument("XML protocol not supported");
      } else {
	throw invalid_argument("Unknown protocol type "+protocolType);
      }
    }

    if (!args["workers"].empty()) {
      workerCount = atoi(args["workers"].c_str());
    }
  } catch (exception& e) {
    cerr << e.what() << endl;
    cerr << usage;
  }

  // Dispatcher
  shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

  shared_ptr<TestHandler> testHandler(new TestHandler());

  shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));

  // Transport
  shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));

  // Factory
  shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());

  if (serverType == "simple") {

    // Server
    TSimpleServer simpleServer(testProcessor,
			       serverSocket,
                               transportFactory,
                               protocolFactory);

    printf("Starting the server on port %d...\n", port);
    simpleServer.serve();

  } else if (serverType == "thread-pool") {

    shared_ptr<ThreadManager> threadManager =
      ThreadManager::newSimpleThreadManager(workerCount);

    shared_ptr<PosixThreadFactory> threadFactory =
      shared_ptr<PosixThreadFactory>(new PosixThreadFactory());

    threadManager->threadFactory(threadFactory);

    threadManager->start();

    TThreadPoolServer threadPoolServer(testProcessor,
				       serverSocket,
                                       transportFactory,
                                       protocolFactory,
				       threadManager);

    printf("Starting the server on port %d...\n", port);
    threadPoolServer.serve();

  } else if (serverType == "threaded") {

    TThreadedServer threadedServer(testProcessor,
                                   serverSocket,
                                   transportFactory,
                                   protocolFactory);

    printf("Starting the server on port %d...\n", port);
    threadedServer.serve();

  } else if (serverType == "nonblocking") {

    TNonblockingServer nonblockingServer(testProcessor, port);
    nonblockingServer.setFrameResponses(frameOutput);
    if (frameOutput) {
      printf("Using framed output mode\n");
    } else {
      printf("Using non-framed output mode\n");
    }

    printf("Starting the nonblocking server on port %d...\n", port);
    nonblockingServer.serve();

  }

  printf("done.\n");
  return 0;
}
<|endoftext|>


<commit_before>
// Note - python_bindings_common.h must be included before condor_common to avoid
// re-definition warnings.
#include "python_bindings_common.h"

# if defined(__APPLE__)
# undef HAVE_SSIZE_T
# include <pyport.h>
# endif

#include "condor_common.h"
#include <boost/python/overloads.hpp>

#include "enum_utils.h"
#include "condor_attributes.h"
#include "dc_startd.h"
#include "globus_utils.h"
#include "classad/source.h"

#include "old_boost.h"
#include "module_lock.h"
#include "classad_wrapper.h"

/*
 * Object representing a claim on a remote startd.
 *
 * Purpose is twofold: one, to represent 'full' claims as found in the
 * collector.  Two, to provide a python binding for the COD API.
 */
struct Startd
{

    Startd() {}

    Startd(boost::python::object ad_obj)
    {
        ClassAdWrapper ad = boost::python::extract<ClassAdWrapper>(ad_obj);
        if (!ad.EvaluateAttrString(ATTR_MY_ADDRESS, m_addr))
        {
            THROW_EX(ValueError, "No contact string in ClassAd");
        }
    }

    std::string
    drain_jobs(int how_fast=DRAIN_GRACEFUL, bool resume_on_completion=false, boost::python::object check_obj=boost::python::object(""))
    {
        std::string check_expr;
        boost::python::extract<std::string> expr_extract(check_obj);
        if (expr_extract.check())
        {
            check_expr = expr_extract();
        }
        else
        {
            classad::ClassAdUnParser printer;
            classad_shared_ptr<classad::ExprTree> expr(convert_python_to_exprtree(check_obj));
            printer.Unparse(check_expr, expr.get());
        }

        //boost::python::string retval;
        std::string request_id;

        DCStartd startd(m_addr.c_str());
        // FIXME: allow python bindings to specify START expression.
        bool rval = startd.drainJobs(how_fast, resume_on_completion, check_expr.c_str(), NULL, request_id);
        if (!rval) {THROW_EX(RuntimeError, "Startd failed to begin draining jobs.");}
        return request_id;
    }

    void
    cancel_drain_jobs(boost::python::object rid=boost::python::object())
    {
        const char * request_id = NULL;
        std::string request_id_str;
        if (rid.ptr() == Py_None)
        {
            request_id = NULL;
        }
        else
        {
            request_id_str = boost::python::extract<std::string>(rid);
            request_id = request_id_str.c_str();
        }

        DCStartd startd(m_addr.c_str());
        bool rval = startd.cancelDrainJobs( request_id );
        if (!rval) {THROW_EX(RuntimeError, "Startd failed to cancel draining jobs.");}
    }

private:

    std::string m_addr;
};

void
export_startd()
{
    boost::python::enum_<int>("DrainTypes")
        .value("Fast", DRAIN_FAST)
        .value("Graceful", DRAIN_GRACEFUL)
        .value("Quick", DRAIN_QUICK)
        ;

#if BOOST_VERSION >= 103400
    boost::python::docstring_options doc_options;
    doc_options.disable_cpp_signatures();
    #define SELFARG boost::python::arg("self"),
#else
    #define SELFARG
#endif

    boost::python::class_<Startd>("Startd", "A client class for controlling Startds in HTCondor")
        .def(boost::python::init<>())
        .def(boost::python::init<boost::python::object>(":param ad: An ad describing the Claim (optionally) and a Startd location."))

        .def("drainJobs", &Startd::drain_jobs, "Drain jobs from a startd.",
            ":param drain_type: Type of drain to perform (Fast, Graceful or Quick); must be from DrainTypes enum."
            ":param resume_on_completion: If true, startd will exit the draining state when draining completes.\n"
            ":param check: An optional check expression that must be true for all slots for draining to begin; defaults to 'true'\n"
            ":return: a drain request id that can be used to cancel draining.",
               (SELFARG
                boost::python::arg("drain_type")=DRAIN_GRACEFUL,
                boost::python::arg("resume_on_completion")=false,
                boost::python::arg("constraint")="true"
               )
            )

        .def("cancelDrainJobs", &Startd::cancel_drain_jobs, "Cancel draining jobs from a startd.",
            ":param request_id: optional, if specified cancels only the drain command with the given request_id.",
               (SELFARG
                boost::python::arg("request_id")=""
               )
           )
        ;
}

<commit_msg>(#6628)  Python binds fix.  Also fixed bad documention.<commit_after>
// Note - python_bindings_common.h must be included before condor_common to avoid
// re-definition warnings.
#include "python_bindings_common.h"

# if defined(__APPLE__)
# undef HAVE_SSIZE_T
# include <pyport.h>
# endif

#include "condor_common.h"
#include <boost/python/overloads.hpp>

#include "enum_utils.h"
#include "condor_attributes.h"
#include "dc_startd.h"
#include "globus_utils.h"
#include "classad/source.h"

#include "old_boost.h"
#include "module_lock.h"
#include "classad_wrapper.h"

/*
 * Object representing a claim on a remote startd.
 *
 * Purpose is twofold: one, to represent 'full' claims as found in the
 * collector.  Two, to provide a python binding for the COD API.
 */
struct Startd
{

    Startd() {}

    Startd(boost::python::object ad_obj)
    {
        ClassAdWrapper ad = boost::python::extract<ClassAdWrapper>(ad_obj);
        if (!ad.EvaluateAttrString(ATTR_MY_ADDRESS, m_addr))
        {
            THROW_EX(ValueError, "No contact string in ClassAd");
        }
    }

    std::string
    drain_jobs(int how_fast=DRAIN_GRACEFUL, bool resume_on_completion=false, boost::python::object check_obj=boost::python::object(""), boost::python::object start_obj = boost::python::object() )
    {
        std::string check_expr;
        boost::python::extract<std::string> expr_extract(check_obj);
        if (expr_extract.check())
        {
            check_expr = expr_extract();
        }
        else
        {
            classad::ClassAdUnParser printer;
            classad_shared_ptr<classad::ExprTree> expr(convert_python_to_exprtree(check_obj));
            printer.Unparse(check_expr, expr.get());
        }

		std::string start_expr;
		boost::python::extract<std::string> start_extract( start_obj );
		if( start_extract.check() ) {
			start_expr = start_extract();
		} else {
			classad::ClassAdUnParser printer;
			classad_shared_ptr<classad::ExprTree> expr(convert_python_to_exprtree(start_obj));
			printer.Unparse( start_expr, expr.get());
		}

        std::string request_id;

        DCStartd startd(m_addr.c_str());
        bool rval = startd.drainJobs(how_fast, resume_on_completion, check_expr.c_str(), start_expr.c_str(), request_id);
        if (!rval) {THROW_EX(RuntimeError, "Startd failed to begin draining jobs.");}
        return request_id;
    }

    void
    cancel_drain_jobs(boost::python::object rid=boost::python::object())
    {
        const char * request_id = NULL;
        std::string request_id_str;
        if (rid.ptr() == Py_None)
        {
            request_id = NULL;
        }
        else
        {
            request_id_str = boost::python::extract<std::string>(rid);
            request_id = request_id_str.c_str();
        }

        DCStartd startd(m_addr.c_str());
        bool rval = startd.cancelDrainJobs( request_id );
        if (!rval) {THROW_EX(RuntimeError, "Startd failed to cancel draining jobs.");}
    }

private:

    std::string m_addr;
};

void
export_startd()
{
    boost::python::enum_<int>("DrainTypes")
        .value("Fast", DRAIN_FAST)
        .value("Graceful", DRAIN_GRACEFUL)
        .value("Quick", DRAIN_QUICK)
        ;

#if BOOST_VERSION >= 103400
    boost::python::docstring_options doc_options;
    doc_options.disable_cpp_signatures();
    #define SELFARG boost::python::arg("self"),
#else
    #define SELFARG
#endif

    boost::python::class_<Startd>("Startd", "A client class for controlling Startds in HTCondor")
        .def(boost::python::init<>())
        .def(boost::python::init<boost::python::object>(":param ad: An ad describing the Claim (optionally) and a Startd location."))

        .def("drainJobs", &Startd::drain_jobs, "Drain jobs from a startd.",
            ":param drain_type: Type of drain to perform (Fast, Graceful or Quick); must be from DrainTypes enum."
            ":param resume_on_completion: If true, startd will exit the draining state when draining completes.\n"
            ":param constraint: An optional check expression that must be true for all slots for draining to begin; defaults to 'true'\n"
            ":param start_expr: An optional expression that will be used as the START expression while draining; defaults to FALSE.\n"
            ":return: a drain request id that can be used to cancel draining.",
               (SELFARG
                boost::python::arg("drain_type")=DRAIN_GRACEFUL,
                boost::python::arg("resume_on_completion")=false,
                boost::python::arg("constraint")="true",
                boost::python::arg("start_expr")="false"
               )
            )

        .def("cancelDrainJobs", &Startd::cancel_drain_jobs, "Cancel draining jobs from a startd.",
            ":param request_id: optional, if specified cancels only the drain command with the given request_id.",
               (SELFARG
                boost::python::arg("request_id")=""
               )
           )
        ;
}

<|endoftext|>


<commit_before>#include "askpassphrasedialog.h"
#include "ui_askpassphrasedialog.h"

#include "guiconstants.h"
#include "walletmodel.h"

#include <QMessageBox>
#include <QPushButton>
#include <QKeyEvent>

AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AskPassphraseDialog),
    mode(mode),
    model(0),
    fCapsLock(false)
{
    ui->setupUi(this);
    ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE);

    // Setup Caps Lock detection.
    ui->passEdit1->installEventFilter(this);
    ui->passEdit2->installEventFilter(this);
    ui->passEdit3->installEventFilter(this);
    ui->capsLabel->clear();

    switch(mode)
    {
        case Encrypt: // Ask passphrase x2
            ui->passLabel1->hide();
            ui->passEdit1->hide();
            ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of 10 or more random characters, or eight or more words."));
            setWindowTitle(tr("Encrypt wallet"));
            break;
        case Unlock: // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Unlock wallet"));
            break;
        case Decrypt:   // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Decrypt wallet"));
            break;
        case ChangePass: // Ask old passphrase + new passphrase x2
            setWindowTitle(tr("Change passphrase"));
            ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet."));
            break;
    }

    textChanged();
    connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
}

AskPassphraseDialog::~AskPassphraseDialog()
{
    // Attempt to overwrite text so that they do not linger around in memory
    ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size()));
    ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size()));
    ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size()));
    delete ui;
}

void AskPassphraseDialog::setModel(WalletModel *model)
{
    this->model = model;
}

void AskPassphraseDialog::accept()
{
    SecureString oldpass, newpass1, newpass2;
    if(!model)
        return;
    oldpass.reserve(MAX_PASSPHRASE_SIZE);
    newpass1.reserve(MAX_PASSPHRASE_SIZE);
    newpass2.reserve(MAX_PASSPHRASE_SIZE);
    // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
    // Alternately, find a way to make this input mlock()'d to begin with.
    oldpass.assign(ui->passEdit1->text().toStdString().c_str());
    newpass1.assign(ui->passEdit2->text().toStdString().c_str());
    newpass2.assign(ui->passEdit3->text().toStdString().c_str());

    switch(mode)
    {
    case Encrypt: {
        if(newpass1.empty() || newpass2.empty())
        {
            // Cannot encrypt with empty passphrase
            break;
        }
        QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"),
                 tr("WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\nAre you sure you wish to encrypt your wallet?"),
                 QMessageBox::Yes|QMessageBox::Cancel,
                 QMessageBox::Cancel);
        if(retval == QMessageBox::Yes)
        {
            if(newpass1 == newpass2)
            {
                if(model->setWalletEncrypted(true, newpass1))
                {
                    QMessageBox::warning(this, tr("Wallet encrypted"),
                                         tr("Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer."));
                    QApplication::quit();
                }
                else
                {
                    QMessageBox::critical(this, tr("Wallet encryption failed"),
                                         tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
                }
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The supplied passphrases do not match."));
            }
        }
        else
        {
            QDialog::reject(); // Cancelled
        }
        } break;
    case Unlock:
        if(!model->setWalletLocked(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet unlock failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case Decrypt:
        if(!model->setWalletEncrypted(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet decryption failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case ChangePass:
        if(newpass1 == newpass2)
        {
            if(model->changePassphrase(oldpass, newpass1))
            {
                QMessageBox::information(this, tr("Wallet encrypted"),
                                     tr("Wallet passphrase was successfully changed."));
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The passphrase entered for the wallet decryption was incorrect."));
            }
        }
        else
        {
            QMessageBox::critical(this, tr("Wallet encryption failed"),
                                 tr("The supplied passphrases do not match."));
        }
        break;
    }
}

void AskPassphraseDialog::textChanged()
{
    // Validate input, set Ok button to enabled when acceptable
    bool acceptable = false;
    switch(mode)
    {
    case Encrypt: // New passphrase x2
        acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    case Unlock: // Old passphrase x1
    case Decrypt:
        acceptable = !ui->passEdit1->text().isEmpty();
        break;
    case ChangePass: // Old passphrase x1, new passphrase x2
        acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    }
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable);
}

bool AskPassphraseDialog::event(QEvent *event)
{
    // Detect Caps Lock key press.
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        if (ke->key() == Qt::Key_CapsLock) {
            fCapsLock = !fCapsLock;
        }
        if (fCapsLock) {
            ui->capsLabel->setText(tr("Warning: The Caps Lock key is on."));
        } else {
            ui->capsLabel->clear();
        }
    }
    return QWidget::event(event);
}

bool AskPassphraseDialog::eventFilter(QObject *, QEvent *event)
{
    /* Detect Caps Lock.
     * There is no good OS-independent way to check a key state in Qt, but we
     * can detect Caps Lock by checking for the following condition:
     * Shift key is down and the result is a lower case character, or
     * Shift key is not down and the result is an upper case character.
     */
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        QString str = ke->text();
        if (str.length() != 0) {
            const QChar *psz = str.unicode();
            bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
            if ((fShift && psz->isLower()) || (!fShift && psz->isUpper())) {
                fCapsLock = true;
                ui->capsLabel->setText(tr("Warning: The Caps Lock key is on."));
            } else if (psz->isLetter()) {
                fCapsLock = false;
                ui->capsLabel->clear();
            }
        }
    }
    return false;
}
<commit_msg>When encrypting the wallet, warn user that old backups will become useless.<commit_after>#include "askpassphrasedialog.h"
#include "ui_askpassphrasedialog.h"

#include "guiconstants.h"
#include "walletmodel.h"

#include <QMessageBox>
#include <QPushButton>
#include <QKeyEvent>

AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AskPassphraseDialog),
    mode(mode),
    model(0),
    fCapsLock(false)
{
    ui->setupUi(this);
    ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE);

    // Setup Caps Lock detection.
    ui->passEdit1->installEventFilter(this);
    ui->passEdit2->installEventFilter(this);
    ui->passEdit3->installEventFilter(this);
    ui->capsLabel->clear();

    switch(mode)
    {
        case Encrypt: // Ask passphrase x2
            ui->passLabel1->hide();
            ui->passEdit1->hide();
            ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of 10 or more random characters, or eight or more words."));
            setWindowTitle(tr("Encrypt wallet"));
            break;
        case Unlock: // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Unlock wallet"));
            break;
        case Decrypt:   // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Decrypt wallet"));
            break;
        case ChangePass: // Ask old passphrase + new passphrase x2
            setWindowTitle(tr("Change passphrase"));
            ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet."));
            break;
    }

    textChanged();
    connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
}

AskPassphraseDialog::~AskPassphraseDialog()
{
    // Attempt to overwrite text so that they do not linger around in memory
    ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size()));
    ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size()));
    ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size()));
    delete ui;
}

void AskPassphraseDialog::setModel(WalletModel *model)
{
    this->model = model;
}

void AskPassphraseDialog::accept()
{
    SecureString oldpass, newpass1, newpass2;
    if(!model)
        return;
    oldpass.reserve(MAX_PASSPHRASE_SIZE);
    newpass1.reserve(MAX_PASSPHRASE_SIZE);
    newpass2.reserve(MAX_PASSPHRASE_SIZE);
    // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
    // Alternately, find a way to make this input mlock()'d to begin with.
    oldpass.assign(ui->passEdit1->text().toStdString().c_str());
    newpass1.assign(ui->passEdit2->text().toStdString().c_str());
    newpass2.assign(ui->passEdit3->text().toStdString().c_str());

    switch(mode)
    {
    case Encrypt: {
        if(newpass1.empty() || newpass2.empty())
        {
            // Cannot encrypt with empty passphrase
            break;
        }
        QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"),
                 tr("WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\nAre you sure you wish to encrypt your wallet?"),
                 QMessageBox::Yes|QMessageBox::Cancel,
                 QMessageBox::Cancel);
        if(retval == QMessageBox::Yes)
        {
            if(newpass1 == newpass2)
            {
                if(model->setWalletEncrypted(true, newpass1))
                {
                    QMessageBox::warning(this, tr("Wallet encrypted"),
                                         "<qt>" +
                                         tr("Bitcoin will close now to finish the encryption process. "
                                         "Remember that encrypting your wallet cannot fully protect "
                                         "your bitcoins from being stolen by malware infecting your computer.") +
                                         "

" +
                                         tr("IMPORTANT: Any previous backups you have made of your wallet file "
                                         "should be replaced with the newly generated, encrypted wallet file. "
                                         "For security reasons, previous backups of the unencrypted wallet file "
                                         "will become useless as soon as you start using the new, encrypted wallet.") +
                                         "</qt>");
                    QApplication::quit();
                }
                else
                {
                    QMessageBox::critical(this, tr("Wallet encryption failed"),
                                         tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
                }
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The supplied passphrases do not match."));
            }
        }
        else
        {
            QDialog::reject(); // Cancelled
        }
        } break;
    case Unlock:
        if(!model->setWalletLocked(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet unlock failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case Decrypt:
        if(!model->setWalletEncrypted(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet decryption failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case ChangePass:
        if(newpass1 == newpass2)
        {
            if(model->changePassphrase(oldpass, newpass1))
            {
                QMessageBox::information(this, tr("Wallet encrypted"),
                                     tr("Wallet passphrase was successfully changed."));
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The passphrase entered for the wallet decryption was incorrect."));
            }
        }
        else
        {
            QMessageBox::critical(this, tr("Wallet encryption failed"),
                                 tr("The supplied passphrases do not match."));
        }
        break;
    }
}

void AskPassphraseDialog::textChanged()
{
    // Validate input, set Ok button to enabled when acceptable
    bool acceptable = false;
    switch(mode)
    {
    case Encrypt: // New passphrase x2
        acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    case Unlock: // Old passphrase x1
    case Decrypt:
        acceptable = !ui->passEdit1->text().isEmpty();
        break;
    case ChangePass: // Old passphrase x1, new passphrase x2
        acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    }
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable);
}

bool AskPassphraseDialog::event(QEvent *event)
{
    // Detect Caps Lock key press.
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        if (ke->key() == Qt::Key_CapsLock) {
            fCapsLock = !fCapsLock;
        }
        if (fCapsLock) {
            ui->capsLabel->setText(tr("Warning: The Caps Lock key is on."));
        } else {
            ui->capsLabel->clear();
        }
    }
    return QWidget::event(event);
}

bool AskPassphraseDialog::eventFilter(QObject *, QEvent *event)
{
    /* Detect Caps Lock.
     * There is no good OS-independent way to check a key state in Qt, but we
     * can detect Caps Lock by checking for the following condition:
     * Shift key is down and the result is a lower case character, or
     * Shift key is not down and the result is an upper case character.
     */
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        QString str = ke->text();
        if (str.length() != 0) {
            const QChar *psz = str.unicode();
            bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
            if ((fShift && psz->isLower()) || (!fShift && psz->isUpper())) {
                fCapsLock = true;
                ui->capsLabel->setText(tr("Warning: The Caps Lock key is on."));
            } else if (psz->isLetter()) {
                fCapsLock = false;
                ui->capsLabel->clear();
            }
        }
    }
    return false;
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (     0, uint256("0x0000002d0f86558a6e737a3a351043ee73906fe077692dfaa3c9328aaca21964"))
        ( 25000, uint256("0x000000000000892fe49518331d3ce99075a61ae03fe0c3fb5363babf793f9ed5"))
        (111111, uint256("0X0000000000023b44c09a7f8740cec05de8d88e7cbc606457cf86c45a8f1c2c1d"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1390822264, // * UNIX timestamp of last checkpoint block
        0,     // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        60000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 0, uint256("0x0000000a23e3eb42dc87b61d4015c80ffd85471d34e2c7210c7ca63b78a58612"))
        ;

    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1390434081,
        0,
        60000.0
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Added checkpoint at 557625<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (     0, uint256("0x0000002d0f86558a6e737a3a351043ee73906fe077692dfaa3c9328aaca21964"))
        ( 25000, uint256("0x000000000000892fe49518331d3ce99075a61ae03fe0c3fb5363babf793f9ed5"))
        (111111, uint256("0x0000000000023b44c09a7f8740cec05de8d88e7cbc606457cf86c45a8f1c2c1d"))
        (557625, uint256("0x0000000000057faf782713f21104bffcfc8cc9107df88dea399b06ffe3e0d6c4"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1408634353, // * UNIX timestamp of last checkpoint block
        0,     // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        1000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 0, uint256("0x0000000a23e3eb42dc87b61d4015c80ffd85471d34e2c7210c7ca63b78a58612"))
        ;

    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1390434081,
        0,
        1000.0
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>