예제 #1
0
파일: VObject.cpp 프로젝트: ruphy/kfunambol
void VObject::fromNativeEncoding()
{
    bool is_30 = !wcscmp(getVersion(), TEXT("3.0"));

    for (int index = propertiesCount() - 1; index >= 0; index--) {
        VProperty *vprop = getProperty(index);

        if (vprop->equalsEncoding(TEXT("QUOTED-PRINTABLE"))) {
            // remove this, we cannot recreate it
            vprop->removeParameter(TEXT("ENCODING"));
        }

        WCHAR *native = vprop->getValue();
        // in the worst case every comma/linebreak is replaced with
        // two characters and each \n with =0D=0A
        WCHAR *foreign = new WCHAR[6 * wcslen(native) + 1];
        WCHAR curr;
        int in = 0, out = 0;
        // line break is encoded with either one or two
        // characters on different platforms
        const int linebreaklen = wcslen(SYNC4J_LINEBREAK);

        // use backslash for special characters,
        // if necessary do quoted-printable encoding
        bool doquoted = !is_30 &&
            wcsstr(native, SYNC4J_LINEBREAK) != NULL;
        while ((curr = native[in]) != 0) {
            in++;
            switch (curr) {
             case ',':
                if (!is_30) {
                    // normal character
                    foreign[out] = curr;
                    out++;
                    break;
                }
                // no break!
             case ';':
             case '\\':
                foreign[out] = '\\';
                out++;
                foreign[out] = curr;
                out++;
                break;
             case SEMICOLON_REPLACEMENT:
                foreign[out] = ';';
                out++;
                break;
             default:
                if (doquoted &&
                    (curr == '=' || (unsigned char)curr >= 128)) {
                    // escape = and non-ASCII characters
                    swprintf(foreign + out, 4, TEXT("=%02X"), (unsigned int)(unsigned char)curr);
                    out += 3;
                } else if (!wcsncmp(native + in - 1,
                                    SYNC4J_LINEBREAK,
                                    linebreaklen)) {
                    // line break
                    if (is_30) {
                        foreign[out] = '\\';
                        out++;
                        foreign[out] = 'n';
                        out++;
                    } else {
                        wcscpy(foreign + out, TEXT("=0D=0A"));
                        out += 6;
                    }
                    in += linebreaklen - 1;
                } else {
                    foreign[out] = curr;
                    out++;
                }
                break;
            }
        }
        foreign[out] = 0;
        vprop->setValue(foreign);
        delete [] foreign;
        if (doquoted) {
            // we have used quoted-printable encoding
            vprop->addParameter(TEXT("ENCODING"), TEXT("QUOTED-PRINTABLE"));
        }
    }
}
예제 #2
0
VProperty* VConverter::readFieldHeader(WCHAR* buffer) {

    WCHAR* headerIndex = NULL;
    WCHAR* quotaIndex = NULL;
    quotaIndex = wcschr(buffer, '"');
    headerIndex = wcschr(buffer, ':');


    if(!headerIndex)
        return NULL;
    bool quota = false;
    // If the header contains a quotation mark,
    // then rescan it starting directly after the _quotation mark_
    // (not after the end of the header, as in the original code)
    // to find the real end of the header.
    //
    // The reason for this code apparently is that the simple search above
    // might have found a headerIndex which points into the middle of
    // the quoted string.
    //
    // A better solution would be to always scan the header properly.
    if(quotaIndex && quotaIndex < headerIndex) {
        quota = true;
        int len = int(wcslen(buffer));
        for(int i = int(quotaIndex - buffer) + 1; i < len; i++) {
            if(buffer[i] == '"')
                quota = !quota;
            if(buffer[i] == ':' && !quota) {
                headerIndex = &buffer[i];
                break;
            }
        }
    }

    if(quota)
        return NULL;

    VProperty* prop = new VProperty(NULL);

    WCHAR* header = new WCHAR[wcslen(buffer) + 1];
    buffer[headerIndex - buffer] = '\0';
    wcscpy(header, buffer);
    // Shift the remaing string to the front of the buffer.
    // Using wcscpy() for that is incorrect because the standard
    // does not guarantee in which order bytes are moved!
    // wcscpy(buffer, ++headerIndex);
    ++headerIndex;
    memmove(buffer, headerIndex, (wcslen(headerIndex) + 1) * sizeof(*headerIndex));

    //if the header is folded (in .ics files)
    //we need to remove the folding
    WCHAR* headerFolding = NULL;
    if ((headerFolding = wcsstr(header, TEXT("\n ")))) {
        header[headerFolding - header] = '\0';
    }

    WCHAR seps[] = TEXT(";");
    WCHAR *token;
    bool first = true;

    token = wcstok( header, seps );
    while( token != NULL ) {
        if (first) {

            WCHAR* group = new WCHAR[wcslen(token) + 1];
            if(extractGroup(token, group))
                prop->addParameter(TEXT("GROUP"), group);
            else
                delete [] group; group= NULL;
            prop->setName(token);
            first = false;
        }
        else {
            WCHAR* paramIndex;
            paramIndex = wcschr(token, '=');

            if(paramIndex) {
                WCHAR* paramName = new WCHAR[wcslen(token) + 1];
                token[paramIndex - token] = '\0';
                wcscpy(paramName, token);
                ++paramIndex;
                memmove(token, paramIndex, (wcslen(paramIndex) + 1) * sizeof(*paramIndex));

                WCHAR* paramVal = new WCHAR[wcslen(token) + 1];
                wcscpy(paramVal, token);
                prop->addParameter(paramName, paramVal);

                delete [] paramName; paramName = NULL;
                delete [] paramVal; paramVal = NULL;
            }
            else {
                prop->addParameter(token,NULL);
            }
        }
        token = wcstok( NULL, seps );
    }

    delete [] header; header = NULL;
    delete token; token = NULL;

    return prop;
}
예제 #3
0
VProperty* ToDo::getVPropertyFromiCalProperty(const WCHAR* name, iCalProperty* prop) {
    if(name && prop) {
        VProperty *vprop = new VProperty(name, prop->getValue());

        if(prop->getAltre())
            vprop->addParameter(TEXT("ALTREP"), prop->getAltre());
        if(prop->getCn())
            vprop->addParameter(TEXT("CN"), prop->getCn());
        if(prop->getCutype())
            vprop->addParameter(TEXT("CUTYPE"), prop->getCutype());
        if(prop->getDelegatedFrom())
            vprop->addParameter(TEXT("DELEGATED-FROM"), prop->getDelegatedFrom());
        if(prop->getDelegatedTo())
            vprop->addParameter(TEXT("DELEGATED-TO"), prop->getDelegatedTo());
        if(prop->getDir())
            vprop->addParameter(TEXT("DIR"), prop->getDir());
        if(prop->getEncoding())
            vprop->addParameter(TEXT("ENCODING"), prop->getEncoding());
        if(prop->getFormatType())
            vprop->addParameter(TEXT("FMTTYPE"), prop->getFormatType());
        if(prop->getFbType())
            vprop->addParameter(TEXT("FBTYPE"), prop->getFbType());
        if(prop->getLanguage())
            vprop->addParameter(TEXT("LANGUAGE"), prop->getLanguage());
        if(prop->getMember())
            vprop->addParameter(TEXT("MEMBER"), prop->getMember());
        if(prop->getPartStat())
            vprop->addParameter(TEXT("PARTSTAT"), prop->getPartStat());
        if(prop->getRange())
            vprop->addParameter(TEXT("RANGE"), prop->getRange());
        if(prop->getTrigRel())
            vprop->addParameter(TEXT("RELATED"), prop->getTrigRel());
        if(prop->getRelated())
            vprop->addParameter(TEXT("RELTYPE"), prop->getRelated());
        if(prop->getRole())
            vprop->addParameter(TEXT("ROLE"), prop->getRole());
        if(prop->getRsvp())
            vprop->addParameter(TEXT("RSVP"), prop->getRsvp());
        if(prop->getSentBy())
            vprop->addParameter(TEXT("SENT-BY"), prop->getSentBy());
        if(prop->getTzID())
            vprop->addParameter(TEXT("TZID"), prop->getTzID());
        if(prop->getValueType())
            vprop->addParameter(TEXT("VALUE"), prop->getValueType());
        if(prop->getXParam()) {
            ArrayList* xParamList = new ArrayList();
            xParamList = prop->getXParam();
            for(int i = 0; i<xParamList->size(); i++) {
                WKeyValuePair* xParam = (WKeyValuePair*)xParamList->get(i);
                if(xParam->getKey())
                    if(xParam->getValue())
                        vprop->addParameter(xParam->getKey(), xParam->getValue());
                    else
                        vprop->addParameter(xParam->getKey(), NULL);
            }
            delete xParamList;
            xParamList = NULL;
        }

        return vprop;
    }
    else
        return NULL;
}
예제 #4
0
//
// Format and return a vCard string from the propertyMap.
//
wstring& WinContact::toString() {

    vCard = L"";

    //
    // Conversion: WinContact -> vObject.
    // ----------------------------------
    //
    VObject* vo = new VObject();
    wstring element;
    VProperty* vp = NULL;
    bool found = false;


    vp = new VProperty(L"BEGIN", L"VCARD");
    vo->addProperty(vp);
    delete vp; vp = NULL;

    vp = new VProperty(L"VERSION", VCARD_VERSION);
    vo->addProperty(vp);
    delete vp; vp = NULL;
        
    // ------- Name -------
    // Add only if at least 1 property is supported, but include 
    // all elements in the right order.
    found = false;
    vp = new VProperty(L"N");
    if (getProperty(L"LastName",   element))  found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"FirstName",  element))  found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"MiddleName", element))  found = true;  
    vp->addValue(element.c_str());
    if (getProperty(L"Title",      element))  found = true;  
    vp->addValue(element.c_str());
    if (getProperty(L"Suffix",     element))  found = true;  
    vp->addValue(element.c_str());
    if (found) {
        vo->addProperty(vp);
    }
    delete vp; vp = NULL;


    if (getProperty(L"Birthday", element)) {
        vp = new VProperty(L"BDAY", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Body", element)) {
        vp = new VProperty(L"NOTE", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"BusinessFaxNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"WORK", NULL);
        vp->addParameter(L"FAX", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"BusinessTelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"VOICE", NULL);
        vp->addParameter(L"WORK",  NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Business2TelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"VOICE", NULL);
        vp->addParameter(L"WORK",  NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"BusinessWebPage", element)) {
        vp = new VProperty(L"URL", element.c_str());
        vp->addParameter(L"WORK",  NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"CarTelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"CAR",   NULL);
        vp->addParameter(L"VOICE", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Categories", element)) {
        vp = new VProperty(L"CATEGORIES", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"CompanyMainTelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"WORK",  NULL);
        vp->addParameter(L"PREF",  NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"FileAs", element)) {
        vp = new VProperty(L"FN", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }

    // Mapping is:
    // Email1Address <-> EMAIL;INTERNET:
    // Email2Address <-> EMAIL;INTERNET;HOME:
    // Email3Address <-> EMAIL;INTERNET;WORK:
    if (getProperty(L"Email1Address", element)) {
        vp = new VProperty(L"EMAIL", element.c_str());
        vp->addParameter(L"INTERNET", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Email2Address", element)) {
        vp = new VProperty(L"EMAIL", element.c_str());
        vp->addParameter(L"INTERNET", NULL);
        vp->addParameter(L"HOME",     NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Email3Address", element)) {
        vp = new VProperty(L"EMAIL", element.c_str());
        vp->addParameter(L"INTERNET", NULL);
        vp->addParameter(L"WORK",     NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }

    if (getProperty(L"JobTitle", element)) {
        vp = new VProperty(L"TITLE", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"HomeTelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"VOICE", NULL);
        vp->addParameter(L"HOME",  NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Home2TelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"VOICE", NULL);
        vp->addParameter(L"HOME",  NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"HomeFaxNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"HOME", NULL);
        vp->addParameter(L"FAX", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"HomeWebPage", element)) {
        vp = new VProperty(L"URL", element.c_str());
        vp->addParameter(L"HOME", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Importance", element)) {
        vp = new VProperty(L"PRIORITY", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"MobileTelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"CELL", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"NickName", element)) {
        vp = new VProperty(L"NICKNAME", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"OtherFaxNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"FAX", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"OtherTelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"VOICE", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"PagerNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"PAGER", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"PrimaryTelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"PREF",  NULL);
        vp->addParameter(L"VOICE", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Profession", element)) {
        vp = new VProperty(L"ROLE", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Sensitivity", element)) {
        long sensitivity = _wtoi(element.c_str());
        vp = new VProperty(TEXT("CLASS"));
        if(sensitivity == winPrivate) {
            vp->addValue(TEXT("PRIVATE"));
        }
        else if (sensitivity == winConfidential) {
            vp->addValue(TEXT("CONFIDENTIAL"));
        }
        else {  // default value
            vp->addValue(TEXT("PUBLIC"));
        }
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"WebPage", element)) {
        vp = new VProperty(L"URL", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }


    // ----- ORG -----
    // Add only if at least 1 property is supported, but include 
    // all elements in the right order.
    found = false;
    vp = new VProperty(L"ORG");
    if (getProperty(L"CompanyName",    element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"Department",     element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"OfficeLocation", element))   found = true;
    vp->addValue(element.c_str());
    if (found) {
        vo->addProperty(vp);
    }
    delete vp; vp = NULL;


    // ----- Address HOME -----
    // Add only if at least 1 property is supported, but include 
    // all elements in the right order.
    // "AddressPostOfficeBox" is not supported by WM.
    // "AddressExtended" is not supported by Outlook/WM.
    found = false;
    vp = new VProperty(L"ADR");
    vp->addParameter(L"HOME", NULL);
    if (getProperty(L"HomeAddressPostOfficeBox", element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"HomeAddressExtended",      element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"HomeAddressStreet",        element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"HomeAddressCity",          element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"HomeAddressState",         element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"HomeAddressPostalCode",    element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"HomeAddressCountry",       element))   found = true;
    vp->addValue(element.c_str());
    if (found) {
        vo->addProperty(vp);
    }
    delete vp; vp = NULL;


    // ----- Address -----
    // Add only if at least 1 property is supported, but include 
    // all elements in the right order.
    // "AddressPostOfficeBox" is not supported by WM.
    // "AddressExtended" is not supported by Outlook/WM.
    found = false;
    vp = new VProperty(L"ADR");
    if (getProperty(L"OtherAddressPostOfficeBox", element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"OtherAddressExtended",      element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"OtherAddressStreet",        element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"OtherAddressCity",          element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"OtherAddressState",         element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"OtherAddressPostalCode",    element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"OtherAddressCountry",       element))   found = true;
    vp->addValue(element.c_str());
    if (found) {
        vo->addProperty(vp);
    }
    delete vp; vp = NULL;


    // ----- Address WORK -----
    // Add only if at least 1 property is supported, but include 
    // all elements in the right order.
    // "AddressPostOfficeBox" is not supported by WM.
    // "AddressExtended" is not supported by Outlook/WM.
    found = false;
    vp = new VProperty(L"ADR");
    vp->addParameter(L"WORK", NULL);
    if (getProperty(L"BusinessAddressPostOfficeBox", element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"BusinessAddressExtended",      element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"BusinessAddressStreet",        element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"BusinessAddressCity",          element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"BusinessAddressState",         element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"BusinessAddressPostalCode",    element))   found = true;
    vp->addValue(element.c_str());
    if (getProperty(L"BusinessAddressCountry",       element))   found = true;
    vp->addValue(element.c_str());
    if (found) {
        vo->addProperty(vp);
    }
    delete vp; vp = NULL;
    
     //PHOTO
    if (getProperty(L"Photo", element)) {
        vp = new VProperty(L"PHOTO", element.c_str());
        if (element != L"") {
            vp->addParameter(L"CONTENT-VALUE", L"UNCHANGED");        
            vp->addParameter(L"ENCODING", L"b");
            if (photoType.length() > 0) {
                vp->addParameter(L"TYPE", photoType.c_str());
            }
        }
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }    

    //
    // ---- Funambol defined properties ----
    // Support for other fields that don't have a
    // specific correspondence in vCard.
    if (getProperty(L"Anniversary", element)) {
        vp = new VProperty(L"X-ANNIVERSARY");
        vp->addValue(element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(TEXT("BillingInformation"), element)) {
        vp = new VProperty(TEXT("X-FUNAMBOL-BILLINGINFO"), element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"CallbackTelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"X-FUNAMBOL-CALLBACK",  NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Children", element)) {
        vp = new VProperty(L"X-FUNAMBOL-CHILDREN", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Companies", element)) {
        vp = new VProperty(L"X-FUNAMBOL-COMPANIES", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"CustomerID", element)) {
        vp = new VProperty(L"X-FUNAMBOL-CUSTOMERID", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Folder", element)) {
        vp = new VProperty(L"X-FUNAMBOL-FOLDER");
        vp->addValue(element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Gender", element)) {
        vp = new VProperty(L"X-FUNAMBOL-GENDER", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"GovernmentIDNumber", element)) {
        vp = new VProperty(L"X-FUNAMBOL-GOVERNMENTID", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Hobby", element)) {
        vp = new VProperty(L"X-FUNAMBOL-HOBBIES", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"IMAddress", element)) {
        vp = new VProperty(L"EMAIL", element.c_str());
        vp->addParameter(L"INTERNET", NULL);
        vp->addParameter(L"HOME",     NULL);
        vp->addParameter(L"X-FUNAMBOL-INSTANTMESSENGER", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"IM2Address", element)) {
        vp = new VProperty(L"EMAIL", element.c_str());
        vp->addParameter(L"INTERNET", NULL);
        vp->addParameter(L"HOME",     NULL);
        vp->addParameter(L"X-FUNAMBOL-INSTANTMESSENGER", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"IM3Address", element)) {
        vp = new VProperty(L"EMAIL", element.c_str());
        vp->addParameter(L"INTERNET", NULL);
        vp->addParameter(L"HOME",     NULL);
        vp->addParameter(L"X-FUNAMBOL-INSTANTMESSENGER", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Initials", element)) {
        vp = new VProperty(L"X-FUNAMBOL-INITIALS", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }

    if (getProperty(L"Language", element)) {
        vp = new VProperty(L"X-FUNAMBOL-LANGUAGES", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"ManagerName", element)) {
        vp = new VProperty(L"X-MANAGER", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Mileage", element)) {
        vp = new VProperty(L"X-FUNAMBOL-MILEAGE", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"OrganizationalIDNumber", element)) {
        vp = new VProperty(L"X-FUNAMBOL-ORGANIZATIONALID", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"RadioTelephoneNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"X-FUNAMBOL-RADIO", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Spouse", element)) {
        vp = new VProperty(L"X-SPOUSE", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"Subject", element)) {
        vp = new VProperty(L"X-FUNAMBOL-SUBJECT", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"TelexNumber", element)) {
        vp = new VProperty(L"TEL", element.c_str());
        vp->addParameter(L"X-FUNAMBOL-TELEX", NULL);
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"YomiCompanyName", element)) {
        vp = new VProperty(L"X-FUNAMBOL-YOMICOMPANYNAME", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"YomiFirstName", element)) {
        vp = new VProperty(L"X-FUNAMBOL-YOMIFIRSTNAME", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }
    if (getProperty(L"YomiLastName", element)) {
        vp = new VProperty(L"X-FUNAMBOL-YOMILASTNAME", element.c_str());
        vo->addProperty(vp);
        delete vp; vp = NULL;
    }


    vp = new VProperty(L"END", L"VCARD");
    vo->addProperty(vp);
    delete vp; vp = NULL;


    //
    // Format the vCard.
    // -----------------
    //
    WCHAR* tmp = vo->toString();
    if (tmp) {
        vCard = tmp;
        delete [] tmp;
    }
    if (vo) { delete vo; vo = NULL; }
    return vCard;
}