mirror of https://github.com/postgres/postgres
Here's a patch against the current CVS. The changes from the previous patch are mostly related to the changed interface for PG_Stream. Anders BengtssonREL7_2_STABLE
parent
12f59470a1
commit
ff21a8e5c8
@ -0,0 +1,167 @@ |
||||
package org.postgresql.core; |
||||
|
||||
import java.io.*; |
||||
import java.util.*; |
||||
import java.sql.SQLException; |
||||
import org.postgresql.util.*; |
||||
|
||||
/** |
||||
* Converts to and from the character encoding used by the backend. |
||||
* |
||||
* $Id: Encoding.java,v 1.1 2001/07/21 18:52:11 momjian Exp $ |
||||
*/ |
||||
|
||||
public class Encoding { |
||||
|
||||
private static final Encoding DEFAULT_ENCODING = new Encoding(null); |
||||
|
||||
/** |
||||
* Preferred JVM encodings for backend encodings. |
||||
*/ |
||||
private static final Hashtable encodings = new Hashtable(); |
||||
|
||||
static { |
||||
encodings.put("SQL_ASCII", new String[] { "ASCII", "us-ascii" }); |
||||
encodings.put("UNICODE", new String[] { "UTF-8", "UTF8" }); |
||||
encodings.put("LATIN1", new String[] { "ISO8859_1" }); |
||||
encodings.put("LATIN2", new String[] { "ISO8859_2" }); |
||||
encodings.put("LATIN3", new String[] { "ISO8859_3" }); |
||||
encodings.put("LATIN4", new String[] { "ISO8859_4" }); |
||||
encodings.put("LATIN5", new String[] { "ISO8859_5" }); |
||||
encodings.put("LATIN6", new String[] { "ISO8859_6" }); |
||||
encodings.put("LATIN7", new String[] { "ISO8859_7" }); |
||||
encodings.put("LATIN8", new String[] { "ISO8859_8" }); |
||||
encodings.put("LATIN9", new String[] { "ISO8859_9" }); |
||||
encodings.put("EUC_JP", new String[] { "EUC_JP" }); |
||||
encodings.put("EUC_CN", new String[] { "EUC_CN" }); |
||||
encodings.put("EUC_KR", new String[] { "EUC_KR" }); |
||||
encodings.put("EUC_TW", new String[] { "EUC_TW" }); |
||||
encodings.put("WIN", new String[] { "Cp1252" }); |
||||
// We prefer KOI8-U, since it is a superset of KOI8-R.
|
||||
encodings.put("KOI8", new String[] { "KOI8_U", "KOI8_R" }); |
||||
// If the database isn't encoding-aware then we can't have
|
||||
// any preferred encodings.
|
||||
encodings.put("UNKNOWN", new String[0]); |
||||
} |
||||
|
||||
private final String encoding; |
||||
|
||||
private Encoding(String encoding) { |
||||
this.encoding = encoding; |
||||
} |
||||
|
||||
/** |
||||
* Get an Encoding for from the given database encoding and |
||||
* the encoding passed in by the user. |
||||
*/ |
||||
public static Encoding getEncoding(String databaseEncoding, |
||||
String passedEncoding) |
||||
{ |
||||
if (passedEncoding != null) { |
||||
if (isAvailable(passedEncoding)) { |
||||
return new Encoding(passedEncoding); |
||||
} else { |
||||
return defaultEncoding(); |
||||
} |
||||
} else { |
||||
return encodingForDatabaseEncoding(databaseEncoding); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Get an Encoding matching the given database encoding. |
||||
*/ |
||||
private static Encoding encodingForDatabaseEncoding(String databaseEncoding) { |
||||
// If the backend encoding is known and there is a suitable
|
||||
// encoding in the JVM we use that. Otherwise we fall back
|
||||
// to the default encoding of the JVM.
|
||||
|
||||
if (encodings.containsKey(databaseEncoding)) { |
||||
String[] candidates = (String[]) encodings.get(databaseEncoding); |
||||
for (int i = 0; i < candidates.length; i++) { |
||||
if (isAvailable(candidates[i])) { |
||||
return new Encoding(candidates[i]); |
||||
} |
||||
} |
||||
} |
||||
return defaultEncoding(); |
||||
} |
||||
|
||||
/** |
||||
* Name of the (JVM) encoding used. |
||||
*/ |
||||
public String name() { |
||||
return encoding; |
||||
} |
||||
|
||||
/** |
||||
* Encode a string to an array of bytes. |
||||
*/ |
||||
public byte[] encode(String s) throws SQLException { |
||||
try { |
||||
if (encoding == null) { |
||||
return s.getBytes(); |
||||
} else { |
||||
return s.getBytes(encoding); |
||||
} |
||||
} catch (UnsupportedEncodingException e) { |
||||
throw new PSQLException("postgresql.stream.encoding", e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Decode an array of bytes into a string. |
||||
*/ |
||||
public String decode(byte[] encodedString, int offset, int length) throws SQLException { |
||||
try { |
||||
if (encoding == null) { |
||||
return new String(encodedString, offset, length); |
||||
} else { |
||||
return new String(encodedString, offset, length, encoding); |
||||
} |
||||
} catch (UnsupportedEncodingException e) { |
||||
throw new PSQLException("postgresql.stream.encoding", e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Decode an array of bytes into a string. |
||||
*/ |
||||
public String decode(byte[] encodedString) throws SQLException { |
||||
return decode(encodedString, 0, encodedString.length); |
||||
} |
||||
|
||||
/** |
||||
* Get a Reader that decodes the given InputStream. |
||||
*/ |
||||
public Reader getDecodingReader(InputStream in) throws SQLException { |
||||
try { |
||||
if (encoding == null) { |
||||
return new InputStreamReader(in); |
||||
} else { |
||||
return new InputStreamReader(in, encoding); |
||||
} |
||||
} catch (UnsupportedEncodingException e) { |
||||
throw new PSQLException("postgresql.res.encoding", e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Get an Encoding using the default encoding for the JVM. |
||||
*/ |
||||
public static Encoding defaultEncoding() { |
||||
return DEFAULT_ENCODING; |
||||
} |
||||
|
||||
/** |
||||
* Test if an encoding is available in the JVM. |
||||
*/ |
||||
private static boolean isAvailable(String encodingName) { |
||||
try { |
||||
"DUMMY".getBytes(encodingName); |
||||
return true; |
||||
} catch (UnsupportedEncodingException e) { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,57 @@ |
||||
|
||||
package org.postgresql.test.jdbc2; |
||||
|
||||
import junit.framework.*; |
||||
import org.postgresql.core.Encoding; |
||||
import java.io.*; |
||||
|
||||
/** |
||||
* Tests for the Encoding class. |
||||
* |
||||
* $Id: EncodingTest.java,v 1.1 2001/07/21 18:52:11 momjian Exp $ |
||||
*/ |
||||
|
||||
|
||||
public class EncodingTest extends TestCase { |
||||
|
||||
public EncodingTest(String name) { |
||||
super(name); |
||||
} |
||||
|
||||
public void testCreation() throws Exception { |
||||
Encoding encoding; |
||||
encoding = Encoding.getEncoding("UNICODE", null); |
||||
assertEquals("UTF", encoding.name().substring(0, 3).toUpperCase()); |
||||
encoding = Encoding.getEncoding("SQL_ASCII", null); |
||||
assert(encoding.name().toUpperCase().indexOf("ASCII") != -1); |
||||
assertEquals("When encoding is unknown the default encoding should be used", |
||||
Encoding.defaultEncoding(), |
||||
Encoding.getEncoding("UNKNOWN", null)); |
||||
encoding = Encoding.getEncoding("SQL_ASCII", "utf-8"); |
||||
assert("Encoding passed in by the user should be preferred", |
||||
encoding.name().toUpperCase().indexOf("UTF") != -1); |
||||
} |
||||
|
||||
public void testTransformations() throws Exception { |
||||
Encoding encoding = Encoding.getEncoding("UNICODE", null); |
||||
assertEquals("ab", encoding.decode(new byte[] { 97, 98 })); |
||||
|
||||
assertEquals(2, encoding.encode("ab").length); |
||||
assertEquals(97, encoding.encode("a")[0]); |
||||
assertEquals(98, encoding.encode("b")[0]); |
||||
|
||||
encoding = Encoding.defaultEncoding(); |
||||
assertEquals("a".getBytes()[0], encoding.encode("a")[0]); |
||||
assertEquals(new String(new byte[] { 97 }), |
||||
encoding.decode(new byte[] { 97 })); |
||||
} |
||||
|
||||
public void testReader() throws Exception { |
||||
Encoding encoding = Encoding.getEncoding("SQL_ASCII", null); |
||||
InputStream stream = new ByteArrayInputStream(new byte[] { 97, 98 }); |
||||
Reader reader = encoding.getDecodingReader(stream); |
||||
assertEquals(97, reader.read()); |
||||
assertEquals(98, reader.read()); |
||||
assertEquals(-1, reader.read()); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue