extras/physfs_rb/physfs/rb_physfs_file.c
changeset 514 f4e89d934fee
child 654 c0ae01de361d
equal deleted inserted replaced
513:bd18a574bda5 514:f4e89d934fee
       
     1 /*
       
     2  * PhysicsFS File abstraction - ruby interface
       
     3  * 
       
     4  * Author::  Ed Sinjiashvili (slimb@vlinkmail.com)
       
     5  * License:: LGPL
       
     6  */
       
     7 
       
     8 #include "physfs.h"
       
     9 #include "ruby.h"
       
    10 
       
    11 #include "rb_physfs.h"
       
    12 #include "rb_physfs_file.h"
       
    13 #include "physfsrwops.h"
       
    14 
       
    15 VALUE classPhysfsFile;
       
    16 
       
    17 /*
       
    18  * construct new PhysicsFS::File object
       
    19  */
       
    20 VALUE physfs_file_new (PHYSFS_file *file)
       
    21 {
       
    22     if (file == 0)
       
    23         return Qnil;
       
    24 
       
    25     return Data_Wrap_Struct (classPhysfsFile, 0, 0, file);
       
    26 }
       
    27 
       
    28 /*
       
    29  * PhysicsFS::File#close 
       
    30  *
       
    31  * Close the file. It's illegal to use the object after its closure.
       
    32  */
       
    33 VALUE physfs_file_close (VALUE self)
       
    34 {
       
    35     int result;
       
    36     PHYSFS_file *file;
       
    37     Data_Get_Struct (self, PHYSFS_file, file);
       
    38 
       
    39     if (file == 0)
       
    40 	return Qfalse;
       
    41 
       
    42     result = PHYSFS_close (file);
       
    43     DATA_PTR(self) = 0;
       
    44 
       
    45     if (result)
       
    46         return Qtrue;
       
    47     return Qfalse;
       
    48 }
       
    49 
       
    50 /*
       
    51  * PhysicsFS::File#read obj_size, num_objects
       
    52  *
       
    53  * Read *objCount* objects which are *objSize* each.
       
    54  * return String instance containing raw data or nil if failure.
       
    55  * #length of string will reflect real number of objects read.
       
    56  */
       
    57 VALUE physfs_file_read (VALUE self, VALUE objSize, VALUE objCount)
       
    58 {
       
    59     int objRead;
       
    60     void *buffer;
       
    61     VALUE result;
       
    62     PHYSFS_file *file;
       
    63 
       
    64     Data_Get_Struct (self, PHYSFS_file, file);
       
    65     if (file == 0)
       
    66 	return Qnil; //wasted file - no read possible
       
    67 
       
    68     buffer  = malloc (FIX2UINT(objSize) * FIX2UINT(objCount));
       
    69     if (buffer == 0)
       
    70 	return Qnil;
       
    71 
       
    72     objRead = PHYSFS_read (file, buffer, FIX2UINT(objSize), FIX2UINT(objCount));
       
    73     if (objRead == -1)
       
    74     {
       
    75         free (buffer);
       
    76         return Qnil;
       
    77     }
       
    78 
       
    79     result = rb_str_new (buffer, objRead * FIX2UINT(objSize));
       
    80     free (buffer);
       
    81     return result;
       
    82 }
       
    83 
       
    84 /*
       
    85  * PhysicsFS::File#write buffer, obj_size, num_objects
       
    86  *
       
    87  * return nil on failure or number of objects written.
       
    88  */
       
    89 VALUE physfs_file_write (VALUE self, VALUE buf, VALUE objSize, VALUE objCount)
       
    90 {
       
    91     int result;
       
    92     PHYSFS_file *file;
       
    93 
       
    94     Data_Get_Struct (self, PHYSFS_file, file);
       
    95     if (file == 0)
       
    96 	return Qnil;
       
    97 
       
    98     result = PHYSFS_write (file, STR2CSTR(buf), 
       
    99                            FIX2UINT(objSize), FIX2UINT(objCount));
       
   100     if (result == -1)
       
   101         return Qnil;
       
   102 
       
   103     return INT2FIX(result);
       
   104 }
       
   105 
       
   106 /*
       
   107  * PhysicsFS::File#eof? 
       
   108  */
       
   109 VALUE physfs_file_eof (VALUE self)
       
   110 {
       
   111     int result;
       
   112     PHYSFS_file *file;
       
   113 
       
   114     Data_Get_Struct (self, PHYSFS_file, file);
       
   115     if (file == 0)
       
   116 	return Qnil;
       
   117 
       
   118     result = PHYSFS_eof (file);
       
   119 
       
   120     if (result)
       
   121         return Qtrue;
       
   122 
       
   123     return Qfalse;
       
   124 }
       
   125 
       
   126 /*
       
   127  * PhysicsFS::File#tell
       
   128  *
       
   129  * tells current position in file
       
   130  */
       
   131 VALUE physfs_file_tell (VALUE self)
       
   132 {
       
   133     int result;
       
   134     PHYSFS_file *file;
       
   135 
       
   136     Data_Get_Struct (self, PHYSFS_file, file);
       
   137     if (file == 0)
       
   138 	return Qnil;
       
   139 
       
   140     result = PHYSFS_tell (file);
       
   141 
       
   142     if (result == -1)
       
   143         return Qnil;
       
   144 
       
   145     return INT2FIX(result);
       
   146 }    
       
   147 
       
   148 /*
       
   149  * PhysicsFS::File#seek pos
       
   150  *
       
   151  * seek to pos in file
       
   152  */
       
   153 VALUE physfs_file_seek (VALUE self, VALUE pos)
       
   154 {
       
   155     int result;
       
   156     PHYSFS_file *file;
       
   157 
       
   158     Data_Get_Struct (self, PHYSFS_file, file);
       
   159     if (file == 0)
       
   160 	return Qnil;
       
   161 
       
   162     result = PHYSFS_seek (file, FIX2LONG(pos));
       
   163 
       
   164     if (result)
       
   165         return Qtrue;
       
   166 
       
   167     return Qfalse;    
       
   168 }
       
   169 
       
   170 /*
       
   171  * PhysicsFS::File#length 
       
   172  */
       
   173 VALUE physfs_file_length (VALUE self)
       
   174 {
       
   175     int result;
       
   176     PHYSFS_file *file;
       
   177 
       
   178     Data_Get_Struct (self, PHYSFS_file, file);
       
   179     if (file == 0)
       
   180 	return Qnil;
       
   181 
       
   182     result = PHYSFS_fileLength (file);
       
   183 
       
   184     if (result == -1)
       
   185         return Qnil;
       
   186 
       
   187     return INT2FIX(result);
       
   188 }
       
   189 
       
   190 /*
       
   191  * PhysicsFS::File#to_rwops
       
   192  *
       
   193  * File object is converted to RWops object. 
       
   194  * File object becomes unusable after that - every operation
       
   195  * should be done through new-born RWops object. 
       
   196  */
       
   197 VALUE physfs_file_to_rwops (VALUE self)
       
   198 {
       
   199     PHYSFS_file *file;
       
   200     SDL_RWops   *rwops;
       
   201 
       
   202     Data_Get_Struct (self, PHYSFS_file, file);
       
   203     if (file == 0)
       
   204 	return Qnil;
       
   205 
       
   206     rwops = PHYSFSRWOPS_makeRWops (file);
       
   207     if (rwops == 0)
       
   208 	return Qnil;
       
   209 
       
   210     DATA_PTR(self) = 0; // oh, gosh, we've sacrificed ourselves!
       
   211     return sdl_rwops_new (rwops);
       
   212 }
       
   213 
       
   214 void init_physfs_file (void)
       
   215 {
       
   216     classPhysfsFile = rb_define_class_under (modulePhysfs, "File", rb_cObject);
       
   217 
       
   218     rb_define_method (classPhysfsFile, "close",    physfs_file_close,    0);
       
   219     rb_define_method (classPhysfsFile, "eof?",     physfs_file_eof,      0);
       
   220     rb_define_method (classPhysfsFile, "tell",     physfs_file_tell,     0);
       
   221     rb_define_method (classPhysfsFile, "seek",     physfs_file_seek,     1);
       
   222     rb_define_method (classPhysfsFile, "length",   physfs_file_length,   0);
       
   223     rb_define_method (classPhysfsFile, "read",     physfs_file_read,     2);
       
   224     rb_define_method (classPhysfsFile, "write",    physfs_file_write,    3);
       
   225     rb_define_method (classPhysfsFile, "to_rwops", physfs_file_to_rwops, 0);
       
   226 }