Max 5 API Reference
00001 /** 00002 @file 00003 filebyte - similar to filein. 00004 Accesses a file on disk and outputs a given byte of the file's data. 00005 Note that we use the "open" message, not "read", because we're not loading the file into memory. 00006 00007 updated 3/22/09 ajm: new API 00008 00009 @ingroup examples 00010 */ 00011 00012 #include "ext.h" 00013 #include "ext_obex.h" 00014 #include "ext_path.h" 00015 00016 #ifdef MAC_VERSION 00017 #include "ext_strings.h" 00018 #endif 00019 00020 #ifndef MAC_VERSION 00021 // if defined, use windows calls, otherwise use max's cross platform "sysfile" API 00022 #define FILEBYTE_WINDOWS_SPECIFIC 00023 #endif 00024 00025 void *filebyte_class; 00026 00027 typedef struct filebyte { 00028 t_object f_ob; 00029 #ifdef FILEBYTE_WINDOWS_SPECIFIC 00030 HANDLE f_fh; 00031 #else // cross platform sysfile calls 00032 t_filehandle f_fh; 00033 #endif 00034 short f_open; 00035 void *f_out; 00036 } t_filebyte; 00037 00038 t_symbol *ps_nothing; 00039 00040 void filebyte_doint(t_filebyte *x, long n); 00041 void filebyte_int(t_filebyte *x, long n); 00042 void filebyte_close(t_filebyte *x); 00043 void filebyte_doopen(t_filebyte *x, t_symbol *s); 00044 void filebyte_open(t_filebyte *x, t_symbol *s); 00045 void filebyte_free(t_filebyte *x); 00046 void filebyte_assist(t_filebyte *x, void *b, long m, long a, char *s); 00047 void *filebyte_new(t_symbol *fn); 00048 00049 int main(void) 00050 { 00051 t_class *c; 00052 00053 c = class_new("filebyte", (method)filebyte_new, (method)filebyte_free, (short)sizeof(t_filebyte), 00054 0L, A_DEFSYM, 0); 00055 class_addmethod(c, (method)filebyte_int, "int", A_LONG, 0); 00056 class_addmethod(c, (method)filebyte_close, "fclose", 0); 00057 class_addmethod(c, (method)filebyte_open, "open", A_DEFSYM,0); 00058 class_addmethod(c, (method)filebyte_assist, "assist", A_CANT,0); 00059 class_register(CLASS_BOX, c); 00060 filebyte_class = c; 00061 00062 ps_nothing = gensym(""); 00063 return 0; 00064 } 00065 00066 void filebyte_doint(t_filebyte *x, long n) // byte access 00067 { 00068 Byte data; 00069 long count; 00070 long err; 00071 00072 if (x->f_open) { 00073 #ifdef FILEBYTE_WINDOWS_SPECIFIC 00074 if (INVALID_SET_FILE_POINTER!=SetFilePointer(x->f_fh,n,NULL,FILE_BEGIN)) 00075 err = 0; 00076 else 00077 err = GetLastError(); 00078 #else // cross platform sysfile calls 00079 err = sysfile_setpos(x->f_fh,SYSFILE_FROMSTART,n); 00080 #endif 00081 if (err) 00082 error("filebyte: seek err %d",err); 00083 else { 00084 count = 1; 00085 #ifdef FILEBYTE_WINDOWS_SPECIFIC 00086 if (ReadFile(x->f_fh,&data,count,(LPDWORD)&count,NULL)) 00087 err = 0; 00088 else 00089 err = GetLastError(); 00090 #else // cross platform sysfile calls 00091 err = sysfile_read(x->f_fh,&count,&data); 00092 #endif 00093 if (err) 00094 error("filebyte: read err %d",err); 00095 else { 00096 outlet_int(x->f_out,data); 00097 } 00098 } 00099 } else { 00100 error("filebyte: no open file"); 00101 } 00102 } 00103 00104 void filebyte_int(t_filebyte *x, long n) 00105 { 00106 defer_low(x,(method)filebyte_doint,(t_symbol *)n,0,0L); // trick. passing int as symbol 00107 } 00108 00109 void filebyte_close(t_filebyte *x) 00110 { 00111 if (x->f_open) { 00112 #ifdef FILEBYTE_WINDOWS_SPECIFIC 00113 CloseHandle(x->f_fh); 00114 #else // cross platform sysfile calls 00115 sysfile_close(x->f_fh); 00116 #endif 00117 x->f_fh = 0; 00118 x->f_open = FALSE; 00119 } 00120 } 00121 00122 void filebyte_doopen(t_filebyte *x, t_symbol *s) 00123 { 00124 short path; 00125 char ps[256]; 00126 #ifdef FILEBYTE_WINDOWS_SPECIFIC 00127 char ps2[256]; 00128 #endif 00129 long type,err; 00130 00131 filebyte_close(x); 00132 if (s==ps_nothing) { 00133 if (open_dialog(ps,&path,&type,0L,0)) 00134 return; 00135 } else { 00136 strcpy(ps,s->s_name); 00137 if (locatefile_extended(ps,&path,&type,&type,-1)) { 00138 error("filebyte: %s: can't find file",ps); 00139 return; 00140 } 00141 } 00142 #ifdef FILEBYTE_WINDOWS_SPECIFIC 00143 // convert path + name to pathname 00144 path_topathname(path,ps,ps2); 00145 // convert max style pathname to native pathname 00146 path_nameconform(ps2,ps,PATH_STYLE_NATIVE,PATH_TYPE_ABSOLUTE); 00147 // open file 00148 x->f_fh = CreateFile(ps,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); 00149 if (x->f_fh==INVALID_HANDLE_VALUE) { 00150 x->f_fh = 0; 00151 err = GetLastError(); 00152 } else { 00153 err = 0; 00154 } 00155 #else // cross platform sysfile calls 00156 err = path_opensysfile(ps,path,&x->f_fh,READ_PERM); 00157 #endif 00158 if (err) { 00159 x->f_fh = 0; 00160 error("filebyte: %s: error %d opening file",ps,err); 00161 return; 00162 } 00163 x->f_open = TRUE; 00164 } 00165 00166 void filebyte_open(t_filebyte *x, t_symbol *s) 00167 { 00168 defer_low(x,(method)filebyte_doopen,s,0,0L); 00169 } 00170 00171 void filebyte_free(t_filebyte *x) 00172 { 00173 filebyte_close(x); 00174 } 00175 00176 void filebyte_assist(t_filebyte *x, void *b, long m, long a, char *s) 00177 { 00178 if (m == ASSIST_INLET) // inlet 00179 sprintf(s,"(int) byte in file"); 00180 else // outlet 00181 sprintf(s,"(int) byte in file output"); 00182 } 00183 00184 void *filebyte_new(t_symbol *fn) 00185 { 00186 t_filebyte *x; 00187 00188 x = object_alloc(filebyte_class); 00189 x->f_out = intout(x); 00190 x->f_open = FALSE; 00191 x->f_fh = 0; 00192 if (fn != ps_nothing) { 00193 filebyte_doopen(x,fn); 00194 } 00195 return (x); 00196 }
Copyright © 2008, Cycling '74