+typedef struct _addrbookent {
+ StrBuf *name;
+ HashList *VC;
+ long ab_msgnum; /* message number of address book entry */
+ StrBuf *msgNoStr;
+} addrbookent;
+
+void deleteAbEnt(void *v) {
+ addrbookent *vc = (addrbookent*)v;
+ DeleteHash(&vc->VC);
+ FreeStrBuf(&vc->name);
+ FreeStrBuf(&vc->msgNoStr);
+ free(vc);
+}
+
+HashList *DefineToToken = NULL;
+HashList *VCTokenToDefine = NULL;
+HashList *vcNames = NULL; /* todo: fill with the name strings */
+vcField* vcfUnknown = NULL;
+
+void RegisterVCardToken(vcField* vf, StrBuf *name, int inTokenCount)
+{
+ if (vf->Type == UnKnown) {
+ vcfUnknown = vf;
+ }
+ RegisterTokenParamDefine(SKEY(name), vf->cval);
+ Put(DefineToToken, LKEY(vf->cval), vf, reference_free_handler);
+ Put(vcNames, LKEY(vf->cval), NewStrBufPlain(CKEY(vf->Name)), HFreeStrBuf);
+
+ syslog(LOG_DEBUG, "Token: %s -> %ld, %d",
+ ChrPtr(name),
+ vf->cval,
+ inTokenCount);
+
+}
+
+void autoRegisterTokens(long *enumCounter, vcField* vf, StrBuf *BaseStr, int layer, long parentCVal)
+{
+ int i = 0;
+ StrBuf *subStr = NewStrBuf();
+ while (vf[i].STR.len > 0) {
+ FlushStrBuf(subStr);
+ vf[i].cval = (*enumCounter) ++;
+ vf[i].parentCVal = parentCVal;
+ StrBufAppendBuf(subStr, BaseStr, 0);
+ if (StrLength(subStr) > 0) {
+ StrBufAppendBufPlain(subStr, HKEY("."), 0);
+ }
+ StrBufAppendBufPlain(subStr, CKEY(vf[i].STR), 0);
+ if (layer == 0) {
+ Put(VCTokenToDefine, CKEY(vf[i].STR), &vf[i], reference_free_handler);
+ }
+ switch (vf[i].Type) {
+ case FlatString:
+ break;
+ case StringCluster:
+ {
+ autoRegisterTokens(enumCounter, vf[i].Sub, subStr, 1, vf[i].cval);
+ }
+ break;
+ case PhoneNumber:
+ break;
+ case EmailAddr:
+ break;
+ case Street:
+ break;
+ case Number:
+ break;
+ case AliasFor:
+ break;
+ case Base64BinaryAttachment:
+ break;
+ case TerminateList:
+ break;
+ case Address:
+ break;
+ case UnKnown:
+ break;
+ }
+ RegisterVCardToken(&vf[i], subStr, i);
+ i++;
+ }
+ FreeStrBuf(&subStr);
+}
+
+int preeval_vcard_item(WCTemplateToken *Token)
+{
+ WCTemplputParams TPP;
+ WCTemplputParams *TP;
+ int searchFieldNo;
+ StrBuf *Target = NULL;
+
+ memset(&TPP, 0, sizeof(WCTemplputParams));
+ TP = &TPP;
+ TP->Tokens = Token;
+ searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0);
+ if (searchFieldNo >= VCEnumCounter) {
+ LogTemplateError(NULL, "VCardItem", ERR_PARM1, TP,
+ "Invalid define");
+ return 0;
+ }
+ return 1;
+}
+
+void tmpl_vcard_item(StrBuf *Target, WCTemplputParams *TP)
+{
+ void *vItem;
+ long searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0);
+ addrbookent *ab = (addrbookent*) CTX(CTX_VCARD);
+ if (GetHash(ab->VC, LKEY(searchFieldNo), &vItem) && (vItem != NULL)) {
+ StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1);
+ }
+}
+
+void tmpl_vcard_context_item(StrBuf *Target, WCTemplputParams *TP)
+{
+ void *vItem;
+ vcField *t = (vcField*) CTX(CTX_VCARD_TYPE);
+ addrbookent *ab = (addrbookent*) CTX(CTX_VCARD);
+
+ if (t == NULL) {
+ LogTemplateError(NULL, "VCard item", ERR_NAME, TP,
+ "Missing context");
+ return;
+ }
+
+ if (GetHash(ab->VC, LKEY(t->cval), &vItem) && (vItem != NULL)) {
+ StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 0);
+ }
+ else {
+ LogTemplateError(NULL, "VCard item", ERR_NAME, TP,
+ "Doesn't have that key - did you miss to filter in advance?");
+ }
+}
+int preeval_vcard_name_str(WCTemplateToken *Token)
+{
+ WCTemplputParams TPP;
+ WCTemplputParams *TP;
+ int searchFieldNo;
+ StrBuf *Target = NULL;
+
+ memset(&TPP, 0, sizeof(WCTemplputParams));
+ TP = &TPP;
+ TP->Tokens = Token;
+ searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0);
+ if (searchFieldNo >= VCEnumCounter) {
+ LogTemplateError(NULL, "VCardName", ERR_PARM1, TP,
+ "Invalid define");
+ return 0;
+ }
+ return 1;
+}
+
+void tmpl_vcard_name_str(StrBuf *Target, WCTemplputParams *TP)
+{
+ void *vItem;
+ long searchFieldNo = GetTemplateTokenNumber(Target, TP, 0, 0);
+ /* todo: get descriptive string for this vcard type */
+ if (GetHash(vcNames, LKEY(searchFieldNo), &vItem) && (vItem != NULL)) {
+ StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1);
+ }
+ else {
+ LogTemplateError(NULL, "VCard item type", ERR_NAME, TP,
+ "No i18n string for this.");
+ return;
+ }
+}
+
+void tmpl_vcard_msgno(StrBuf *Target, WCTemplputParams *TP)
+{
+ addrbookent *ab = (addrbookent*) CTX(CTX_VCARD);
+ if (ab->msgNoStr == NULL) {
+ ab->msgNoStr = NewStrBufPlain(NULL, 64);
+ }
+ StrBufPrintf(ab->msgNoStr, "%ld", ab->ab_msgnum);
+ StrBufAppendTemplate(Target, TP, ab->msgNoStr, 0);
+}
+void tmpl_vcard_context_name_str(StrBuf *Target, WCTemplputParams *TP)
+{
+ void *vItem;
+ vcField *t = (vcField*) CTX(CTX_VCARD_TYPE);
+
+ if (t == NULL) {
+ LogTemplateError(NULL, "VCard item type", ERR_NAME, TP,
+ "Missing context");
+ return;
+ }
+
+ if (GetHash(vcNames, LKEY(t->cval), &vItem) && (vItem != NULL)) {
+ StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1);
+ }
+ else {
+ LogTemplateError(NULL, "VCard item type", ERR_NAME, TP,
+ "No i18n string for this.");
+ return;
+ }
+}
+
+int filter_VC_ByType(const char* key, long len, void *Context, StrBuf *Target, WCTemplputParams *TP)
+{
+ long searchType;
+ long type = 0;
+ void *v;
+ int rc = 0;
+ vcField *vf = (vcField*) Context;
+
+ memcpy(&type, key, sizeof(long));
+ searchType = GetTemplateTokenNumber(Target, TP, IT_ADDT_PARAM(0), 0);
+
+ if (vf->Type == searchType) {
+ addrbookent *ab = (addrbookent*) CTX(CTX_VCARD);
+ if (GetHash(ab->VC, LKEY(vf->cval), &v) && v != NULL)
+ return 1;
+ }
+ return rc;
+}
+
+
+
+
+HashList *getContextVcard(StrBuf *Target, WCTemplputParams *TP)
+{
+ vcField *vf = (vcField*) CTX(CTX_VCARD_TYPE);
+ addrbookent *ab = (addrbookent*) CTX(CTX_VCARD);
+
+ if ((vf == NULL) || (ab == NULL)) {
+ LogTemplateError(NULL, "VCard item type", ERR_NAME, TP,
+ "Need VCard and Vcard type in context");
+
+ return NULL;
+ }
+ return ab->VC;
+}
+
+int filter_VC_ByContextType(const char* key, long len, void *Context, StrBuf *Target, WCTemplputParams *TP)
+{
+ long searchType;
+ vcField *vf = (vcField*) CTX(CTX_VCARD_TYPE);
+
+ memcpy(&searchType, key, sizeof(long));
+
+ if (vf->cval == searchType) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+int conditional_VC_Havetype(StrBuf *Target, WCTemplputParams *TP)
+{
+ addrbookent *ab = (addrbookent*) CTX(CTX_VCARD);
+ long HaveFieldType = GetTemplateTokenNumber(Target, TP, 2, 0);
+ int rc = 0;
+ void *vVCitem;
+ const char *Key;
+ long len;
+ HashPos *it = GetNewHashPos(ab->VC, 0);
+ while (GetNextHashPos(ab->VC, it, &len, &Key, &vVCitem) &&
+ (vVCitem != NULL))
+ {
+ void *vvcField;
+ long type = 0;
+ memcpy(&type, Key, sizeof(long));
+ if (GetHash(DefineToToken, LKEY(type), &vvcField) &&
+ (vvcField != NULL))
+ {
+ vcField *t = (vcField*) vvcField;
+ if (t && t->Type == HaveFieldType) {
+ rc = 1;
+ break;
+ }
+ }
+ }
+ DeleteHashPos(&it);
+ return rc;