Added AutoRecoveringHttpDataSource

This commit is contained in:
Thong Nguyen 2012-10-17 11:57:27 +01:00
parent 1f3c8eca52
commit d9d1d86f31
14 changed files with 465 additions and 3 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -7,6 +7,10 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
A16CB9AD162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A16CB9AA162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m */; };
A16CB9AE162EC4AB00CFD1E8 /* DataSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A16CB9AC162EC4AB00CFD1E8 /* DataSourceWrapper.m */; };
A16CB9B1162EC5E300CFD1E8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A16CB9B0162EC5E300CFD1E8 /* SystemConfiguration.framework */; };
A16CB9B3162EC5E900CFD1E8 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A16CB9B2162EC5E900CFD1E8 /* Default-568h@2x.png */; };
A186B4E4157F80E700BD0084 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B4E3157F80E700BD0084 /* UIKit.framework */; }; A186B4E4157F80E700BD0084 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B4E3157F80E700BD0084 /* UIKit.framework */; };
A186B4E6157F80E700BD0084 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B4E5157F80E700BD0084 /* Foundation.framework */; }; A186B4E6157F80E700BD0084 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A186B4E5157F80E700BD0084 /* Foundation.framework */; };
A186B4EE157F80E700BD0084 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A186B4EC157F80E700BD0084 /* InfoPlist.strings */; }; A186B4EE157F80E700BD0084 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A186B4EC157F80E700BD0084 /* InfoPlist.strings */; };
@ -25,6 +29,12 @@
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
A16CB9A9162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoRecoveringHttpDataSource.h; sourceTree = "<group>"; };
A16CB9AA162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AutoRecoveringHttpDataSource.m; sourceTree = "<group>"; };
A16CB9AB162EC4AB00CFD1E8 /* DataSourceWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSourceWrapper.h; sourceTree = "<group>"; };
A16CB9AC162EC4AB00CFD1E8 /* DataSourceWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataSourceWrapper.m; sourceTree = "<group>"; };
A16CB9B0162EC5E300CFD1E8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
A16CB9B2162EC5E900CFD1E8 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Default-568h@2x.png"; sourceTree = "<group>"; };
A186B4DF157F80E600BD0084 /* Audjustable.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Audjustable.app; sourceTree = BUILT_PRODUCTS_DIR; }; A186B4DF157F80E600BD0084 /* Audjustable.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Audjustable.app; sourceTree = BUILT_PRODUCTS_DIR; };
A186B4E3157F80E700BD0084 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; A186B4E3157F80E700BD0084 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
A186B4E5157F80E700BD0084 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; A186B4E5157F80E700BD0084 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@ -58,6 +68,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A16CB9B1162EC5E300CFD1E8 /* SystemConfiguration.framework in Frameworks */,
A186B51A157F819500BD0084 /* CFNetwork.framework in Frameworks */, A186B51A157F819500BD0084 /* CFNetwork.framework in Frameworks */,
A186B518157F818900BD0084 /* CoreFoundation.framework in Frameworks */, A186B518157F818900BD0084 /* CoreFoundation.framework in Frameworks */,
A186B514157F817500BD0084 /* AudioToolbox.framework in Frameworks */, A186B514157F817500BD0084 /* AudioToolbox.framework in Frameworks */,
@ -72,6 +83,7 @@
A186B4D4157F80E600BD0084 = { A186B4D4157F80E600BD0084 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A16CB9B0162EC5E300CFD1E8 /* SystemConfiguration.framework */,
A186B4E9157F80E700BD0084 /* Audjustable */, A186B4E9157F80E700BD0084 /* Audjustable */,
A186B4E2157F80E700BD0084 /* Frameworks */, A186B4E2157F80E700BD0084 /* Frameworks */,
A186B4E0157F80E600BD0084 /* Products */, A186B4E0157F80E600BD0084 /* Products */,
@ -116,6 +128,7 @@
A186B51B157F81D900BD0084 /* Resources */, A186B51B157F81D900BD0084 /* Resources */,
A186B4EB157F80E700BD0084 /* Audjustable-Info.plist */, A186B4EB157F80E700BD0084 /* Audjustable-Info.plist */,
A186B4EC157F80E700BD0084 /* InfoPlist.strings */, A186B4EC157F80E700BD0084 /* InfoPlist.strings */,
A16CB9B2162EC5E900CFD1E8 /* Default-568h@2x.png */,
A186B4EF157F80E700BD0084 /* main.m */, A186B4EF157F80E700BD0084 /* main.m */,
A186B4F1157F80E700BD0084 /* Audjustable-Prefix.pch */, A186B4F1157F80E700BD0084 /* Audjustable-Prefix.pch */,
); );
@ -135,6 +148,10 @@
A186B4FF157F813100BD0084 /* AudioPlayer */ = { A186B4FF157F813100BD0084 /* AudioPlayer */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A16CB9A9162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.h */,
A16CB9AA162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m */,
A16CB9AB162EC4AB00CFD1E8 /* DataSourceWrapper.h */,
A16CB9AC162EC4AB00CFD1E8 /* DataSourceWrapper.m */,
A186B500157F813100BD0084 /* AudioPlayer.h */, A186B500157F813100BD0084 /* AudioPlayer.h */,
A186B501157F813100BD0084 /* AudioPlayer.m */, A186B501157F813100BD0084 /* AudioPlayer.m */,
A186B502157F813100BD0084 /* CoreFoundationDataSource.h */, A186B502157F813100BD0084 /* CoreFoundationDataSource.h */,
@ -209,6 +226,7 @@
files = ( files = (
A186B4EE157F80E700BD0084 /* InfoPlist.strings in Resources */, A186B4EE157F80E700BD0084 /* InfoPlist.strings in Resources */,
A186B51D157F825400BD0084 /* sample.m4a in Resources */, A186B51D157F825400BD0084 /* sample.m4a in Resources */,
A16CB9B3162EC5E900CFD1E8 /* Default-568h@2x.png in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -227,6 +245,8 @@
A186B50F157F813100BD0084 /* HttpDataSource.m in Sources */, A186B50F157F813100BD0084 /* HttpDataSource.m in Sources */,
A186B510157F813100BD0084 /* LocalFileDataSource.m in Sources */, A186B510157F813100BD0084 /* LocalFileDataSource.m in Sources */,
A186B511157F813100BD0084 /* AudioPlayerView.m in Sources */, A186B511157F813100BD0084 /* AudioPlayerView.m in Sources */,
A16CB9AD162EC4AB00CFD1E8 /* AutoRecoveringHttpDataSource.m in Sources */,
A16CB9AE162EC4AB00CFD1E8 /* DataSourceWrapper.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Audjustable.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0450"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A186B4DE157F80E600BD0084"
BuildableName = "Audjustable.app"
BlueprintName = "Audjustable"
ReferencedContainer = "container:Audjustable.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A186B4DE157F80E600BD0084"
BuildableName = "Audjustable.app"
BlueprintName = "Audjustable"
ReferencedContainer = "container:Audjustable.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A186B4DE157F80E600BD0084"
BuildableName = "Audjustable.app"
BlueprintName = "Audjustable"
ReferencedContainer = "container:Audjustable.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A186B4DE157F80E600BD0084"
BuildableName = "Audjustable.app"
BlueprintName = "Audjustable"
ReferencedContainer = "container:Audjustable.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Audjustable.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>A186B4DE157F80E600BD0084</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

BIN
Audjustable/Classes/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -103,6 +103,7 @@ AudioPlayerErrorCode;
-(void) audioPlayer:(AudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(AudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration; -(void) audioPlayer:(AudioPlayer*)audioPlayer didFinishPlayingQueueItemId:(NSObject*)queueItemId withReason:(AudioPlayerStopReason)stopReason andProgress:(double)progress andDuration:(double)duration;
@optional @optional
-(void) audioPlayer:(AudioPlayer*)audioPlayer internalStateChanged:(AudioPlayerInternalState)state; -(void) audioPlayer:(AudioPlayer*)audioPlayer internalStateChanged:(AudioPlayerInternalState)state;
-(void) audioPlayer:(AudioPlayer*)audioPlayer didCancelQueuedItems:(NSArray*)queuedItems;
@end @end
@class QueueEntry; @class QueueEntry;

View File

@ -468,7 +468,34 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ
{ {
@synchronized(self) @synchronized(self)
{ {
NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:bufferingQueue.count + upcomingQueue.count];
QueueEntry* entry = [bufferingQueue dequeue];
if (entry && entry != currentlyPlayingEntry)
{
[array addObject:[entry queueItemId]];
}
while (bufferingQueue.count > 0)
{
[array addObject:[[bufferingQueue dequeue] queueItemId]];
}
for (QueueEntry* entry in upcomingQueue)
{
[array addObject:entry.queueItemId];
}
[upcomingQueue removeAllObjects]; [upcomingQueue removeAllObjects];
dispatch_async(dispatch_get_main_queue(), ^
{
if ([self.delegate respondsToSelector:@selector(audioPlayer:didCancelQueuedItems:)])
{
[self.delegate audioPlayer:self didCancelQueuedItems:array];
}
});
} }
} }
@ -1258,13 +1285,18 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ
currentlyReadingEntry.dataSource.delegate = nil; currentlyReadingEntry.dataSource.delegate = nil;
[currentlyReadingEntry.dataSource unregisterForEvents]; [currentlyReadingEntry.dataSource unregisterForEvents];
if (currentlyReadingEntry) if (currentlyPlayingEntry)
{ {
[self processDidFinishPlaying:currentlyPlayingEntry withNext:nil]; [self processDidFinishPlaying:currentlyPlayingEntry withNext:nil];
} }
pthread_mutex_lock(&queueBuffersMutex); pthread_mutex_lock(&queueBuffersMutex);
if ([bufferingQueue peek] == currentlyPlayingEntry)
{
[bufferingQueue dequeue];
}
currentlyPlayingEntry = nil; currentlyPlayingEntry = nil;
currentlyReadingEntry = nil; currentlyReadingEntry = nil;
seekToTimeWasRequested = NO; seekToTimeWasRequested = NO;
@ -1276,15 +1308,20 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ
currentlyReadingEntry.dataSource.delegate = nil; currentlyReadingEntry.dataSource.delegate = nil;
[currentlyReadingEntry.dataSource unregisterForEvents]; [currentlyReadingEntry.dataSource unregisterForEvents];
if (currentlyReadingEntry) if (currentlyPlayingEntry)
{ {
[self processDidFinishPlaying:currentlyPlayingEntry withNext:nil]; [self processDidFinishPlaying:currentlyPlayingEntry withNext:nil];
} }
pthread_mutex_lock(&queueBuffersMutex); pthread_mutex_lock(&queueBuffersMutex);
if ([bufferingQueue peek] == currentlyPlayingEntry)
{
[bufferingQueue dequeue];
}
currentlyPlayingEntry = nil; currentlyPlayingEntry = nil;
currentlyReadingEntry = nil; currentlyReadingEntry = nil;
pthread_mutex_unlock(&queueBuffersMutex); pthread_mutex_unlock(&queueBuffersMutex);
[self resetAudioQueue]; [self resetAudioQueue];

View File

@ -0,0 +1,19 @@
//
// AutoRecoveringHttpDataSource.h
// bloom
//
// Created by Thong Nguyen on 16/10/2012.
// Copyright (c) 2012 DDN Ltd. All rights reserved.
//
#import "DataSource.h"
#import "HttpDataSource.h"
#import "DataSourceWrapper.h"
@interface AutoRecoveringHttpDataSource : DataSourceWrapper
-(id) initWithHttpDataSource:(HttpDataSource*)innerDataSource;
@property (readonly) HttpDataSource* innerDataSource;
@end

View File

@ -0,0 +1,169 @@
//
// AutoRecoveringHttpDataSource.m
// bloom
//
// Created by Thong Nguyen on 16/10/2012.
// Copyright (c) 2012 DDN Ltd. All rights reserved.
//
#import <sys/socket.h>
#import <netinet/in.h>
#import <netinet6/in6.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
#import <netdb.h>
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import "AutoRecoveringHttpDataSource.h"
#define MAX_IMMEDIATE_RECONNECT_ATTEMPTS (8)
@interface AutoRecoveringHttpDataSource()
{
int reconnectAttempts;
BOOL waitingForNetwork;
SCNetworkReachabilityRef reachabilityRef;
}
-(void) reachabilityChanged;
@end
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
{
@autoreleasepool
{
AutoRecoveringHttpDataSource* dataSource = (__bridge AutoRecoveringHttpDataSource*)info;
[dataSource reachabilityChanged];
}
}
@implementation AutoRecoveringHttpDataSource
-(HttpDataSource*) innerHttpDataSource
{
return (HttpDataSource*)self.innerDataSource;
}
-(id) initWithHttpDataSource:(HttpDataSource*)innerDataSourceIn
{
if (self = [super initWithDataSource:innerDataSourceIn])
{
self.innerDataSource.delegate = self;
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
reachabilityRef = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
}
return self;
}
-(BOOL) startNotifierOnRunLoop:(NSRunLoop*)runLoop
{
BOOL retVal = NO;
SCNetworkReachabilityContext context = { 0, (__bridge void*)self, NULL, NULL, NULL };
if (SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context))
{
if(SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, runLoop.getCFRunLoop, kCFRunLoopDefaultMode))
{
retVal = YES;
}
}
return retVal;
}
-(BOOL) registerForEvents:(NSRunLoop*)runLoop
{
[super registerForEvents:runLoop];
[self startNotifierOnRunLoop:runLoop];
return YES;
}
-(void) unregisterForEvents
{
[self stopNotifier];
}
-(void) stopNotifier
{
if (reachabilityRef != NULL)
{
SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
}
}
-(BOOL) hasGotNetworkConnection
{
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
{
return ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
}
return NO;
}
-(void) dealloc
{
[self stopNotifier];
if (reachabilityRef!= NULL)
{
CFRelease(reachabilityRef);
}
}
-(void) reachabilityChanged
{
if (waitingForNetwork)
{
waitingForNetwork = NO;
[self attemptReconnect];
}
}
-(void) dataSourceDataAvailable:(DataSource*)dataSource
{
reconnectAttempts = 0;
[super dataSourceDataAvailable:dataSource];
}
-(void) attemptReconnect
{
reconnectAttempts++;
[self seekToOffset:self.position];
}
-(void) dataSourceErrorOccured:(DataSource*)dataSource
{
if (![self hasGotNetworkConnection])
{
waitingForNetwork = YES;
return;
}
if (reconnectAttempts > MAX_IMMEDIATE_RECONNECT_ATTEMPTS)
{
[self performSelector:@selector(attemptReconnect) withObject:nil afterDelay:5];
}
else
{
[self attemptReconnect];
}
}
@end

View File

@ -0,0 +1,17 @@
//
// DataSourceWrapper.h
// bloom
//
// Created by Thong Nguyen on 16/10/2012.
// Copyright (c) 2012 DDN Ltd. All rights reserved.
//
#import "DataSource.h"
@interface DataSourceWrapper : DataSource<DataSourceDelegate>
-(id) initWithDataSource:(DataSource*)innerDataSource;
@property (readonly) DataSource* innerDataSource;
@end

View File

@ -0,0 +1,84 @@
//
// DataSourceWrapper.m
// bloom
//
// Created by Thong Nguyen on 16/10/2012.
// Copyright (c) 2012 DDN Ltd. All rights reserved.
//
#import "DataSourceWrapper.h"
@interface DataSourceWrapper()
@property (readwrite) DataSource* innerDataSource;
@end
@implementation DataSourceWrapper
-(id) initWithDataSource:(DataSource*)innerDataSourceIn
{
if (self = [super init])
{
self.innerDataSource = innerDataSourceIn;
self.innerDataSource.delegate = self;
}
return self;
}
-(long long) length
{
return self.innerDataSource.length;
}
-(void) seekToOffset:(long long)offset
{
return [self.innerDataSource seekToOffset:offset];
}
-(int) readIntoBuffer:(UInt8*)buffer withSize:(int)size
{
return [self.innerDataSource readIntoBuffer:buffer withSize:size];
}
-(long long) position
{
return self.innerDataSource.position;
}
-(BOOL) registerForEvents:(NSRunLoop*)runLoop
{
return [self.innerDataSource registerForEvents:runLoop];
}
-(void) unregisterForEvents
{
[self.innerDataSource unregisterForEvents];
}
-(void) close
{
[self.innerDataSource close];
}
-(BOOL) hasBytesAvailable
{
return self.innerDataSource.hasBytesAvailable;
}
-(void) dataSourceDataAvailable:(DataSource*)dataSource
{
[self.delegate dataSourceDataAvailable:self];
}
-(void) dataSourceErrorOccured:(DataSource*)dataSource
{
[self.delegate dataSourceErrorOccured:self];
}
-(void) dataSourceEof:(DataSource*)dataSource
{
[self.delegate dataSourceEof:self];
}
@end

BIN
Default-568h@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB