Code Coverage Report for src/api/open-buffer.c


Hit Total Coverage
Lines: 31 31 100.0%
Branches: 72 72 100.0%

1 /*
2 * libnogg: a decoder library for Ogg Vorbis streams
3 * Copyright (c) 2014-2024 Andrew Church <achurch@achurch.org>
4 *
5 * This software may be copied and redistributed under certain conditions;
6 * see the file "COPYING" in the source code distribution for details.
7 * NO WARRANTY is provided with this software.
8 */
9
10 #include "include/nogg.h"
11 #include "src/common.h"
12 #include "src/util/open.h"
13
14 #include <stdlib.h>
15 #include <string.h>
16
17 /*************************************************************************/
18 /******************** Buffer data type and callbacks *********************/
19 /*************************************************************************/
20
21 /* Parameter block passed to buffer_open(). */
22 typedef struct vorbis_buffer_info_t {
23 const void *buffer;
24 int64_t length;
25 } vorbis_buffer_info_t;
26
27 /* Internal callback (see comments at open_params_t.open_callback).
28 * The buffer pointer is passed in the opaque parameter; the buffer length
29 * will separately be stored to vorbis->data_length. */
30 static void *buffer_open(vorbis_t *handle, void *callback_data)
31 {
32 vorbis_buffer_info_t *buffer_info = (vorbis_buffer_info_t *)callback_data;
33 handle->buffer_data = buffer_info->buffer;
34 handle->data_length = buffer_info->length;
35 handle->buffer_read_pos = 0;
36 return handle;
37 }
38
39 static int64_t buffer_length(void *opaque)
40 {
41 vorbis_t *handle = (vorbis_t *)opaque;
42 return handle->data_length;
43 }
44
45 static int64_t buffer_tell(void *opaque)
46 {
47 vorbis_t *handle = (vorbis_t *)opaque;
48 return handle->buffer_read_pos;
49 }
50
51 static void buffer_seek(void *opaque, int64_t offset)
52 {
53 vorbis_t *handle = (vorbis_t *)opaque;
54 handle->buffer_read_pos = offset;
55 }
56
57 static int32_t buffer_read(void *opaque, void *buffer, int32_t length)
58 {
59 vorbis_t *handle = (vorbis_t *)opaque;
60 (18/18) if (length > handle->data_length - handle->buffer_read_pos) {
61 length = (int32_t)(handle->data_length - handle->buffer_read_pos);
62 }
63 memcpy(buffer, handle->buffer_data + handle->buffer_read_pos, length);
64 handle->buffer_read_pos += length;
65 return length;
66 }
67
68 static const vorbis_callbacks_t buffer_callbacks = {
69 .length = buffer_length,
70 .tell = buffer_tell,
71 .seek = buffer_seek,
72 .read = buffer_read,
73 };
74
75 /*************************************************************************/
76 /*************************** Interface routine ***************************/
77 /*************************************************************************/
78
79 vorbis_t *vorbis_open_buffer(
80 const void *buffer, int64_t length, unsigned int options,
81 vorbis_error_t *error_ret)
82 {
83 (36/36) if (!buffer || length < 0) {
84 (18/18) if (error_ret) {
85 *error_ret = VORBIS_ERROR_INVALID_ARGUMENT;
86 }
87 return NULL;
88 }
89
90 vorbis_buffer_info_t buffer_info = {.buffer = buffer, .length = length};
91 return open_common(
92 &(open_params_t){.callbacks = &buffer_callbacks,
93 .callback_data = &buffer_info,
94 .open_callback = buffer_open,
95 .options = options,
96 .packet_mode = false},
97 error_ret);
98 }
99
100 /*************************************************************************/
101 /*************************************************************************/