SEXP nanoarrow_c_pointer_move()

in r/src/pointers.c [125:192]


SEXP nanoarrow_c_pointer_move(SEXP ptr_src, SEXP ptr_dst) {
  SEXP xptr_src = PROTECT(nanoarrow_c_pointer(ptr_src));

  if (Rf_inherits(ptr_dst, "nanoarrow_schema")) {
    struct ArrowSchema* obj_dst = (struct ArrowSchema*)R_ExternalPtrAddr(ptr_dst);
    if (obj_dst == NULL) {
      Rf_error("`ptr_dst` is a pointer to NULL");
    }

    if (obj_dst->release != NULL) {
      Rf_error("`ptr_dst` is a valid struct ArrowSchema");
    }

    struct ArrowSchema* obj_src = (struct ArrowSchema*)R_ExternalPtrAddr(xptr_src);
    if (obj_src == NULL || obj_src->release == NULL) {
      Rf_error("`ptr_src` is not a valid struct ArrowSchema");
    }

    ArrowSchemaMove(obj_src, obj_dst);
  } else if (Rf_inherits(ptr_dst, "nanoarrow_array")) {
    struct ArrowArray* obj_dst = (struct ArrowArray*)R_ExternalPtrAddr(ptr_dst);
    if (obj_dst == NULL) {
      Rf_error("`ptr_dst` is a pointer to NULL");
    }

    if (obj_dst->release != NULL) {
      Rf_error("`ptr_dst` is a valid struct ArrowArray");
    }

    struct ArrowArray* obj_src = (struct ArrowArray*)R_ExternalPtrAddr(xptr_src);
    if (obj_src == NULL || obj_src->release == NULL) {
      Rf_error("`ptr_src` is not a valid struct ArrowArray");
    }

    ArrowArrayMove(obj_src, obj_dst);
  } else if (Rf_inherits(ptr_dst, "nanoarrow_array_stream")) {
    struct ArrowArrayStream* obj_dst =
        (struct ArrowArrayStream*)R_ExternalPtrAddr(ptr_dst);
    if (obj_dst == NULL) {
      Rf_error("`ptr_dst` is a pointer to NULL");
    }

    if (obj_dst->release != NULL) {
      Rf_error("`ptr_dst` is a valid struct ArrowArrayStream");
    }

    struct ArrowArrayStream* obj_src =
        (struct ArrowArrayStream*)R_ExternalPtrAddr(xptr_src);
    if (obj_src == NULL || obj_src->release == NULL) {
      Rf_error("`ptr_src` is not a valid struct ArrowArrayStream");
    }

    ArrowArrayStreamMove(obj_src, obj_dst);
  } else {
    Rf_error(
        "`ptr_dst` must inherit from 'nanoarrow_schema', 'nanoarrow_array', or "
        "'nanoarrow_array_stream'");
  }

  // also move SEXP dependencies
  R_SetExternalPtrProtected(ptr_dst, R_ExternalPtrProtected(xptr_src));
  R_SetExternalPtrTag(ptr_dst, R_ExternalPtrTag(xptr_src));
  R_SetExternalPtrProtected(xptr_src, R_NilValue);
  R_SetExternalPtrTag(xptr_src, R_NilValue);

  UNPROTECT(1);
  return R_NilValue;
}