// // Copyright (c) 2008, Brian Frank and Andy Frank // Licensed under the Academic Free License version 3.0 // // History: // 2 May 08 Brian Frank Creation // ** ** FilePart is used to transfer binary content from a File. ** class FilePart : EmailPart { ** ** File content ** File? file ** ** Construct with default type of "text/plain". ** new make() { headers["Content-Transfer-Encoding"] = "base64" } ** ** Validate this part - throw Err if not configured correctly: ** - file must be non-null ** - if Content-Type not set, defaults to file.mimeType ** - if Content-Type name param not set, defaults to file.name ** - Content-Transfer-Encoding must be base64 ** override Void validate() { super.validate // check file is configured if ((Obj?)file == null) throw Err("file null in ${Type.of(this).name}") // default content-type to file mime type if (headers["Content-Type"] == null) { mime := file.mimeType ?: throw Err("Must specify Content-Type or file extension") headers["Content-Type"] = mime.toStr } // add name parameter mime := MimeType.fromStr(headers["Content-Type"]) if (mime.params["name"] == null && file.name.isAscii) headers["Content-Type"] = mime.toStr + "; name=\"$file.name\"" // we only support base64 if (headers["Content-Transfer-Encoding"] != "base64") throw Err("Content-Transfer-Encoding must be base64") } ** ** Encode as a MIME message according to RFC 822. ** override Void encode(OutStream out) { // ensure valid and configure defaults validate // write headers super.encode(out) // write file contents in base64 in := file.in try encodeBase64(in, file.size, out) finally in.close } ** Encode 'size' bytes from 'in' to 'out' as base64 with maximum line length of 50. ** ** Neither stream is closed after calling this function. @NoDoc static Void encodeBase64(InStream in, Int size, OutStream out) { buf := Buf() { capacity = 100 } left := size while (left > 0) { in.readBufFully(buf, left.min(48)) out.print(buf.toBase64).print("\r\n") left -= buf.size buf.clear } } }