vproperty.cpp

来自「funambol window mobile客户端源代码」· C++ 代码 · 共 761 行 · 第 1/2 页

CPP
761
字号
            WCHAR *value, *valueConv;
            for (int i=0; i<valueCount(); i++) {
                if (i>0) {
                    valueString.append(TEXT(";"));
                }
                value = getValue(i);

                // Escape special chars - based on version (";"  "\", ",")
                valueConv = escapeSpecialChars(value, version);

                valueString.append(valueConv);
                delete [] valueConv;
            }
        } else { 
            
            WCHAR *value;
            for (int i=0; i<valueCount(); i++) {
                if (i>0) {
                    valueString.append(TEXT(";"));
                }
                value = getValue(i);         
                if (i == 0 && (value != NULL) && wcslen(value) > 0 && (wcscmp(name, TEXT("PHOTO")) == 0)) {
                    valueString.append(TEXT("\r\n"));
                }   
                valueString.append(value);
            }

        }

        if (isToFormatValue) {
            // QUOTED-PRINTABLE encoding (of all values)
            if (equalsEncoding(TEXT("QUOTED-PRINTABLE"))) {

                char* s  = toMultibyte(valueString.c_str());
                char* qp = convertToQP(s, 0);
                WCHAR* qpValueString = toWideChar(qp);
                if(qpValueString)
                    propertyString.append(qpValueString);
                else
                    propertyString.append(valueString);

                delete [] qpValueString;
                delete [] s;
                delete [] qp;
            }

            // BASE64 encoding (of all values)
            else if(equalsEncoding(TEXT("BASE64")) ||
               equalsEncoding(TEXT("B")) ||
               equalsEncoding(TEXT("b")) ) {

                char* s  = toMultibyte(valueString.c_str());
                int len = strlen(s);
                char* base64 = new char[2*len + 1];
                b64_encode(base64, s, len);
                WCHAR* b64ValueString = toWideChar(base64);

                propertyString.append(b64ValueString);
                // Extra line break: required for v.2.1 / optional for v.3.0
                //propertyString.append(RFC822_LINE_BREAK);

                delete [] b64ValueString;
                delete [] base64;
                delete [] s;
            }


            // Default encoding (7bit)
            else {
                propertyString.append(valueString);
            }
        } else { // not is to apply any transformation
            propertyString.append(valueString);
        }
    }


finally:
    // memory must be free by caller with delete []
    WCHAR *str = wstrdup(propertyString);
    return str;
}




WCHAR* VProperty::getParameter(int index){

    WKeyValuePair *parameter;
    parameter = (WKeyValuePair*)parameters->get(index);
    return (WCHAR *)parameter->getKey();
}

bool VProperty::equalsEncoding(WCHAR* encoding) {

    if ((encoding != NULL) && ((containsParameter(TEXT("ENCODING")) &&
        !wcscmp(getParameterValue(TEXT("ENCODING")),encoding)) ||
        containsParameter(encoding)))
        return true;
    return false;
}



bool VProperty::isType(WCHAR* type) {
    if(containsParameter(type))
        return true;
    if(containsParameter(TEXT("TYPE")) && getParameterValue(TEXT("TYPE"))) {

        WCHAR seps[] = TEXT(",");
        WCHAR* token;

        token = wcstok(getParameterValue(TEXT("TYPE")), seps );

        while( token != NULL )
        {
            if(!wcscmp(type, token))
                return true;
            token = wcstok( NULL, seps );
        }
    }

    if(containsParameter(TEXT("type")) && getParameterValue(TEXT("type"))) {

        WCHAR seps[] = TEXT(",");
        WCHAR* token;

        token = wcstok(getParameterValue(TEXT("type")), seps );

        while( token != NULL )
        {
            if(!wcscmp(type, token))
                return true;
            token = wcstok( NULL, seps );
        }
    }
    return false;
}


BEGIN_NAMESPACE

// ------------------ Public functions --------------------

/*
 * Convert a char* string into QUOTED-PRINTABLE format.
 * @param psz     : the input char* string
 * @param start   : the start point of the line
 * @return        : the char* string in QP format (new - must be freed by the caller!)
 *                  (NULL if conversion failed)
 */
char* convertToQP(const char* input, int start) {

    int   count   = start;
    int   maxLen  = 3*strlen(input);         // This is the max length for output string
    char *sAppend = NULL;
    char  szTemp[10];
    const char *p;

    // new - must be freed by the caller
    char* qpString = new char[maxLen + 1];
    strcpy(qpString, "");

    if (maxLen>0) {
        sAppend = new char[maxLen + 1];
        strncpy(sAppend, input, maxLen);
        sAppend[maxLen]=0;

        if(!sAppend)
            return NULL;

        for (p = sAppend; *p; p++) {
            //if (count > QP_MAX_LINE_LEN) {
            //    strcat(qpString, "=\r\n");
            //    count = 0;
            //}
            //else
            if (*p == '\t' || *p == ' ') {
                const char *pScan = p;
                while (*pScan && (*pScan == '\t' || *pScan == ' ')) {
                    pScan++;
                }
                if (*pScan == '\0') {
                    while (*p) {
                        unsigned char ind = *p;
                        sprintf(szTemp, "=%02X", ind);
                        strcat(qpString, szTemp);
                        count += 3;
                        p++;

                        //if (count > QP_MAX_LINE_LEN) {
                        //    strcat(qpString, "=\r\n");
                        //    count = 0;
                        //}
                    }
                    break;
                }
                else {
                    sprintf(szTemp, "%c", *p);
                    strcat(qpString, szTemp);
                    count++;
                }
                continue;
            }
            else if (('!' <= *p) && ('~' >= *p) && ('=' != *p)) {
                sprintf(szTemp, "%c", *p);
                strcat(qpString, szTemp);
                count++;
            }
            else {
                unsigned char ind = *p;
                sprintf(szTemp, "=%02X", ind);
                strcat(qpString, szTemp);
                count += 3;
            }
        }

        delete [] sAppend;
    }
    return qpString;
}



// Returns true if special encoding is needed for the string 'in'.
bool encodingIsNeed(const char *in) {
    for(int i = 0; i < int(strlen(in)); i++)
        if ( (in[i] < 0x20) || ((unsigned char)in[i] > 0x7f))
            return true;

    return false;
}





/*
* Escape special characters adding a back-slash (i.e. ";" -> "\;")
* @param inputString  : the input string to parse
* @param version      : vCard version "2.1" or "3.0" - we have different chars to escape
 *                     (if not defined, default will be 2.1)
* @return             : the new allocated string with escaped chars
* Note:
*      returns new allocated WCHAR*, must be freed by the caller.
*/
WCHAR* escapeSpecialChars(const WCHAR* inputString, WCHAR* version) {

    int i, j, inputLen, outputLen;
    inputLen  = wcslen(inputString);
    WCHAR* wc = new WCHAR[2];
    WCHAR charsToEscape[4];

    bool is_30 = false;
    if (version) {
        is_30 = !wcscmp(version, TEXT("3.0"));
    }
    if (is_30) {
        wcscpy(charsToEscape, VCARD30_SPECIAL_CHARS);
    }
    else {
        wcscpy(charsToEscape, VCARD21_SPECIAL_CHARS);
    }


    // First find the length of output value
    outputLen = inputLen;
    for (i=0; i<inputLen; i++) {
        wcsncpy(wc, &inputString[i], 1);
        wc[1]=0;
        if (wcsstr(charsToEscape, wc))
            outputLen ++;
    }
    WCHAR* outputString = new WCHAR[outputLen+1];


    // Now escape special characters (add back-slash)
    j=0;
    for (i=0; i<inputLen; i++) {
        wcsncpy(wc, &inputString[i], 1);
        wc[1]=0;
        if (wcsstr(charsToEscape, wc)) {
            if (is_30 && inputString[i]=='\\' && inputString[i+1]=='n') {
                // none: this is "\n" sequence, MUST NOT be escaped in 3.0
            }
            else {
                outputString[j]   = '\\';
                j++;
            }
        }
        outputString[j] = inputString[i];
        j++;
    }

    outputString[outputLen] = 0;
    delete [] wc;
    return outputString;
}




/*
 * Folding of long lines. Output string is splitted into multiple
 * lines, delimited by the RFC-822 line break ("\r\n").
 * @param inputString : input WCHAR string of text
 * @param maxLine     : the length of lines in the output string
 * @return            : output WCHAR string with folded lines (new allocated)
 *
 * Note:
 *      returns new allocated WCHAR*, must be freed by the caller.
 */
WCHAR* folding(const WCHAR* inputString, const int maxLine) {

    // "\r\n" followed by a white space as line ending (RFC 2425)
    WCHAR newLine[4];
    wcscpy(newLine, RFC822_LINE_BREAK);
    wcscat(newLine, TEXT(" \0"));
    int outputLen = 0, i = 0;
    int inputLen  = wcslen(inputString);
    WCHAR* outputString;

    // No folding needed
    if (inputLen <= maxLine) {
        outputString = new WCHAR[inputLen + 1];
        wcscpy(outputString, inputString);
        goto finally;
    }

    outputLen = inputLen + (int)(inputLen/maxLine + 1)*wcslen(newLine);
    outputString = new WCHAR[outputLen + 1];
    outputString[0] = 0;

    for (i=0; i<inputLen; i += maxLine) {
        wcsncat(outputString, inputString+i, maxLine);
        wcscat(outputString, newLine);
    }
    outputString[outputLen] = 0;

finally:
    return outputString;
}



/*
 * Unfolding a logical line. Input string is splitted into multiple
 * lines, delimited by the RFC-822 line break ("\r\n") followed by one space.
 * @param inputString : input  WCHAR string with folded lines
 * @return            : output WCHAR string unfolded (new allocated)
 *
 * Note:
 *      returns new allocated WCHAR*, must be freed by the caller.
 */
WCHAR* unfolding(const WCHAR* inputString) {

    int inputLen  = wcslen(inputString);
    WCHAR* outputString = new WCHAR[inputLen + 1];
    outputString[0] = 0;

    int j=0;
    for (int i=0; i<inputLen-2; i++) {
        if (inputString[i]   == '\r' &&
            inputString[i+1] == '\n' &&
            inputString[i+2] == ' ') {
            i += 2;
            continue;
        }
        outputString[j] = inputString[i];
        j++;
    }
    outputString[j] = 0;

    return outputString;
}

END_NAMESPACE


⌨️ 快捷键说明

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