rust/hg-core/src/dirstate/parsers.rs
changeset 48022 f2a9db29cb2d
parent 48018 08efe5945d2b
child 48068 bf8837e3d7ce
equal deleted inserted replaced
48021:627cd8f33db0 48022:f2a9db29cb2d
    48     Ok((parents, entries, copies))
    48     Ok((parents, entries, copies))
    49 }
    49 }
    50 
    50 
    51 #[derive(BytesCast)]
    51 #[derive(BytesCast)]
    52 #[repr(C)]
    52 #[repr(C)]
    53 pub(super) struct RawEntry {
    53 struct RawEntry {
    54     state: u8,
    54     state: u8,
    55     mode: unaligned::I32Be,
    55     mode: unaligned::I32Be,
    56     size: unaligned::I32Be,
    56     size: unaligned::I32Be,
    57     mtime: unaligned::I32Be,
    57     mtime: unaligned::I32Be,
    58     length: unaligned::I32Be,
    58     length: unaligned::I32Be,
    71     contents = rest;
    71     contents = rest;
    72     while !contents.is_empty() {
    72     while !contents.is_empty() {
    73         let (raw_entry, rest) = RawEntry::from_bytes(contents)
    73         let (raw_entry, rest) = RawEntry::from_bytes(contents)
    74             .map_err(|_| HgError::corrupted("Overflow in dirstate."))?;
    74             .map_err(|_| HgError::corrupted("Overflow in dirstate."))?;
    75 
    75 
    76         let entry = DirstateEntry {
    76         let entry = DirstateEntry::from_v1_data(
    77             state: EntryState::try_from(raw_entry.state)?,
    77             EntryState::try_from(raw_entry.state)?,
    78             mode: raw_entry.mode.get(),
    78             raw_entry.mode.get(),
    79             mtime: raw_entry.mtime.get(),
    79             raw_entry.size.get(),
    80             size: raw_entry.size.get(),
    80             raw_entry.mtime.get(),
    81         };
    81         );
    82         let (paths, rest) =
    82         let (paths, rest) =
    83             u8::slice_from_bytes(rest, raw_entry.length.get() as usize)
    83             u8::slice_from_bytes(rest, raw_entry.length.get() as usize)
    84                 .map_err(|_| HgError::corrupted("Overflow in dirstate."))?;
    84                 .map_err(|_| HgError::corrupted("Overflow in dirstate."))?;
    85 
    85 
    86         // `paths` is either a single path, or two paths separated by a NULL
    86         // `paths` is either a single path, or two paths separated by a NULL
   122     entry: &DirstateEntry,
   122     entry: &DirstateEntry,
   123     copy_source: Option<&HgPath>,
   123     copy_source: Option<&HgPath>,
   124     packed: &mut Vec<u8>,
   124     packed: &mut Vec<u8>,
   125 ) {
   125 ) {
   126     let length = packed_filename_and_copy_source_size(filename, copy_source);
   126     let length = packed_filename_and_copy_source_size(filename, copy_source);
       
   127     let (state, mode, size, mtime) = entry.v1_data();
   127 
   128 
   128     // Unwrapping because `impl std::io::Write for Vec<u8>` never errors
   129     // Unwrapping because `impl std::io::Write for Vec<u8>` never errors
   129     packed.write_u8(entry.state.into()).unwrap();
   130     packed.write_u8(state).unwrap();
   130     packed.write_i32::<BigEndian>(entry.mode).unwrap();
   131     packed.write_i32::<BigEndian>(mode).unwrap();
   131     packed.write_i32::<BigEndian>(entry.size).unwrap();
   132     packed.write_i32::<BigEndian>(size).unwrap();
   132     packed.write_i32::<BigEndian>(entry.mtime).unwrap();
   133     packed.write_i32::<BigEndian>(mtime).unwrap();
   133     packed.write_i32::<BigEndian>(length as i32).unwrap();
   134     packed.write_i32::<BigEndian>(length as i32).unwrap();
   134     packed.extend(filename.as_bytes());
   135     packed.extend(filename.as_bytes());
   135     if let Some(source) = copy_source {
   136     if let Some(source) = copy_source {
   136         packed.push(b'\0');
   137         packed.push(b'\0');
   137         packed.extend(source.as_bytes());
   138         packed.extend(source.as_bytes());
   210     }
   211     }
   211     #[test]
   212     #[test]
   212     fn test_pack_dirstate_one_entry() {
   213     fn test_pack_dirstate_one_entry() {
   213         let expected_state_map: StateMap = [(
   214         let expected_state_map: StateMap = [(
   214             HgPathBuf::from_bytes(b"f1"),
   215             HgPathBuf::from_bytes(b"f1"),
   215             DirstateEntry {
   216             DirstateEntry::from_v1_data(
   216                 state: EntryState::Normal,
   217                 EntryState::Normal,
   217                 mode: 0o644,
   218                 0o644,
   218                 size: 0,
   219                 0,
   219                 mtime: 791231220,
   220                 791231220,
   220             },
   221             ),
   221         )]
   222         )]
   222         .iter()
   223         .iter()
   223         .cloned()
   224         .cloned()
   224         .collect();
   225         .collect();
   225         let mut state_map = expected_state_map.clone();
   226         let mut state_map = expected_state_map.clone();
   247     }
   248     }
   248     #[test]
   249     #[test]
   249     fn test_pack_dirstate_one_entry_with_copy() {
   250     fn test_pack_dirstate_one_entry_with_copy() {
   250         let expected_state_map: StateMap = [(
   251         let expected_state_map: StateMap = [(
   251             HgPathBuf::from_bytes(b"f1"),
   252             HgPathBuf::from_bytes(b"f1"),
   252             DirstateEntry {
   253             DirstateEntry::from_v1_data(
   253                 state: EntryState::Normal,
   254                 EntryState::Normal,
   254                 mode: 0o644,
   255                 0o644,
   255                 size: 0,
   256                 0,
   256                 mtime: 791231220,
   257                 791231220,
   257             },
   258             ),
   258         )]
   259         )]
   259         .iter()
   260         .iter()
   260         .cloned()
   261         .cloned()
   261         .collect();
   262         .collect();
   262         let mut state_map = expected_state_map.clone();
   263         let mut state_map = expected_state_map.clone();
   288 
   289 
   289     #[test]
   290     #[test]
   290     fn test_parse_pack_one_entry_with_copy() {
   291     fn test_parse_pack_one_entry_with_copy() {
   291         let mut state_map: StateMap = [(
   292         let mut state_map: StateMap = [(
   292             HgPathBuf::from_bytes(b"f1"),
   293             HgPathBuf::from_bytes(b"f1"),
   293             DirstateEntry {
   294             DirstateEntry::from_v1_data(
   294                 state: EntryState::Normal,
   295                 EntryState::Normal,
   295                 mode: 0o644,
   296                 0o644,
   296                 size: 0,
   297                 0,
   297                 mtime: 791231220,
   298                 791231220,
   298             },
   299             ),
   299         )]
   300         )]
   300         .iter()
   301         .iter()
   301         .cloned()
   302         .cloned()
   302         .collect();
   303         .collect();
   303         let mut copymap = FastHashMap::default();
   304         let mut copymap = FastHashMap::default();
   334     #[test]
   335     #[test]
   335     fn test_parse_pack_multiple_entries_with_copy() {
   336     fn test_parse_pack_multiple_entries_with_copy() {
   336         let mut state_map: StateMap = [
   337         let mut state_map: StateMap = [
   337             (
   338             (
   338                 HgPathBuf::from_bytes(b"f1"),
   339                 HgPathBuf::from_bytes(b"f1"),
   339                 DirstateEntry {
   340                 DirstateEntry::from_v1_data(
   340                     state: EntryState::Normal,
   341                     EntryState::Normal,
   341                     mode: 0o644,
   342                     0o644,
   342                     size: 0,
   343                     0,
   343                     mtime: 791231220,
   344                     791231220,
   344                 },
   345                 ),
   345             ),
   346             ),
   346             (
   347             (
   347                 HgPathBuf::from_bytes(b"f2"),
   348                 HgPathBuf::from_bytes(b"f2"),
   348                 DirstateEntry {
   349                 DirstateEntry::from_v1_data(
   349                     state: EntryState::Merged,
   350                     EntryState::Merged,
   350                     mode: 0o777,
   351                     0o777,
   351                     size: 1000,
   352                     1000,
   352                     mtime: 791231220,
   353                     791231220,
   353                 },
   354                 ),
   354             ),
   355             ),
   355             (
   356             (
   356                 HgPathBuf::from_bytes(b"f3"),
   357                 HgPathBuf::from_bytes(b"f3"),
   357                 DirstateEntry {
   358                 DirstateEntry::from_v1_data(
   358                     state: EntryState::Removed,
   359                     EntryState::Removed,
   359                     mode: 0o644,
   360                     0o644,
   360                     size: 234553,
   361                     234553,
   361                     mtime: 791231220,
   362                     791231220,
   362                 },
   363                 ),
   363             ),
   364             ),
   364             (
   365             (
   365                 HgPathBuf::from_bytes(b"f4\xF6"),
   366                 HgPathBuf::from_bytes(b"f4\xF6"),
   366                 DirstateEntry {
   367                 DirstateEntry::from_v1_data(EntryState::Added, 0o644, -1, -1),
   367                     state: EntryState::Added,
       
   368                     mode: 0o644,
       
   369                     size: -1,
       
   370                     mtime: -1,
       
   371                 },
       
   372             ),
   368             ),
   373         ]
   369         ]
   374         .iter()
   370         .iter()
   375         .cloned()
   371         .cloned()
   376         .collect();
   372         .collect();
   412     #[test]
   408     #[test]
   413     /// https://www.mercurial-scm.org/repo/hg/rev/af3f26b6bba4
   409     /// https://www.mercurial-scm.org/repo/hg/rev/af3f26b6bba4
   414     fn test_parse_pack_one_entry_with_copy_and_time_conflict() {
   410     fn test_parse_pack_one_entry_with_copy_and_time_conflict() {
   415         let mut state_map: StateMap = [(
   411         let mut state_map: StateMap = [(
   416             HgPathBuf::from_bytes(b"f1"),
   412             HgPathBuf::from_bytes(b"f1"),
   417             DirstateEntry {
   413             DirstateEntry::from_v1_data(
   418                 state: EntryState::Normal,
   414                 EntryState::Normal,
   419                 mode: 0o644,
   415                 0o644,
   420                 size: 0,
   416                 0,
   421                 mtime: 15000000,
   417                 15000000,
   422             },
   418             ),
   423         )]
   419         )]
   424         .iter()
   420         .iter()
   425         .cloned()
   421         .cloned()
   426         .collect();
   422         .collect();
   427         let mut copymap = FastHashMap::default();
   423         let mut copymap = FastHashMap::default();
   452         assert_eq!(
   448         assert_eq!(
   453             (
   449             (
   454                 &parents,
   450                 &parents,
   455                 [(
   451                 [(
   456                     HgPathBuf::from_bytes(b"f1"),
   452                     HgPathBuf::from_bytes(b"f1"),
   457                     DirstateEntry {
   453                     DirstateEntry::from_v1_data(
   458                         state: EntryState::Normal,
   454                         EntryState::Normal,
   459                         mode: 0o644,
   455                         0o644,
   460                         size: 0,
   456                         0,
   461                         mtime: -1
   457                         -1
   462                     }
   458                     )
   463                 )]
   459                 )]
   464                 .iter()
   460                 .iter()
   465                 .cloned()
   461                 .cloned()
   466                 .collect::<StateMap>(),
   462                 .collect::<StateMap>(),
   467                 copymap,
   463                 copymap,