Coverage Report

Created: 2025-11-16 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwmf/src/bbuf.c
Line
Count
Source
1
/* libwmf (bbuf.c): library for wmf conversion
2
   Copyright (C) 2000,2001 Francis James Franklin
3
4
   The libwmf Library is free software; you can redistribute it and/or
5
   modify it under the terms of the GNU Library General Public License as
6
   published by the Free Software Foundation; either version 2 of the
7
   License, or (at your option) any later version.
8
9
   The libwmf Library 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 GNU
12
   Library General Public License for more details.
13
14
   You should have received a copy of the GNU Library General Public
15
   License along with the libwmf Library; see the file COPYING.  If not,
16
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
   Boston, MA 02111-1307, USA.  */
18
19
20
#ifdef HAVE_CONFIG_H
21
#include "wmfconfig.h"
22
#endif
23
24
#include <stdio.h>
25
26
#include "wmfdefs.h"
27
28
#include "bbuf.h"
29
30
/**
31
 * Set custom metafile input-stream handler functions.
32
 * 
33
 * @param API       the API handle
34
 * @param fp_read   function to read a byte
35
 * @param fp_seek   function to set position
36
 * @param fp_tell   function to get position
37
 * @param user_data handle for user data
38
 * 
39
 * \b libwmf has simple methods for reading either from file or from memory, but many applications will want
40
 * to use customized variants of these. wmf_bbuf_input() enables this.
41
 * 
42
 * @verbatim
43
typedef int  (*wmfRead) (void* user_data);
44
typedef int  (*wmfSeek) (void* user_data,long position);
45
typedef long (*wmfTell) (void* user_data);
46
@endverbatim
47
 * 
48
 * \b wmfRead returns unsigned char cast to int, or EOF (cf. fgetc())
49
 * 
50
 * \b wmfSeek returns (-1) on error, otherwise 0 (cf. fseek())
51
 * 
52
 * \b wmfTell returns (-1) on error, otherwise current position (cf. ftell())
53
 * 
54
 * @return Returns the library error state (\b wmf_E_None on success).
55
 *         Possible library error state of \b wmf_E_Glitch, if any of the three functions is zero.
56
 */
57
wmf_error_t wmf_bbuf_input (wmfAPI* API,wmfRead fp_read,wmfSeek fp_seek,wmfTell fp_tell,void* user_data)
58
11.9k
{ if (ERR (API)) return (API->err);
59
60
11.9k
  if ((fp_read == 0) || (fp_seek == 0) || (fp_tell == 0))
61
0
  { WMF_ERROR (API,"wmf_bbuf_input: null arg. given unexpectedly!");
62
0
    API->err = wmf_E_Glitch;
63
0
  }
64
11.9k
  else
65
11.9k
  { API->buffer_data = user_data;
66
67
11.9k
    API->bbuf.read = fp_read;
68
11.9k
    API->bbuf.seek = fp_seek;
69
11.9k
    API->bbuf.tell = fp_tell;
70
11.9k
  }
71
72
11.9k
  return (API->err);
73
11.9k
}
74
75
/**
76
 * Open file as metafile.
77
 * 
78
 * @param API  the API handle
79
 * @param file file name
80
 * 
81
 * Simple method for reading from file.
82
 * 
83
 * @return Returns the library error state (\b wmf_E_None on success).
84
 *         Possible library error states of \b wmf_E_Glitch or \b wmf_E_BadFile.
85
 */
86
wmf_error_t wmf_file_open (wmfAPI* API,const char* file)
87
0
{ wmfBBufFileInfo* file_info = 0;
88
89
0
  if (ERR (API)) return (API->err);
90
91
0
  if (API->buffer_data)
92
0
  { WMF_ERROR (API,"wmf_file_open: input stream already open!");
93
0
    API->err = wmf_E_Glitch;
94
0
    return (API->err);
95
0
  }
96
97
0
  file_info = (wmfBBufFileInfo*) wmf_malloc (API,sizeof (wmfBBufFileInfo));
98
99
0
  if (ERR (API)) return (API->err);
100
101
0
  if ((file_info->file = fopen (file,"rb")) == 0)
102
0
  { WMF_ERROR (API,"wmf_file_open: unable to open file for reading.");
103
0
    wmf_free (API,file_info);
104
0
    API->err = wmf_E_BadFile;
105
0
    return (API->err);
106
0
  }
107
108
0
  wmf_bbuf_input (API,wmf_file_read,wmf_file_seek,wmf_file_tell,(void*) file_info);
109
110
0
  if (ERR (API))
111
0
  { wmf_file_close (API);
112
0
    return (API->err);
113
0
  }
114
115
0
  API->flags |= API_FILE_OPEN;
116
117
0
  return (API->err);
118
0
}
119
120
/**
121
 * Close metafile input file stream.
122
 * 
123
 * @param API the API handle
124
 * 
125
 * @return Returns the library error state (\b wmf_E_None on success).
126
 *         Possible library error state of \b wmf_E_Glitch.
127
 */
128
wmf_error_t wmf_file_close (wmfAPI* API)
129
0
{ wmfBBufFileInfo* file_info = (wmfBBufFileInfo*) (API->buffer_data);
130
131
0
  if ((API->buffer_data == 0) || ((API->flags & API_FILE_OPEN) == 0))
132
0
  { WMF_ERROR (API,"wmf_file_close: attempt to close unopened stream!");
133
0
    API->err = wmf_E_Glitch;
134
0
    return (API->err);
135
0
  }
136
137
0
  fclose (file_info->file);
138
139
0
  API->flags &= ~API_FILE_OPEN;
140
141
0
  wmf_free (API,API->buffer_data);
142
143
0
  API->buffer_data = 0;
144
145
0
  API->bbuf.read = 0;
146
0
  API->bbuf.seek = 0;
147
0
  API->bbuf.tell = 0;
148
149
0
  return (API->err);
150
0
}
151
152
/**
153
 * @internal
154
 */
155
int wmf_file_read (void* user_data)
156
0
{ wmfBBufFileInfo* file_info = (wmfBBufFileInfo*) user_data;
157
158
0
  return (fgetc (file_info->file));
159
0
}
160
161
/**
162
 * @internal
163
 */
164
int wmf_file_seek (void* user_data,long pos)
165
0
{ wmfBBufFileInfo* file_info = (wmfBBufFileInfo*) user_data;
166
167
0
  return (fseek (file_info->file,pos,SEEK_SET));
168
0
}
169
170
/**
171
 * @internal
172
 */
173
long wmf_file_tell (void* user_data)
174
0
{ wmfBBufFileInfo* file_info = (wmfBBufFileInfo*) user_data;
175
176
0
  return (ftell (file_info->file));
177
0
}
178
179
/**
180
 * Open metafile in memory.
181
 * 
182
 * @param API    the API handle
183
 * @param mem    the metafile in memory
184
 * @param length the length in bytes of metafile data
185
 * 
186
 * Simple method for reading from memory as array of unsigned char.
187
 * 
188
 * @return Returns the library error state (\b wmf_E_None on success).
189
 *         Possible library error state of \b wmf_E_Glitch.
190
 */
191
wmf_error_t wmf_mem_open (wmfAPI* API,unsigned char* mem,long length)
192
0
{ wmfBBufMemInfo* mem_info = 0;
193
194
0
  if (ERR (API)) return (API->err);
195
196
0
  if (API->buffer_data)
197
0
  { WMF_ERROR (API,"wmf_mem_open: input stream already open!");
198
0
    API->err = wmf_E_Glitch;
199
0
    return (API->err);
200
0
  }
201
202
0
  if ((mem == 0) || (length <= 0))
203
0
  { WMF_ERROR (API,"wmf_mem_open: null or improper buffer!");
204
0
    API->err = wmf_E_Glitch;
205
0
    return (API->err);
206
0
  }
207
208
0
  mem_info = (wmfBBufMemInfo*) wmf_malloc (API,sizeof (wmfBBufMemInfo));
209
210
0
  if (ERR (API)) return (API->err);
211
212
0
  mem_info->mem = mem;
213
0
  mem_info->ptr = mem;
214
215
0
  mem_info->pos = 0;
216
0
  mem_info->length = length;
217
218
0
  wmf_bbuf_input (API,wmf_mem_read,wmf_mem_seek,wmf_mem_tell,(void*) mem_info);
219
220
0
  if (ERR (API))
221
0
  { wmf_mem_close (API);
222
0
    return (API->err);
223
0
  }
224
225
0
  return (API->err);
226
0
}
227
228
/**
229
 * Close metafile input memory stream.
230
 * 
231
 * @param API the API handle
232
 * 
233
 * @return Returns the library error state (\b wmf_E_None on success).
234
 */
235
wmf_error_t wmf_mem_close (wmfAPI* API)
236
0
{ wmf_free (API,API->buffer_data);
237
238
0
  API->buffer_data = 0;
239
240
0
  API->bbuf.read = 0;
241
0
  API->bbuf.seek = 0;
242
0
  API->bbuf.tell = 0;
243
244
0
  return (API->err);
245
0
}
246
247
/**
248
 * @internal
249
 */
250
int wmf_mem_read (void* user_data)
251
0
{ int byte = EOF;
252
253
0
  wmfBBufMemInfo* mem_info = (wmfBBufMemInfo*) user_data;
254
255
0
  if (mem_info->pos < mem_info->length)
256
0
  { byte = (int) (*(mem_info->ptr));
257
258
0
    mem_info->ptr++;
259
0
    mem_info->pos++;
260
0
  }
261
262
0
  return (byte);
263
0
}
264
265
/**
266
 * @internal
267
 */
268
int wmf_mem_seek (void* user_data,long pos)
269
0
{ wmfBBufMemInfo* mem_info = (wmfBBufMemInfo*) user_data;
270
271
0
  if ((pos < 0) || (pos >= mem_info->length)) return (-1);
272
273
0
  mem_info->ptr = mem_info->mem + pos;
274
0
  mem_info->pos = pos;
275
276
0
  return (0);
277
0
}
278
279
/**
280
 * @internal
281
 */
282
long wmf_mem_tell (void* user_data)
283
0
{ wmfBBufMemInfo* mem_info = (wmfBBufMemInfo*) user_data;
284
285
0
  return (mem_info->pos);
286
0
}