accessor.rs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // SPDX-License-Identifier: AGPL-3.0-or-later
  2. //! This module contains the [Accessor] type.
  3. use positioned_io::{ReadAt, Size, WriteAt};
  4. use std::io::{self, Read, Seek, SeekFrom, Write};
  5. use crate::{
  6. sectored_buf::SectoredBuf, BlockMeta, Cursor, Decompose, FlushMeta, MetaAccess, Positioned,
  7. ReadDual, Result, SecretStream, Sectored, Split, TryCompose, TrySeek, WriteDual,
  8. ZeroExtendable,
  9. };
  10. pub use private::Accessor;
  11. mod private {
  12. use super::*;
  13. /// Wraps a position independent stream of cipher text and exposes the positioned stream of
  14. /// validated plaintext data it contains.
  15. pub struct Accessor<T: Size> {
  16. inner: SectoredBuf<SecretStream<Cursor<T>>>,
  17. }
  18. impl<T: ReadAt + Sectored + AsRef<BlockMeta> + Size> Accessor<T> {
  19. /// Creates a new [Accessor] by wrapping the given type.
  20. pub fn new(inner: T) -> Result<Accessor<T>> {
  21. let meta: &BlockMeta = inner.as_ref();
  22. let key = meta.body.block_key()?.clone();
  23. let inner = SecretStream::new(key).try_compose(Cursor::new(inner))?;
  24. Ok(Self {
  25. inner: SectoredBuf::new(inner)?,
  26. })
  27. }
  28. }
  29. impl<T: Size> Accessor<T> {
  30. /// Returns a reference to the inner type.
  31. pub fn get_ref(&self) -> &T {
  32. self.inner.get_ref().get_ref().get_ref()
  33. }
  34. /// Returns a mutable reference to the inner type.
  35. pub fn get_mut(&mut self) -> &mut T {
  36. self.inner.get_mut().get_mut().get_mut()
  37. }
  38. }
  39. impl<T: Size + ReadAt + AsRef<BlockMeta>> Accessor<T> {
  40. /// Returns a reference to the internal buffer. The returned slice starts at the given
  41. /// offset in the stream and is no longer than the given size, though it may be shorter in
  42. /// the case where the stream's total length is shorter than `offset + size`, or if there
  43. /// are fewer than `size` bytes buffered after `offset`.
  44. pub fn get_buf(&self, offset: u64, size: u64) -> Result<&[u8]> {
  45. self.inner.get_buf(offset, size)
  46. }
  47. }
  48. impl<T: Size + ReadAt + WriteAt + MetaAccess> ZeroExtendable for Accessor<T> {
  49. fn zero_extend(&mut self, len: u64) -> io::Result<()> {
  50. self.inner.zero_extend(len)
  51. }
  52. }
  53. impl<T: ReadAt + AsRef<BlockMeta> + Size> Read for Accessor<T> {
  54. fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
  55. self.inner.read(buf)
  56. }
  57. }
  58. impl<T: ReadAt + WriteAt + MetaAccess> Write for Accessor<T> {
  59. fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
  60. self.inner.write(buf)
  61. }
  62. fn flush(&mut self) -> std::io::Result<()> {
  63. self.inner.flush()
  64. }
  65. }
  66. impl<T: ReadAt + WriteAt + MetaAccess> Seek for Accessor<T> {
  67. fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
  68. self.inner.seek(pos)
  69. }
  70. }
  71. impl<U, T: AsRef<U> + Size> AsRef<U> for Accessor<T> {
  72. fn as_ref(&self) -> &U {
  73. self.inner.get_ref().as_ref()
  74. }
  75. }
  76. impl<U, T: AsMut<U> + Size> AsMut<U> for Accessor<T> {
  77. fn as_mut(&mut self) -> &mut U {
  78. self.inner.get_mut().as_mut()
  79. }
  80. }
  81. impl<T: Size> Decompose<T> for Accessor<T> {
  82. fn into_inner(self) -> T {
  83. self.inner.into_inner().into_inner().into_inner()
  84. }
  85. }
  86. impl<T: FlushMeta + Size> FlushMeta for Accessor<T> {
  87. fn flush_meta(&mut self) -> Result<()> {
  88. self.get_mut().flush_meta()
  89. }
  90. }
  91. impl<T: Size> Sectored for Accessor<T> {
  92. fn sector_sz(&self) -> usize {
  93. self.inner.sector_sz()
  94. }
  95. }
  96. impl<T: Size> Size for Accessor<T> {
  97. fn size(&self) -> std::io::Result<Option<u64>> {
  98. self.inner.get_ref().size()
  99. }
  100. }
  101. impl<T: ReadAt + WriteAt + MetaAccess> WriteDual for Accessor<T> {
  102. fn write_from<R: Read>(&mut self, read: R, count: usize) -> std::io::Result<usize> {
  103. self.inner.write_from(read, count)
  104. }
  105. }
  106. impl<T: ReadAt + AsRef<BlockMeta> + Size> ReadDual for Accessor<T> {
  107. fn read_into<W: Write>(&mut self, write: W, count: usize) -> std::io::Result<usize> {
  108. self.inner.read_into(write, count)
  109. }
  110. }
  111. impl<T: Size> Positioned for Accessor<T> {
  112. fn pos(&self) -> usize {
  113. self.inner.pos()
  114. }
  115. }
  116. impl<T: ReadAt + AsRef<BlockMeta> + Size> TrySeek for Accessor<T> {
  117. fn try_seek(&mut self, seek_from: SeekFrom) -> std::io::Result<()> {
  118. self.inner.try_seek(seek_from)
  119. }
  120. }
  121. impl<T: Size> Split<Accessor<&'static [u8]>, T> for Accessor<T> {
  122. fn split(self) -> (Accessor<&'static [u8]>, T) {
  123. let (sectored_buf, inner) = self.inner.split();
  124. let (secret_stream, inner) = inner.split();
  125. let (cursor, inner) = inner.split();
  126. let new_inner =
  127. SectoredBuf::combine(sectored_buf, SecretStream::combine(secret_stream, cursor));
  128. (Accessor { inner: new_inner }, inner)
  129. }
  130. fn combine(left: Accessor<&'static [u8]>, right: T) -> Self {
  131. let (sectored_buf, inner) = left.inner.split();
  132. let (secret_stream, inner) = inner.split();
  133. let (cursor, ..) = inner.split();
  134. let new_inner = SectoredBuf::combine(
  135. sectored_buf,
  136. SecretStream::combine(secret_stream, Cursor::combine(cursor, right)),
  137. );
  138. Accessor { inner: new_inner }
  139. }
  140. }
  141. }
  142. #[cfg(test)]
  143. mod test {
  144. use super::*;
  145. use crate::test_helpers::make_block_with;
  146. #[test]
  147. fn can_wrap_block_ref() {
  148. let block = make_block_with().into_inner().into_inner().into_inner();
  149. let mut accessor = Accessor::new(block).expect("failed to wrap block");
  150. const EXPECTED: &[u8] = &[1u8; 8];
  151. accessor.write_all(EXPECTED).expect("write failed");
  152. accessor.flush().expect("flush failed");
  153. accessor.rewind().expect("rewind failed");
  154. let block = accessor.into_inner();
  155. let mut wrapped = Accessor::new(&block).expect("failed to wrap block reference");
  156. let mut actual = [0u8; EXPECTED.len()];
  157. wrapped.read(&mut actual).expect("read failed");
  158. assert_eq!(EXPECTED, actual);
  159. }
  160. }