1 #include "mpeg3private.h"
2 #include "mpeg3protos.h"
10 mpeg3_fs_t
* mpeg3_new_fs(char *path
)
12 mpeg3_fs_t
*fs
= calloc(1, sizeof(mpeg3_fs_t
));
13 fs
->buffer
= calloc(1, MPEG3_IO_SIZE
);
15 fs
->buffer_position
= -0xffff;
16 fs
->css
= mpeg3_new_css();
17 strcpy(fs
->path
, path
);
21 int mpeg3_delete_fs(mpeg3_fs_t
*fs
)
23 mpeg3_delete_css(fs
->css
);
29 int mpeg3_copy_fs(mpeg3_fs_t
*dst
, mpeg3_fs_t
*src
)
31 strcpy(dst
->path
, src
->path
);
32 dst
->current_byte
= 0;
36 int64_t mpeg3io_get_total_bytes(mpeg3_fs_t
*fs
)
39 stat64(fs
->path
, &ostat
);
40 fs
->total_bytes
= ostat
.st_size
;
41 return fs
->total_bytes
;
44 * fseek(fs->fd, 0, SEEK_END);
45 * fs->total_bytes = ftell(fs->fd);
46 * fseek(fs->fd, 0, SEEK_SET);
47 * return fs->total_bytes;
51 int64_t mpeg3io_path_total_bytes(char *path
)
54 if(stat64(path
, &st
) < 0) return 0;
58 int mpeg3io_open_file(mpeg3_fs_t
*fs
)
60 /* Need to perform authentication before reading a single byte. */
61 mpeg3_get_keys(fs
->css
, fs
->path
);
63 //printf("mpeg3io_open_file 1 %s\n", fs->path);
64 if(!(fs
->fd
= fopen64(fs
->path
, "rb")))
66 if (fs
->path
) fprintf(stderr
,"[mpeg3io_open_file] Error opening file '%s': ",fs
->path
);
71 fs
->total_bytes
= mpeg3io_get_total_bytes(fs
);
80 fs
->buffer_position
= -0xffff;
84 int mpeg3io_close_file(mpeg3_fs_t
*fs
)
86 if(fs
->fd
) fclose(fs
->fd
);
91 int mpeg3io_read_data(unsigned char *buffer
, int64_t bytes
, mpeg3_fs_t
*fs
)
93 int result
= 0, i
, fragment_size
;
94 //printf("mpeg3io_read_data 1 %d\n", bytes);
96 for(i
= 0; bytes
> 0 && !result
; )
98 result
= mpeg3io_sync_buffer(fs
);
99 //printf("mpeg3io_read_data 2\n");
101 fragment_size
= MPEG3_IO_SIZE
;
103 if(fragment_size
> bytes
) fragment_size
= bytes
;
105 if(fs
->buffer_offset
+ fragment_size
> fs
->buffer_size
)
106 fragment_size
= fs
->buffer_size
- fs
->buffer_offset
;
108 memcpy(buffer
+ i
, fs
->buffer
+ fs
->buffer_offset
, fragment_size
);
110 fs
->buffer_offset
+= fragment_size
;
111 fs
->current_byte
+= fragment_size
;
113 bytes
-= fragment_size
;
114 //printf("mpeg3io_read_data 10 %d\n", bytes);
117 //printf("mpeg3io_read_data 100 %d\n", bytes);
118 return (result
&& bytes
);
121 int mpeg3io_seek(mpeg3_fs_t
*fs
, int64_t byte
)
123 //printf("mpeg3io_seek 1 %lld\n", byte);
124 fs
->current_byte
= byte
;
125 return (fs
->current_byte
< 0) || (fs
->current_byte
> fs
->total_bytes
);
128 int mpeg3io_seek_relative(mpeg3_fs_t
*fs
, int64_t bytes
)
130 //printf("mpeg3io_seek_relative 1 %lld\n", bytes);
131 fs
->current_byte
+= bytes
;
132 return (fs
->current_byte
< 0) || (fs
->current_byte
> fs
->total_bytes
);
136 void mpeg3io_read_buffer(mpeg3_fs_t
*fs
)
138 // Special case for sequential reverse buffer.
139 // This is only used for searching for previous codes.
140 // Here we move a full half buffer backwards since the search normally
141 // goes backwards and then forwards a little bit.
142 if(fs
->current_byte
< fs
->buffer_position
&&
143 fs
->current_byte
>= fs
->buffer_position
- MPEG3_IO_SIZE
/ 2)
145 int64_t new_buffer_position
= fs
->current_byte
- MPEG3_IO_SIZE
/ 2;
146 int64_t new_buffer_size
= MIN(fs
->buffer_size
+ MPEG3_IO_SIZE
/ 2,
148 if(new_buffer_position
< 0)
150 new_buffer_size
+= new_buffer_position
;
151 new_buffer_position
= 0;
154 // Shift existing buffer forward and calculate amount of new data needed.
155 int remainder
= new_buffer_position
+ new_buffer_size
- fs
->buffer_position
;
156 if(remainder
< 0) remainder
= 0;
157 int remainder_start
= new_buffer_size
- remainder
;
160 memmove(fs
->buffer
+ remainder_start
, fs
->buffer
, remainder
);
165 fseeko64(fs
->fd
, new_buffer_position
, SEEK_SET
);
166 fread(fs
->buffer
, 1, remainder_start
, fs
->fd
);
169 fs
->buffer_position
= new_buffer_position
;
170 fs
->buffer_size
= new_buffer_size
;
171 fs
->buffer_offset
= fs
->current_byte
- fs
->buffer_position
;
174 // Sequential forward buffer or random seek
177 fs
->buffer_position
= fs
->current_byte
;
178 fs
->buffer_offset
= 0;
180 result
= fseeko64(fs
->fd
, fs
->buffer_position
, SEEK_SET
);
181 //printf("mpeg3io_read_buffer 2 %llx %llx\n", fs->buffer_position, ftell(fs->fd));
182 fs
->buffer_size
= fread(fs
->buffer
, 1, MPEG3_IO_SIZE
, fs
->fd
);
187 * printf(__FUNCTION__ " 2 result=%d ftell=%llx buffer_position=%llx %02x%02x%02x%02x%02x%02x%02x%02x %02x%02x\n",
190 * fs->buffer_position,
205 void mpeg3io_complete_path(char *complete_path
, char *path
)
209 char current_dir
[MPEG3_STRLEN
];
210 getcwd(current_dir
, MPEG3_STRLEN
);
211 sprintf(complete_path
, "%s/%s", current_dir
, path
);
214 strcpy(complete_path
, path
);
217 int mpeg3io_device(char *path
, char *device
)
219 struct stat64 file_st
, device_st
;
223 if(stat64(path
, &file_st
) < 0)
225 perror("mpeg3io_device");
229 fp
= setmntent(MOUNTED
, "r");
230 while(fp
&& (mnt
= getmntent(fp
)))
232 if(stat64(mnt
->mnt_fsname
, &device_st
) < 0) continue;
233 if(device_st
.st_rdev
== file_st
.st_dev
)
235 strncpy(device
, mnt
->mnt_fsname
, MPEG3_STRLEN
);
244 void mpeg3io_get_directory(char *directory
, char *path
)
246 char *ptr
= strrchr(path
, '/');
250 for(i
= 0; i
< ptr
- path
; i
++)
252 directory
[i
] = path
[i
];
258 void mpeg3io_get_filename(char *filename
, char *path
)
260 char *ptr
= strrchr(path
, '/');
266 strcpy(filename
, ptr
);
269 void mpeg3io_joinpath(char *title_path
, char *directory
, char *new_filename
)
271 sprintf(title_path
, "%s/%s", directory
, new_filename
);