~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/NGit/NGit/ObjectInserter.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
This code is derived from jgit (http://eclipse.org/jgit).
 
3
Copyright owners are documented in jgit's IP log.
 
4
 
 
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
 
9
 
 
10
All rights reserved.
 
11
 
 
12
Redistribution and use in source and binary forms, with or
 
13
without modification, are permitted provided that the following
 
14
conditions are met:
 
15
 
 
16
- Redistributions of source code must retain the above copyright
 
17
  notice, this list of conditions and the following disclaimer.
 
18
 
 
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.
 
23
 
 
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
 
27
  written permission.
 
28
 
 
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.
 
42
*/
 
43
 
 
44
using System;
 
45
using NGit;
 
46
using NGit.Transport;
 
47
using Sharpen;
 
48
 
 
49
namespace NGit
 
50
{
 
51
        /// <summary>
 
52
        /// Inserts objects into an existing
 
53
        /// <code>ObjectDatabase</code>
 
54
        /// .
 
55
        /// <p>
 
56
        /// An inserter is not thread-safe. Individual threads should each obtain their
 
57
        /// own unique inserter instance, or must arrange for locking at a higher level
 
58
        /// to ensure the inserter is in use by no more than one thread at a time.
 
59
        /// <p>
 
60
        /// Objects written by an inserter may not be immediately visible for reading
 
61
        /// after the insert method completes. Callers must invoke either
 
62
        /// <see cref="Release()">Release()</see>
 
63
        /// or
 
64
        /// <see cref="Flush()">Flush()</see>
 
65
        /// prior to updating references or
 
66
        /// otherwise making the returned ObjectIds visible to other code.
 
67
        /// </summary>
 
68
        public abstract class ObjectInserter
 
69
        {
 
70
                /// <summary>An inserter that can be used for formatting and id generation only.</summary>
 
71
                /// <remarks>An inserter that can be used for formatting and id generation only.</remarks>
 
72
                public class Formatter : ObjectInserter
 
73
                {
 
74
                        /// <exception cref="System.IO.IOException"></exception>
 
75
                        public override ObjectId Insert(int objectType, long length, InputStream @in)
 
76
                        {
 
77
                                throw new NotSupportedException();
 
78
                        }
 
79
 
 
80
                        /// <exception cref="System.IO.IOException"></exception>
 
81
                        public override PackParser NewPackParser(InputStream @in)
 
82
                        {
 
83
                                throw new NotSupportedException();
 
84
                        }
 
85
 
 
86
                        /// <exception cref="System.IO.IOException"></exception>
 
87
                        public override void Flush()
 
88
                        {
 
89
                        }
 
90
 
 
91
                        // Do nothing.
 
92
                        public override void Release()
 
93
                        {
 
94
                        }
 
95
                        // Do nothing.
 
96
                }
 
97
 
 
98
                /// <summary>Digest to compute the name of an object.</summary>
 
99
                /// <remarks>Digest to compute the name of an object.</remarks>
 
100
                private readonly MessageDigest digest;
 
101
 
 
102
                /// <summary>Temporary working buffer for streaming data through.</summary>
 
103
                /// <remarks>Temporary working buffer for streaming data through.</remarks>
 
104
                private byte[] tempBuffer;
 
105
 
 
106
                /// <summary>Create a new inserter for a database.</summary>
 
107
                /// <remarks>Create a new inserter for a database.</remarks>
 
108
                public ObjectInserter()
 
109
                {
 
110
                        digest = Constants.NewMessageDigest();
 
111
                }
 
112
 
 
113
                /// <returns>a temporary byte array for use by the caller.</returns>
 
114
                protected internal virtual byte[] Buffer()
 
115
                {
 
116
                        if (tempBuffer == null)
 
117
                        {
 
118
                                tempBuffer = new byte[8192];
 
119
                        }
 
120
                        return tempBuffer;
 
121
                }
 
122
 
 
123
                /// <returns>digest to help compute an ObjectId</returns>
 
124
                protected internal virtual MessageDigest Digest()
 
125
                {
 
126
                        digest.Reset();
 
127
                        return digest;
 
128
                }
 
129
 
 
130
                /// <summary>Compute the name of an object, without inserting it.</summary>
 
131
                /// <remarks>Compute the name of an object, without inserting it.</remarks>
 
132
                /// <param name="type">type code of the object to store.</param>
 
133
                /// <param name="data">complete content of the object.</param>
 
134
                /// <returns>the name of the object.</returns>
 
135
                public virtual ObjectId IdFor(int type, byte[] data)
 
136
                {
 
137
                        return IdFor(type, data, 0, data.Length);
 
138
                }
 
139
 
 
140
                /// <summary>Compute the name of an object, without inserting it.</summary>
 
141
                /// <remarks>Compute the name of an object, without inserting it.</remarks>
 
142
                /// <param name="type">type code of the object to store.</param>
 
143
                /// <param name="data">complete content of the object.</param>
 
144
                /// <param name="off">
 
145
                /// first position within
 
146
                /// <code>data</code>
 
147
                /// .
 
148
                /// </param>
 
149
                /// <param name="len">
 
150
                /// number of bytes to copy from
 
151
                /// <code>data</code>
 
152
                /// .
 
153
                /// </param>
 
154
                /// <returns>the name of the object.</returns>
 
155
                public virtual ObjectId IdFor(int type, byte[] data, int off, int len)
 
156
                {
 
157
                        MessageDigest md = Digest();
 
158
                        md.Update(Constants.EncodedTypeString(type));
 
159
                        md.Update(unchecked((byte)' '));
 
160
                        md.Update(Constants.EncodeASCII(len));
 
161
                        md.Update(unchecked((byte)0));
 
162
                        md.Update(data, off, len);
 
163
                        return ObjectId.FromRaw(md.Digest());
 
164
                }
 
165
 
 
166
                /// <summary>Compute the name of an object, without inserting it.</summary>
 
167
                /// <remarks>Compute the name of an object, without inserting it.</remarks>
 
168
                /// <param name="objectType">type code of the object to store.</param>
 
169
                /// <param name="length">
 
170
                /// number of bytes to scan from
 
171
                /// <code>in</code>
 
172
                /// .
 
173
                /// </param>
 
174
                /// <param name="in">
 
175
                /// stream providing the object content. The caller is responsible
 
176
                /// for closing the stream.
 
177
                /// </param>
 
178
                /// <returns>the name of the object.</returns>
 
179
                /// <exception cref="System.IO.IOException">the source stream could not be read.</exception>
 
180
                public virtual ObjectId IdFor(int objectType, long length, InputStream @in)
 
181
                {
 
182
                        MessageDigest md = Digest();
 
183
                        md.Update(Constants.EncodedTypeString(objectType));
 
184
                        md.Update(unchecked((byte)' '));
 
185
                        md.Update(Constants.EncodeASCII(length));
 
186
                        md.Update(unchecked((byte)0));
 
187
                        byte[] buf = Buffer();
 
188
                        while (length > 0)
 
189
                        {
 
190
                                int n = @in.Read(buf, 0, (int)Math.Min(length, buf.Length));
 
191
                                if (n < 0)
 
192
                                {
 
193
                                        throw new EOFException("Unexpected end of input");
 
194
                                }
 
195
                                md.Update(buf, 0, n);
 
196
                                length -= n;
 
197
                        }
 
198
                        return ObjectId.FromRaw(md.Digest());
 
199
                }
 
200
 
 
201
                /// <summary>Compute the ObjectId for the given tree without inserting it.</summary>
 
202
                /// <remarks>Compute the ObjectId for the given tree without inserting it.</remarks>
 
203
                /// <param name="formatter"></param>
 
204
                /// <returns>the computed ObjectId</returns>
 
205
                public virtual ObjectId IdFor(TreeFormatter formatter)
 
206
                {
 
207
                        return formatter.ComputeId(this);
 
208
                }
 
209
 
 
210
                /// <summary>Insert a single tree into the store, returning its unique name.</summary>
 
211
                /// <remarks>Insert a single tree into the store, returning its unique name.</remarks>
 
212
                /// <param name="formatter">the formatter containing the proposed tree's data.</param>
 
213
                /// <returns>the name of the tree object.</returns>
 
214
                /// <exception cref="System.IO.IOException">the object could not be stored.</exception>
 
215
                public ObjectId Insert(TreeFormatter formatter)
 
216
                {
 
217
                        // Delegate to the formatter, as then it can pass the raw internal
 
218
                        // buffer back to this inserter, avoiding unnecessary data copying.
 
219
                        //
 
220
                        return formatter.InsertTo(this);
 
221
                }
 
222
 
 
223
                /// <summary>Insert a single commit into the store, returning its unique name.</summary>
 
224
                /// <remarks>Insert a single commit into the store, returning its unique name.</remarks>
 
225
                /// <param name="builder">the builder containing the proposed commit's data.</param>
 
226
                /// <returns>the name of the commit object.</returns>
 
227
                /// <exception cref="System.IO.IOException">the object could not be stored.</exception>
 
228
                public ObjectId Insert(NGit.CommitBuilder builder)
 
229
                {
 
230
                        return Insert(Constants.OBJ_COMMIT, builder.Build());
 
231
                }
 
232
 
 
233
                /// <summary>Insert a single annotated tag into the store, returning its unique name.
 
234
                ///     </summary>
 
235
                /// <remarks>Insert a single annotated tag into the store, returning its unique name.
 
236
                ///     </remarks>
 
237
                /// <param name="builder">the builder containing the proposed tag's data.</param>
 
238
                /// <returns>the name of the tag object.</returns>
 
239
                /// <exception cref="System.IO.IOException">the object could not be stored.</exception>
 
240
                public ObjectId Insert(TagBuilder builder)
 
241
                {
 
242
                        return Insert(Constants.OBJ_TAG, builder.Build());
 
243
                }
 
244
 
 
245
                /// <summary>Insert a single object into the store, returning its unique name.</summary>
 
246
                /// <remarks>Insert a single object into the store, returning its unique name.</remarks>
 
247
                /// <param name="type">type code of the object to store.</param>
 
248
                /// <param name="data">complete content of the object.</param>
 
249
                /// <returns>the name of the object.</returns>
 
250
                /// <exception cref="System.IO.IOException">the object could not be stored.</exception>
 
251
                public virtual ObjectId Insert(int type, byte[] data)
 
252
                {
 
253
                        return Insert(type, data, 0, data.Length);
 
254
                }
 
255
 
 
256
                /// <summary>Insert a single object into the store, returning its unique name.</summary>
 
257
                /// <remarks>Insert a single object into the store, returning its unique name.</remarks>
 
258
                /// <param name="type">type code of the object to store.</param>
 
259
                /// <param name="data">complete content of the object.</param>
 
260
                /// <param name="off">
 
261
                /// first position within
 
262
                /// <code>data</code>
 
263
                /// .
 
264
                /// </param>
 
265
                /// <param name="len">
 
266
                /// number of bytes to copy from
 
267
                /// <code>data</code>
 
268
                /// .
 
269
                /// </param>
 
270
                /// <returns>the name of the object.</returns>
 
271
                /// <exception cref="System.IO.IOException">the object could not be stored.</exception>
 
272
                public virtual ObjectId Insert(int type, byte[] data, int off, int len)
 
273
                {
 
274
                        return Insert(type, len, new ByteArrayInputStream(data, off, len));
 
275
                }
 
276
 
 
277
                /// <summary>Insert a single object into the store, returning its unique name.</summary>
 
278
                /// <remarks>Insert a single object into the store, returning its unique name.</remarks>
 
279
                /// <param name="objectType">type code of the object to store.</param>
 
280
                /// <param name="length">
 
281
                /// number of bytes to copy from
 
282
                /// <code>in</code>
 
283
                /// .
 
284
                /// </param>
 
285
                /// <param name="in">
 
286
                /// stream providing the object content. The caller is responsible
 
287
                /// for closing the stream.
 
288
                /// </param>
 
289
                /// <returns>the name of the object.</returns>
 
290
                /// <exception cref="System.IO.IOException">
 
291
                /// the object could not be stored, or the source stream could
 
292
                /// not be read.
 
293
                /// </exception>
 
294
                public abstract ObjectId Insert(int objectType, long length, InputStream @in);
 
295
 
 
296
                /// <summary>Initialize a parser to read from a pack formatted stream.</summary>
 
297
                /// <remarks>Initialize a parser to read from a pack formatted stream.</remarks>
 
298
                /// <param name="in">
 
299
                /// the input stream. The stream is not closed by the parser, and
 
300
                /// must instead be closed by the caller once parsing is complete.
 
301
                /// </param>
 
302
                /// <returns>the pack parser.</returns>
 
303
                /// <exception cref="System.IO.IOException">
 
304
                /// the parser instance, which can be configured and then used to
 
305
                /// parse objects into the ObjectDatabase.
 
306
                /// </exception>
 
307
                public abstract PackParser NewPackParser(InputStream @in);
 
308
 
 
309
                /// <summary>Make all inserted objects visible.</summary>
 
310
                /// <remarks>
 
311
                /// Make all inserted objects visible.
 
312
                /// <p>
 
313
                /// The flush may take some period of time to make the objects available to
 
314
                /// other threads.
 
315
                /// </remarks>
 
316
                /// <exception cref="System.IO.IOException">
 
317
                /// the flush could not be completed; objects inserted thus far
 
318
                /// are in an indeterminate state.
 
319
                /// </exception>
 
320
                public abstract void Flush();
 
321
 
 
322
                /// <summary>Release any resources used by this inserter.</summary>
 
323
                /// <remarks>
 
324
                /// Release any resources used by this inserter.
 
325
                /// <p>
 
326
                /// An inserter that has been released can be used again, but may need to be
 
327
                /// released after the subsequent usage.
 
328
                /// </remarks>
 
329
                public abstract void Release();
 
330
        }
 
331
}