2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <sys/types.h>
35 static struct stream_priv_s
{
38 } stream_priv_dflts
= {
42 #define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f)
44 static const m_option_t stream_opts_fields
[] = {
45 {"string", ST_OFF(filename
), CONF_TYPE_STRING
, 0, 0 ,0, NULL
},
46 {"filename", ST_OFF(filename2
), CONF_TYPE_STRING
, 0, 0 ,0, NULL
},
47 { NULL
, NULL
, 0, 0, 0, 0, NULL
}
49 static const struct m_struct_st stream_opts
= {
51 sizeof(struct stream_priv_s
),
56 static int fill_buffer(stream_t
*s
, char* buffer
, int max_len
){
57 int r
= read(s
->fd
,buffer
,max_len
);
58 return (r
<= 0) ? -1 : r
;
61 static int write_buffer(stream_t
*s
, char* buffer
, int len
) {
65 r
= write(s
->fd
,buffer
,len
);
74 static int seek(stream_t
*s
,off_t newpos
) {
76 if(lseek(s
->fd
,s
->pos
,SEEK_SET
)<0) {
83 static int seek_forward(stream_t
*s
,off_t newpos
) {
85 mp_msg(MSGT_STREAM
,MSGL_INFO
,"Cannot seek backward in linear streams!\n");
89 int len
=s
->fill_buffer(s
,s
->buffer
,STREAM_BUFFER_SIZE
);
90 if(len
<=0){ s
->eof
=1; s
->buf_pos
=s
->buf_len
=0; break; } // EOF
98 static int control(stream_t
*s
, int cmd
, void *arg
) {
100 case STREAM_CTRL_GET_SIZE
: {
103 size
= lseek(s
->fd
, 0, SEEK_END
);
104 lseek(s
->fd
, s
->pos
, SEEK_SET
);
105 if(size
!= (off_t
)-1) {
106 *((off_t
*)arg
) = size
;
111 return STREAM_UNSUPPORTED
;
114 static int open_f(stream_t
*stream
,int mode
, void* opts
, int* file_format
) {
118 unsigned char *filename
;
119 struct stream_priv_s
* p
= (struct stream_priv_s
*)opts
;
121 if(mode
== STREAM_READ
)
123 else if(mode
== STREAM_WRITE
)
124 m
= O_RDWR
|O_CREAT
|O_TRUNC
;
126 mp_msg(MSGT_OPEN
,MSGL_ERR
, "[file] Unknown open mode %d\n",mode
);
127 m_struct_free(&stream_opts
,opts
);
128 return STREAM_UNSUPPORTED
;
132 filename
= p
->filename
;
133 else if(p
->filename2
)
134 filename
= p
->filename2
;
138 mp_msg(MSGT_OPEN
,MSGL_ERR
, "[file] No filename\n");
139 m_struct_free(&stream_opts
,opts
);
144 // extract '/' from '/x:/path'
145 if( filename
[ 0 ] == '/' && filename
[ 1 ] && filename
[ 2 ] == ':' )
151 if(!strcmp(filename
,"-")){
152 if(mode
== STREAM_READ
) {
154 mp_tmsg(MSGT_OPEN
,MSGL_INFO
,"Reading from stdin...\n");
157 setmode(fileno(stdin
),O_BINARY
);
160 mp_msg(MSGT_OPEN
,MSGL_INFO
,"Writing to stdout\n");
163 setmode(fileno(stdout
),O_BINARY
);
167 mode_t openmode
= S_IRUSR
|S_IWUSR
;
169 openmode
|= S_IRGRP
|S_IWGRP
|S_IROTH
|S_IWOTH
;
171 f
=open(filename
,m
, openmode
);
173 mp_tmsg(MSGT_OPEN
, MSGL_ERR
, "Cannot open file '%s': %s\n", filename
,
175 m_struct_free(&stream_opts
,opts
);
180 if (fstat(f
, &st
) == 0 && S_ISDIR(st
.st_mode
)) {
181 mp_tmsg(MSGT_OPEN
,MSGL_ERR
,"File is a directory: '%s'\n",filename
);
183 m_struct_free(&stream_opts
,opts
);
189 len
=lseek(f
,0,SEEK_END
); lseek(f
,0,SEEK_SET
);
191 // seeks on stdin incorrectly succeed on MinGW
196 if(mode
== STREAM_READ
) stream
->seek
= seek_forward
;
197 stream
->type
= STREAMTYPE_STREAM
; // Must be move to STREAMTYPE_FILE
198 stream
->flags
|= MP_STREAM_SEEK_FW
;
199 } else if(len
>= 0) {
201 stream
->end_pos
= len
;
202 stream
->type
= STREAMTYPE_FILE
;
205 mp_msg(MSGT_OPEN
,MSGL_V
,"[file] File size is %"PRId64
" bytes\n", (int64_t)len
);
208 stream
->fill_buffer
= fill_buffer
;
209 stream
->write_buffer
= write_buffer
;
210 stream
->control
= control
;
211 stream
->read_chunk
= 64*1024;
213 m_struct_free(&stream_opts
,opts
);
217 const stream_info_t stream_info_file
= {
221 "based on the code from ??? (probably Arpi)",
223 { "file", "", NULL
},
225 1 // Urls are an option string