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 }