View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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 }