﻿#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#include-once
; #INDEX# =======================================================================================================================
; Title .........: UDF to Decode Word Encoded with Quoted Printable
; AutoIt Version : 3.3.10.2++
; Language ......: English
; Description ...:
; Author(s) .....: Prog@ndy
; Modified ......: mLipok
; ===============================================================================================================================
#CS
	Author original post
	https://autoit.de/index.php/Thread/11350-UTF8-Sting-Convertieren/?postID=87721#post87721

	Quoted-Printable
	http://tools.ietf.org/html/rfc2045#section-6.7
	https://www.ietf.org/rfc/rfc2045.txt
#CE

;~ _QuotedPrintable_Example()

Func _QuotedPrintable_Example()
	Local $sTestString = ''
	#forceref $sTestString
;~ https://autoit.de/index.php/Thread/11350-UTF8-Sting-Convertieren/?postID=87721#post87721
;~ $sTestString = "=?utf-8?b?QmFja3VwIEV4ZWMtTWVsZHVuZzogQXVmdHJhZyBlcmZvbGdyZWljaA==?="
	$sTestString = "=?iso-8859-2?Q?3%_na_Otwartym_Koncie_Oszcz=EAdno=B6ciowym?="
	$sTestString = "=?iso-8859-2?Q?EndFunc   ;=3D=3D>_MY_EXAMPLE_POP3?="
;~ 	MsgBox(0, '', _QuotedPrintable_DecodeEncodedWord($sTestString))
;~ 	MsgBox(0, '', _QuotedPrintable_DecodeEncodedWord("Subject: =?iso-8859-1?Q?=A1Hola,_se=F1or!?="))
EndFunc   ;==>_QuotedPrintable_Example

; #FUNCTION# ====================================================================================================================
; Name ..........: _QuotedPrintable_GetCodepage
; Description ...:
; Syntax ........: _QuotedPrintable_GetCodepage($charset)
; Parameters ....: $charset             - An unknown value.
; Return values .: None
; Author ........: Prog@ndy
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _QuotedPrintable_GetCodepage($charset)
	Local Const $PATH = "HKEY_CLASSES_ROOT\MIME\Database\Charset\"
	Local $alias
	While 1
		$alias = RegRead($PATH & $charset, "AliasForCharset")
		If @error Then ExitLoop
		$charset = $alias
	WEnd
	Local $result = RegRead($PATH & $charset, "InternetEncoding")
	Return SetError(@error, @extended, $result)
EndFunc   ;==>_QuotedPrintable_GetCodepage

; #FUNCTION# ====================================================================================================================
; Name ..........: _QuotedPrintable_MultiByteToWideChar
; Description ...:
; Syntax ........: _QuotedPrintable_MultiByteToWideChar($iCodePage, $dwFlags, $lpMultiByteStr, $cbMultiByte, $lpWideCharStr,
;                  $cchWideChar)
; Parameters ....: $iCodePage            - An unknown value.
;                  $dwFlags             - An unknown value.
;                  $lpMultiByteStr      - An unknown value.
;                  $cbMultiByte         - An unknown value.
;                  $lpWideCharStr       - An unknown value.
;                  $cchWideChar         - An unknown value.
; Return values .: None
; Author ........: Prog@ndy
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _QuotedPrintable_MultiByteToWideChar($iCodePage, $dwFlags, $lpMultiByteStr, $cbMultiByte, $lpWideCharStr, $cchWideChar)
	Local $TypeMBStr = "str"
	If IsPtr($lpMultiByteStr) Then $TypeMBStr = "ptr"
	Local $aResult = DllCall("Kernel32.dll", "int", "MultiByteToWideChar", "UINT", $iCodePage, "DWORD", $dwFlags, _
			$TypeMBStr, $lpMultiByteStr, "int", $cbMultiByte, "ptr", $lpWideCharStr, "int", $cchWideChar)
	If @error Then Return SetError(@error, 0, 0)
	Return $aResult[0]
EndFunc   ;==>_QuotedPrintable_MultiByteToWideChar

; #FUNCTION# ====================================================================================================================
; Name ..........: _QuotedPrintable_TranslateString
; Description ...:
; Syntax ........: _QuotedPrintable_TranslateString($sStringToTranslate, $iCodePage)
; Parameters ....: $sStringToTranslate              - An unknown value.
;                  $iCodePage            - An unknown value.
; Return values .: None
; Author ........: Prog@ndy
; Modified ......: mLipok
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _QuotedPrintable_TranslateString($sStringToTranslate, $iCodePage)
	SetError(0)
	If Not (IsInt($iCodePage) And $iCodePage > 0) Then $iCodePage = _QuotedPrintable_GetCodepage($iCodePage)
	If @error Or $iCodePage = 0 Then Return SetError(1, 0, "")

	Local $iLength = _QuotedPrintable_MultiByteToWideChar($iCodePage, 0, $sStringToTranslate, StringLen($sStringToTranslate), 0, 0)
	Local $Buffer = DllStructCreate("wchar[" & $iLength + 1 & "]")
	If Not _QuotedPrintable_MultiByteToWideChar($iCodePage, 0, $sStringToTranslate, StringLen($sStringToTranslate), DllStructGetPtr($Buffer), $iLength) Then
		Return SetError(2, 0, "")

	EndIf

	Return DllStructGetData($Buffer, 1)

EndFunc   ;==>_QuotedPrintable_TranslateString

; #FUNCTION# ====================================================================================================================
; Name ..........: _QuotedPrintable_Base64Decode
; Description ...:
; Syntax ........: _QuotedPrintable_Base64Decode($s)
; Parameters ....: $s                   - A string value.
; Return values .: None
; Author ........: Eddy
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _QuotedPrintable_Base64Decode($s)
	Local $key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', _
			$t = '', $p = -8, $a = 0, $c, $d, $len = StringLen($s)
	For $i = 1 To $len
		$c = StringInStr($key, StringMid($s, $i, 1), 1) - 1
		If $c < 0 Then ContinueLoop
		$a = BitOR(BitShift($a, -6), BitAND($c, 63))
		$p = $p + 6
		If $p >= 0 Then
			$d = BitAND(BitShift($a, $p), 255)
			If $c <> 64 Then $t = $t & Chr($d)
			$a = BitAND($a, 63)
			$p = $p - 8
		EndIf
	Next
	Return $t
EndFunc   ;==>_QuotedPrintable_Base64Decode

; #FUNCTION# ====================================================================================================================
; Name ..........: _QuotedPrintable_Decode
; Description ...:
; Syntax ........: _QuotedPrintable_Decode($s[, $IsQ = False])
; Parameters ....: $s                   - A string value.
;                  $IsQ                 - [optional] An unknown value. Default is False.
; Return values .: None
; Author ........: Prog@ndy
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _QuotedPrintable_Decode($s, $IsQ = False)
	If $IsQ Then $s = StringReplace($s, "_", " ")
	$s = StringSplit($s, "=")
	Local $result = $s[1]
	For $i = 2 To $s[0]
		$result &= Chr(Dec(StringLeft($s[$i], 2))) & StringTrimLeft($s[$i], 2)
	Next
	Return $result
EndFunc   ;==>_QuotedPrintable_Decode

; #FUNCTION# ====================================================================================================================
; Name ..........: _QuotedPrintable_DecodeEncodedWord
; Description ...:
; Syntax ........: _QuotedPrintable_DecodeEncodedWord($sStringToDecode)
; Parameters ....: $sStringToDecode           - A dll struct value.
; Return values .: None
; Author ........: Prog@ndy
; Modified ......: mLipok
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _QuotedPrintable_DecodeEncodedWord($sStringToDecode)
	Local $aEncodedChunks = StringRegExp($sStringToDecode, "=\?(.+?)\?(.)\?(.*?)\?=", 4)
	If Not @error Then
		Local $aParts
		For $iChunk = 0 To UBound($aEncodedChunks) - 1
			$aParts = $aEncodedChunks[$iChunk]
			Switch $aParts[2]
				Case "B", "b"
					$aParts[3] = _QuotedPrintable_Base64Decode($aParts[3])
				Case "Q", "q"
					$aParts[3] = _QuotedPrintable_Decode($aParts[3], True)
			EndSwitch
			$aParts[3] = _QuotedPrintable_TranslateString($aParts[3], $aParts[1])
			$sStringToDecode = StringReplace($sStringToDecode, $aParts[0], $aParts[3])
		Next
	EndIf
	Return $sStringToDecode
EndFunc   ;==>_QuotedPrintable_DecodeEncodedWord

;~ Under construction
;~ Func _QuotedPrintable_DecodeEncodedText($sStringToDecode)
;~ 	StringSplit(
;~ EndFunc