rust/hg-core/src/revlog/path_encode.rs
changeset 50167 ee63c87a0cac
parent 50166 6ea3b1acb5de
child 50366 eb07591825fa
equal deleted inserted replaced
50166:6ea3b1acb5de 50167:ee63c87a0cac
   525 fn hash_mangle(src: &[u8], sha: &[u8]) -> Vec<u8> {
   525 fn hash_mangle(src: &[u8], sha: &[u8]) -> Vec<u8> {
   526     let dirprefixlen = 8;
   526     let dirprefixlen = 8;
   527     let maxshortdirslen = 68;
   527     let maxshortdirslen = 68;
   528 
   528 
   529     let last_slash = src.iter().rposition(|b| *b == b'/');
   529     let last_slash = src.iter().rposition(|b| *b == b'/');
   530     let last_dot: Option<usize> = {
   530     let basename_start = match last_slash {
   531         let s = last_slash.unwrap_or(0);
   531         Some(slash) => slash + 1,
   532         src[s..].iter().rposition(|b| *b == b'.').map(|i| i + s)
   532         None => 0,
       
   533     };
       
   534     let basename = &src[basename_start..];
       
   535     let ext = match basename.iter().rposition(|b| *b == b'.') {
       
   536         None => &[],
       
   537         Some(dot) => &basename[dot..],
   533     };
   538     };
   534 
   539 
   535     let mut dest = Vec::with_capacity(MAXSTOREPATHLEN);
   540     let mut dest = Vec::with_capacity(MAXSTOREPATHLEN);
   536     dest.write_bytes(b"dh/");
   541     dest.write_bytes(b"dh/");
   537 
   542 
   545             }
   550             }
   546             dest.write_byte(b'/');
   551             dest.write_byte(b'/');
   547         }
   552         }
   548     }
   553     }
   549 
   554 
   550     let used = dest.len() + 40 + {
   555     let used = dest.len() + 40 + ext.len();
   551         if let Some(l) = last_dot {
       
   552             src.len() - l
       
   553         } else {
       
   554             0
       
   555         }
       
   556     };
       
   557 
   556 
   558     if MAXSTOREPATHLEN > used {
   557     if MAXSTOREPATHLEN > used {
   559         let slop = MAXSTOREPATHLEN - used;
   558         let slop = MAXSTOREPATHLEN - used;
   560         let basenamelen = match last_slash {
   559         let len = std::cmp::min(basename.len(), slop);
   561             Some(l) => src.len() - l - 1,
   560         dest.write_bytes(&basename[..len])
   562             None => src.len(),
       
   563         };
       
   564         let basenamelen = std::cmp::min(basenamelen, slop);
       
   565         if basenamelen > 0 {
       
   566             let start = match last_slash {
       
   567                 Some(l) => l + 1,
       
   568                 None => 0,
       
   569             };
       
   570             dest.write_bytes(&src[start..][..basenamelen])
       
   571         }
       
   572     }
   561     }
   573     for c in sha {
   562     for c in sha {
   574         hexencode(&mut dest, *c);
   563         hexencode(&mut dest, *c);
   575     }
   564     }
   576     if let Some(l) = last_dot {
   565     dest.write_bytes(ext);
   577         dest.write_bytes(&src[l..]);
       
   578     }
       
   579     dest.shrink_to_fit();
   566     dest.shrink_to_fit();
   580     dest
   567     dest
   581 }
   568 }
   582 
   569 
   583 fn hash_encode(src: &[u8]) -> Vec<u8> {
   570 fn hash_encode(src: &[u8]) -> Vec<u8> {