diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2011-07-22 08:36:22 +0200 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2011-07-29 08:15:19 +0200 |
commit | 53a42ad24b5158fe67ef1e1659e3b854099ee877 (patch) | |
tree | 01a30cc7a24f457fd8f230f6ff4232c4bd50486a /src/sysync/scriptcontext.cpp | |
parent | 92d2f367e72eccedb2cd1e103ec7770b6a426ef2 (diff) |
support for processing PHOTO data + URIsmeego-1-2
"blob" fields: avoid binary encoding if possible
================================================
This change is meant for the PHOTO value, which can contain both
binary data and plain text URIs. Other binary data fields might also
benefit when their content turns out to be plain text (shorter
encoding).
The change is that base64 encoding is not enforced if all characters
are ASCII and printable. That allows special characters like colon,
comma, and semicolon to appear unchanged in the content.
Regardless whether the check succeeds, the result is guaranteed to
contain only ASCII characters, either because it only contains those
to start with or because of the base64 encoding.
(cherry picked from commit 8d5cce896dcc5dba028d1cfa18f08e31adcc6e73)
scripting: added READ() method
==============================
The READ(filename) method returns the content of the file identified
with "filename". Relative paths are interpreted relative to the current
directory. On failures, an error messages is logged and UNASSIGNED
is returned.
This method is useful for inlining the photo data referenced with
local file:// URIs shortly before sending to a remote peer. SyncEvolution
uses the method in its outgoing vcard script as follows:
Field list:
<!-- Photo -->
<field name="PHOTO" type="blob" compare="never" merge="fillempty"/>
<field name="PHOTO_TYPE" type="string" compare="never" merge="fillempty"/>
<field name="PHOTO_VALUE" type="string" compare="never" merge="fillempty"/>
Profile:
<property name="PHOTO" filter="no">
<value field="PHOTO" conversion="BLOB_B64"/>
<parameter name="TYPE" default="no" show="yes">
<value field="PHOTO_TYPE"/>
</parameter>
<parameter name="VALUE" default="no" show="yes">
<value field="PHOTO_VALUE"/>
</parameter>
</property>
Script:
if (PHOTO_VALUE == "uri" &&
SUBSTR(PHOTO, 0, 7) == "file://") {
// inline the photo data
string data;
data = READ(SUBSTR(PHOTO, 7));
if (data != UNASSIGNED) {
PHOTO = data;
PHOTO_VALUE = "binary";
}
}
Test cases for inlining, not inlining because of non-file URI and
failed inling (file not found) were added to SyncEvolution.
(cherry picked from commit e3fdd5ca811f24b2f80e598f9d00d2e134aa85e1)
"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. (cherry picked from commit
0fd1d64b6ef8beb666c8fac6d29fb2e19341a7bc)
Diffstat (limited to 'src/sysync/scriptcontext.cpp')
-rwxr-xr-x | src/sysync/scriptcontext.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/sysync/scriptcontext.cpp b/src/sysync/scriptcontext.cpp index 35dff88..c99d2c2 100755 --- a/src/sysync/scriptcontext.cpp +++ b/src/sysync/scriptcontext.cpp @@ -27,6 +27,7 @@ #include "pcre.h" // for RegEx functions #endif +#include <stdio.h> // script debug messages #ifdef SYDEBUG @@ -869,6 +870,55 @@ public: aTermP->setAsInteger(exitcode); }; // func_Shellexecute + // string READ(string file) + // reads the file and returns its content or UNASSIGNED in case of failure; + // errors are logged + static void func_Read(TItemField *&aTermP, TScriptContext *aFuncContextP) + { + // get params + string file; + aFuncContextP->getLocalVar(0)->getAsString(file); + + // execute now + string content; + FILE *in; + in = fopen(file.c_str(), "rb"); + if (in) { + long size = fseek(in, 0, SEEK_END); + if (size >= 0) { + // managed to obtain size, use it to pre-allocate result + content.reserve(size); + fseek(in, 0, SEEK_SET); + } else { + // ignore seek error, might not be a plain file + clearerr(in); + } + + if (!ferror(in)) { + char buf[8192]; + size_t read; + while ((read = fread(buf, 1, sizeof(buf), in)) > 0) { + content.append(buf, read); + } + } + } + + if (in && !ferror(in)) { + // return content as string + aTermP->setAsString(content); + } else { + PLOGDEBUGPRINTFX(aFuncContextP->getDbgLogger(), + DBG_ERROR,( + "IO error in READ(\"%s\"): %s ", + file.c_str(), + strerror(errno))); + } + + if (in) { + fclose(in); + } + } // func_Read + // string REMOTERULENAME() // returns name of the LAST matched remote rule (or subrule), empty if none @@ -2220,6 +2270,7 @@ const TBuiltInFuncDef BuiltInFuncDefs[] = { { "REQUESTMAXTIME", TBuiltinStdFuncs::func_RequestMaxTime, fty_none, 1, param_oneInteger }, { "REQUESTMINTIME", TBuiltinStdFuncs::func_RequestMinTime, fty_none, 1, param_oneInteger }, { "SHELLEXECUTE", TBuiltinStdFuncs::func_Shellexecute, fty_integer, 3, param_Shellexecute }, + { "READ", TBuiltinStdFuncs::func_Read, fty_string, 1, param_oneString }, { "SESSIONVAR", TBuiltinStdFuncs::func_SessionVar, fty_none, 1, param_oneString }, { "SETSESSIONVAR", TBuiltinStdFuncs::func_SetSessionVar, fty_none, 2, param_SetSessionVar }, { "ABORTSESSION", TBuiltinStdFuncs::func_AbortSession, fty_none, 1, param_oneInteger }, |