Switch jgit library to the EDL (3-clause BSD)
[jgit.git] / org.spearce.jgit / src / org / spearce / jgit / lib / WindowCursor.java
blob0f4dab99d5ff722b13500690de54a3cd0f336f8c
1 /*
2 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
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
21 * written permission.
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];
49 ByteWindow window;
51 Object handle;
53 /**
54 * Copy bytes from the window to a caller supplied buffer.
56 * @param provider
57 * the file the desired window is stored within.
58 * @param position
59 * position within the file to read from.
60 * @param dstbuf
61 * destination buffer to copy into.
62 * @param dstoff
63 * offset within <code>dstbuf</code> to start copying into.
64 * @param cnt
65 * number of bytes to copy. This value may exceed the number of
66 * bytes remaining in the window starting at offset
67 * <code>pos</code>.
68 * @return number of bytes actually copied; this may be less than
69 * <code>cnt</code> if <code>cnt</code> exceeded the number of
70 * bytes available.
71 * @throws IOException
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 WindowedFile provider, long position, final byte[] dstbuf,
76 int dstoff, final int cnt) throws IOException {
77 final long length = provider.length();
78 int need = cnt;
79 while (need > 0 && position < length) {
80 pin(provider, position);
81 final int r = window.copy(handle, position, dstbuf, dstoff, need);
82 position += r;
83 dstoff += r;
84 need -= r;
86 return cnt - need;
89 /**
90 * Pump bytes into the supplied inflater as input.
92 * @param provider
93 * the file the desired window is stored within.
94 * @param position
95 * position within the file to read from.
96 * @param dstbuf
97 * destination buffer the inflater should output decompressed
98 * data to.
99 * @param dstoff
100 * current offset within <code>dstbuf</code> to inflate into.
101 * @param inf
102 * the inflater to feed input to. The caller is responsible for
103 * initializing the inflater as multiple windows may need to
104 * supply data to the same inflater to completely decompress
105 * something.
106 * @return updated <code>dstoff</code> based on the number of bytes
107 * successfully copied into <code>dstbuf</code> by
108 * <code>inf</code>. If the inflater is not yet finished then
109 * another window's data must still be supplied as input to finish
110 * decompression.
111 * @throws IOException
112 * this cursor does not match the provider or id and the proper
113 * window could not be acquired through the provider's cache.
114 * @throws DataFormatException
115 * the inflater encountered an invalid chunk of data. Data
116 * stream corruption is likely.
118 int inflate(final WindowedFile provider, long position,
119 final byte[] dstbuf, int dstoff, final Inflater inf)
120 throws IOException, DataFormatException {
121 for (;;) {
122 pin(provider, position);
123 dstoff = window.inflate(handle, position, dstbuf, dstoff, inf);
124 if (inf.finished())
125 return dstoff;
126 position = window.end;
130 private void pin(final WindowedFile provider, final long position)
131 throws IOException {
132 final ByteWindow w = window;
133 if (w == null || !w.contains(provider, position))
134 WindowCache.get(this, provider, position);
137 /** Release the current window cursor. */
138 public void release() {
139 window = null;
140 handle = null;