comparison src/com/tmate/hgkit/ll/HgDirstate.java @ 10:382cfe9463db

Dirstate parsing. DataAccess refactored to allow reuse and control over constants
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Sat, 25 Dec 2010 21:50:12 +0100
parents
children d46773d89a19
comparison
equal deleted inserted replaced
9:d6d2a630f4a6 10:382cfe9463db
1 /*
2 * Copyright (c) 2010 Artem Tikhomirov
3 */
4 package com.tmate.hgkit.ll;
5
6 import java.io.File;
7 import java.io.IOException;
8 import java.util.Collections;
9 import java.util.Date;
10 import java.util.LinkedList;
11 import java.util.List;
12
13 import com.tmate.hgkit.fs.DataAccess;
14 import com.tmate.hgkit.fs.DataAccessProvider;
15
16 /**
17 * @see http://mercurial.selenic.com/wiki/DirState
18 * @see http://mercurial.selenic.com/wiki/FileFormats#dirstate
19 * @author artem
20 */
21 public class HgDirstate {
22
23 private final LocalHgRepo repo;
24 private final File dirstateFile;
25 private List<Record> normal;
26 private List<Record> added;
27 private List<Record> removed;
28 private List<Record> merged;
29
30 public HgDirstate(LocalHgRepo hgRepo, File dirstate) {
31 this.repo = hgRepo;
32 this.dirstateFile = dirstate;
33 }
34
35 private void read() {
36 normal = added = removed = merged = Collections.emptyList();
37 if (!dirstateFile.exists()) {
38 return;
39 }
40 DataAccessProvider dap = repo.getDataAccess();
41 DataAccess da = dap.create(dirstateFile);
42 if (da.isEmpty()) {
43 return;
44 }
45 normal = new LinkedList<Record>();
46 added = new LinkedList<Record>();
47 removed = new LinkedList<Record>();
48 merged = new LinkedList<Record>();
49 try {
50 // XXX skip(40) if we don't need these?
51 byte[] parents = new byte[40];
52 da.readBytes(parents, 0, 40);
53 parents = null;
54 do {
55 final byte state = da.readByte();
56 final int fmode = da.readInt();
57 final int size = da.readInt();
58 final int time = da.readInt();
59 final int nameLen = da.readInt();
60 String fn1 = null, fn2 = null;
61 byte[] name = new byte[nameLen];
62 da.readBytes(name, 0, nameLen);
63 for (int i = 0; i < nameLen; i++) {
64 if (name[i] == 0) {
65 fn1 = new String(name, 0, i);
66 fn2 = new String(name, i+1, nameLen);
67 break;
68 }
69 }
70 if (fn1 == null) {
71 fn1 = new String(name);
72 }
73 Record r = new Record(fmode, size, time, fn1, fn2);
74 if (state == 'n') {
75 normal.add(r);
76 } else if (state == 'a') {
77 added.add(r);
78 } else if (state == 'r') {
79 removed.add(r);
80 } else if (state == 'm') {
81 merged.add(r);
82 } else {
83 // FIXME log error?
84 }
85 } while (!da.isEmpty());
86 } catch (IOException ex) {
87 ex.printStackTrace(); // FIXME log error, clean dirstate?
88 } finally {
89 da.done();
90 }
91 }
92
93 public void dump() {
94 read();
95 @SuppressWarnings("unchecked")
96 List<Record>[] all = new List[] { normal, added, removed, merged };
97 char[] x = new char[] {'n', 'a', 'r', 'm' };
98 for (int i = 0; i < all.length; i++) {
99 for (Record r : all[i]) {
100 System.out.printf("%c %3o%6d %30tc\t\t%s", x[i], r.mode, r.size, (long) r.time, r.name1);
101 if (r.name2 != null) {
102 System.out.printf(" --> %s", r.name2);
103 }
104 System.out.println();
105 }
106 System.out.println();
107 }
108 }
109
110 private static class Record {
111 final int mode;
112 final int size;
113 final int time;
114 final String name1;
115 final String name2;
116
117 public Record(int fmode, int fsize, int ftime, String name1, String name2) {
118 mode = fmode;
119 size = fsize;
120 time = ftime;
121 this.name1 = name1;
122 this.name2 = name2;
123
124 }
125 }
126 }