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 <glib.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "debug.h"
25 #include "probe-buffer.h"
26 
27 typedef struct
28 {
30  unsigned char buffer[16384];
31  int filled, at;
32 }
34 
35 static int probe_buffer_fclose (VFSFile * file)
36 {
37  ProbeBuffer * p = vfs_get_handle (file);
38 
39  int ret = vfs_fclose (p->file);
40  g_slice_free (ProbeBuffer, p);
41  return ret;
42 }
43 
44 static void increase_buffer (ProbeBuffer * p, int64_t size)
45 {
46  size = (size + 0xFF) & ~0xFF;
47 
48  if (size > sizeof p->buffer)
49  size = sizeof p->buffer;
50 
51  if (p->filled < size)
52  p->filled += vfs_fread (p->buffer + p->filled, 1, size - p->filled,
53  p->file);
54 }
55 
56 static int64_t probe_buffer_fread (void * buffer, int64_t size, int64_t count,
57  VFSFile * file)
58 {
59  ProbeBuffer * p = vfs_get_handle (file);
60 
61  increase_buffer (p, p->at + size * count);
62  int readed = (size > 0) ? MIN (count, (p->filled - p->at) / size) : 0;
63  memcpy (buffer, p->buffer + p->at, size * readed);
64 
65  p->at += size * readed;
66  return readed;
67 }
68 
69 static int64_t probe_buffer_fwrite (const void * data, int64_t size, int64_t count,
70  VFSFile * file)
71 {
72  /* not implemented */
73  return 0;
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;
88 
89  if (whence == SEEK_CUR)
90  offset += p->at;
91 
92  g_return_val_if_fail (offset >= 0, -1);
93  increase_buffer (p, offset);
94 
95  if (offset > p->filled)
96  return -1;
97 
98  p->at = offset;
99  return 0;
100 }
101 
102 static int probe_buffer_ungetc (int c, VFSFile * file)
103 {
104  return (! probe_buffer_fseek (file, -1, SEEK_CUR)) ? c : EOF;
105 }
106 
107 static void probe_buffer_rewind (VFSFile * file)
108 {
109  probe_buffer_fseek (file, 0, SEEK_SET);
110 }
111 
112 static int64_t probe_buffer_ftell (VFSFile * file)
113 {
114  return ((ProbeBuffer *) vfs_get_handle (file))->at;
115 }
116 
118 {
119  ProbeBuffer * p = vfs_get_handle (file);
120  return (p->at < p->filled) ? FALSE : vfs_feof (p->file);
121 }
122 
123 static int probe_buffer_ftruncate (VFSFile * file, int64_t size)
124 {
125  /* not implemented */
126  return -1;
127 }
128 
129 static int64_t probe_buffer_fsize (VFSFile * file)
130 {
131  return vfs_fsize (((ProbeBuffer *) vfs_get_handle (file))->file);
132 }
133 
134 static char * probe_buffer_get_metadata (VFSFile * file, const char * field)
135 {
136  return vfs_get_metadata (((ProbeBuffer *) vfs_get_handle (file))->file, field);
137 }
138 
140 {
141  .vfs_fopen_impl = NULL,
142  .vfs_fclose_impl = probe_buffer_fclose,
143  .vfs_fread_impl = probe_buffer_fread,
144  .vfs_fwrite_impl = probe_buffer_fwrite,
145  .vfs_getc_impl = probe_buffer_getc,
146  .vfs_ungetc_impl = probe_buffer_ungetc,
147  .vfs_fseek_impl = probe_buffer_fseek,
148  .vfs_rewind_impl = probe_buffer_rewind,
149  .vfs_ftell_impl = probe_buffer_ftell,
150  .vfs_feof_impl = probe_buffer_feof,
151  .vfs_ftruncate_impl = probe_buffer_ftruncate,
152  .vfs_fsize_impl = probe_buffer_fsize,
153  .vfs_get_metadata_impl = probe_buffer_get_metadata,
154 };
155 
157 {
158  VFSFile * file = vfs_fopen (filename, "r");
159 
160  if (! file)
161  return NULL;
162 
163  ProbeBuffer * p = g_slice_new (ProbeBuffer);
164  p->file = file;
165  p->filled = 0;
166  p->at = 0;
167 
168  return vfs_new (filename, & probe_buffer_table, p);
169 }