Skip to content

Instantly share code, notes, and snippets.

@landonf
Created May 25, 2010 01:13
Show Gist options
  • Save landonf/412641 to your computer and use it in GitHub Desktop.
Save landonf/412641 to your computer and use it in GitHub Desktop.
/**
* An abstract interface that provides purely asynchronous, read-only access to stream-based data.
*
* TODO: Define end-of-stream handling
*
* @par Thread Safety
* Not Thread-safe. May not be shared across threads.
*/
@protocol PLInputStream
#pragma mark Read Methods
/**
* Asynchronously read up to @a length bytes from the input stream.
*
* @param length Maximum number of bytes to read. If no data is available, the request will be enqueued until
* the input stream is ready for reading, the request is cancelled, or timeout occurs.
* @param timeout The maximum amount of time to wait for the read to complete before a timeout occurs. If 0,
* the request will wait indefinitely.
*
* Upon completion or error the PLInputStreamDelegate::stream:readRequest:didCompleteWithResult: method will be called.
*/
- (PLStreamReadRequest *) readBytes: (NSUInteger) length timeout: (NSTimeInterval) timeout;
#pragma mark Skip Methods
/**
* Skip over and discard up to @a length bytes from this input stream.
*
* @param length Maximum number of bytes to skip. Fewer bytes may be skipped.
* @param timeout The maximum amount of time to wait for the skip to complete before a timeout occurs. If 0,
* the request will wait indefinitely.
*
* Upon completion or error the PLInputStreamDelegate::stream:skipRequest:didCompleteWithResult: will be called.
*/
- (PLStreamSkipRequest *) skip: (NSUInteger) length timeout: (NSTimeInterval) timeout;
@end
/**
* Defines the methods implemented by delegates of PLInputStream objects.
*/
@protocol PLInputStreamDelegate <PLStreamDelegate>
/**
* Called upon successful completion or early termination of a read request.
*
* @param stream The associated input stream.
* @param request The terminated read request.
* @param result The read result.
*/
- (void) stream: (id<PLInputStream>) stream readRequest: (PLStreamReadRequest *) request didCompleteWithResult: (PLStreamReadResult *) result;
/**
* Called upon successful completion or early termination of a skip request.
*
* @param stream The associated input stream.
* @param request The terminated skip request.
* @param result The read result.
*/
- (void) stream: (id<PLInputStream>) stream skipRequest: (PLStreamSkipRequest *) request didCompleteWithResult: (PLStreamSkipResult *) result;
@end
@interface PLStreamReadRequest : NSObject {
@private
/** Waiting blocks. */
NSMutableArray *_waiters;
/** Result, or nil if the request is pending. */
PLStreamReadResult *_result;
/** Block to execute on cancellation. */
void (^_cancelBlock)();
}
+ (id) requestWithCancelBlock: (void (^)()) cancelBlock;
- (id) initWithCancelBlock: (void (^)()) cancelBlock;
- (void) wait: (void (^)(PLStreamReadResult *result)) block;
- (void) cancel;
- (void) setResult: (PLStreamReadResult *) result;
@end
@interface PLStreamReadResult : NSObject {
@private
/** Data read, or nil if none read. */
NSData *_data;
/** Read error, or nil if no error. */
NSError *_error;
}
+ (id) resultWithData: (NSData *) data error: (NSError *) error;
- (id) initWithData: (NSData *) data error: (NSError *) error;
/**
* The data read from the input stream. May be empty if a read error occured or the end-of-stream was reached. This
* parameter may be non-empty even if a read error causes early termination of a read.
*/
@property(nonatomic, readonly) NSData *data;
/**
* A read error in the PLStreamErrorDomain, or nil if no read error occured.
*/
@property(nonatomic, readonly) NSError *error;
@end
@landonf
Copy link
Author

landonf commented May 25, 2010

Example usage with blocks:

[[stream readBytes: 1 timeout: 0] wait: ^(PLStreamReadResult *res) {
    NSLog(@"Read one byte: %@", res.data);
}];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment