Coverage Report

Created: 2026-08-13 07:43

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
8.31k
{
25
8.31k
  playlist.clear();
26
8.31k
  clear_playlist_();
27
8.31k
  track_count_ = raw_track_count_;
28
8.31k
}
29
30
void Gme_File::unload()
31
8.31k
{
32
8.31k
  clear_playlist(); // *before* clearing track count
33
8.31k
  track_count_     = 0;
34
8.31k
  raw_track_count_ = 0;
35
8.31k
  file_data.clear();
36
8.31k
}
37
38
Gme_File::Gme_File()
39
2.44k
{
40
2.44k
  type_         = 0;
41
2.44k
  user_data_    = 0;
42
2.44k
  user_cleanup_ = 0;
43
2.44k
  unload(); // clears fields
44
2.44k
  blargg_verify_byte_order(); // used by most emulator types, so save them the trouble
45
2.44k
}
46
47
Gme_File::~Gme_File()
48
2.44k
{
49
2.44k
  if ( user_cleanup_ )
50
0
    user_cleanup_( user_data_ );
51
2.44k
}
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
372
{
62
372
  RETURN_ERR( file_data.resize( in.remain() ) );
63
372
  RETURN_ERR( in.read( file_data.begin(), file_data.size() ) );
64
372
  if ( type()->track_count == 1 )
65
358
  {
66
358
    RETURN_ERR( tracks.resize( 2 ) );
67
358
    tracks[0] = 0, tracks[1] = file_data.size();
68
358
  }
69
372
  return load_mem_( file_data.begin(), file_data.size() );
70
372
}
71
72
// public load functions call this at beginning
73
2.44k
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
2.44k
{
80
2.44k
  if ( !track_count() )
81
396
    set_track_count( type()->track_count );
82
2.44k
  if ( !err )
83
2.36k
    post_load_();
84
81
  else
85
81
    unload();
86
87
2.44k
  return err;
88
2.44k
}
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
2.44k
{
116
2.44k
  pre_load();
117
2.44k
  return post_load( load_( in ) );
118
2.44k
}
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
40.0k
{
138
40.0k
  if ( !in || !*in )
139
15.2k
    return;
140
141
  // remove spaces/junk from beginning
142
31.7k
  while ( in_size && unsigned (*in - 1) <= ' ' - 1 )
143
6.90k
  {
144
6.90k
    in++;
145
6.90k
    in_size--;
146
6.90k
  }
147
148
  // truncate
149
24.8k
  if ( in_size > max_field_ )
150
3
    in_size = max_field_;
151
152
  // find terminator
153
24.8k
  int len = 0;
154
342k
  while ( len < in_size && in [len] )
155
317k
    len++;
156
157
  // remove spaces/junk from end
158
28.5k
  while ( len && unsigned (in [len - 1]) <= ' ' )
159
3.67k
    len--;
160
161
  // copy
162
24.8k
  out [len] = 0;
163
24.8k
  memcpy( out, in, len );
164
165
  // strip out stupid fields that should have been left blank
166
24.8k
  if ( !strcmp( out, "?" ) || !strcmp( out, "<?>" ) || !strcmp( out, "< ? >" ) )
167
2
    out [0] = 0;
168
24.8k
}
169
170
void Gme_File::copy_field_( char* out, const char* in )
171
17.6k
{
172
17.6k
  copy_field_( out, in, max_field_ );
173
17.6k
}
174
175
blargg_err_t Gme_File::remap_track_( int* track_io ) const
176
19.9k
{
177
19.9k
  if ( (unsigned) *track_io >= (unsigned) track_count() )
178
86
    return "Invalid track";
179
180
19.8k
  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
19.8k
  else
194
19.8k
  {
195
19.8k
    check( !playlist.size() );
196
19.8k
  }
197
19.8k
  return 0;
198
19.8k
}
199
200
blargg_err_t Gme_File::track_info( track_info_t* out, int track ) const
201
9.94k
{
202
9.94k
  out->track_count = track_count();
203
9.94k
  out->length        = -1;
204
9.94k
  out->loop_length   = -1;
205
9.94k
  out->intro_length  = -1;
206
9.94k
  out->fade_length   = -1;
207
9.94k
  out->play_length   = -1;
208
9.94k
  out->repeat_count  = -1;
209
9.94k
  out->song [0]      = 0;
210
211
9.94k
  out->game [0]      = 0;
212
9.94k
  out->author [0]    = 0;
213
9.94k
  out->composer [0]  = 0;
214
9.94k
  out->engineer [0]  = 0;
215
9.94k
  out->sequencer [0] = 0;
216
9.94k
  out->tagger [0]    = 0;
217
9.94k
  out->copyright [0] = 0;
218
9.94k
  out->date [0]      = 0;
219
9.94k
  out->comment [0]   = 0;
220
9.94k
  out->dumper [0]    = 0;
221
9.94k
  out->system [0]    = 0;
222
9.94k
  out->disc [0]      = 0;
223
9.94k
  out->track [0]     = 0;
224
9.94k
  out->ost [0]       = 0;
225
226
9.94k
  copy_field_( out->system, type()->system );
227
228
9.94k
  int remapped = track;
229
9.94k
  RETURN_ERR( remap_track_( &remapped ) );
230
9.94k
  RETURN_ERR( track_info_( out, remapped ) );
231
232
  // override with m3u info
233
9.94k
  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
9.94k
  return 0;
255
9.94k
}