On Jul 21, 2011, at 14:13 , Patrick Ohly wrote: > On Do, 2011-07-21 at 12:21 +0200, Patrick Ohly wrote: >> Now there is only one other problem with PHOTO uris. They get encoded as >> binary data: >> >> PHOTO;VALUE=uri:http://example.com/photo.jpg >> => >> PHOTO;ENCODING=B;VALUE=uri:aHR0cDovL2V4YW1wbGUuY29tL3Bob3RvLmpwZw== >> >> Is that because PHOTO is defined as "blob"? >> >> Would it make sense to be selective in the encoder for "blob" and only >> use binary encoding if the content contains non-printable characters? > > This patch has the desired effect: > > [...] > > I tried it with both binary PHOTO and VALUE=uri.
Looks fine, however I'd prefer to restrict that functionality to a new convmode CONVMODE_BLOB_AUTO, instead of changing the behaviour of CONVMODE_BLOB_B64 which has the B64 encoding as a promise in its name :-). I added this in the following patch (which fits on top of current meego/bmc19661). >From 1161e5f15100432f7edad792bc72fe64ca22bf00 Mon Sep 17 00:00:00 2001 From: Lukas Zeller <[email protected]> Date: Fri, 22 Jul 2011 14:34:24 +0200 Subject: [PATCH] "blob" fields: Added separate CONVMODE_BLOB_AUTO conversion mode for fields that should be rendered as B64 only in case they are really non-printable or non-ASCII This is an addition to 8d5cce896d ("blob" fields: avoid binary encoding if possible) to avoid change of behaviour for CONVMODE_BLOB_B64. --- src/sysync/mimedirprofile.cpp | 32 ++++++++++++++++++++++---------- src/sysync/mimedirprofile.h | 1 + 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/sysync/mimedirprofile.cpp b/src/sysync/mimedirprofile.cpp index 1499876..c8fe995 100644 --- a/src/sysync/mimedirprofile.cpp +++ b/src/sysync/mimedirprofile.cpp @@ -175,6 +175,8 @@ bool TMIMEProfileConfig::getConvMode(cAppCharP aText, sInt16 &aConvMode) aConvMode = CONVMODE_MULTIMIX; else if (strucmp(aText,"blob_b64",n)==0) aConvMode = CONVMODE_BLOB_B64; + else if (strucmp(aText,"blob_auto",n)==0) + aConvMode = CONVMODE_BLOB_AUTO; else if (strucmp(aText,"mailto",n)==0) aConvMode = CONVMODE_MAILTO; else if (strucmp(aText,"valuetype",n)==0) @@ -2260,7 +2262,8 @@ sInt16 TMimeDirProfileHandler::generateValue( maxSiz = 0; // no size restriction bool noTruncate=aItem.getTargetItemType()->getFieldOptions(fid)->notruncate; // check for BLOB values - if ((aConvDefP->convmode & CONVMODE_MASK)==CONVMODE_BLOB_B64) { + sInt16 convmode = aConvDefP->convmode & CONVMODE_MASK; + if (convmode==CONVMODE_BLOB_B64 || convmode==CONVMODE_BLOB_AUTO) { // no value lists, escaping, enums. Simply set value and encoding TItemField *fldP = aItem.getArrayField(fid,aRepOffset,true); // existing array elements only if (!fldP) return GENVALUE_EXHAUSTED; // no leaf field - must be exhausted array (fldP==NULL is not possible here for non-arrays) @@ -2275,16 +2278,22 @@ sInt16 TMimeDirProfileHandler::generateValue( } // append to existing string fldP->appendToString(outval,maxSiz); - // force B64 encoding if non-printable or non-ASCII characters - // are in the value - size_t len = outval.size(); - for (size_t i = 0; i < len; i++) { - char c = outval[i]; - if (!isascii(c) || !isprint(c)) { - aEncoding=enc_base64; - break; + if (convmode==CONVMODE_BLOB_AUTO) { + // auto mode: use B64 encoding only if non-printable or + // non-ASCII characters are in the value + size_t len = outval.size(); + for (size_t i = 0; i < len; i++) { + char c = outval[i]; + if (!isascii(c) || !isprint(c)) { + aEncoding=enc_base64; + break; + } } } + else { + // blob mode: always use B64 + aEncoding=enc_base64; + } // only ASCII in value: either because it contains only // those to start with or because they will be encoded aNonASCII=false; @@ -3658,7 +3667,10 @@ bool TMimeDirProfileHandler::parseValue( // find out if value exists (available in source and target) if (isFieldAvailable(aItem,fid)) { // parse only if field available in both source and target - if ((aConvDefP->convmode & CONVMODE_MASK)==CONVMODE_BLOB_B64) { + if ( + (aConvDefP->convmode & CONVMODE_MASK)==CONVMODE_BLOB_B64 || + (aConvDefP->convmode & CONVMODE_MASK)==CONVMODE_BLOB_AUTO + ) { // move 1:1 into field // - get pointer to leaf field TItemField *fldP = aItem.getArrayField(fid,aRepOffset); diff --git a/src/sysync/mimedirprofile.h b/src/sysync/mimedirprofile.h index 4db8bdf..ed67fbf 100755 --- a/src/sysync/mimedirprofile.h +++ b/src/sysync/mimedirprofile.h @@ -49,6 +49,7 @@ namespace sysync { #define CONVMODE_VALUETYPE 14 // automatic VALUE parameter e.g. for timestamp fields that contain a date-only value (VALUE=DATE) or duration (VALUE=DURATION) #define CONVMODE_MULTIMIX 15 // special mode for mapping enums to bits (like CONVMODE_BITMAP), but mixed from multiple fields and with option to store as-is (special enum "value" syntax needed) #define CONVMODE_FULLVALUETYPE 16 // explicit VALUE parameter, does not assume a default +#define CONVMODE_BLOB_AUTO 17 // like CONVMODE_BLOB_B64, but if data consists of printable ASCII-chars only, no B64 encoding is used // derived type modes start here #define CONVMODE_MIME_DERIVATES 20 -- 1.7.5.4+GitX Lukas Zeller, plan44.ch [email protected] - www.plan44.ch _______________________________________________ os-libsynthesis mailing list [email protected] http://lists.synthesis.ch/mailman/listinfo/os-libsynthesis
