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

Reply via email to