Example #1
0
/* zipfile.save(callback) */
Handle<Value> ZipFile::Save(const Arguments& args)
{
    ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This());

    if (zf->Busy())
      return ThrowException(Exception::Error(String::New("Zipfile already in use..")));

    Local<Value> cb = args[0];
    if (!cb->IsFunction())
      return ThrowException(Exception::Error(
            String::New("Second argument should be a callback function.")));

    save_closure_t *save = new save_closure_t;

    save->done = false;
    save->zf = zf;
    save->error = NULL;
    save->save_cb = Persistent<Function>::New(Handle<Function>::Cast(cb));
    pthread_mutex_init(&save->mutex, NULL);

    saving_closures.insert(save);

    zf->saving = true;
    zf->Ref();

    ev_ref(EV_DEFAULT_UC);
    pthread_create(&save->thread, NULL, Save_Thread, save);
    
    return Undefined();
}
Example #2
0
Handle<Value> ZipFile::readFile(const Arguments& args) {
    HandleScope scope;

    if (args.Length() < 2)
        return ThrowException(Exception::TypeError(
                                  String::New("requires two arguments, the name of a file and a callback")));

    // first arg must be name
    if (!args[0]->IsString())
        return ThrowException(Exception::TypeError(
                                  String::New("first argument must be a file name inside the zip")));

    // last arg must be function callback
    if (!args[args.Length()-1]->IsFunction())
        return ThrowException(Exception::TypeError(
                                  String::New("last argument must be a callback function")));

    std::string name = TOSTR(args[0]);

    ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This());

    closure_t *closure = new closure_t();
    closure->request.data = closure;

    // libzip is not threadsafe so we cannot use the zf->archive_
    // instead we open a new zip archive for each thread
    struct zip *za;
    int err;
    char errstr[1024];
    if ((za = zip_open(zf->file_name_.c_str() , 0, &err)) == NULL) {
        zip_error_to_str(errstr, sizeof(errstr), err, errno);
        std::stringstream s;
        s << "cannot open file: " << zf->file_name_ << " error: " << errstr << "\n";
        zip_close(za);
        return ThrowException(Exception::Error(
                                  String::New(s.str().c_str())));
    }

    closure->zf = zf;
    closure->za = za;
    closure->error = false;
    closure->name = name;
    closure->cb = Persistent<Function>::New(Handle<Function>::Cast(args[args.Length()-1]));
    uv_queue_work(uv_default_loop(), &closure->request, Work_ReadFile, Work_AfterReadFile);
    uv_ref(uv_default_loop());
    zf->Ref();
    return Undefined();
}
Example #3
0
/* zipfile.read(buffer, pos, len, cb) -> cb(bytesRead, error) */
Handle<Value> ZipFile::Read(const Arguments& args)
{
    ZipFile* zf = ObjectWrap::Unwrap<ZipFile>(args.This());

    if (!Buffer::HasInstance(args[0])) {
      return ThrowException(Exception::Error(
                  String::New("First argument needs to be a buffer")));
    }
    Local<Object> buffer_obj = args[0]->ToObject();
    char *buffer_data = Buffer::Data(buffer_obj);
    size_t buffer_length = Buffer::Length(buffer_obj);

    zip_uint64_t off = args[1]->Int32Value();
    if (off >= buffer_length) {
      return ThrowException(Exception::Error(
            String::New("Offset is out of bounds")));
    }

    zip_uint64_t len = args[2]->Int32Value();
    if (off + len > buffer_length) {
      return ThrowException(Exception::Error(
            String::New("Length is extends beyond buffer")));
    }

    Local<Value> cb = args[3];
    if (!cb->IsFunction())
      return ThrowException(Exception::Error(
            String::New("Fourth argument should be a callback function.")));

    read_closure_t *closure = new read_closure_t();
    closure->zf = zf;
    closure->read = 0;
    closure->data = buffer_data+off;
    closure->len = len;
    closure->cb = Persistent<Function>::New(Handle<Function>::Cast(args[3]));

    eio_custom(EIO_Read, EIO_PRI_DEFAULT, EIO_AfterRead, closure);
    zf->Ref();
    ev_ref(EV_DEFAULT_UC);

    return Undefined();
}