1. /*
  2. * Copyright 2000,2002,2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. /*
  18. * This package is based on the work done by Timothy Gerard Endres
  19. * (time@ice.com) to whom the Ant project is very grateful for his great code.
  20. */
  21. package org.apache.tools.tar;
  22. /**
  23. * This class provides static utility methods to work with byte streams.
  24. *
  25. */
  26. public class TarUtils {
  27. /**
  28. * Parse an octal string from a header buffer. This is used for the
  29. * file permission mode value.
  30. *
  31. * @param header The header buffer from which to parse.
  32. * @param offset The offset into the buffer from which to parse.
  33. * @param length The number of header bytes to parse.
  34. * @return The long value of the octal string.
  35. */
  36. public static long parseOctal(byte[] header, int offset, int length) {
  37. long result = 0;
  38. boolean stillPadding = true;
  39. int end = offset + length;
  40. for (int i = offset; i < end; ++i) {
  41. if (header[i] == 0) {
  42. break;
  43. }
  44. if (header[i] == (byte) ' ' || header[i] == '0') {
  45. if (stillPadding) {
  46. continue;
  47. }
  48. if (header[i] == (byte) ' ') {
  49. break;
  50. }
  51. }
  52. stillPadding = false;
  53. result = (result << 3) + (header[i] - '0');
  54. }
  55. return result;
  56. }
  57. /**
  58. * Parse an entry name from a header buffer.
  59. *
  60. * @param header The header buffer from which to parse.
  61. * @param offset The offset into the buffer from which to parse.
  62. * @param length The number of header bytes to parse.
  63. * @return The header's entry name.
  64. */
  65. public static StringBuffer parseName(byte[] header, int offset, int length) {
  66. StringBuffer result = new StringBuffer(length);
  67. int end = offset + length;
  68. for (int i = offset; i < end; ++i) {
  69. if (header[i] == 0) {
  70. break;
  71. }
  72. result.append((char) header[i]);
  73. }
  74. return result;
  75. }
  76. /**
  77. * Determine the number of bytes in an entry name.
  78. *
  79. * @param name The header name from which to parse.
  80. * @param offset The offset into the buffer from which to parse.
  81. * @param length The number of header bytes to parse.
  82. * @return The number of bytes in a header's entry name.
  83. */
  84. public static int getNameBytes(StringBuffer name, byte[] buf, int offset, int length) {
  85. int i;
  86. for (i = 0; i < length && i < name.length(); ++i) {
  87. buf[offset + i] = (byte) name.charAt(i);
  88. }
  89. for (; i < length; ++i) {
  90. buf[offset + i] = 0;
  91. }
  92. return offset + length;
  93. }
  94. /**
  95. * Parse an octal integer from a header buffer.
  96. *
  97. * @param value The header value
  98. * @param offset The offset into the buffer from which to parse.
  99. * @param length The number of header bytes to parse.
  100. * @return The integer value of the octal bytes.
  101. */
  102. public static int getOctalBytes(long value, byte[] buf, int offset, int length) {
  103. int idx = length - 1;
  104. buf[offset + idx] = 0;
  105. --idx;
  106. buf[offset + idx] = (byte) ' ';
  107. --idx;
  108. if (value == 0) {
  109. buf[offset + idx] = (byte) '0';
  110. --idx;
  111. } else {
  112. for (long val = value; idx >= 0 && val > 0; --idx) {
  113. buf[offset + idx] = (byte) ((byte) '0' + (byte) (val & 7));
  114. val = val >> 3;
  115. }
  116. }
  117. for (; idx >= 0; --idx) {
  118. buf[offset + idx] = (byte) ' ';
  119. }
  120. return offset + length;
  121. }
  122. /**
  123. * Parse an octal long integer from a header buffer.
  124. *
  125. * @param value The header value
  126. * @param offset The offset into the buffer from which to parse.
  127. * @param length The number of header bytes to parse.
  128. * @return The long value of the octal bytes.
  129. */
  130. public static int getLongOctalBytes(long value, byte[] buf, int offset, int length) {
  131. byte[] temp = new byte[length + 1];
  132. getOctalBytes(value, temp, 0, length + 1);
  133. System.arraycopy(temp, 0, buf, offset, length);
  134. return offset + length;
  135. }
  136. /**
  137. * Parse the checksum octal integer from a header buffer.
  138. *
  139. * @param value The header value
  140. * @param offset The offset into the buffer from which to parse.
  141. * @param length The number of header bytes to parse.
  142. * @return The integer value of the entry's checksum.
  143. */
  144. public static int getCheckSumOctalBytes(long value, byte[] buf, int offset, int length) {
  145. getOctalBytes(value, buf, offset, length);
  146. buf[offset + length - 1] = (byte) ' ';
  147. buf[offset + length - 2] = 0;
  148. return offset + length;
  149. }
  150. /**
  151. * Compute the checksum of a tar entry header.
  152. *
  153. * @param buf The tar entry's header buffer.
  154. * @return The computed checksum.
  155. */
  156. public static long computeCheckSum(byte[] buf) {
  157. long sum = 0;
  158. for (int i = 0; i < buf.length; ++i) {
  159. sum += 255 & buf[i];
  160. }
  161. return sum;
  162. }
  163. }