1 /* 2 * Copyright (c) 1997, 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt.datatransfer; 27 28 import java.util.Enumeration; 29 import java.util.Hashtable; 30 import java.util.Iterator; 31 import java.util.Map; 32 import java.util.Set; 33 34 35 /** 36 * An object that encapsulates the parameter list of a MimeType 37 * as defined in RFC 2045 and 2046. 38 * 39 * @author jeff.dunn@eng.sun.com 40 */ 41 class MimeTypeParameterList implements Cloneable { 42 43 /** 44 * Default constructor. 45 */ 46 public MimeTypeParameterList() { 47 parameters = new Hashtable<>(); 48 } 49 50 public MimeTypeParameterList(String rawdata) 51 throws MimeTypeParseException 52 { 53 parameters = new Hashtable<>(); 54 55 // now parse rawdata 56 parse(rawdata); 57 } 58 59 public int hashCode() { 60 int code = Integer.MAX_VALUE/45; // "random" value for empty lists 61 String paramName = null; 62 Enumeration<String> enum_ = this.getNames(); 63 64 while (enum_.hasMoreElements()) { 65 paramName = enum_.nextElement(); 66 code += paramName.hashCode(); 67 code += this.get(paramName).hashCode(); 68 } 69 70 return code; 71 } // hashCode() 72 73 /** 74 * Two parameter lists are considered equal if they have exactly 75 * the same set of parameter names and associated values. The 76 * order of the parameters is not considered. 77 */ 78 public boolean equals(Object thatObject) { 79 //System.out.println("MimeTypeParameterList.equals("+this+","+thatObject+")"); 80 if (!(thatObject instanceof MimeTypeParameterList)) { 81 return false; 82 } 83 MimeTypeParameterList that = (MimeTypeParameterList)thatObject; 84 if (this.size() != that.size()) { 85 return false; 86 } 87 String name = null; 88 String thisValue = null; 89 String thatValue = null; 90 Set<Map.Entry<String, String>> entries = parameters.entrySet(); 91 Iterator<Map.Entry<String, String>> iterator = entries.iterator(); 92 Map.Entry<String, String> entry = null; 93 while (iterator.hasNext()) { 94 entry = iterator.next(); 95 name = entry.getKey(); 96 thisValue = entry.getValue(); 229 } 230 } 231 } 232 } 233 234 /** 235 * return the number of name-value pairs in this list. 236 */ 237 public int size() { 238 return parameters.size(); 239 } 240 241 /** 242 * Determine whether or not this list is empty. 243 */ 244 public boolean isEmpty() { 245 return parameters.isEmpty(); 246 } 247 248 /** 249 * Retrieve the value associated with the given name, or null if there 250 * is no current association. 251 */ 252 public String get(String name) { 253 return parameters.get(name.trim().toLowerCase()); 254 } 255 256 /** 257 * Set the value to be associated with the given name, replacing 258 * any previous association. 259 */ 260 public void set(String name, String value) { 261 parameters.put(name.trim().toLowerCase(), value); 262 } 263 264 /** 265 * Remove any value associated with the given name. 266 */ 267 public void remove(String name) { 268 parameters.remove(name.trim().toLowerCase()); 269 } 270 271 /** 272 * Retrieve an enumeration of all the names in this list. 273 */ 274 public Enumeration<String> getNames() { 275 return parameters.keys(); 276 } 277 278 public String toString() { 279 // Heuristic: 8 characters per field 280 StringBuilder buffer = new StringBuilder(parameters.size() * 16); 281 282 Enumeration<String> keys = parameters.keys(); 283 while(keys.hasMoreElements()) 284 { 285 buffer.append("; "); 286 287 String key = keys.nextElement(); 288 buffer.append(key); 289 buffer.append('='); 290 buffer.append(quote(parameters.get(key))); 291 } 292 293 return buffer.toString(); 294 } 295 296 /** 297 * @return a clone of this object 298 */ 299 @SuppressWarnings("unchecked") // Cast from clone 300 public Object clone() { 301 MimeTypeParameterList newObj = null; 302 try { 303 newObj = (MimeTypeParameterList)super.clone(); 304 } catch (CloneNotSupportedException cannotHappen) { 305 } 306 newObj.parameters = (Hashtable<String, String>)parameters.clone(); 307 return newObj; 308 } 309 310 private Hashtable<String, String> parameters; 311 312 // below here be scary parsing related things 313 314 /** 315 * Determine whether or not a given character belongs to a legal token. 316 */ 317 private static boolean isTokenChar(char c) { 318 return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0); 319 } 320 321 /** 322 * return the index of the first non white space character in 323 * rawdata at or after index i. 324 */ 325 private static int skipWhiteSpace(String rawdata, int i) { 326 int length = rawdata.length(); 327 if (i < length) { 328 char c = rawdata.charAt(i); 329 while ((i < length) && Character.isWhitespace(c)) { 330 ++i; 331 c = rawdata.charAt(i); 332 } 333 } 334 335 return i; 336 } 337 338 /** 339 * A routine that knows how and when to quote and escape the given value. 340 */ 341 private static String quote(String value) { 342 boolean needsQuotes = false; 343 357 for(int i = 0; i < length; ++i) { 358 char c = value.charAt(i); 359 if((c == '\\') || (c == '"')) { 360 buffer.append('\\'); 361 } 362 buffer.append(c); 363 } 364 365 // add the closing quote 366 buffer.append('"'); 367 368 return buffer.toString(); 369 } 370 else 371 { 372 return value; 373 } 374 } 375 376 /** 377 * A routine that knows how to strip the quotes and escape sequences from the given value. 378 */ 379 private static String unquote(String value) { 380 int valueLength = value.length(); 381 StringBuilder buffer = new StringBuilder(valueLength); 382 383 boolean escaped = false; 384 for(int i = 0; i < valueLength; ++i) { 385 char currentChar = value.charAt(i); 386 if(!escaped && (currentChar != '\\')) { 387 buffer.append(currentChar); 388 } else if(escaped) { 389 buffer.append(currentChar); 390 escaped = false; 391 } else { 392 escaped = true; 393 } 394 } 395 396 return buffer.toString(); 397 } 398 399 /** 400 * A string that holds all the special chars. 401 */ 402 private static final String TSPECIALS = "()<>@,;:\\\"/[]?="; 403 404 } | 1 /* 2 * Copyright (c) 1997, 2017, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt.datatransfer; 27 28 import java.util.Enumeration; 29 import java.util.Hashtable; 30 import java.util.Iterator; 31 import java.util.Map; 32 import java.util.Set; 33 34 /** 35 * An object that encapsulates the parameter list of a MimeType as defined in 36 * RFC 2045 and 2046. 37 * 38 * @author jeff.dunn@eng.sun.com 39 */ 40 class MimeTypeParameterList implements Cloneable { 41 42 /** 43 * Default constructor. 44 */ 45 public MimeTypeParameterList() { 46 parameters = new Hashtable<>(); 47 } 48 49 public MimeTypeParameterList(String rawdata) 50 throws MimeTypeParseException 51 { 52 parameters = new Hashtable<>(); 53 54 // now parse rawdata 55 parse(rawdata); 56 } 57 58 public int hashCode() { 59 int code = Integer.MAX_VALUE/45; // "random" value for empty lists 60 String paramName = null; 61 Enumeration<String> enum_ = this.getNames(); 62 63 while (enum_.hasMoreElements()) { 64 paramName = enum_.nextElement(); 65 code += paramName.hashCode(); 66 code += this.get(paramName).hashCode(); 67 } 68 69 return code; 70 } // hashCode() 71 72 /** 73 * Two parameter lists are considered equal if they have exactly the same 74 * set of parameter names and associated values. The order of the parameters 75 * is not considered. 76 */ 77 public boolean equals(Object thatObject) { 78 //System.out.println("MimeTypeParameterList.equals("+this+","+thatObject+")"); 79 if (!(thatObject instanceof MimeTypeParameterList)) { 80 return false; 81 } 82 MimeTypeParameterList that = (MimeTypeParameterList)thatObject; 83 if (this.size() != that.size()) { 84 return false; 85 } 86 String name = null; 87 String thisValue = null; 88 String thatValue = null; 89 Set<Map.Entry<String, String>> entries = parameters.entrySet(); 90 Iterator<Map.Entry<String, String>> iterator = entries.iterator(); 91 Map.Entry<String, String> entry = null; 92 while (iterator.hasNext()) { 93 entry = iterator.next(); 94 name = entry.getKey(); 95 thisValue = entry.getValue(); 228 } 229 } 230 } 231 } 232 233 /** 234 * return the number of name-value pairs in this list. 235 */ 236 public int size() { 237 return parameters.size(); 238 } 239 240 /** 241 * Determine whether or not this list is empty. 242 */ 243 public boolean isEmpty() { 244 return parameters.isEmpty(); 245 } 246 247 /** 248 * Retrieve the value associated with the given name, or {@code null} if 249 * there is no current association. 250 */ 251 public String get(String name) { 252 return parameters.get(name.trim().toLowerCase()); 253 } 254 255 /** 256 * Set the value to be associated with the given name, replacing any 257 * previous association. 258 */ 259 public void set(String name, String value) { 260 parameters.put(name.trim().toLowerCase(), value); 261 } 262 263 /** 264 * Remove any value associated with the given name. 265 */ 266 public void remove(String name) { 267 parameters.remove(name.trim().toLowerCase()); 268 } 269 270 /** 271 * Retrieve an enumeration of all the names in this list. 272 */ 273 public Enumeration<String> getNames() { 274 return parameters.keys(); 275 } 276 277 public String toString() { 278 // Heuristic: 8 characters per field 279 StringBuilder buffer = new StringBuilder(parameters.size() * 16); 280 281 Enumeration<String> keys = parameters.keys(); 282 while(keys.hasMoreElements()) 283 { 284 buffer.append("; "); 285 286 String key = keys.nextElement(); 287 buffer.append(key); 288 buffer.append('='); 289 buffer.append(quote(parameters.get(key))); 290 } 291 292 return buffer.toString(); 293 } 294 295 /** 296 * Returns a clone of this object. 297 * 298 * @return a clone of this object 299 */ 300 @SuppressWarnings("unchecked") // Cast from clone 301 public Object clone() { 302 MimeTypeParameterList newObj = null; 303 try { 304 newObj = (MimeTypeParameterList)super.clone(); 305 } catch (CloneNotSupportedException cannotHappen) { 306 } 307 newObj.parameters = (Hashtable<String, String>)parameters.clone(); 308 return newObj; 309 } 310 311 private Hashtable<String, String> parameters; 312 313 // below here be scary parsing related things 314 315 /** 316 * Determine whether or not a given character belongs to a legal token. 317 */ 318 private static boolean isTokenChar(char c) { 319 return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0); 320 } 321 322 /** 323 * Returns the index of the first non white space character in 324 * {@code rawdata} at or after index {@code i}. 325 */ 326 private static int skipWhiteSpace(String rawdata, int i) { 327 int length = rawdata.length(); 328 if (i < length) { 329 char c = rawdata.charAt(i); 330 while ((i < length) && Character.isWhitespace(c)) { 331 ++i; 332 c = rawdata.charAt(i); 333 } 334 } 335 336 return i; 337 } 338 339 /** 340 * A routine that knows how and when to quote and escape the given value. 341 */ 342 private static String quote(String value) { 343 boolean needsQuotes = false; 344 358 for(int i = 0; i < length; ++i) { 359 char c = value.charAt(i); 360 if((c == '\\') || (c == '"')) { 361 buffer.append('\\'); 362 } 363 buffer.append(c); 364 } 365 366 // add the closing quote 367 buffer.append('"'); 368 369 return buffer.toString(); 370 } 371 else 372 { 373 return value; 374 } 375 } 376 377 /** 378 * A routine that knows how to strip the quotes and escape sequences from 379 * the given value. 380 */ 381 private static String unquote(String value) { 382 int valueLength = value.length(); 383 StringBuilder buffer = new StringBuilder(valueLength); 384 385 boolean escaped = false; 386 for(int i = 0; i < valueLength; ++i) { 387 char currentChar = value.charAt(i); 388 if(!escaped && (currentChar != '\\')) { 389 buffer.append(currentChar); 390 } else if(escaped) { 391 buffer.append(currentChar); 392 escaped = false; 393 } else { 394 escaped = true; 395 } 396 } 397 398 return buffer.toString(); 399 } 400 401 /** 402 * A string that holds all the special chars. 403 */ 404 private static final String TSPECIALS = "()<>@,;:\\\"/[]?="; 405 } |