Advertisement
Guest User

Untitled

a guest
Jan 15th, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.34 KB | None | 0 0
  1. extern crate bytes;
  2. extern crate tokio;
  3. extern crate tokio_codec;
  4.  
  5. use bytes::{BufMut, BytesMut};
  6. use std::io::{Error, ErrorKind};
  7. use std::str;
  8. use tokio::prelude::*;
  9. use tokio_codec::{Decoder, Encoder};
  10.  
  11. pub enum MailItem {
  12.     SingleLine(String),
  13.     MultiLine(Vec<u8>)
  14. }
  15.  
  16. pub struct MailSocketCodec {
  17.     uses_dot_stuff: bool,
  18.  
  19.     /// The index of where we should search for CRLF in the input stream.
  20.     next_index: usize,
  21.  
  22.     multiline_size: usize
  23. }
  24.  
  25. /// To implement:
  26. /// receiveLine
  27. /// receiveNBytes
  28. /// receiveUntilDot
  29. /// startTLS
  30. /// connect
  31. /// close
  32. impl Encoder for MailSocketCodec {
  33.     type Item = MailItem;
  34.     type Error = Error;
  35.     fn encode(&mut self, item: MailItem,
  36.               buf: &mut BytesMut) -> Result<(), Error> {
  37.         match item {
  38.             MailItem::SingleLine(line) => {
  39.                 assert!(!line.contains("\r") && !line.contains("\n"),
  40.                     "Cannot send CR or LF values across a single line");
  41.                 buf.reserve(line.len() + 2);
  42.                 buf.put(line);
  43.                 buf.put("\r\n");
  44.                 Ok(())
  45.             },
  46.             MailItem::MultiLine(bytes) => {
  47.                 match self.uses_dot_stuff {
  48.                     true => {
  49.                         panic!("Dot stuff not yet implemented");
  50.                     },
  51.                     false => {
  52.                         buf.put(bytes);
  53.                         Ok(())
  54.                     }
  55.                 }
  56.             }
  57.         }
  58.     }
  59. }
  60.  
  61. fn make_str(s: &[u8]) -> Result<String, Error> {
  62.     str::from_utf8(s)
  63.         .map(|s| s.to_string())
  64.         .map_err(|_| Error::new(ErrorKind::InvalidData, "Not UTF-8"))
  65. }
  66.  
  67. impl Decoder for MailSocketCodec {
  68.     type Item = MailItem;
  69.     type Error = Error;
  70.     fn decode(&mut self,
  71.               buf: &mut BytesMut) -> Result<Option<MailItem>, Error> {
  72.         match (self.multiline_size, self.uses_dot_stuff) {
  73.             (0, _) => {
  74.                 // We're parsing in single-line mode.
  75.                 let offset = buf[self.next_index..].windows(2).position(|t| t == b"\r\n");
  76.                 if let Some(count) = offset {
  77.                     let count = self.next_index + count;
  78.  
  79.                     // Take the full string, sans CRLF, into the line
  80.                     let line = buf.split_to(count);
  81.  
  82.                     // Drop off the CRLF from the buffer.
  83.                     buf.split_to(2);
  84.  
  85.                     // Reset our search point for the next CRLF.
  86.                     self.next_index = 0;
  87.  
  88.                     // Finally, return the line we saved.
  89.                     make_str(&line).map(|val| Some(MailItem::SingleLine(val)))
  90.                 } else {
  91.                     // Note that we don't need to scan this portion of the array
  92.                     // anymore...
  93.                     self.next_index = buf.len();
  94.  
  95.                     // ... unless the very last byte was a CR.
  96.                     if buf.len() >= 1 && buf[buf.len() - 1] == b'\r' {
  97.                         self.next_index -= 1;
  98.                     }
  99.                     Ok(None)
  100.                 }
  101.             },
  102.             (_, true) => {
  103.                 panic!("Dot stuffing not implemented");
  104.             },
  105.             (count, false) => {
  106.                 panic!("Exact count not implemented");
  107.             }
  108.         }
  109.     }
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement