VError VPictureData_MacPicture::SaveToFile(VFile& inFile)const
{
	VError result = VE_OK;
	if (fDataProvider && fDataProvider->GetDataSize())
	{
		VPtr p = fDataProvider->BeginDirectAccess();
		if (p)
		{
			result = inFile.Create();
			if (result == VE_OK)
			{
				VFileDesc* inFileDesc;
				result = inFile.Open(FA_READ_WRITE, &inFileDesc);
				if (result == VE_OK)
				{
					char buff[0x200];
					memset(buff, 0, 0x200);
					result = inFileDesc->PutData(buff, 0x200, 0);
					if (result == VE_OK)
					{
						result = inFileDesc->PutData(p, fDataProvider->GetDataSize(), 0x200);
					}
					delete inFileDesc;
				}
			}
			fDataProvider->EndDirectAccess();
		}
		else
			fDataProvider->ThrowLastError();

	}
	else
	{
		VBlobWithPtr blob;
		VSize outsize;
		result = Save(&blob, 0, outsize);
		if (result == VE_OK)
		{
			result = inFile.Create();
			if (result == VE_OK)
			{
				VFileDesc* inFileDesc;
				result = inFile.Open(FA_READ_WRITE, &inFileDesc);
				if (result == VE_OK)
				{
					char buff[0x200];
					memset(buff, 0, 0x200);
					result = inFileDesc->PutData(buff, 0x200, 0);
					if (result == VE_OK)
					{
						result = inFileDesc->PutData(blob.GetDataPtr(), blob.GetSize(), 0x200);
					}
					delete inFileDesc;
				}
			}
		}
	}
	return result;
}
VError VPictureData_GDIPlus::Save(VBlob* inData,VIndex inOffset,VSize& outSize,_VPictureAccumulator* /*inRecorder*/)const
{
	VError result=VE_UNKNOWN_ERROR;
	if(fDataProvider)
	{
		return inherited::Save(inData,inOffset,outSize);
	}
	else
	{
		if(fBitmap)
		{
			VBlobWithPtr blob;
				
			bool savedone=false;
			const VPictureCodec* deco=RetainDecoder();
			if(deco)
			{
				if(!deco->IsEncoder())
				{
					ReleaseRefCountable(&deco);
				}
			}
			if(!deco)
			{
				VPictureCodecFactoryRef fact;
				deco=fact->RetainDecoderByIdentifier(".png");
			}
			if(deco)
			{
					
				result = deco->Encode(this,NULL,blob); 
					
				if(result==VE_OK)
				{
					outSize=blob.GetSize();
					result=inData->PutData(blob.GetDataPtr(),outSize,inOffset);
				}
			}
		}

		/*
		if(fBitmap)
		{
			DWORD err;
			IStream* stream=NULL; 
			err= ::CreateStreamOnHGlobal(NULL,true,&stream);
			if(err == S_OK)
			{
				VPictureCodecFactoryRef fact;
				const xGDIPlusDecoderList& encoderlist=fact->xGetGDIPlus_Decoder();
				
				Gdiplus::Status stat = Gdiplus::GenericError;

				CLSID encoder;
				
				
				if(encoderlist.FindClassID(*fBitmap,encoder))
				{
					stat = fBitmap->Save(stream,&encoder,NULL);
				
					HGLOBAL glob;
					GetHGlobalFromStream(stream,&glob);
					char* c=(char*)GlobalLock(glob);
					outSize=GlobalSize(glob);
					result = inData->PutData(c,outSize,inOffset);
					GlobalUnlock(glob);
					stream->Release();
				}
				else
				{
					assert(false);
				}
			}
		}
		*/
	}
	return result;
}
void testMySQLConnectorPreparedStatementWithTypeBlob()
{
    CSQLConnector* connector = (CSQLConnector*) ( VComponentManager::RetainComponent ( 'MYSQ', 'SQL ' ) );

    VJSONObject* params = new VJSONObject();

    params->SetProperty ( "hostname",	MYSQL_HOST );

    params->SetProperty ( "user",		MYSQL_USER );

    params->SetProperty ( "password",	MYSQL_CORRECT_PASSWORD );

    params->SetProperty ( "database",	MYSQL_DATABASE );

    params->SetProperty ( "port",		MYSQL_PORT );

    params->SetProperty ( "ssl",			MYSQL_SSL_FALSE );

    ISQLSession* session = connector->CreateSession ( params );

    ReleaseRefCountable ( &params );

    if ( session != NULL )
    {
        ISQLStatement* statement = session->CreateStatement ( "SELECT * FROM test_blob" );

        VError error = VE_OK;

        ISQLPreparedStatement* pStmt = statement->CreatePreparedStatement ( error );

        ISQLResultSet* res = pStmt->Execute ( error );

        if ( error == VE_OK )
        {
            if ( res->IsError() )
            {
                printf ( "an error occured in the execution of the prepared statement!\n" );
            }
            else
            {
                uBYTE expected[3][16] =
                {
                    {0x0f, 0xC9, 0xCB, 0xBB, 0xCC, 0xCE, 0xB9, 0xC8, 0xCA, 0xBC, 0xCC, 0xCE, 0xB9, 0xC9, 0xCB, 0xBB},
                    {0x03, 0xAB, 0xCD, 0xEF},
                    {0x00}
                };

                sLONG i = 0;

                bool ok = true;

                while ( !res->IsEOF() )
                {
                    ISQLRow* row = res->RetainNextRow();

                    VValue* value = row->GetNthValue ( 2 );

                    VBlobWithPtr* blobValue = static_cast<VBlobWithPtr*> ( value );

                    sLONG8 len = blobValue->GetSize();



                    if ( len != expected[i][0] )
                    {
                        ok = false;
                    }
                    else if ( len == 0 )
                    {

                    }
                    else
                    {
                        uBYTE* buffer = ( uBYTE* ) ::malloc ( len );

                        xbox::VSize copied;

                        blobValue->GetData ( buffer, len, 0, &copied );

                        for ( sLONG n = 0; n < len; ++n )
                        {
                            if ( expected[i][n + 1] != buffer[n] )
                            {
                                ok = false;

                                break;
                            }
                        }
                    }


                    ReleaseRefCountable ( &row );

                    ++i;
                }

                if ( ok )
                {
                    printf ( "testMySQLConnectorPreparedStatementWithTypeBlob is OK\n" );
                }
                else
                {
                    printf ( "testMySQLConnectorPreparedStatementWithTypeBlob is KO\n" );
                }
            }

            ReleaseRefCountable ( &res );
        }
        else
        {
            printf ( "an error occured in the execution of the prepared statement!\n" );
        }

        ReleaseRefCountable ( &session );
    }
    else
    {
        printf ( "connection to mysql server failed ..\n" );
    }

    ReleaseRefCountable ( &connector );
}
VError VZipComponent::ExpandBlob(VBlob *inCompressedBlob , VBlob *outExpandedBlob)
{
	if(!testAssert(inCompressedBlob != NULL))
		return VE_INVALID_PARAMETER;
	if(!testAssert(outExpandedBlob != NULL))
		return VE_INVALID_PARAMETER;
	
	VError errorToReturn = VE_OK;
	
	
	VBlobStream* expandedBlobStream = new VBlobStream();	
	VError openWritingExpandedBlobStream = expandedBlobStream -> OpenWriting();			
	if (openWritingExpandedBlobStream != VE_OK)
		errorToReturn = vThrowError(VE_ZIP_CANNOT_ACCESS_BLOB_CONTENT);
	
	
	if (errorToReturn == VE_OK){
		
		VBlobWithPtr* compressedBlobWithPtr = new VBlobWithPtr(*inCompressedBlob);
		
		if (errorToReturn == VE_OK){ 
			
			errorToReturn = ExpandMemoryBlock(compressedBlobWithPtr->GetDataPtr(), inCompressedBlob->GetSize(), expandedBlobStream);
			
			if (errorToReturn == VE_ZIP_NON_COMPRESSED_INPUT_DATA){
				errorToReturn = vThrowError(VE_ZIP_NON_COMPRESSED_INPUT_BLOB);	
			}
			
			if (errorToReturn == VE_OK){
				
				// Once the decompression succeded, we have to put the content of expandedBlobStream in outExpandedBlob. 
				//To do so, we have to pass via a temporary buffer to transfer these data (since the class VBlob does not inherit IStreamable). 
				errorToReturn = expandedBlobStream -> CloseWriting(true);
				
				if (errorToReturn == VE_OK){
					
					errorToReturn = expandedBlobStream -> OpenReading();
					
					sLONG8 expandedBlobStreamSize = expandedBlobStream -> GetSize();
					Bytef * expandedBuffer = (Bytef *) malloc(expandedBlobStreamSize  * sizeof(Bytef));	
					if (expandedBuffer == NULL){
						errorToReturn = vThrowError(VE_MEMORY_FULL);
					}	
					
					if (errorToReturn == VE_OK){
						// if everything is ok, the data of expandedBlobStream are copyied in the temporary buffer
						errorToReturn = expandedBlobStream -> GetData(expandedBuffer, expandedBlobStreamSize);
						expandedBlobStream -> CloseReading();
						
						
						if (errorToReturn == VE_OK){
							// if everything is still ok, the data of the temporary buffer are copyied in outExpandedBlob
							errorToReturn = outExpandedBlob -> PutData(expandedBuffer, expandedBlobStreamSize);
						}
					}	
					
					if (expandedBuffer != NULL)
						free(expandedBuffer); 
				}				
			}
		}
		
		// if something wrong occured with streams either in decompression (streams cannot be read, opened, closed, etc.) or in transfering data to outExpandedBlob
		// note: if it is a pure decompression error, this error is thrown.
		if (errorToReturn != VE_OK && errorToReturn != VE_ZIP_DECOMPRESSION_FAILED && errorToReturn != VE_ZIP_NON_COMPRESSED_INPUT_BLOB){
			errorToReturn = vThrowError(VE_ZIP_CANNOT_ACCESS_BLOB_CONTENT);
		}
	}
	delete expandedBlobStream;
	
	return errorToReturn;	
}  
VError VZipComponent::CompressBlob( VBlob *inBlobToCompress , const EZipCompressionLevel inCompressionLevel , VBlob *outCompressedBlob )
{
	if(!testAssert(inBlobToCompress != NULL))
		return VE_INVALID_PARAMETER;
	if(!testAssert(outCompressedBlob != NULL))
		return VE_INVALID_PARAMETER;
	
	VError errorToReturn = VE_OK;
	
	
	VBlobStream* compressedBlobStream = new VBlobStream();
	
	errorToReturn = compressedBlobStream -> OpenWriting();	
	if (errorToReturn != VE_OK)
		errorToReturn = vThrowError(VE_ZIP_CANNOT_ACCESS_BLOB_CONTENT);

	
	if (errorToReturn == VE_OK){ 
	
		VBlobWithPtr* blobWithPtrToCompress = new VBlobWithPtr(*inBlobToCompress);
		
		if (errorToReturn == VE_OK){
			
			errorToReturn = CompressMemoryBlock(blobWithPtrToCompress->GetDataPtr(), inBlobToCompress->GetSize(), inCompressionLevel, compressedBlobStream);
			
			if (errorToReturn == VE_OK){
				
				// Once the compression succedeed, we have to put the content of compressedBlobStream in outCompressedBlob. 
				//To do so, we have to pass via a temporary buffer to transfer these data (since the class VBlob does not inherit IStreamable). 
				errorToReturn = compressedBlobStream -> CloseWriting(true);
				
				if (errorToReturn == VE_OK){
										
					errorToReturn = compressedBlobStream -> OpenReading();
					
					if (errorToReturn == VE_OK){
						
						sLONG8 compressedBlobStreamSize = compressedBlobStream -> GetSize();
						Bytef * compressedBuffer = (Bytef *) malloc(compressedBlobStreamSize  * sizeof(Bytef));	
						if (compressedBuffer == NULL){
							errorToReturn = vThrowError(VE_MEMORY_FULL);
						}	
						
						if (errorToReturn == VE_OK){
							
							// if everything is ok, the data of compressedBlobStream are copyied in the temporary buffer
							errorToReturn = compressedBlobStream -> GetData(compressedBuffer, compressedBlobStreamSize);
							compressedBlobStream -> CloseReading();
							
							if (errorToReturn == VE_OK){
								// if everything is still ok, the data of the temporary buffer are copyied in outCompressedBlob
								errorToReturn = outCompressedBlob -> PutData(compressedBuffer, compressedBlobStreamSize);
								
							}
						}	
						
						if (compressedBuffer != NULL)
							free(compressedBuffer);	
					} 
				}
				
				// if something wrong occured with streams either in compression (streams cannot be read, opened, closed, etc.) or in transfering data to outCompressedBlob
				// note: if it is a pure compression error, this error is thrown.
				if (errorToReturn != VE_OK && errorToReturn != VE_ZIP_COMPRESSION_FAILED){
					errorToReturn = vThrowError(VE_ZIP_CANNOT_ACCESS_BLOB_CONTENT);
				}
			}
		}
	
		delete blobWithPtrToCompress;
	}
	delete compressedBlobStream; 
	return errorToReturn; 
}
VValueSingle *JS4D::ValueToVValue( ContextRef inContext, ValueRef inValue, ValueRef *outException)
{
	if (inValue == NULL)
		return NULL;
	
	VValueSingle *value;
	JSType type = JSValueGetType( inContext, inValue);
	switch( type)
	{
		case kJSTypeUndefined:
		case kJSTypeNull:
			value = NULL;	//new VEmpty;
			break;
		
		case kJSTypeBoolean:
			value = new VBoolean( JSValueToBoolean( inContext, inValue));
			break;

		case kJSTypeNumber:
			value = new VReal( JSValueToNumber( inContext, inValue, outException));
			break;

		case kJSTypeString:
			{
				JSStringRef jsString = JSValueToStringCopy( inContext, inValue, outException);
				if (jsString != NULL)
				{
					VString *s = new VString;
					size_t length = JSStringGetLength( jsString);
					UniChar *p = (s != NULL) ? s->GetCPointerForWrite( length) : NULL;
					if (p != NULL)
					{
						::memcpy( p, JSStringGetCharactersPtr( jsString), length * sizeof( UniChar));
						s->Validate( length);
						value = s;
					}
					else
					{
						delete s;
						value = NULL;
					}
					JSStringRelease( jsString);
				}
				else
				{
					value = NULL;
				}
				break;
			}
		
		case kJSTypeObject:
			{
				if (ValueIsInstanceOf( inContext, inValue, CVSTR( "Date"), outException))
				{
					VTime *time = new VTime;
					if (time != NULL)
					{
						JSObjectRef dateObject = JSValueToObject( inContext, inValue, outException);
						DateObjectToVTime( inContext, dateObject, *time, outException);
						value = time;
					}
					else
					{
						value = NULL;
					}
				}
				else if (JSValueIsObjectOfClass( inContext, inValue, VJSFolderIterator::Class()))
				{
					value = NULL;
					JS4DFolderIterator* container = static_cast<JS4DFolderIterator*>(JSObjectGetPrivate( JSValueToObject( inContext, inValue, outException) ));
					if (testAssert( container != NULL))
					{
						VFolder* folder = container->GetFolder();
						if (folder != NULL)
						{
							VString *s = new VString;
							if (s != NULL)
								folder->GetPath( *s, FPS_POSIX);
							value = s;
						}
					}
				}
				else if (JSValueIsObjectOfClass( inContext, inValue, VJSFileIterator::Class()))
				{
					value = NULL;
					JS4DFileIterator* container = static_cast<JS4DFileIterator*>(JSObjectGetPrivate( JSValueToObject( inContext, inValue, outException) ));
					if (testAssert( container != NULL))
					{
						VFile* file = container->GetFile();
						if (file != NULL)
						{
							VString *s = new VString;
							if (s != NULL)
								file->GetPath( *s, FPS_POSIX);
							value = s;
						}
					}
				}
				else if (JSValueIsObjectOfClass( inContext, inValue, VJSBlob::Class()))
				{
					// remember File inherits from Blob so one must check File before Blob
					VJSBlob::PrivateDataType* blobValue = static_cast<VJSBlob::PrivateDataType*>(JSObjectGetPrivate( JSValueToObject( inContext, inValue, outException) ));
					if (testAssert( blobValue != NULL))
					{
						VJSDataSlice *slice = blobValue->RetainDataSlice();
						VBlobWithPtr *blob = new VBlobWithPtr;
						if ( (blob != NULL) && (slice != NULL) && (slice->GetDataSize() > 0) )
						{
							if (blob->PutData( slice->GetDataPtr(), slice->GetDataSize()) != VE_OK)
							{
								delete blob;
								blob = NULL;
							}
						}
						value = blob;
						ReleaseRefCountable( &slice);
					}
					else
					{
						value = NULL;
					}
				}
#if !VERSION_LINUX  // Postponed Linux Implementation !
				else if (JSValueIsObjectOfClass( inContext, inValue, VJSImage::Class()))
				{
					VJSImage::PrivateDataType* piccontainer = static_cast<VJSImage::PrivateDataType*>(JSObjectGetPrivate( JSValueToObject( inContext, inValue, outException) ));
					if (testAssert( piccontainer != NULL))
					{
						VPicture *vpic = piccontainer->GetPict();
						value = (vpic != NULL) ? new VPicture(*vpic) : NULL;
					}
					else
					{
						value = NULL;
					}
				}
#endif
				else
				{
					value = NULL;
				}
				break;
			}
		
		default:
			value = NULL;
			break;
	}
	return value;
}