comparison src/org/tmatesoft/hg/repo/HgDataFile.java @ 148:1a7a9a20e1f9

Exceptions, javadoc. Initial cancel and progress support
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 23 Feb 2011 22:36:28 +0100
parents 3959bffb14e9
children d5268ca7715b
comparison
equal deleted inserted replaced
147:a05145db4d0c 148:1a7a9a20e1f9
14 * the terms of a license other than GNU General Public License 14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com 15 * contact TMate Software at support@hg4j.com
16 */ 16 */
17 package org.tmatesoft.hg.repo; 17 package org.tmatesoft.hg.repo;
18 18
19 import static org.tmatesoft.hg.repo.HgInternals.wrongLocalRevision;
20 import static org.tmatesoft.hg.repo.HgRepository.*;
19 import static org.tmatesoft.hg.repo.HgRepository.TIP; 21 import static org.tmatesoft.hg.repo.HgRepository.TIP;
20 22 import static org.tmatesoft.hg.repo.HgRepository.WORKING_COPY;
23
24 import java.io.IOException;
21 import java.nio.ByteBuffer; 25 import java.nio.ByteBuffer;
22 import java.util.ArrayList; 26 import java.util.ArrayList;
23 import java.util.Collection; 27 import java.util.Collection;
24 import java.util.TreeMap; 28 import java.util.TreeMap;
25 29
30 import org.tmatesoft.hg.core.HgDataStreamException;
26 import org.tmatesoft.hg.core.Nodeid; 31 import org.tmatesoft.hg.core.Nodeid;
27 import org.tmatesoft.hg.internal.FilterByteChannel; 32 import org.tmatesoft.hg.internal.FilterByteChannel;
28 import org.tmatesoft.hg.internal.RevlogStream; 33 import org.tmatesoft.hg.internal.RevlogStream;
29 import org.tmatesoft.hg.util.ByteChannel; 34 import org.tmatesoft.hg.util.ByteChannel;
35 import org.tmatesoft.hg.util.CancelSupport;
36 import org.tmatesoft.hg.util.CancelledException;
30 import org.tmatesoft.hg.util.Path; 37 import org.tmatesoft.hg.util.Path;
38 import org.tmatesoft.hg.util.ProgressSupport;
31 39
32 40
33 41
34 /** 42 /**
35 * ? name:HgFileNode? 43 * ? name:HgFileNode?
73 public byte[] content() { 81 public byte[] content() {
74 return content(TIP); 82 return content(TIP);
75 } 83 }
76 84
77 /*XXX not sure applyFilters is the best way to do, perhaps, callers shall add filters themselves?*/ 85 /*XXX not sure applyFilters is the best way to do, perhaps, callers shall add filters themselves?*/
78 public void content(int revision, ByteChannel sink, boolean applyFilters) throws /*TODO typed*/Exception { 86 public void content(int revision, ByteChannel sink, boolean applyFilters) throws HgDataStreamException, IOException, CancelledException {
79 byte[] content = content(revision); 87 byte[] content = content(revision);
88 final CancelSupport cancelSupport = CancelSupport.Factory.get(sink);
89 final ProgressSupport progressSupport = ProgressSupport.Factory.get(sink);
80 ByteBuffer buf = ByteBuffer.allocate(512); 90 ByteBuffer buf = ByteBuffer.allocate(512);
81 int left = content.length; 91 int left = content.length;
92 progressSupport.start(left);
82 int offset = 0; 93 int offset = 0;
94 cancelSupport.checkCancelled();
83 ByteChannel _sink = applyFilters ? new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath())) : sink; 95 ByteChannel _sink = applyFilters ? new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath())) : sink;
84 do { 96 do {
85 buf.put(content, offset, Math.min(left, buf.remaining())); 97 buf.put(content, offset, Math.min(left, buf.remaining()));
86 buf.flip(); 98 buf.flip();
99 cancelSupport.checkCancelled();
87 // XXX I may not rely on returned number of bytes but track change in buf position instead. 100 // XXX I may not rely on returned number of bytes but track change in buf position instead.
88 int consumed = _sink.write(buf); 101 int consumed = _sink.write(buf);
89 buf.compact(); 102 buf.compact();
90 offset += consumed; 103 offset += consumed;
91 left -= consumed; 104 left -= consumed;
105 progressSupport.worked(consumed);
92 } while (left > 0); 106 } while (left > 0);
107 progressSupport.done(); // XXX shall specify whether #done() is invoked always or only if completed successfully.
93 } 108 }
94 109
95 // for data files need to check heading of the file content for possible metadata 110 // for data files need to check heading of the file content for possible metadata
96 // @see http://mercurial.selenic.com/wiki/FileFormats#data.2BAC8- 111 // @see http://mercurial.selenic.com/wiki/FileFormats#data.2BAC8-
97 @Override 112 @Override
98 public byte[] content(int revision) { 113 public byte[] content(int revision) {
99 if (revision == TIP) { 114 if (revision == TIP) {
100 revision = getLastRevision(); 115 revision = getLastRevision();
116 }
117 if (wrongLocalRevision(revision) || revision == BAD_REVISION || revision == WORKING_COPY) {
118 throw new IllegalArgumentException(String.valueOf(revision));
101 } 119 }
102 byte[] data = super.content(revision); 120 byte[] data = super.content(revision);
103 if (metadata == null) { 121 if (metadata == null) {
104 metadata = new Metadata(); 122 metadata = new Metadata();
105 } 123 }