2
This code is derived from jgit (http://eclipse.org/jgit).
3
Copyright owners are documented in jgit's IP log.
5
This program and the accompanying materials are made available
6
under the terms of the Eclipse Distribution License v1.0 which
7
accompanies this distribution, is reproduced below, and is
8
available at http://www.eclipse.org/org/documents/edl-v10.php
12
Redistribution and use in source and binary forms, with or
13
without modification, are permitted provided that the following
16
- Redistributions of source code must retain the above copyright
17
notice, this list of conditions and the following disclaimer.
19
- Redistributions in binary form must reproduce the above
20
copyright notice, this list of conditions and the following
21
disclaimer in the documentation and/or other materials provided
22
with the distribution.
24
- Neither the name of the Eclipse Foundation, Inc. nor the
25
names of its contributors may be used to endorse or promote
26
products derived from this software without specific prior
29
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
using System.Collections.Generic;
49
using NGit.Storage.File;
54
namespace NGit.Transport
56
/// <summary>Fetch connection for bundle based classes.</summary>
58
/// Fetch connection for bundle based classes. It used by
60
/// <see cref="TransportBundle">TransportBundle</see>
62
internal class BundleFetchConnection : BaseFetchConnection
64
private readonly NGit.Transport.Transport transport;
66
internal InputStream bin;
68
internal readonly IDictionary<ObjectId, string> prereqs = new Dictionary<ObjectId
71
private string lockMessage;
73
private PackLock packLock;
75
/// <exception cref="NGit.Errors.TransportException"></exception>
76
internal BundleFetchConnection(NGit.Transport.Transport transportBundle, InputStream
79
transport = transportBundle;
80
bin = new BufferedInputStream(src);
83
switch (ReadSignature())
93
throw new TransportException(transport.uri, JGitText.Get().notABundle);
97
catch (TransportException err)
102
catch (IOException err)
105
throw new TransportException(transport.uri, err.Message, err);
107
catch (RuntimeException err)
110
throw new TransportException(transport.uri, err.Message, err);
114
/// <exception cref="System.IO.IOException"></exception>
115
private int ReadSignature()
117
string rev = ReadLine(new byte[1024]);
118
if (NGit.Transport.TransportBundleConstants.V2_BUNDLE_SIGNATURE.Equals(rev))
122
throw new TransportException(transport.uri, JGitText.Get().notABundle);
125
/// <exception cref="System.IO.IOException"></exception>
126
private void ReadBundleV2()
128
byte[] hdrbuf = new byte[1024];
129
LinkedHashMap<string, Ref> avail = new LinkedHashMap<string, Ref>();
132
string line = ReadLine(hdrbuf);
133
if (line.Length == 0)
139
ObjectId id = ObjectId.FromString(Sharpen.Runtime.Substring(line, 1, 41));
140
string shortDesc = null;
141
if (line.Length > 42)
143
shortDesc = Sharpen.Runtime.Substring(line, 42);
145
prereqs.Put(id, shortDesc);
148
string name = Sharpen.Runtime.Substring(line, 41, line.Length);
149
ObjectId id_1 = ObjectId.FromString(Sharpen.Runtime.Substring(line, 0, 40));
150
Ref prior = avail.Put(name, new ObjectIdRef.Unpeeled(RefStorage.NETWORK, name, id_1
154
throw DuplicateAdvertisement(name);
160
private PackProtocolException DuplicateAdvertisement(string name)
162
return new PackProtocolException(transport.uri, MessageFormat.Format(JGitText.Get
163
().duplicateAdvertisementsOf, name));
166
/// <exception cref="System.IO.IOException"></exception>
167
private string ReadLine(byte[] hdrbuf)
169
bin.Mark(hdrbuf.Length);
170
int cnt = bin.Read(hdrbuf);
172
while (lf < cnt && hdrbuf[lf] != '\n')
177
IOUtil.SkipFully(bin, lf);
178
if (lf < cnt && hdrbuf[lf] == '\n')
180
IOUtil.SkipFully(bin, 1);
182
return RawParseUtils.Decode(Constants.CHARSET, hdrbuf, 0, lf);
185
public override bool DidFetchTestConnectivity()
190
/// <exception cref="NGit.Errors.TransportException"></exception>
191
protected internal override void DoFetch(ProgressMonitor monitor, ICollection<Ref
192
> want, ICollection<ObjectId> have)
194
VerifyPrerequisites();
197
ObjectInserter ins = transport.local.NewObjectInserter();
200
PackParser parser = ins.NewPackParser(bin);
201
parser.SetAllowThin(true);
202
parser.SetObjectChecking(transport.IsCheckFetchedObjects());
203
parser.SetLockMessage(lockMessage);
204
packLock = parser.Parse(NullProgressMonitor.INSTANCE);
212
catch (IOException err)
215
throw new TransportException(transport.uri, err.Message, err);
217
catch (RuntimeException err)
220
throw new TransportException(transport.uri, err.Message, err);
224
public override void SetPackLockMessage(string message)
226
lockMessage = message;
229
public override ICollection<PackLock> GetPackLocks()
231
if (packLock != null)
233
return Sharpen.Collections.Singleton(packLock);
235
return Sharpen.Collections.EmptyList<PackLock>();
238
/// <exception cref="NGit.Errors.TransportException"></exception>
239
private void VerifyPrerequisites()
241
if (prereqs.IsEmpty())
245
RevWalk rw = new RevWalk(transport.local);
248
RevFlag PREREQ = rw.NewFlag("PREREQ");
249
RevFlag SEEN = rw.NewFlag("SEEN");
250
IDictionary<ObjectId, string> missing = new Dictionary<ObjectId, string>();
251
IList<RevObject> commits = new AList<RevObject>();
252
foreach (KeyValuePair<ObjectId, string> e in prereqs.EntrySet())
257
RevCommit c = rw.ParseCommit(p);
264
catch (MissingObjectException)
266
missing.Put(p, e.Value);
268
catch (IOException err)
270
throw new TransportException(transport.uri, MessageFormat.Format(JGitText.Get().cannotReadCommit
274
if (!missing.IsEmpty())
276
throw new MissingBundlePrerequisiteException(transport.uri, missing);
278
foreach (Ref r in transport.local.GetAllRefs().Values)
282
rw.MarkStart(rw.ParseCommit(r.GetObjectId()));
288
// If we cannot read the value of the ref skip it.
289
int remaining = commits.Count;
293
while ((c = rw.Next()) != null)
298
if (--remaining == 0)
305
catch (IOException err)
307
throw new TransportException(transport.uri, JGitText.Get().cannotReadObject, err);
311
foreach (RevObject o in commits)
315
missing.Put(o, prereqs.Get(o));
318
throw new MissingBundlePrerequisiteException(transport.uri, missing);
327
public override void Close()
340
// Ignore close failures.