📄 vproperty.cpp
字号:
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;
}
// ------------------ 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -