<commit_before>#include "dx509.h"
Persistent<FunctionTemplate> DX509::constructor;

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

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

  NODE_SET_PROTOTYPE_METHOD(constructor, "parse", parseCert);
  Local<ObjectTemplate> proto = constructor->PrototypeTemplate();

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

Handle<Value> DX509::New(const Arguments &args) {
  HandleScope scope;
  DX509 *x = new DX509();
  x->Wrap(args.This());
  return args.This();
}

Handle<Value> DX509::parseCert(const Arguments &args) {
  HandleScope scope;
  DX509 *dx509 = ObjectWrap::Unwrap<DX509>(args.This());

  ASSERT_IS_STRING_OR_BUFFER(args[0]);

  ssize_t cert_len = DecodeBytes(args[0], BINARY);
  char* cert_buf = new char[cert_len];
  ssize_t written = DecodeWrite(cert_buf, cert_len, args[0], BINARY);
  assert(cert_len = written);
  X509 *x = dx509->load_cert(cert_buf, cert_len, 1);

  //node symbols
  Persistent<String> serial_symbol    = NODE_PSYMBOL("serial");
  Persistent<String> subject_symbol    = NODE_PSYMBOL("subject");
  Persistent<String> issuer_symbol     = NODE_PSYMBOL("issuer");
  Persistent<String> valid_from_symbol = NODE_PSYMBOL("valid_from");
  Persistent<String> valid_to_symbol   = NODE_PSYMBOL("valid_to");
  Persistent<String> fingerprint_symbol   = NODE_PSYMBOL("fingerprint");
  Persistent<String> name_symbol       = NODE_PSYMBOL("name");
  Persistent<String> version_symbol    = NODE_PSYMBOL("version");
  Persistent<String> ext_key_usage_symbol = NODE_PSYMBOL("ext_key_usage");
  Persistent<String> signature_algo_symbol = NODE_PSYMBOL("signature_algorithm");
  Persistent<String> signature_symbol = NODE_PSYMBOL("signature");
  Persistent<String> pubkey_symbol = NODE_PSYMBOL("public_key");
  Persistent<String> public_key_algo = NODE_PSYMBOL("public_key_algo");
  Local<Object> info = Object::New();

  //subject name
  char *details = X509_NAME_oneline(X509_get_subject_name(x), 0, 0);
  info->Set(subject_symbol, String::New(details));

  //issuer name
  details = X509_NAME_oneline(X509_get_issuer_name(x), 0, 0);
  info->Set(issuer_symbol, String::New(details));
  OPENSSL_free(details);

  char buf [256];
  BIO* bio = BIO_new(BIO_s_mem());
  memset(buf, 0, sizeof(buf));
  X509_CINF *ci = x->cert_info;

  //Serial
  i2a_ASN1_INTEGER(bio, X509_get_serialNumber(x));
  BIO_read(bio, buf, sizeof(buf)-1);
  info->Set(serial_symbol, String::New(buf));

  //Version
  long l;
  l = X509_get_version(x)+1;
  info->Set(version_symbol, Integer::New(l));

  //valid from
  ASN1_TIME_print(bio, X509_get_notBefore(x));
  BIO_read(bio, buf, sizeof(buf)-1);
  info->Set(valid_from_symbol, String::New(buf));

  //Not before
  ASN1_TIME_print(bio, X509_get_notAfter(x));
  BIO_read(bio, buf, sizeof(buf)-1);
  info->Set(valid_to_symbol, String::New(buf));

  //Public Key info
  int wrote = i2a_ASN1_OBJECT(bio, ci->key->algor->algorithm);
  BIO_read(bio, buf, sizeof(buf)-1);
  buf[wrote] = '\0';
  info->Set(public_key_algo, String::New(buf));

  //Signature Algorithm
  wrote = i2a_ASN1_OBJECT(bio, ci->signature->algorithm);
  BIO_read(bio, buf, sizeof(buf)-1);
  buf[wrote] = '\0';
  info->Set(signature_algo_symbol, String::New(buf));

  //Signature
  BIO *sig_bio = BIO_new(BIO_s_mem());
  ASN1_STRING *sigh = x->signature;
  unsigned char *s;
  unsigned int n1 = sigh->length;
  s = sigh->data;
  for (int i=0; i<n1; i++) {
    BIO_printf(sig_bio, "%02x%s", s[i], ((i+1) == n1) ? "":":");
  }
  char sig_buf [n1*3];
  BIO_read(sig_bio, sig_buf, sizeof(sig_buf)-1);
  info->Set(signature_symbol, String::New(sig_buf));

  //finger print
  int j;
  unsigned int n;
  unsigned char md[EVP_MAX_MD_SIZE];
  const EVP_MD *fdig = EVP_sha1();
  if (X509_digest(x, fdig, md, &n)) {
    const char hex[] = "0123456789ABCDEF";
    char fingerprint[EVP_MAX_MD_SIZE*3];
    for (j=0; j<n; j++) {
      fingerprint[3*j] = hex[(md[j] & 0xf0) >> 4];
      fingerprint[(3*j)+1] = hex[(md[j] & 0x0f)];
      fingerprint[(3*j)+2] = ':';
    }

    if (n > 0) {
      fingerprint[(3*(n-1))+2] = '\0';
    } else {
      fingerprint[0] = '\0';
    }
    info->Set(fingerprint_symbol, String::New(fingerprint));
  } else {
    fprintf(stderr, "Digest bad\n");
  }

  //Extensions
  STACK_OF(ASN1_OBJECT) *eku = (STACK_OF(ASN1_OBJECT) *)X509_get_ext_d2i(
      x, NID_ext_key_usage, NULL, NULL);
  if (eku != NULL) {
    Local<Array> ext_key_usage = Array::New();

    for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
      memset(buf, 0, sizeof(buf));
      OBJ_obj2txt(buf, sizeof(buf) - 1, sk_ASN1_OBJECT_value(eku, i), 1);
      ext_key_usage->Set(Integer::New(i), String::New(buf));
    }
    sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
    info->Set(ext_key_usage_symbol, ext_key_usage);
  }

  EVP_PKEY *pkey;
  pkey = X509_get_pubkey(x);
  BIO *key_bio = BIO_new(BIO_s_mem());
  int ok = PEM_write_bio_PUBKEY(key_bio, pkey);
  if (ok) {
    BUF_MEM *bptr;
    BIO_get_mem_ptr(key_bio, &bptr);
    char *pub_buf = (char *)malloc(bptr->length +1);
    memcpy(pub_buf, bptr->data, bptr->length-1);
    pub_buf[bptr->length-1] = 0;
    info->Set(pubkey_symbol, String::New(pub_buf));
    delete [] pub_buf;
    BIO_free(key_bio);
  }

  // delete [] buf;
  X509_free(x);
  if (bio != NULL) BIO_free(bio);
  return scope.Close(info);
}

X509* DX509::load_cert(char *cert, int cert_len, int format) {
  BIO *bp = BIO_new_mem_buf(cert, cert_len);
  X509 *x = NULL;
  if (format == 0) {
    x = d2i_X509_bio(bp, NULL);
  } else if (format == 1) {
    x = PEM_read_bio_X509_AUX(bp, NULL, NULL, NULL);
  }

  if (x == NULL) {
    // ERR_print_errors(stderr);
  }
  if (bp != NULL) {
    BIO_free(bp);
  }
  return x;
}

DX509::DX509() : ObjectWrap() {
}

DX509::~DX509() {
}
<commit_msg>serial in proper format<commit_after>#include "dx509.h"
Persistent<FunctionTemplate> DX509::constructor;

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

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

  NODE_SET_PROTOTYPE_METHOD(constructor, "parse", parseCert);
  Local<ObjectTemplate> proto = constructor->PrototypeTemplate();

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

Handle<Value> DX509::New(const Arguments &args) {
  HandleScope scope;
  DX509 *x = new DX509();
  x->Wrap(args.This());
  return args.This();
}

Handle<Value> DX509::parseCert(const Arguments &args) {
  HandleScope scope;
  DX509 *dx509 = ObjectWrap::Unwrap<DX509>(args.This());

  ASSERT_IS_STRING_OR_BUFFER(args[0]);

  ssize_t cert_len = DecodeBytes(args[0], BINARY);
  char* cert_buf = new char[cert_len];
  ssize_t written = DecodeWrite(cert_buf, cert_len, args[0], BINARY);
  assert(cert_len = written);
  X509 *x = dx509->load_cert(cert_buf, cert_len, 1);

  //node symbols
  Persistent<String> serial_symbol    = NODE_PSYMBOL("serial");
  Persistent<String> subject_symbol    = NODE_PSYMBOL("subject");
  Persistent<String> issuer_symbol     = NODE_PSYMBOL("issuer");
  Persistent<String> valid_from_symbol = NODE_PSYMBOL("valid_from");
  Persistent<String> valid_to_symbol   = NODE_PSYMBOL("valid_to");
  Persistent<String> fingerprint_symbol   = NODE_PSYMBOL("fingerprint");
  Persistent<String> name_symbol       = NODE_PSYMBOL("name");
  Persistent<String> version_symbol    = NODE_PSYMBOL("version");
  Persistent<String> ext_key_usage_symbol = NODE_PSYMBOL("ext_key_usage");
  Persistent<String> signature_algo_symbol = NODE_PSYMBOL("signature_algorithm");
  Persistent<String> signature_symbol = NODE_PSYMBOL("signature");
  Persistent<String> pubkey_symbol = NODE_PSYMBOL("public_key");
  Persistent<String> public_key_algo = NODE_PSYMBOL("public_key_algo");
  Local<Object> info = Object::New();

  //subject name
  char *details = X509_NAME_oneline(X509_get_subject_name(x), 0, 0);
  info->Set(subject_symbol, String::New(details));

  //issuer name
  details = X509_NAME_oneline(X509_get_issuer_name(x), 0, 0);
  info->Set(issuer_symbol, String::New(details));
  OPENSSL_free(details);

  char buf [256];
  BIO* bio = BIO_new(BIO_s_mem());
  memset(buf, 0, sizeof(buf));
  X509_CINF *ci = x->cert_info;

  //Serial
  ASN1_INTEGER *bs = X509_get_serialNumber(x);
  for (int i = 0; i< bs->length; i++) {
    BIO_printf(bio, "%02x%s", bs->data[i], ((i+1 == bs->length)? "": ":"));
  }
  BIO_read(bio, buf, sizeof(buf)-1);
  info->Set(serial_symbol, String::New(buf));

  //Version
  long l;
  l = X509_get_version(x)+1;
  info->Set(version_symbol, Integer::New(l));

  //valid from
  ASN1_TIME_print(bio, X509_get_notBefore(x));
  BIO_read(bio, buf, sizeof(buf)-1);
  info->Set(valid_from_symbol, String::New(buf));

  //Not before
  ASN1_TIME_print(bio, X509_get_notAfter(x));
  BIO_read(bio, buf, sizeof(buf)-1);
  info->Set(valid_to_symbol, String::New(buf));

  //Public Key info
  int wrote = i2a_ASN1_OBJECT(bio, ci->key->algor->algorithm);
  BIO_read(bio, buf, sizeof(buf)-1);
  buf[wrote] = '\0';
  info->Set(public_key_algo, String::New(buf));

  //Signature Algorithm
  wrote = i2a_ASN1_OBJECT(bio, ci->signature->algorithm);
  BIO_read(bio, buf, sizeof(buf)-1);
  buf[wrote] = '\0';
  info->Set(signature_algo_symbol, String::New(buf));

  //Signature
  BIO *sig_bio = BIO_new(BIO_s_mem());
  ASN1_STRING *sigh = x->signature;
  unsigned char *s;
  unsigned int n1 = sigh->length;
  s = sigh->data;
  for (int i=0; i<n1; i++) {
    BIO_printf(sig_bio, "%02x%s", s[i], ((i+1) == n1) ? "":":");
  }
  char sig_buf [n1*3];
  BIO_read(sig_bio, sig_buf, sizeof(sig_buf)-1);
  info->Set(signature_symbol, String::New(sig_buf));

  //finger print
  int j;
  unsigned int n;
  unsigned char md[EVP_MAX_MD_SIZE];
  const EVP_MD *fdig = EVP_sha1();
  if (X509_digest(x, fdig, md, &n)) {
    const char hex[] = "0123456789ABCDEF";
    char fingerprint[EVP_MAX_MD_SIZE*3];
    for (j=0; j<n; j++) {
      fingerprint[3*j] = hex[(md[j] & 0xf0) >> 4];
      fingerprint[(3*j)+1] = hex[(md[j] & 0x0f)];
      fingerprint[(3*j)+2] = ':';
    }

    if (n > 0) {
      fingerprint[(3*(n-1))+2] = '\0';
    } else {
      fingerprint[0] = '\0';
    }
    info->Set(fingerprint_symbol, String::New(fingerprint));
  } else {
    fprintf(stderr, "Digest bad\n");
  }

  //Extensions
  STACK_OF(ASN1_OBJECT) *eku = (STACK_OF(ASN1_OBJECT) *)X509_get_ext_d2i(
      x, NID_ext_key_usage, NULL, NULL);
  if (eku != NULL) {
    Local<Array> ext_key_usage = Array::New();

    for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
      memset(buf, 0, sizeof(buf));
      OBJ_obj2txt(buf, sizeof(buf) - 1, sk_ASN1_OBJECT_value(eku, i), 1);
      ext_key_usage->Set(Integer::New(i), String::New(buf));
    }
    sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
    info->Set(ext_key_usage_symbol, ext_key_usage);
  }

  EVP_PKEY *pkey;
  pkey = X509_get_pubkey(x);
  BIO *key_bio = BIO_new(BIO_s_mem());
  int ok = PEM_write_bio_PUBKEY(key_bio, pkey);
  if (ok) {
    BUF_MEM *bptr;
    BIO_get_mem_ptr(key_bio, &bptr);
    char *pub_buf = (char *)malloc(bptr->length +1);
    memcpy(pub_buf, bptr->data, bptr->length-1);
    pub_buf[bptr->length-1] = 0;
    info->Set(pubkey_symbol, String::New(pub_buf));
    delete [] pub_buf;
    BIO_free(key_bio);
  }

  // delete [] buf;
  X509_free(x);
  if (bio != NULL) BIO_free(bio);
  return scope.Close(info);
}

X509* DX509::load_cert(char *cert, int cert_len, int format) {
  BIO *bp = BIO_new_mem_buf(cert, cert_len);
  X509 *x = NULL;
  if (format == 0) {
    x = d2i_X509_bio(bp, NULL);
  } else if (format == 1) {
    x = PEM_read_bio_X509_AUX(bp, NULL, NULL, NULL);
  }

  if (x == NULL) {
    // ERR_print_errors(stderr);
  }
  if (bp != NULL) {
    BIO_free(bp);
  }
  return x;
}

DX509::DX509() : ObjectWrap() {
}

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


<commit_before>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>

using namespace std;

const int width=640, height=480;
const int pipRadius = 10;
const int racketWidth = 20;

int pipX = width/2, pipY = height/2;
int pipXSpeed = 200, pipYSpeed = 200; // pixels per second

int racketSpeed = 200;

int lastTime = 0;

enum RacketPosition {LEFT, RIGHT};

struct Racket {
    int y;
    int size;
    float r, g, b;
    RacketPosition position;

    Racket(RacketPosition position, int y, int size, float r, float g, float b) {
        this->position = position;
        this->y = y;
        this->size = size;
        this->r = r;
        this->g = g;
        this->b = b;
    }
};

Racket racket1 = Racket(LEFT, height/2, 120, 1, 1, 0);
Racket racket2 = Racket(RIGHT, height/2, 120, 0, 1, 1);

void reshape(GLFWwindow* window, int width, int height ) {
    int w, h;
    glfwGetFramebufferSize(window, &w, &h);
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION );
    glLoadIdentity();
    glScalef(1.f, -1.f, 1.f);
    glOrtho(0, width, height, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW );
    glLoadIdentity();
}

void drawNet() {
    glPushMatrix();

    glColor3f(0, 0, 1);
    glLineWidth(5);

    glBegin(GL_LINES);
        glVertex2d(width/2, 0);
        glVertex2d(width/2, height);
    glEnd();

    glPopMatrix();
}

void drawBall() {
    glPushMatrix();

    glColor3f(1.0, 0.0, 0.0);

    glBegin(GL_QUADS);
        glVertex2d(pipX - pipRadius, pipY + pipRadius);
        glVertex2d(pipX + pipRadius, pipY + pipRadius);
        glVertex2d(pipX + pipRadius, pipY - pipRadius);
        glVertex2d(pipX - pipRadius, pipY - pipRadius);
    glEnd();

    glPopMatrix();
}

void drawRacket(Racket racket) {
    glPushMatrix();

    glColor3f(racket.r, racket.g, racket.b);

    int racketLeft;

    switch(racket.position) {
        case RIGHT:
            racketLeft = width - racketWidth;
            break;
        case LEFT:
            racketLeft = 0;
        default:
            break;
    }

    glBegin(GL_QUADS);
        glVertex2d(racketLeft, racket.y + racket.size/2);
        glVertex2d(racketLeft + racketWidth, racket.y + racket.size/2);
        glVertex2d(racketLeft + racketWidth, racket.y - racket.size/2);
        glVertex2d(racketLeft, racket.y - racket.size/2);
    glEnd();

    glPopMatrix();
}

int guessWherePipIsGoing() {
    int distanceToWall = 0;
    if (pipXSpeed > 0) {
        distanceToWall = width - (pipRadius * 2) - pipX;
        cout << "to me: " << distanceToWall << endl;
    } else {
        distanceToWall = pipX - (pipRadius * 2);
        cout << "to you: " << distanceToWall << endl;
    }
    //float angle = atan(pipYSpeed / pipXSpeed);
    //cout << "with an angle of atan(" << pipYSpeed/pipXSpeed <<  ")=" << angle << endl;
    //return pipY + (tan(angle) * distanceToWall);
    //cout << "predicted y: " << (distanceToWall / abs(pipXSpeed)) * pipYSpeed << endl;

    return pipY + (distanceToWall / pipXSpeed) * pipYSpeed;
}

void moveRacketToY(Racket & racket, int timeDiff) {
    int y = height/2;
    if (racket.position == RIGHT && pipXSpeed > 0) {
        y = guessWherePipIsGoing();
    } else if (racket.position == LEFT && pipXSpeed <= 0) {
        y = guessWherePipIsGoing();
    }

    if(racket.y < y) {
        if (height - racket.y <= racket.size / 2) {
            racket.y = height - racket.size / 2;
        } else if (y - racket.y > (racketSpeed * timeDiff) / 1000) {
            racket.y += (racketSpeed * timeDiff) / 1000;
        } else {
            racket.y = y;
        }
    } else if(racket.y > y) {
        if (racket.y <= racket.size / 2) {
            racket.y = racket.size / 2;
        } else if (racket.y - y > (racketSpeed * timeDiff) / 1000) {
            racket.y -= (racketSpeed * timeDiff) / 1000;
        } else {
            racket.y = y;
        }
    }
}

bool collidesWithRacket(Racket racket) {
    if (pipY > racket.y + racket.size/2 || pipY < racket.y - racket.size/2)
        return false;

    switch(racket.position) {
        case RIGHT:
            if (pipX < width - racketWidth)
                return false;
            break;
        case LEFT:
            if (pipX > racketWidth)
                return false;
        default:
            break;
    }

    return true;

}

void recalculateBall(int timeDiff) {
    pipX += (pipXSpeed * timeDiff)/1000;
    pipY += (pipYSpeed * timeDiff)/1000;

    if (pipY < pipRadius || pipY > height - pipRadius) {
        if (pipY < pipRadius) pipY = pipRadius;
        if (pipY > height - pipRadius) pipY = height - pipRadius;
        pipYSpeed = -pipYSpeed;
    }

    if (collidesWithRacket(racket1) || collidesWithRacket(racket2)) {
        if (pipX < racketWidth + pipRadius) pipX = racketWidth + pipRadius;
        if (pipX > width - racketWidth - pipRadius) pipX = width - racketWidth - pipRadius;
        pipXSpeed = -pipXSpeed;
    } else if (pipX < pipRadius || pipX > width - pipRadius) {
        if (pipX < pipRadius) pipX = pipRadius;
        if (pipX > width - pipRadius) pipX = width - pipRadius;
        pipX = width/2;
        pipY = height/2;
    }
}

int main(void) {
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */

    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    window = glfwCreateWindow(width, height, "Lana Tennis", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    reshape(window, width, height);

    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glfwSetWindowSizeCallback(window, reshape);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window)) {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        int newTime = floor(glfwGetTime() * 1000);
        if (newTime - lastTime > 10) {
            recalculateBall(newTime - lastTime);

            moveRacketToY(racket1, newTime - lastTime);
            moveRacketToY(racket2, newTime - lastTime);

            lastTime = newTime;
        }

        drawNet();
        drawBall();
        drawRacket(racket1);
        drawRacket(racket2);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}<commit_msg>Fixed AI movement<commit_after>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>

using namespace std;

const int width=640, height=480;
const int pipRadius = 10;
const int racketWidth = 20;

int pipX = width/2, pipY = height/2;
int pipXSpeed = 200, pipYSpeed = 200; // pixels per second

int racketSpeed = 200;

int lastTime = 0;

enum RacketPosition {LEFT, RIGHT};

struct Racket {
    int y;
    int size;
    float r, g, b;
    RacketPosition position;

    Racket(RacketPosition position, int y, int size, float r, float g, float b) {
        this->position = position;
        this->y = y;
        this->size = size;
        this->r = r;
        this->g = g;
        this->b = b;
    }
};

Racket racket1 = Racket(LEFT, height/2, 120, 1, 1, 0);
Racket racket2 = Racket(RIGHT, height/2, 120, 0, 1, 1);

void reshape(GLFWwindow* window, int width, int height ) {
    int w, h;
    glfwGetFramebufferSize(window, &w, &h);
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION );
    glLoadIdentity();
    glScalef(1.f, -1.f, 1.f);
    glOrtho(0, width, height, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW );
    glLoadIdentity();
}

void drawNet() {
    glPushMatrix();

    glColor3f(0, 0, 1);
    glLineWidth(5);

    glBegin(GL_LINES);
        glVertex2d(width/2, 0);
        glVertex2d(width/2, height);
    glEnd();

    glPopMatrix();
}

void drawBall() {
    glPushMatrix();

    glColor3f(1.0, 0.0, 0.0);

    glBegin(GL_QUADS);
        glVertex2d(pipX - pipRadius, pipY + pipRadius);
        glVertex2d(pipX + pipRadius, pipY + pipRadius);
        glVertex2d(pipX + pipRadius, pipY - pipRadius);
        glVertex2d(pipX - pipRadius, pipY - pipRadius);
    glEnd();

    glPopMatrix();
}

void drawRacket(Racket racket) {
    glPushMatrix();

    glColor3f(racket.r, racket.g, racket.b);

    int racketLeft;

    switch(racket.position) {
        case RIGHT:
            racketLeft = width - racketWidth;
            break;
        case LEFT:
            racketLeft = 0;
        default:
            break;
    }

    glBegin(GL_QUADS);
        glVertex2d(racketLeft, racket.y + racket.size/2);
        glVertex2d(racketLeft + racketWidth, racket.y + racket.size/2);
        glVertex2d(racketLeft + racketWidth, racket.y - racket.size/2);
        glVertex2d(racketLeft, racket.y - racket.size/2);
    glEnd();

    glPopMatrix();
}

int guessWherePipIsGoing() {
    int distanceToWall = 0;
    if (pipXSpeed > 0) {
        distanceToWall = width - (pipRadius * 2) - pipX;
    } else {
        distanceToWall = pipX - (pipRadius * 2);
    }
    float angle = atan(pipYSpeed / abs(pipXSpeed));
    //cout << "with an angle of atan(" << pipYSpeed/pipXSpeed <<  ")=" << angle << endl;
    //return pipY + (tan(angle) * distanceToWall);
    //cout << "predicted y: " << (distanceToWall / abs(pipXSpeed)) * pipYSpeed << endl;

    cout << "predicted y: " << pipY + (tan(angle) * distanceToWall) << endl;

    return pipY + (tan(angle) * distanceToWall);
}

void moveRacketToY(Racket & racket, int timeDiff) {
    int y = height/2;
    if (racket.position == RIGHT && pipXSpeed > 0) {
        y = guessWherePipIsGoing();
    } else if (racket.position == LEFT && pipXSpeed <= 0) {
        y = guessWherePipIsGoing();
    }

    if(racket.y < y) {
        if (height - racket.y <= racket.size / 2) {
            racket.y = height - racket.size / 2;
        } else if (y - racket.y > (racketSpeed * timeDiff) / 1000) {
            racket.y += (racketSpeed * timeDiff) / 1000;
        } else {
            racket.y = y;
        }
    } else if(racket.y > y) {
        if (racket.y <= racket.size / 2) {
            racket.y = racket.size / 2;
        } else if (racket.y - y > (racketSpeed * timeDiff) / 1000) {
            racket.y -= (racketSpeed * timeDiff) / 1000;
        } else {
            racket.y = y;
        }
    }
}

bool collidesWithRacket(Racket racket) {
    if (pipY > racket.y + racket.size/2 || pipY < racket.y - racket.size/2)
        return false;

    switch(racket.position) {
        case RIGHT:
            if (pipX < width - racketWidth)
                return false;
            break;
        case LEFT:
            if (pipX > racketWidth)
                return false;
        default:
            break;
    }

    return true;

}

void recalculateBall(int timeDiff) {
    pipX += (pipXSpeed * timeDiff)/1000;
    pipY += (pipYSpeed * timeDiff)/1000;

    if (pipY < pipRadius || pipY > height - pipRadius) {
        if (pipY < pipRadius) pipY = pipRadius;
        if (pipY > height - pipRadius) pipY = height - pipRadius;
        pipYSpeed = -pipYSpeed;
    }

    if (collidesWithRacket(racket1) || collidesWithRacket(racket2)) {
        if (pipX < racketWidth + pipRadius) pipX = racketWidth + pipRadius;
        if (pipX > width - racketWidth - pipRadius) pipX = width - racketWidth - pipRadius;
        pipXSpeed = -pipXSpeed;
    } else if (pipX < pipRadius || pipX > width - pipRadius) {
        if (pipX < pipRadius) pipX = pipRadius;
        if (pipX > width - pipRadius) pipX = width - pipRadius;
        pipX = width/2;
        pipY = height/2;
    }
}

int main(void) {
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */

    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    window = glfwCreateWindow(width, height, "Lana Tennis", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    reshape(window, width, height);

    glEnable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glfwSetWindowSizeCallback(window, reshape);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window)) {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        int newTime = floor(glfwGetTime() * 1000);
        if (newTime - lastTime > 10) {
            recalculateBall(newTime - lastTime);

            moveRacketToY(racket1, newTime - lastTime);
            moveRacketToY(racket2, newTime - lastTime);

            lastTime = newTime;
        }

        drawNet();
        drawBall();
        drawRacket(racket1);
        drawRacket(racket2);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}<|endoftext|>


<commit_before>#include "CSAOptMessageQueue.h"
#include <sstream>
#include <csignal>

namespace {
    volatile std::sig_atomic_t gSignalStatus;
}

CSAOpt::MessageQueue *msgQueue;

void signal_handler(int signal) {
    gSignalStatus = signal;
//    if(msgQueue) {
//        msgQueue->abort();
//    }
}

int main(int argc, char* argv[]) {
    int port = 11551;
    int port2 = 12559;
    if(argc > 2) {
        port = std::stoi(std::string{argv[1]});
        port2 = std::stoi(std::string{argv[2]});
    }

    std::signal(SIGINT, signal_handler);

    msgQueue = new CSAOpt::MessageQueue(port, port2);

    while(gSignalStatus == 0) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    std::cout << "Deleting msgQueue" << std::endl;
    delete msgQueue;
    std::cout << "Done." << std::endl;
}
<commit_msg>Made sure to get unsigned ints from the program arguments<commit_after>#include "CSAOptMessageQueue.h"
#include <sstream>
#include <csignal>

namespace {
    volatile std::sig_atomic_t gSignalStatus;
}

CSAOpt::MessageQueue *msgQueue;

void signal_handler(int signal) {
    gSignalStatus = signal;
}

int main(int argc, char* argv[]) {
    unsigned int port = 11551;
    unsigned int port2 = 12559;
    if(argc > 2) {
        port = (unsigned int) std::stoi(std::string{argv[1]});
        port2 = (unsigned int) std::stoi(std::string{argv[2]});
    }

    std::signal(SIGINT, signal_handler);

    msgQueue = new CSAOpt::MessageQueue(port, port2);

    std::vector<std::string> arguments(argv, argv + argc);
    for(auto && arg : arguments) {
        if(arg == "-v" || arg == "--verbose") {
            msgQueue->logDebug();
        }
    }

    while(gSignalStatus == 0 && !msgQueue->finished) {
        // just sit around and wait for exit
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    delete msgQueue;
    std::cout << "Bye." << std::endl;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>

#include <string>

#include "globals.h"
#include "profiler.h"
#include "stacktraces.h"

static Profiler *prof;
FILE *Globals::OutFile;
int Globals::DumpInterval;

void JNICALL OnThreadStart(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
                           jthread thread) {
  IMPLICITLY_USE(jvmti_env);
  IMPLICITLY_USE(thread);
  Accessors::SetCurrentJniEnv(jni_env);
}

void JNICALL OnThreadEnd(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) {
  IMPLICITLY_USE(jvmti_env);
  IMPLICITLY_USE(jni_env);
  IMPLICITLY_USE(thread);
}

// This has to be here, or the VM turns off class loading events.
// And AsyncGetCallTrace needs class loading events to be turned on!
void JNICALL OnClassLoad(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread,
                         jclass klass) {
  IMPLICITLY_USE(jvmti_env);
  IMPLICITLY_USE(jni_env);
  IMPLICITLY_USE(thread);
  IMPLICITLY_USE(klass);
}

// Calls GetClassMethods on a given class to force the creation of
// jmethodIDs of it.
void CreateJMethodIDsForClass(jvmtiEnv *jvmti, jclass klass) {
  jint method_count;
  JvmtiScopedPtr<jmethodID> methods(jvmti);
  jvmtiError e = jvmti->GetClassMethods(klass, &method_count, methods.GetRef());
  if (e != JVMTI_ERROR_NONE && e != JVMTI_ERROR_CLASS_NOT_PREPARED) {
    // JVMTI_ERROR_CLASS_NOT_PREPARED is okay because some classes may
    // be loaded but not prepared at this point.
    JvmtiScopedPtr<char> ksig(jvmti);
    JVMTI_ERROR((jvmti->GetClassSignature(klass, ksig.GetRef(), NULL)));
    fprintf(
        stderr,
        "Failed to create method IDs for methods in class %s with error %d ",
        ksig.Get(), e);
  }
}

void JNICALL OnVMInit(jvmtiEnv *jvmti, JNIEnv *jni_env, jthread thread) {
  IMPLICITLY_USE(thread);
  IMPLICITLY_USE(jni_env);
  // Forces the creation of jmethodIDs of the classes that had already
  // been loaded (eg java.lang.Object, java.lang.ClassLoader) and
  // OnClassPrepare() misses.
  jint class_count;
  JvmtiScopedPtr<jclass> classes(jvmti);
  JVMTI_ERROR((jvmti->GetLoadedClasses(&class_count, classes.GetRef())));
  jclass *classList = classes.Get();
  for (int i = 0; i < class_count; ++i) {
    jclass klass = classList[i];
    CreateJMethodIDsForClass(jvmti, klass);
  }

  //create dumper thread
  if (Globals::DumpInterval > 0) {
      jclass klass = jni_env->FindClass("java/lang/Thread");
      if (!klass) {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
      jmethodID method = jni_env->GetMethodID(klass, "<init>", "(Ljava/lang/String;)V");
      if (!method) {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
      jstring name = jni_env->NewStringUTF("AgentDumperThread");
      if (!name) {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
      jthread dump_thread = jni_env->NewObject(klass, method, name);
      if (!dump_thread) {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
      if (jvmti->RunAgentThread(dump_thread,&_dumper_interface,prof,JVMTI_THREAD_NORM_PRIORITY) !=0)
      {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
  }

  prof->Start();
}

void JNICALL OnClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
                            jthread thread, jclass klass) {
  IMPLICITLY_USE(jni_env);
  IMPLICITLY_USE(thread);
  // We need to do this to "prime the pump", as it were -- make sure
  // that all of the methodIDs have been initialized internally, for
  // AsyncGetCallTrace.  I imagine it slows down class loading a mite,
  // but honestly, how fast does class loading have to be?
  CreateJMethodIDsForClass(jvmti_env, klass);
}

void JNICALL OnVMDeath(jvmtiEnv *jvmti_env, JNIEnv *jni_env) {
  IMPLICITLY_USE(jvmti_env);
  IMPLICITLY_USE(jni_env);

  prof->Stop();
  prof->DumpToFile(Globals::OutFile, NULL);
}

static bool PrepareJvmti(jvmtiEnv *jvmti) {
  // Set the list of permissions to do the various internal VM things
  // we want to do.
  jvmtiCapabilities caps;

  memset(&caps, 0, sizeof(caps));
  caps.can_generate_all_class_hook_events = 1;

  caps.can_get_source_file_name = 1;
  caps.can_get_line_numbers = 1;
  caps.can_get_bytecodes = 1;
  caps.can_get_constant_pool = 1;

  jvmtiCapabilities all_caps;
  int error;

  if (JVMTI_ERROR_NONE ==
      (error = jvmti->GetPotentialCapabilities(&all_caps))) {
    // This makes sure that if we need a capability, it is one of the
    // potential capabilities.  The technique isn't wonderful, but it
    // is compact and as likely to be compatible between versions as
    // anything else.
    char *has = reinterpret_cast<char *>(&all_caps);
    const char *should_have = reinterpret_cast<const char *>(&caps);
    for (int i = 0; i < sizeof(all_caps); i++) {
      if ((should_have[i] != 0) && (has[i] == 0)) {
        return false;
      }
    }

    // This adds the capabilities.
    if ((error = jvmti->AddCapabilities(&caps)) != JVMTI_ERROR_NONE) {
      fprintf(stderr, "Failed to add capabilities with error %d\n", error);
      return false;
    }
  }
  return true;
}

static bool RegisterJvmti(jvmtiEnv *jvmti) {
  // Create the list of callbacks to be called on given events.
  jvmtiEventCallbacks *callbacks = new jvmtiEventCallbacks();
  memset(callbacks, 0, sizeof(jvmtiEventCallbacks));

  callbacks->ThreadStart = &OnThreadStart;
  callbacks->ThreadEnd = &OnThreadEnd;
  callbacks->VMInit = &OnVMInit;
  callbacks->VMDeath = &OnVMDeath;

  callbacks->ClassLoad = &OnClassLoad;
  callbacks->ClassPrepare = &OnClassPrepare;

  JVMTI_ERROR_1(
      (jvmti->SetEventCallbacks(callbacks, sizeof(jvmtiEventCallbacks))),
      false);

  jvmtiEvent events[] = {JVMTI_EVENT_CLASS_LOAD, JVMTI_EVENT_CLASS_PREPARE,
                         JVMTI_EVENT_THREAD_END, JVMTI_EVENT_THREAD_START,
                         JVMTI_EVENT_VM_DEATH, JVMTI_EVENT_VM_INIT};

  size_t num_events = sizeof(events) / sizeof(jvmtiEvent);

  // Enable the callbacks to be triggered when the events occur.
  // Events are enumerated in jvmstatagent.h
  for (int i = 0; i < num_events; i++) {
    JVMTI_ERROR_1(
        (jvmti->SetEventNotificationMode(JVMTI_ENABLE, events[i], NULL)),
        false);
  }

  return true;
}

#define POSITIVE(x) (static_cast<size_t>(x > 0 ? x : 0))

static char* SetFileFromOption(char *equals) {
  char *name_begin = equals + 1;
  char *name_end;
  if ((name_end = strchr(equals, ',')) == NULL) {
    name_end = equals + strlen(equals);
  }
  size_t len = POSITIVE(name_end - name_begin);
  char *file_name = new char[len];
  strncpy(file_name, name_begin, len);
  if (strcmp(file_name, "stderr") == 0) {
    Globals::OutFile = stderr;
  } else if (strcmp(file_name, "stdout") == 0) {
    Globals::OutFile = stdout;
  } else {
    Globals::OutFile = fopen(file_name, "w+");
    if (Globals::OutFile == NULL) {
      fprintf(stderr, "Could not open file %s: ", file_name);
      perror(NULL);
      exit(1);
    }
  }

  delete[] file_name;
  return name_end;
}

static char* SetIntervalFromOption(char *equals) {
  char *name_begin = equals + 1;
  char *name_end;
  if ((name_end = strchr(equals, ',')) == NULL) {
    name_end = equals + strlen(equals);
  }
  size_t len = POSITIVE(name_end - name_begin);
  char *interval = new char[len];
  strncpy(interval, name_begin, len);
  int intervalValue = atoi(interval);
  Globals::DumpInterval = intervalValue;
  delete[] interval;
  return name_end;
}

static void ParseArguments(char *options) {
  char *key = options;
  for (char *next = options; ;
       next = strchr((key = next + 1), ',')) {
    char *equals = strchr(key, '=');
    if (equals == NULL) {
      fprintf(stderr, "No value for key %s\n", key);
      continue;
    }
    if (strncmp(key, "file", POSITIVE(equals - key)) == 0) {
      next=SetFileFromOption(equals);
    }
    if (strncmp(key, "interval", POSITIVE(equals - key)) == 0) {
      next=SetIntervalFromOption(equals);
    }

    if (next == NULL || *next == '\0') {
        break;
    }
  }

  if (Globals::OutFile == NULL) {
    char path[PATH_MAX];
    if (getcwd(path, PATH_MAX) == NULL) {
      fprintf(stderr, "cwd too long?\n");
      exit(0);
    }
    size_t pathlen = strlen(path);
    strncat(path, "/", PATH_MAX - (pathlen++));
    strncat(path, kDefaultOutFile, PATH_MAX - pathlen);
    Globals::OutFile = fopen(path, "w+");
  }
}

AGENTEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options,
                                      void *reserved) {
  IMPLICITLY_USE(reserved);
  int err;
  jvmtiEnv *jvmti;
  ParseArguments(options);

  Accessors::Init();

  if ((err = (vm->GetEnv(reinterpret_cast<void **>(&jvmti), JVMTI_VERSION))) !=
      JNI_OK) {
    fprintf(stderr, "JNI Error %d\n", err);
    return 1;
  }

  if (!PrepareJvmti(jvmti)) {
    fprintf(stderr, "Failed to initialize JVMTI.  Continuing...\n");
    return 0;
  }

  if (!RegisterJvmti(jvmti)) {
    fprintf(stderr, "Failed to enable JVMTI events.  Continuing...\n");
    // We fail hard here because we may have failed in the middle of
    // registering callbacks, which will leave the system in an
    // inconsistent state.
    return 1;
  }

  Asgct::SetAsgct(Accessors::GetJvmFunction<ASGCTType>("AsyncGetCallTrace"));

  prof = new Profiler(jvmti);

  return 0;
}

AGENTEXPORT void JNICALL Agent_OnUnload(JavaVM *vm) {
  IMPLICITLY_USE(vm);
  Accessors::Destroy();
}
<commit_msg>fix argument parse bug<commit_after>#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>

#include <string>

#include "globals.h"
#include "profiler.h"
#include "stacktraces.h"

static Profiler *prof;
FILE *Globals::OutFile;
int Globals::DumpInterval;

void JNICALL OnThreadStart(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
                           jthread thread) {
  IMPLICITLY_USE(jvmti_env);
  IMPLICITLY_USE(thread);
  Accessors::SetCurrentJniEnv(jni_env);
}

void JNICALL OnThreadEnd(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) {
  IMPLICITLY_USE(jvmti_env);
  IMPLICITLY_USE(jni_env);
  IMPLICITLY_USE(thread);
}

// This has to be here, or the VM turns off class loading events.
// And AsyncGetCallTrace needs class loading events to be turned on!
void JNICALL OnClassLoad(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread,
                         jclass klass) {
  IMPLICITLY_USE(jvmti_env);
  IMPLICITLY_USE(jni_env);
  IMPLICITLY_USE(thread);
  IMPLICITLY_USE(klass);
}

// Calls GetClassMethods on a given class to force the creation of
// jmethodIDs of it.
void CreateJMethodIDsForClass(jvmtiEnv *jvmti, jclass klass) {
  jint method_count;
  JvmtiScopedPtr<jmethodID> methods(jvmti);
  jvmtiError e = jvmti->GetClassMethods(klass, &method_count, methods.GetRef());
  if (e != JVMTI_ERROR_NONE && e != JVMTI_ERROR_CLASS_NOT_PREPARED) {
    // JVMTI_ERROR_CLASS_NOT_PREPARED is okay because some classes may
    // be loaded but not prepared at this point.
    JvmtiScopedPtr<char> ksig(jvmti);
    JVMTI_ERROR((jvmti->GetClassSignature(klass, ksig.GetRef(), NULL)));
    fprintf(
        stderr,
        "Failed to create method IDs for methods in class %s with error %d ",
        ksig.Get(), e);
  }
}

void JNICALL OnVMInit(jvmtiEnv *jvmti, JNIEnv *jni_env, jthread thread) {
  IMPLICITLY_USE(thread);
  IMPLICITLY_USE(jni_env);
  // Forces the creation of jmethodIDs of the classes that had already
  // been loaded (eg java.lang.Object, java.lang.ClassLoader) and
  // OnClassPrepare() misses.
  jint class_count;
  JvmtiScopedPtr<jclass> classes(jvmti);
  JVMTI_ERROR((jvmti->GetLoadedClasses(&class_count, classes.GetRef())));
  jclass *classList = classes.Get();
  for (int i = 0; i < class_count; ++i) {
    jclass klass = classList[i];
    CreateJMethodIDsForClass(jvmti, klass);
  }

  //create dumper thread
  if (Globals::DumpInterval > 0) {
      jclass klass = jni_env->FindClass("java/lang/Thread");
      if (!klass) {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
      jmethodID method = jni_env->GetMethodID(klass, "<init>", "(Ljava/lang/String;)V");
      if (!method) {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
      jstring name = jni_env->NewStringUTF("AgentDumperThread");
      if (!name) {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
      jthread dump_thread = jni_env->NewObject(klass, method, name);
      if (!dump_thread) {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
      if (jvmti->RunAgentThread(dump_thread,&_dumper_interface,prof,JVMTI_THREAD_NORM_PRIORITY) !=0)
      {
          fprintf(stderr, "Failed to start dumper thread\n");
          return ;
      }
  }

  prof->Start();
}

void JNICALL OnClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *jni_env,
                            jthread thread, jclass klass) {
  IMPLICITLY_USE(jni_env);
  IMPLICITLY_USE(thread);
  // We need to do this to "prime the pump", as it were -- make sure
  // that all of the methodIDs have been initialized internally, for
  // AsyncGetCallTrace.  I imagine it slows down class loading a mite,
  // but honestly, how fast does class loading have to be?
  CreateJMethodIDsForClass(jvmti_env, klass);
}

void JNICALL OnVMDeath(jvmtiEnv *jvmti_env, JNIEnv *jni_env) {
  IMPLICITLY_USE(jvmti_env);
  IMPLICITLY_USE(jni_env);

  prof->Stop();
  prof->DumpToFile(Globals::OutFile, NULL);
}

static bool PrepareJvmti(jvmtiEnv *jvmti) {
  // Set the list of permissions to do the various internal VM things
  // we want to do.
  jvmtiCapabilities caps;

  memset(&caps, 0, sizeof(caps));
  caps.can_generate_all_class_hook_events = 1;

  caps.can_get_source_file_name = 1;
  caps.can_get_line_numbers = 1;
  caps.can_get_bytecodes = 1;
  caps.can_get_constant_pool = 1;

  jvmtiCapabilities all_caps;
  int error;

  if (JVMTI_ERROR_NONE ==
      (error = jvmti->GetPotentialCapabilities(&all_caps))) {
    // This makes sure that if we need a capability, it is one of the
    // potential capabilities.  The technique isn't wonderful, but it
    // is compact and as likely to be compatible between versions as
    // anything else.
    char *has = reinterpret_cast<char *>(&all_caps);
    const char *should_have = reinterpret_cast<const char *>(&caps);
    for (int i = 0; i < sizeof(all_caps); i++) {
      if ((should_have[i] != 0) && (has[i] == 0)) {
        return false;
      }
    }

    // This adds the capabilities.
    if ((error = jvmti->AddCapabilities(&caps)) != JVMTI_ERROR_NONE) {
      fprintf(stderr, "Failed to add capabilities with error %d\n", error);
      return false;
    }
  }
  return true;
}

static bool RegisterJvmti(jvmtiEnv *jvmti) {
  // Create the list of callbacks to be called on given events.
  jvmtiEventCallbacks *callbacks = new jvmtiEventCallbacks();
  memset(callbacks, 0, sizeof(jvmtiEventCallbacks));

  callbacks->ThreadStart = &OnThreadStart;
  callbacks->ThreadEnd = &OnThreadEnd;
  callbacks->VMInit = &OnVMInit;
  callbacks->VMDeath = &OnVMDeath;

  callbacks->ClassLoad = &OnClassLoad;
  callbacks->ClassPrepare = &OnClassPrepare;

  JVMTI_ERROR_1(
      (jvmti->SetEventCallbacks(callbacks, sizeof(jvmtiEventCallbacks))),
      false);

  jvmtiEvent events[] = {JVMTI_EVENT_CLASS_LOAD, JVMTI_EVENT_CLASS_PREPARE,
                         JVMTI_EVENT_THREAD_END, JVMTI_EVENT_THREAD_START,
                         JVMTI_EVENT_VM_DEATH, JVMTI_EVENT_VM_INIT};

  size_t num_events = sizeof(events) / sizeof(jvmtiEvent);

  // Enable the callbacks to be triggered when the events occur.
  // Events are enumerated in jvmstatagent.h
  for (int i = 0; i < num_events; i++) {
    JVMTI_ERROR_1(
        (jvmti->SetEventNotificationMode(JVMTI_ENABLE, events[i], NULL)),
        false);
  }

  return true;
}

#define POSITIVE(x) (static_cast<size_t>(x > 0 ? x : 0))

static void SetFileFromOption(char *equals) {
  char *name_begin = equals + 1;
  char *name_end;
  if ((name_end = strchr(equals, ',')) == NULL) {
    name_end = equals + strlen(equals);
  }
  size_t len = POSITIVE(name_end - name_begin);
  char *file_name = new char[len];
  strncpy(file_name, name_begin, len);
  if (strcmp(file_name, "stderr") == 0) {
    Globals::OutFile = stderr;
  } else if (strcmp(file_name, "stdout") == 0) {
    Globals::OutFile = stdout;
  } else {
    Globals::OutFile = fopen(file_name, "w+");
    if (Globals::OutFile == NULL) {
      fprintf(stderr, "Could not open file %s: ", file_name);
      perror(NULL);
      exit(1);
    }
  }

  delete[] file_name;
}

static void SetIntervalFromOption(char *equals) {
  char *name_begin = equals + 1;
  char *name_end;
  if ((name_end = strchr(equals, ',')) == NULL) {
    name_end = equals + strlen(equals);
  }
  size_t len = POSITIVE(name_end - name_begin);
  char *interval = new char[len];
  strncpy(interval, name_begin, len);
  int intervalValue = atoi(interval);
  Globals::DumpInterval = intervalValue;
  delete[] interval;
}

static void ParseArguments(char *options) {
  if (options == NULL) {
      return;
  }
  char *key = options;
  for (char *next = strchr(options,','); *key != '\0';
          next = strchr((key = next + 1), ',')) {
      char *equals = strchr(key, '=');
      if (equals == NULL) {
          fprintf(stderr, "No value for key %s\n", key);
          continue;
      }
      if (strncmp(key, "file", POSITIVE(equals - key)) == 0) {
          SetFileFromOption(equals);
      }
      if (strncmp(key, "interval", POSITIVE(equals - key)) == 0) {
          SetIntervalFromOption(equals);
      }

      if (next == NULL || *next == '\0') {
          break;
      }
  }

  if (Globals::OutFile == NULL) {
    char path[PATH_MAX];
    if (getcwd(path, PATH_MAX) == NULL) {
      fprintf(stderr, "cwd too long?\n");
      exit(0);
    }
    size_t pathlen = strlen(path);
    strncat(path, "/", PATH_MAX - (pathlen++));
    strncat(path, kDefaultOutFile, PATH_MAX - pathlen);
    Globals::OutFile = fopen(path, "w+");
  }
}

AGENTEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options,
                                      void *reserved) {
  IMPLICITLY_USE(reserved);
  int err;
  jvmtiEnv *jvmti;
  ParseArguments(options);

  Accessors::Init();

  if ((err = (vm->GetEnv(reinterpret_cast<void **>(&jvmti), JVMTI_VERSION))) !=
      JNI_OK) {
    fprintf(stderr, "JNI Error %d\n", err);
    return 1;
  }

  if (!PrepareJvmti(jvmti)) {
    fprintf(stderr, "Failed to initialize JVMTI.  Continuing...\n");
    return 0;
  }

  if (!RegisterJvmti(jvmti)) {
    fprintf(stderr, "Failed to enable JVMTI events.  Continuing...\n");
    // We fail hard here because we may have failed in the middle of
    // registering callbacks, which will leave the system in an
    // inconsistent state.
    return 1;
  }

  Asgct::SetAsgct(Accessors::GetJvmFunction<ASGCTType>("AsyncGetCallTrace"));

  prof = new Profiler(jvmti);

  return 0;
}

AGENTEXPORT void JNICALL Agent_OnUnload(JavaVM *vm) {
  IMPLICITLY_USE(vm);
  Accessors::Destroy();
}
<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Alexander Chumakov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "testbase.h"

#include "utils.h"

#include <QMap>
#include <QDebug>
#include <wbxml.h>
#include <string.h>
#include <wbxml_conv.h>

#include <QDateTime>
#include <QCoreApplication>

/*!
    \page example.html
    \title Generic QDoc Guide
    There are three essential materials for generating documentation with qdoc:

    \list
        \li \c qdoc binary
        \li \c qdocconf configuration files
        \li \c Documentation in \c C++, \c QML, and \c .qdoc files
    \endlist
*/

QMap<int, QString> TheMap;

int main(int argc, char **argv)
{
  QCoreApplication app(argc, argv);

  if (2 == argc && !strcmp(argv[1], "reg")) {
    Utils::registerAccount();
    qDebug() << "MAIN: registration done.";
    return 0;
  } else if (2 == argc && !strcmp(argv[1], "iconv")) {
    Utils::iconvTest();
    return 0;
  } else if (2 == argc && !strcmp(argv[1], "check-test")) {
    TestBase testBase;
    qDebug() << "MAIN result (expected: false): " << testBase.checkTags(0x1020u, 0x2030u, 0x3040, 0x4051, 0x5061);
    qDebug() << "MAIN result (expected:  true): " << testBase.checkTags(0x1020u, 0x2030u, 0x3040, 0x4050, 0x5061);
    return 0;
  } else if (2 == argc && !strcmp(argv[1], "time")) {
    QDateTime dateTime(QDateTime(QDate(2015, 2, 15), QTime(10, 33, 50, 775), Qt::UTC));
    qDebug() << "ISO     Date: " << dateTime.toString(Qt::ISODate);
    qDebug() << "RFC2822 Date: " << dateTime.toString(Qt::RFC2822Date);
    qDebug() << "Custom  Date: " << dateTime.toString("yyyy-MM-ddTHH:mm:ss.zzzZ");
    return 0;
  }

  TestBase test;

#if 0 // Base64 encoding test
  const WB_UTINY TheData[] = {
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
  };
  WB_UTINY *const encoded = wbxml_base64_encode (TheData, sizeof (TheData));
  qDebug() << "Encoded: " << (const char *)encoded;

  wbxml_free (encoded);
#endif // Base64 encoding test

  WB_UTINY xmlBlock[] =
    "<?xml version=\"1.0\"?>"
    "<!DOCTYPE AirSync PUBLIC \"-//AIRSYNC//DTD AirSync//EN\" \"http://www.microsoft.com/\">"
    "<FolderSync xmlns=\"http://synce.org/formats/airsync_wm5/airsync\">"
    "<SyncKey>0</SyncKey>"
    "</FolderSync>";

  WBXMLGenWBXMLParams gparams;
  gparams.wbxml_version = WBXML_VERSION_13;
  gparams.keep_ignorable_ws = FALSE;
  gparams.use_strtbl = TRUE;
  gparams.produce_anonymous = TRUE;

  WB_UTINY *wbxml = NULL;
  WB_ULONG wbxml_len = 0;
  const WBXMLError result = wbxml_conv_xml2wbxml_withlen(
    xmlBlock, strlen ((const char *)xmlBlock),
    &wbxml, &wbxml_len,
    &gparams);
  qDebug() << "********************************************************************************************";
  qDebug() << "BWXml result: " << (const char *)wbxml_errors_string (result) << ", block: " << wbxml << ", Length: " << wbxml_len;
  qDebug() << "XML Data:" << (const char *)xmlBlock << ", Land ID: " << WBXML_LANG_AIRSYNC;
  Utils::hexDump(wbxml, wbxml_len);
  qDebug() << "********************************************************************************************";
  WBXMLTree *wbxml_tree = NULL;
  const WBXMLError treeRes = wbxml_tree_from_xml(xmlBlock, strlen ((const char *)xmlBlock), &wbxml_tree);
  qDebug() << "Converted to a tree, result: " << (const char *)wbxml_errors_string(treeRes) << ", " << wbxml_tree;
  qDebug() << "Charset: " << wbxml_tree->orig_charset << ", codePage: " << wbxml_tree->cur_code_page;
  WBXMLTreeNode *item = wbxml_tree->root;
  Utils::logNode(qDebug(), item);

  qDebug() << "********************************************************************************************";
  /* Example from [MS-ASWBXML].pdf */
  WB_UTINY testWbxml[] = {
    0x03, 0x01, 0x6A, 0x00, 0x45, 0x5C, 0x4F, 0x50,
    0x03, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x63, 0x74,
    0x73, 0x00, 0x01, 0x4B, 0x03, 0x32, 0x00, 0x01,
    0x52, 0x03, 0x32, 0x00, 0x01, 0x4E, 0x03, 0x31,
    0x00, 0x01, 0x56, 0x47, 0x4D, 0x03, 0x32, 0x3A,
    0x31, 0x00, 0x01, 0x5D, 0x00, 0x11, 0x4A, 0x46,
    0x03, 0x31, 0x00, 0x01, 0x4C, 0x03, 0x30, 0x00,
    0x01, 0x4D, 0x03, 0x31, 0x00, 0x01, 0x01, 0x00,
    0x01, 0x5E, 0x03, 0x46, 0x75, 0x6E, 0x6B, 0x2C,
    0x20, 0x44, 0x6F, 0x6E, 0x00, 0x01, 0x5F, 0x03,
    0x44, 0x6F, 0x6E, 0x00, 0x01, 0x69, 0x03, 0x46,
    0x75, 0x6E, 0x6B, 0x00, 0x01, 0x00, 0x11, 0x56,
    0x03, 0x31, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01
  };

  WBXMLGenXMLParams params;
  params.gen_type = WBXML_GEN_XML_INDENT;
  params.lang = WBXML_LANG_AIRSYNC;
  params.indent = 0;
  params.keep_ignorable_ws = TRUE;
  WB_ULONG xml_len = 2;
  WB_UTINY *pXml = NULL;
  const WBXMLError wbres = wbxml_conv_wbxml2xml_withlen(
    testWbxml, sizeof (testWbxml),
    &pXml, &xml_len,
    &params);
  qDebug() << "XML: result: " << (const char *)wbxml_errors_string(wbres) << ", XML length: " << xml_len;
  qDebug() << (const char *)pXml;

  qDebug() << "********************************************************************************************";
  WBXMLTree *resTree = NULL;
  const WBXMLError lastRes = wbxml_tree_from_wbxml(testWbxml, sizeof (testWbxml), WBXML_LANG_AIRSYNC, &resTree);
  qDebug() << "Tree from WBXML result: " << (const char *)wbxml_errors_string(lastRes);
  Utils::logNode(qDebug(), resTree->root);
  qDebug() << "********************************************************************************************";
  // Manually creating WBXML tree for SyncFolder ActiveSync command.
  // Tree node type: "WBXML_TREE_ELEMENT_NODE", name: "[WBXML_VALUE_TOKEN: ENTRY: "FolderSync", PAGE: 7, TOKEN: 22]"
  //    Tree node type: "WBXML_TREE_ELEMENT_NODE", name: "[WBXML_VALUE_TOKEN: ENTRY: "SyncKey", PAGE: 0, TOKEN: 11]"
  //      Tree node type: "WBXML_TREE_TEXT_NODE", content: "0"

  // Create the tree object
  WBXMLTree *createdTree = wbxml_tree_create(WBXML_LANG_AIRSYNC, WBXML_CHARSET_UTF_8);
  WBXMLTreeNode *folderSyncNode = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE);
  WBXMLTreeNode *syncKeyNode = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE);

  // Creare/prepare the value TREE-NODE:
  WBXMLTreeNode *const keyNode = wbxml_tree_node_create_text((const unsigned char *)("0"), 1);

  // Create the 'SyncKey' TREE-TAG
  WBXMLTagEntry tagEntry;
  tagEntry.xmlName = NULL;
  tagEntry.wbxmlCodePage = 7;
  tagEntry.wbxmlToken = 18;
  syncKeyNode->name = wbxml_tag_create_token(&tagEntry);
  // Create the 'FolderSync' tag
  WBXMLTagEntry tagEntry1;
  tagEntry1.xmlName = NULL;
  tagEntry1.wbxmlCodePage = 7;
  tagEntry1.wbxmlToken = 22;
  folderSyncNode->name = wbxml_tag_create_token(&tagEntry1);

  // Configure links
  createdTree->root = folderSyncNode;
  folderSyncNode->children = syncKeyNode;
  syncKeyNode->parent = folderSyncNode;
  syncKeyNode->children = keyNode;
  keyNode->parent = syncKeyNode;

  qDebug() << "Created tree:";
  Utils::logNode(qDebug(), createdTree->root);
  WB_UTINY *createdWbxml = NULL;
  WB_ULONG  createdWbxmlLen = 0;
  const WBXMLError createdWbxmlResult = wbxml_tree_to_wbxml(createdTree, &createdWbxml, &createdWbxmlLen, &gparams);
  qDebug() << "Result: " << (const char *)wbxml_errors_string(createdWbxmlResult) << ", length: " << createdWbxmlLen;
  Utils::hexDump(createdWbxml, createdWbxmlLen);

  qDebug() << "********************************************************************************************";

  return app.exec();
}
<commit_msg>Added QDateTime string parsing example.<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Alexander Chumakov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "testbase.h"

#include "utils.h"

#include <QMap>
#include <QDebug>
#include <wbxml.h>
#include <string.h>
#include <wbxml_conv.h>

#include <QDateTime>
#include <QCoreApplication>

/*!
    \page example.html
    \title Generic QDoc Guide
    There are three essential materials for generating documentation with qdoc:

    \list
        \li \c qdoc binary
        \li \c qdocconf configuration files
        \li \c Documentation in \c C++, \c QML, and \c .qdoc files
    \endlist
*/

QMap<int, QString> TheMap;

int main(int argc, char **argv)
{
  QCoreApplication app(argc, argv);

  if (2 == argc && !strcmp(argv[1], "reg")) {
    Utils::registerAccount();
    qDebug() << "MAIN: registration done.";
    return 0;
  } else if (2 == argc && !strcmp(argv[1], "iconv")) {
    Utils::iconvTest();
    return 0;
  } else if (2 == argc && !strcmp(argv[1], "check-test")) {
    TestBase testBase;
    qDebug() << "MAIN result (expected: false): " << testBase.checkTags(0x1020u, 0x2030u, 0x3040, 0x4051, 0x5061);
    qDebug() << "MAIN result (expected:  true): " << testBase.checkTags(0x1020u, 0x2030u, 0x3040, 0x4050, 0x5061);
    return 0;
  } else if (2 == argc && !strcmp(argv[1], "time")) {
    QDateTime dateTime(QDateTime(QDate(2015, 2, 15), QTime(10, 33, 50, 775), Qt::UTC));
    qDebug() << "ISO     Date: " << dateTime.toString(Qt::ISODate);
    qDebug() << "RFC2822 Date: " << dateTime.toString(Qt::RFC2822Date);
    qDebug() << "Custom  Date: " << dateTime.toString("yyyy-MM-ddTHH:mm:ss.zzzZ");
    const QDateTime &parsed = QDateTime::fromString("2016-06-21T21:20:31.235Z", Qt::ISODate);
    qDebug() << "Parsed: " << parsed;
    return 0;
  }

  TestBase test;

#if 0 // Base64 encoding test
  const WB_UTINY TheData[] = {
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
  };
  WB_UTINY *const encoded = wbxml_base64_encode (TheData, sizeof (TheData));
  qDebug() << "Encoded: " << (const char *)encoded;

  wbxml_free (encoded);
#endif // Base64 encoding test

  WB_UTINY xmlBlock[] =
    "<?xml version=\"1.0\"?>"
    "<!DOCTYPE AirSync PUBLIC \"-//AIRSYNC//DTD AirSync//EN\" \"http://www.microsoft.com/\">"
    "<FolderSync xmlns=\"http://synce.org/formats/airsync_wm5/airsync\">"
    "<SyncKey>0</SyncKey>"
    "</FolderSync>";

  WBXMLGenWBXMLParams gparams;
  gparams.wbxml_version = WBXML_VERSION_13;
  gparams.keep_ignorable_ws = FALSE;
  gparams.use_strtbl = TRUE;
  gparams.produce_anonymous = TRUE;

  WB_UTINY *wbxml = NULL;
  WB_ULONG wbxml_len = 0;
  const WBXMLError result = wbxml_conv_xml2wbxml_withlen(
    xmlBlock, strlen ((const char *)xmlBlock),
    &wbxml, &wbxml_len,
    &gparams);
  qDebug() << "********************************************************************************************";
  qDebug() << "BWXml result: " << (const char *)wbxml_errors_string (result) << ", block: " << wbxml << ", Length: " << wbxml_len;
  qDebug() << "XML Data:" << (const char *)xmlBlock << ", Land ID: " << WBXML_LANG_AIRSYNC;
  Utils::hexDump(wbxml, wbxml_len);
  qDebug() << "********************************************************************************************";
  WBXMLTree *wbxml_tree = NULL;
  const WBXMLError treeRes = wbxml_tree_from_xml(xmlBlock, strlen ((const char *)xmlBlock), &wbxml_tree);
  qDebug() << "Converted to a tree, result: " << (const char *)wbxml_errors_string(treeRes) << ", " << wbxml_tree;
  qDebug() << "Charset: " << wbxml_tree->orig_charset << ", codePage: " << wbxml_tree->cur_code_page;
  WBXMLTreeNode *item = wbxml_tree->root;
  Utils::logNode(qDebug(), item);

  qDebug() << "********************************************************************************************";
  /* Example from [MS-ASWBXML].pdf */
  WB_UTINY testWbxml[] = {
    0x03, 0x01, 0x6A, 0x00, 0x45, 0x5C, 0x4F, 0x50,
    0x03, 0x43, 0x6F, 0x6E, 0x74, 0x61, 0x63, 0x74,
    0x73, 0x00, 0x01, 0x4B, 0x03, 0x32, 0x00, 0x01,
    0x52, 0x03, 0x32, 0x00, 0x01, 0x4E, 0x03, 0x31,
    0x00, 0x01, 0x56, 0x47, 0x4D, 0x03, 0x32, 0x3A,
    0x31, 0x00, 0x01, 0x5D, 0x00, 0x11, 0x4A, 0x46,
    0x03, 0x31, 0x00, 0x01, 0x4C, 0x03, 0x30, 0x00,
    0x01, 0x4D, 0x03, 0x31, 0x00, 0x01, 0x01, 0x00,
    0x01, 0x5E, 0x03, 0x46, 0x75, 0x6E, 0x6B, 0x2C,
    0x20, 0x44, 0x6F, 0x6E, 0x00, 0x01, 0x5F, 0x03,
    0x44, 0x6F, 0x6E, 0x00, 0x01, 0x69, 0x03, 0x46,
    0x75, 0x6E, 0x6B, 0x00, 0x01, 0x00, 0x11, 0x56,
    0x03, 0x31, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01
  };

  WBXMLGenXMLParams params;
  params.gen_type = WBXML_GEN_XML_INDENT;
  params.lang = WBXML_LANG_AIRSYNC;
  params.indent = 0;
  params.keep_ignorable_ws = TRUE;
  WB_ULONG xml_len = 2;
  WB_UTINY *pXml = NULL;
  const WBXMLError wbres = wbxml_conv_wbxml2xml_withlen(
    testWbxml, sizeof (testWbxml),
    &pXml, &xml_len,
    &params);
  qDebug() << "XML: result: " << (const char *)wbxml_errors_string(wbres) << ", XML length: " << xml_len;
  qDebug() << (const char *)pXml;

  qDebug() << "********************************************************************************************";
  WBXMLTree *resTree = NULL;
  const WBXMLError lastRes = wbxml_tree_from_wbxml(testWbxml, sizeof (testWbxml), WBXML_LANG_AIRSYNC, &resTree);
  qDebug() << "Tree from WBXML result: " << (const char *)wbxml_errors_string(lastRes);
  Utils::logNode(qDebug(), resTree->root);
  qDebug() << "********************************************************************************************";
  // Manually creating WBXML tree for SyncFolder ActiveSync command.
  // Tree node type: "WBXML_TREE_ELEMENT_NODE", name: "[WBXML_VALUE_TOKEN: ENTRY: "FolderSync", PAGE: 7, TOKEN: 22]"
  //    Tree node type: "WBXML_TREE_ELEMENT_NODE", name: "[WBXML_VALUE_TOKEN: ENTRY: "SyncKey", PAGE: 0, TOKEN: 11]"
  //      Tree node type: "WBXML_TREE_TEXT_NODE", content: "0"

  // Create the tree object
  WBXMLTree *createdTree = wbxml_tree_create(WBXML_LANG_AIRSYNC, WBXML_CHARSET_UTF_8);
  WBXMLTreeNode *folderSyncNode = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE);
  WBXMLTreeNode *syncKeyNode = wbxml_tree_node_create(WBXML_TREE_ELEMENT_NODE);

  // Creare/prepare the value TREE-NODE:
  WBXMLTreeNode *const keyNode = wbxml_tree_node_create_text((const unsigned char *)("0"), 1);

  // Create the 'SyncKey' TREE-TAG
  WBXMLTagEntry tagEntry;
  tagEntry.xmlName = NULL;
  tagEntry.wbxmlCodePage = 7;
  tagEntry.wbxmlToken = 18;
  syncKeyNode->name = wbxml_tag_create_token(&tagEntry);
  // Create the 'FolderSync' tag
  WBXMLTagEntry tagEntry1;
  tagEntry1.xmlName = NULL;
  tagEntry1.wbxmlCodePage = 7;
  tagEntry1.wbxmlToken = 22;
  folderSyncNode->name = wbxml_tag_create_token(&tagEntry1);

  // Configure links
  createdTree->root = folderSyncNode;
  folderSyncNode->children = syncKeyNode;
  syncKeyNode->parent = folderSyncNode;
  syncKeyNode->children = keyNode;
  keyNode->parent = syncKeyNode;

  qDebug() << "Created tree:";
  Utils::logNode(qDebug(), createdTree->root);
  WB_UTINY *createdWbxml = NULL;
  WB_ULONG  createdWbxmlLen = 0;
  const WBXMLError createdWbxmlResult = wbxml_tree_to_wbxml(createdTree, &createdWbxml, &createdWbxmlLen, &gparams);
  qDebug() << "Result: " << (const char *)wbxml_errors_string(createdWbxmlResult) << ", length: " << createdWbxmlLen;
  Utils::hexDump(createdWbxml, createdWbxmlLen);

  qDebug() << "********************************************************************************************";

  return app.exec();
}
<|endoftext|>


<commit_before>#include <SFML/Window.hpp>
#include <cmath>
#include <iostream>

#include "renderer.h"
#include "input.h"
#include "octree.h"
#include "player.h"

using namespace std;

Octree<bool> makeTerrain(int level)
{
    vector<Octree<bool> >blocks;
    for(int i = 0; i < 8; i++)
    {
        bool leaf = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
        if(level < 5)
        {

            if(leaf)
            {
                bool type = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
                blocks.push_back(Octree<bool>(type));
            }
            else
            {
                blocks.push_back(makeTerrain(level + 1));
            }
        }
        else if(level == 5)
        {
            bool type = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
            blocks.push_back(Octree<bool>(type));
        }
    }
    Octree<bool> terrain(blocks);
    return terrain;
}

int main()
{
    // Create the main window
    sf::Window App(sf::VideoMode(800, 600, 32), "MineCube");

    Octree<bool> terrain = makeTerrain(0);

    // Create a renderer and input handler
    Renderer renderer(terrain);
    InputHandler input_handler(&App);

    //App.UseVerticalSync(true);

    // Create a clock for measuring time elapsed
    sf::Clock Clock;

    Player player(5.f, 0.f, 180.f, 5.f, 70.f, 30.f);

    App.ShowMouseCursor(false);

    // Start game loop
    while (App.IsOpened())
    {
        float ElapsedTime = Clock.GetElapsedTime();
        Clock.Reset();

        if ((App.GetInput().IsKeyDown(sf::Key::S)))    // W = forwards
            player.Forward(-ElapsedTime);

        if ((App.GetInput().IsKeyDown(sf::Key::W)))    // S = backwards
            player.Forward(ElapsedTime);

        if ((App.GetInput().IsKeyDown(sf::Key::D)))    //A = strafe left
            player.Strafe(-ElapsedTime);

        if ((App.GetInput().IsKeyDown(sf::Key::A)))    //D = strafe right
            player.Strafe(ElapsedTime);

        if ((App.GetInput().IsKeyDown(sf::Key::Z)))
            player.Speed++;

        if((App.GetInput().IsKeyDown(sf::Key::X)))
            player.Speed--;

        if (App.GetInput().IsKeyDown(sf::Key::Space)) renderer.terrain = makeTerrain(0);

        // Rotate view based on mouse movement
        float mouseDeltaX = App.GetInput().GetMouseX() - 100;
        float mouseDeltaY = App.GetInput().GetMouseY() - 100;
        App.SetCursorPosition(100, 100);
        if (!(mouseDeltaX == -100 && mouseDeltaY == -100))
            player.ChangeRotation((mouseDeltaY/10), (mouseDeltaX/10));

        input_handler.handleEvents();

        // Set the active window before using OpenGL commands
        // It's useless here because active window is always the same,
        // but don't forget it if you use multiple windows or controls
        App.SetActive();

        renderer.render(player.X, player.Y, player.Z, player.Yrot, player.Zrot);

        // Finally, display rendered frame on screen
        App.Display();
    }

    return EXIT_SUCCESS;
}

<commit_msg>Collapse main.cpp a little<commit_after>#include <SFML/Window.hpp>
#include <cmath>
#include <iostream>

#include "renderer.h"
#include "input.h"
#include "octree.h"
#include "player.h"

using namespace std;

Octree<bool> makeTerrain(int level)
{
    vector<Octree<bool> >blocks;
    for(int i = 0; i < 8; i++)
    {
        bool leaf = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
        if(level < 5)
        {

            if(leaf)
            {
                bool type = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
                blocks.push_back(Octree<bool>(type));
            }
            else
            {
                blocks.push_back(makeTerrain(level + 1));
            }
        }
        else if(level == 5)
        {
            bool type = (sf::Randomizer::Random(-1.f, 1.f) <= 0.0f ? true : false);
            blocks.push_back(Octree<bool>(type));
        }
    }
    Octree<bool> terrain(blocks);
    return terrain;
}

int main()
{
    // Create the main window
    sf::Window App(sf::VideoMode(800, 600, 32), "MineCube");

    Octree<bool> terrain = makeTerrain(0);

    // Create a renderer and input handler
    Renderer renderer(terrain);
    InputHandler input_handler(&App);

    //App.UseVerticalSync(true);

    // Create a clock for measuring time elapsed
    sf::Clock Clock;

    Player player(5.f, 0.f, 180.f, 5.f, 70.f, 30.f);

    App.ShowMouseCursor(false);

    // Start game loop
    while (App.IsOpened())
    {
        const sf::Input& Input = App->GetInput();

        float ElapsedTime = Clock.GetElapsedTime();
        Clock.Reset();

        if ((Input.IsKeyDown(sf::Key::S))) player.Forward(-ElapsedTime);
        if ((Input.IsKeyDown(sf::Key::W))) player.Forward( ElapsedTime);
        if ((Input.IsKeyDown(sf::Key::D))) player.Strafe(-ElapsedTime);
        if ((Input.IsKeyDown(sf::Key::A))) player.Strafe( ElapsedTime);
        if ((Input.IsKeyDown(sf::Key::Z))) player.Speed++;
        if ((Input.IsKeyDown(sf::Key::X))) player.Speed--;

        if (Input.IsKeyDown(sf::Key::Space)) renderer.terrain = makeTerrain(0);

        // Rotate view based on mouse movement
        float mouseDeltaX = Input.GetMouseX() - 100;
        float mouseDeltaY = Input.GetMouseY() - 100;
        App.SetCursorPosition(100, 100);

        if (!(mouseDeltaX == -100 && mouseDeltaY == -100) && !(mouseDeltaX == 0 && mouseDeltaY == 0))
            player.ChangeRotation((mouseDeltaY/10), (mouseDeltaX/10));

        input_handler.handleEvents();

        // Set the active window before using OpenGL commands
        // It's useless here because active window is always the same,
        // but don't forget it if you use multiple windows or controls
        App.SetActive();

        renderer.render(player.X, player.Y, player.Z, player.Yrot, player.Zrot);

        // Finally, display rendered frame on screen
        App.Display();
    }

    return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#include <nan.h>

using namespace v8;
using namespace node;

void freeNothing(char*, void*) { }

NAN_METHOD(testCall) {
	NanScope();
	NanReturnUndefined();
}

NAN_METHOD(testRetString) {
	NanScope();
	NanReturnValue(NanNew("1234567890"));
}

NAN_METHOD(testGet) {
	NanScope();

	Local<Object> obj = args[0]->ToObject();
	int a = obj->Get(NanNew("a"))->Int32Value(),
        b = obj->Get(NanNew("b"))->Int32Value(),
        c = obj->Get(NanNew("c"))->Int32Value();

	NanReturnValue(NanNew<Number>(a + b + c));
}

NAN_METHOD(testRetObj) {
	NanScope();

	Local<Object> obj = NanNew<Object>();
	obj->Set(NanNew("a"), NanNew("1234567890"));
	obj->Set(NanNew("b"), NanNew("234567890"));
	obj->Set(NanNew("c"), NanNew("34567890"));

	NanReturnValue(obj);
}

NAN_METHOD(testBuffer) {
	NanScope();
	NanReturnValue(NanNewBufferHandle(0));
}

NAN_METHOD(testBufferSmalloc) {
	NanScope();
	NanReturnValue(NanNewBufferHandle(0, 0, freeNothing, 0));
}

NAN_METHOD(testCallback) {
	NanScope();
	NanCallback(Local<Function>::Cast(args[0])).Call(0, 0);
	NanReturnUndefined();
}

class TestWrap : public ObjectWrap {
public:
	static Persistent<Function> ctor;

	void static setup(Handle<Object> exports) {
		Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(TestWrap::New);
		tpl->SetClassName(NanNew("TestWrap"));
		tpl->InstanceTemplate()->SetInternalFieldCount(1);

		NODE_SET_METHOD(tpl->PrototypeTemplate(), "unwrap", TestWrap::unwrap);
		NODE_SET_METHOD(tpl->PrototypeTemplate(), "foo", TestWrap::foo);

		exports->Set(NanNew("TestWrap"), tpl->GetFunction());
		NanAssignPersistent(TestWrap::ctor, tpl->GetFunction());
	}

	static NAN_METHOD(New) {
		NanScope();

		TestWrap* tw = new TestWrap();
		tw->Wrap(args.This());

		NanReturnValue(args.This());
	}

	static NAN_METHOD(unwrap) {
		NanScope();
		TestWrap* tw = ObjectWrap::Unwrap<TestWrap>(args.This());
		tw->_foo++;
		NanReturnUndefined();
	}

	static NAN_METHOD(foo) {
		NanScope();
		NanReturnUndefined();
	}

private:
	int _foo;
};

Persistent<Function> TestWrap::ctor;

NAN_METHOD(testWrapNew) {
	NanScope();
	NanReturnValue(NanNew(TestWrap::ctor)->NewInstance());
}

Persistent<Context> testContext;
Persistent<Script> testScript;
void initTestContext() {
	Handle<ObjectTemplate> global = NanNew<ObjectTemplate>();
	global->Set(NanNew("a"), NanNew("1234567890"));
	global->Set(NanNew("b"), NanNew("234567890"));
	global->Set(NanNew("c"), NanNew("34567890"));

	v8::Handle<v8::Context> context = NanNewContextHandle(NULL, global);
	Context::Scope context_scope(context);
	NanAssignPersistent(testContext, context);

	Handle<Script> script = Script::Compile(NanNew("({ a: a, b: b, c: c })"));
	NanAssignPersistent(testScript, script);
}

NAN_METHOD(testRun) {
	NanScope();
	//Context::Scope context_scope(NanNew(testContext));
	Local<Script> script = NanNew(testScript);
	NanReturnValue(script->Run());
}

void InitAll(Handle<Object> exports) {
	initTestContext();
	NODE_SET_METHOD(exports, "testRun", testRun);

	NODE_SET_METHOD(exports, "testCall", testCall);
	NODE_SET_METHOD(exports, "testRetString", testRetString);
	NODE_SET_METHOD(exports, "testGet", testGet);
	NODE_SET_METHOD(exports, "testRetObj", testRetObj);
	NODE_SET_METHOD(exports, "testCallback", testCallback);
	NODE_SET_METHOD(exports, "testBuffer", testBuffer);
	NODE_SET_METHOD(exports, "testBufferSmalloc", testBufferSmalloc);
	NODE_SET_METHOD(exports, "testWrapNew", testWrapNew);
	TestWrap::setup(exports);
}

NODE_MODULE(node_microbench, InitAll);
<commit_msg>use NODE_SET_PROTOTYPE_METHOD macro.<commit_after>#include <nan.h>

using namespace v8;
using namespace node;

void freeNothing(char*, void*) { }

NAN_METHOD(testCall) {
	NanScope();
	NanReturnUndefined();
}

NAN_METHOD(testRetString) {
	NanScope();
	NanReturnValue(NanNew("1234567890"));
}

NAN_METHOD(testGet) {
	NanScope();

	Local<Object> obj = args[0]->ToObject();
	int a = obj->Get(NanNew("a"))->Int32Value(),
        b = obj->Get(NanNew("b"))->Int32Value(),
        c = obj->Get(NanNew("c"))->Int32Value();

	NanReturnValue(NanNew<Number>(a + b + c));
}

NAN_METHOD(testRetObj) {
	NanScope();

	Local<Object> obj = NanNew<Object>();
	obj->Set(NanNew("a"), NanNew("1234567890"));
	obj->Set(NanNew("b"), NanNew("234567890"));
	obj->Set(NanNew("c"), NanNew("34567890"));

	NanReturnValue(obj);
}

NAN_METHOD(testBuffer) {
	NanScope();
	NanReturnValue(NanNewBufferHandle(0));
}

NAN_METHOD(testBufferSmalloc) {
	NanScope();
	NanReturnValue(NanNewBufferHandle(0, 0, freeNothing, 0));
}

NAN_METHOD(testCallback) {
	NanScope();
	NanCallback(Local<Function>::Cast(args[0])).Call(0, 0);
	NanReturnUndefined();
}

class TestWrap : public ObjectWrap {
public:
	static Persistent<Function> ctor;

	void static setup(Handle<Object> exports) {
		Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(TestWrap::New);
		tpl->SetClassName(NanNew("TestWrap"));
		tpl->InstanceTemplate()->SetInternalFieldCount(1);

		NODE_SET_PROTOTYPE_METHOD(tpl, "unwrap", TestWrap::unwrap);
		NODE_SET_PROTOTYPE_METHOD(tpl, "foo", TestWrap::foo);

		exports->Set(NanNew("TestWrap"), tpl->GetFunction());
		NanAssignPersistent(TestWrap::ctor, tpl->GetFunction());
	}

	static NAN_METHOD(New) {
		NanScope();

		TestWrap* tw = new TestWrap();
		tw->Wrap(args.This());

		NanReturnValue(args.This());
	}

	static NAN_METHOD(unwrap) {
		NanScope();
		TestWrap* tw = ObjectWrap::Unwrap<TestWrap>(args.This());
		tw->_foo++;
		NanReturnUndefined();
	}

	static NAN_METHOD(foo) {
		NanScope();
		NanReturnUndefined();
	}

private:
	int _foo;
};

Persistent<Function> TestWrap::ctor;

NAN_METHOD(testWrapNew) {
	NanScope();
	NanReturnValue(NanNew(TestWrap::ctor)->NewInstance());
}

Persistent<Context> testContext;
Persistent<Script> testScript;
void initTestContext() {
	Handle<ObjectTemplate> global = NanNew<ObjectTemplate>();
	global->Set(NanNew("a"), NanNew("1234567890"));
	global->Set(NanNew("b"), NanNew("234567890"));
	global->Set(NanNew("c"), NanNew("34567890"));

	v8::Handle<v8::Context> context = NanNewContextHandle(NULL, global);
	Context::Scope context_scope(context);
	NanAssignPersistent(testContext, context);

	Handle<Script> script = Script::Compile(NanNew("({ a: a, b: b, c: c })"));
	NanAssignPersistent(testScript, script);
}

NAN_METHOD(testRun) {
	NanScope();
	//Context::Scope context_scope(NanNew(testContext));
	Local<Script> script = NanNew(testScript);
	NanReturnValue(script->Run());
}

void InitAll(Handle<Object> exports) {
	initTestContext();
	NODE_SET_METHOD(exports, "testRun", testRun);

	NODE_SET_METHOD(exports, "testCall", testCall);
	NODE_SET_METHOD(exports, "testRetString", testRetString);
	NODE_SET_METHOD(exports, "testGet", testGet);
	NODE_SET_METHOD(exports, "testRetObj", testRetObj);
	NODE_SET_METHOD(exports, "testCallback", testCallback);
	NODE_SET_METHOD(exports, "testBuffer", testBuffer);
	NODE_SET_METHOD(exports, "testBufferSmalloc", testBufferSmalloc);
	NODE_SET_METHOD(exports, "testWrapNew", testWrapNew);
	TestWrap::setup(exports);
}

NODE_MODULE(node_microbench, InitAll);
<|endoftext|>


<commit_before>/**
 * Sheets
 * A tool to quickly organize, browse, and search for your datasheets.
 *
 * @author Nathan Campos <nathanpc@dreamintech.net>
 */

#include <iostream>
#include <vector> // REMOVE
#include <string> // REMOVE

#include "dir_parse.h"
#include "db.h"
#include "color.h"
using namespace std;

int main(int argc, char *argv[]) {
	// TODO: Parse command-line stuff.
	// TODO: Store the database inside the config dir at ~

	// Setup the directories stuff.
	Dir_Parse dir(argv[1]);
	dir.iterate();

	// Setup the database stuff.
	DB db("datasheets.db");
	db.query("DROP TABLE IF EXISTS datasheets;");
	db.query("CREATE TABLE datasheets(id integer primary key, path text, tags text);");

	// Index everything.
	for (size_t i = 0; i < dir.datasheets.size(); ++i) {
		vector<string> datasheet = dir.datasheets[i];

		string qry = "INSERT INTO datasheets VALUES(NULL, \"" + datasheet[0] + "\", \"" + datasheet[1] + "\");";
		db.query(qry.c_str());

		cout << BOLDGREEN << "Indexed: " << RESET << dir.trim_path(datasheet[0]) << endl;
	}

	cout << endl << BOLDBLUE << "Successfully indexed " << dir.datasheets.size() << " datasheets." << RESET << endl;

	return 0;
}
<commit_msg>Parsing the arguments<commit_after>/**
 * Sheets
 * A tool to quickly organize, browse, and search for your datasheets.
 *
 * @author Nathan Campos <nathanpc@dreamintech.net>
 */

#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <boost/filesystem.hpp>

#include "dir_parse.h"
#include "db.h"
#include "color.h"

using namespace std;
namespace fs = boost::filesystem;

void usage() {
	cout << BOLDWHITE << "Usage: " << RESET << "sheets [-i|-s] directory|term" << endl << endl;

	cout << BOLDWHITE << "Commands:" << RESET << endl;
	cout << "    -i(index)\t  Indexes a directory" << endl;
	cout << "    -s(search)\t  Search for a datasheet using a term" << endl;
}

void index(const char *directory) {
	// Setup the directories stuff.
	Dir_Parse dir(directory);
	dir.iterate();

	// Setup the database stuff.
	DB db("datasheets.db");
	db.query("DROP TABLE IF EXISTS datasheets;");
	db.query("CREATE TABLE datasheets(id integer primary key, path text, tags text);");

	// Index everything.
	for (size_t i = 0; i < dir.datasheets.size(); ++i) {
		vector<string> datasheet = dir.datasheets[i];

		string qry = "INSERT INTO datasheets VALUES(NULL, \"" + datasheet[0] + "\", \"" + datasheet[1] + "\");";
		db.query(qry.c_str());

		cout << BOLDGREEN << "Indexed: " << RESET << dir.trim_path(datasheet[0]) << endl;
	}

	cout << endl << BOLDBLUE << "Successfully indexed " << dir.datasheets.size() << " datasheets." << RESET << endl;
}

int main(int argc, char *argv[]) {
	// TODO: Store the database inside the config dir at ~

	// Check if there's at least one argument.
	if (argc == 1) {
		usage();
		return 1;
	}

	// Check if the user just typed the directory with no commands.
	if (argv[1][0] != '-' && strcmp(argv[1], "index") != 0 && strcmp(argv[1], "search") != 0) {
		if (fs::is_directory(argv[1])) {
			index(argv[1]);
		}
	}

	// The usual argument parsing stuff.
	if (strcmp(argv[1], "-i") == 0 || strcmp(argv[1], "index") == 0) {
		index(argv[1]);
	} else if (strcmp(argv[1], "-s") == 0 || strcmp(argv[1], "search") == 0) {
		cout << "Search for: " << argv[1] << endl;
	} else {
		usage();
		return 1;
	}

	return 0;
}
<|endoftext|>


<commit_before>#include <string>
#include <regex>
#include <fstream>
#include <utils.h>
#include "TwitchBot.h"

#include <tw/authenticator.h>
#include <tw/reader.h>

/* botData stores settings for initializing a TwitchBot instance */
struct botData {
	std::string name;
	std::string channel;
	std::string pass;
};

bool readSettings(botData *bd, std::string &error);

int main(int argc, char **argv)
{
	botData bd;
	std::string error;

	if (argc > 2) {
		std::cerr << "usage: " << argv[0] << " [CHANNEL]" << std::endl;
		return 1;
	}

	if (!readSettings(&bd, error)) {
		std::cerr << error << std::endl;
		std::cin.get();
		return 1;
	}

	std::string channel = bd.channel;
	if (argc == 2) {
		channel = argv[1];
		if (channel[0] != '#')
			channel = '#' + channel;
	}

	TwitchBot bot(bd.name, channel, bd.pass);

	if (bot.isConnected())
		bot.serverLoop();

	return 0;
}

bool readSettings(botData *bd, std::string &error)
{
	/* open settings */
	std::string path = utils::configdir() + utils::config("settings");
	std::ifstream reader(path);
	if (!reader.is_open()) {
		error = "could not locate " + path;
		return false;
	}

	std::string line;
	uint8_t lineNum = 0;

	while (std::getline(reader, line)) {
		++lineNum;
		/* remove whitespace */
		line.erase(std::remove_if(line.begin(), line.end(), isspace),
				line.end());

		/* lines starting with * are comments */
		if (utils::startsWith(line, "*"))
			continue;

		std::regex lineRegex("(name|channel|password):(.+?)");
		std::smatch match;
		const std::string s = line;
		if (std::regex_match(s.begin(), s.end(), match, lineRegex)) {
			if (match[1].str() == "name") {
				bd->name = match[2];
			} else if (match[1].str() == "channel") {
				if (!utils::startsWith(match[2].str(), "#"))
					error = "Channel must start with #";
				bd->channel = match[2];
			} else {
				if (!utils::startsWith(match[2].str(), "oauth:"))
					error = "Password must be a valid "
						 "oauth token, starting with "
						 "\"oauth:\".";
				bd->pass = match[2];
			}
		} else {
			error = "Syntax error on line "
				+ std::to_string(lineNum) + " of " + path;
		}
		if (!error.empty())
			return false;
	}

	reader.close();
	return true;
}
<commit_msg>Started work on Twitch authorization<commit_after>#include <cpr/cpr.h>
#include <fstream>
#include <regex>
#include <string>
#include <utils.h>
#include "TwitchBot.h"
#ifdef __linux__
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
#endif

/* LynxBot authorization URL */
static const char *AUTH_URL = "https://api.twitch.tv/kraken/oauth2/"
"authorize?response_type=token&client_id=kkjhmekkzbepq0pgn34g671y5nexap8&"
"redirect_uri=https://frolv.github.io/lynxbot/twitchauthconfirm.html&"
"scope=channel_editor+channel_subscriptions";

/* botData stores settings for initializing a TwitchBot instance */
struct botData {
	std::string name;
	std::string channel;
	std::string pass;
	std::string access_token;
};

void launchBot(botData *bd);
bool readSettings(botData *bd, std::string &error);
void twitchAuth(botData *bd);
bool authtest(const std::string &token, std::string &user);
void writeAuth(const std::string &token);
#ifdef __linux__
static int open_linux();
#endif
#ifdef _WIN32
static int open_win();
#endif

/* LynxBot: a Twitch.tv IRC bot for Oldschool Runescape */
int main(int argc, char **argv)
{
	botData bd;
	std::string error;

	if (argc > 2) {
		std::cerr << "usage: " << argv[0] << " [CHANNEL]" << std::endl;
		return 1;
	}

	if (!readSettings(&bd, error)) {
		std::cerr << error << std::endl;
		std::cin.get();
		return 1;
	}

	/* authenticate with twitch */
	if (bd.access_token.empty()) {
		twitchAuth(&bd);
		writeAuth(bd.access_token);
	}

	if (argc == 2) {
		bd.channel = argv[1];
		if (bd.channel[0] != '#')
			bd.channel = '#' + bd.channel;
	}

	launchBot(&bd);
	return 0;
}

/* launchBot: start a TwitchBot instance */
void launchBot(botData *bd)
{
	TwitchBot bot(bd->name, bd->channel, bd->pass);

	if (bot.isConnected())
		bot.serverLoop();
}

/* readSettings: read LynxBot settings file */
bool readSettings(botData *bd, std::string &error)
{
	/* open settings */
	std::string path = utils::configdir() + utils::config("settings");
	std::ifstream reader(path);
	if (!reader.is_open()) {
		error = "could not locate " + path;
		return false;
	}

	std::string line;
	uint8_t lineNum = 0;

	while (std::getline(reader, line)) {
		++lineNum;
		/* remove whitespace */
		line.erase(std::remove_if(line.begin(), line.end(), isspace),
				line.end());

		/* lines starting with * are comments */
		if (utils::startsWith(line, "*"))
			continue;

		std::regex lineRegex("(name|channel|password|twitchtok):(.+?)");
		std::smatch match;
		const std::string s = line;
		if (std::regex_match(s.begin(), s.end(), match, lineRegex)) {
			if (match[1].str() == "name") {
				bd->name = match[2].str();
			} else if (match[1].str() == "channel") {
				if (!utils::startsWith(match[2].str(), "#"))
					error = "Channel must start with #";
				bd->channel = match[2].str();
			} else if (match[1].str() == "password") {
				if (!utils::startsWith(match[2].str(), "oauth:"))
					error = "Password must be a valid "
						 "oauth token, starting with "
						 "\"oauth:\".";
				bd->pass = match[2].str();
			} else {
				bd->access_token = match[2].str();
			}
		} else {
			error = "Syntax error on line "
				+ std::to_string(lineNum) + " of " + path;
		}
		if (!error.empty())
			return false;
	}

	reader.close();
	return true;
}

/* twitchAuth: interactively authorize LynxBot with a Twitch account */
void twitchAuth(botData *bd)
{
	char c = '\0';
	std::cout << "In order for the $status command to work, LynxBot must be"
		" authorized to update your Twitch channel settings.\nWould you"
		" like to authorize LynxBot now? (y/n) ";
	while (c != 'y' && c != 'n')
		std::cin >> c;
	if (c == 'n') {
		bd->access_token = "NULL";
		return;
	}

	int status;
#ifdef __linux__
	status = open_linux();
#endif
#ifdef _WIN32
	status = open_win();
#endif
	if (status != 0) {
		std::cerr << "Could not open web browser" << std::endl;
		std::cin.get();
		exit(1);
	}

	std::cout << "The authorization URL has been opened in your "
		"browser. Sign in with your Twitch account and click "
		"\"Authorize\" to proceed." << std::endl;

	std::string token, user;
	std::cout << "After you have clicked \"Authorize\" you will be "
		"redirected to a webpage with an access token." << std::endl;
	std::cout << "Enter the access token here:" << std::endl;
	while (token.empty())
		std::getline(std::cin, token);

	if (authtest(token, user)) {
		bd->access_token = token;
		std::cout << "Welcome, " << user << "!\nLynxBot has "
			"successfully been authorized with "
			"your Twitch account." << std::endl;
	} else {
		std::cout << "Invalid token. Authorization failed."
			<< std::endl;
	}
	std::cin.get();
}

/* authtest: test access token validity */
bool authtest(const std::string &token, std::string &user)
{
	Json::Value json;
	cpr::Response resp = cpr::Get(cpr::Url("https://api.twitch.tv/kraken"),
			cpr::Header{{ "Authorization", "OAuth " + token }});

	Json::Reader reader;
	if (!reader.parse(resp.text, json))
		return false;

	if (json["token"]["valid"].asBool()) {
		user = json["token"]["user_name"].asString();
		return true;
	}
	return false;
}

/* writeAuth: write access token to settings file */
void writeAuth(const std::string &token)
{
	if (token.empty())
		return;

	std::string path = utils::configdir() + utils::config("settings");
	std::ofstream writer(path, std::ios::app);
	writer << "twitchtok: " << token << std::endl;
	writer.close();
}

#ifdef __linux__
/* open_linux: launch browser on linux systems */
static int open_linux()
{
	switch (fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		execl("/usr/bin/xdg-open", "xdg-open", AUTH_URL, (char *)NULL);
		perror("/usr/bin/xdg-open");
		exit(1);
	default:
		int status;
		wait(&status);
		return status >> 8;
	}
}
#endif
<|endoftext|>


<commit_before>#include "talk.h"

Talk::Talk()
{
}
<commit_msg>Delete talk.cpp<commit_after><|endoftext|>


<commit_before>#include <cstdio>
#include <string>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>
#include <future>
#include <cerrno>
#include <atomic>

// libfcgi-dev includes
#define NO_FCGI_DEFINES 1
//#include <fcgio.h>
#include <fcgi_config.h>
#include <fcgi_stdio.h>

// Our thread engine.
#include "ThreadEngine.h"

std::atomic_bool quit;

ThreadHandler *threads;

void OpenListener(int sock_fd)
{
	printf("Listener spawned for socket %d in thread %d\n", sock_fd, ThreadHandler::GetThreadID());
	FCGX_Request request;
	memset(&request, 0, sizeof(FCGX_Request));

	FCGX_InitRequest(&request, sock_fd, 0);

	// Idle infinitely and accept requests.
	while(FCGX_Accept_r(&request) == 0)
	{
		printf("Thread %d handling request\n", ThreadHandler::GetThreadID());
		const char *qstr = FCGX_GetParam("QUERY_STRING", request.envp);

		// 200 OK
		FCGX_SetExitStatus(200, request.out);

		// Form the HTML header enough, nginx will fill in the rest.
		FCGX_FPrintF(request.out, "Content-Type: text/html\r\n\r\n");

		// Send our message
		FCGX_FPrintF(request.out, "
%s thread %d
", qstr, ThreadHandler::GetThreadID());

		FCGX_Finish_r(&request);
	}

	printf("Exiting listener thread %d\n", ThreadHandler::GetThreadID());

	FCGX_Free(&request, sock_fd);
}

int main(int argc, char **argv)
{
	std::vector<std::string> args(argv, argv+argc);
	quit = false;
	ThreadHandler th;
	th.Initialize();
	threads = &th;

	FCGX_Init();
	int sock_fd = FCGX_OpenSocket(":3000", 1024);
	printf("Opened socket fd: %d\n", sock_fd);

	for (int i = 0; i < 10; ++i)
		th.AddQueue(OpenListener, sock_fd);

	printf("Submitting jobs...\n");
	th.Submit();

	printf("Idling main thread.\n");
	while(!quit)
		sleep(1);

	printf("Shutting down.\n");
	th.Shutdown();

	return EXIT_FAILURE;
}
<commit_msg>Added some informational tidbits. Nginx supports these in most default configs<commit_after>#include <cstdio>
#include <string>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>
#include <future>
#include <cerrno>
#include <atomic>

// libfcgi-dev includes
#define NO_FCGI_DEFINES 1
//#include <fcgio.h>
#include <fcgi_config.h>
#include <fcgi_stdio.h>

// Our thread engine.
#include "ThreadEngine.h"

std::atomic_bool quit;

ThreadHandler *threads;

void OpenListener(int sock_fd)
{
	printf("Listener spawned for socket %d in thread %d\n", sock_fd, ThreadHandler::GetThreadID());
	FCGX_Request request;
	memset(&request, 0, sizeof(FCGX_Request));

	FCGX_InitRequest(&request, sock_fd, 0);

	// Idle infinitely and accept requests.
	while(FCGX_Accept_r(&request) == 0)
	{
		printf("Thread %d handling request\n", ThreadHandler::GetThreadID());
		const char *qstr = FCGX_GetParam("QUERY_STRING", request.envp);

		// 200 OK
		FCGX_SetExitStatus(200, request.out);

		// Form the HTML header enough, nginx will fill in the rest.
		FCGX_FPrintF(request.out, "Content-Type: text/html\r\n\r\n");

		// Send our message
		FCGX_FPrintF(request.out, "
%s thread %d
", qstr, ThreadHandler::GetThreadID());

		FCGX_FPrintF(request.out, "
%s
", FCGX_GetParam("REMOTE_ADDR", request.envp));
		FCGX_FPrintF(request.out, "%s
", FCGX_GetParam("REQUEST_URI", request.envp));
		FCGX_FPrintF(request.out, "%s
", FCGX_GetParam("SERVER_PROTOCOL", request.envp));
		FCGX_FPrintF(request.out, "%s
", FCGX_GetParam("REQUEST_METHOD", request.envp));
		FCGX_FPrintF(request.out, "%s
", FCGX_GetParam("REMOTE_PORT", request.envp));
		FCGX_FPrintF(request.out, "%s
", FCGX_GetParam("SCRIPT_NAME", request.envp));
		FCGX_FPrintF(request.out, "
");

		FCGX_Finish_r(&request);
	}

	printf("Exiting listener thread %d\n", ThreadHandler::GetThreadID());

	FCGX_Free(&request, sock_fd);
}

int main(int argc, char **argv)
{
	std::vector<std::string> args(argv, argv+argc);
	quit = false;
	ThreadHandler th;
	th.Initialize();
	threads = &th;

	FCGX_Init();
	int sock_fd = FCGX_OpenSocket(":3000", 1024);
	printf("Opened socket fd: %d\n", sock_fd);

	for (int i = 0; i < 10; ++i)
		th.AddQueue(OpenListener, sock_fd);

	printf("Submitting jobs...\n");
	th.Submit();

	printf("Idling main thread.\n");
	while(!quit)
		sleep(1);

	printf("Shutting down.\n");
	th.Shutdown();

	return EXIT_FAILURE;
}
<|endoftext|>