Coverage Report - org.webmacro.util.EncodingCache
 
Classes in this File Line Coverage Branch Coverage Complexity
ArrayBucket
0%
0/1
N/A
6.25
Bucket
0%
0/1
N/A
6.25
EncodingCache
0%
0/105
0%
0/48
6.25
 
 1  
 /*
 2  
  * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
 3  
  *
 4  
  * Redistribution and use in source and binary forms, with or without
 5  
  * modification, are permitted under the terms of either of the following
 6  
  * Open Source licenses:
 7  
  *
 8  
  * The GNU General Public License, version 2, or any later version, as
 9  
  * published by the Free Software Foundation
 10  
  * (http://www.fsf.org/copyleft/gpl.html);
 11  
  *
 12  
  *  or
 13  
  *
 14  
  * The Semiotek Public License (http://webmacro.org/LICENSE.)
 15  
  *
 16  
  * This software is provided "as is", with NO WARRANTY, not even the
 17  
  * implied warranties of fitness to purpose, or merchantability. You
 18  
  * assume all risks and liabilities associated with its use.
 19  
  *
 20  
  * See www.webmacro.org for more information on the WebMacro project.
 21  
  */
 22  
 
 23  
 
 24  
 package org.webmacro.util;
 25  
 
 26  
 import java.io.BufferedReader;
 27  
 import java.io.InputStreamReader;
 28  
 import java.io.UnsupportedEncodingException;
 29  
 import java.util.HashMap;
 30  
 import java.util.Map;
 31  
 
 32  0
 class Bucket
 33  
 {
 34  
 
 35  
     public String string1;
 36  
     public String string2;
 37  
     public String string3;
 38  
     public String string4;
 39  
     public String string5;
 40  
     public byte[] bytes1;
 41  
     public byte[] bytes2;
 42  
     public byte[] bytes3;
 43  
     public byte[] bytes4;
 44  
     public byte[] bytes5;
 45  
 }
 46  
 
 47  0
 class ArrayBucket
 48  
 {
 49  
 
 50  
     public String string1[];
 51  
     public String string2[];
 52  
     public String string3[];
 53  
     public String string4[];
 54  
     public String string5[];
 55  
     public byte[] bytes1[];
 56  
     public byte[] bytes2[];
 57  
     public byte[] bytes3[];
 58  
     public byte[] bytes4[];
 59  
     public byte[] bytes5[];
 60  
 }
 61  
 
 62  
 
 63  
 /**
 64  
  * Provides for a cache of encodings of strings.
 65  
  */
 66  
 final public class EncodingCache
 67  
 {
 68  
 
 69  
     final private String _encoding;
 70  
     final private Bucket[] _cache;
 71  
     final private ArrayBucket[] _acache;
 72  
     final private int _size;
 73  
 
 74  0
     final static private Map _ecCache = new HashMap();
 75  
 
 76  
     public EncodingCache (String encoding)
 77  
             throws UnsupportedEncodingException
 78  
     {
 79  0
         this(encoding, 1001);
 80  0
     }
 81  
 
 82  
     /**
 83  
      * Create a new EncodingCache with space for buckets * length
 84  
      * encoded strings. Buckets is the number of hashtable buckets
 85  
      * the cache will be based on, length is the number of objects
 86  
      * that can be held in each bucket.
 87  
      */
 88  
     public EncodingCache (String encoding, int buckets)
 89  
             throws UnsupportedEncodingException
 90  0
     {
 91  0
         _size = buckets;
 92  
 
 93  0
         _cache = new Bucket[_size];
 94  0
         _acache = new ArrayBucket[_size];
 95  
 
 96  0
         for (int i = 0; i < _size; i++)
 97  
         {
 98  0
             _cache[i] = new Bucket();
 99  0
             _acache[i] = new ArrayBucket();
 100  
         }
 101  
 
 102  0
         if ((encoding == null) ||
 103  
                 encoding.equalsIgnoreCase("UNICODE") ||
 104  
                 encoding.equalsIgnoreCase("UNICODEBIG") ||
 105  
                 encoding.equalsIgnoreCase("UNICODELITTLE") ||
 106  
                 encoding.equalsIgnoreCase("UTF16"))
 107  
         {
 108  0
             throw new UnsupportedEncodingException(
 109  
                     "The encoding you specified is invalid: " + 
 110  
                     encoding + ". " + 
 111  
                     "Note that the UNICODE and UTF16 encodings are not " + 
 112  
                     "supported by WebMacro because " + 
 113  
                     "they prefix the stream with a marker indicating " + 
 114  
                     "whether the stream is big endian or little endian. " + 
 115  
                     "Instead choose the byte ordering yourself by using " + 
 116  
                     "the UTF-16BE or UTF-16LE encodings.");
 117  
         }
 118  0
         _encoding = encoding;
 119  
         // throw exception if encoding is invalid
 120  0
         "some test string".getBytes(encoding); 
 121  0
     }
 122  
 
 123  
     public String getEncodingName ()
 124  
     {
 125  0
         return _encoding;
 126  
     }
 127  
 
 128  
     public byte[] encode (String s)
 129  
     {
 130  0
         if (s == null)
 131  0
             return null;
 132  
 
 133  0
         int hash = s.hashCode() % _size;
 134  0
         if (hash < 0) hash = -hash;
 135  0
         Bucket b = _cache[hash];
 136  0
         synchronized (b)
 137  
         {
 138  0
             if (b.string1 == s)
 139  0
                 return b.bytes1;
 140  0
             else if (b.string2 == s)
 141  0
                 return b.bytes2;
 142  0
             else if (b.string3 == s)
 143  0
                 return b.bytes3;
 144  0
             else if (b.string4 == s)
 145  0
                 return b.bytes4;
 146  0
             else if (b.string5 == s)
 147  0
                 return b.bytes5;
 148  
 
 149  
             try
 150  
             {
 151  0
                 byte[] buf = s.getBytes(_encoding);
 152  
 
 153  0
                 b.string5 = b.string4;
 154  0
                 b.string4 = b.string3;
 155  0
                 b.string3 = b.string2;
 156  0
                 b.string2 = b.string1;
 157  0
                 b.string1 = s;
 158  
 
 159  0
                 b.bytes5 = b.bytes4;
 160  0
                 b.bytes4 = b.bytes3;
 161  0
                 b.bytes3 = b.bytes2;
 162  0
                 b.bytes2 = b.bytes1;
 163  0
                 b.bytes1 = buf;
 164  
                 ;
 165  
 
 166  0
                 return buf;
 167  
             }
 168  0
             catch (UnsupportedEncodingException e)
 169  
             {
 170  0
                 e.printStackTrace(); // never happen: we check in constructor
 171  0
                 return null;
 172  
             }
 173  0
         }
 174  
     }
 175  
 
 176  
     public byte[][] encode (String s[])
 177  
     {
 178  0
         return encode(s, System.identityHashCode(s));
 179  
     }
 180  
 
 181  
     public byte[][] encode (String s[], int hash)
 182  
     {
 183  0
         if (hash < 0) hash = -hash;
 184  0
         hash %= _size;
 185  0
         ArrayBucket b = _acache[hash];
 186  0
         synchronized (b)
 187  
         {
 188  0
             if (b.string1 == s)
 189  0
                 return b.bytes1;
 190  0
             else if (b.string2 == s)
 191  0
                 return b.bytes2;
 192  0
             else if (b.string3 == s)
 193  0
                 return b.bytes3;
 194  0
             else if (b.string4 == s)
 195  0
                 return b.bytes4;
 196  0
             else if (b.string5 == s)
 197  0
                 return b.bytes5;
 198  0
             else if (s == null)
 199  0
                 return null;
 200  
 
 201  
             try
 202  
             {
 203  0
                 byte[][] buf = new byte[s.length][];
 204  0
                 for (int i = 0; i < buf.length; i++)
 205  
                 {
 206  0
                     if (s[i] != null)
 207  
                     {
 208  0
                         buf[i] = s[i].getBytes(_encoding);
 209  
                     }
 210  
                 }
 211  
 
 212  0
                 b.string5 = b.string4;
 213  0
                 b.string4 = b.string3;
 214  0
                 b.string3 = b.string2;
 215  0
                 b.string2 = b.string1;
 216  0
                 b.string1 = s;
 217  
 
 218  0
                 b.bytes5 = b.bytes4;
 219  0
                 b.bytes4 = b.bytes3;
 220  0
                 b.bytes3 = b.bytes2;
 221  0
                 b.bytes2 = b.bytes1;
 222  0
                 b.bytes1 = buf;
 223  
                 ;
 224  
 
 225  0
                 return buf;
 226  
             }
 227  0
             catch (UnsupportedEncodingException e)
 228  
             {
 229  0
                 e.printStackTrace(); // will never happen: we check in constructor
 230  0
                 return null;
 231  
             }
 232  0
         }
 233  
     }
 234  
 
 235  
 
 236  
     public static EncodingCache getInstance (String encoding)
 237  
             throws UnsupportedEncodingException
 238  
     {
 239  0
         synchronized (_ecCache)
 240  
         {
 241  0
             EncodingCache ec = (EncodingCache) _ecCache.get(encoding);
 242  0
             if (ec == null)
 243  
             {
 244  0
                 ec = new EncodingCache(encoding);
 245  0
                 _ecCache.put(encoding, ec);
 246  
             }
 247  0
             return ec;
 248  0
         }
 249  
     }
 250  
 
 251  
     public static void main (String arg[])
 252  
     {
 253  
         try
 254  
         {
 255  
             /*
 256  
              byte[] prefix = getPrefix(arg[0]);
 257  
              System.out.println("Prefix for " + arg[0] + " is " + 
 258  
              prefix.length + " bytes long");
 259  
              */
 260  0
             EncodingCache ec = new EncodingCache("UTF-16LE", 11);
 261  0
             BufferedReader in = new
 262  
                     BufferedReader(new InputStreamReader(System.in));
 263  
             String s;
 264  0
             while ((s = in.readLine()) != null)
 265  
             {
 266  0
                 String s1 = s.intern();
 267  0
                 byte b[] = ec.encode(s1);
 268  0
                 String s2 = new String(b, "UTF-16LE");
 269  0
                 System.out.print("Encoding string: " + s1 + " --> [");
 270  0
                 System.out.print(s2);
 271  0
                 System.out.println("]");
 272  0
             }
 273  
         }
 274  0
         catch (Exception e)
 275  
         {
 276  0
             e.printStackTrace();
 277  0
         }
 278  0
     }
 279  
 }
 280