[evolution-mapi] Include and use fixed OpenChange's fxparser
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Include and use fixed OpenChange's fxparser
- Date: Mon, 31 Oct 2011 12:13:39 +0000 (UTC)
commit dd28e4bde0551336e5d06e9b330990dc8cc84a6b
Author: Milan Crha <mcrha redhat com>
Date: Mon Oct 31 13:11:06 2011 +0100
Include and use fixed OpenChange's fxparser
src/libexchangemapi/e-mapi-fast-transfer.c | 16 +-
src/libexchangemapi/e-mapi-fast-transfer.h | 1 +
src/libexchangemapi/e-mapi-openchange.c | 665 ++++++++++++++++++++++++++++
src/libexchangemapi/e-mapi-openchange.h | 13 +
4 files changed, 688 insertions(+), 7 deletions(-)
---
diff --git a/src/libexchangemapi/e-mapi-fast-transfer.c b/src/libexchangemapi/e-mapi-fast-transfer.c
index c5e942e..1ae3feb 100644
--- a/src/libexchangemapi/e-mapi-fast-transfer.c
+++ b/src/libexchangemapi/e-mapi-fast-transfer.c
@@ -422,7 +422,7 @@ e_mapi_fast_transfer_internal (EMapiConnection *conn,
enum MAPISTATUS ms;
enum TransferStatus transferStatus;
uint16_t stepCount = -1, totalCount = -1;
- struct fx_parser_context *parser;
+ struct e_mapi_fx_parser_context *parser;
EMapiFXParserClosure data = { 0 };
data.conn = conn;
@@ -448,11 +448,11 @@ e_mapi_fast_transfer_internal (EMapiConnection *conn,
data.marker = PidTagStartMessage;
}
- parser = fxparser_init (data.mem_ctx, &data);
- fxparser_set_marker_callback (parser, parse_marker_cb);
- fxparser_set_delprop_callback (parser, parse_delprop_cb);
- fxparser_set_namedprop_callback (parser, parse_namedprop_cb);
- fxparser_set_property_callback (parser, parse_property_cb);
+ parser = e_mapi_fxparser_init (data.mem_ctx, &data);
+ e_mapi_fxparser_set_marker_callback (parser, parse_marker_cb);
+ e_mapi_fxparser_set_delprop_callback (parser, parse_delprop_cb);
+ e_mapi_fxparser_set_namedprop_callback (parser, parse_namedprop_cb);
+ e_mapi_fxparser_set_property_callback (parser, parse_property_cb);
do {
DATA_BLOB transferdata;
@@ -461,7 +461,9 @@ e_mapi_fast_transfer_internal (EMapiConnection *conn,
if (ms != MAPI_E_SUCCESS)
break;
- fxparser_parse (parser, &transferdata);
+ ms = e_mapi_fxparser_parse (parser, &transferdata);
+ if (ms != MAPI_E_SUCCESS)
+ break;
} while ((transferStatus == TransferStatus_Partial) || (transferStatus == TransferStatus_NoRoom));
if (data.object) {
diff --git a/src/libexchangemapi/e-mapi-fast-transfer.h b/src/libexchangemapi/e-mapi-fast-transfer.h
index fba1822..f409f6f 100644
--- a/src/libexchangemapi/e-mapi-fast-transfer.h
+++ b/src/libexchangemapi/e-mapi-fast-transfer.h
@@ -40,6 +40,7 @@ typedef struct _EMapiObject EMapiObject;
typedef struct _EMapiRecipient EMapiRecipient;
typedef struct _EMapiAttachment EMapiAttachment;
+/* returns whether continue in transfer of the next object */
typedef gboolean (*EMapiFastTransferCB) (EMapiConnection *conn,
TALLOC_CTX *mem_ctx,
/* const */ EMapiObject *object,
diff --git a/src/libexchangemapi/e-mapi-openchange.c b/src/libexchangemapi/e-mapi-openchange.c
index ae0abe2..de7049c 100644
--- a/src/libexchangemapi/e-mapi-openchange.c
+++ b/src/libexchangemapi/e-mapi-openchange.c
@@ -664,3 +664,668 @@ e_mapi_nameid_string_lookup_canonical(const char *Name, const char *OLEGUID, uin
OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL);
}
+
+enum e_mapi_fx_parser_state { ParserState_Entry, ParserState_HaveTag, ParserState_HavePropTag };
+
+struct e_mapi_fx_parser_context {
+ TALLOC_CTX *mem_ctx;
+ DATA_BLOB data; /* the data we have (so far) to parse */
+ uint32_t idx; /* where we are up to in the data blob */
+ enum e_mapi_fx_parser_state state;
+ struct SPropValue lpProp; /* the current property tag and value we are parsing */
+ struct MAPINAMEID namedprop; /* the current named property we are parsing */
+ bool enough_data;
+ uint32_t tag;
+ void *priv;
+
+ /* callbacks for parser actions */
+ enum MAPISTATUS (*op_marker)(uint32_t, void *);
+ enum MAPISTATUS (*op_delprop)(uint32_t, void *);
+ enum MAPISTATUS (*op_namedprop)(uint32_t, struct MAPINAMEID, void *);
+ enum MAPISTATUS (*op_property)(struct SPropValue, void *);
+};
+
+static bool pull_uint8_t(struct e_mapi_fx_parser_context *parser, uint8_t *val)
+{
+ if ((parser->idx) + 1 > parser->data.length) {
+ *val = 0;
+ return false;
+ }
+ *val = parser->data.data[parser->idx];
+ (parser->idx)++;
+ return true;
+}
+
+static bool pull_uint16_t(struct e_mapi_fx_parser_context *parser, uint16_t *val)
+{
+ if ((parser->idx) + 2 > parser->data.length) {
+ *val = 0;
+ return false;
+ }
+ *val = parser->data.data[parser->idx];
+ (parser->idx)++;
+ *val += parser->data.data[parser->idx] << 8;
+ (parser->idx)++;
+ return true;
+}
+
+static bool pull_uint32_t(struct e_mapi_fx_parser_context *parser, uint32_t *val)
+{
+ if ((parser->idx) + 4 > parser->data.length) {
+ *val = 0;
+ return false;
+ }
+ *val = parser->data.data[parser->idx];
+ (parser->idx)++;
+ *val += parser->data.data[parser->idx] << 8;
+ (parser->idx)++;
+ *val += parser->data.data[parser->idx] << 16;
+ (parser->idx)++;
+ *val += parser->data.data[parser->idx] << 24;
+ (parser->idx)++;
+ return true;
+}
+
+static bool pull_tag(struct e_mapi_fx_parser_context *parser)
+{
+ return pull_uint32_t(parser, &(parser->tag));
+}
+
+static bool pull_uint8_data(struct e_mapi_fx_parser_context *parser, uint32_t read_len, uint8_t **data_read)
+{
+ uint32_t i;
+ for (i = 0; i < read_len; i++) {
+ if (!pull_uint8_t(parser, (uint8_t*)&((*data_read)[i]))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool pull_int64_t(struct e_mapi_fx_parser_context *parser, int64_t *val)
+{
+ int64_t tmp;
+ if ((parser->idx) + 8 > parser->data.length) {
+ *val = 0;
+ return false;
+ }
+ *val = parser->data.data[parser->idx];
+ (parser->idx)++;
+
+ tmp = parser->data.data[parser->idx];
+ *val += (tmp << 8);
+ (parser->idx)++;
+
+ tmp = parser->data.data[parser->idx];
+ *val += (tmp << 16);
+ (parser->idx)++;
+
+ tmp = parser->data.data[parser->idx];
+ *val += (tmp << 24);
+ (parser->idx)++;
+
+ tmp = parser->data.data[parser->idx];
+ *val += (tmp << 32);
+ (parser->idx)++;
+
+ tmp = parser->data.data[parser->idx];
+ *val += (tmp << 40);
+ (parser->idx)++;
+
+ tmp = parser->data.data[parser->idx];
+ *val += (tmp << 48);
+ (parser->idx)++;
+
+ tmp = parser->data.data[parser->idx];
+ *val += (tmp << 56);
+ (parser->idx)++;
+
+ return true;
+}
+
+static bool pull_double(struct e_mapi_fx_parser_context *parser, double *val)
+{
+ return pull_int64_t(parser, (int64_t *)val);
+}
+
+static bool pull_guid(struct e_mapi_fx_parser_context *parser, struct GUID *guid)
+{
+ int i;
+
+ if ((parser->idx) + 16 > parser->data.length) {
+ GUID_all_zero(guid);
+ return false;
+ }
+ if (!pull_uint32_t(parser, &(guid->time_low)))
+ return false;
+ if (!pull_uint16_t(parser, &(guid->time_mid)))
+ return false;
+ if (!pull_uint16_t(parser, &(guid->time_hi_and_version)))
+ return false;
+ if (!pull_uint8_t(parser, &(guid->clock_seq[0])))
+ return false;
+ if (!pull_uint8_t(parser, &(guid->clock_seq[1])))
+ return false;
+ for (i = 0; i < 6; ++i) {
+ if (!pull_uint8_t(parser, &(guid->node[i])))
+ return false;
+ }
+ return true;
+}
+
+static bool pull_systime(struct e_mapi_fx_parser_context *parser, struct FILETIME *ft)
+{
+ struct FILETIME filetime = {0,0};
+
+ if (parser->idx + 8 > parser->data.length ||
+ !pull_uint32_t(parser, &(filetime.dwLowDateTime)) ||
+ !pull_uint32_t(parser, &(filetime.dwHighDateTime)))
+ return false;
+
+ *ft = filetime;
+
+ return true;
+}
+
+static bool pull_clsid(struct e_mapi_fx_parser_context *parser, struct FlatUID_r **pclsid)
+{
+ struct FlatUID_r *clsid;
+ int i = 0;
+
+ if (parser->idx + 16 > parser->data.length)
+ return false;
+
+ clsid = talloc_zero(parser->mem_ctx, struct FlatUID_r);
+ for (i = 0; i < 16; ++i) {
+ if (!pull_uint8_t(parser, &(clsid->ab[i])))
+ return false;
+ }
+
+ *pclsid = clsid;
+
+ return true;
+}
+
+static bool pull_string8(struct e_mapi_fx_parser_context *parser, char **pstr)
+{
+ char *str;
+ uint32_t i, length;
+
+ if (!pull_uint32_t(parser, &length) ||
+ parser->idx + length > parser->data.length)
+ return false;
+
+ str = talloc_array(parser->mem_ctx, char, length + 1);
+ for (i = 0; i < length; i++) {
+ if (!pull_uint8_t(parser, (uint8_t*)&(str[i]))) {
+ return false;
+ }
+ }
+ str[length] = '\0';
+
+ *pstr = str;
+
+ return true;
+}
+
+static bool fetch_ucs2_data(struct e_mapi_fx_parser_context *parser, uint32_t numbytes, smb_ucs2_t **data_read)
+{
+ if ((parser->idx) + numbytes > parser->data.length) {
+ // printf("insufficient data in fetch_ucs2_data (%i requested, %zi available)\n", numbytes, (parser->data.length - parser->idx));
+ return false;
+ }
+
+ *data_read = talloc_array(parser->mem_ctx, smb_ucs2_t, numbytes/2);
+ memcpy(*data_read, &(parser->data.data[parser->idx]), numbytes);
+ parser->idx += numbytes;
+ return true;
+}
+
+static bool fetch_ucs2_nullterminated(struct e_mapi_fx_parser_context *parser, smb_ucs2_t **data_read)
+{
+ uint32_t idx_local = parser->idx;
+ bool found = false;
+ while (idx_local < parser->data.length -1) {
+ smb_ucs2_t val = 0x0000;
+ val += parser->data.data[idx_local];
+ idx_local++;
+ val += parser->data.data[idx_local] << 8;
+ idx_local++;
+ if (val == 0x0000) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return false;
+ return fetch_ucs2_data(parser, idx_local-(parser->idx), data_read);
+}
+
+static bool pull_unicode(struct e_mapi_fx_parser_context *parser, char **pstr)
+{
+ smb_ucs2_t *ucs2_data = NULL;
+ char *utf8_data = NULL;
+ size_t utf8_len;
+ uint32_t length;
+
+ if (!pull_uint32_t(parser, &length) ||
+ parser->idx + length > parser->data.length)
+ return false;
+
+ ucs2_data = talloc_array(parser->mem_ctx, smb_ucs2_t, length/2);
+
+ if (!fetch_ucs2_data(parser, length, &ucs2_data)) {
+ return false;
+ }
+ pull_ucs2_talloc(parser->mem_ctx, &utf8_data, ucs2_data, &utf8_len);
+
+ *pstr = utf8_data;
+
+ return true;
+}
+
+static bool pull_binary(struct e_mapi_fx_parser_context *parser, struct Binary_r *bin)
+{
+ if (!pull_uint32_t(parser, &(bin->cb)) ||
+ parser->idx + bin->cb > parser->data.length)
+ return false;
+
+ bin->lpb = talloc_array(parser->mem_ctx, uint8_t, bin->cb + 1);
+
+ return pull_uint8_data(parser, bin->cb, &(bin->lpb));
+}
+
+/*
+ pull a property value from the blob, starting at position idx
+*/
+static bool fetch_property_value(struct e_mapi_fx_parser_context *parser, DATA_BLOB *buf, struct SPropValue *prop)
+{
+ switch(prop->ulPropTag & 0xFFFF) {
+ case PT_NULL:
+ {
+ if (!pull_uint32_t(parser, &(prop->value.null)))
+ return false;
+ break;
+ }
+ case PT_SHORT:
+ {
+ if (!pull_uint16_t(parser, &(prop->value.i)))
+ return false;
+ break;
+ }
+ case PT_LONG:
+ {
+ if (!pull_uint32_t(parser, &(prop->value.l)))
+ return false;
+ break;
+ }
+ case PT_DOUBLE:
+ {
+ if (!pull_double(parser, (double *)&(prop->value.dbl)))
+ return false;
+ break;
+ }
+ case PT_BOOLEAN:
+ {
+ if (parser->idx + 2 > parser->data.length ||
+ !pull_uint8_t(parser, &(prop->value.b)))
+ return false;
+
+ /* special case for fast transfer, 2 bytes instead of one */
+ (parser->idx)++;
+ break;
+ }
+ case PT_I8:
+ {
+ int64_t val;
+ if (!pull_int64_t(parser, &(val)))
+ return false;
+ prop->value.d = val;
+ break;
+ }
+ case PT_STRING8:
+ {
+ char *str = NULL;
+ if (!pull_string8(parser, &str))
+ return false;
+ prop->value.lpszA = str;
+ break;
+ }
+ case PT_UNICODE:
+ {
+ char *str = NULL;
+ if (!pull_unicode (parser, &str))
+ return false;
+ prop->value.lpszW = str;
+ break;
+ }
+ case PT_SYSTIME:
+ {
+ if (!pull_systime(parser, &prop->value.ft))
+ return false;
+ break;
+ }
+ case PT_CLSID:
+ {
+ if (!pull_clsid(parser, &prop->value.lpguid))
+ return false;
+ break;
+ }
+ case PT_SVREID:
+ case PT_BINARY:
+ {
+ if (!pull_binary(parser, &prop->value.bin))
+ return false;
+ break;
+ }
+ case PT_OBJECT:
+ {
+ if (!pull_uint32_t(parser, &(prop->value.object)))
+ return false;
+ break;
+ }
+ case PT_ERROR:
+ {
+ uint32_t num;
+ if (!pull_uint32_t(parser, &num))
+ return false;
+ prop->value.err = num;
+ break;
+ }
+ case PT_MV_BINARY:
+ {
+ uint32_t i;
+ if (!pull_uint32_t(parser, &(prop->value.MVbin.cValues)) ||
+ parser->idx + prop->value.MVbin.cValues * 4 > parser->data.length)
+ return false;
+ prop->value.MVbin.lpbin = talloc_array(parser->mem_ctx, struct Binary_r, prop->value.MVbin.cValues);
+ for (i = 0; i < prop->value.MVbin.cValues; i++) {
+ if (!pull_binary(parser, &(prop->value.MVbin.lpbin[i])))
+ return false;
+ }
+ break;
+ }
+ case PT_MV_SHORT:
+ {
+ uint32_t i;
+ if (!pull_uint32_t(parser, &(prop->value.MVi.cValues)) ||
+ parser->idx + prop->value.MVi.cValues * 2 > parser->data.length)
+ return false;
+ prop->value.MVi.lpi = talloc_array(parser->mem_ctx, uint16_t, prop->value.MVi.cValues);
+ for (i = 0; i < prop->value.MVi.cValues; i++) {
+ if (!pull_uint16_t(parser, &(prop->value.MVi.lpi[i])))
+ return false;
+ }
+ break;
+ }
+ case PT_MV_LONG:
+ {
+ uint32_t i;
+ if (!pull_uint32_t(parser, &(prop->value.MVl.cValues)) ||
+ parser->idx + prop->value.MVl.cValues * 4 > parser->data.length)
+ return false;
+ prop->value.MVl.lpl = talloc_array(parser->mem_ctx, uint32_t, prop->value.MVl.cValues);
+ for (i = 0; i < prop->value.MVl.cValues; i++) {
+ if (!pull_uint32_t(parser, &(prop->value.MVl.lpl[i])))
+ return false;
+ }
+ break;
+ }
+ case PT_MV_STRING8:
+ {
+ uint32_t i;
+ char *str;
+ if (!pull_uint32_t(parser, &(prop->value.MVszA.cValues)) ||
+ parser->idx + prop->value.MVszA.cValues * 4 > parser->data.length)
+ return false;
+ prop->value.MVszA.lppszA = (const char **) talloc_array(parser->mem_ctx, char *, prop->value.MVszA.cValues);
+ for (i = 0; i < prop->value.MVszA.cValues; i++) {
+ str = NULL;
+ if (!pull_string8(parser, &str))
+ return false;
+ prop->value.MVszA.lppszA[i] = str;
+ }
+ break;
+ }
+ case PT_MV_CLSID:
+ {
+ uint32_t i;
+ if (!pull_uint32_t(parser, &(prop->value.MVguid.cValues)) ||
+ parser->idx + prop->value.MVguid.cValues * 16 > parser->data.length)
+ return false;
+ prop->value.MVguid.lpguid = talloc_array(parser->mem_ctx, struct FlatUID_r *, prop->value.MVguid.cValues);
+ for (i = 0; i < prop->value.MVguid.cValues; i++) {
+ if (!pull_clsid(parser, &(prop->value.MVguid.lpguid[i])))
+ return false;
+ }
+ break;
+ }
+ case PT_MV_UNICODE:
+ {
+ uint32_t i;
+ char *str;
+
+ if (!pull_uint32_t(parser, &(prop->value.MVszW.cValues)) ||
+ parser->idx + prop->value.MVszW.cValues * 4 > parser->data.length)
+ return false;
+ prop->value.MVszW.lppszW = (const char **) talloc_array(parser->mem_ctx, char *, prop->value.MVszW.cValues);
+ for (i = 0; i < prop->value.MVszW.cValues; i++) {
+ str = NULL;
+ if (!pull_unicode(parser, &str))
+ return false;
+ prop->value.MVszW.lppszW[i] = str;
+ }
+ break;
+ }
+ case PT_MV_SYSTIME:
+ {
+ uint32_t i;
+ if (!pull_uint32_t(parser, &(prop->value.MVft.cValues)) ||
+ parser->idx + prop->value.MVft.cValues * 8 > parser->data.length)
+ return false;
+ prop->value.MVft.lpft = talloc_array(parser->mem_ctx, struct FILETIME, prop->value.MVft.cValues);
+ for (i = 0; i < prop->value.MVft.cValues; i++) {
+ if (!pull_systime(parser, &(prop->value.MVft.lpft[i])))
+ return false;
+ }
+ break;
+ }
+ default:
+ printf("unhandled conversion case in fetch_property_value(): 0x%x\n", (prop->ulPropTag & 0xFFFF));
+ g_return_val_if_reached(false);
+ }
+ return true;
+}
+
+static bool pull_named_property(struct e_mapi_fx_parser_context *parser, enum MAPISTATUS *ms)
+{
+ uint8_t type = 0;
+ if (!pull_guid(parser, &(parser->namedprop.lpguid)))
+ return false;
+ /* printf("guid : %s\n", GUID_string(parser->mem_ctx, &(parser->namedprop.lpguid))); */
+ if (!pull_uint8_t(parser, &type))
+ return false;
+ if (type == 0) {
+ parser->namedprop.ulKind = MNID_ID;
+ if (!pull_uint32_t(parser, &(parser->namedprop.kind.lid)))
+ return false;
+ /* printf("LID dispid: 0x%08x\n", parser->namedprop.kind.lid); */
+ } else if (type == 1) {
+ smb_ucs2_t *ucs2_data = NULL;
+ size_t utf8_len;
+ parser->namedprop.ulKind = MNID_STRING;
+ if (!fetch_ucs2_nullterminated(parser, &ucs2_data))
+ return false;
+ pull_ucs2_talloc(parser->mem_ctx, (char**)&(parser->namedprop.kind.lpwstr.Name), ucs2_data, &(utf8_len));
+ parser->namedprop.kind.lpwstr.NameSize = utf8_len;
+ /* printf("named: %s\n", parser->namedprop.kind.lpwstr.Name); */
+ } else {
+ printf("unknown named property kind: 0x%02x\n", parser->namedprop.ulKind);
+ g_return_val_if_reached(false);
+ }
+ if (parser->op_namedprop) {
+ *ms = parser->op_namedprop(parser->lpProp.ulPropTag, parser->namedprop, parser->priv);
+ }
+
+ return true;
+}
+
+/**
+ \details set a callback function for marker output
+*/
+_PUBLIC_ void e_mapi_fxparser_set_marker_callback(struct e_mapi_fx_parser_context *parser, e_mapi_fxparser_marker_callback_t marker_callback)
+{
+ parser->op_marker = marker_callback;
+}
+
+/**
+ \details set a callback function for delete properties output
+*/
+_PUBLIC_ void e_mapi_fxparser_set_delprop_callback(struct e_mapi_fx_parser_context *parser, e_mapi_fxparser_delprop_callback_t delprop_callback)
+{
+ parser->op_delprop = delprop_callback;
+}
+
+/**
+ \details set a callback function for named properties output
+*/
+_PUBLIC_ void e_mapi_fxparser_set_namedprop_callback(struct e_mapi_fx_parser_context *parser, e_mapi_fxparser_namedprop_callback_t namedprop_callback)
+{
+ parser->op_namedprop = namedprop_callback;
+}
+
+/**
+ \details set a callback function for property output
+*/
+_PUBLIC_ void e_mapi_fxparser_set_property_callback(struct e_mapi_fx_parser_context *parser, e_mapi_fxparser_property_callback_t property_callback)
+{
+ parser->op_property = property_callback;
+}
+
+/**
+ \details initialise a fast transfer parser
+*/
+_PUBLIC_ struct e_mapi_fx_parser_context* e_mapi_fxparser_init(TALLOC_CTX *mem_ctx, void *priv)
+{
+ struct e_mapi_fx_parser_context *parser = talloc_zero(mem_ctx, struct e_mapi_fx_parser_context);
+
+ parser->mem_ctx = mem_ctx;
+ parser->data = data_blob_talloc_named(parser->mem_ctx, NULL, 0, "fast transfer parser");
+ parser->state = ParserState_Entry;
+ parser->idx = 0;
+ parser->lpProp.ulPropTag = (enum MAPITAGS) 0;
+ parser->lpProp.dwAlignPad = 0;
+ parser->lpProp.value.l = 0;
+ parser->priv = priv;
+
+ return parser;
+}
+
+/**
+ \details parse a fast transfer buffer
+*/
+_PUBLIC_ enum MAPISTATUS e_mapi_fxparser_parse(struct e_mapi_fx_parser_context *parser, DATA_BLOB *fxbuf)
+{
+ enum MAPISTATUS ms = MAPI_E_SUCCESS;
+
+ data_blob_append(parser->mem_ctx, &(parser->data), fxbuf->data, fxbuf->length);
+ parser->enough_data = true;
+ while(ms == MAPI_E_SUCCESS && (parser->idx < parser->data.length) && parser->enough_data) {
+ uint32_t idx = parser->idx;
+
+ switch(parser->state) {
+ case ParserState_Entry:
+ {
+ if (pull_tag(parser)) {
+ /* printf("tag: 0x%08x\n", parser->tag); */
+ parser->state = ParserState_HaveTag;
+ } else {
+ parser->enough_data = false;
+ parser->idx = idx;
+ }
+ break;
+ }
+ case ParserState_HaveTag:
+ {
+ switch (parser->tag) {
+ case PidTagStartTopFld:
+ case PidTagStartSubFld:
+ case PidTagEndFolder:
+ case PidTagStartMessage:
+ case PidTagStartFAIMsg:
+ case PidTagEndMessage:
+ case PidTagStartRecip:
+ case PidTagEndToRecip:
+ case PidTagNewAttach:
+ case PidTagEndAttach:
+ case PidTagStartEmbed:
+ case PidTagEndEmbed:
+ if (parser->op_marker) {
+ ms = parser->op_marker(parser->tag, parser->priv);
+ }
+ parser->state = ParserState_Entry;
+ break;
+ case PidTagFXDelProp:
+ {
+ uint32_t tag;
+ if (pull_uint32_t(parser, &tag)) {
+ if (parser->op_delprop) {
+ ms = parser->op_delprop(tag, parser->priv);
+ }
+ parser->state = ParserState_Entry;
+ } else {
+ parser->enough_data = false;
+ parser->idx = idx;
+ }
+ break;
+ }
+ default:
+ {
+ /* standard property thing */
+ parser->lpProp.ulPropTag = (enum MAPITAGS) parser->tag;
+ parser->lpProp.dwAlignPad = 0;
+ if ((parser->lpProp.ulPropTag >> 16) & 0x8000) {
+ /* this is a named property */
+ // printf("tag: 0x%08x\n", parser->tag);
+ // TODO: this should probably be a separate parser state
+ // TODO: this needs to return the named property
+ if (pull_named_property(parser, &ms)) {
+ parser->state = ParserState_HavePropTag;
+ } else {
+ parser->enough_data = false;
+ parser->idx = idx;
+ }
+ } else {
+ parser->state = ParserState_HavePropTag;
+ }
+ }
+ }
+ break;
+ }
+ case ParserState_HavePropTag:
+ {
+ if (fetch_property_value(parser, &(parser->data), &(parser->lpProp))) {
+ // printf("position %i of %zi\n", parser->idx, parser->data.length);
+ if (parser->op_property) {
+ ms = parser->op_property(parser->lpProp, parser->priv);
+ }
+ parser->state = ParserState_Entry;
+ } else {
+ parser->enough_data = false;
+ parser->idx = idx;
+ }
+ break;
+ }
+ }
+ }
+ {
+ // Remove the part of the buffer that we've used
+ uint32_t remainder_len = parser->data.length - parser->idx;
+ DATA_BLOB remainder = data_blob_talloc_named(parser->mem_ctx, &(parser->data.data[parser->idx]), remainder_len, "fast transfer parser");
+ data_blob_free(&(parser->data));
+ parser->data = remainder;
+ parser->idx = 0;
+ }
+
+ return ms;
+}
diff --git a/src/libexchangemapi/e-mapi-openchange.h b/src/libexchangemapi/e-mapi-openchange.h
index 0a1d6e5..36b0af4 100644
--- a/src/libexchangemapi/e-mapi-openchange.h
+++ b/src/libexchangemapi/e-mapi-openchange.h
@@ -35,6 +35,19 @@ G_BEGIN_DECLS
enum MAPISTATUS e_mapi_nameid_lid_lookup_canonical (uint16_t lid, const char *OLEGUID, uint32_t *propTag);
enum MAPISTATUS e_mapi_nameid_string_lookup_canonical(const char *Name, const char *OLEGUID, uint32_t *propTag);
+struct e_mapi_fx_parser_context;
+typedef enum MAPISTATUS (*e_mapi_fxparser_marker_callback_t)(uint32_t, void *);
+typedef enum MAPISTATUS (*e_mapi_fxparser_delprop_callback_t)(uint32_t, void *);
+typedef enum MAPISTATUS (*e_mapi_fxparser_namedprop_callback_t)(uint32_t, struct MAPINAMEID, void *);
+typedef enum MAPISTATUS (*e_mapi_fxparser_property_callback_t)(struct SPropValue, void *);
+
+struct e_mapi_fx_parser_context *e_mapi_fxparser_init(TALLOC_CTX *, void *);
+void e_mapi_fxparser_set_marker_callback(struct e_mapi_fx_parser_context *, e_mapi_fxparser_marker_callback_t);
+void e_mapi_fxparser_set_delprop_callback(struct e_mapi_fx_parser_context *, e_mapi_fxparser_delprop_callback_t);
+void e_mapi_fxparser_set_namedprop_callback(struct e_mapi_fx_parser_context *, e_mapi_fxparser_namedprop_callback_t);
+void e_mapi_fxparser_set_property_callback(struct e_mapi_fx_parser_context *, e_mapi_fxparser_property_callback_t);
+enum MAPISTATUS e_mapi_fxparser_parse(struct e_mapi_fx_parser_context *, DATA_BLOB *);
+
G_END_DECLS
#endif /* E_MAPI_OPENCHANGE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]