1
0
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:
Tom Lint 2014-07-22 17:02:45 +02:00
parent e234c493b4
commit 92ffadf6e0
7 changed files with 353 additions and 42 deletions

View File

@ -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);
};
}

View File

@ -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();

View File

@ -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)

View File

@ -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;
}

View File

@ -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);
}
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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.");