static void load_id666(service_ptr_t<file> & p_file, LPID666TAG lpTag, abort_callback & p_abort)//must be seeked to correct spot before calling { t_uint8 szBuf[4]; p_file->read_object( &szBuf, 4, p_abort ); if( ! memcmp( szBuf, xid6_signature, 4 ) ) { t_uint32 tag_size; p_file->read_lendian_t( tag_size, p_abort ); t_filesize offset = p_file->get_position( p_abort ); service_ptr_t< reader_limited > m_file = new service_impl_t< reader_limited >; m_file->init( p_file, offset, offset + tag_size, p_abort ); service_ptr_t<file> p_file = m_file.get_ptr(); try { parse_id666( p_file, lpTag, false, p_abort ); } catch ( const exception_io_data & ) { p_file->seek( 0, p_abort ); memset( lpTag, 0, sizeof( *lpTag ) ); parse_id666( p_file, lpTag, true, p_abort ); } } else throw exception_tag_not_found(); }
static void parse_id666( service_ptr_t< file > & p_file, LPID666TAG lpTag, bool aligned, abort_callback & p_abort ) { while ( ! p_file->is_eof( p_abort ) ) { t_uint8 id, type; t_uint16 data; p_file->read_object_t( id, p_abort ); p_file->read_object_t( type, p_abort ); p_file->read_lendian_t( data, p_abort ); switch ( type ) { case XTYPE_STR: { if ( data < 1 || data > 256 ) throw exception_io_data(); switch ( id ) { case XID_SONG: p_file->read_object( lpTag->szTitle, data, p_abort ); break; case XID_GAME: p_file->read_object( lpTag->szGame, data, p_abort ); break; case XID_ARTIST: p_file->read_object( lpTag->szArtist, data, p_abort ); break; case XID_PUB: p_file->read_object( lpTag->szPublisher, data, p_abort ); break; case XID_OST: p_file->read_object( lpTag->szOST, data, p_abort ); break; case XID_DUMPER: p_file->read_object( lpTag->szDumper, data, p_abort ); break; case XID_CMNTS: p_file->read_object( lpTag->szComment, data, p_abort ); break; default: p_file->skip( data, p_abort ); break; } if ( aligned && ( data & 3 ) ) p_file->skip( 4 - ( data & 3 ), p_abort ); } break; case XTYPE_INT: { if ( data != 4 ) throw exception_io_data(); t_uint32 value; p_file->read_lendian_t( value, p_abort ); switch ( id ) { case XID_DATE: SetDate( lpTag->szDate, ( value >> 16 ) & 255, ( value >> 8 ) & 255, value & 255 ); break; case XID_INTRO: if ( value > 383999999 ) value = 383999999; lpTag->uSong_ms = value / 64; break; case XID_LOOP: if ( value > 383999999 ) value = 383999999; lpTag->uLoop_ms = value / 64; break; case XID_END: if ( value > 383999999 ) value = 383999999; lpTag->uEnd_ms = value / 64; break; case XID_FADE: if ( value > 3839999 ) value = 3839999; lpTag->uFade_ms = value / 64; break; case XID_AMP: if ( value < 32768 ) value = 32768; else if ( value > 524288 ) value = 524288; lpTag->uAmplification = value; break; } } break; case XTYPE_DATA: { switch ( id ) { case XID_EMU: lpTag->bEmulator = t_uint8( data ); break; case XID_DISC: lpTag->bDisc = t_uint8( data ); if ( lpTag->bDisc > 9 ) lpTag->bDisc = 9; break; case XID_TRACK: if ( data > ( ( 100 << 8 ) - 1 ) ) data = 0; lpTag->wTrack = data; break; case XID_COPY: lpTag->wCopyright = data; break; case XID_MUTE: lpTag->bMute = t_uint8( data ); break; case XID_LOOPX: if ( data < 1 ) data = 1; else if ( data > 9 ) data = 9; lpTag->uLoopCount = data; break; case XID_AMP: lpTag->uAmplification = data; lpTag->uAmplification <<= 12; if ( lpTag->uAmplification < 32768 ) lpTag->uAmplification = 32768; else if ( lpTag->uAmplification > 524288 ) lpTag->uAmplification = 524288; break; } } break; } } }