001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: Base64Test.java 447277 2006-09-18 06:19:34Z jeremias $ */
019:
020: package org.apache.xmlgraphics.util.io;
021:
022: import java.io.File;
023: import java.io.PipedOutputStream;
024: import java.io.PipedInputStream;
025: import java.io.InputStream;
026: import java.io.OutputStream;
027: import java.io.IOException;
028:
029: import java.net.URL;
030:
031: import junit.framework.TestCase;
032:
033: /**
034: * This test validates that the Base64 encoder/decoders work properly.
035: *
036: * @author <a href="mailto:deweese@apache.org">Thomas DeWeese</a>
037: * @version $Id: Base64Test.java 447277 2006-09-18 06:19:34Z jeremias $
038: */
039: public class Base64Test extends TestCase {
040:
041: private void innerBase64Test(String action, URL in, URL ref)
042: throws Exception {
043: InputStream inIS = in.openStream();
044:
045: if (action.equals("ROUND"))
046: ref = in;
047: else if (!action.equals("ENCODE") && !action.equals("DECODE")) {
048: fail("Bad action string");
049: }
050:
051: InputStream refIS = ref.openStream();
052:
053: if (action.equals("ENCODE") || action.equals("ROUND")) {
054: // We need to encode the incomming data
055: PipedOutputStream pos = new PipedOutputStream();
056: OutputStream os = new Base64EncodeStream(pos);
057:
058: // Copy the input to the Base64 Encoder (in a seperate thread).
059: Thread t = new StreamCopier(inIS, os);
060:
061: // Read that from the piped output stream.
062: inIS = new PipedInputStream(pos);
063: t.start();
064: }
065:
066: if (action.equals("DECODE") || action.equals("ROUND")) {
067: inIS = new Base64DecodeStream(inIS);
068: }
069:
070: int mismatch = compareStreams(inIS, refIS, action
071: .equals("ENCODE"));
072:
073: if (mismatch != -1) {
074: fail("Wrong result");
075: }
076: }
077:
078: private void innerBase64Test(String action, String in, String ref)
079: throws Exception {
080: final String baseURL = "file:test/resources/org/apache/xmlgraphics/util/io/";
081: innerBase64Test(action, new URL(baseURL + in), new URL(baseURL
082: + ref));
083: }
084:
085: private void innerBase64Test(String in) throws Exception {
086: innerBase64Test("ROUND", in, in);
087: }
088:
089: private void testBase64Group(String name) throws Exception {
090: innerBase64Test("ENCODE", name, name + ".64");
091: innerBase64Test("DECODE", name + ".64", name);
092: innerBase64Test(name);
093: }
094:
095: /**
096: * This method will only throw exceptions if some aspect
097: * of the test's internal operation fails.
098: */
099: public void testBase64() throws Exception {
100: System.out.println(new File(".").getCanonicalPath());
101: testBase64Group("zeroByte");
102: testBase64Group("oneByte");
103: testBase64Group("twoByte");
104: testBase64Group("threeByte");
105: testBase64Group("fourByte");
106: testBase64Group("tenByte");
107: testBase64Group("small");
108: testBase64Group("medium");
109: innerBase64Test("DECODE", "medium.pc.64", "medium");
110: innerBase64Test("large");
111: }
112:
113: /**
114: * Returns true if the contents of <tt>is1</tt> match the
115: * contents of <tt>is2</tt>
116: */
117: public static int compareStreams(InputStream is1, InputStream is2,
118: boolean skipws) {
119: byte[] data1 = new byte[100];
120: byte[] data2 = new byte[100];
121: int off1 = 0;
122: int off2 = 0;
123: int idx = 0;
124:
125: try {
126: while (true) {
127: int len1 = is1.read(data1, off1, data1.length - off1);
128: int len2 = is2.read(data2, off2, data2.length - off2);
129:
130: if (off1 != 0) {
131: if (len1 == -1)
132: len1 = off1;
133: else
134: len1 += off1;
135: }
136:
137: if (off2 != 0) {
138: if (len2 == -1)
139: len2 = off2;
140: else
141: len2 += off2;
142: }
143:
144: if (len1 == -1) {
145: if (len2 == -1)
146: break; // Both done...
147:
148: // Only is1 is done...
149: if (!skipws)
150: return idx;
151:
152: // check if the rest of is2 is whitespace...
153: for (int i2 = 0; i2 < len2; i2++)
154: if ((data2[i2] != '\n') && (data2[i2] != '\r')
155: && (data2[i2] != ' '))
156: return idx + i2;
157: off1 = off2 = 0;
158: continue;
159: }
160:
161: if (len2 == -1) {
162: // Only is2 is done...
163: if (!skipws)
164: return idx;
165:
166: // Check if rest of is1 is whitespace...
167: for (int i1 = 0; i1 < len1; i1++)
168: if ((data1[i1] != '\n') && (data1[i1] != '\r')
169: && (data1[i1] != ' '))
170: return idx + i1;
171: off1 = off2 = 0;
172: continue;
173: }
174:
175: int i1 = 0;
176: int i2 = 0;
177: while ((i1 < len1) && (i2 < len2)) {
178: if (skipws) {
179: if ((data1[i1] == '\n') || (data1[i1] == '\r')
180: || (data1[i1] == ' ')) {
181: i1++;
182: continue;
183: }
184: if ((data2[i2] == '\n') || (data2[i2] == '\r')
185: || (data2[i2] == ' ')) {
186: i2++;
187: continue;
188: }
189: }
190: if (data1[i1] != data2[i2])
191: return idx + i2;
192:
193: i1++;
194: i2++;
195: }
196:
197: if (i1 != len1)
198: System.arraycopy(data1, i1, data1, 0, len1 - i1);
199: if (i2 != len2)
200: System.arraycopy(data2, i2, data2, 0, len2 - i2);
201: off1 = len1 - i1;
202: off2 = len2 - i2;
203: idx += i2;
204: }
205: } catch (IOException ioe) {
206: ioe.printStackTrace();
207: return idx;
208: }
209:
210: return -1;
211: }
212:
213: static class StreamCopier extends Thread {
214: InputStream src;
215: OutputStream dst;
216:
217: public StreamCopier(InputStream src, OutputStream dst) {
218: this .src = src;
219: this .dst = dst;
220: }
221:
222: public void run() {
223: try {
224: byte[] data = new byte[1000];
225: while (true) {
226: int len = src.read(data, 0, data.length);
227: if (len == -1)
228: break;
229:
230: dst.write(data, 0, len);
231: }
232: } catch (IOException ioe) {
233: // Nothing
234: }
235: try {
236: dst.close();
237: } catch (IOException ioe) {
238: // Nothing
239: }
240: }
241: }
242: }
|