cog/Plugins/AdPlug/AdPlug/fileprovider.mm

117 lines
2.6 KiB
Plaintext

//
// fileprovider.cpp
// AdPlug
//
// Created by Christopher Snowhill on 1/27/18.
// Copyright © 2018-2022 Christopher Snowhill. All rights reserved.
//
#include "fileprovider.h"
class binistream_cog : public binistream {
id<CogSource> m_file;
Byte m_buffer[4096];
int m_buffer_filled, m_buffer_position;
public:
binistream_cog(id<CogSource> 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<CogSource> 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;
}