summaryrefslogtreecommitdiffstats
path: root/openpgp/src/serialize/stream.rs
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-11-19 17:32:46 +0100
committerJustus Winter <justus@sequoia-pgp.org>2019-11-19 17:32:46 +0100
commit505f45f8077ac92b4ae5fa6cde88a10a3be15af3 (patch)
tree61146c2790a9f66bfa03ae301dfa1e397cb93c19 /openpgp/src/serialize/stream.rs
parent1ddc1dd61b45b41801c1d1c364cd6789314cb8f3 (diff)
openpgp: Use the builder pattern for stream::LiteralWriter.
- See #375.
Diffstat (limited to 'openpgp/src/serialize/stream.rs')
-rw-r--r--openpgp/src/serialize/stream.rs116
1 files changed, 59 insertions, 57 deletions
diff --git a/openpgp/src/serialize/stream.rs b/openpgp/src/serialize/stream.rs
index 38c14fa7..201df920 100644
--- a/openpgp/src/serialize/stream.rs
+++ b/openpgp/src/serialize/stream.rs
@@ -240,7 +240,7 @@ impl<'a> Signer<'a> {
/// {
/// let message = Message::new(&mut o);
/// let signer = Signer::new(message, signing_keypair).build()?;
- /// let mut ls = LiteralWriter::new(signer, None, None, None)?;
+ /// let mut ls = LiteralWriter::new(signer).build()?;
/// ls.write_all(b"Make it so, number one!")?;
/// ls.finalize()?;
/// }
@@ -544,7 +544,7 @@ impl<'a> writer::Stackable<'a, Cookie> for Signer<'a> {
/// let mut o = vec![];
/// {
/// let message = Message::new(&mut o);
-/// let mut w = LiteralWriter::new(message, None, None, None)?;
+/// let mut w = LiteralWriter::new(message).build()?;
/// w.write_all(b"Hello world.")?;
/// w.finalize()?;
/// }
@@ -553,47 +553,52 @@ impl<'a> writer::Stackable<'a, Cookie> for Signer<'a> {
/// # }
/// ```
pub struct LiteralWriter<'a> {
+ template: Literal,
inner: writer::BoxStack<'a, Cookie>,
signature_writer: Option<writer::BoxStack<'a, Cookie>>,
}
impl<'a> LiteralWriter<'a> {
/// Creates a new literal writer.
+ pub fn new(inner: writer::Stack<'a, Cookie>) -> Self {
+ LiteralWriter {
+ template: Literal::new(DataFormat::default()),
+ inner: writer::BoxStack::from(inner),
+ signature_writer: None,
+ }
+ }
+
+ /// Sets the data format.
+ pub fn format(mut self, format: DataFormat) -> Self {
+ self.template.set_format(format);
+ self
+ }
+
+ /// Sets the filename.
+ ///
+ /// The standard does not specify the encoding. Filenames must
+ /// not be longer than 255 bytes.
+ pub fn filename<B: AsRef<[u8]>>(mut self, filename: B) -> Result<Self> {
+ self.template.set_filename_from_bytes(filename.as_ref())?;
+ Ok(self)
+ }
+
+ /// Sets the data format.
+ pub fn date(mut self, timestamp: time::Tm) -> Result<Self>
+ {
+ self.template.set_date(Some(timestamp));
+ Ok(self)
+ }
+
+ /// Finalizes the literal writer, returning the writer stack.
///
/// `format`, `filename`, and `date` will be emitted as part of
/// the literal packets headers. Note that these headers will not
/// be authenticated by signatures (but will be authenticated by a
/// SEIP/MDC container), and are therefore unreliable and should
/// not be trusted.
- ///
- /// If `date` is `None`, then the earliest representable time will
- /// be used as a dummy value.
- pub fn new<'f, D, F, T>(inner: writer::Stack<'a, Cookie>,
- format: D, filename: F, date: T)
- -> Result<writer::Stack<'a, Cookie>>
- where D: Into<Option<DataFormat>>,
- F: Into<Option<&'f [u8]>>,
- T: Into<Option<time::Tm>>
- {
- Self::make(inner,
- format.into().unwrap_or_default(),
- filename.into(), date.into())
- }
-
- fn make(inner: writer::Stack<'a, Cookie>,
- format: DataFormat,
- filename: Option<&[u8]>,
- date: Option<time::Tm>)
- -> Result<writer::Stack<'a, Cookie>> {
- let mut inner = writer::BoxStack::from(inner);
- let level = inner.cookie_ref().level + 1;
-
- let mut template = Literal::new(format);
- template.set_date(date);
-
- if let Some(f) = filename {
- template.set_filename_from_bytes(f)?;
- }
+ pub fn build(mut self) -> Result<writer::Stack<'a, Cookie>> {
+ let level = self.inner.cookie_ref().level + 1;
// For historical reasons, signatures over literal data
// packets only include the body without metadata or framing.
@@ -604,35 +609,32 @@ impl<'a> LiteralWriter<'a> {
if let &Cookie {
private: Private::Signer{..},
..
- } = inner.cookie_ref() {
+ } = self.inner.cookie_ref() {
true
} else {
false
};
- let mut signature_writer = None;
if signer_above {
- let stack = inner.pop()?;
+ let stack = self.inner.pop()?;
// We know a signer has an inner stackable.
let stack = stack.unwrap();
- signature_writer = Some(inner);
- inner = stack;
+ self.signature_writer = Some(self.inner);
+ self.inner = stack;
}
// Not hashed by the signature_writer (see above).
- CTB::new(Tag::Literal).serialize(&mut inner)?;
+ CTB::new(Tag::Literal).serialize(&mut self.inner)?;
// Neither is any framing added by the PartialBodyFilter.
- let mut inner
- = PartialBodyFilter::new(writer::Stack::from(inner), Cookie::new(level));
+ self.inner
+ = PartialBodyFilter::new(writer::Stack::from(self.inner),
+ Cookie::new(level)).into();
// Nor the headers.
- template.serialize_headers(&mut inner, false)?;
+ self.template.serialize_headers(&mut self.inner, false)?;
- Ok(writer::Stack::from(Box::new(Self {
- inner: inner.into(),
- signature_writer: signature_writer,
- })))
+ Ok(writer::Stack::from(Box::new(self)))
}
}
@@ -726,7 +728,7 @@ impl<'a> writer::Stackable<'a, Cookie> for LiteralWriter<'a> {
/// let message = Message::new(&mut o);
/// let w = Compressor::new(message,
/// CompressionAlgorithm::Uncompressed, None)?;
-/// let mut w = LiteralWriter::new(w, None, None, None)?;
+/// let mut w = LiteralWriter::new(w).build()?;
/// w.write_all(b"Hello world.")?;
/// w.finalize()?;
/// }
@@ -966,7 +968,7 @@ impl<'a> Encryptor<'a> {
/// &["совершенно секретно".into()],
/// &recipients, None, None)
/// .expect("Failed to create encryptor");
- /// let mut w = LiteralWriter::new(encryptor, None, None, None)?;
+ /// let mut w = LiteralWriter::new(encryptor).build()?;
/// w.write_all(b"Hello world.")?;
/// w.finalize()?;
/// # Ok(())
@@ -1266,14 +1268,14 @@ mod test {
let m = Message::new(&mut o);
let c = Compressor::new(
m, CompressionAlgorithm::Uncompressed, None).unwrap();
- let mut ls = LiteralWriter::new(c, T, None, None).unwrap();
+ let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
write!(ls, "one").unwrap();
let c = ls.finalize_one().unwrap().unwrap(); // Pop the LiteralWriter.
- let mut ls = LiteralWriter::new(c, T, None, None).unwrap();
+ let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
write!(ls, "two").unwrap();
let c = ls.finalize_one().unwrap().unwrap(); // Pop the LiteralWriter.
let c = c.finalize_one().unwrap().unwrap(); // Pop the Compressor.
- let mut ls = LiteralWriter::new(c, T, None, None).unwrap();
+ let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
write!(ls, "three").unwrap();
}
@@ -1327,19 +1329,19 @@ mod test {
m, CompressionAlgorithm::Uncompressed, None).unwrap();
let c = Compressor::new(
c0, CompressionAlgorithm::Uncompressed, None).unwrap();
- let mut ls = LiteralWriter::new(c, T, None, None).unwrap();
+ let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
write!(ls, "one").unwrap();
let c = ls.finalize_one().unwrap().unwrap();
- let mut ls = LiteralWriter::new(c, T, None, None).unwrap();
+ let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
write!(ls, "two").unwrap();
let c = ls.finalize_one().unwrap().unwrap();
let c0 = c.finalize_one().unwrap().unwrap();
let c = Compressor::new(
c0, CompressionAlgorithm::Uncompressed, None).unwrap();
- let mut ls = LiteralWriter::new(c, T, None, None).unwrap();
+ let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
write!(ls, "three").unwrap();
let c = ls.finalize_one().unwrap().unwrap();
- let mut ls = LiteralWriter::new(c, T, None, None).unwrap();
+ let mut ls = LiteralWriter::new(c).format(T).build().unwrap();
write!(ls, "four").unwrap();
}
@@ -1363,7 +1365,7 @@ mod test {
let m = Message::new(&mut o);
let c = Compressor::new(m,
CompressionAlgorithm::BZip2, None).unwrap();
- let mut ls = LiteralWriter::new(c, None, None, None).unwrap();
+ let mut ls = LiteralWriter::new(c).build().unwrap();
// Write 64 megabytes of zeroes.
for _ in 0 .. 16 {
ls.write_all(&zeros).unwrap();
@@ -1402,7 +1404,7 @@ mod test {
signer = signer.add_signer(s);
}
let signer = signer.build().unwrap();
- let mut ls = LiteralWriter::new(signer, None, None, None).unwrap();
+ let mut ls = LiteralWriter::new(signer).build().unwrap();
ls.write_all(b"Tis, tis, tis. Tis is important.").unwrap();
let signer = ls.finalize_one().unwrap().unwrap();
let _ = signer.finalize_one().unwrap().unwrap();
@@ -1439,7 +1441,7 @@ mod test {
m, &passwords,
&[], None, None)
.unwrap();
- let mut literal = LiteralWriter::new(encryptor, None, None, None)
+ let mut literal = LiteralWriter::new(encryptor).build()
.unwrap();
literal.write_all(message).unwrap();
}
@@ -1627,7 +1629,7 @@ mod test {
let encryptor = Encryptor::new(
m, &[], &recipients, None, AEADAlgorithm::EAX)
.unwrap();
- let mut literal = LiteralWriter::new(encryptor, None, None, None)
+ let mut literal = LiteralWriter::new(encryptor).build()
.unwrap();
literal.write_all(&content).unwrap();
// literal.finalize().unwrap();