void VJSImage::_thumbnail(XBOX::VJSParms_callStaticFunction& ioParms, VJSPictureContainer* inPict)
{
	bool ok = true;
	if (!ioParms.IsNumberParam(1))
	{
		ok = false;
		vThrowError(VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1");
	}
	if (!ioParms.IsNumberParam(2))
	{
		ok = false;
		vThrowError(VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "2");
	}
	VPicture* pic = inPict->GetPict();
	if (pic != nil && ok)
	{
		sLONG w = 0, h = 0, mode = 0;
		ioParms.GetLongParam(1, &w);
		ioParms.GetLongParam(2, &h);
		ioParms.GetLongParam(3, &mode);
		if (w == 0)
			w = 300;
		if (h == 0)
			h = 300;
		if (mode == 0)
			mode = 4;
		VPicture* thumb = pic->BuildThumbnail(w, h, (PictureMosaic)mode);
		if (thumb != nil)
		{
			VPictureCodecFactoryRef fact;
			VPicture* thumb2 = new VPicture();
			VError err = fact->Encode(*thumb, L".jpg", *thumb2, nil);
			if (err == VE_OK)
			{
				/*
				VJSPictureContainer* pictContains = new VJSPictureContainer(thumb2, true, ioParms.GetContextRef());
				ioParms.ReturnValue(VJSImage::CreateInstance(ioParms.GetContextRef(), pictContains));
				pictContains->Release();
				*/
				ioParms.ReturnVValue(*thumb2);
				delete thumb2;
			}
			else
			{
				delete thumb2;
				ioParms.ReturnNullValue();
			}
			delete thumb;
		}
		else
			ioParms.ReturnNullValue();
	}
	else
		ioParms.ReturnNullValue();
}
void VJSNetServerClass::_pause (XBOX::VJSParms_callStaticFunction &ioParms, VJSNetServerObject *inServer)
{
	xbox_assert(inServer != NULL);

	sLONG	waitingTime;	// In milliseconds.

	if (!ioParms.CountParams())

		waitingTime = 1;

	else if (ioParms.CountParams() != 1 || !ioParms.IsNumberParam(1) || !ioParms.GetLongParam(1, &waitingTime)) {

		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1");
		return;

	}

	// Need support from VTCPConnectionListener.

	XBOX::vThrowError(XBOX::VE_JVSC_UNSUPPORTED_FUNCTION, "net.Server.pause()");
}
void VJSNetServerSyncClass::_accept (XBOX::VJSParms_callStaticFunction &ioParms, VJSNetServerObject *inServer)
{
	xbox_assert(inServer != NULL);

	sLONG	timeOut;

	if (ioParms.CountParams() >= 1) {

		if (!ioParms.IsNumberParam(1) || !ioParms.GetLongParam(1, &timeOut)) {

			XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1");
			return;

		}

		if (timeOut < 0) {

			XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1");
			return;

		}

	} else

		timeOut = 0;

	XBOX::XTCPSock	*socket;

	// If socket returned is NULL, accept() has timed out or an error has occured.
	// An exception is thrown by GetNewConnectedSocket() if erroneous.

	if ((socket = inServer->fSockListener->GetNewConnectedSocket(timeOut)) == NULL) 

		ioParms.ReturnNullValue();

	else {

		XBOX::VTCPEndPoint	*endPoint		= NULL;
		VJSNetSocketObject	*socketObject	= NULL;
	
		if ((endPoint = new XBOX::VTCPEndPoint(socket)) == NULL 
		|| (socketObject = new VJSNetSocketObject(true, VJSNetSocketObject::eTYPE_TCP4, false)) == NULL) {

			if (endPoint != NULL)

				endPoint->Release();

			if (socketObject != NULL)

				socketObject->Release();

			socket->Close();
			delete socket;

			XBOX::vThrowError(XBOX::VE_MEMORY_FULL);
		
		} else {

			socketObject->fEndPoint = endPoint;
			socketObject->fEndPoint->SetNoDelay(false);

			XBOX::VJSObject	newSocketSync = VJSNetSocketSyncClass::CreateInstance(ioParms.GetContext(), socketObject);
			XBOX::VString	address;

			socketObject->fObjectRef = newSocketSync.GetObjectRef();
			socketObject->fWorker = VJSWorker::RetainWorker(ioParms.GetContext());

			socketObject->fEndPoint->GetIP(address);
			newSocketSync.SetProperty("remoteAddress", address);
			newSocketSync.SetProperty("remotePort", (sLONG) socketObject->fEndPoint->GetPort() & 0xffff);

			ioParms.ReturnValue(newSocketSync);

		}

	}
}
void VJSNetServerSyncClass::_listen (XBOX::VJSParms_callStaticFunction &ioParms, VJSNetServerObject *inServer)
{
	xbox_assert(inServer != NULL);

	sLONG	port;

	if (ioParms.CountParams() >= 1) {

		if (!ioParms.IsNumberParam(1) || !ioParms.GetLongParam(1, &port)) {

			XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1");
			return;

		}

	} else

		port = 0;		// Will use a random port (useful?).

// Re-use code of async listen().

#if WITH_DEPRECATED_IPV4_API
	
	uLONG	address;

	if (ioParms.CountParams() >= 2) {

		XBOX::VString	hostname;

		if (!ioParms.IsStringParam(2) || !ioParms.GetStringParam(2, hostname)) {

			XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_STRING, "2");
			return;

		}

		address = XBOX::ServerNetTools::ResolveAddress(hostname);

	} else

		address = 0;	// Same as "localhost".

#else

	//jmo - je ne comprends pas bien la logique du resolve sur le hostname...
	//      On veut une IP 'publique' ? J'ai simplifié.
	
	VString address=VNetAddress::GetAnyIP();

#endif
	
	// We are already listening, stop previous listener.

	if (inServer->fConnectionListener != NULL)

		inServer->Close();

	// Setup new listener.

	if ((inServer->fSockListener = new XBOX::VSockListener()) == NULL) {

		XBOX::vThrowError(XBOX::VE_MEMORY_FULL);
		return;

	}

	XBOX::VError	error;

	error = XBOX::VE_OK;
	if (inServer->fIsSSL)
		
		error = inServer->fSockListener->SetKeyAndCertificate(inServer->fKey, inServer->fCertificate);

	if (error != XBOX::VE_OK) {

		inServer->Close();
		XBOX::vThrowError(error);

	}
	else if (!inServer->fSockListener->SetBlocking(true)
	|| !inServer->fSockListener->AddListeningPort(address, port, inServer->fIsSSL)	
	|| !inServer->fSockListener->StartListening()) {

		inServer->Close();
		XBOX::vThrowError(XBOX::VE_SRVR_FAILED_TO_CREATE_LISTENING_SOCKET);
		
	}
	else {

		inServer->fAddress = address;	
		inServer->fPort = port;	

	}
}
void VJSNetServerClass::_listen (XBOX::VJSParms_callStaticFunction &ioParms, VJSNetServerObject *inServer)
{
	xbox_assert(inServer != NULL);

	XBOX::VString	address;
	sLONG			port;

	if (!ioParms.CountParams()) {

		XBOX::vThrowError(XBOX::VE_JVSC_EXPECTING_PARAMETER, "net.Server.listen()");
		return;

	}

	if (!ioParms.IsNumberParam(1) || !ioParms.GetLongParam(1, &port)) {
		
		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1");
		return;

	}

	XBOX::VString	hostname;
	XBOX::VJSObject	callback(ioParms.GetContext());
	bool			hasCallback;

	hostname = "";
	hasCallback = false;
	if (ioParms.CountParams() >= 2) {

		if (ioParms.IsStringParam(2)) {
			
			if (!ioParms.GetStringParam(2, hostname)) {

				XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_STRING, "2");
				return;

			}

		} else if (ioParms.IsObjectParam(2) && ioParms.GetParamFunc(2, callback)) {

			hasCallback = true;

		} else {

			XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_FUNCTION, "2");
			return;

		}

	} 

	if (ioParms.CountParams() == 3 ) {
	
		if ((hasCallback || !ioParms.IsObjectParam(3) || !ioParms.GetParamFunc(3, callback))) {

			XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_FUNCTION, "3");
			return;

		} else

			hasCallback = true;

	}

	// We are already listening, stop previous listener.

	if (inServer->fConnectionListener != NULL)

		inServer->Close();

	// Set up listener.
	
	if ((inServer->fConnectionListener = new XBOX::VTCPConnectionListener())== NULL) {

		XBOX::vThrowError(XBOX::VE_MEMORY_FULL);
		return;

	} 

	if (inServer->fIsSSL)

		inServer->fConnectionListener->SetSSLKeyAndCertificate(inServer->fCertificate, inServer->fKey);

	VJSNetSocketObject::sMutex.Lock();

	if (VJSNetSocketObject::sSelectIOPool == NULL)

		VJSNetSocketObject::sSelectIOPool = new XBOX::VTCPSelectIOPool();

	VJSNetSocketObject::sMutex.Unlock();

	inServer->fConnectionListener->AddSelectIOPool(VJSNetSocketObject::sSelectIOPool);

	VJSWorker	*worker;

	worker = VJSWorker::RetainWorker(ioParms.GetContext());

	VJSConnectionHandlerFactory	*connectionHandlerFactory;
	
	if ((connectionHandlerFactory = new VJSConnectionHandlerFactory(worker, inServer, inServer->fIsSSL)) == NULL) {

		XBOX::vThrowError(XBOX::VE_MEMORY_FULL);
		XBOX::ReleaseRefCountable<VJSWorker>(&worker);
		return;

	}

#if WITH_DEPRECATED_IPV4_API
	
	sLONG	resolvedAddress;

	if (hostname.GetLength()) {

		address = hostname;
		resolvedAddress = XBOX::ServerNetTools::ResolveAddress(hostname);

	} else {

		address = "0.0.0.0";

		std::vector<IP4>	localIPs;

		if (XBOX::ServerNetTools::GetLocalIPv4Addresses(localIPs))

			resolvedAddress = localIPs[0];

		else

			resolvedAddress = 0;	// Should be same as above.

	}

	connectionHandlerFactory->SetIP(resolvedAddress);

#else

	XBOX::VNetAddressList	addrList;
	bool				isIPv6;

	if (hostname.GetLength()) {

		XBOX::VNetAddress	addr(hostname, port);

		isIPv6 = addr.IsV6();
		addrList.FromDnsQuery(hostname, port);
		
	} else {

		addrList.FromLocalInterfaces();
		isIPv6 = false;

	}

	// Always take first matching type address.

	XBOX::VNetAddressList::const_iterator	it;

	for (it = addrList.begin(); it != addrList.end(); it++)

		if ((*it).IsV6() == isIPv6)

			break;

	address = (*it).GetIP();
		
	connectionHandlerFactory->SetIP(address);

#endif	

	connectionHandlerFactory->AddNewPort(port);

	XBOX::VError	error;

	error = inServer->fConnectionListener->AddConnectionHandlerFactory(connectionHandlerFactory);
	connectionHandlerFactory->Release();	// AddConnectionHandlerFactory() has done a retain().

	if (error != XBOX::VE_OK 
	|| (error = inServer->fConnectionListener->StartListening()) != XBOX::VE_OK) 
		
		XBOX::vThrowError(error);

	else {

		inServer->fAddress = address;
		inServer->fPort = port;
			
		if (hasCallback) 
			
			inServer->AddListener("listening", callback, false);
		
		worker->QueueEvent(VJSNetEvent::Create(inServer, "listening"));

	}
	XBOX::ReleaseRefCountable<VJSWorker>(&worker);
}