blob: 54ef01bb6bc71dfbd61435c03ba80f89e6d00989 [file] [log] [blame]
/*
* ====================================================================
* Copyright (c) 2000-2002 CollabNet. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://subversion.tigris.org/license-1.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
*
* This software consists of voluntary contributions made by many
* individuals. For exact contribution history, see the revision
* history and logs, available at http://subversion.tigris.org/.
* ====================================================================
*/
#include <ruby.h>
#include <svn_pools.h>
#include <svn_fs.h>
#include "svn_ruby.h"
#include "fs_root.h"
#include "fs_node.h"
#include "txdelta.h"
#include "error.h"
static VALUE cSvnFsRoot;
static VALUE cSvnFsRevisionRoot;
static VALUE cSvnFsTxnRoot;
typedef struct svn_ruby_fs_root_t
{
svn_fs_root_t *root;
apr_pool_t *pool;
svn_boolean_t closed;
} svn_ruby_fs_root_t;
svn_fs_root_t *
svn_ruby_fs_root (VALUE aRoot)
{
svn_ruby_fs_root_t *root;
Data_Get_Struct (aRoot, svn_ruby_fs_root_t, root);
return root->root;
}
static void
free_fs_root (void *p)
{
svn_ruby_fs_root_t *root = p;
if (!root->closed)
svn_fs_close_root (root->root);
apr_pool_destroy (root->pool);
}
VALUE
svn_ruby_fs_rev_root_new (svn_fs_root_t *root, apr_pool_t *pool)
{
svn_ruby_fs_root_t *rb_root;
VALUE obj;
obj = Data_Make_Struct (cSvnFsRevisionRoot, svn_ruby_fs_root_t,
0, free_fs_root, rb_root);
rb_root->root = root;
rb_root->pool = pool;
rb_root->closed = FALSE;
rb_obj_call_init (obj, 0, 0);
return obj;
}
VALUE
svn_ruby_fs_txn_root_new (svn_fs_root_t *root, apr_pool_t *pool)
{
svn_ruby_fs_root_t *rb_root;
VALUE obj;
obj = Data_Make_Struct (cSvnFsTxnRoot, svn_ruby_fs_root_t,
0, free_fs_root, rb_root);
rb_root->root = root;
rb_root->pool = pool;
rb_root->closed = FALSE;
rb_obj_call_init (obj, 0, 0);
return obj;
}
/* FsRoot instance methods. */
static VALUE
fs_root_close (VALUE self)
{
svn_ruby_fs_root_t *root;
Data_Get_Struct (self, svn_ruby_fs_root_t, root);
if (root->closed)
rb_raise (rb_eRuntimeError, "closed root");
svn_fs_close_root (root->root);
root->closed = TRUE;
return Qnil;
}
static VALUE
check_path (VALUE self, VALUE aPath)
{
svn_node_kind_t kind;
svn_ruby_fs_root_t *root;
apr_pool_t *pool;
Check_Type (aPath, T_STRING);
Data_Get_Struct (self, svn_ruby_fs_root_t, root);
if (root->closed)
rb_raise (rb_eRuntimeError, "closed root");
pool = svn_pool_create (root->pool);
kind = svn_fs_check_path (root->root, StringValuePtr (aPath), pool);
apr_pool_destroy (pool);
return INT2FIX (kind);
}
static VALUE
is_dir (VALUE self, VALUE aPath)
{
int is_dir;
svn_ruby_fs_root_t *root;
const char *path;
apr_pool_t *pool;
svn_error_t *err;
Check_Type (aPath, T_STRING);
path = StringValuePtr (aPath);
Data_Get_Struct (self, svn_ruby_fs_root_t, root);
if (root->closed)
rb_raise (rb_eRuntimeError, "closed root");
pool = svn_pool_create (root->pool);
err = svn_fs_is_dir (&is_dir, root->root, path, pool);
apr_pool_destroy (pool);
if (err)
svn_ruby_raise (err);
if (is_dir)
return Qtrue;
else
return Qfalse;
}
static VALUE
is_file (VALUE self, VALUE aPath)
{
int is_file;
svn_ruby_fs_root_t *root;
const char *path;
apr_pool_t *pool;
svn_error_t *err;
Check_Type (aPath, T_STRING);
path = StringValuePtr (aPath);
Data_Get_Struct (self, svn_ruby_fs_root_t, root);
if (root->closed)
rb_raise (rb_eRuntimeError, "closed root");
pool = svn_pool_create (root->pool);
err = svn_fs_is_file (&is_file, root->root, path, pool);
apr_pool_destroy (pool);
if (err)
svn_ruby_raise (err);
if (is_file)
return Qtrue;
else
return Qfalse;
}
static VALUE
file (VALUE self, VALUE aPath)
{
Check_Type (aPath, T_STRING);
if (rb_funcall (self, rb_intern ("file?"), 1, aPath) != Qtrue)
rb_raise (rb_eRuntimeError, "No such file: %s", StringValuePtr (aPath));
return svn_ruby_fs_file_new (self, aPath);
}
static VALUE
dir (VALUE self, VALUE aPath)
{
Check_Type (aPath, T_STRING);
if (rb_funcall (self, rb_intern ("dir?"), 1, aPath) != Qtrue)
rb_raise (rb_eRuntimeError, "No such directory: %s", StringValuePtr (aPath));
return svn_ruby_fs_dir_new (self, aPath);
}
static VALUE
node (VALUE self, VALUE aPath)
{
Check_Type (aPath, T_STRING);
if (rb_funcall (self, rb_intern ("file?"), 1, aPath) == Qtrue)
return svn_ruby_fs_file_new (self, aPath);
else if (rb_funcall (self, rb_intern ("dir?"), 1, aPath) == Qtrue)
return svn_ruby_fs_dir_new (self, aPath);
else
{
rb_raise (rb_eRuntimeError, "Unknown node type");
return Qnil; /* Silence compiler. */
}
}
/* TxnRoot instance methods. */
static VALUE
make_dir (VALUE self, VALUE aPath)
{
svn_ruby_fs_root_t *root;
const char *path;
apr_pool_t *pool;
svn_error_t *err;
Check_Type (aPath, T_STRING);
path = StringValuePtr (aPath);
Data_Get_Struct (self, svn_ruby_fs_root_t, root);
if (root->closed)
rb_raise (rb_eRuntimeError, "closed root");
pool = svn_pool_create (root->pool);
err = svn_fs_make_dir (root->root, path, pool);
apr_pool_destroy (pool);
if (err)
svn_ruby_raise (err);
return Qnil;
}
static VALUE
make_file (VALUE self, VALUE aPath)
{
svn_ruby_fs_root_t *root;
const char *path;
apr_pool_t *pool;
svn_error_t *err;
Check_Type (aPath, T_STRING);
path = StringValuePtr (aPath);
Data_Get_Struct (self, svn_ruby_fs_root_t, root);
pool = svn_pool_create (root->pool);
err = svn_fs_make_file (root->root, path, pool);
apr_pool_destroy (pool);
if (err)
svn_ruby_raise (err);
return Qnil;
}
static VALUE
fs_apply_textdelta (VALUE self, VALUE aPath)
{
svn_txdelta_window_handler_t handler;
void *handler_baton;
svn_ruby_fs_root_t *root;
const char *path;
apr_pool_t *pool;
svn_error_t *err;
Check_Type (aPath, T_STRING);
path = StringValuePtr (aPath);
Data_Get_Struct (self, svn_ruby_fs_root_t, root);
if (root->closed)
rb_raise (rb_eRuntimeError, "closed root");
pool = svn_pool_create (NULL);
err = svn_fs_apply_textdelta (&handler, &handler_baton, root->root, path, pool);
if (err)
{
apr_pool_destroy (pool);
svn_ruby_raise (err);
}
return svn_ruby_txdelta_new (handler, handler_baton, pool);
}
static VALUE
change_node_prop (VALUE self, VALUE path, VALUE aName, VALUE aValue)
{
svn_ruby_fs_root_t *root;
const svn_string_t *value;
apr_pool_t *pool;
svn_error_t *err;
Check_Type (path, T_STRING);
Check_Type (aName, T_STRING);
if (aValue != Qnil)
Check_Type (aValue, T_STRING);
Data_Get_Struct (self, svn_ruby_fs_root_t, root);
pool = svn_pool_create (root->pool);
if (aValue == Qnil)
value = NULL;
else
value = svn_string_ncreate (StringValuePtr (aValue),
RSTRING (aValue)->len, pool);
err = svn_fs_change_node_prop (root->root, StringValuePtr (path),
StringValuePtr (aName), value, pool);
apr_pool_destroy (pool);
if (err)
svn_ruby_raise (err);
return Qnil;
}
svn_boolean_t
svn_ruby_is_fs_root (VALUE obj)
{
if (rb_obj_is_kind_of (obj, cSvnFsRoot) == Qtrue)
return TRUE;
else
return FALSE;
}
void
svn_ruby_init_fs_root (void)
{
cSvnFsRoot = rb_define_class_under (svn_ruby_mSvn, "FsRoot", rb_cObject);
rb_undef_method (CLASS_OF (cSvnFsRoot), "new");
rb_define_method (cSvnFsRoot, "close", fs_root_close, 0);
rb_define_method (cSvnFsRoot, "checkPath", check_path, 1);
rb_define_method (cSvnFsRoot, "dir?", is_dir, 1);
rb_define_method (cSvnFsRoot, "file?", is_file, 1);
rb_define_method (cSvnFsRoot, "file", file, 1);
rb_define_method (cSvnFsRoot, "dir", dir, 1);
rb_define_method (cSvnFsRoot, "node", node, 1);
cSvnFsRevisionRoot = rb_define_class_under (svn_ruby_mSvn, "FsRevisionRoot",
cSvnFsRoot);
cSvnFsTxnRoot = rb_define_class_under (svn_ruby_mSvn, "FsTxnRoot", cSvnFsRoot);
rb_define_method (cSvnFsTxnRoot, "makeDir", make_dir, 1);
rb_define_method (cSvnFsTxnRoot, "makeFile", make_file, 1);
rb_define_method (cSvnFsTxnRoot, "applyTextDelta",
fs_apply_textdelta, 1);
rb_define_method (cSvnFsTxnRoot, "changeNodeProp", change_node_prop, 3);
}