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.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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.InputStream;
  20. import java.io.IOException;
  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 OutputStream out;
  34. private String name;
  35. /**
  36. * Constructor specifing a name for the encoded buffer, begin
  37. * line will be:
  38. * <pre>
  39. * begin 644 [NAME]
  40. * </pre>
  41. * @param name the name of the encoded buffer.
  42. */
  43. public UUEncoder(String name) {
  44. this.name = name;
  45. }
  46. /**
  47. * UUEncode bytes from the input stream, and write them as text characters
  48. * to the output stream. This method will run until it exhausts the
  49. * input stream.
  50. * @param is the input stream.
  51. * @param out the output stream.
  52. */
  53. public void encode(InputStream is, OutputStream out)
  54. throws IOException {
  55. this.out = out;
  56. encodeBegin();
  57. byte[] buffer = new byte[MAX_CHARS_PER_LINE * 100];
  58. int count;
  59. while ((count = is.read(buffer, 0, buffer.length)) != -1) {
  60. int pos = 0;
  61. while (count > 0) {
  62. int num = count > MAX_CHARS_PER_LINE
  63. ? MAX_CHARS_PER_LINE
  64. : count;
  65. encodeLine(buffer, pos, num, out);
  66. pos += num;
  67. count -= num;
  68. }
  69. }
  70. out.flush();
  71. encodeEnd();
  72. }
  73. /**
  74. * Encode a string to the output.
  75. */
  76. private void encodeString(String n) throws IOException {
  77. PrintStream writer = new PrintStream(out);
  78. writer.print(n);
  79. writer.flush();
  80. }
  81. private void encodeBegin() throws IOException {
  82. encodeString("begin " + DEFAULT_MODE + " " + name + "\n");
  83. }
  84. private void encodeEnd() throws IOException {
  85. encodeString(" \nend\n");
  86. }
  87. /**
  88. * Encode a single line of data (less than or equal to 45 characters).
  89. *
  90. * @param data The array of byte data.
  91. * @param off The starting offset within the data.
  92. * @param length Length of the data to encode.
  93. * @param out The output stream the encoded data is written to.
  94. *
  95. * @exception IOException
  96. */
  97. private void encodeLine(
  98. byte[] data, int offset, int length, OutputStream out)
  99. throws IOException {
  100. // write out the number of characters encoded in this line.
  101. out.write((byte)((length & 0x3F) + ' '));
  102. byte a;
  103. byte b;
  104. byte c;
  105. for (int i = 0; i < length;) {
  106. // set the padding defaults
  107. b = 1;
  108. c = 1;
  109. // get the next 3 bytes (if we have them)
  110. a = data[offset + i++];
  111. if (i < length) {
  112. b = data[offset + i++];
  113. if (i < length) {
  114. c = data[offset + i++];
  115. }
  116. }
  117. byte d1 = (byte)(((a >>> 2) & 0x3F) + ' ');
  118. byte d2 = (byte)(((( a << 4) & 0x30) | ((b >>> 4) & 0x0F)) + ' ');
  119. byte d3 = (byte)((((b << 2) & 0x3C) | ((c >>> 6) & 0x3)) + ' ');
  120. byte d4 = (byte)((c & 0x3F) + ' ');
  121. out.write(d1);
  122. out.write(d2);
  123. out.write(d3);
  124. out.write(d4);
  125. }
  126. // terminate with a linefeed alone
  127. out.write('\n');
  128. }
  129. }