Add Russian translation provided by Валерий Крувялис <valkru@mail.ru>
[xiph-mirror.git] / vorbis-tools / ogg123 / file_transport.c
blobf557e89930e67ec286c58ee553b57792316f7a95
1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2001 *
9 * by Stan Seibert <volsung@xiph.org> AND OTHER CONTRIBUTORS *
10 * http://www.xiph.org/ *
11 * *
12 ********************************************************************
14 last mod: $Id$
16 ********************************************************************/
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
26 #include "transport.h"
27 #include "i18n.h"
30 typedef struct file_private_t {
31 FILE *fp;
32 data_source_stats_t stats;
33 int seekable;
34 } file_private_t;
37 transport_t file_transport; /* Forward declaration */
40 int file_can_transport (char *source_string)
42 return 1; /* The file transport is tested last, so always try it */
45 data_source_t* file_open (char *source_string, ogg123_options_t *ogg123_opts)
47 data_source_t *source;
48 file_private_t *private;
50 /* Allocate data source structures */
51 source = malloc(sizeof(data_source_t));
52 private = malloc(sizeof(file_private_t));
54 if (source != NULL && private != NULL) {
55 source->source_string = strdup(source_string);
56 source->transport = &file_transport;
57 source->private = private;
59 private->seekable = 1;
60 private->stats.transfer_rate = 0;
61 private->stats.bytes_read = 0;
62 private->stats.input_buffer_used = 0;
63 } else {
64 fprintf(stderr, _("ERROR: Out of memory.\n"));
65 exit(1);
68 /* Open file */
69 if (strcmp(source_string, "-") == 0) {
70 private->fp = stdin;
71 private->seekable = 0;
72 } else
73 private->fp = fopen(source_string, "r");
75 if (private->fp == NULL) {
76 free(source->source_string);
77 free(private);
78 free(source);
80 return NULL;
83 return source;
87 int file_peek (data_source_t *source, void *ptr, size_t size, size_t nmemb)
89 file_private_t *private = source->private;
90 FILE *fp = private->fp;
91 int items;
92 long start;
94 if (!private->seekable) return 0;
96 /* Record where we are */
97 start = ftell(fp);
99 items = fread(ptr, size, nmemb, fp);
101 /* Now go back so we maintain the peek() semantics */
102 if (fseek(fp, start, SEEK_SET) != 0)
103 items = 0; /* Flag error condition since we couldn't seek back to
104 the beginning */
106 return items;
110 int file_read (data_source_t *source, void *ptr, size_t size, size_t nmemb)
112 file_private_t *private = source->private;
113 FILE *fp = private->fp;
114 int bytes_read;
116 bytes_read = fread(ptr, size, nmemb, fp);
118 if (bytes_read > 0)
119 private->stats.bytes_read += bytes_read;
121 return bytes_read;
125 int file_seek (data_source_t *source, long offset, int whence)
127 file_private_t *private = source->private;
128 FILE *fp = private->fp;
130 if (!private->seekable) return -1;
132 return fseek(fp, offset, whence);
136 data_source_stats_t * file_statistics (data_source_t *source)
138 file_private_t *private = source->private;
140 return malloc_data_source_stats(&private->stats);
144 long file_tell (data_source_t *source)
146 file_private_t *private = source->private;
147 FILE *fp = private->fp;
149 if (!private->seekable) return -1;
151 return ftell(fp);
155 void file_close (data_source_t *source)
157 file_private_t *private = source->private;
158 FILE *fp = private->fp;
160 fclose(fp);
162 free(source->source_string);
163 free(source->private);
164 free(source);
168 transport_t file_transport = {
169 "file",
170 &file_can_transport,
171 &file_open,
172 &file_peek,
173 &file_read,
174 &file_seek,
175 &file_statistics,
176 &file_tell,
177 &file_close