Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
coderZsq committed Nov 25, 2020
1 parent e03562c commit 240ad3e
Show file tree
Hide file tree
Showing 5 changed files with 390 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
143474D1256BFA8300149168 /* SQURLRequestSerializationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 143474D0256BFA8300149168 /* SQURLRequestSerializationTest.m */; };
14560566256E957F00746C4A /* SQMultipartBodyStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 14560565256E957F00746C4A /* SQMultipartBodyStream.m */; };
14963573256BEC5200B1E31B /* SQHTTPBodyPart.m in Sources */ = {isa = PBXBuildFile; fileRef = 14963572256BEC5200B1E31B /* SQHTTPBodyPart.m */; };
149635AB256BFA3600B1E31B /* AFNetworking_DebugTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 149635AA256BFA3600B1E31B /* AFNetworking_DebugTests.m */; };
14A334872568D62400772436 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14A334862568D62400772436 /* AppDelegate.m */; };
Expand Down Expand Up @@ -35,6 +36,8 @@
/* Begin PBXFileReference section */
002F3802D60E85956ACBBB58 /* Pods-AFNetworking-Debug.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AFNetworking-Debug.release.xcconfig"; path = "Target Support Files/Pods-AFNetworking-Debug/Pods-AFNetworking-Debug.release.xcconfig"; sourceTree = "<group>"; };
143474D0256BFA8300149168 /* SQURLRequestSerializationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQURLRequestSerializationTest.m; sourceTree = "<group>"; };
14560564256E957F00746C4A /* SQMultipartBodyStream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQMultipartBodyStream.h; sourceTree = "<group>"; };
14560565256E957F00746C4A /* SQMultipartBodyStream.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SQMultipartBodyStream.m; sourceTree = "<group>"; };
14963571256BEC5200B1E31B /* SQHTTPBodyPart.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQHTTPBodyPart.h; sourceTree = "<group>"; };
14963572256BEC5200B1E31B /* SQHTTPBodyPart.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SQHTTPBodyPart.m; sourceTree = "<group>"; };
149635A8256BFA3600B1E31B /* AFNetworking-DebugTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "AFNetworking-DebugTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -122,6 +125,8 @@
14ED0255256A480700D370FD /* SQQueryStringPair.m */,
14963571256BEC5200B1E31B /* SQHTTPBodyPart.h */,
14963572256BEC5200B1E31B /* SQHTTPBodyPart.m */,
14560564256E957F00746C4A /* SQMultipartBodyStream.h */,
14560565256E957F00746C4A /* SQMultipartBodyStream.m */,
14ED0265256A4AD700D370FD /* SQURLRequestSerialization.h */,
14ED0266256A4AD700D370FD /* SQURLRequestSerialization.m */,
14A3348E2568D62400772436 /* Main.storyboard */,
Expand Down Expand Up @@ -304,6 +309,7 @@
files = (
14A3348D2568D62400772436 /* ViewController.m in Sources */,
14963573256BEC5200B1E31B /* SQHTTPBodyPart.m in Sources */,
14560566256E957F00746C4A /* SQMultipartBodyStream.m in Sources */,
14A334872568D62400772436 /* AppDelegate.m in Sources */,
14ED0267256A4AD700D370FD /* SQURLRequestSerialization.m in Sources */,
14A334982568D62500772436 /* main.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// SQMultipartBodyStream.h
// AFNetworking-Debug
//
// Created by 朱双泉 on 2020/11/25.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class SQHTTPBodyPart;

@interface SQMultipartBodyStream : NSInputStream <NSStreamDelegate>

@property (nonatomic, assign) NSUInteger numberOfBytesInPacket;
@property (nonatomic, assign) NSTimeInterval delay;
@property (nonatomic, strong) NSInputStream *inputStream;
@property (readonly, nonatomic, assign) unsigned long long contentLength;
@property (readonly, nonatomic, assign, getter=isEmpty) BOOL empty;

- (instancetype)initWithStringEncoding:(NSStringEncoding)encoding;
- (void)setInitialAndFinalBoundaries;
- (void)appendHTTPBodyPart:(SQHTTPBodyPart *)bodyPart;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//
// SQMultipartBodyStream.m
// AFNetworking-Debug
//
// Created by 朱双泉 on 2020/11/25.
//

#import "SQMultipartBodyStream.h"
#import "SQHTTPBodyPart.h"

@interface NSStream ()
@property (readwrite) NSStreamStatus streamStatus;
@property (readwrite, copy) NSError *streamError;
@end

@interface SQMultipartBodyStream () <NSCopying>
@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding;
@property (readwrite, nonatomic, strong) NSMutableArray *HTTPBodyParts;
@property (readwrite, nonatomic, strong) NSEnumerator *HTTPBodyPartEnumerator;
@property (readwrite, nonatomic, strong) SQHTTPBodyPart *currentHTTPBodyPart;
@property (readwrite, nonatomic, strong) NSOutputStream *outputStream;
@property (readwrite, nonatomic, strong) NSMutableData *buffer;
@end

@implementation SQMultipartBodyStream

@synthesize delegate;
@synthesize streamStatus;
@synthesize streamError;

- (instancetype)initWithStringEncoding:(NSStringEncoding)encoding {
self = [super init];
if (!self) {
return nil;
}
self.stringEncoding = encoding;
self.HTTPBodyParts = [NSMutableArray array];
self.numberOfBytesInPacket = NSIntegerMax;
return self;
}

- (void)setInitialAndFinalBoundaries {
if ([self.HTTPBodyParts count] > 0) {
for (SQHTTPBodyPart *bodyPart in self.HTTPBodyParts) {
bodyPart.hasInitialBoundary = NO;
bodyPart.hasFinalBoundary = NO;
}
[[self.HTTPBodyParts firstObject] setHasInitialBoundary:YES];
[[self.HTTPBodyParts lastObject] setHasFinalBoundary:YES];
}
}

- (void)appendHTTPBodyPart:(SQHTTPBodyPart *)bodyPart {
[self.HTTPBodyParts addObject:bodyPart];
}

- (BOOL)isEmpty {
return [self.HTTPBodyParts count] == 0;
}

#pragma mark - NSInputStream

- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length {
if ([self streamStatus] == NSStreamStatusClosed) {
return 0;
}

NSInteger totalNumberOfBytesRead = 0;

while ((NSUInteger)totalNumberOfBytesRead < MIN(length, self.numberOfBytesInPacket)) {
if (!self.currentHTTPBodyPart || ![self.currentHTTPBodyPart hasBytesAvailable]) {
if (!(self.currentHTTPBodyPart = [self.HTTPBodyPartEnumerator nextObject])) {
break;
}
} else {
NSUInteger maxLength = MIN(length, self.numberOfBytesInPacket) - (NSUInteger)totalNumberOfBytesRead;
NSInteger numberOfBytesRead = [self.currentHTTPBodyPart read:&buffer[totalNumberOfBytesRead] maxLength:maxLength];
if (numberOfBytesRead == -1) {
self.streamError = self.currentHTTPBodyPart.inputStream.streamError;
break;
} else {
totalNumberOfBytesRead += numberOfBytesRead;
if (self.delay > 0.0f) {
[NSThread sleepForTimeInterval:self.delay];
}
}
}
}
return totalNumberOfBytesRead;
}

- (BOOL)getBuffer:(__unused uint8_t * _Nullable *)buffer length:(__unused NSUInteger *)len {
return NO;
}

- (BOOL)hasBytesAvailable {
return [self streamStatus] == NSStreamStatusOpen;
}

#pragma mark - NSStream

- (void)open {
if (self.streamStatus == NSStreamStatusOpen) {
return;
}
self.streamStatus = NSStreamStatusOpen;
[self setInitialAndFinalBoundaries];
self.HTTPBodyPartEnumerator = [self.HTTPBodyParts objectEnumerator];
}

- (void)close {
self.streamStatus = NSStreamStatusClosed;
}

- (id)propertyForKey:(__unused NSStreamPropertyKey)key {
return nil;
}

- (BOOL)setProperty:(__unused id)property forKey:(__unused NSStreamPropertyKey)key {
return NO;
}

- (void)scheduleInRunLoop:(__unused NSRunLoop *)aRunLoop forMode:(__unused NSRunLoopMode)mode {

}

- (void)removeFromRunLoop:(__unused NSRunLoop *)aRunLoop forMode:(__unused NSRunLoopMode)mode {

}

- (unsigned long long)contentLength {
unsigned long long length = 0;
for (SQHTTPBodyPart *bodyPart in self.HTTPBodyParts) {
length += [bodyPart contentLength];
}
return length;
}

#pragma mark - Undocumented CFReadStream Bridged Methods

- (void)_scheduleInCFRunLoop:(__unused CFRunLoopRef)aRunLoop forMode:(__unused CFStringRef)aMode {

}

- (void)_unscheduleFromCFRunLoop:(__unused CFRunLoopRef)aRunLoop forMode:(__unused CFStringRef)aMode {

}

- (BOOL)_setCFClientFlags:(__unused CFOptionFlags)inFlags callback:(__unused CFReadStreamClientCallBack)inCallback context:(__unused CFStreamClientContext *)inContext {
return NO;
}

#pragma mark - NSCopying

- (instancetype)copyWithZone:(NSZone *)zone {
SQMultipartBodyStream *bodyStreamCopy = [[[self class] allocWithZone:zone] initWithStringEncoding:self.stringEncoding];
for (SQHTTPBodyPart *bodyPart in self.HTTPBodyParts) {
[bodyStreamCopy appendHTTPBodyPart:[bodyPart copy]];
}
[bodyStreamCopy setInitialAndFinalBoundaries];
return bodyStreamCopy;
}

@end
Binary file added SQDebug/AFNetworking/AFNetworking.xmind
Binary file not shown.
Loading

0 comments on commit 240ad3e

Please sign in to comment.