Source file: /~heha/messtech/matdde.zip/source/ddelib.c

#include <windows.h>
#include <ddeml.h>
#include <malloc.h>		//fuer _memmax()
#include <string.h>		//fuer str...()
#include <stdlib.h>		//fuer atof()

#define DLLMEX
#include "header\mex.h"

#include "header\fastdde.h"
#include "header\testargs.h"	//fuer ErrorBeep()

#pragma hdrstop


/////////////////////////////////////////////////////////////////////////////////////////////////////
void GetMatrixSize( char huge* hDataString, DWORD* DataSize, UINT* rows, UINT* columns )
{
	DWORD i = 0;

	*rows = 0;		//Initialwerte
	*columns = 1;	//Initialwerte

	while ( hDataString[i++] && i < *DataSize )
	{
		if ( hDataString[i] == '\t' && *rows == 0 ) 	//Tabulatoren nur in der 1. Zeile der Matrix erfassen
			(*columns)++;   							//und Anzahl der Spalten ermitteln
	    if ( hDataString[i] == '\r' )   				//wenn Zeilenende, dann eine Zeile mehr
		    (*rows)++;
	}
	
	if (*rows == 0 && i > 1) (*rows)++; 				//mindestens eine Zeile, sonst leere Matrix
	*DataSize = i;  									//tatsaechliche Groesse bis zur abschliessenden Null
}



/////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL Str2Double( double huge* dest, DWORD MatrixSize, char huge* hDataString, DWORD DataSize )
{
	DWORD i,k,m;
	BOOL result = TRUE;
	char huge* pNextString = hDataString;
	char strBuffer[100];	//es werden bis zu 100 Stellen (max. Wert fuer atof) fuer eine Zahl kopiert

	i = k = m = 0;
	
	while ( i < MatrixSize )
	{
		
		//Beginn der naechsten Zahl suchen 
		while ( m++ < DataSize )
		{
			if ( *pNextString == '\0' || *pNextString == '\t' ) 
			{
				pNextString++;
				break;		
			}
			if ( *pNextString == '\r' )
			{
				pNextString += 2;
				m++;
				break;
			}                 
			pNextString++;
		}                       
		
		if ( *hDataString == '\0' )	//wenn Daten fehlen
			return FALSE;
		
		if ( *hDataString == '\t' || *hDataString == '\r' ) 
		{            
			dest[i] = 0;
			result = FALSE;
		}
		else	
		{
			//lokale Kopie, wegen atof() -huge-Zeigerproblem
			hmemcpy( (char huge*) strBuffer, (char huge*) hDataString, min(sizeof(strBuffer), m - k) );	
			dest[i] = atof( strBuffer );  
		}
		
		k = m;
		hDataString = pNextString;
		i++;
	}
	if (!result)
    	mexPrintf( "??? Possible empty element(s) of source matrix.\r\n" );	
    return TRUE;
}

        
        
/////////////////////////////////////////////////////////////////////////////////////////////////////
void Transpose(	double huge* dest, double huge* src, UINT rows, UINT cols )
{                                                                 

	UINT i, k;
	double huge* help;

//	*** Matrix transponieren                                            
	if (cols < rows) 			//weniger Spalten als Zeilen?
	{   										//Spalten-Schleife aussen
	for ( i = 0; i < cols; i++ )
		{
			help = src + (DWORD)i;
			for ( k = 0; k < rows; k++ )
			{
				hmemcpy( dest, help, sizeof(double) );
				dest++; 
				help += (DWORD)cols;
			}
		}
    } else {									//Zeilen-Schleife aussen
    	for ( k = 0; k < rows; k++ )
    	{
			help = dest + (DWORD)k;
    		for ( i = 0; i < cols; i++ )
			{
				hmemcpy( help, src, sizeof(double) );
				src++; 
				help += (DWORD)rows;
			}
    	}
    }

}



/////////////////////////////////////////////////////////////////////////////////////////////////////
void HandleDdeError(UINT DdeError)
{
    static char szErr[31] = "??? DDEML: ";
    static char *DdeE[] = {
		"AdvAckTimeout"              ,
        "Busy"                       ,
        "DataAckTimeout"             ,
        "Dll_Not_Initialized"        ,
        "Dll_Usage"                  ,
        "ExecAckTimeout"             ,
        "InvalidParameter"           ,
        "Low Memory warning"         ,
        "Memory_Error"               ,
        "NotProcessed"               ,
        "No_Conv_Established"        ,
        "PokeAckTimeout"             ,
        "PostMsg_Failed"             ,
        "Reentrancy"                 ,
        "Server_Died"                ,
        "Sys_Error"                  ,
        "UnadvAckTimeout"            ,
        "Unfound_Queue_ID"           ,    
	};
    if (!DdeError) {   
        strcpy(&szErr[4], "0");
    } else if (DdeError > DMLERR_LAST || DdeError < DMLERR_FIRST) {
        strcpy(&szErr[4], "Unknown DDEML Error");
    } else {
        strcpy(&szErr[4], DdeE[DdeError - DMLERR_FIRST]);
    }
    strcat(szErr,".\r\n");
	mexPrintf(szErr);
	ErrorBeep();    
}



/////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTextStringReq( HDDEDATA hData, Matrix** DestMatrix )
{
	DWORD	DataSize, StringLen = 0;
    UINT MaxStringLen = 0x2000;		//max. 8 K * 8 Byte = 64 KByte in String-Matrix
    
	char huge* hDataString = (char huge*)DdeAccessData( hData, &DataSize );
    
	//Stringlaenge bestimmen
	char huge* hDataString_end = hDataString;
	while ( *(hDataString_end++) != '\0' && StringLen < DataSize) StringLen++;
	if (StringLen == DataSize) StringLen--;
	
	if (StringLen > MaxStringLen)   							//abschneiden
	{
		mexPrintf( "??? Possible data lost. More then 8 KByte text.\r\n" );
		ErrorBeep();
		StringLen = MaxStringLen;
		hmemcpy( &hDataString[StringLen], "\0", sizeof(char) ); //Null am Ende!
	}
	
	*DestMatrix = mxCreateString( hDataString );   //arbeitet nur mit Strings bis 8 KByte!
		
    DdeUnaccessData( hData );
	    
	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CFTextReq( HDDEDATA hData, Matrix** DestMatrix )
{
	HGLOBAL	hGlobal;
	UINT 	rows, columns;  
	DWORD	DataSize, matrixSize;
	double huge* src;
	double huge* dest;
	
	char huge* hDataString = (char huge*)DdeAccessData( hData, &DataSize);

	GetMatrixSize( hDataString, &DataSize, &rows, &columns );
	matrixSize = (DWORD)rows * (DWORD)columns;

	//Speicher reservieren
	hGlobal = GlobalAlloc( GPTR, matrixSize * sizeof(double) );
	if ( !hGlobal )
	{
		DdeUnaccessData( hData );
		mexPrintf( "??? Memory allocation error.\r\n" );
		ErrorBeep();
		return FALSE;
	}
    
	dest = (double huge*)GlobalLock( hGlobal );	//Speicherbereich mit double-Werten
    
	if ( Str2Double( dest, matrixSize, hDataString, DataSize ) )	//Konvertierung string -> double	
	{

	//Matrix erzeugen
		if ((*DestMatrix = mxCreateFull( rows, columns, REAL )) )
		{

			src		= dest;		//die zu double konvertierten strings sind jetzt source
			dest	= (double huge*)mxGetPr( *DestMatrix ); 
	
	//Matrix transponieren                
			Transpose( dest, src, rows, columns );	//ddelib.c
		}
		else
		{
			mexPrintf( "??? Memory allocation error.\r\n" );
			ErrorBeep();
	    }
	}

	GlobalUnlock( hGlobal );
	GlobalFree( hGlobal );

	DdeUnaccessData( hData );

	return TRUE;
}



///////////////////////////////////////////////////////DDE-Excel Format
BOOL FastDDEReq( HDDEDATA hData, Matrix** DestMatrix )
{
	WORD i=0; WORD j, k=0;
	DWORD Size, DataSize, SourceBytes, BytesMoved = 0;
	TableHeader	TabHeader;
	FloatHeader	FtHeader;
	BOOL result	= TRUE;
	char huge* src;
	char huge* dest;
	char huge* help;
	char huge* hDataBlock = (char huge*) DdeAccessData( hData, &DataSize );
	
//tdtTable-Header lesen
    hmemcpy( &TabHeader, hDataBlock, sizeof(TabHeader) );
    Size= (DWORD)TabHeader.rows * TabHeader.columns * sizeof(double);
    
//Matrix erzeugen
	if ( !(*DestMatrix = mxCreateFull( (int)TabHeader.rows, (int)TabHeader.columns, REAL )) )  //int?
	{
		DdeUnaccessData( hData );
		mexPrintf( "??? Memory allocation error.\r\n" );
		ErrorBeep();
    	return FALSE;
    }
    
    SourceBytes	= sizeof(TabHeader);
    src			= hDataBlock + sizeof(TabHeader);
	dest		= (char huge*)mxGetPr( *DestMatrix ); 
	help		= dest;
	
	while ( BytesMoved < Size )
    {
	    SourceBytes += sizeof(FtHeader);
	    if ( SourceBytes > DataSize )
		{
			result = FALSE;
			break;
		}
		//tdtFloat-Header kopieren
	    hmemcpy( (char*)&FtHeader, (char huge*)src, sizeof(FtHeader) );
        src += sizeof(FtHeader);
        SourceBytes += FtHeader.cbFloat;
        if ( FtHeader.Float != tdtFloat || SourceBytes > DataSize)
		{
			result = FALSE;
			break;
		}
	    //Double-Daten kopieren
		if (TabHeader.columns == 1 || TabHeader.rows == 1)		//Reihenfolge bleibt    
		{
        	hmemcpy( (char huge*)help, (char huge*)src, FtHeader.cbFloat);
        	src += FtHeader.cbFloat;
        	help += FtHeader.cbFloat;
        }
        else													//Transponieren
        {
			j = FtHeader.cbFloat;
		    while ( k < TabHeader.rows )
	    	{
	    		while ( i < TabHeader.columns )
				{
					if ( j < sizeof(double) )
						break;
					hmemcpy( help, src, sizeof(double) );
					j -= sizeof(double);
					src += sizeof(double); 
					help += TabHeader.rows * sizeof(double);
					i++;
				}
				if ( i < TabHeader.columns )
					break;
				i = 0;
				k++;
				help = dest + (DWORD)k * sizeof(double);		//huge-Adresse!
	    	}
        }
        BytesMoved += FtHeader.cbFloat;
    }
	
	DdeUnaccessData( hData );

	if (result)
		return TRUE;
	else
	{
		mexPrintf( "??? Error. Invalid binary data.\r\n" );
		ErrorBeep();
    	return FALSE;
    }
}
Detected encoding: ASCII (7 bit)2