2 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * - Neither the name of the Git Development Community nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 package org
.spearce
.jgit
.lib
;
40 import java
.io
.IOException
;
41 import java
.util
.zip
.DataFormatException
;
42 import java
.util
.zip
.Inflater
;
44 /** Active handle to a ByteWindow. */
45 public final class WindowCursor
{
46 /** Temporary buffer large enough for at least one raw object id. */
47 final byte[] tempId
= new byte[Constants
.OBJECT_ID_LENGTH
];
51 private ByteWindow window
;
54 * Copy bytes from the window to a caller supplied buffer.
57 * the file the desired window is stored within.
59 * position within the file to read from.
61 * destination buffer to copy into.
63 * offset within <code>dstbuf</code> to start copying into.
65 * number of bytes to copy. This value may exceed the number of
66 * bytes remaining in the window starting at offset
68 * @return number of bytes actually copied; this may be less than
69 * <code>cnt</code> if <code>cnt</code> exceeded the number of
72 * this cursor does not match the provider or id and the proper
73 * window could not be acquired through the provider's cache.
75 int copy(final PackFile pack
, long position
, final byte[] dstbuf
,
76 int dstoff
, final int cnt
) throws IOException
{
77 final long length
= pack
.length
;
79 while (need
> 0 && position
< length
) {
81 final int r
= window
.copy(position
, dstbuf
, dstoff
, need
);
90 * Pump bytes into the supplied inflater as input.
93 * the file the desired window is stored within.
95 * position within the file to read from.
97 * destination buffer the inflater should output decompressed
100 * current offset within <code>dstbuf</code> to inflate into.
101 * @return updated <code>dstoff</code> based on the number of bytes
102 * successfully inflated into <code>dstbuf</code>.
103 * @throws IOException
104 * this cursor does not match the provider or id and the proper
105 * window could not be acquired through the provider's cache.
106 * @throws DataFormatException
107 * the inflater encountered an invalid chunk of data. Data
108 * stream corruption is likely.
110 int inflate(final PackFile pack
, long position
, final byte[] dstbuf
,
111 int dstoff
) throws IOException
, DataFormatException
{
113 inf
= InflaterCache
.get();
118 dstoff
= window
.inflate(position
, dstbuf
, dstoff
, inf
);
121 position
= window
.end
;
125 void inflateVerify(final PackFile pack
, long position
)
126 throws IOException
, DataFormatException
{
128 inf
= InflaterCache
.get();
133 window
.inflateVerify(position
, inf
);
136 position
= window
.end
;
140 private void pin(final PackFile pack
, final long position
)
142 final ByteWindow w
= window
;
143 if (w
== null || !w
.contains(pack
, position
)) {
144 // If memory is low, we may need what is in our window field to
145 // be cleaned up by the GC during the get for the next window.
146 // So we always clear it, even though we are just going to set
150 window
= WindowCache
.get(pack
, position
);
154 /** Release the current window cursor. */
155 public void release() {
158 InflaterCache
.release(inf
);
165 * @param curs cursor to release; may be null.
166 * @return always null.
168 public static WindowCursor
release(final WindowCursor curs
) {