Class: Cosmos::BufferedFile
- Defined in:
- ext/cosmos/ext/buffered_file/buffered_file.c
Constant Summary
Constants inherited from File
Instance Method Summary collapse
-
#initialize(*args) ⇒ Object
constructor
Initialize the BufferedFile.
-
#pos ⇒ Object
Get the current file position.
-
#read(arg_length) ⇒ Object
Read using an internal buffer to avoid system calls.
-
#seek(*args) ⇒ Object
Seek to a given file position.
Methods inherited from File
build_timestamped_filename, find_in_search_path, is_ascii?
Constructor Details
#initialize(*args) ⇒ Object
Initialize the BufferedFile. Takes the same args as File
30 31 32 33 34 35 |
# File 'ext/cosmos/ext/buffered_file/buffered_file.c', line 30
static VALUE buffered_file_initialize(int argc, VALUE* argv, VALUE self) {
rb_call_super(argc, argv);
rb_ivar_set(self, id_ivar_buffer, rb_str_new2(""));
rb_ivar_set(self, id_ivar_buffer_index, INT2FIX(0));
return self;
}
|
Instance Method Details
#pos ⇒ Object
Get the current file position
94 95 96 97 98 99 100 |
# File 'ext/cosmos/ext/buffered_file/buffered_file.c', line 94
static VALUE buffered_file_pos(VALUE self) {
volatile VALUE parent_pos = rb_call_super(0, NULL);
long long ll_pos = NUM2LL(parent_pos);
long buffer_length = RSTRING_LEN(rb_ivar_get(self, id_ivar_buffer));
long buffer_index = FIX2INT(rb_ivar_get(self, id_ivar_buffer_index));
return LL2NUM(ll_pos - (long long)(buffer_length - buffer_index));
}
|
#read(arg_length) ⇒ Object
Read using an internal buffer to avoid system calls
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'ext/cosmos/ext/buffered_file/buffered_file.c', line 38
static VALUE buffered_file_read(VALUE self, VALUE arg_length) {
long length = FIX2INT(arg_length);
volatile VALUE buffer = rb_ivar_get(self, id_ivar_buffer);
long buffer_length = RSTRING_LEN(buffer);
long buffer_index = FIX2INT(rb_ivar_get(self, id_ivar_buffer_index));
volatile VALUE result = Qnil;
volatile VALUE super_arg = Qnil;
if (length <= (buffer_length - buffer_index)) {
/* Return part of the buffer without having to go to the OS */
result = rb_str_substr(buffer, buffer_index, length);
buffer_index += length;
rb_ivar_set(self, id_ivar_buffer_index, INT2FIX(buffer_index));
return result;
} else if (length > BUFFER_SIZE) {
/* Reading more than our buffer */
if (buffer_length > 0) {
if (buffer_index > 0) {
rb_funcall(buffer, id_method_slice_bang, 1, rb_range_new(INT2FIX(0), INT2FIX(buffer_index - 1), Qfalse));
buffer_length = RSTRING_LEN(buffer);
buffer_index = 0;
rb_ivar_set(self, id_ivar_buffer_index, INT2FIX(0));
}
super_arg = INT2FIX(length - buffer_length);
rb_str_append(buffer, rb_funcall(rb_call_super(1, (VALUE*) &super_arg), id_method_to_s, 0));
return rb_funcall(buffer, id_method_slice_bang, 1, rb_const_get(cBufferedFile, id_const_ALL_RANGE));
} else {
return rb_call_super(1, &arg_length);
}
} else {
/* Read into the buffer */
if (buffer_index > 0) {
rb_funcall(buffer, id_method_slice_bang, 1, rb_range_new(INT2FIX(0), INT2FIX(buffer_index - 1), Qfalse));
buffer_length = RSTRING_LEN(buffer);
buffer_index = 0;
rb_ivar_set(self, id_ivar_buffer_index, INT2FIX(0));
}
super_arg = INT2FIX(BUFFER_SIZE - buffer_length);
rb_str_append(buffer, rb_funcall(rb_call_super(1, (VALUE*) &super_arg), id_method_to_s, 0));
buffer_length = RSTRING_LEN(buffer);
if (buffer_length <= 0) {
return Qnil;
}
if (length <= buffer_length) {
result = rb_str_substr(buffer, buffer_index, length);
buffer_index += length;
rb_ivar_set(self, id_ivar_buffer_index, INT2FIX(buffer_index));
return result;
} else {
return rb_funcall(buffer, id_method_slice_bang, 1, rb_const_get(cBufferedFile, id_const_ALL_RANGE));
}
}
}
|
#seek(*args) ⇒ Object
Seek to a given file position
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'ext/cosmos/ext/buffered_file/buffered_file.c', line 103
static VALUE buffered_file_seek(int argc, VALUE* argv, VALUE self) {
volatile VALUE amount = Qnil;
volatile VALUE whence = Qnil;
long buffer_index = 0;
volatile VALUE super_args[2] = {Qnil, Qnil};
switch (argc)
{
case 1:
amount = argv[0];
whence = BUFFERED_FILE_SEEK_SET;
break;
case 2:
amount = argv[0];
whence = argv[1];
break;
default:
/* Invalid number of arguments given - let super handle */
return rb_call_super(argc, argv);
};
if (whence == BUFFERED_FILE_SEEK_CUR) {
buffer_index = FIX2INT(rb_ivar_get(self, id_ivar_buffer_index)) + FIX2INT(amount);
if ((buffer_index >= 0) && (buffer_index < RSTRING_LEN(rb_ivar_get(self, id_ivar_buffer)))) {
rb_ivar_set(self, id_ivar_buffer_index, INT2FIX(buffer_index));
return INT2FIX(0);
}
super_args[0] = rb_funcall(self, id_method_pos, 0);
super_args[1] = BUFFERED_FILE_SEEK_SET;
rb_call_super(2, (VALUE*) super_args);
}
rb_funcall(rb_ivar_get(self, id_ivar_buffer), id_method_clear, 0);
rb_ivar_set(self, id_ivar_buffer_index, INT2FIX(0));
return rb_call_super(argc, argv);
}
|