Coverage Report

Created: 2026-09-28 07:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/contrib/contrib-build/game-music-emu/gme/Gme_File.cpp
Line
Count
Source
1
// Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
2
3
#include "Gme_File.h"
4
5
#include "blargg_endian.h"
6
#include <string.h>
7
8
/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
9
can redistribute it and/or modify it under the terms of the GNU Lesser
10
General Public License as published by the Free Software Foundation; either
11
version 2.1 of the License, or (at your option) any later version. This
12
module is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15
details. You should have received a copy of the GNU Lesser General Public
16
License along with this module; if not, write to the Free Software Foundation,
17
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
18
19
#include "blargg_source.h"
20
21
const char* const gme_wrong_file_type = "Wrong file type for this emulator";
22
23
void Gme_File::clear_playlist()
24
10.4k
{
25
10.4k
  playlist.clear();
26
10.4k
  clear_playlist_();
27
10.4k
  track_count_ = raw_track_count_;
28
10.4k
}
29
30
void Gme_File::unload()
31
10.4k
{
32
10.4k
  clear_playlist(); // *before* clearing track count
33
10.4k
  track_count_     = 0;
34
10.4k
  raw_track_count_ = 0;
35
10.4k
  file_data.clear();
36
10.4k
}
37
38
Gme_File::Gme_File()
39
3.10k
{
40
3.10k
  type_         = 0;
41
3.10k
  user_data_    = 0;
42
3.10k
  user_cleanup_ = 0;
43
3.10k
  unload(); // clears fields
44
3.10k
  blargg_verify_byte_order(); // used by most emulator types, so save them the trouble
45
3.10k
}
46
47
Gme_File::~Gme_File()
48
3.10k
{
49
3.10k
  if ( user_cleanup_ )
50
0
    user_cleanup_( user_data_ );
51
3.10k
}
52
53
blargg_err_t Gme_File::load_mem_( byte const* data, long size )
54
0
{
55
0
  require( data != file_data.begin() ); // load_mem_() or load_() must be overridden
56
0
  Mem_File_Reader in( data, size );
57
0
  return load_( in );
58
0
}
59
60
blargg_err_t Gme_File::load_( Data_Reader& in )
61
635
{
62
635
  RETURN_ERR( file_data.resize( in.remain() ) );
63
635
  RETURN_ERR( in.read( file_data.begin(), file_data.size() ) );
64
635
  if ( type()->track_count == 1 )
65
605
  {
66
605
    RETURN_ERR( tracks.resize( 2 ) );
67
605
    tracks[0] = 0, tracks[1] = file_data.size();
68
605
  }
69
635
  return load_mem_( file_data.begin(), file_data.size() );
70
635
}
71
72
// public load functions call this at beginning
73
3.10k
void Gme_File::pre_load() { unload(); }
74
75
0
void Gme_File::post_load_() { }
76
77
// public load functions call this at end
78
blargg_err_t Gme_File::post_load( blargg_err_t err )
79
3.10k
{
80
3.10k
  if ( !track_count() )
81
651
    set_track_count( type()->track_count );
82
3.10k
  if ( !err )
83
3.00k
    post_load_();
84
102
  else
85
102
    unload();
86
87
3.10k
  return err;
88
3.10k
}
89
90
// Public load functions
91
92
blargg_err_t Gme_File::load_mem( void const* in, long size )
93
0
{
94
0
  pre_load();
95
0
  return post_load( load_mem_( (byte const*) in, size ) );
96
0
}
97
98
blargg_err_t Gme_File::load_tracks( void const* in, long* sizes, int count )
99
0
{
100
0
  pre_load();
101
0
  if ( type()->track_count != 1 )
102
0
    return "File type must have a fixed track count of 1";
103
0
  set_track_count( count );
104
0
  RETURN_ERR( tracks.resize( count + 1 ) );
105
0
  long size = 0;
106
0
  for ( int i = 0; i < count; size += sizes[i++] )
107
0
    tracks[i] = size;
108
0
  tracks[count] = size;
109
0
  RETURN_ERR( file_data.resize( size ) );
110
0
  memcpy( file_data.begin(), in, size );
111
0
  return post_load( load_mem_( file_data.begin(), tracks[1] ) );
112
0
}
113
114
blargg_err_t Gme_File::load( Data_Reader& in )
115
3.10k
{
116
3.10k
  pre_load();
117
3.10k
  return post_load( load_( in ) );
118
3.10k
}
119
120
blargg_err_t Gme_File::load_file( const char* path )
121
0
{
122
0
  pre_load();
123
0
  GME_FILE_READER in;
124
0
  RETURN_ERR( in.open( path ) );
125
0
  return post_load( load_( in ) );
126
0
}
127
128
blargg_err_t Gme_File::load_remaining_( void const* h, long s, Data_Reader& in )
129
0
{
130
0
  Remaining_Reader rem( h, s, &in );
131
0
  return load( rem );
132
0
}
133
134
// Track info
135
136
void Gme_File::copy_field_( char* out, const char* in, int in_size )
137
49.4k
{
138
49.4k
  if ( !in || !*in )
139
20.4k
    return;
140
141
  // remove spaces/junk from beginning
142
38.3k
  while ( in_size && unsigned (*in - 1) <= ' ' - 1 )
143
9.32k
  {
144
9.32k
    in++;
145
9.32k
    in_size--;
146
9.32k
  }
147
148
  // truncate
149
29.0k
  if ( in_size > max_field_ )
150
4
    in_size = max_field_;
151
152
  // find terminator
153
29.0k
  int len = 0;
154
399k
  while ( len < in_size && in [len] )
155
370k
    len++;
156
157
  // remove spaces/junk from end
158
34.5k
  while ( len && unsigned (in [len - 1]) <= ' ' )
159
5.50k
    len--;
160
161
  // copy
162
29.0k
  out [len] = 0;
163
29.0k
  memcpy( out, in, len );
164
165
  // strip out stupid fields that should have been left blank
166
29.0k
  if ( !strcmp( out, "?" ) || !strcmp( out, "<?>" ) || !strcmp( out, "< ? >" ) )
167
1
    out [0] = 0;
168
29.0k
}
169
170
void Gme_File::copy_field_( char* out, const char* in )
171
22.3k
{
172
22.3k
  copy_field_( out, in, max_field_ );
173
22.3k
}
174
175
blargg_err_t Gme_File::remap_track_( int* track_io ) const
176
24.0k
{
177
24.0k
  if ( (unsigned) *track_io >= (unsigned) track_count() )
178
108
    return "Invalid track";
179
180
23.9k
  if ( (unsigned) *track_io < (unsigned) playlist.size() )
181
0
  {
182
0
    M3u_Playlist::entry_t const& e = playlist [*track_io];
183
0
    *track_io = 0;
184
0
    if ( e.track >= 0 )
185
0
    {
186
0
      *track_io = e.track;
187
0
      if ( !(type_->flags_ & 0x02) )
188
0
        *track_io -= e.decimal_track;
189
0
    }
190
0
    if ( *track_io >= raw_track_count_ )
191
0
      return "Invalid track in m3u playlist";
192
0
  }
193
23.9k
  else
194
23.9k
  {
195
23.9k
    check( !playlist.size() );
196
23.9k
  }
197
23.9k
  return 0;
198
23.9k
}
199
200
blargg_err_t Gme_File::track_info( track_info_t* out, int track ) const
201
11.9k
{
202
11.9k
  out->track_count = track_count();
203
11.9k
  out->length        = -1;
204
11.9k
  out->loop_length   = -1;
205
11.9k
  out->intro_length  = -1;
206
11.9k
  out->fade_length   = -1;
207
11.9k
  out->play_length   = -1;
208
11.9k
  out->repeat_count  = -1;
209
11.9k
  out->song [0]      = 0;
210
211
11.9k
  out->game [0]      = 0;
212
11.9k
  out->author [0]    = 0;
213
11.9k
  out->composer [0]  = 0;
214
11.9k
  out->engineer [0]  = 0;
215
11.9k
  out->sequencer [0] = 0;
216
11.9k
  out->tagger [0]    = 0;
217
11.9k
  out->copyright [0] = 0;
218
11.9k
  out->date [0]      = 0;
219
11.9k
  out->comment [0]   = 0;
220
11.9k
  out->dumper [0]    = 0;
221
11.9k
  out->system [0]    = 0;
222
11.9k
  out->disc [0]      = 0;
223
11.9k
  out->track [0]     = 0;
224
11.9k
  out->ost [0]       = 0;
225
226
11.9k
  copy_field_( out->system, type()->system );
227
228
11.9k
  int remapped = track;
229
11.9k
  RETURN_ERR( remap_track_( &remapped ) );
230
11.9k
  RETURN_ERR( track_info_( out, remapped ) );
231
232
  // override with m3u info
233
11.9k
  if ( playlist.size() )
234
0
  {
235
0
    M3u_Playlist::info_t const& i = playlist.info();
236
0
    copy_field_( out->game  , i.title );
237
0
    copy_field_( out->author, i.artist );
238
0
    copy_field_( out->engineer, i.engineer );
239
0
    copy_field_( out->composer, i.composer );
240
0
    copy_field_( out->sequencer, i.sequencer );
241
0
    copy_field_( out->copyright, i.copyright );
242
0
    copy_field_( out->dumper, i.ripping );
243
0
    copy_field_( out->tagger, i.tagging );
244
0
    copy_field_( out->date, i.date );
245
246
0
    M3u_Playlist::entry_t const& e = playlist [track];
247
0
    copy_field_( out->song, e.name );
248
0
    if ( e.length >= 0 ) out->length       = e.length;
249
0
    if ( e.intro  >= 0 ) out->intro_length = e.intro;
250
0
    if ( e.loop   >= 0 ) out->loop_length  = e.loop;
251
0
    if ( e.fade   >= 0 ) out->fade_length  = e.fade;
252
0
    if ( e.repeat >= 0 ) out->repeat_count = e.repeat;
253
0
  }
254
11.9k
  return 0;
255
11.9k
}