You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

UUEncoder.java 4.8 kB

11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. */
  18. package org.apache.tools.ant.util;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.OutputStream;
  22. import java.io.PrintStream;
  23. /**
  24. * UUEncoding of an input stream placed into an OutputStream.
  25. * This class is meant to be a drop in replacement for
  26. * sun.misc.UUEncoder, which was previously used by Ant.
  27. * The uuencode algorithm code has been copied from the
  28. * geronimo project.
  29. **/
  30. public class UUEncoder {
  31. protected static final int DEFAULT_MODE = 644;
  32. private static final int MAX_CHARS_PER_LINE = 45;
  33. private static final int INPUT_BUFFER_SIZE = MAX_CHARS_PER_LINE * 100;
  34. private OutputStream out;
  35. private String name;
  36. /**
  37. * Constructor specifying a name for the encoded buffer, begin
  38. * line will be:
  39. * <pre>
  40. * begin 644 [NAME]
  41. * </pre>
  42. * @param name the name of the encoded buffer.
  43. */
  44. public UUEncoder(String name) {
  45. this.name = name;
  46. }
  47. /**
  48. * UUEncode bytes from the input stream, and write them as text characters
  49. * to the output stream. This method will run until it exhausts the
  50. * input stream.
  51. * @param is the input stream.
  52. * @param out the output stream.
  53. * @throws IOException if there is an error.
  54. */
  55. public void encode(InputStream is, OutputStream out)
  56. throws IOException {
  57. this.out = out;
  58. encodeBegin();
  59. byte[] buffer = new byte[INPUT_BUFFER_SIZE];
  60. int count;
  61. while ((count = is.read(buffer, 0, buffer.length)) != -1) {
  62. int pos = 0;
  63. while (count > 0) {
  64. int num = count > MAX_CHARS_PER_LINE
  65. ? MAX_CHARS_PER_LINE
  66. : count;
  67. encodeLine(buffer, pos, num, out);
  68. pos += num;
  69. count -= num;
  70. }
  71. }
  72. out.flush();
  73. encodeEnd();
  74. }
  75. /**
  76. * Encode a string to the output.
  77. */
  78. private void encodeString(String n) {
  79. PrintStream writer = new PrintStream(out);
  80. writer.print(n);
  81. writer.flush();
  82. }
  83. private void encodeBegin() {
  84. encodeString("begin " + DEFAULT_MODE + " " + name + "\n");
  85. }
  86. private void encodeEnd() {
  87. encodeString(" \nend\n");
  88. }
  89. /**
  90. * Encode a single line of data (less than or equal to 45 characters).
  91. *
  92. * @param data The array of byte data.
  93. * @param offset The starting offset within the data.
  94. * @param length Length of the data to encode.
  95. * @param out The output stream the encoded data is written to.
  96. * @exception IOException if something goes wrong
  97. */
  98. private void encodeLine(
  99. byte[] data, int offset, int length, OutputStream out)
  100. throws IOException {
  101. // write out the number of characters encoded in this line.
  102. // CheckStyle:MagicNumber OFF
  103. out.write((byte) ((length & 0x3F) + ' '));
  104. // CheckStyle:MagicNumber ON
  105. byte a;
  106. byte b;
  107. byte c;
  108. for (int i = 0; i < length;) {
  109. // set the padding defaults
  110. b = 1;
  111. c = 1;
  112. // get the next 3 bytes (if we have them)
  113. a = data[offset + i++];
  114. if (i < length) {
  115. b = data[offset + i++];
  116. if (i < length) {
  117. c = data[offset + i++];
  118. }
  119. }
  120. // CheckStyle:MagicNumber OFF
  121. byte d1 = (byte) (((a >>> 2) & 0x3F) + ' ');
  122. byte d2 = (byte) ((((a << 4) & 0x30) | ((b >>> 4) & 0x0F)) + ' ');
  123. byte d3 = (byte) ((((b << 2) & 0x3C) | ((c >>> 6) & 0x3)) + ' ');
  124. byte d4 = (byte) ((c & 0x3F) + ' ');
  125. // CheckStyle:MagicNumber ON
  126. out.write(d1);
  127. out.write(d2);
  128. out.write(d3);
  129. out.write(d4);
  130. }
  131. // terminate with a linefeed alone
  132. out.write('\n');
  133. }
  134. }