diff options
Diffstat (limited to 'libjava/gnu/gcj/convert/UnicodeToBytes.java')
| -rw-r--r-- | libjava/gnu/gcj/convert/UnicodeToBytes.java | 108 |
1 files changed, 74 insertions, 34 deletions
diff --git a/libjava/gnu/gcj/convert/UnicodeToBytes.java b/libjava/gnu/gcj/convert/UnicodeToBytes.java index dce7797fbaf..858be11f674 100644 --- a/libjava/gnu/gcj/convert/UnicodeToBytes.java +++ b/libjava/gnu/gcj/convert/UnicodeToBytes.java @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* Copyright (C) 1999, 2000, 2001 Free Software Foundation This file is part of libgcj. @@ -7,7 +7,7 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ package gnu.gcj.convert; - + public abstract class UnicodeToBytes extends IOConverter { /** Buffer to emit bytes to. @@ -15,28 +15,20 @@ public abstract class UnicodeToBytes extends IOConverter public byte[] buf; public int count; - static Class defaultEncodingClass; + // The name of the default encoding. + static String defaultEncoding; - static synchronized void getDefaultEncodingClass() - { - // Test (defaultEncodingClass == null) again in case of race condition. - if (defaultEncodingClass == null) - { - String encoding = canonicalize (System.getProperty("file.encoding")); - String className = "gnu.gcj.convert.Output_"+encoding; - try - { - defaultEncodingClass = Class.forName(className); - } - catch (ClassNotFoundException ex) - { - throw new NoClassDefFoundError("missing default encoding " - + encoding + " (class " - + className + " not found)"); - - } - } - } + /* These keep a small cache of encoders for reuse. The array holds + the actual encoders. The currCachePos is the next value we are + going to replace in the cache. We don't just throw the data away + if the cache is full, because if the cache filled up with stuff we + don't need then the cache would be worthless. We instead + circulate through the cache the implement kind of an LRU + algorithm. */ + private static final int CACHE_SIZE = 4; // A power of 2 for speed + private static UnicodeToBytes[] encoderCache + = new UnicodeToBytes[CACHE_SIZE]; + private static int currCachePos = 0; public abstract String getName(); @@ -44,20 +36,34 @@ public abstract class UnicodeToBytes extends IOConverter { try { - if (defaultEncodingClass == null) - getDefaultEncodingClass(); - return (UnicodeToBytes) defaultEncodingClass.newInstance(); + synchronized (UnicodeToBytes.class) + { + if (defaultEncoding == null) + { + String encoding + = canonicalize (System.getProperty("file.encoding", + "8859_1")); + String className = "gnu.gcj.convert.Output_" + encoding; + try + { + Class defaultEncodingClass = Class.forName(className); + defaultEncoding = encoding; + } + catch (ClassNotFoundException ex) + { + throw new NoClassDefFoundError("missing default encoding " + + encoding + " (class " + + className + + " not found)"); + } + } + } + + return getEncoder (defaultEncoding); } catch (Throwable ex) { - try - { - return new Output_iconv (System.getProperty ("file.encoding")); - } - catch (Throwable ex2) - { - return new Output_8859_1(); - } + return new Output_8859_1(); } } @@ -65,6 +71,23 @@ public abstract class UnicodeToBytes extends IOConverter public static UnicodeToBytes getEncoder (String encoding) throws java.io.UnsupportedEncodingException { + /* First hunt in our cache to see if we have a encoder that is + already allocated. */ + synchronized (UnicodeToBytes.class) + { + int i; + for (i = 0; i < encoderCache.length; ++i) + { + if (encoderCache[i] != null + && encoding.equals(encoderCache[i].getName ())) + { + UnicodeToBytes rv = encoderCache[i]; + encoderCache[i] = null; + return rv; + } + } + } + String className = "gnu.gcj.convert.Output_" + canonicalize (encoding); Class encodingClass; try @@ -122,4 +145,21 @@ public abstract class UnicodeToBytes extends IOConverter str.getChars(inpos, srcEnd, work, 0); return write(work, inpos, inlength); } + + /** Indicate that the converter is resuable. + * This class keeps track of converters on a per-encoding basis. + * When done with an encoder you may call this method to indicate + * that it can be reused later. + */ + public void done () + { + synchronized (UnicodeToBytes.class) + { + this.buf = null; + this.count = 0; + + encoderCache[currCachePos] = this; + currCachePos = (currCachePos + 1) % CACHE_SIZE; + } + } } |

