text: // This is a generated file, modify: generate/templates/class_content.cc.
  #include <nan.h>
  #include <string.h>
  #include <chrono>
  #include <thread>
  
  extern "C" {
    #include <git2.h>
   }
  
  #include "../include/functions/copy.h"
  #include "../include/macros.h"
  #include "../include/treebuilder.h"
  
    #include "../include/treebuilder.h"
    #include "../include/tree_entry.h"
    #include "../include/oid.h"
    #include "../include/repository.h"
    #include "../include/tree.h"
   
  #include <iostream>
  
  using namespace std;
  using namespace v8;
  using namespace node;
  
    GitTreebuilder::GitTreebuilder(git_treebuilder *raw, bool selfFreeing) {
      this->raw = raw;
      this->selfFreeing = selfFreeing;
    }
  
    GitTreebuilder::~GitTreebuilder() {
        if (this->selfFreeing) {
          git_treebuilder_free(this->raw);
          this->raw = NULL;
        }
   
      // this will cause an error if you have a non-self-freeing object that also needs
      // to save values. Since the object that will eventually free the object has no
      // way of knowing to free these values.
                                    
    }
  
    void GitTreebuilder::InitializeComponent(Handle<v8::Object> target) {
      NanScope();
  
      Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(JSNewFunction);
  
      tpl->InstanceTemplate()->SetInternalFieldCount(1);
      tpl->SetClassName(NanNew<String>("Treebuilder"));
  
            NODE_SET_PROTOTYPE_METHOD(tpl, "clear", Clear);
              NODE_SET_PROTOTYPE_METHOD(tpl, "entrycount", Entrycount);
              NODE_SET_PROTOTYPE_METHOD(tpl, "free", Free);
              NODE_SET_PROTOTYPE_METHOD(tpl, "get", Get);
              NODE_SET_PROTOTYPE_METHOD(tpl, "insert", Insert);
               NODE_SET_METHOD(tpl, "create", Create);
              NODE_SET_PROTOTYPE_METHOD(tpl, "remove", Remove);
              NODE_SET_PROTOTYPE_METHOD(tpl, "write", Write);
      
      Local<Function> _constructor_template = tpl->GetFunction();
      NanAssignPersistent(constructor_template, _constructor_template);
      target->Set(NanNew<String>("Treebuilder"), _constructor_template);
    }
  
    NAN_METHOD(GitTreebuilder::JSNewFunction) {
      NanScope();
  
      if (args.Length() == 0 || !args[0]->IsExternal()) {
           return NanThrowError("A new GitTreebuilder cannot be instantiated.");
       }
  
      GitTreebuilder* object = new GitTreebuilder(static_cast<git_treebuilder *>(Handle<External>::Cast(args[0])->Value()), args[1]->BooleanValue());
      object->Wrap(args.This());
  
      NanReturnValue(args.This());
    }
  
    Handle<v8::Value> GitTreebuilder::New(void *raw, bool selfFreeing) {
      NanEscapableScope();
      Handle<v8::Value> argv[2] = { NanNew<External>((void *)raw), NanNew<Boolean>(selfFreeing) };
      return NanEscapeScope(NanNew<Function>(GitTreebuilder::constructor_template)->NewInstance(2, argv));
    }
  
    git_treebuilder *GitTreebuilder::GetValue() {
      return this->raw;
    }
  
    git_treebuilder **GitTreebuilder::GetRefValue() {
      return this->raw == NULL ? NULL : &this->raw;
    }
  
    void GitTreebuilder::ClearValue() {
      this->raw = NULL;
    }
  
    
  /*
       */
  NAN_METHOD(GitTreebuilder::Clear) {
    NanEscapableScope();
  
   git_treebuilder_clear(
  ObjectWrap::Unwrap<GitTreebuilder>(args.This())->GetValue()
    );
  
     NanReturnUndefined();
  }
     
  /*
       * @return Number  result    */
  NAN_METHOD(GitTreebuilder::Entrycount) {
    NanEscapableScope();
  
     unsigned int result = git_treebuilder_entrycount(
  ObjectWrap::Unwrap<GitTreebuilder>(args.This())->GetValue()
    );
  
   
    Handle<v8::Value> to;
  // start convert_to_v8 block
       to = NanNew<Number>( result);
    // end convert_to_v8 block
    NodeGitPsueodoNanReturnEscapingValue(to);
  }
     
  /*
       */
  NAN_METHOD(GitTreebuilder::Free) {
    NanEscapableScope();
  
  if (ObjectWrap::Unwrap<GitTreebuilder>(args.This())->GetValue() != NULL) {
   git_treebuilder_free(
  ObjectWrap::Unwrap<GitTreebuilder>(args.This())->GetValue()
    );
  
    ObjectWrap::Unwrap<GitTreebuilder>(args.This())->ClearValue();
  }
     NanReturnUndefined();
  }
     
  /*
     * @param String filename
       * @return TreeEntry  result    */
  NAN_METHOD(GitTreebuilder::Get) {
    NanEscapableScope();
  
    if (args.Length() == 0 || !args[0]->IsString()) {
      return NanThrowError("String filename is required.");
    }
  
  // start convert_from_v8 block
    const char * from_filename;
  
    String::Utf8Value filename(args[0]->ToString());
    from_filename = (const char *) strdup(*filename);
  // end convert_from_v8 block
     const git_tree_entry * result = git_treebuilder_get(
  ObjectWrap::Unwrap<GitTreebuilder>(args.This())->GetValue()
  ,from_filename
    );
  
     // null checks on pointers
    if (!result) {
      NodeGitPsueodoNanReturnEscapingValue(NanUndefined());
    }
  
    Handle<v8::Value> to;
  // start convert_to_v8 block
    
    if (result != NULL) {
      // GitTreeEntry result
         to = GitTreeEntry::New((void *)result, false);
     }
    else {
      to = NanNull();
    }
  
   // end convert_to_v8 block
    NodeGitPsueodoNanReturnEscapingValue(to);
  }
    
  /*
      * @param String filename
     * @param Oid id
     * @param Number filemode
      * @param TreeEntry callback
     */
  NAN_METHOD(GitTreebuilder::Insert) {
    NanScope();
  
    if (args.Length() == 0 || !args[0]->IsString()) {
      return NanThrowError("String filename is required.");
    }
  
    if (args.Length() == 1
      || (!args[1]->IsObject() && !args[1]->IsString())) {
      return NanThrowError("Oid id is required.");
    }
    if (args.Length() == 2 || !args[2]->IsNumber()) {
      return NanThrowError("Number filemode is required.");
    }
  
    if (args.Length() == 3 || !args[3]->IsFunction()) {
      return NanThrowError("Callback is required and must be a Function.");
    }
  
    InsertBaton* baton = new InsertBaton;
  
    baton->error_code = GIT_OK;
    baton->error = NULL;
  
    baton->bld = ObjectWrap::Unwrap<GitTreebuilder>(args.This())->GetValue();
  // start convert_from_v8 block
    const char * from_filename;
  
    String::Utf8Value filename(args[0]->ToString());
    from_filename = (const char *) strdup(*filename);
  // end convert_from_v8 block
    baton->filename = from_filename;
  // start convert_from_v8 block
    const git_oid * from_id;
    if (args[1]->IsString()) {
      // Try and parse in a string to a git_oid
      String::Utf8Value oidString(args[1]->ToString());
      git_oid *oidOut = (git_oid *)malloc(sizeof(git_oid));
  
      if (git_oid_fromstr(oidOut, (const char *) strdup(*oidString)) != GIT_OK) {
        free(oidOut);
  
        if (giterr_last()) {
          return NanThrowError(giterr_last()->message);
        } else {
          return NanThrowError("Unknown Error");
        }
      }
  
      from_id = oidOut;
    }
    else {
      from_id = ObjectWrap::Unwrap<GitOid>(args[1]->ToObject())->GetValue();
    }
  // end convert_from_v8 block
    baton->id = from_id;
    baton->idNeedsFree = args[1]->IsString();
  // start convert_from_v8 block
    git_filemode_t from_filemode;
    from_filemode = (git_filemode_t)  (int) args[2]->ToNumber()->Value();
  // end convert_from_v8 block
    baton->filemode = from_filemode;
  
    NanCallback *callback = new NanCallback(Local<Function>::Cast(args[3]));
    InsertWorker *worker = new InsertWorker(baton, callback);
    worker->SaveToPersistent("bld", args.This());
    if (!args[0]->IsUndefined() && !args[0]->IsNull())
      worker->SaveToPersistent("filename", args[0]->ToObject());
    if (!args[1]->IsUndefined() && !args[1]->IsNull())
      worker->SaveToPersistent("id", args[1]->ToObject());
    if (!args[2]->IsUndefined() && !args[2]->IsNull())
      worker->SaveToPersistent("filemode", args[2]->ToObject());
  
    NanAsyncQueueWorker(worker);
    NanReturnUndefined();
  }
  
  void GitTreebuilder::InsertWorker::Execute() {
    int result = git_treebuilder_insert(
  &baton->out,baton->bld,baton->filename,baton->id,baton->filemode    );
  
    baton->error_code = result;
  
    if (result != GIT_OK && giterr_last() != NULL) {
      baton->error = git_error_dup(giterr_last());
    }
  
  }
  
  void GitTreebuilder::InsertWorker::HandleOKCallback() {
    TryCatch try_catch;
  
    if (baton->error_code == GIT_OK) {
      Handle<v8::Value> to;
  // start convert_to_v8 block
    
    if (baton->out != NULL) {
      // GitTreeEntry baton->out
         to = GitTreeEntry::New((void *)baton->out, false);
     }
    else {
      to = NanNull();
    }
  
   // end convert_to_v8 block
      Handle<v8::Value> result = to;
      Handle<v8::Value> argv[2] = {
        NanNull(),
        result
      };
      callback->Call(2, argv);
    } else {
      if (baton->error) {
        Handle<v8::Value> argv[1] = {
          NanError(baton->error->message)
        };
        callback->Call(1, argv);
        if (baton->error->message)
          free((void *)baton->error->message);
        free((void *)baton->error);
      } else {
        callback->Call(0, NULL);
      }
  
    }
  
    if (try_catch.HasCaught()) {
      node::FatalException(try_catch);
    }
  
    free((void *)baton->filename);
    if (baton->idNeedsFree) {
      baton->idNeedsFree = false;
      free((void *)baton->id);
    }
  
    delete baton;
  }
  
    
  /*
    * @param Repository repo
     * @param Tree source
      * @param Treebuilder callback
     */
  NAN_METHOD(GitTreebuilder::Create) {
    NanScope();
  
    if (args.Length() == 0 || !args[0]->IsObject()) {
      return NanThrowError("Repository repo is required.");
    }
  
    if (args.Length() == 1 || !args[1]->IsObject()) {
      return NanThrowError("Tree source is required.");
    }
  
    if (args.Length() == 2 || !args[2]->IsFunction()) {
      return NanThrowError("Callback is required and must be a Function.");
    }
  
    CreateBaton* baton = new CreateBaton;
  
    baton->error_code = GIT_OK;
    baton->error = NULL;
  
  // start convert_from_v8 block
    git_repository * from_repo;
    from_repo = ObjectWrap::Unwrap<GitRepository>(args[0]->ToObject())->GetValue();
  // end convert_from_v8 block
    baton->repo = from_repo;
  // start convert_from_v8 block
    const git_tree * from_source;
    from_source = ObjectWrap::Unwrap<GitTree>(args[1]->ToObject())->GetValue();
  // end convert_from_v8 block
    baton->source = from_source;
  
    NanCallback *callback = new NanCallback(Local<Function>::Cast(args[2]));
    CreateWorker *worker = new CreateWorker(baton, callback);
    if (!args[0]->IsUndefined() && !args[0]->IsNull())
      worker->SaveToPersistent("repo", args[0]->ToObject());
    if (!args[1]->IsUndefined() && !args[1]->IsNull())
      worker->SaveToPersistent("source", args[1]->ToObject());
  
    NanAsyncQueueWorker(worker);
    NanReturnUndefined();
  }
  
  void GitTreebuilder::CreateWorker::Execute() {
    int result = git_treebuilder_new(
  &baton->out,baton->repo,baton->source    );
  
    baton->error_code = result;
  
    if (result != GIT_OK && giterr_last() != NULL) {
      baton->error = git_error_dup(giterr_last());
    }
  
  }
  
  void GitTreebuilder::CreateWorker::HandleOKCallback() {
    TryCatch try_catch;
  
    if (baton->error_code == GIT_OK) {
      Handle<v8::Value> to;
  // start convert_to_v8 block
    
    if (baton->out != NULL) {
      // GitTreebuilder baton->out
         to = GitTreebuilder::New((void *)baton->out, false);
     }
    else {
      to = NanNull();
    }
  
   // end convert_to_v8 block
      Handle<v8::Value> result = to;
      Handle<v8::Value> argv[2] = {
        NanNull(),
        result
      };
      callback->Call(2, argv);
    } else {
      if (baton->error) {
        Handle<v8::Value> argv[1] = {
          NanError(baton->error->message)
        };
        callback->Call(1, argv);
        if (baton->error->message)
          free((void *)baton->error->message);
        free((void *)baton->error);
      } else {
        callback->Call(0, NULL);
      }
  
    }
  
    if (try_catch.HasCaught()) {
      node::FatalException(try_catch);
    }
  
  
    delete baton;
  }
  
     
  /*
     * @param String filename
       * @return Number  result    */
  NAN_METHOD(GitTreebuilder::Remove) {
    NanEscapableScope();
  
    if (args.Length() == 0 || !args[0]->IsString()) {
      return NanThrowError("String filename is required.");
    }
  
  // start convert_from_v8 block
    const char * from_filename;
  
    String::Utf8Value filename(args[0]->ToString());
    from_filename = (const char *) strdup(*filename);
  // end convert_from_v8 block
     int result = git_treebuilder_remove(
  ObjectWrap::Unwrap<GitTreebuilder>(args.This())->GetValue()
  ,from_filename
    );
  
   
    Handle<v8::Value> to;
  // start convert_to_v8 block
       to = NanNew<Number>( result);
    // end convert_to_v8 block
    NodeGitPsueodoNanReturnEscapingValue(to);
  }
     
  /*
   * @param Oid id
         * @return Number  result    */
  NAN_METHOD(GitTreebuilder::Write) {
    NanEscapableScope();
  
    if (args.Length() == 0
      || (!args[0]->IsObject() && !args[0]->IsString())) {
      return NanThrowError("Oid id is required.");
    }
  // start convert_from_v8 block
    git_oid * from_id;
    if (args[0]->IsString()) {
      // Try and parse in a string to a git_oid
      String::Utf8Value oidString(args[0]->ToString());
      git_oid *oidOut = (git_oid *)malloc(sizeof(git_oid));
  
      if (git_oid_fromstr(oidOut, (const char *) strdup(*oidString)) != GIT_OK) {
        free(oidOut);
  
        if (giterr_last()) {
          return NanThrowError(giterr_last()->message);
        } else {
          return NanThrowError("Unknown Error");
        }
      }
  
      from_id = oidOut;
    }
    else {
      from_id = ObjectWrap::Unwrap<GitOid>(args[0]->ToObject())->GetValue();
    }
  // end convert_from_v8 block
     int result = git_treebuilder_write(
  from_id
  ,ObjectWrap::Unwrap<GitTreebuilder>(args.This())->GetValue()
    );
  
     if (args[0]->IsString()) {
      free((void *)from_id);
    }
  
    Handle<v8::Value> to;
  // start convert_to_v8 block
       to = NanNew<Number>( result);
    // end convert_to_v8 block
    NodeGitPsueodoNanReturnEscapingValue(to);
  }
        Persistent<Function> GitTreebuilder::constructor_template;
   