///|
pub fn decode_body(input : String, encoding : TransferEncoding) -> String {
match encoding {
QuotedPrintable => decode_quoted_printable(input)
Base64 => decode_base64_text(input)
_ => input
}
}
///|
pub fn decode_quoted_printable(input : String) -> String {
let chars : Array[Char] = []
for ch in input {
chars.push(ch)
}
let mut out = ""
let mut i = 0
while i < chars.length() {
if chars[i] == '=' && i + 2 < chars.length() {
if chars[i + 1] == '\r' && chars[i + 2] == '\n' {
i = i + 3
} else if chars[i + 1] == '\n' {
i = i + 2
} else {
let hi = hex_value(chars[i + 1])
let lo = hex_value(chars[i + 2])
if hi >= 0 && lo >= 0 {
out = out + Int::unsafe_to_char(hi * 16 + lo).to_string()
i = i + 3
} else {
out = out + chars[i].to_string()
i = i + 1
}
}
} else {
out = out + chars[i].to_string()
i = i + 1
}
}
out
}
///|
pub fn hex_value(ch : Char) -> Int {
if ch >= '0' && ch <= '9' {
ch.to_int() - '0'.to_int()
} else if ch >= 'A' && ch <= 'F' {
ch.to_int() - 'A'.to_int() + 10
} else if ch >= 'a' && ch <= 'f' {
ch.to_int() - 'a'.to_int() + 10
} else {
-1
}
}
///|
pub fn decode_base64_text(input : String) -> String {
let cleaned = clean_base64(input)
let chars : Array[Char] = []
for ch in cleaned {
chars.push(ch)
}
let bytes : Array[Int] = []
let mut i = 0
while i < chars.length() {
let a = b64_value(chars[i])
let b = if i + 1 < chars.length() { b64_value(chars[i + 1]) } else { -1 }
let c = if i + 2 < chars.length() { b64_value(chars[i + 2]) } else { -1 }
let d = if i + 3 < chars.length() { b64_value(chars[i + 3]) } else { -1 }
if a >= 0 && b >= 0 {
bytes.push(a * 4 + b / 16)
if c >= 0 {
bytes.push(b % 16 * 16 + c / 4)
}
if d >= 0 {
bytes.push(c % 4 * 64 + d)
}
}
i = i + 4
}
let mut out = ""
for byte in bytes {
out = out + Int::unsafe_to_char(byte).to_string()
}
out
}
///|
fn clean_base64(input : String) -> String {
let mut out = ""
for ch in input {
if ch == '=' || b64_value(ch) >= 0 {
out = out + ch.to_string()
}
}
out
}
///|
fn b64_value(ch : Char) -> Int {
if ch >= 'A' && ch <= 'Z' {
ch.to_int() - 'A'.to_int()
} else if ch >= 'a' && ch <= 'z' {
ch.to_int() - 'a'.to_int() + 26
} else if ch >= '0' && ch <= '9' {
ch.to_int() - '0'.to_int() + 52
} else if ch == '+' {
62
} else if ch == '/' {
63
} else {
-1
}
}