Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
204
libs/platform/socket_apple.mm
Normal file
204
libs/platform/socket_apple.mm
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include "platform/socket.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
|
||||
@interface SocketImpl : NSObject
|
||||
|
||||
@property(nonatomic) NSInputStream * inputStream;
|
||||
@property(nonatomic) NSOutputStream * outputStream;
|
||||
|
||||
@property(nonatomic) uint32_t timeout;
|
||||
|
||||
- (BOOL)open:(NSString *)host port:(NSUInteger)port;
|
||||
- (void)close;
|
||||
|
||||
- (BOOL)read:(uint8_t *)data count:(NSUInteger)count;
|
||||
- (BOOL)write:(uint8_t const *)data count:(NSUInteger)count;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SocketImpl
|
||||
|
||||
- (BOOL)open:(NSString *)host port:(NSUInteger)port
|
||||
{
|
||||
[self close];
|
||||
|
||||
NSDate * openStart = [NSDate date];
|
||||
|
||||
CFReadStreamRef readStream;
|
||||
CFWriteStreamRef writeStream;
|
||||
|
||||
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(host), (UInt32)port, &readStream,
|
||||
&writeStream);
|
||||
|
||||
NSDictionary * settings = @{
|
||||
#ifndef RELEASE
|
||||
(id)kCFStreamSSLValidatesCertificateChain : @NO,
|
||||
#endif
|
||||
(id)kCFStreamSSLLevel : (id)kCFStreamSocketSecurityLevelNegotiatedSSL
|
||||
};
|
||||
|
||||
CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
|
||||
CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
|
||||
|
||||
self.inputStream = (__bridge_transfer NSInputStream *)readStream;
|
||||
self.outputStream = (__bridge_transfer NSOutputStream *)writeStream;
|
||||
|
||||
[self.inputStream open];
|
||||
[self.outputStream open];
|
||||
|
||||
while ([[NSDate date] timeIntervalSinceDate:openStart] < self.timeout)
|
||||
{
|
||||
NSStreamStatus const inputStreamStatus = self.inputStream.streamStatus;
|
||||
NSStreamStatus const outputStreamStatus = self.outputStream.streamStatus;
|
||||
if (inputStreamStatus == NSStreamStatusError || outputStreamStatus == NSStreamStatusError)
|
||||
return NO;
|
||||
if (inputStreamStatus == NSStreamStatusOpen && outputStreamStatus == NSStreamStatusOpen)
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)close
|
||||
{
|
||||
if (self.inputStream)
|
||||
{
|
||||
[self.inputStream close];
|
||||
self.inputStream = nil;
|
||||
}
|
||||
|
||||
if (self.outputStream)
|
||||
{
|
||||
[self.outputStream close];
|
||||
self.outputStream = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)read:(uint8_t *)data count:(NSUInteger)count
|
||||
{
|
||||
if (!self.inputStream || self.inputStream.streamStatus != NSStreamStatusOpen)
|
||||
return NO;
|
||||
|
||||
NSDate * readStart = [NSDate date];
|
||||
uint8_t * readPtr = data;
|
||||
while (count != 0 && [[NSDate date] timeIntervalSinceDate:readStart] < self.timeout)
|
||||
{
|
||||
NSInteger const readCount = [self.inputStream read:readPtr maxLength:count];
|
||||
|
||||
if (readCount > 0)
|
||||
{
|
||||
LOG(LDEBUG, ("Stream has read ", readCount, " bytes."));
|
||||
count -= readCount;
|
||||
readPtr += readCount;
|
||||
}
|
||||
else if (readCount == 0)
|
||||
{
|
||||
LOG(LDEBUG, ("The end of the read buffer was reached."));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LERROR, ("An error has occurred on the read stream."));
|
||||
#ifdef RELEASE
|
||||
LOG(LERROR, (self.inputStream.streamError));
|
||||
#else
|
||||
NSLog(@"%@", self.inputStream.streamError);
|
||||
#endif
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
- (BOOL)write:(uint8_t const *)data count:(NSUInteger)count
|
||||
{
|
||||
if (!self.outputStream || self.outputStream.streamStatus != NSStreamStatusOpen)
|
||||
return NO;
|
||||
|
||||
uint8_t const * writePtr = data;
|
||||
|
||||
NSDate * writeStart = [NSDate date];
|
||||
while (count != 0 && [[NSDate date] timeIntervalSinceDate:writeStart] < self.timeout)
|
||||
{
|
||||
NSInteger const writeCount = [self.outputStream write:writePtr maxLength:count];
|
||||
|
||||
if (writeCount > 0)
|
||||
{
|
||||
LOG(LDEBUG, ("Stream has written ", writeCount, " bytes."));
|
||||
count -= writeCount;
|
||||
writePtr += writeCount;
|
||||
}
|
||||
else if (writeCount == 0)
|
||||
{
|
||||
LOG(LDEBUG, ("The end of the write stream has been reached."));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LERROR, ("An error has occurred on the write stream."));
|
||||
#ifdef RELEASE
|
||||
LOG(LERROR, (self.outputStream.streamError));
|
||||
#else
|
||||
NSLog(@"%@", self.outputStream.streamError);
|
||||
#endif
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace platform
|
||||
{
|
||||
class PlatformSocket final : public Socket
|
||||
{
|
||||
public:
|
||||
PlatformSocket();
|
||||
// Socket overrides
|
||||
~PlatformSocket();
|
||||
bool Open(std::string const & host, uint16_t port) override;
|
||||
void Close() override;
|
||||
bool Read(uint8_t * data, uint32_t count) override;
|
||||
bool Write(uint8_t const * data, uint32_t count) override;
|
||||
void SetTimeout(uint32_t milliseconds) override;
|
||||
|
||||
private:
|
||||
SocketImpl * m_socketImpl = nullptr;
|
||||
};
|
||||
|
||||
std::unique_ptr<Socket> CreateSocket()
|
||||
{
|
||||
return std::make_unique<PlatformSocket>();
|
||||
}
|
||||
|
||||
PlatformSocket::PlatformSocket() { m_socketImpl = [[SocketImpl alloc] init]; }
|
||||
|
||||
PlatformSocket::~PlatformSocket()
|
||||
{
|
||||
Close();
|
||||
m_socketImpl = nullptr;
|
||||
}
|
||||
|
||||
bool PlatformSocket::Open(std::string const & host, uint16_t port)
|
||||
{
|
||||
return [m_socketImpl open:@(host.c_str()) port:port];
|
||||
}
|
||||
|
||||
void PlatformSocket::Close() { [m_socketImpl close]; }
|
||||
|
||||
bool PlatformSocket::Read(uint8_t * data, uint32_t count)
|
||||
{
|
||||
return [m_socketImpl read:data count:count];
|
||||
}
|
||||
|
||||
bool PlatformSocket::Write(uint8_t const * data, uint32_t count)
|
||||
{
|
||||
return [m_socketImpl write:data count:count];
|
||||
}
|
||||
|
||||
void PlatformSocket::SetTimeout(uint32_t milliseconds) { m_socketImpl.timeout = milliseconds; }
|
||||
} // namespace platform
|
||||
Loading…
Add table
Add a link
Reference in a new issue