📄 contutils.cpp
字号:
/*****************************************************************************/
/* TraverseVEL */
/* Use recursion to figure out how large a VCARD_ENTRY_LIST list is */
/* */
/* if a dest is given, also build the list by copying in the data */
/* */
/* */
/* Returns the size (in bytes) of the list and all children */
/*****************************************************************************/
UINT TraverseVEL(VCARD_ENTRY_LIST *vclEntry, char *dest, UINT offset)
{
//base case of recursion
if(!vclEntry) return 0;
//the current size of the list
UINT size = 0;
StringList *pslTemp = vclEntry->pMembers;
while(pslTemp)
{
UINT uiEntrySize = strlen(pslTemp->pEntry);
if(dest)
{
memcpy(dest+size+offset, pslTemp->pEntry, uiEntrySize);
if(pslTemp->pNext)
dest[size+offset+uiEntrySize] = ',';
}
size += uiEntrySize;
if(pslTemp->pNext)
size ++;
pslTemp = pslTemp->pNext;
}
//if there is another item, add a ';'
if(vclEntry->pNext)
{
if(dest)
dest[size+offset] = ';';
size ++;
}
//recurse
return (size + TraverseVEL(vclEntry->pNext, dest, size+offset));
}
/*****************************************************************************/
/* TraverseVCL */
/* Use recursion to figure out how large a VCARD_LINE list is */
/* */
/* if a dest is given, also build the list */
/* */
/* */
/* Returns the size (in bytes) of the list and all children */
/*****************************************************************************/
UINT TraverseVCL(VCARD_LINE *vclList, char *dest, UINT offset)
{
//base case of recursion
if(!vclList) return 0;
UINT size = strlen(vclList->pName);
if(dest)
memcpy(dest+offset, vclList->pName, size);
//recurse on all VCARD_ENTRY_LIST's
size += TraverseVEL(vclList->pLineEntries, dest, size+offset);
//move in the new line
if(dest)
memcpy(dest+offset+size, "\r\n", 2);
return (size + 2 + TraverseVCL(vclList->pNext, dest, size+offset+2));
}
/*****************************************************************************/
/* DeleteVEL */
/* Use recursion to delete VCARD_ENTRY_LIST list */
/* */
/*****************************************************************************/
void DeleteVEL(VCARD_ENTRY_LIST *pLineEntry)
{
if(!pLineEntry) return;
//first delete all the string members
StringList *pTemp = pLineEntry->pMembers;
StringList *pPrev = NULL;
while(pTemp)
{
if(pTemp->pEntry)
{
if(pTemp->pEntry)
{
delete [] pTemp->pEntry;
pTemp->pEntry = NULL;
}
}
pPrev = pTemp;
pTemp = pPrev->pNext;
if(pPrev)
{
pPrev->pNext = NULL;
delete pPrev;
}
}
//now delete the remainter of our list
DeleteVEL(pLineEntry->pNext);
pLineEntry->pNext = NULL;
//delete our self
if(pLineEntry)
{
delete pLineEntry;
}
}
/*****************************************************************************/
/* DeleteVEL */
/* Use recursion to delete VCARD_LINE list */
/* */
/*****************************************************************************/
void DeleteVCL(VCARD_LINE *vclList)
{
if(!vclList) return;
//NOTE: dont delete vclList->pName because it came from the table
//delete the vcard entries (recursive)
DeleteVEL(vclList->pLineEntries);
//recursively delete the list
DeleteVCL(vclList->pNext);
//delete ourselve
if(vclList)
{
delete vclList;
}
}
/*****************************************************************************/
/* MakeVCard */
/* Given a record, search the LOOKUP TABLE for the entry */
/* When found, add the line to a VCARD_LINE list */
/* Once all entries are processed, recursivly run through the VCARD_LINE*/
/* to determine the size (in bytes) required for storage... then */
/* then allocate that much space, and recursivly run again to do the */
/* copy */
/* */
/* WARNING: this function allocates memory that it DOESNT FREE */
/* */
/* Returns 0 on error, char* pointing to the next VCARD on success */
/*****************************************************************************/
char *MakeVCard(CEPROPVAL *pPropVal, UINT retrieved, UINT *dataSize)
{
VCARD_LINE *vclList = NULL;
for(UINT i=0; i<retrieved; i++)
{
//look for the table entry for this OID
for(UINT j=0; j<g_ContactSize; j++)
{
// when found, update the list of items (but only add it once)
if(pPropVal[i].propid == g_sContactOidTranslator[j].oid_id)
{
AddLine(&vclList, &pPropVal[i], j);
break;
}
}
}
//now we have made the VCard, so put the information
// into an array and ship it out
UINT uiBytesReq = TraverseVCL(vclList, 0, 0);
//allocate enough memory to hold the data, and copy it it
*dataSize = strlen(VCARD_HEADER)+uiBytesReq+strlen(VCARD_FOOTER);
char *lpDest = new char[*dataSize];
memcpy(lpDest, VCARD_HEADER, strlen(VCARD_HEADER));
TraverseVCL(vclList, lpDest, strlen(VCARD_HEADER));
memcpy(lpDest+uiBytesReq+strlen(VCARD_HEADER),
VCARD_FOOTER, strlen(VCARD_FOOTER));
//destroy the VCARD list
DeleteVCL(vclList);
return lpDest;
}
/*****************************************************************************/
/* AddLine */
/* Add a line entry to a VCARD_LIST */
/* */
/* Generate a line that will be inserted into the VCARD file */
/* Since certain VCARD lines may be constructed of multiple field */
/* (for example, N: contains first name, last name, prefix, etc */
/* we must search to first find the 'N:' node and then place the */
/* record in according to ordinal (as supplied by the LOOKUP TABLE */
/*****************************************************************************/
void AddLine(VCARD_LINE **ppvclList, CEPROPVAL *pPropVal, UINT uiTableIdx)
{
VCARD_LINE *pVCList = *ppvclList;
VCARD_LINE *pVCLast = pVCList;
VCARD_LINE *pOurLine = NULL;
//first see if this line has been entered already, if it has
// set pOurLine and break out of the loop
while(pVCList)
{
if(strcmp(pVCList->pName,g_sContactOidTranslator[uiTableIdx].line_name) == 0)
{
pOurLine = pVCList;
break;
}
if(pVCList->pNext)
pVCLast = pVCList->pNext;
pVCList = pVCList->pNext;
}
//this will happen if there were no entries
if(!pOurLine && pVCLast == NULL)
{
pVCLast = new VCARD_LINE();
*ppvclList = pVCLast;
pOurLine = pVCLast;
pOurLine->pName = g_sContactOidTranslator[uiTableIdx].line_name;
pOurLine->pNext = NULL;
pOurLine->pLineEntries = NULL;
}
else if(!pOurLine && pVCLast->pNext == NULL)
{
pVCLast->pNext = new VCARD_LINE();
pOurLine = pVCLast->pNext;
pOurLine->pName = g_sContactOidTranslator[uiTableIdx].line_name;
pOurLine->pNext = NULL;
pOurLine->pLineEntries = NULL;
}
ASSERT(pOurLine);
//now that we have the line for our new (or entry to append into)
// put in the attribute
VCARD_ENTRY_LIST *pVELTemp = 0;
UINT uiCnt = g_sContactOidTranslator[uiTableIdx].iOrd;
if(pOurLine->pLineEntries)
pVELTemp = pOurLine->pLineEntries;
else
{
pVELTemp = new VCARD_ENTRY_LIST();
pOurLine->pLineEntries = pVELTemp;
memset(pVELTemp, 0, sizeof(VCARD_ENTRY_LIST));
}
//go to the uiCnt'th node in the linked list (making new
// nodes as required
while(uiCnt > 1)
{
//if the next item DNE create one
if(!pVELTemp->pNext)
{
pVELTemp->pNext = new VCARD_ENTRY_LIST();
memset(pVELTemp->pNext, 0, sizeof(VCARD_ENTRY_LIST));
}
//jump to the next item
pVELTemp = pVELTemp->pNext;
uiCnt --;
}
//now that we have the item, place our string onto the entrys list
if(!pVELTemp->pMembers)
{
pVELTemp->pMembers = new StringList();
pVELTemp->pMembers->pNext = 0;
pVELTemp->pMembers->pEntry = UnicodeToChar(pPropVal->val.lpwstr);
}
else
{
StringList *pTemp = new StringList();
pTemp->pNext = pVELTemp->pMembers;
pTemp->pEntry = UnicodeToChar(pPropVal->val.lpwstr);
pVELTemp->pMembers = pTemp;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -