// // fileprovider.cpp // AdPlug // // Created by Christopher Snowhill on 1/27/18. // Copyright © 2018-2023 Christopher Snowhill. All rights reserved. // #include "fileprovider.h" class binistream_cog : public binistream { id m_file; Byte m_buffer[4096]; int m_buffer_filled, m_buffer_position; public: binistream_cog(id p_file) : m_file(p_file), m_buffer_filled(0), m_buffer_position(0) { } void seek(long pos, Offset offs) { switch(offs) { case Set: break; case Add: if((pos < 0 && m_buffer_position + pos >= 0) || (pos >= 0 && m_buffer_position + pos < m_buffer_filled + m_buffer_position)) { m_buffer_filled -= pos; m_buffer_position += pos; err &= ~Eof; return; } else pos += [m_file tell] - m_buffer_filled; break; case End: [m_file seek:0 whence:SEEK_END]; pos += [m_file tell]; break; } [m_file seek:0 whence:SEEK_END]; if(pos < [m_file tell]) { err &= ~Eof; [m_file seek:pos whence:SEEK_SET]; } m_buffer_filled = 0; m_buffer_position = 0; } long pos() { return [m_file tell] - m_buffer_filled; } Byte getByte() { if(err & Eof) return -1; if(!m_buffer_filled) { m_buffer_filled = (int)[m_file read:m_buffer amount:4096]; if(!m_buffer_filled) { err |= Eof; return -1; } m_buffer_position = 0; } Byte value = m_buffer[m_buffer_position]; ++m_buffer_position; --m_buffer_filled; return value; } }; binistream *CProvider_cog::open(std::string filename) const { id p_file; if(filename == m_file_path) { p_file = m_file_hint; [p_file seek:0 whence:SEEK_SET]; } if(p_file == nil) { NSString *urlString = [NSString stringWithUTF8String:filename.c_str()]; NSString *fragmentString = @""; NSRange fragmentRange = [urlString rangeOfString:@"#" options:NSBackwardsSearch]; if(fragmentRange.location != NSNotFound) { fragmentString = [urlString substringFromIndex:fragmentRange.location]; urlString = [urlString substringToIndex:fragmentRange.location]; } NSURL *url = [NSURL URLWithString:[[urlString stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLFragmentAllowedCharacterSet] stringByAppendingString:fragmentString]]; id audioSourceClass = NSClassFromString(@"AudioSource"); p_file = [audioSourceClass audioSourceForURL:url]; if(![p_file open:url]) return 0; } binistream_cog *f = new binistream_cog(p_file); if(f->error()) { delete f; return 0; } f->setFlag(binio::BigEndian, false); f->setFlag(binio::FloatIEEE); return f; } void CProvider_cog::close(binistream *f) const { binistream_cog *ff = (binistream_cog *)f; if(f) delete ff; }