1b815c7f3Sopenharmony_ci#ifndef SNDFILE_FUZZ_HEADER_H
2b815c7f3Sopenharmony_ci#define SNDFILE_FUZZ_HEADER_H
3b815c7f3Sopenharmony_ci
4b815c7f3Sopenharmony_citypedef struct
5b815c7f3Sopenharmony_ci{
6b815c7f3Sopenharmony_ci  sf_count_t offset ;
7b815c7f3Sopenharmony_ci  sf_count_t length ;
8b815c7f3Sopenharmony_ci  const unsigned char *data ;
9b815c7f3Sopenharmony_ci} VIO_DATA ;
10b815c7f3Sopenharmony_ci
11b815c7f3Sopenharmony_cistatic sf_count_t vfget_filelen (void *user_data)
12b815c7f3Sopenharmony_ci{  VIO_DATA *vf = (VIO_DATA *)user_data ;
13b815c7f3Sopenharmony_ci   return vf->length ;
14b815c7f3Sopenharmony_ci}
15b815c7f3Sopenharmony_ci
16b815c7f3Sopenharmony_cistatic sf_count_t vfseek (sf_count_t offset, int whence, void *user_data)
17b815c7f3Sopenharmony_ci{
18b815c7f3Sopenharmony_ci  VIO_DATA *vf = (VIO_DATA *)user_data ;
19b815c7f3Sopenharmony_ci  sf_count_t new_offset ;
20b815c7f3Sopenharmony_ci
21b815c7f3Sopenharmony_ci  switch (whence)
22b815c7f3Sopenharmony_ci  {   case SEEK_SET :
23b815c7f3Sopenharmony_ci        new_offset = offset ;
24b815c7f3Sopenharmony_ci        break ;
25b815c7f3Sopenharmony_ci
26b815c7f3Sopenharmony_ci    case SEEK_CUR :
27b815c7f3Sopenharmony_ci        new_offset = vf->offset + offset ;
28b815c7f3Sopenharmony_ci        break ;
29b815c7f3Sopenharmony_ci
30b815c7f3Sopenharmony_ci    case SEEK_END :
31b815c7f3Sopenharmony_ci        new_offset = vf->length + offset ;
32b815c7f3Sopenharmony_ci        break ;
33b815c7f3Sopenharmony_ci
34b815c7f3Sopenharmony_ci    default :
35b815c7f3Sopenharmony_ci        break ;
36b815c7f3Sopenharmony_ci  }
37b815c7f3Sopenharmony_ci
38b815c7f3Sopenharmony_ci  /* Ensure you can't seek outside the data */
39b815c7f3Sopenharmony_ci  if (new_offset > vf->length)
40b815c7f3Sopenharmony_ci  {  /* Trying to seek past the end of the data */
41b815c7f3Sopenharmony_ci     printf("vf overseek: new_offset(%" PRId64 ") > vf->length(%" PRId64 ");"
42b815c7f3Sopenharmony_ci            "  whence(%d), vf->offset(%" PRId64 "), offset(%" PRId64 ")\n",
43b815c7f3Sopenharmony_ci            new_offset, vf->length, whence, vf->offset, offset) ;
44b815c7f3Sopenharmony_ci     new_offset = vf->length ;
45b815c7f3Sopenharmony_ci  }
46b815c7f3Sopenharmony_ci  else if (new_offset < 0)
47b815c7f3Sopenharmony_ci  {  /* Trying to seek before the start of the data */
48b815c7f3Sopenharmony_ci     printf("vf underseek: new_offset(%" PRId64 ") < 0;  whence(%d), vf->offset"
49b815c7f3Sopenharmony_ci            "(%" PRId64 "), vf->length(%" PRId64 "), offset(%" PRId64 ")\n",
50b815c7f3Sopenharmony_ci            new_offset, whence, vf->offset, vf->length, offset) ;
51b815c7f3Sopenharmony_ci     new_offset = 0 ;
52b815c7f3Sopenharmony_ci  }
53b815c7f3Sopenharmony_ci  vf->offset = new_offset ;
54b815c7f3Sopenharmony_ci
55b815c7f3Sopenharmony_ci  return vf->offset ;
56b815c7f3Sopenharmony_ci}
57b815c7f3Sopenharmony_ci
58b815c7f3Sopenharmony_cistatic sf_count_t vfread (void *ptr, sf_count_t count, void *user_data)
59b815c7f3Sopenharmony_ci{  VIO_DATA *vf = (VIO_DATA *)user_data ;
60b815c7f3Sopenharmony_ci
61b815c7f3Sopenharmony_ci   if (vf->offset + count > vf->length)
62b815c7f3Sopenharmony_ci     count = vf->length - vf->offset ;
63b815c7f3Sopenharmony_ci
64b815c7f3Sopenharmony_ci   memcpy(ptr, vf->data + vf->offset, count) ;
65b815c7f3Sopenharmony_ci   vf->offset += count ;
66b815c7f3Sopenharmony_ci
67b815c7f3Sopenharmony_ci   return count ;
68b815c7f3Sopenharmony_ci}
69b815c7f3Sopenharmony_ci
70b815c7f3Sopenharmony_cistatic sf_count_t vfwrite (const void *ptr, sf_count_t count, void *user_data)
71b815c7f3Sopenharmony_ci{
72b815c7f3Sopenharmony_ci  (void)ptr ;
73b815c7f3Sopenharmony_ci  (void)count ;
74b815c7f3Sopenharmony_ci  (void)user_data ;
75b815c7f3Sopenharmony_ci
76b815c7f3Sopenharmony_ci  // Cannot write to this virtual file.
77b815c7f3Sopenharmony_ci  return 0;
78b815c7f3Sopenharmony_ci}
79b815c7f3Sopenharmony_ci
80b815c7f3Sopenharmony_cistatic sf_count_t vftell (void *user_data)
81b815c7f3Sopenharmony_ci{ VIO_DATA *vf = (VIO_DATA *)user_data ;
82b815c7f3Sopenharmony_ci
83b815c7f3Sopenharmony_ci  return vf->offset ;
84b815c7f3Sopenharmony_ci}
85b815c7f3Sopenharmony_ci
86b815c7f3Sopenharmony_ciint sf_init_file(const uint8_t *data,
87b815c7f3Sopenharmony_ci                size_t size,
88b815c7f3Sopenharmony_ci                SNDFILE **sndfile,
89b815c7f3Sopenharmony_ci                VIO_DATA *vio_data,
90b815c7f3Sopenharmony_ci                SF_VIRTUAL_IO *vio, SF_INFO *sndfile_info)
91b815c7f3Sopenharmony_ci{  float* read_buffer = NULL ;
92b815c7f3Sopenharmony_ci
93b815c7f3Sopenharmony_ci   // Initialize the virtual IO structure.
94b815c7f3Sopenharmony_ci   vio->get_filelen = vfget_filelen ;
95b815c7f3Sopenharmony_ci   vio->seek = vfseek ;
96b815c7f3Sopenharmony_ci   vio->read = vfread ;
97b815c7f3Sopenharmony_ci   vio->write = vfwrite ;
98b815c7f3Sopenharmony_ci   vio->tell = vftell ;
99b815c7f3Sopenharmony_ci
100b815c7f3Sopenharmony_ci   // Initialize the VIO user data.
101b815c7f3Sopenharmony_ci   vio_data->data = data ;
102b815c7f3Sopenharmony_ci   vio_data->length = size ;
103b815c7f3Sopenharmony_ci   vio_data->offset = 0 ;
104b815c7f3Sopenharmony_ci
105b815c7f3Sopenharmony_ci   memset(sndfile_info, 0, sizeof(SF_INFO)) ;
106b815c7f3Sopenharmony_ci
107b815c7f3Sopenharmony_ci   // Try and open the virtual file.
108b815c7f3Sopenharmony_ci   *sndfile = sf_open_virtual(vio, SFM_READ, sndfile_info, vio_data) ;
109b815c7f3Sopenharmony_ci
110b815c7f3Sopenharmony_ci   if (sndfile_info->channels == 0)
111b815c7f3Sopenharmony_ci		 return -1 ;
112b815c7f3Sopenharmony_ci
113b815c7f3Sopenharmony_ci   if (sndfile_info->channels > 1024 * 1024)
114b815c7f3Sopenharmony_ci		 return -1 ;
115b815c7f3Sopenharmony_ci
116b815c7f3Sopenharmony_ci   return 0;
117b815c7f3Sopenharmony_ci}
118b815c7f3Sopenharmony_ci
119b815c7f3Sopenharmony_ci#endif
120