git_zero_server/receive/
attributes.rs1use git_zero_core::{Error, Result};
3
4pub struct FsckAttributes {
8 remaining: u64,
9 line: u16,
10 stopped: bool,
11 failure: Option<Error>,
12}
13
14impl FsckAttributes {
15 pub fn new(size: u64) -> Result<Self> {
16 if size > 100 * 1024 * 1024 {
17 return Err(Error::InvalidObject);
18 }
19 Ok(Self {
20 remaining: size,
21 line: 0,
22 stopped: false,
23 failure: None,
24 })
25 }
26
27 pub fn update(&mut self, bytes: &[u8]) -> Result<()> {
28 if let Some(error) = self.failure {
29 return Err(error);
30 }
31 let result = self.feed(bytes);
32 if let Err(error) = result {
33 self.failure = Some(error);
34 }
35 result
36 }
37
38 fn feed(&mut self, bytes: &[u8]) -> Result<()> {
39 self.remaining = self
40 .remaining
41 .checked_sub(bytes.len() as u64)
42 .ok_or(Error::InvalidObject)?;
43 if self.stopped {
44 return Ok(());
45 }
46 for &byte in bytes {
47 if byte == 0 {
48 self.stopped = true;
49 break;
50 }
51 if byte == b'\n' {
52 self.line = 0;
53 } else {
54 self.line += 1;
55 if self.line >= 2048 {
56 return Err(Error::InvalidObject);
57 }
58 }
59 }
60 Ok(())
61 }
62
63 pub fn finish(&self) -> Result<()> {
64 if let Some(error) = self.failure {
65 return Err(error);
66 }
67 if self.remaining == 0 {
68 Ok(())
69 } else {
70 Err(Error::InvalidObject)
71 }
72 }
73}