00001 #include "mpeg3private.h"
00002 #include "mpeg3protos.h"
00003
00004 #include <mntent.h>
00005 #include <stdint.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include <sys/stat.h>
00009
00010 mpeg3_fs_t* mpeg3_new_fs(char *path)
00011 {
00012 mpeg3_fs_t *fs = calloc(1, sizeof(mpeg3_fs_t));
00013 fs->buffer = calloc(1, MPEG3_IO_SIZE);
00014
00015 fs->buffer_position = -0xffff;
00016 fs->css = mpeg3_new_css();
00017 strcpy(fs->path, path);
00018 return fs;
00019 }
00020
00021 int mpeg3_delete_fs(mpeg3_fs_t *fs)
00022 {
00023 mpeg3_delete_css(fs->css);
00024 free(fs->buffer);
00025 free(fs);
00026 return 0;
00027 }
00028
00029 int mpeg3_copy_fs(mpeg3_fs_t *dst, mpeg3_fs_t *src)
00030 {
00031 strcpy(dst->path, src->path);
00032 dst->current_byte = 0;
00033 return 0;
00034 }
00035
00036 int64_t mpeg3io_get_total_bytes(mpeg3_fs_t *fs)
00037 {
00038 struct stat64 ostat;
00039 stat64(fs->path, &ostat);
00040 fs->total_bytes = ostat.st_size;
00041 return fs->total_bytes;
00042
00043
00044
00045
00046
00047
00048
00049 }
00050
00051 int64_t mpeg3io_path_total_bytes(char *path)
00052 {
00053 struct stat64 st;
00054 if(stat64(path, &st) < 0) return 0;
00055 return st.st_size;
00056 }
00057
00058 int mpeg3io_open_file(mpeg3_fs_t *fs)
00059 {
00060
00061 mpeg3_get_keys(fs->css, fs->path);
00062
00063
00064 if(!(fs->fd = fopen64(fs->path, "rb")))
00065 {
00066 if (fs->path) fprintf(stderr,"[mpeg3io_open_file] Error opening file '%s': ",fs->path);
00067 perror("");
00068 return 1;
00069 }
00070
00071 fs->total_bytes = mpeg3io_get_total_bytes(fs);
00072
00073 if(!fs->total_bytes)
00074 {
00075 fclose(fs->fd);
00076 return 1;
00077 }
00078
00079 fs->current_byte = 0;
00080 fs->buffer_position = -0xffff;
00081 return 0;
00082 }
00083
00084 int mpeg3io_close_file(mpeg3_fs_t *fs)
00085 {
00086 if(fs->fd) fclose(fs->fd);
00087 fs->fd = 0;
00088 return 0;
00089 }
00090
00091 int mpeg3io_read_data(unsigned char *buffer, int64_t bytes, mpeg3_fs_t *fs)
00092 {
00093 int result = 0, i, fragment_size;
00094
00095
00096 for(i = 0; bytes > 0 && !result; )
00097 {
00098 result = mpeg3io_sync_buffer(fs);
00099
00100
00101 fragment_size = MPEG3_IO_SIZE;
00102
00103 if(fragment_size > bytes) fragment_size = bytes;
00104
00105 if(fs->buffer_offset + fragment_size > fs->buffer_size)
00106 fragment_size = fs->buffer_size - fs->buffer_offset;
00107
00108 memcpy(buffer + i, fs->buffer + fs->buffer_offset, fragment_size);
00109
00110 fs->buffer_offset += fragment_size;
00111 fs->current_byte += fragment_size;
00112 i += fragment_size;
00113 bytes -= fragment_size;
00114
00115 }
00116
00117
00118 return (result && bytes);
00119 }
00120
00121 int mpeg3io_seek(mpeg3_fs_t *fs, int64_t byte)
00122 {
00123
00124 fs->current_byte = byte;
00125 return (fs->current_byte < 0) || (fs->current_byte > fs->total_bytes);
00126 }
00127
00128 int mpeg3io_seek_relative(mpeg3_fs_t *fs, int64_t bytes)
00129 {
00130
00131 fs->current_byte += bytes;
00132 return (fs->current_byte < 0) || (fs->current_byte > fs->total_bytes);
00133 }
00134
00135
00136 void mpeg3io_read_buffer(mpeg3_fs_t *fs)
00137 {
00138
00139
00140
00141
00142 if(fs->current_byte < fs->buffer_position &&
00143 fs->current_byte >= fs->buffer_position - MPEG3_IO_SIZE / 2)
00144 {
00145 int64_t new_buffer_position = fs->current_byte - MPEG3_IO_SIZE / 2;
00146 int64_t new_buffer_size = MIN(fs->buffer_size + MPEG3_IO_SIZE / 2,
00147 MPEG3_IO_SIZE);
00148 if(new_buffer_position < 0)
00149 {
00150 new_buffer_size += new_buffer_position;
00151 new_buffer_position = 0;
00152 }
00153
00154
00155 int remainder = new_buffer_position + new_buffer_size - fs->buffer_position;
00156 if(remainder < 0) remainder = 0;
00157 int remainder_start = new_buffer_size - remainder;
00158 if(remainder)
00159 {
00160 memmove(fs->buffer + remainder_start, fs->buffer, remainder);
00161 }
00162
00163
00164
00165 fseeko64(fs->fd, new_buffer_position, SEEK_SET);
00166 fread(fs->buffer, 1, remainder_start, fs->fd);
00167
00168
00169 fs->buffer_position = new_buffer_position;
00170 fs->buffer_size = new_buffer_size;
00171 fs->buffer_offset = fs->current_byte - fs->buffer_position;
00172 }
00173 else
00174
00175 {
00176 int result;
00177 fs->buffer_position = fs->current_byte;
00178 fs->buffer_offset = 0;
00179
00180 result = fseeko64(fs->fd, fs->buffer_position, SEEK_SET);
00181
00182 fs->buffer_size = fread(fs->buffer, 1, MPEG3_IO_SIZE, fs->fd);
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 }
00203 }
00204
00205 void mpeg3io_complete_path(char *complete_path, char *path)
00206 {
00207 if(path[0] != '/')
00208 {
00209 char current_dir[MPEG3_STRLEN];
00210 getcwd(current_dir, MPEG3_STRLEN);
00211 sprintf(complete_path, "%s/%s", current_dir, path);
00212 }
00213 else
00214 strcpy(complete_path, path);
00215 }
00216
00217 int mpeg3io_device(char *path, char *device)
00218 {
00219 struct stat64 file_st, device_st;
00220 struct mntent *mnt;
00221 FILE *fp;
00222
00223 if(stat64(path, &file_st) < 0)
00224 {
00225 perror("mpeg3io_device");
00226 return 1;
00227 }
00228
00229 fp = setmntent(MOUNTED, "r");
00230 while(fp && (mnt = getmntent(fp)))
00231 {
00232 if(stat64(mnt->mnt_fsname, &device_st) < 0) continue;
00233 if(device_st.st_rdev == file_st.st_dev)
00234 {
00235 strncpy(device, mnt->mnt_fsname, MPEG3_STRLEN);
00236 break;
00237 }
00238 }
00239 endmntent(fp);
00240
00241 return 0;
00242 }
00243
00244 void mpeg3io_get_directory(char *directory, char *path)
00245 {
00246 char *ptr = strrchr(path, '/');
00247 if(ptr)
00248 {
00249 int i;
00250 for(i = 0; i < ptr - path; i++)
00251 {
00252 directory[i] = path[i];
00253 }
00254 directory[i] = 0;
00255 }
00256 }
00257
00258 void mpeg3io_get_filename(char *filename, char *path)
00259 {
00260 char *ptr = strrchr(path, '/');
00261 if(!ptr)
00262 ptr = path;
00263 else
00264 ptr++;
00265
00266 strcpy(filename, ptr);
00267 }
00268
00269 void mpeg3io_joinpath(char *title_path, char *directory, char *new_filename)
00270 {
00271 sprintf(title_path, "%s/%s", directory, new_filename);
00272 }
00273
00274