Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
probe-buffer.c
Go to the documentation of this file.
1 /*
2  * probe-buffer.c
3  * Copyright 2010-2011 John Lindgren
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions, and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions, and the following disclaimer in the documentation
13  * provided with the distribution.
14  *
15  * This software is provided "as is" and without any warranty, express or
16  * implied. In no event shall the authors be liable for any damages arising from
17  * the use of this software.
18  */
19 
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "debug.h"
24 #include "probe-buffer.h"
25 
26 #define BUFSIZE (256 * 1024)
27 
28 typedef struct
29 {
31  int filled, at;
32  unsigned char buffer[BUFSIZE];
33 }
35 
36 static int probe_buffer_fclose (VFSFile * file)
37 {
38  ProbeBuffer * p = vfs_get_handle (file);
39 
40  int ret = vfs_fclose (p->file);
41  free (p);
42  return ret;
43 }
44 
45 static void increase_buffer (ProbeBuffer * p, int64_t size)
46 {
47  size = (size + 0xFF) & ~0xFF;
48 
49  if (size > sizeof p->buffer)
50  size = sizeof p->buffer;
51 
52  if (p->filled < size)
53  p->filled += vfs_fread (p->buffer + p->filled, 1, size - p->filled,
54  p->file);
55 }
56 
57 static int64_t probe_buffer_fread (void * buffer, int64_t size, int64_t count,
58  VFSFile * file)
59 {
60  ProbeBuffer * p = vfs_get_handle (file);
61 
62  increase_buffer (p, p->at + size * count);
63  int readed = (size > 0) ? MIN (count, (p->filled - p->at) / size) : 0;
64  memcpy (buffer, p->buffer + p->at, size * readed);
65 
66  p->at += size * readed;
67  return readed;
68 }
69 
70 static int64_t probe_buffer_fwrite (const void * data, int64_t size, int64_t count,
71  VFSFile * file)
72 {
73  return 0; /* not allowed */
74 }
75 
76 static int probe_buffer_getc (VFSFile * file)
77 {
78  unsigned char c;
79  return (probe_buffer_fread (& c, 1, 1, file) == 1) ? c : EOF;
80 }
81 
82 static int probe_buffer_fseek (VFSFile * file, int64_t offset, int whence)
83 {
84  ProbeBuffer * p = vfs_get_handle (file);
85 
86  if (whence == SEEK_END)
87  return -1; /* not allowed */
88 
89  if (whence == SEEK_CUR)
90  offset += p->at;
91 
92  if (offset < 0)
93  return -1;
94 
95  increase_buffer (p, offset);
96 
97  if (offset > p->filled)
98  return -1;
99 
100  p->at = offset;
101  return 0;
102 }
103 
104 static int probe_buffer_ungetc (int c, VFSFile * file)
105 {
106  return (! probe_buffer_fseek (file, -1, SEEK_CUR)) ? c : EOF;
107 }
108 
109 static void probe_buffer_rewind (VFSFile * file)
110 {
111  probe_buffer_fseek (file, 0, SEEK_SET);
112 }
113 
114 static int64_t probe_buffer_ftell (VFSFile * file)
115 {
116  return ((ProbeBuffer *) vfs_get_handle (file))->at;
117 }
118 
120 {
121  ProbeBuffer * p = vfs_get_handle (file);
122 
123  if (p->at < p->filled)
124  return FALSE;
125  if (p->at == sizeof p->buffer)
126  return TRUE;
127 
128  return vfs_feof (p->file);
129 }
130 
131 static int probe_buffer_ftruncate (VFSFile * file, int64_t size)
132 {
133  return -1; /* not allowed */
134 }
135 
136 static int64_t probe_buffer_fsize (VFSFile * file)
137 {
138  ProbeBuffer * p = vfs_get_handle (file);
139 
140  int64_t size = vfs_fsize (p->file);
141  return MIN (size, sizeof p->buffer);
142 }
143 
144 static char * probe_buffer_get_metadata (VFSFile * file, const char * field)
145 {
146  return vfs_get_metadata (((ProbeBuffer *) vfs_get_handle (file))->file, field);
147 }
148 
150 {
151  .vfs_fopen_impl = NULL,
152  .vfs_fclose_impl = probe_buffer_fclose,
153  .vfs_fread_impl = probe_buffer_fread,
154  .vfs_fwrite_impl = probe_buffer_fwrite,
155  .vfs_getc_impl = probe_buffer_getc,
156  .vfs_ungetc_impl = probe_buffer_ungetc,
157  .vfs_fseek_impl = probe_buffer_fseek,
158  .vfs_rewind_impl = probe_buffer_rewind,
159  .vfs_ftell_impl = probe_buffer_ftell,
160  .vfs_feof_impl = probe_buffer_feof,
161  .vfs_ftruncate_impl = probe_buffer_ftruncate,
162  .vfs_fsize_impl = probe_buffer_fsize,
163  .vfs_get_metadata_impl = probe_buffer_get_metadata,
164 };
165 
167 {
168  VFSFile * file = vfs_fopen (filename, "r");
169 
170  if (! file)
171  return NULL;
172 
173  ProbeBuffer * p = malloc (sizeof (ProbeBuffer));
174  p->file = file;
175  p->filled = 0;
176  p->at = 0;
177 
178  return vfs_new (filename, & probe_buffer_table, p);
179 }