1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs.provider.tar;
18
19 /***
20 * This class provides static utility methods to work with byte streams.
21 *
22 * @author <a href="mailto:time@ice.com">Timothy Gerard Endres</a>
23 * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
24 * @version $Revision: 480428 $ $Date: 2006-11-29 07:15:24 +0100 (Mi, 29 Nov 2006) $
25 */
26 class TarUtils
27 {
28 /***
29 * Parse the checksum octal integer from a header buffer.
30 *
31 * @param offset The offset into the buffer from which to parse.
32 * @param length The number of header bytes to parse.
33 * @param value Description of Parameter
34 * @param buf Description of Parameter
35 * @return The integer value of the entry's checksum.
36 */
37 public static int getCheckSumOctalBytes( final long value,
38 final byte[] buf,
39 final int offset,
40 final int length )
41 {
42 getOctalBytes( value, buf, offset, length );
43
44 buf[ offset + length - 1 ] = (byte)' ';
45 buf[ offset + length - 2 ] = 0;
46
47 return offset + length;
48 }
49
50 /***
51 * Parse an octal long integer from a header buffer.
52 *
53 * @param offset The offset into the buffer from which to parse.
54 * @param length The number of header bytes to parse.
55 * @param value Description of Parameter
56 * @param buf Description of Parameter
57 * @return The long value of the octal bytes.
58 */
59 public static int getLongOctalBytes( final long value,
60 final byte[] buf,
61 final int offset,
62 final int length )
63 {
64 byte[] temp = new byte[ length + 1 ];
65
66 getOctalBytes( value, temp, 0, length + 1 );
67 System.arraycopy( temp, 0, buf, offset, length );
68
69 return offset + length;
70 }
71
72 /***
73 * Determine the number of bytes in an entry name.
74 *
75 * @param offset The offset into the buffer from which to parse.
76 * @param length The number of header bytes to parse.
77 * @param name Description of Parameter
78 * @param buffer Description of Parameter
79 * @return The number of bytes in a header's entry name.
80 */
81 public static int getNameBytes( final StringBuffer name,
82 final byte[] buffer,
83 final int offset,
84 final int length )
85 {
86 int i;
87
88 for( i = 0; i < length && i < name.length(); ++i )
89 {
90 buffer[ offset + i ] = (byte)name.charAt( i );
91 }
92
93 for( ; i < length; ++i )
94 {
95 buffer[ offset + i ] = 0;
96 }
97
98 return offset + length;
99 }
100
101 /***
102 * Parse an octal integer from a header buffer.
103 *
104 * @param offset The offset into the buffer from which to parse.
105 * @param length The number of header bytes to parse.
106 * @return The integer value of the octal bytes.
107 */
108 public static int getOctalBytes( final long value,
109 final byte[] buffer,
110 final int offset,
111 final int length )
112 {
113 int idx = length - 1;
114
115 buffer[ offset + idx ] = 0;
116 --idx;
117 buffer[ offset + idx ] = (byte)' ';
118 --idx;
119
120 if( value == 0 )
121 {
122 buffer[ offset + idx ] = (byte)'0';
123 --idx;
124 }
125 else
126 {
127 long val = value;
128 while( idx >= 0 && val > 0 )
129 {
130 buffer[ offset + idx ] = (byte)( (byte)'0' + (byte)( val & 7 ) );
131 val = val >> 3;
132 idx--;
133 }
134 }
135
136 while( idx >= 0 )
137 {
138 buffer[ offset + idx ] = (byte)' ';
139 idx--;
140 }
141
142 return offset + length;
143 }
144
145 /***
146 * Compute the checksum of a tar entry header.
147 *
148 * @param buffer The tar entry's header buffer.
149 * @return The computed checksum.
150 */
151 public static long computeCheckSum( final byte[] buffer )
152 {
153 long sum = 0;
154
155 for( int i = 0; i < buffer.length; ++i )
156 {
157 sum += 255 & buffer[ i ];
158 }
159
160 return sum;
161 }
162
163 /***
164 * Parse an entry name from a header buffer.
165 *
166 * @param header The header buffer from which to parse.
167 * @param offset The offset into the buffer from which to parse.
168 * @param length The number of header bytes to parse.
169 * @return The header's entry name.
170 */
171 public static StringBuffer parseName( final byte[] header,
172 final int offset,
173 final int length )
174 {
175 StringBuffer result = new StringBuffer( length );
176 int end = offset + length;
177
178 for( int i = offset; i < end; ++i )
179 {
180 if( header[ i ] == 0 )
181 {
182 break;
183 }
184
185 result.append( (char)header[ i ] );
186 }
187
188 return result;
189 }
190
191 /***
192 * Parse an octal string from a header buffer. This is used for the file
193 * permission mode value.
194 *
195 * @param header The header buffer from which to parse.
196 * @param offset The offset into the buffer from which to parse.
197 * @param length The number of header bytes to parse.
198 * @return The long value of the octal string.
199 */
200 public static long parseOctal( final byte[] header,
201 final int offset,
202 final int length )
203 {
204 long result = 0;
205 boolean stillPadding = true;
206 int end = offset + length;
207
208 for( int i = offset; i < end; ++i )
209 {
210 if( header[ i ] == 0 )
211 {
212 break;
213 }
214
215 if( header[ i ] == (byte)' ' || header[ i ] == '0' )
216 {
217 if( stillPadding )
218 {
219 continue;
220 }
221
222 if( header[ i ] == (byte)' ' )
223 {
224 break;
225 }
226 }
227
228 stillPadding = false;
229 result = ( result << 3 ) + ( header[ i ] - '0' );
230 }
231
232 return result;
233 }
234 }