From bb3a9a32fda97426bf7f05b04724d894eb4399c7 Mon Sep 17 00:00:00 2001
From: George Hazan <george.hazan@gmail.com>
Date: Sat, 30 May 2015 22:53:24 +0000
Subject: patch for the embedded images processing

git-svn-id: http://svn.miranda-ng.org/main/trunk@13920 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
---
 protocols/JabberG/src/jabber.cpp           | 10 +++++++
 protocols/JabberG/src/jabber_groupchat.cpp |  4 +++
 protocols/JabberG/src/jabber_misc.cpp      | 48 ++++++++++++++++++++++++++++++
 protocols/JabberG/src/jabber_proto.h       |  5 ++--
 protocols/JabberG/src/stdafx.h             |  1 +
 5 files changed, 66 insertions(+), 2 deletions(-)

(limited to 'protocols')

diff --git a/protocols/JabberG/src/jabber.cpp b/protocols/JabberG/src/jabber.cpp
index ef3b25aac1..a309320cb7 100644
--- a/protocols/JabberG/src/jabber.cpp
+++ b/protocols/JabberG/src/jabber.cpp
@@ -38,6 +38,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 HINSTANCE hInst;
 
 int hLangpack;
+unsigned int g_nTempFileId;
 
 int g_cbCountries;
 CountryListEntry *g_countries;
@@ -233,6 +234,15 @@ extern "C" int __declspec(dllexport) Unload(void)
 	DestroyHookableEvent(hExtListInit);
 	DestroyHookableEvent(hDiscoInfoResult);
 
+	if (g_nTempFileId != 0) {
+		TCHAR tszTempPath[MAX_PATH], tszTempFile[MAX_PATH];
+		GetTempPath(_countof(tszTempPath), tszTempPath);
+		for (unsigned i = 1; i <= g_nTempFileId; i++) {
+			GetTempFileName(tszTempPath, _T("jab"), i, tszTempFile);
+			DeleteFile(tszTempFile);
+		}
+	}
+
 	g_MenuUninit();
 	return 0;
 }
diff --git a/protocols/JabberG/src/jabber_groupchat.cpp b/protocols/JabberG/src/jabber_groupchat.cpp
index 976c864f5e..4736324897 100644
--- a/protocols/JabberG/src/jabber_groupchat.cpp
+++ b/protocols/JabberG/src/jabber_groupchat.cpp
@@ -1033,6 +1033,7 @@ void CJabberProto::GroupchatProcessMessage(HXML node)
 	HXML n, m;
 	const TCHAR *from, *type, *p, *nick, *resource;
 	JABBER_LIST_ITEM *item;
+	CMString imgLink;
 
 	if (!xmlGetName(node) || mir_tstrcmp(xmlGetName(node), _T("message"))) return;
 	if ((from = xmlGetAttrValue(node, _T("from"))) == NULL) return;
@@ -1073,6 +1074,8 @@ void CJabberProto::GroupchatProcessMessage(HXML node)
 		item->getTemp()->m_tszStatusMessage = mir_tstrdup(msgText);
 	}
 	else {
+		imgLink = ExtractImage(node);
+
 		if ((n = xmlGetChildByTag(node, "body", "xml:lang", m_tszSelectedLang)) == NULL)
 			if ((n = xmlGetChild(node, "body")) == NULL)
 				return;
@@ -1112,6 +1115,7 @@ void CJabberProto::GroupchatProcessMessage(HXML node)
 
 	CMString tszText(msgText);
 	tszText.Replace(_T("%"), _T("%%"));
+	tszText += imgLink;
 
 	GCEVENT gce = { sizeof(gce), &gcd };
 	gce.ptszUID = resource;
diff --git a/protocols/JabberG/src/jabber_misc.cpp b/protocols/JabberG/src/jabber_misc.cpp
index 844dc54ba7..21c686a724 100644
--- a/protocols/JabberG/src/jabber_misc.cpp
+++ b/protocols/JabberG/src/jabber_misc.cpp
@@ -499,3 +499,51 @@ void CJabberProto::MsgPopup(MCONTACT hContact, const TCHAR *szMsg, const TCHAR *
 		MessageBox(NULL, szMsg, szTitle, mtype);
 	}
 }
+
+CMString CJabberProto::ExtractImage(HXML node)
+{
+	HXML nHtml, nBody, nImg;
+	LPCTSTR src;
+	CMString link;
+
+	if ((nHtml = xmlGetChild(node, "html")) != NULL &&
+		(nBody = xmlGetChild(nHtml, "body")) != NULL &&
+		(nImg = xmlGetChild(nBody, "img")) != NULL &&
+		(src = xmlGetAttrValue(nImg, _T("src"))) != NULL) {
+
+		CMString strSrc(src);
+		if (strSrc.Left(11).Compare(L"data:image/") == 0) {
+			int end = strSrc.Find(L';');
+			if (end != -1) {
+				CMString ext(strSrc.c_str() + 11, end - 11);
+				int comma = strSrc.Find(L',', end);
+				if (comma != -1) {
+					CMString image(strSrc.c_str() + comma + 1, strSrc.GetLength() - comma - 1);
+					image.Replace(L"%2B", L"+");
+					image.Replace(L"%2F", L"/");
+					image.Replace(L"%3D", L"=");
+
+					TCHAR tszTempPath[MAX_PATH], tszTempFile[MAX_PATH];
+					GetTempPath(_countof(tszTempPath), tszTempPath);
+					GetTempFileName(tszTempPath, _T("jab"), InterlockedIncrement(&g_nTempFileId), tszTempFile);
+
+					HANDLE h = CreateFile(tszTempFile, GENERIC_READ | GENERIC_WRITE,
+						FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
+						FILE_ATTRIBUTE_NORMAL, NULL);
+
+					if (h != INVALID_HANDLE_VALUE) {
+						DWORD n;
+						unsigned int bufferLen;
+						ptrA buffer((char*)mir_base64_decode(_T2A(image), &bufferLen));
+						WriteFile(h, buffer, bufferLen, &n, NULL);
+						CloseHandle(h);
+
+						link = _T(" file:///");
+						link += tszTempFile;
+					}
+				}
+			}
+		}
+	}
+	return link;
+}
diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h
index 2f4764c94b..1f0ee12510 100644
--- a/protocols/JabberG/src/jabber_proto.h
+++ b/protocols/JabberG/src/jabber_proto.h
@@ -598,6 +598,7 @@ struct CJabberProto : public PROTO<CJabberProto>, public IJabberInterface
 	void   SetContactOfflineStatus(MCONTACT hContact);
 	void   InitPopups(void);
 	void   MsgPopup(MCONTACT hContact, const TCHAR *szMsg, const TCHAR *szTitle);
+	CMString ExtractImage(HXML node);
 
 	//---- jabber_opt.cpp ----------------------------------------------------------------
 	INT_PTR  __cdecl OnMenuHandleRosterControl(WPARAM wParam, LPARAM lParam);
@@ -834,7 +835,7 @@ public:
 	DWORD     STDMETHODCALLTYPE GetFlags() const;                    // Set of JIF_* flags.
 	int       STDMETHODCALLTYPE GetVersion() const;                  // Returns version of IJabberInterface.
 	DWORD     STDMETHODCALLTYPE GetJabberVersion() const;            // Returns Jabber plugin version.
-			    
+
 	int       STDMETHODCALLTYPE CompareJIDs(LPCTSTR jid1, LPCTSTR jid2); // Strips resource names from given JIDs and returns result of comparison for these JIDs.
 	MCONTACT  STDMETHODCALLTYPE ContactFromJID(LPCTSTR jid);             // Returns contact handle for given JID.
 	LPTSTR    STDMETHODCALLTYPE ContactToJID(MCONTACT hContact);           // Returns JID of hContact. You must free the result using mir_free().
@@ -857,7 +858,7 @@ public:
 	int       STDMETHODCALLTYPE RemoveFeatures(LPCTSTR szFeatures); // Removes features from the list of features returned by the client.
 	LPTSTR    STDMETHODCALLTYPE GetResourceFeatures(LPCTSTR jid);   // Returns all features supported by JID in format "feature1\0feature2\0...\0featureN\0\0". You must free returned string using mir_free().
 	HANDLE    STDMETHODCALLTYPE GetHandle();                        // Returns connection handle
-			    
+
 private:
 	JabberFeatCapPairDynamic *FindFeature(LPCTSTR szFeature);
 };
diff --git a/protocols/JabberG/src/stdafx.h b/protocols/JabberG/src/stdafx.h
index ee466f79df..fc6eb5c31d 100644
--- a/protocols/JabberG/src/stdafx.h
+++ b/protocols/JabberG/src/stdafx.h
@@ -590,6 +590,7 @@ extern HANDLE hExtraActivity;
 
 extern TCHAR szCoreVersion[];
 
+extern unsigned int g_nTempFileId;
 extern int g_cbCountries;
 extern struct CountryListEntry* g_countries;
 
-- 
cgit v1.2.3