mirror of
https://github.com/Halofreak1990/XFXFramework
synced 2024-12-26 13:49:34 +01:00
Fixed String operator[] signature
Partially implemented Socket and SocketAsyncEventArgs
This commit is contained in:
parent
e234c493b4
commit
92ffadf6e0
@ -29,13 +29,13 @@ namespace System
|
||||
{
|
||||
private:
|
||||
AddressFamily_t addressFamily;
|
||||
/* true if we called Close_internal */
|
||||
bool closed;
|
||||
HANDLE handle;
|
||||
bool isConnected;
|
||||
ProtocolType_t protocolType;
|
||||
|
||||
protected:
|
||||
virtual ~Socket();
|
||||
|
||||
void Dispose(bool disposing);
|
||||
|
||||
public:
|
||||
@ -43,6 +43,7 @@ namespace System
|
||||
int Available() const;
|
||||
bool Connected() const;
|
||||
HANDLE getHandle() const;
|
||||
static bool OSSupportsIPv4();
|
||||
ProtocolType_t getProtocolType() const;
|
||||
int ReceiveBufferSize;
|
||||
EndPoint* getRemoteEndPoint() const;
|
||||
@ -50,20 +51,21 @@ namespace System
|
||||
short Ttl;
|
||||
|
||||
Socket(AddressFamily_t addressFamily, SocketType_t socketType, ProtocolType_t protocolType);
|
||||
virtual ~Socket();
|
||||
|
||||
static void CancelConnectAsync(SocketAsyncEventArgs e);
|
||||
static void CancelConnectAsync(SocketAsyncEventArgs * const e);
|
||||
void Close();
|
||||
void Close(int timeOut);
|
||||
static bool ConnectAsync(SocketType_t socketType, ProtocolType_t protocolType, SocketAsyncEventArgs e);
|
||||
bool ConnectAsync(SocketAsyncEventArgs e);
|
||||
bool ConnectAsync(SocketAsyncEventArgs * const e);
|
||||
void Dispose();
|
||||
void EndConnect(IAsyncResult * asyncResult);
|
||||
void EndDisconnect(IAsyncResult * asyncResult);
|
||||
static const Type& GetType();
|
||||
bool ReceiveAsync(SocketAsyncEventArgs e);
|
||||
bool ReceiveFromAsync(SocketAsyncEventArgs e);
|
||||
bool SendAsync(SocketAsyncEventArgs e);
|
||||
bool SendToAsync(SocketAsyncEventArgs e);
|
||||
bool ReceiveAsync(SocketAsyncEventArgs * const e);
|
||||
bool ReceiveFromAsync(SocketAsyncEventArgs * const e);
|
||||
bool SendAsync(SocketAsyncEventArgs * const e);
|
||||
bool SendToAsync(SocketAsyncEventArgs * const e);
|
||||
void Shutdown(SocketShutdown_t how);
|
||||
};
|
||||
}
|
||||
|
@ -23,8 +23,17 @@ namespace System
|
||||
class SocketAsyncEventArgs : public EventArgs, public IDisposable
|
||||
{
|
||||
private:
|
||||
int count;
|
||||
Socket* curSocket;
|
||||
int inProgress;
|
||||
bool isDisposed;
|
||||
SocketAsyncOperation_t lastOperation;
|
||||
int offset;
|
||||
friend class Socket;
|
||||
|
||||
void SetBufferInternal(byte buffer[], int offset, int count);
|
||||
void SetLastOperation(SocketAsyncOperation_t op);
|
||||
|
||||
protected:
|
||||
virtual void Oncompleted(SocketAsyncEventArgs* e);
|
||||
virtual ~SocketAsyncEventArgs();
|
||||
@ -44,6 +53,7 @@ namespace System
|
||||
EventHandler Completed;
|
||||
|
||||
SocketAsyncEventArgs();
|
||||
~SocketAsyncEventArgs();
|
||||
|
||||
void Dispose();
|
||||
static const Type& GetType();
|
||||
|
@ -91,7 +91,7 @@ namespace System
|
||||
String operator+=(const String& right);
|
||||
String operator+=(const char* right);
|
||||
String operator+(const String& right) const;
|
||||
const char operator [](const int index) const;
|
||||
const char& operator[](const int index) const;
|
||||
};
|
||||
|
||||
inline const String operator +(const char * left, const String& right)
|
||||
|
@ -17,7 +17,7 @@ namespace System
|
||||
// The value to be added to the integer at location1.
|
||||
// Returns
|
||||
// The new value stored at location1.
|
||||
static inline int Add(volatile long* const location1, const long value)
|
||||
static inline int Add(volatile int* const location1, const int value)
|
||||
{
|
||||
long retval = value;
|
||||
__asm__("lock; xaddl %[retval], %[location1]" : [retval] "+r" (retval) : [location1] "m" (*location1) : "memory");
|
||||
@ -49,9 +49,9 @@ namespace System
|
||||
// The value that is compared to the value at location1.
|
||||
// Returns
|
||||
// The original value in location1.
|
||||
static inline Int64 CompareExchange(volatile Int64* const Int64 location1, const Int64 value, const Int64 comparand)
|
||||
static inline long long CompareExchange(volatile long long* const location1, const long long value, const long long comparand)
|
||||
{
|
||||
Int64 retval = comparand;
|
||||
long long retval = comparand;
|
||||
|
||||
__asm__
|
||||
(
|
||||
@ -87,21 +87,21 @@ namespace System
|
||||
// The variable whose value is to be decremented.
|
||||
// Returns
|
||||
// The decremented value.
|
||||
static inline long Decrement(volatile long * const location)
|
||||
static inline long Decrement(volatile int * const location)
|
||||
{
|
||||
return Add(location, -1) - 1;
|
||||
}
|
||||
|
||||
// Sets a 32-bit signed integer to a specified value and returns the original value, as an atomic operation.
|
||||
// location1
|
||||
// The variable to set to the specified value.
|
||||
// The variable to set to the specified value.
|
||||
// value
|
||||
// The value to which the location1 parameter is set.
|
||||
// The value to which the location1 parameter is set.
|
||||
// Returns
|
||||
// The original value of location1.
|
||||
static inline long Exchange(volatile long* const location1, const long value)
|
||||
static inline int Exchange(volatile int * const location1, const int value)
|
||||
{
|
||||
long retval = value;
|
||||
int retval = value;
|
||||
__asm__("xchgl %[retval], %[location1]" : [retval] "+r" (retval) : [location1] "m" (*location1) : "memory");
|
||||
return retval;
|
||||
}
|
||||
@ -125,7 +125,7 @@ namespace System
|
||||
// The variable whose value is to be incremented.
|
||||
// Returns
|
||||
// The incremented value.
|
||||
static inline long Increment(volatile long * const location)
|
||||
static inline int Increment(volatile int * const location)
|
||||
{
|
||||
return Add(location, 1) + 1;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ namespace System
|
||||
|
||||
bool Socket::Connected() const
|
||||
{
|
||||
// TODO: implement
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
HANDLE Socket::getHandle() const
|
||||
@ -67,11 +67,16 @@ namespace System
|
||||
|
||||
ProtocolType_t Socket::getProtocolType() const
|
||||
{
|
||||
// TODO: implement
|
||||
return protocolType;
|
||||
}
|
||||
|
||||
EndPoint* Socket::getRemoteEndPoint() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Socket::Socket(AddressFamily_t addressFamily, SocketType_t socketType, ProtocolType_t protocolType)
|
||||
: addressFamily(addressFamily)
|
||||
: addressFamily(addressFamily), protocolType(protocolType)
|
||||
{
|
||||
// TODO: implement remainder
|
||||
}
|
||||
@ -91,9 +96,17 @@ namespace System
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
bool Socket::ConnectAsync(SocketAsyncEventArgs e)
|
||||
bool Socket::ConnectAsync(SocketAsyncEventArgs * const e)
|
||||
{
|
||||
// TODO: implement
|
||||
// NO check is made whether e != null in MS.NET (NRE is thrown in such case)
|
||||
if (disposed && closed)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType().ToString());
|
||||
}
|
||||
|
||||
sassert(e->RemoteEndPoint != null, String::Format("remoteEP: %s", FrameworkResources::ArgumentNull_Generic));
|
||||
|
||||
return ConnectAsyncReal(e);
|
||||
}
|
||||
|
||||
void Socket::Dispose()
|
||||
@ -103,12 +116,55 @@ namespace System
|
||||
|
||||
void Socket::EndConnect(IAsyncResult* asyncResult)
|
||||
{
|
||||
// TODO: implement
|
||||
sassert(!disposed || !closed, "");
|
||||
|
||||
sassert(asyncResult != null, String::Format("asyncResult: %s", FrameworkResources::ArgumentNull_Generic));
|
||||
|
||||
SocketAsyncResult * req = as<SocketAsyncResult *>(asyncResult);
|
||||
|
||||
sassert(req != null, "Invalid IAsyncResult");
|
||||
|
||||
if (Interlocked::CompareExchange(&req.EndCalled, 1, 0) == 1)
|
||||
{
|
||||
throw InvalidAsyncOp("EndConnect");
|
||||
}
|
||||
|
||||
if (!asyncResult->IsCompleted())
|
||||
{
|
||||
asyncResult->AsyncWaitHandle.WaitOne();
|
||||
}
|
||||
|
||||
req.CheckIfThrowDelayedException();
|
||||
}
|
||||
|
||||
void Socket::EndDisconnect(IAsyncResult* asyncResult)
|
||||
{
|
||||
// TODO: implement
|
||||
if (disposed && closed)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType ().ToString ());
|
||||
}
|
||||
|
||||
if (asyncResult == null)
|
||||
{
|
||||
throw new ArgumentNullException("asyncResult");
|
||||
}
|
||||
|
||||
SocketAsyncResult * req = as<SocketAsyncResult *>(asyncResult);
|
||||
|
||||
if (req == null)
|
||||
throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
|
||||
|
||||
if (Interlocked::CompareExchange(&req.EndCalled, 1, 0) == 1)
|
||||
{
|
||||
throw InvalidAsyncOp("EndDisconnect");
|
||||
}
|
||||
|
||||
if (!asyncResult->IsCompleted())
|
||||
{
|
||||
asyncResult->AsyncWaitHandle.WaitOne();
|
||||
}
|
||||
|
||||
req->CheckIfThrowDelayedException();
|
||||
}
|
||||
|
||||
const Type& Socket::GetType()
|
||||
@ -116,29 +172,208 @@ namespace System
|
||||
return SocketTypeInfo;
|
||||
}
|
||||
|
||||
bool Socket::ReceiveAsync(SocketAsyncEventArgs e)
|
||||
bool Socket::ReceiveAsync(SocketAsyncEventArgs * const e)
|
||||
{
|
||||
// TODO: implement
|
||||
// NO check is made whether e != null in MS.NET (NRE is thrown in such case)
|
||||
if (disposed && closed)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType ().ToString ());
|
||||
}
|
||||
|
||||
// LAME SPEC: the ArgumentException is never thrown, instead an NRE is
|
||||
// thrown when e.Buffer and e.BufferList are null (works fine when one is
|
||||
// set to a valid object)
|
||||
if (e->getBuffer() == null && e->BufferList == null)
|
||||
{
|
||||
throw new NullReferenceException ("Either e.Buffer or e.BufferList must be valid buffers.");
|
||||
}
|
||||
|
||||
e->curSocket = this;
|
||||
SocketOperation op = (e->getBuffer() != null) ? SocketOperation::Receive : SocketOperation::ReceiveGeneric;
|
||||
e->Worker.Init (this, e, op);
|
||||
SocketAsyncResult res = e->Worker.result;
|
||||
|
||||
if (e->getBuffer() != null)
|
||||
{
|
||||
res.Buffer = e->getBuffer();
|
||||
res.Offset = e->getOffset();
|
||||
res.Size = e->Count();
|
||||
}
|
||||
else
|
||||
{
|
||||
res.Buffers = e->BufferList;
|
||||
}
|
||||
|
||||
res.SockFlags = e->SocketFlags;
|
||||
int count;
|
||||
|
||||
lock (readQ)
|
||||
{
|
||||
readQ.Enqueue(e->Worker);
|
||||
count = readQ.Count;
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
// Receive takes care of ReceiveGeneric
|
||||
socket_pool_queue(Worker.Dispatcher, res);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Socket::ReceiveFromAsync(SocketAsyncEventArgs e)
|
||||
bool Socket::ReceiveFromAsync(SocketAsyncEventArgs * const e)
|
||||
{
|
||||
// TODO: implement
|
||||
if (disposed && closed)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType ().ToString ());
|
||||
}
|
||||
|
||||
// We do not support recv into multiple buffers yet
|
||||
if (e->getBufferList() != null)
|
||||
{
|
||||
throw new NotSupportedException("Mono doesn't support using BufferList at this point.");
|
||||
}
|
||||
|
||||
if (e->RemoteEndPoint == null)
|
||||
{
|
||||
throw new ArgumentNullException("remoteEP", "Value cannot be null.");
|
||||
}
|
||||
|
||||
e->curSocket = this;
|
||||
e->Worker.Init(this, e, SocketOperation::ReceiveFrom);
|
||||
SocketAsyncResult res = e->Worker.result;
|
||||
res.Buffer = e->getBuffer();
|
||||
res.Offset = e->getOffset();
|
||||
res.Size = e->Count();
|
||||
res.EndPoint = e->RemoteEndPoint;
|
||||
res.SockFlags = e->SocketFlags;
|
||||
int count;
|
||||
|
||||
lock (readQ)
|
||||
{
|
||||
readQ.Enqueue(e.Worker);
|
||||
count = readQ.Count;
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
socket_pool_queue (Worker.Dispatcher, res);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Socket::SendAsync(SocketAsyncEventArgs e)
|
||||
bool Socket::SendAsync(SocketAsyncEventArgs * const e)
|
||||
{
|
||||
// TODO: implement
|
||||
// NO check is made whether e != null in MS.NET (NRE is thrown in such case)
|
||||
if (disposed && closed)
|
||||
{
|
||||
throw new ObjectDisposedException (GetType ().ToString ());
|
||||
}
|
||||
|
||||
if (e->getBuffer() == null && e->BufferList == null)
|
||||
{
|
||||
throw new NullReferenceException("Either e.Buffer or e.BufferList must be valid buffers.");
|
||||
}
|
||||
|
||||
e->curSocket = this;
|
||||
SocketOperation op = (e->getBuffer() != null) ? SocketOperation::Send : SocketOperation::SendGeneric;
|
||||
e->Worker.Init(this, e, op);
|
||||
SocketAsyncResult res = e->Worker.result;
|
||||
|
||||
if (e->getBuffer() != null)
|
||||
{
|
||||
res.Buffer = e->getBuffer();
|
||||
res.Offset = e->getOffset();
|
||||
res.Size = e->Count();
|
||||
}
|
||||
else
|
||||
{
|
||||
res.Buffers = e->BufferList;
|
||||
}
|
||||
|
||||
res.SockFlags = e->SocketFlags;
|
||||
int count;
|
||||
|
||||
lock (writeQ)
|
||||
{
|
||||
writeQ.Enqueue(e.Worker);
|
||||
count = writeQ.Count;
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
// Send takes care of SendGeneric
|
||||
socket_pool_queue(Worker.Dispatcher, res);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Socket::SendToAsync(SocketAsyncEventArgs e)
|
||||
bool Socket::SendToAsync(SocketAsyncEventArgs * const e)
|
||||
{
|
||||
// TODO: implement
|
||||
// NO check is made whether e != null in MS.NET (NRE is thrown in such case)
|
||||
if (disposed && closed)
|
||||
{
|
||||
throw new ObjectDisposedException (GetType().ToString());
|
||||
}
|
||||
|
||||
if (e->BufferList != null)
|
||||
{
|
||||
throw new NotSupportedException ("Mono doesn't support using BufferList at this point.");
|
||||
}
|
||||
|
||||
if (e->RemoteEndPoint == null)
|
||||
{
|
||||
throw new ArgumentNullException("remoteEP", "Value cannot be null.");
|
||||
}
|
||||
|
||||
e->curSocket = this;
|
||||
e->Worker.Init(this, e, SocketOperation::SendTo);
|
||||
SocketAsyncResult res = e->Worker.result;
|
||||
res.Buffer = e->getBuffer();
|
||||
res.Offset = e->getOffset();
|
||||
res.Size = e->Count;
|
||||
res.SockFlags = e->SocketFlags;
|
||||
res.EndPoint = e->RemoteEndPoint;
|
||||
int count;
|
||||
|
||||
lock (writeQ)
|
||||
{
|
||||
writeQ.Enqueue(e->Worker);
|
||||
count = writeQ.Count;
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
{
|
||||
socket_pool_queue(Worker.Dispatcher, res);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Socket::Shutdown(SocketShutdown_t how)
|
||||
{
|
||||
if (disposed && closed)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType ().ToString ());
|
||||
}
|
||||
|
||||
if (!isConnected)
|
||||
{
|
||||
throw new SocketException(10057); // Not connected
|
||||
}
|
||||
|
||||
int error;
|
||||
|
||||
// TODO: implement
|
||||
Shutdown_internal(socket, how, out error);
|
||||
|
||||
if (error != 0)
|
||||
{
|
||||
throw new SocketException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,16 +25,21 @@
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <System/Threading/Interlocked.h>
|
||||
#include <System/Net/Sockets/SocketAsyncEventArgs.h>
|
||||
#include <System/Type.h>
|
||||
|
||||
#include <sassert.h>
|
||||
|
||||
using namespace System::Threading;
|
||||
|
||||
namespace System
|
||||
{
|
||||
namespace Net
|
||||
{
|
||||
namespace Sockets
|
||||
{
|
||||
const Type SocketAsyncEventArgsTypeInfo("SocketAsyncEventArgs", "SYstem::Net::Sockets::SocketAsyncEventArgs", TypeCode::Object);
|
||||
const Type SocketAsyncEventArgsTypeInfo("SocketAsyncEventArgs", "System::Net::Sockets::SocketAsyncEventArgs", TypeCode::Object);
|
||||
|
||||
byte * SocketAsyncEventArgs::getBuffer() const
|
||||
{
|
||||
@ -48,36 +53,50 @@ namespace System
|
||||
|
||||
Socket * SocketAsyncEventArgs::getConnectSocket() const
|
||||
{
|
||||
// TODO: implement
|
||||
switch (this->SocketError)
|
||||
{
|
||||
case SocketError::AccessDenied:
|
||||
return null;
|
||||
default:
|
||||
return curSocket;
|
||||
}
|
||||
}
|
||||
|
||||
int SocketAsyncEventArgs::Count() const
|
||||
{
|
||||
// TODO: implement
|
||||
return count;
|
||||
}
|
||||
|
||||
SocketAsyncOperation_t SocketAsyncEventArgs::getLastOperation() const
|
||||
{
|
||||
// TODO: implement
|
||||
return lastOperation;
|
||||
}
|
||||
|
||||
int SocketAsyncEventArgs::getOffset() const
|
||||
{
|
||||
// TODO: implement
|
||||
return offset;
|
||||
}
|
||||
|
||||
SocketAsyncEventArgs::SocketAsyncEventArgs()
|
||||
{
|
||||
lastOperation = SocketAsyncOperation::None;
|
||||
this->SocketError = SocketError::Success;
|
||||
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
SocketAsyncEventArgs::SocketAsyncEventArgs()
|
||||
SocketAsyncEventArgs::~SocketAsyncEventArgs()
|
||||
{
|
||||
// TODO: implement
|
||||
if (!isDisposed)
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
}
|
||||
|
||||
void SocketAsyncEventArgs::Dispose()
|
||||
{
|
||||
isDisposed = true;
|
||||
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
@ -86,10 +105,55 @@ namespace System
|
||||
return SocketAsyncEventArgsTypeInfo;
|
||||
}
|
||||
|
||||
void SocketAsyncEventArgs::Oncompleted(SocketAsyncEventArgs* e)
|
||||
void SocketAsyncEventArgs::Oncompleted(SocketAsyncEventArgs * e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Completed(this, e);
|
||||
}
|
||||
|
||||
void SocketAsyncEventArgs::SetBuffer(const int offset, const int count)
|
||||
{
|
||||
SetBufferInternal(getBuffer(), offset, count);
|
||||
}
|
||||
|
||||
void SocketAsyncEventArgs::SetBuffer(byte buffer[], const int offset, const int count)
|
||||
{
|
||||
SetBufferInternal(buffer, offset, count);
|
||||
}
|
||||
|
||||
void SocketAsyncEventArgs::SetBufferInternal(byte buffer[], int offset, int count)
|
||||
{
|
||||
if (buffer != null)
|
||||
{
|
||||
sassert(getBufferList() != null, "Buffer and BufferList properties cannot both be non-null.");
|
||||
|
||||
int buflen = buffer.Length;
|
||||
|
||||
sassert(offset >= 0 && offset < buflen, "");
|
||||
//throw new ArgumentOutOfRangeException("offset");
|
||||
|
||||
sassert(count >= 0 && count <= buflen - offset, "");
|
||||
//throw new ArgumentOutOfRangeException("count");
|
||||
|
||||
this->count = count;
|
||||
this->offset = offset;
|
||||
}
|
||||
|
||||
Buffer = buffer;
|
||||
}
|
||||
|
||||
void SocketAsyncEventArgs::SetLastOperation(SocketAsyncOperation_t op)
|
||||
{
|
||||
sassert(!isDisposed, "");
|
||||
|
||||
sassert(Interlocked::Exchange(&inProgress, 1) == 0, "");
|
||||
|
||||
lastOperation = op;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ namespace System
|
||||
return result;
|
||||
}
|
||||
|
||||
const char String::operator [](const int index) const
|
||||
const char& String::operator [](const int index) const
|
||||
{
|
||||
sassert(index > 0 && index < Length, "index out of range.");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user