⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 si_var.c

📁 是一个手机功能的模拟程序
💻 C
字号:
/*
 * Copyright (C) Ericsson Mobile Communications AB, 2000.
 * Licensed to AU-System AB.
 * All rights reserved.
 *
 * This software is covered by the license agreement between
 * the end user and AU-System AB, and may be used and copied
 * only in accordance with the terms of the said agreement.
 *
 * Neither Ericsson Mobile Communications AB nor AU-System AB
 * assumes any responsibility or liability for any errors or inaccuracies in
 * this software, or any consequential, incidental or indirect damage arising
 * out of the use of the Generic WAP Client software.
 */
#include "si_var.h"

#ifdef HAS_FLOAT
	#include "si_float.h"
#endif

#include "si_int.h"
#include "si_misc.h"



static VOID Var_Empty(pstructVar thisx)
{
	if ( thisx->type == typeString && thisx->val.theString != NULL )
	{
		DEALLOC(&(thisx->val.theString));
	}
}


pstructVar Var_New( VOID )
{
	pstructVar var;

	var = NEWSTRUCT(structVar);
	var->type = typeString;
	var->theStringLen = 0;
	var->val.theString = NULL;
	return var;
}


VOID Var_Delete(pstructVar* pThis)
{
	if ( *pThis == NULL )
		return;

	Var_Empty(*pThis);
	DEALLOC(pThis);
}


BOOL Var_ConvertMethod( enumConvertMethod method, pstructVar op1, pstructVar op2 )
{
	BOOL res = TRUE;
	enumVarConvertResult convRes;
	pstructVar	a, b;

	switch ( method )
	{

		case CONVERT_BOOLS:
			if ( op1 == NULL || op1->type == typeInvalid )
			{
				res = FALSE;
				break;
			}
			res = (VCR_OK == Var_Convert(op1, typeBool));
			if ( op2 && res == TRUE )
			{
      	if (op2->type != typeInvalid)
        {
					res = (VCR_OK == Var_Convert(op2, typeBool));
        }
        else
        {
        	res = FALSE;
        }
			}
			break;


		case CONVERT_INTS:
			if ( op1 == NULL || op1->type == typeInvalid )
			{
				res = FALSE;
				break;
			}
			res = (VCR_OK == Var_Convert(op1, typeInteger));
			if ( op2 && res == TRUE )
			{
      	if (op2->type != typeInvalid)
        {
					res = (VCR_OK == Var_Convert(op2, typeInteger));
        }
        else
        {
        	res = FALSE;
        }
			}
			break;


		case CONVERT_FLOATS:
#ifdef HAS_FLOAT
			if ( op1 == NULL || op1->type == typeInvalid )
			{
				res = FALSE;
				break;
			}
			res = (VCR_OK == Var_Convert(op1, typeFloat));
			if ( op2 && res == TRUE )
			{
      	if (op2->type != typeInvalid)
        {
					res = (VCR_OK == Var_Convert(op2, typeFloat));
        }
        else
        {
        	res = FALSE;
        }
			}
#else
			res = FALSE;
#endif
			break;


		case CONVERT_STRINGS:
			if ( op1 == NULL || op1->type == typeInvalid )
			{
				res = FALSE;
				break;
			}
			res = (VCR_OK == Var_Convert(op1, typeString));
			if ( op2 && res == TRUE )
			{
      	if (op2->type != typeInvalid)
        {
					res = (VCR_OK == Var_Convert(op2, typeString));
        }
        else
        {
        	res = FALSE;
        }
			}
			break;


		case CONVERT_INT_FLOAT: /* Unary */
			if ( op1 == NULL || op2 != NULL || op1->type == typeInvalid )
			{
				res = FALSE;
				break;
			}
			convRes = Var_Convert(op1, typeInteger);
      if (convRes == VCR_OVERFLOW)
      {
      	/* conversion failed due to overflow and there will be no try
        to convert it to a float */
        res = FALSE;
        break;
      }
      res = (convRes == VCR_OK);
#ifdef HAS_FLOAT
			if ( res == FALSE )
			{
				res = (VCR_OK == Var_Convert(op1, typeFloat));
			}
#endif
			break;


		case CONVERT_INTS_FLOATS:
			if ( op1 == NULL || op2 == NULL || op1->type == typeInvalid || op2->type == typeInvalid)
			{
				res = FALSE;
				break;
			}

#ifdef HAS_FLOAT
			if ( op1->type == typeFloat || op2->type == typeFloat )
			{
				res = (VCR_OK == Var_Convert(op1, typeFloat));
				if ( res == TRUE )
				{
					res = (VCR_OK == Var_Convert(op2, typeFloat));
				}
				break;
			}

			a = Var_New();
			b = Var_New();

			Var_AssignVar(a, op1);
			Var_AssignVar(b, op2);

			convRes = Var_Convert(a, typeInteger);
			if ( convRes == VCR_OK )
			{
				convRes = Var_Convert(b, typeInteger);
			}

      if (convRes == VCR_OVERFLOW)
      {
      	/* conversion failed due to overflow and there will be no try
        to convert to float */
        res = FALSE;
				Var_Delete(&a);
				Var_Delete(&b);
        break;
      }
      res = (convRes == VCR_OK);

			if ( res == TRUE )
			{
				Var_AssignVar(op1, a);
				Var_AssignVar(op2, b);
			}
			else
			{
				Var_AssignVar(a, op1);
				Var_AssignVar(b, op2);

				res = (VCR_OK == Var_Convert(a, typeFloat));
				if ( res == TRUE )
				{
					res = (VCR_OK == Var_Convert(b, typeFloat));
				}
				if ( res == TRUE )
				{
					Var_AssignVar(op1, a);
					Var_AssignVar(op2, b);
				}
			}

			Var_Delete(&a);
			Var_Delete(&b);
#else
			res = (VCR_OK == Var_Convert(op1, typeInteger));
			if ( res == TRUE )
			{
				res = (VCR_OK == Var_Convert(op2, typeInteger));
			}
#endif
			break;


		case CONVERT_INTS_FLOATS_STRINGS:
			res = FALSE;
			if ( op1 == NULL || op2 == NULL || op1->type == typeInvalid || op2->type == typeInvalid)
			{
				break;
			}
			
			if ( op1->type == typeString || op2->type == typeString )
			{
				res = (VCR_OK == Var_Convert(op1, typeString));
				if ( res == TRUE )
				{
					res = (VCR_OK == Var_Convert(op2, typeString));
				}
				break;
			}
			
#ifdef HAS_FLOAT
			if ( op1->type == typeFloat || op2->type == typeFloat )
			{
				res = (VCR_OK == Var_Convert(op1, typeFloat));
				if ( res == TRUE )
				{
					res = (VCR_OK == Var_Convert(op2, typeFloat));
				}
				break;
			}
#endif

			res = (VCR_OK == Var_Convert(op1, typeInteger));
			if ( res == TRUE )
			{
				res = (VCR_OK == Var_Convert(op2, typeInteger));
			}
			break;
	}

	return( res );
}


/* Tries to convert the variable "thisx" to type "toType".              */
/* Returns VCR_OK if the conversion was succesfull.                      */
/* VCR_NOT_OK is returned if the variable couldn't be converted, and        */
/* in that case the variable "thisx" isn't modified.                    */
/* VCR_OVERFLOW is returned if a string to integer convertion overflows */
enumVarConvertResult Var_Convert(pstructVar thisx, enumVarType toType )
{
	enumVarConvertResult		res = VCR_OK;
  BOOL    boolRes = TRUE;
	WCHAR		*str = NULL;
	UINT32	len = 0;

	WCHAR		wc_true[]  = {'t','r','u','e', 0};
	WCHAR		wc_false[] = {'f','a','l','s','e', 0};


	if ( thisx->type == typeInvalid )
		return VCR_NOT_OK;

	switch ( toType )
	{
		case typeInteger:
			switch ( thisx->type )
			{
				case typeFloat:
					/* Not allowed */
					res = VCR_NOT_OK;
					break;
				case typeString:
					{
					UINT8	charsUsed;
					BOOL	isOverflow;
					INT32	tmpInt;

					/* Is there something to convert? */
					if ( thisx->val.theString == NULL || thisx->theStringLen == 0 )
						{
						res = VCR_NOT_OK;
						break;
						}

					/* OK, try to convert the string */
					thisx->val.theString[thisx->theStringLen] = 0;
					boolRes = String2Int(thisx->val.theString, &charsUsed, &tmpInt, &isOverflow);

					/* Exit if it wasn't a valid number in the string */
					if ( boolRes == FALSE )
          {
						if (isOverflow)
            {
							res = VCR_OVERFLOW;
            }
            else
            {
							res = VCR_NOT_OK;
            }
						break;
          }

					/* Is all characters used or is there only whitespace left in the string? */
					if ( charsUsed == thisx->theStringLen )
						{
						/* All is OK! */
						Var_AssignInt(thisx, tmpInt);
						break;
						}
					str = thisx->val.theString + charsUsed;
					len = thisx->theStringLen - charsUsed;
					while ( len )
						{
						if ( ! IsWhitespaceChar(*str) )
							{
							res = VCR_NOT_OK;
							break;
							}
						len--;
						}

					if (res == VCR_OK)
						{
						/* All is OK! */
						Var_AssignInt(thisx, tmpInt);
						}
					}
					break;
			}
			break;

		case typeFloat:
#ifdef HAS_FLOAT
			switch ( thisx->type )
			{
				case typeBool:
				case typeInteger:
					thisx->val.theFloat = (FLOAT32)thisx->val.theInt;
					break;
				case typeString:
					{
					UINT8	  charsUsed;
					BOOL	  isOverflow;
          FLOAT32 f;

					/* Is there something to convert? */
					if ( thisx->val.theString == NULL || thisx->theStringLen == 0 )
						{
						res = VCR_NOT_OK;
						break;
						}

					/* OK, try to convert the string */
					thisx->val.theString[thisx->theStringLen] = 0;
					boolRes = String2Float (thisx->val.theString, &charsUsed,
                                  &f, &isOverflow);

					/* Exit if it wasn't a valid number in the string */
					if ( boolRes == FALSE )
          {
						res = VCR_NOT_OK;
						break;
          }

					/* Is all characters used or is there only whitespace left in the string? */
					if ( charsUsed == thisx->theStringLen )
						{
						/* All is OK! */
						Var_AssignFloat(thisx, f);
						break;
						}
					str = thisx->val.theString + charsUsed;
					len = thisx->theStringLen - charsUsed;
					while ( len )
						{
						if ( ! IsWhitespaceChar(*str) )
							{
							res = VCR_NOT_OK;
							break;
							}
						len--;
						}

					if (res == VCR_OK) 
						{
						/* All is OK! */
						Var_AssignFloat (thisx, f);
						}
					}
					break;
			}
#else 
			res = VCR_NOT_OK;
#endif
			break;

		case typeString:
			switch ( thisx->type )
			{
				case typeInteger:
					{
					WCHAR tmp[20];

					Int2String(thisx->val.theInt, tmp);
					Var_AssignString(thisx, STRINGLENGTH(tmp), tmp);
					}
					break;
				case typeFloat:
#ifdef HAS_FLOAT
					{
					WCHAR			tmp[50];

					Float2String (thisx->val.theFloat, tmp);
					Var_AssignString(thisx, STRINGLENGTH(tmp), tmp);
					}
#else
					res = VCR_NOT_OK;
#endif
					break;
				case typeBool:
					Var_Empty(thisx);
					if ( thisx->val.theInt == 0 )
						Var_AssignString(thisx, 5, wc_false);
					else
						Var_AssignString(thisx, 4, wc_true);
					break;
			}
			break;

		case typeBool:
			switch ( thisx->type )
			{
				case typeInteger:
					thisx->val.theInt = ((thisx->val.theInt == 0) ? 0 : 1);
					break;
				case typeFloat:
#ifdef HAS_FLOAT
					thisx->val.theInt = ((thisx->val.theFloat == 0.0) ? 0 : 1);
#else
					res = VCR_NOT_OK;
#endif
					break;
				case typeString:
					Var_AssignBool( thisx, ((thisx->theStringLen > 0) ? TRUE : FALSE));
					break;
			}
			break;

		case typeInvalid:
			Var_Empty(thisx);
			break;
	}

	if ( res == VCR_OK )
		thisx->type = toType;
	return( res );
}


VOID Var_AssignVar(pstructVar thisx, pstructVar src )
{
	Var_Empty(thisx);

	thisx->type = src->type;
	switch ( thisx->type )
	{
		case typeString:
			thisx->theStringLen = src->theStringLen;
			if ( thisx->theStringLen > 0 )
			{
				thisx->val.theString = NEWARRAY(WCHAR, thisx->theStringLen+1);
				thisx->val.theString[thisx->theStringLen] = 0;
				COPYSTRINGN(thisx->val.theString, src->val.theString, thisx->theStringLen);
			}
			else
				thisx->val.theString = NULL;
			break;
		case typeInteger:
		case typeBool:
			thisx->val.theInt = src->val.theInt;
			break;
		case typeFloat:
#ifdef HAS_FLOAT
			thisx->val.theFloat = src->val.theFloat;
#else
			thisx->type = typeInvalid;
#endif
			break;
		case typeInvalid:
			thisx->val.theInt = 0;
			break;
	}
}


VOID Var_AssignInt(pstructVar thisx, INT32 val)
{
	Var_Empty(thisx);
	thisx->type = typeInteger;
	thisx->val.theInt = val;
}


VOID Var_AssignFloat(pstructVar thisx, FLOAT32 val)
{
	Var_Empty(thisx);
#ifdef HAS_FLOAT
	thisx->type = typeFloat;

	if ( ! IsLegalFloatVal(val) )
  {
		thisx->type = typeInvalid;
	}
	else if ( IsUnderflow(val) )
  {
		thisx->val.theFloat = (FLOAT32)0;
  }
  else
  {
		thisx->val.theFloat = val;
  }
#else
	thisx->type = typeInvalid;
#endif
}


VOID Var_AssignString(pstructVar thisx, UINT32 len, WCHAR* str)
{
	Var_Empty(thisx);
	thisx->type = typeString;
	thisx->theStringLen = len;
	thisx->val.theString = NEWARRAY(WCHAR, len+1);
	COPYSTRINGN(thisx->val.theString, str, len);
	thisx->val.theString[len] = 0;
}


VOID Var_AssignStringDirect(pstructVar thisx, UINT32 len, WCHAR** str)
/* the string is taken as is, not copied! */
{
	Var_Empty(thisx);
	thisx->type = typeString;
	thisx->theStringLen = len;
	thisx->val.theString = *str;
	*str = NULL;
}


VOID Var_NewString(pstructVar thisx, UINT32 len)
{
	if (len > 0)
		{
		Var_Empty(thisx);
		thisx->type = typeString;
		thisx->theStringLen = len;
		thisx->val.theString = NEWARRAY(WCHAR, len+1);
		thisx->val.theString[len] = 0; /* NULL TERMINATED outside the asked for length */
		}
	else
		{
		Var_Empty(thisx);
		thisx->type = typeString;
		thisx->theStringLen = len;
		thisx->val.theString = NULL;
		}
}


VOID Var_AssignBool(pstructVar thisx, BOOL val)
{
	Var_Empty(thisx);
	thisx->type = typeBool;
	thisx->val.theInt = val;
}


VOID Var_AssignInvalid(pstructVar thisx)
{
	Var_Empty(thisx);
	thisx->type = typeInvalid;
	thisx->val.theInt = 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -