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

📄 vutils.cpp

📁 这个是微软WINCE的OBEX协议例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/**************************************************************************/
/*  VUtils.cpp                                                            */
/*                                                                        */
/*  This file contains utility routines to process VCARDS/VCAL's  		  */
/*                                                                        */
/*  DISCLAIMER!!!:  this does not FULLY support the vCard/vCalc spec      */
/*     it is intended as an example to the OBEX Inbox and nothing more    */
/*     I dont believe it will cause harm or behave strangly, but use it   */
/*     at your own risk!                                                  */
/*                                                                        */
/*  Functions included:                                                   */
/*    getVCalStateObj      -- singleton toget a pointer to vCal state info*/
/*    vCardInputFunct      -- used to handle globals/input conversion     */
/*                            for vCard's (used in LOOKUP TABLE)          */
/*    vCalInputFunct       -- used to handle globals/input conversion     */
/*                            for vCal's (used in LOOKUP TABLE)           */
/*    _stricmp             -- backwards compatiblity for HPC, is _stricmp */
/*    StartDateToFileTime  -- convert vCard time into FILETIME struct     */
/*    UnicodeToChar        -- convert UNICODE to CHAR string              */
/*                                                                        */
/*    ParseVCard         -- parse out vCard... look for BEGIN/END         */
/*    ParseMajorComponents -- parse out major components from vCard       */
/*                            stuff like TYPE, PARAMS, VALUE              */ 
/*    ParseLine            -- take a vCard line and parse out FIELD info  */
/*    ParseFields          -- do VALUE/FIELD parsing that ParseLine didnt */
/*                                                                        */
/*                                                                        */
/*  Other related files:                                                  */
/*                                                                        */
/*                                                                        */
/**************************************************************************/

#include "VUtils.h"

//LOOKUP TABLE DEFINATIONS-------------------------------------------------
//  g_sContactOidTranslator contains information on where to store 
//  information on an individual line from a vCard.  The idea is this:
//
//  1.  Fetch a line entry from a vCard
//  2.  Parse out fields (and ordinal numbers for entry locations)
//         this includes the name field, value, and parameters
//  3.  Search through the folling table, looking for iOrd and 
//         a match on the name field.  Once found, send each of the values
//         through the inputFunction to handle initing global values
//		   and conversion to the correct type of CEPROPVAL struct
//
//  DESCRIPTION OF FIELDS:
//	    Field:         Description:
//      1.			   Field Name -- the name given by the VCard/cal spec
//	    2.             Conversion function ptr to convert the record to
//					      something that can be sent in a vcard
//						  *used for output*
//		3.			   Input fuction-- used to handle global values
//						  and conversion into CEPROPVAL struct.  Use this
//						  to convert incoming data into format that can
//						  be used by the PocketPC
//		4.			   Record ID of the database entry
//		5.			   Ordinal # of the value in the vCard entry
//						  for example, on a N: (name field in vCard)
//						  the field is filled out like this:
//						  N:<last><first>.... the last name would have 
//						  ordinal 1 and the first name 2... for items
//						  that only have one value (TITLE for exampe)
//						  set ORD to be 1

//#ifdef VCAL  //  <--  VCAL table

OID_TRANSLATOR g_sCalendarOidTranslator[] = {
	//Name fields
	{"DESCRIPTION:",  UnicodeToChar,       vCalInputFunct, HHPR_SUBJECT,              1,   },
    {"LOCATION:",     UnicodeToChar,       vCalInputFunct, HHPR_APPT_LOCATION,        1,   },    
	{"DTSTART:",      StartDateToFileTime, vCalInputFunct, HHPR_APPT_START_WHOLE,     1,   },
	{"DTEND:",        StartDateToFileTime, vCalInputFunct, HHPR_APPT_DURATION,        1,   },
};
UINT g_CalendarSize = ARRAYSIZE(g_sCalendarOidTranslator);
//#endif

//#ifdef VCARD //  <-- vCard Table

OID_TRANSLATOR g_sContactOidTranslator[] = {
	//Name fields
	{"N:",  UnicodeToChar, vCardInputFunct, PR_SURNAME_W,     1,   },
	{"N:",  UnicodeToChar, vCardInputFunct, PR_GIVEN_NAME_W,  2,   },
	{"N:",  UnicodeToChar, vCardInputFunct, HHPR_NAME_PREFIX, 4,   },
	{"N:",  UnicodeToChar, vCardInputFunct, PR_GENERATION_W,  5,   },

	//home address fields 
	{"ADR;TYPE=home:",  UnicodeToChar,   vCardInputFunct, HHPR_HOME_ADDRESS_STREET,       3},
	{"ADR;TYPE=home:",  UnicodeToChar,   vCardInputFunct, HHPR_HOME_ADDRESS_CITY,         4},
	{"ADR;TYPE=home:",  UnicodeToChar,   vCardInputFunct, HHPR_HOME_ADDRESS_STATE,        5},
	{"ADR;TYPE=home:",  UnicodeToChar,   vCardInputFunct, HHPR_HOME_ADDRESS_POSTAL_CODE,  6},
	{"ADR;TYPE=home:",  UnicodeToChar,   vCardInputFunct, HHPR_HOME_ADDRESS_COUNTRY,      7},

	//office address fields
	{"ADR;TYPE=work:", UnicodeToChar,  vCardInputFunct, HHPR_OFFICE_ADDRESS_STREET,      3},
	{"ADR;TYPE=work:", UnicodeToChar,  vCardInputFunct, HHPR_OFFICE_ADDRESS_CITY,        4},
	{"ADR;TYPE=work:", UnicodeToChar,  vCardInputFunct, HHPR_OFFICE_ADDRESS_STATE,       5},
	{"ADR;TYPE=work:", UnicodeToChar,  vCardInputFunct, HHPR_OFFICE_ADDRESS_POSTAL_CODE, 6},
	{"ADR;TYPE=work:", UnicodeToChar,  vCardInputFunct, HHPR_OFFICE_ADDRESS_COUNTRY,     7},

	//phone number fields
	{"TEL;TYPE=work:", UnicodeToChar, vCardInputFunct, PR_BUSINESS_TELEPHONE_NUMBER_W,   1},
	{"TEL;TYPE=car:",  UnicodeToChar, vCardInputFunct, PR_CAR_TELEPHONE_NUMBER_W,        1},
	{"TEL;TYPE=home:", UnicodeToChar, vCardInputFunct, PR_HOME_TELEPHONE_NUMBER_W,       1},
	{"TEL;TYPE=cell:", UnicodeToChar, vCardInputFunct, PR_CELLULAR_TELEPHONE_NUMBER_W,   1},
	{"TEL;TYPE=pref:", UnicodeToChar, vCardInputFunct, PR_PRIMARY_TELEPHONE_NUMBER_W,    1},

	//email addresses
	{"EMAIL;TYPE=internet,pref:", UnicodeToChar, vCardInputFunct, HHPR_EMAIL1_EMAIL_ADDRESS,1},
	{"EMAIL;TYPE=internet,pref:", UnicodeToChar, vCardInputFunct, HHPR_EMAIL2_EMAIL_ADDRESS,1},

	//title
	{"TITLE:", UnicodeToChar, vCardInputFunct, PR_TITLE_W, 1},

	//company/organization
	{"ORG:",  UnicodeToChar, vCardInputFunct, PR_COMPANY_NAME_W, 1},
	//---** when nothing else fits, give one of these a try
	{"ADR:",  UnicodeToChar,  vCardInputFunct, HHPR_HOME_ADDRESS_STREET,       3},
	{"ADR:",  UnicodeToChar,   vCardInputFunct, HHPR_HOME_ADDRESS_CITY,        4},
	{"ADR:",  UnicodeToChar,  vCardInputFunct, HHPR_HOME_ADDRESS_STATE,        5},
	{"ADR:",  UnicodeToChar,  vCardInputFunct, HHPR_HOME_ADDRESS_POSTAL_CODE,  6},
	{"ADR:",  UnicodeToChar,  vCardInputFunct,  HHPR_HOME_ADDRESS_COUNTRY,     7},

	{"EMAIL;TYPE=HOME:",     UnicodeToChar, vCardInputFunct, HHPR_EMAIL1_EMAIL_ADDRESS,1},
	{"EMAIL;TYPE=PREF:",     UnicodeToChar, vCardInputFunct, HHPR_EMAIL1_EMAIL_ADDRESS,1},
	{"EMAIL;TYPE=INTERNET:", UnicodeToChar, vCardInputFunct, HHPR_EMAIL1_EMAIL_ADDRESS,1}
};
UINT g_ContactSize = ARRAYSIZE(g_sContactOidTranslator);

//#endif


/*****************************************************************************/
/*   Function: vCardInputFunct							                     */
/*   convert data sent to this into a format compatible with the CE database */
/*                                                                           */
/*   RETURN a pointer to a CEPROPVAL (that must be destroyed later)          */
/*      describing the new database item                                     */
/*                                                                           */
/*   Begin by converting the string into unicode, and replacing \r with      */
/*      ' '                                                                  */
/*****************************************************************************/
CEPROPVAL *vCardInputFunct(CEPROPID propID, LPSTR type, LPSTR pField, void *pState)
{
	CEPROPVAL *prop = new CEPROPVAL;
	memset(prop, 0, sizeof(CEPROPVAL));
	prop->propid = propID;	
	int size,j;
	
	size = MultiByteToWideChar(CP_ACP, 
		0, 
		pField, 
		-1, 
		0,
		0);					
	ASSERT(size);
	prop->val.lpwstr = new WCHAR [size];			
	MultiByteToWideChar(CP_ACP, 0, pField, -1, 
		prop->val.lpwstr, size);
	
    //replace all \r's.... 
    for(j=0; j<size; j++)
    {
        if(prop->val.lpwstr[j] == '\r')
            prop->val.lpwstr[j] = ' ';
    }				
    

    //take note of the propID... if its for SURNAME or GIVEN_NAME, put the value into 
    //  global space
    if(PR_SURNAME_W == propID)
    {
       VCardStateObj *pVCState = (VCardStateObj *)pState;
       pVCState->pSurName = prop;
    }
    else if(PR_GIVEN_NAME_W == propID)
    {
       VCardStateObj *pVCState = (VCardStateObj *)pState;
       pVCState->pGiven = prop;
    }


	return prop;
}


/*****************************************************************************/
/*   Function: vCalInputFunct							                     */
/*   convert data sent to this into a format compatible with the CE database */
/*                                                                           */
/*   RETURN a pointer to a CEPROPVAL (that must be destroyed later)          */
/*      describing the new database item                                     */
/*                                                                           */
/*   Begin by determining what TYPE of data this is                          */
/*         for TIME's do a convertion into the FILETIME stuct used by CE     */
/*****************************************************************************/
CEPROPVAL *vCalInputFunct(CEPROPID propID, LPSTR type, LPSTR pField, void *pState)
{	
	CEPROPVAL *prop = new CEPROPVAL;
	memset(prop, 0, sizeof(CEPROPVAL));
	prop->propid = propID;	

    ASSERT(pState);
	
	//if this is the end, store the value into a global
	if(strcmp(type, "DTEND:") == 0)
	{
		VCalStateObj *pGlobal = (VCalStateObj *)pState;
		if(!pGlobal->stopTime) pGlobal->stopTime = new FILETIME;
		StartDateToFileTime(pField, pGlobal->stopTime);
		delete prop;
		return 0;
	}

    //mark the start time
	else if(strcmp(type, "DTSTART:") == 0)
	{
        VCalStateObj *pGlobal = (VCalStateObj *)pState;
		if(!pGlobal->startTime) pGlobal->startTime = new FILETIME;
		StartDateToFileTime(pField, pGlobal->startTime);
		StartDateToFileTime(pField, &prop->val.filetime);
		return prop;
	}

    //if its a STRING, do the uncode conversion 
	else if(LOWORD(propID) == CEVT_LPWSTR)
	{
		int size,j;

		size = MultiByteToWideChar(CP_ACP, 
			0, 
			pField, 
			-1, 
			0,
			0);					
		ASSERT(size);
		prop->val.lpwstr = new WCHAR [size];				
		MultiByteToWideChar(CP_ACP, 0, pField, -1, 
			prop->val.lpwstr, size);
		
		//replace all \r's.... 
		for(j=0; j<size; j++)
		{
			if(prop->val.lpwstr[j] == '\r')
				prop->val.lpwstr[j] = ' ';
		}					
		
		return prop;
	}
	
	delete prop;
	return 0;
}



/*****************************************************************************/
/*   Function: StartDateToFileTime							                 */
/*      Do a convertion from a text string in the format                     */
/*          <YYYY><MM><DD>T<HH><MM><SS>                                      */
/*                                                                           */
/*      After conversion, put the results into a FILETIME struct             */
/*****************************************************************************/
BOOL StartDateToFileTime(LPSTR dta, LPFILETIME pFileTime)
{
	UINT dLen = strlen(dta);

	SYSTEMTIME sTime;
	char year[5];
	char month[3];
	char day[3];

	if(dLen >= 8)
	{
		memcpy(year, dta, 4);
		year[4] = 0;

		memcpy(month, &dta[4], 2);
		month[2] = 0;

		memcpy(day, &dta[6], 2);
		day[2] = 0;

		//clear out the system time
		memset(&sTime, 0, sizeof(SYSTEMTIME));

		//copy in the values..
		sTime.wYear = atoi(year);
		sTime.wDay = atoi(day);
		sTime.wMonth = atoi(month);

		//now see if there is a time field      
		if(dLen >= 15)
		{
			char hour[3];
			char min[3];
			char sec[3];
			memcpy(hour, &dta[9], 2);
			hour[2] = 0;
			memcpy(min, &dta[11], 2);
			min[2] = 0;
			memcpy(sec, &dta[13], 2);
			sec[2] = 0;

			sTime.wHour += atoi(hour);
			sTime.wMinute = atoi(min);
			sTime.wSecond = atoi(sec);
		}

        //BUGBUG:  this conversion ISNT GOOD for all places!  this is just for Seattle....
        BOOL ret = SystemTimeToFileTime(&sTime, pFileTime);

        _int64 time = pFileTime->dwHighDateTime;
        time <<= 32;
        time |= pFileTime->dwLowDateTime;

        _int64 adj = 7;       
        adj *= 10000000;
        adj *= 60;
        adj *= 60;
        time += adj;

        pFileTime->dwHighDateTime = (DWORD)((time >> 32) & 0x00000000ffffffff);
        pFileTime->dwLowDateTime = (DWORD)(time &          0x00000000ffffffff);

    
    	return ret;

	}
	else 
	{
		return 0;
	}


}

/*****************************************************************************/
/*   Function: UnicodeToChar     							                 */
/*       convert a UNICODE string into a byte string                         */
/*                                                                           */
/*   BUGBUG: DOES NOT HANDLE LANGUAGES OTHER THAN ENGISH!                    */
/*                                                                           */
/*   WARNING: this function ALLOCATES MEMORY that MUST BE FREED BY CALLER!!  */
/*                                                                           */
/*   NOTE: this does the conversion required for vCard (escape chars)        */
/*****************************************************************************/
char *UnicodeToChar(LPTSTR dta)
{
	char *retBuf;
	
	//convert the string from unicode
	int requiredSize = 
        WideCharToMultiByte (CP_ACP, 0, dta, -1, 0, 0, NULL, NULL);
	
	retBuf = new char[requiredSize];
	if(!retBuf) 
        return 0;
	
	if(WideCharToMultiByte (CP_ACP, 
                            0, 
                            dta, 
                            -1, 
                            retBuf, 
                            requiredSize, 
                            NULL, 
                            NULL) == 0)
	{
		delete [] retBuf;

⌨️ 快捷键说明

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