sherman | 313292b | 2012-11-27 22:07:11 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. |
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | * |
| 5 | * This code is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of the GNU General Public License version 2 only, as |
| 7 | * published by the Free Software Foundation. |
| 8 | * |
| 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 12 | * version 2 for more details (a copy is included in the LICENSE file that |
| 13 | * accompanied this code). |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License version |
| 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
| 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| 18 | * |
| 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| 20 | * or visit www.oracle.com if you need additional information or have any |
| 21 | * questions. |
| 22 | */ |
| 23 | |
| 24 | /* |
| 25 | * @test 4235519 |
| 26 | * @author Eric Wang <yiming.wang@oracle.com> |
| 27 | * @summary tests java.util.Base64 |
| 28 | */ |
| 29 | |
| 30 | import java.io.BufferedReader; |
| 31 | import java.io.FileReader; |
| 32 | import java.nio.ByteBuffer; |
| 33 | import java.nio.charset.Charset; |
| 34 | import java.nio.charset.StandardCharsets; |
| 35 | import java.nio.file.Files; |
| 36 | import java.nio.file.Paths; |
| 37 | import java.util.Base64; |
| 38 | import java.util.Base64.Decoder; |
| 39 | import java.util.Base64.Encoder; |
| 40 | import java.util.Objects; |
| 41 | import java.util.Random; |
| 42 | |
| 43 | import sun.misc.BASE64Decoder; |
| 44 | import sun.misc.BASE64Encoder; |
| 45 | |
| 46 | public class TestBase64Golden { |
| 47 | |
| 48 | public static void main(String[] args) throws Exception { |
| 49 | test0(Base64Type.BASIC, Base64.getEncoder(), Base64.getDecoder(), |
| 50 | "plain.txt", "baseEncode.txt"); |
| 51 | |
| 52 | test0(Base64Type.URLSAFE, Base64.getUrlEncoder(), Base64.getUrlDecoder(), |
| 53 | "plain.txt", "urlEncode.txt"); |
| 54 | |
| 55 | test0(Base64Type.MIME, Base64.getMimeEncoder(), Base64.getMimeDecoder(), |
| 56 | "plain.txt", "mimeEncode.txt"); |
| 57 | test1(); |
| 58 | test2(); |
| 59 | } |
| 60 | |
| 61 | public static void test0(Base64Type type, Encoder encoder, Decoder decoder, |
| 62 | String srcFile, String encodedFile) throws Exception { |
| 63 | |
| 64 | String[] srcLns = Files.readAllLines(Paths.get(SRCDIR, srcFile), DEF_CHARSET) |
| 65 | .toArray(new String[0]); |
| 66 | String[] encodedLns = Files.readAllLines(Paths.get(SRCDIR, encodedFile), |
| 67 | DEF_CHARSET) |
| 68 | .toArray(new String[0]); |
| 69 | int lns = 0; |
| 70 | for (String srcStr : srcLns) { |
| 71 | String encodedStr = null; |
| 72 | if (type != Base64Type.MIME) { |
| 73 | encodedStr = encodedLns[lns++]; |
| 74 | } else { |
| 75 | while (lns < encodedLns.length) { |
| 76 | String s = encodedLns[lns++]; |
| 77 | if (s.length() == 0) |
| 78 | break; |
| 79 | if (encodedStr != null) { |
| 80 | encodedStr += DEFAULT_CRLF + s; |
| 81 | } else { |
| 82 | encodedStr = s; |
| 83 | } |
| 84 | } |
| 85 | if (encodedStr == null && srcStr.length() == 0) { |
| 86 | encodedStr = ""; |
| 87 | } |
| 88 | } |
| 89 | System.out.printf("%n src[%d]: %s%n", srcStr.length(), srcStr); |
| 90 | System.out.printf("encoded[%d]: %s%n", encodedStr.length(), encodedStr); |
| 91 | |
| 92 | byte[] srcArr = srcStr.getBytes(DEF_CHARSET); |
| 93 | byte[] encodedArr = encodedStr.getBytes(DEF_CHARSET); |
| 94 | |
| 95 | ByteBuffer srcBuf = ByteBuffer.wrap(srcArr); |
| 96 | ByteBuffer encodedBuf = ByteBuffer.wrap(encodedArr); |
| 97 | byte[] resArr = new byte[encodedArr.length]; |
| 98 | |
| 99 | // test int encode(byte[], byte[]) |
| 100 | int len = encoder.encode(srcArr, resArr); |
| 101 | assertEqual(len, encodedArr.length); |
| 102 | assertEqual(resArr, encodedArr); |
| 103 | |
| 104 | // test byte[] encode(byte[]) |
| 105 | resArr = encoder.encode(srcArr); |
| 106 | assertEqual(resArr, encodedArr); |
| 107 | |
| 108 | // test ByteBuffer encode(ByteBuffer) |
| 109 | int limit = srcBuf.limit(); |
| 110 | ByteBuffer resBuf = encoder.encode(srcBuf); |
| 111 | assertEqual(srcBuf.position(), limit); |
| 112 | assertEqual(srcBuf.limit(), limit); |
| 113 | assertEqual(resBuf, encodedBuf); |
| 114 | srcBuf.rewind(); // reset for next test |
| 115 | |
| 116 | // test encode(ByteBuffer, ByteBuffer, bytesOut) |
| 117 | resBuf.clear(); |
| 118 | len = encoder.encode(srcBuf, resBuf, 0); |
| 119 | assertEqual(len, encodedArr.length); |
| 120 | assertEqual(srcBuf.position(), limit); |
| 121 | assertEqual(srcBuf.limit(), limit); |
| 122 | assertEqual(resBuf.position(), len); |
| 123 | resBuf.flip(); |
| 124 | assertEqual(resBuf, encodedBuf); |
| 125 | srcBuf.rewind(); |
| 126 | |
| 127 | // test encode(ByteBuffer, ByteBuffer, bytesOut)[direct] |
| 128 | ByteBuffer resBuf_d = ByteBuffer.allocateDirect(encodedArr.length); |
| 129 | len = encoder.encode(srcBuf, resBuf_d, 0); |
| 130 | assertEqual(len, encodedArr.length); |
| 131 | assertEqual(srcBuf.position(), limit); |
| 132 | assertEqual(srcBuf.limit(), limit); |
| 133 | assertEqual(resBuf_d.position(), len); |
| 134 | resBuf_d.flip(); |
| 135 | assertEqual(resBuf_d, encodedBuf); |
| 136 | srcBuf.rewind(); |
| 137 | |
| 138 | // test String encodeToString(byte[]) |
| 139 | String resEncodeStr = encoder.encodeToString(srcArr); |
| 140 | assertEqual(resEncodeStr, encodedStr); |
| 141 | |
| 142 | // test int decode(byte[], byte[]) |
| 143 | resArr = new byte[srcArr.length]; |
| 144 | len = decoder.decode(encodedArr, resArr); |
| 145 | assertEqual(len, srcArr.length); |
| 146 | assertEqual(resArr, srcArr); |
| 147 | |
| 148 | // test byte[] decode(byte[]) |
| 149 | resArr = decoder.decode(encodedArr); |
| 150 | assertEqual(resArr, srcArr); |
| 151 | |
| 152 | // test ByteBuffer decode(ByteBuffer) |
| 153 | limit = encodedBuf.limit(); |
| 154 | resBuf = decoder.decode(encodedBuf); |
| 155 | assertEqual(encodedBuf.position(), limit); |
| 156 | assertEqual(encodedBuf.limit(), limit); |
| 157 | assertEqual(resBuf, srcBuf); |
| 158 | encodedBuf.rewind(); // reset for next test |
| 159 | |
| 160 | // test int decode(ByteBuffer, ByteBuffer) |
| 161 | resBuf.clear(); |
| 162 | len = decoder.decode(encodedBuf, resBuf); |
| 163 | assertEqual(len, srcArr.length); |
| 164 | assertEqual(encodedBuf.position(), limit); |
| 165 | assertEqual(encodedBuf.limit(), limit); |
| 166 | assertEqual(resBuf.position(), len); |
| 167 | resBuf.flip(); |
| 168 | assertEqual(resBuf, srcBuf); |
| 169 | encodedBuf.rewind(); // reset for next test |
| 170 | |
| 171 | // test int decode(ByteBuffer, ByteBuffer)[direct] |
| 172 | resBuf_d = ByteBuffer.allocateDirect(srcArr.length); |
| 173 | len = decoder.decode(encodedBuf, resBuf_d); |
| 174 | assertEqual(len, srcArr.length); |
| 175 | assertEqual(encodedBuf.position(), limit); |
| 176 | assertEqual(encodedBuf.limit(), limit); |
| 177 | assertEqual(resBuf_d.position(), len); |
| 178 | resBuf_d.flip(); |
| 179 | assertEqual(resBuf_d, srcBuf); |
| 180 | encodedBuf.rewind(); // reset for next test |
| 181 | |
| 182 | // test byte[] decode(String) |
| 183 | resArr = decoder.decode(encodedStr); |
| 184 | assertEqual(resArr, srcArr); |
| 185 | |
| 186 | // test compatible with sun.misc.Base64Encoder |
| 187 | if (type == Base64Type.MIME) { |
| 188 | sun.misc.BASE64Encoder miscEncoder = new BASE64Encoder(); |
| 189 | sun.misc.BASE64Decoder miscDecoder = new BASE64Decoder(); |
| 190 | resArr = decoder.decode(miscEncoder.encode(srcArr)); |
| 191 | assertEqual(resArr, srcArr); |
| 192 | |
| 193 | resArr = encoder.encode(miscDecoder.decodeBuffer(encodedStr)); |
| 194 | assertEqual(new String(resArr, DEF_CHARSET), encodedStr); |
| 195 | } |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | private static void test1() throws Exception { |
| 200 | byte[] src = new byte[6]; |
| 201 | new Random().nextBytes(src); |
| 202 | |
| 203 | ByteBuffer srcBuf = ByteBuffer.allocate(10); |
| 204 | srcBuf.position(2); |
| 205 | srcBuf.mark(); |
| 206 | srcBuf.limit(8); |
| 207 | srcBuf.put(src); |
| 208 | srcBuf.reset(); |
| 209 | |
| 210 | ByteBuffer dstBuf = ByteBuffer.allocate((src.length + 2) / 3 * 4); |
| 211 | Base64.getEncoder().encode(srcBuf, dstBuf, 0); |
| 212 | dstBuf.rewind(); |
| 213 | byte[] dst = new byte[dstBuf.limit()]; |
| 214 | dstBuf.get(dst); |
| 215 | System.out.printf("%n src[%d]: %s%n", src.length, new String(src)); |
| 216 | System.out.printf("encoded[%d]: %s%n", dst.length, new String(dst)); |
| 217 | assertEqual(src, Base64.getDecoder().decode(dst)); |
| 218 | |
| 219 | dstBuf = ByteBuffer.allocateDirect((src.length + 2) / 3 * 4); |
| 220 | srcBuf.reset(); |
| 221 | Base64.getEncoder().encode(srcBuf, dstBuf, 0); |
| 222 | dstBuf.rewind(); |
| 223 | dst = new byte[dstBuf.limit()]; |
| 224 | dstBuf.get(dst); |
| 225 | assertEqual(src, Base64.getDecoder().decode(dst)); |
| 226 | } |
| 227 | |
| 228 | private static void test2() throws Exception { |
| 229 | byte[] src = new byte[] { |
| 230 | 46, -97, -35, -44, 127, -60, -39, -4, -112, 34, -57, 47, -14, 67, |
| 231 | 40, 18, 90, -59, 68, 112, 23, 121, -91, 94, 35, 49, 104, 17, 30, |
| 232 | -80, -104, -3, -53, 27, 38, -72, -47, 113, -52, 18, 5, -126 }; |
sherman | c2273fa | 2013-10-24 11:12:59 -0700 | [diff] [blame] | 233 | Encoder encoder = Base64.getMimeEncoder(49, new byte[] { 0x7e }); |
sherman | 313292b | 2012-11-27 22:07:11 -0800 | [diff] [blame] | 234 | byte[] encoded = encoder.encode(src); |
| 235 | Decoder decoder = Base64.getMimeDecoder(); |
| 236 | byte[] decoded = decoder.decode(encoded); |
| 237 | if (!Objects.deepEquals(src, decoded)) { |
| 238 | throw new RuntimeException(); |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | // helper |
| 243 | enum Base64Type { |
| 244 | BASIC, URLSAFE, MIME |
| 245 | } |
| 246 | |
| 247 | private static final String SRCDIR = System.getProperty("test.src", "."); |
| 248 | private static final Charset DEF_CHARSET = StandardCharsets.US_ASCII; |
| 249 | private static final String DEF_EXCEPTION_MSG = |
| 250 | "Assertion failed! The result is not same as expected"; |
| 251 | private static final String DEFAULT_CRLF = "\r\n"; |
| 252 | |
| 253 | private static void assertEqual(Object result, Object expect) { |
| 254 | if (!Objects.deepEquals(result, expect)) { |
| 255 | String resultStr = result.toString(); |
| 256 | String expectStr = expect.toString(); |
| 257 | if (result instanceof byte[]) { |
| 258 | resultStr = new String((byte[]) result, DEF_CHARSET); |
| 259 | } |
| 260 | if (expect instanceof byte[]) { |
| 261 | expectStr = new String((byte[]) expect, DEF_CHARSET); |
| 262 | } |
| 263 | throw new RuntimeException(DEF_EXCEPTION_MSG + |
| 264 | " result: " + resultStr + " expected: " + expectStr); |
| 265 | } |
| 266 | } |
| 267 | } |