[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/nodegit/nodegit/v0.0.778/src/reference.cc [Back]  [Original]

/*
 * Copyright 2011, Tim Branyen @tbranyen 
 * @author Michael Robinson @codeofinterest 
 *
 * Dual licensed under the MIT and GPL licenses.
 */

#include 
#include 
#include 

#include "../vendor/libgit2/include/git2.h"

#include "../include/repo.h"
#include "../include/reference.h"
#include "../include/oid.h"
#include "../include/error.h"

#include "../include/functions/string.h"

using namespace v8;
using namespace node;

void GitReference::Initialize(Handle target) {
  HandleScope scope;

  Local tpl = FunctionTemplate::New(New);

  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  tpl->SetClassName(String::NewSymbol("Reference"));

  NODE_SET_PROTOTYPE_METHOD(tpl, "oid", Oid);
  NODE_SET_PROTOTYPE_METHOD(tpl, "lookup", Lookup);

  constructor_template = Persistent::New(tpl->GetFunction());
  target->Set(String::NewSymbol("Reference"), constructor_template);
}

git_reference* GitReference::GetValue() {
  return this->ref;
}

void GitReference::SetValue(git_reference *ref) {
  this->ref = ref;
}

Handle GitReference::New(const Arguments& args) {
  HandleScope scope;

  GitReference *ref = new GitReference();

  ref->Wrap(args.This());

  return args.This();
}

Handle GitReference::Oid(const Arguments& args) {
  HandleScope scope;

  if(args.Length() == 0 || !args[0]->IsFunction()) {
    return ThrowException(Exception::Error(String::New("Callback is required and must be a Function.")));
  }

  OidBaton *baton = new OidBaton;
  baton->request.data = baton;
  baton->error = NULL;
  baton->rawOid = NULL;
  baton->rawRef = ObjectWrap::Unwrap(args.This())->GetValue();
  baton->callback = Persistent::New(Local::Cast(args[0]));

  uv_queue_work(uv_default_loop(), &baton->request, OidWork, (uv_after_work_cb)OidAfterWork);

  return Undefined();
}

void GitReference::OidWork(uv_work_t* req) {
  OidBaton *baton = static_cast(req->data);

  git_ref_t referenceType = git_reference_type(baton->rawRef);

  if (referenceType == GIT_REF_INVALID) {
    printf("invalid\n");
    giterr_set_str(GITERR_INVALID, "Invalid reference type");
    baton->error = giterr_last();
    return;
  }

  if (referenceType == GIT_REF_SYMBOLIC) {
    printf("symbolic\n");
    int returnCode = git_reference_resolve(&baton->rawRef, baton->rawRef);
    if (returnCode != GIT_OK) {
      baton->error = giterr_last();
      return;
    }
  }
  baton->rawOid = git_reference_target(baton->rawRef);
}
void GitReference::OidAfterWork(uv_work_t* req) {
  HandleScope scope;
  OidBaton *baton = static_cast(req->data);

  if (baton->error) {
    Local argv[1] = {
      GitError::WrapError(baton->error)
    };

    TryCatch try_catch;
    baton->callback->Call(Context::GetCurrent()->Global(), 1, argv);
    if (try_catch.HasCaught()) {
      node::FatalException(try_catch);
    }
  } else {

    Handle oid = GitOid::constructor_template->NewInstance();
    GitOid *oidInstance = ObjectWrap::Unwrap(oid);
    oidInstance->SetValue(*const_cast(baton->rawOid));

    Handle argv[2] = {
      Local::New(Null()),
      oid
    };

    TryCatch try_catch;
    baton->callback->Call(Context::GetCurrent()->Global(), 2, argv);
    if (try_catch.HasCaught()) {
      node::FatalException(try_catch);
    }
  }

  delete req;
}

Handle GitReference::Lookup(const Arguments& args) {
  HandleScope scope;

  if(args.Length() == 0 || !args[0]->IsObject()) {
    return ThrowException(Exception::Error(String::New("Repo is required and must be a Object.")));
  }

  if(args.Length() == 1 || !args[1]->IsString()) {
    return ThrowException(Exception::Error(String::New("Name is required and must be a String.")));
  }

  if(args.Length() == 2 || !args[2]->IsFunction()) {
    return ThrowException(Exception::Error(String::New("Callback is required and must be a Function.")));
  }

  LookupBaton *baton = new LookupBaton;
  baton->request.data = baton;
  baton->ref = ObjectWrap::Unwrap(args.This());
  baton->ref->Ref();
  baton->error = NULL;
  baton->rawRepo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue();
  baton->name = stringArgToString(args[1]->ToString());
  baton->callback = Persistent::New(Local::Cast(args[2]));

  uv_queue_work(uv_default_loop(), &baton->request, LookupWork, (uv_after_work_cb)LookupAfterWork);

  return Undefined();
}

void GitReference::LookupWork(uv_work_t *req) {
  LookupBaton *baton = static_cast(req->data);

  baton->rawRef = NULL;
  int returnCode = git_reference_lookup(&baton->rawRef, baton->rawRepo, baton->name.c_str());
  if (returnCode != GIT_OK) {
    baton->error = giterr_last();
  }
}

void GitReference::LookupAfterWork(uv_work_t *req) {
  HandleScope scope;
  LookupBaton *baton = static_cast(req->data);

  if (baton->error) {
    Local argv[1] = {
      GitError::WrapError(baton->error)
    };

    TryCatch try_catch;
    baton->callback->Call(Context::GetCurrent()->Global(), 1, argv);
    if (try_catch.HasCaught()) {
      node::FatalException(try_catch);
    }
  } else {

    baton->ref->SetValue(baton->rawRef);

    Handle argv[2] = {
      Local::New(Null()),
      baton->ref->handle_
    };

    TryCatch try_catch;
    baton->callback->Call(Context::GetCurrent()->Global(), 2, argv);
    if (try_catch.HasCaught()) {
      node::FatalException(try_catch);
    }
  }

  baton->ref->Unref();
  delete req;
}

Persistent GitReference::constructor_template;

Web Proxy Viewer  |  New URL  |  Original Page