OverviewFilesCommitsIssuesDocsReleasesPeers

ollama_semantic_function_calling / ollamatools-new / keet / node_modules / fs-native-extensions / binding.c

791 lines · c ref:
#include <node_api.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>

#include "include/fs-ext.h"
#include "macros.h"

typedef struct {
  fs_ext_lock_t req;

  napi_env env;
  napi_ref ctx;
  napi_ref cb;
} fs_ext_napi_lock_t;

typedef struct {
  fs_ext_trim_t req;

  napi_env env;
  napi_ref ctx;
  napi_ref cb;
} fs_ext_napi_trim_t;

typedef struct {
  fs_ext_sparse_t req;

  napi_env env;
  napi_ref ctx;
  napi_ref cb;
} fs_ext_napi_sparse_t;

typedef struct {
  fs_ext_swap_t req;

  napi_env env;
  napi_ref ctx;
  napi_ref cb;
} fs_ext_napi_swap_t;

typedef struct {
  fs_ext_get_attr_t req;

  napi_env env;
  napi_ref ctx;
  napi_ref cb;
} fs_ext_napi_get_attr_t;

typedef struct {
  fs_ext_set_attr_t req;

  napi_env env;
  napi_ref ctx;
  napi_ref cb;
} fs_ext_napi_set_attr_t;

typedef struct {
  fs_ext_remove_attr_t req;

  napi_env env;
  napi_ref ctx;
  napi_ref cb;
} fs_ext_napi_remove_attr_t;

typedef struct {
  fs_ext_list_attrs_t req;

  napi_env env;
  napi_ref ctx;
  napi_ref cb;
} fs_ext_napi_list_attrs_t;

static void
on_fs_ext_lock(fs_ext_lock_t *req, int status) {
  fs_ext_napi_lock_t *r = (fs_ext_napi_lock_t *) req;

  napi_env env = r->env;

  napi_handle_scope scope;
  napi_open_handle_scope(env, &scope);

  napi_value argv[1];

  napi_value ctx;
  napi_get_reference_value(env, r->ctx, &ctx);

  napi_value callback;
  napi_get_reference_value(env, r->cb, &callback);

  if (req->result < 0) {
    napi_value code;
    napi_create_string_utf8(env, uv_err_name(req->result), -1, &code);

    napi_value message;
    napi_create_string_utf8(env, uv_strerror(req->result), -1, &message);

    napi_create_error(env, code, message, &argv[0]);
  } else {
    napi_get_null(env, &argv[0]);
  }

  NAPI_MAKE_CALLBACK(env, NULL, ctx, callback, 1, argv, NULL);

  napi_close_handle_scope(env, scope);

  napi_delete_reference(env, r->cb);
  napi_delete_reference(env, r->ctx);
}

static void
on_fs_ext_trim(fs_ext_trim_t *req, int status) {
  fs_ext_napi_trim_t *r = (fs_ext_napi_trim_t *) req;

  napi_env env = r->env;

  napi_handle_scope scope;
  napi_open_handle_scope(env, &scope);

  napi_value argv[1];

  napi_value ctx;
  napi_get_reference_value(env, r->ctx, &ctx);

  napi_value callback;
  napi_get_reference_value(env, r->cb, &callback);

  if (req->result < 0) {
    napi_value code;
    napi_create_string_utf8(env, uv_err_name(req->result), -1, &code);

    napi_value message;
    napi_create_string_utf8(env, uv_strerror(req->result), -1, &message);

    napi_create_error(env, code, message, &argv[0]);
  } else {
    napi_get_null(env, &argv[0]);
  }

  NAPI_MAKE_CALLBACK(env, NULL, ctx, callback, 1, argv, NULL);

  napi_close_handle_scope(env, scope);

  napi_delete_reference(env, r->cb);
  napi_delete_reference(env, r->ctx);
}

static void
on_fs_ext_sparse(fs_ext_sparse_t *req, int status) {
  fs_ext_napi_sparse_t *r = (fs_ext_napi_sparse_t *) req;

  napi_env env = r->env;

  napi_handle_scope scope;
  napi_open_handle_scope(env, &scope);

  napi_value argv[1];

  napi_value ctx;
  napi_get_reference_value(env, r->ctx, &ctx);

  napi_value callback;
  napi_get_reference_value(env, r->cb, &callback);

  if (req->result < 0) {
    napi_value code;
    napi_create_string_utf8(env, uv_err_name(req->result), -1, &code);

    napi_value message;
    napi_create_string_utf8(env, uv_strerror(req->result), -1, &message);

    napi_create_error(env, code, message, &argv[0]);
  } else {
    napi_get_null(env, &argv[0]);
  }

  NAPI_MAKE_CALLBACK(env, NULL, ctx, callback, 1, argv, NULL);

  napi_close_handle_scope(env, scope);

  napi_delete_reference(env, r->cb);
  napi_delete_reference(env, r->ctx);
}

static void
on_fs_ext_swap(fs_ext_swap_t *req, int status) {
  fs_ext_napi_swap_t *r = (fs_ext_napi_swap_t *) req;

  napi_env env = r->env;

  napi_handle_scope scope;
  napi_open_handle_scope(env, &scope);

  napi_value argv[1];

  napi_value ctx;
  napi_get_reference_value(env, r->ctx, &ctx);

  napi_value callback;
  napi_get_reference_value(env, r->cb, &callback);

  if (req->result < 0) {
    napi_value code;
    napi_create_string_utf8(env, uv_err_name(req->result), -1, &code);

    napi_value message;
    napi_create_string_utf8(env, uv_strerror(req->result), -1, &message);

    napi_create_error(env, code, message, &argv[0]);
  } else {
    napi_get_null(env, &argv[0]);
  }

  NAPI_MAKE_CALLBACK(env, NULL, ctx, callback, 1, argv, NULL);

  napi_close_handle_scope(env, scope);

  free((char *) req->from);
  free((char *) req->to);

  napi_delete_reference(env, r->cb);
  napi_delete_reference(env, r->ctx);
}

static void
on_fs_ext_get_attr(fs_ext_get_attr_t *req, int status, const uv_buf_t *value) {
  fs_ext_napi_get_attr_t *r = (fs_ext_napi_get_attr_t *) req;

  napi_env env = r->env;

  napi_handle_scope scope;
  napi_open_handle_scope(env, &scope);

  napi_value argv[2];

  napi_value ctx;
  napi_get_reference_value(env, r->ctx, &ctx);

  napi_value callback;
  napi_get_reference_value(env, r->cb, &callback);

  if (req->result < 0 && req->result != UV_ENODATA) {
    napi_value code;
    napi_create_string_utf8(env, uv_err_name(req->result), -1, &code);

    napi_value message;
    napi_create_string_utf8(env, uv_strerror(req->result), -1, &message);

    napi_create_error(env, code, message, &argv[0]);

    napi_get_null(env, &argv[1]);
  } else {
    napi_get_null(env, &argv[0]);

    if (req->result == UV_ENODATA) {
      napi_get_null(env, &argv[1]);
    } else {
      void *data;
      napi_create_arraybuffer(env, value->len, &data, &argv[1]);

      memcpy(data, value->base, value->len);
    }
  }

  NAPI_MAKE_CALLBACK(env, NULL, ctx, callback, 2, argv, NULL);

  napi_close_handle_scope(env, scope);

  free((char *) req->name);

  napi_delete_reference(env, r->cb);
  napi_delete_reference(env, r->ctx);
}

static void
on_fs_ext_set_attr(fs_ext_set_attr_t *req, int status) {
  fs_ext_napi_set_attr_t *r = (fs_ext_napi_set_attr_t *) req;

  napi_env env = r->env;

  napi_handle_scope scope;
  napi_open_handle_scope(env, &scope);

  napi_value argv[1];

  napi_value ctx;
  napi_get_reference_value(env, r->ctx, &ctx);

  napi_value callback;
  napi_get_reference_value(env, r->cb, &callback);

  if (req->result < 0) {
    napi_value code;
    napi_create_string_utf8(env, uv_err_name(req->result), -1, &code);

    napi_value message;
    napi_create_string_utf8(env, uv_strerror(req->result), -1, &message);

    napi_create_error(env, code, message, &argv[0]);
  } else {
    napi_get_null(env, &argv[0]);
  }

  NAPI_MAKE_CALLBACK(env, NULL, ctx, callback, 1, argv, NULL);

  napi_close_handle_scope(env, scope);

  free((char *) req->name);

  napi_delete_reference(env, r->cb);
  napi_delete_reference(env, r->ctx);
}

static void
on_fs_ext_remove_attr(fs_ext_remove_attr_t *req, int status) {
  fs_ext_napi_remove_attr_t *r = (fs_ext_napi_remove_attr_t *) req;

  napi_env env = r->env;

  napi_handle_scope scope;
  napi_open_handle_scope(env, &scope);

  napi_value argv[1];

  napi_value ctx;
  napi_get_reference_value(env, r->ctx, &ctx);

  napi_value callback;
  napi_get_reference_value(env, r->cb, &callback);

  if (req->result < 0 && req->result != UV_ENODATA) {
    napi_value code;
    napi_create_string_utf8(env, uv_err_name(req->result), -1, &code);

    napi_value message;
    napi_create_string_utf8(env, uv_strerror(req->result), -1, &message);

    napi_create_error(env, code, message, &argv[0]);
  } else {
    napi_get_null(env, &argv[0]);
  }

  NAPI_MAKE_CALLBACK(env, NULL, ctx, callback, 1, argv, NULL);

  napi_close_handle_scope(env, scope);

  free((char *) req->name);

  napi_delete_reference(env, r->cb);
  napi_delete_reference(env, r->ctx);
}

static void
on_fs_ext_list_attrs(fs_ext_list_attrs_t *req, int status, const char *attrs[], ssize_t len) {
  fs_ext_napi_list_attrs_t *r = (fs_ext_napi_list_attrs_t *) req;

  napi_env env = r->env;

  napi_handle_scope scope;
  napi_open_handle_scope(env, &scope);

  napi_value argv[2];

  napi_value ctx;
  napi_get_reference_value(env, r->ctx, &ctx);

  napi_value callback;
  napi_get_reference_value(env, r->cb, &callback);

  if (req->result < 0) {
    napi_value code;
    napi_create_string_utf8(env, uv_err_name(req->result), -1, &code);

    napi_value message;
    napi_create_string_utf8(env, uv_strerror(req->result), -1, &message);

    napi_create_error(env, code, message, &argv[0]);

    napi_get_null(env, &argv[1]);
  } else {
    napi_get_null(env, &argv[0]);

    napi_create_array_with_length(env, len, &argv[1]);

    for (size_t i = 0; i < len; i++) {
      napi_value value;
      napi_create_string_utf8(env, attrs[i], -1, &value);

      napi_set_element(env, argv[1], i, value);
    }
  }

  NAPI_MAKE_CALLBACK(env, NULL, ctx, callback, 2, argv, NULL);

  napi_close_handle_scope(env, scope);

  napi_delete_reference(env, r->cb);
  napi_delete_reference(env, r->ctx);
}

NAPI_METHOD(fs_ext_napi_try_lock) {
  NAPI_ARGV(4)
  NAPI_ARGV_UINT32(fd, 0)
  NAPI_ARGV_UINT32(offset, 1)
  NAPI_ARGV_UINT32(len, 2)
  NAPI_ARGV_UINT32(exclusive, 3)

  int err = fs_ext_try_lock(
    uv_get_osfhandle(fd),
    offset,
    len,
    exclusive ? FS_EXT_WRLOCK : FS_EXT_RDLOCK
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_wait_for_lock) {
  NAPI_ARGV(7)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_lock_t *, req, 0)
  NAPI_ARGV_UINT32(fd, 1)
  NAPI_ARGV_UINT32(offset, 2)
  NAPI_ARGV_UINT32(length, 3)
  NAPI_ARGV_UINT32(exclusive, 4)

  req->env = env;

  napi_create_reference(env, argv[5], 1, &(req->ctx));
  napi_create_reference(env, argv[6], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  int err = fs_ext_wait_for_lock(
    loop,
    (fs_ext_lock_t *) req,
    uv_get_osfhandle(fd),
    offset,
    length,
    exclusive ? FS_EXT_WRLOCK : FS_EXT_RDLOCK,
    on_fs_ext_lock
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_try_downgrade_lock) {
  NAPI_ARGV(3)
  NAPI_ARGV_UINT32(fd, 0)
  NAPI_ARGV_UINT32(offset, 1)
  NAPI_ARGV_UINT32(len, 2)

  int err = fs_ext_try_downgrade_lock(uv_get_osfhandle(fd), offset, len);

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_wait_for_downgrade_lock) {
  NAPI_ARGV(6)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_lock_t *, req, 0)
  NAPI_ARGV_UINT32(fd, 1)
  NAPI_ARGV_UINT32(offset, 2)
  NAPI_ARGV_UINT32(length, 3)

  req->env = env;

  napi_create_reference(env, argv[4], 1, &(req->ctx));
  napi_create_reference(env, argv[5], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  int err = fs_ext_wait_for_downgrade_lock(
    loop,
    (fs_ext_lock_t *) req,
    uv_get_osfhandle(fd),
    offset,
    length,
    on_fs_ext_lock
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_try_upgrade_lock) {
  NAPI_ARGV(3)
  NAPI_ARGV_UINT32(fd, 0)
  NAPI_ARGV_UINT32(offset, 1)
  NAPI_ARGV_UINT32(len, 2)

  int err = fs_ext_try_upgrade_lock(uv_get_osfhandle(fd), offset, len);

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_wait_for_upgrade_lock) {
  NAPI_ARGV(6)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_lock_t *, req, 0)
  NAPI_ARGV_UINT32(fd, 1)
  NAPI_ARGV_UINT32(offset, 2)
  NAPI_ARGV_UINT32(length, 3)

  req->env = env;

  napi_create_reference(env, argv[4], 1, &(req->ctx));
  napi_create_reference(env, argv[5], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  int err = fs_ext_wait_for_upgrade_lock(
    loop,
    (fs_ext_lock_t *) req,
    uv_get_osfhandle(fd),
    offset,
    length,
    on_fs_ext_lock
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_unlock) {
  NAPI_ARGV(3)
  NAPI_ARGV_UINT32(fd, 0)
  NAPI_ARGV_UINT32(offset, 1)
  NAPI_ARGV_UINT32(len, 2)

  int err = fs_ext_unlock(uv_get_osfhandle(fd), offset, len);

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_trim) {
  NAPI_ARGV(6)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_trim_t *, req, 0)
  NAPI_ARGV_UINT32(fd, 1)
  NAPI_ARGV_UINT32(offset, 2)
  NAPI_ARGV_UINT32(length, 3)

  req->env = env;

  napi_create_reference(env, argv[4], 1, &(req->ctx));
  napi_create_reference(env, argv[5], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  int err = fs_ext_trim(
    loop,
    (fs_ext_trim_t *) req,
    uv_get_osfhandle(fd),
    offset,
    length,
    on_fs_ext_trim
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_sparse) {
  NAPI_ARGV(4)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_sparse_t *, req, 0)
  NAPI_ARGV_UINT32(fd, 1)

  req->env = env;

  napi_create_reference(env, argv[2], 1, &(req->ctx));
  napi_create_reference(env, argv[3], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  int err = fs_ext_sparse(
    loop,
    (fs_ext_sparse_t *) req,
    uv_get_osfhandle(fd),
    on_fs_ext_sparse
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_swap) {
  NAPI_ARGV(5)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_swap_t *, req, 0)
  NAPI_ARGV_UTF8_MALLOC(from_path, 1)
  NAPI_ARGV_UTF8_MALLOC(to_path, 2)

  req->env = env;

  napi_create_reference(env, argv[3], 1, &(req->ctx));
  napi_create_reference(env, argv[4], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  int err = fs_ext_swap(
    loop,
    (fs_ext_swap_t *) req,
    from_path,
    to_path,
    on_fs_ext_swap
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_get_attr) {
  NAPI_ARGV(5)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_get_attr_t *, req, 0)
  NAPI_ARGV_UINT32(fd, 1)
  NAPI_ARGV_UTF8_MALLOC(name, 2)

  req->env = env;

  napi_create_reference(env, argv[3], 1, &(req->ctx));
  napi_create_reference(env, argv[4], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  int err = fs_ext_get_attr(
    loop,
    (fs_ext_get_attr_t *) req,
    uv_get_osfhandle(fd),
    name,
    on_fs_ext_get_attr
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_set_attr) {
  NAPI_ARGV(6)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_set_attr_t *, req, 0)
  NAPI_ARGV_UINT32(fd, 1)
  NAPI_ARGV_UTF8_MALLOC(name, 2)
  NAPI_ARGV_BUFFER(value, 3)

  req->env = env;

  napi_create_reference(env, argv[4], 1, &(req->ctx));
  napi_create_reference(env, argv[5], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  uv_buf_t buf = uv_buf_init(value, value_len);

  int err = fs_ext_set_attr(
    loop,
    (fs_ext_set_attr_t *) req,
    uv_get_osfhandle(fd),
    name,
    &buf,
    on_fs_ext_set_attr
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_remove_attr) {
  NAPI_ARGV(5)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_remove_attr_t *, req, 0)
  NAPI_ARGV_UINT32(fd, 1)
  NAPI_ARGV_UTF8_MALLOC(name, 2)

  req->env = env;

  napi_create_reference(env, argv[3], 1, &(req->ctx));
  napi_create_reference(env, argv[4], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  int err = fs_ext_remove_attr(
    loop,
    (fs_ext_remove_attr_t *) req,
    uv_get_osfhandle(fd),
    name,
    on_fs_ext_remove_attr
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_METHOD(fs_ext_napi_list_attrs) {
  NAPI_ARGV(4)
  NAPI_ARGV_BUFFER_CAST(fs_ext_napi_list_attrs_t *, req, 0)
  NAPI_ARGV_UINT32(fd, 1)

  req->env = env;

  napi_create_reference(env, argv[2], 1, &(req->ctx));
  napi_create_reference(env, argv[3], 1, &(req->cb));

  uv_loop_t *loop;
  napi_get_uv_event_loop(env, &loop);

  int err = fs_ext_list_attrs(
    loop,
    (fs_ext_list_attrs_t *) req,
    uv_get_osfhandle(fd),
    on_fs_ext_list_attrs
  );

  if (err < 0) {
    napi_throw_error(env, uv_err_name(err), uv_strerror(err));
  }

  return NULL;
}

NAPI_INIT() {
  NAPI_EXPORT_SIZEOF(fs_ext_napi_lock_t)
  NAPI_EXPORT_SIZEOF(fs_ext_napi_trim_t)
  NAPI_EXPORT_SIZEOF(fs_ext_napi_sparse_t)
  NAPI_EXPORT_SIZEOF(fs_ext_napi_swap_t)
  NAPI_EXPORT_SIZEOF(fs_ext_napi_get_attr_t)
  NAPI_EXPORT_SIZEOF(fs_ext_napi_set_attr_t)
  NAPI_EXPORT_SIZEOF(fs_ext_napi_remove_attr_t)
  NAPI_EXPORT_SIZEOF(fs_ext_napi_list_attrs_t)

  NAPI_EXPORT_FUNCTION(fs_ext_napi_try_lock)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_wait_for_lock)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_try_downgrade_lock)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_wait_for_downgrade_lock)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_try_upgrade_lock)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_wait_for_upgrade_lock)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_unlock)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_trim)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_sparse)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_swap)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_get_attr)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_set_attr)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_remove_attr)
  NAPI_EXPORT_FUNCTION(fs_ext_napi_list_attrs)
}