1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 module hunt.shiro.codec.CodecSupport; 20 21 import hunt.shiro.util.ByteSource; 22 23 import hunt.Exceptions; 24 25 /** 26 * Base abstract class that provides useful encoding and decoding operations, especially for character data. 27 * 28 * @since 0.9 29 */ 30 abstract class CodecSupport { 31 32 /** 33 * Shiro's default preferred character encoding, equal to <b><code>UTF-8</code></b>. 34 */ 35 enum string PREFERRED_ENCODING = "UTF-8"; 36 37 /** 38 * Converts the specified character array to a byte array using the Shiro's preferred encoding (UTF-8). 39 * <p/> 40 * This is a convenience method equivalent to calling the {@link #toBytes(String,String)} method with a 41 * a wrapping String and {@link CodecSupport#PREFERRED_ENCODING PREFERRED_ENCODING}, i.e. 42 * <p/> 43 * <code>toBytes( new String(chars), {@link CodecSupport#PREFERRED_ENCODING PREFERRED_ENCODING} );</code> 44 * 45 * @param chars the character array to be converted to a byte array. 46 * @return the byte array of the UTF-8 encoded character array. 47 */ 48 static byte[] toBytes(char[] chars) { 49 // return toBytes(new String(chars), PREFERRED_ENCODING); 50 return cast(byte[])chars; 51 } 52 53 // /** 54 // * Converts the specified character array into a byte array using the specified character encoding. 55 // * <p/> 56 // * This is a convenience method equivalent to calling the {@link #toBytes(String,String)} method with a 57 // * a wrapping String and the specified encoding, i.e. 58 // * <p/> 59 // * <code>toBytes( new String(chars), encoding );</code> 60 // * 61 // * @param chars the character array to be converted to a byte array 62 // * @param encoding the character encoding to use to when converting to bytes. 63 // * @return the bytes of the specified character array under the specified encoding. 64 // * @throws CodecException if the JVM does not support the specified encoding. 65 // */ 66 // static byte[] toBytes(char[] chars, String encoding) throws CodecException { 67 // return toBytes(new String(chars), encoding); 68 // } 69 70 // /** 71 // * Converts the specified source argument to a byte array with Shiro's 72 // * {@link CodecSupport#PREFERRED_ENCODING PREFERRED_ENCODING}. 73 // * 74 // * @param source the string to convert to a byte array. 75 // * @return the bytes representing the specified string under the {@link CodecSupport#PREFERRED_ENCODING PREFERRED_ENCODING}. 76 // * @see #toBytes(String, String) 77 // */ 78 // static byte[] toBytes(String source) { 79 // return toBytes(source, PREFERRED_ENCODING); 80 // } 81 82 // /** 83 // * Converts the specified source to a byte array via the specified encoding, throwing a 84 // * {@link CodecException CodecException} if the encoding fails. 85 // * 86 // * @param source the source string to convert to a byte array. 87 // * @param encoding the encoding to use to use. 88 // * @return the byte array of the specified source with the given encoding. 89 // * @throws CodecException if the JVM does not support the specified encoding. 90 // */ 91 // static byte[] toBytes(String source, String encoding) { 92 // try { 93 // return source.getBytes(encoding); 94 // } catch (UnsupportedEncodingException e) { 95 // String msg = "Unable to convert source [" ~ source ~ "] to byte array using " ~ 96 // "encoding '" ~ encoding ~ "'"; 97 // throw new CodecException(msg, e); 98 // } 99 // } 100 101 // /** 102 // * Converts the specified byte array to a String using the {@link CodecSupport#PREFERRED_ENCODING PREFERRED_ENCODING}. 103 // * 104 // * @param bytes the byte array to turn into a String. 105 // * @return the specified byte array as an encoded String ({@link CodecSupport#PREFERRED_ENCODING PREFERRED_ENCODING}). 106 // * @see #toString(byte[], String) 107 // */ 108 // static String toString(byte[] bytes) { 109 // return toString(bytes, PREFERRED_ENCODING); 110 // } 111 112 // /** 113 // * Converts the specified byte array to a String using the specified character encoding. This implementation 114 // * does the same thing as <code>new {@link String#String(byte[], String) String(byte[], encoding)}</code>, but will 115 // * wrap any {@link UnsupportedEncodingException} with a nicer runtime {@link CodecException}, allowing you to 116 // * decide whether or not you want to catch the exception or let it propagate. 117 // * 118 // * @param bytes the byte array to convert to a String 119 // * @param encoding the character encoding used to encode the String. 120 // * @return the specified byte array as an encoded String 121 // * @throws CodecException if the JVM does not support the specified encoding. 122 // */ 123 // static String toString(byte[] bytes, String encoding) throws CodecException { 124 // try { 125 // return new String(bytes, encoding); 126 // } catch (UnsupportedEncodingException e) { 127 // String msg = "Unable to convert byte array to String with encoding '" ~ encoding ~ "'."; 128 // throw new CodecException(msg, e); 129 // } 130 // } 131 132 // /** 133 // * Returns the specified byte array as a character array using the 134 // * {@link CodecSupport#PREFERRED_ENCODING PREFERRED_ENCODING}. 135 // * 136 // * @param bytes the byte array to convert to a char array 137 // * @return the specified byte array encoded as a character array ({@link CodecSupport#PREFERRED_ENCODING PREFERRED_ENCODING}). 138 // * @see #toChars(byte[], String) 139 // */ 140 // static char[] toChars(byte[] bytes) { 141 // return toChars(bytes, PREFERRED_ENCODING); 142 // } 143 144 // /** 145 // * Converts the specified byte array to a character array using the specified character encoding. 146 // * <p/> 147 // * Effectively calls <code>{@link #toString(byte[], String) toString(bytes,encoding)}.{@link String#toCharArray() toCharArray()};</code> 148 // * 149 // * @param bytes the byte array to convert to a String 150 // * @param encoding the character encoding used to encode the bytes. 151 // * @return the specified byte array as an encoded char array 152 // * @throws CodecException if the JVM does not support the specified encoding. 153 // */ 154 // static char[] toChars(byte[] bytes, String encoding) throws CodecException { 155 // return toString(bytes, encoding).toCharArray(); 156 // } 157 158 /** 159 * Returns {@code true} if the specified object can be easily converted to bytes by instances of this class, 160 * {@code false} otherwise. 161 * <p/> 162 * The default implementation returns {@code true} IFF the specified object is an instance of one of the following 163 * types: 164 * <ul> 165 * <li>{@code byte[]}</li> 166 * <li>{@code char[]}</li> 167 * <li>{@link ByteSource}</li> 168 * <li>{@link String}</li> 169 * <li>{@link File}</li> 170 * </li>{@link InputStream}</li> 171 * </ul> 172 * 173 * @param o the object to test to see if it can be easily converted to a byte array 174 * @return {@code true} if the specified object can be easily converted to bytes by instances of this class, 175 * {@code false} otherwise. 176 * @since 1.0 177 */ 178 protected bool isByteSource(Object o) { 179 ByteSource bs = cast(ByteSource)o; 180 if(bs !is null) 181 return true; 182 183 implementationMissing(false); 184 185 return false; 186 // return o instanceof byte[] || o instanceof char[] || o instanceof String || 187 // o instanceof ByteSource || o instanceof File || o instanceof InputStream; 188 } 189 190 /** 191 * Converts the specified Object into a byte array. 192 * <p/> 193 * If the argument is a {@code byte[]}, {@code char[]}, {@link ByteSource}, {@link String}, {@link File}, or 194 * {@link InputStream}, it will be converted automatically and returned.} 195 * <p/> 196 * If the argument is anything other than these types, it is passed to the 197 * {@link #objectToBytes(Object) objectToBytes} method which must be overridden by subclasses. 198 * 199 * @param o the Object to convert into a byte array 200 * @return a byte array representation of the Object argument. 201 */ 202 protected byte[] toBytes(Object o) { 203 if (o is null) { 204 string msg = "Argument for byte conversion cannot be null."; 205 throw new IllegalArgumentException(msg); 206 } 207 208 implementationMissing(false); 209 return null; 210 // if (o instanceof byte[]) { 211 // return (byte[]) o; 212 // } else if (o instanceof ByteSource) { 213 // return ((ByteSource) o).getBytes(); 214 // } else if (o instanceof char[]) { 215 // return toBytes((char[]) o); 216 // } else if (o instanceof String) { 217 // return toBytes((String) o); 218 // } else if (o instanceof File) { 219 // return toBytes((File) o); 220 // } else if (o instanceof InputStream) { 221 // return toBytes((InputStream) o); 222 // } else { 223 // return objectToBytes(o); 224 // } 225 } 226 227 // /** 228 // * Converts the specified Object into a String. 229 // * <p/> 230 // * If the argument is a {@code byte[]} or {@code char[]} it will be converted to a String using the 231 // * {@link #PREFERRED_ENCODING}. If a String, it will be returned as is. 232 // * <p/> 233 // * If the argument is anything other than these three types, it is passed to the 234 // * {@link #objectToString(Object) objectToString} method. 235 // * 236 // * @param o the Object to convert into a byte array 237 // * @return a byte array representation of the Object argument. 238 // */ 239 // protected String toString(Object o) { 240 // if (o is null) { 241 // String msg = "Argument for String conversion cannot be null."; 242 // throw new IllegalArgumentException(msg); 243 // } 244 // if (o instanceof byte[]) { 245 // return toString((byte[]) o); 246 // } else if (o instanceof char[]) { 247 // return new String((char[]) o); 248 // } else if (o instanceof String) { 249 // return (String) o; 250 // } else { 251 // return objectToString(o); 252 // } 253 // } 254 255 // protected byte[] toBytes(File file) { 256 // if (file is null) { 257 // throw new IllegalArgumentException("File argument cannot be null."); 258 // } 259 // try { 260 // return toBytes(new FileInputStream(file)); 261 // } catch (FileNotFoundException e) { 262 // String msg = "Unable to acquire InputStream for file [" ~ file ~ "]"; 263 // throw new CodecException(msg, e); 264 // } 265 // } 266 267 // /** 268 // * Converts the specified {@link InputStream InputStream} into a byte array. 269 // * 270 // * @param in the InputStream to convert to a byte array 271 // * @return the bytes of the input stream 272 // * @throws IllegalArgumentException if the {@code InputStream} argument is {@code null}. 273 // * @throws CodecException if there is any problem reading from the {@link InputStream}. 274 // * @since 1.0 275 // */ 276 // protected byte[] toBytes(InputStream in) { 277 // if (in is null) { 278 // throw new IllegalArgumentException("InputStream argument cannot be null."); 279 // } 280 // final int BUFFER_SIZE = 512; 281 // ByteArrayOutputStream out = new ByteArrayOutputStream(BUFFER_SIZE); 282 // byte[] buffer = new byte[BUFFER_SIZE]; 283 // int bytesRead; 284 // try { 285 // while ((bytesRead = in.read(buffer)) != -1) { 286 // out.write(buffer, 0, bytesRead); 287 // } 288 // return out.toByteArray(); 289 // } catch (IOException ioe) { 290 // throw new CodecException(ioe); 291 // } finally { 292 // try { 293 // in.close(); 294 // } catch (IOException ignored) { 295 // } 296 // try { 297 // out.close(); 298 // } catch (IOException ignored) { 299 // } 300 // } 301 // } 302 303 // /** 304 // * Default implementation throws a CodecException immediately since it can't infer how to convert the Object 305 // * to a byte array. This method must be overridden by subclasses if anything other than the three default 306 // * types (listed in the {@link #toBytes(Object) toBytes(Object)} JavaDoc) are to be converted to a byte array. 307 // * 308 // * @param o the Object to convert to a byte array. 309 // * @return a byte array representation of the Object argument. 310 // */ 311 // protected byte[] objectToBytes(Object o) { 312 // String msg = "The " ~ getClass().getName() ~ " implementation only supports conversion to " ~ 313 // "byte[] if the source is of type byte[], char[], String, " ~ ByteSource.class.getName() + 314 // " File or InputStream. The instance provided as a method " ~ 315 // "argument is of type [" ~ o.getClass().getName() ~ "]. If you would like to convert " ~ 316 // "this argument type to a byte[], you can 1) convert the argument to one of the supported types " ~ 317 // "yourself and then use that as the method argument or 2) subclass " ~ getClass().getName() + 318 // "and override the objectToBytes(Object o) method."; 319 // throw new CodecException(msg); 320 // } 321 322 // /** 323 // * Default implementation merely returns <code>objectArgument.toString()</code>. Subclasses can override this 324 // * method for different mechanisms of converting an object to a String. 325 // * 326 // * @param o the Object to convert to a byte array. 327 // * @return a String representation of the Object argument. 328 // */ 329 // protected String objectToString(Object o) { 330 // return o.toString(); 331 // } 332 }