diff src/org/tmatesoft/hg/internal/EncodingHelper.java @ 415:ee8264d80747

Explicit constant for regular file flags, access to flags for a given file revision
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 22 Mar 2012 18:54:11 +0100
parents 63c5a9d7ca3f
children 528b6780a8bd
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/EncodingHelper.java	Wed Mar 21 20:51:12 2012 +0100
+++ b/src/org/tmatesoft/hg/internal/EncodingHelper.java	Thu Mar 22 18:54:11 2012 +0100
@@ -17,13 +17,17 @@
 package org.tmatesoft.hg.internal;
 
 import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
 import java.nio.charset.CharacterCodingException;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CharsetEncoder;
 
+import org.tmatesoft.hg.core.SessionContext;
+
 /**
  * Keep all encoding-related issues in the single place
+ * NOT thread-safe (encoder and decoder requires synchronized access)
  * @author Artem Tikhomirov
  * @author TMate Software Ltd.
  */
@@ -34,10 +38,12 @@
 	 * http://mercurial.808500.n3.nabble.com/Unicode-support-request-td3430704.html
 	 */
 	
+	private final SessionContext sessionContext;
 	private final CharsetEncoder encoder;
 	private final CharsetDecoder decoder;
 	
-	EncodingHelper(Charset fsEncoding) {
+	EncodingHelper(Charset fsEncoding, SessionContext ctx) {
+		sessionContext = ctx;
 		decoder = fsEncoding.newDecoder();
 		encoder = fsEncoding.newEncoder();
 	}
@@ -46,16 +52,40 @@
 		try {
 			return decoder.decode(ByteBuffer.wrap(data, start, length)).toString();
 		} catch (CharacterCodingException ex) {
+			sessionContext.getLog().error(getClass(), ex, String.format("Use of charset %s failed, resort to system default", charset().name()));
 			// resort to system-default
 			return new String(data, start, length);
 		}
 	}
 
-	public String fromDirstate(byte[] data, int start, int length) throws CharacterCodingException {
+	/**
+	 * @return byte representation of the string directly comparable to bytes in manifest
+	 */
+	public byte[] toManifest(String s) {
+		if (s == null) {
+			// perhaps, can return byte[0] in this case?
+			throw new IllegalArgumentException();
+		}
+		try {
+			// synchonized(encoder) {
+			ByteBuffer bb = encoder.encode(CharBuffer.wrap(s));
+			// }
+			byte[] rv = new byte[bb.remaining()];
+			bb.get(rv, 0, rv.length);
+			return rv;
+		} catch (CharacterCodingException ex) {
+			sessionContext.getLog().error(getClass(), ex, String.format("Use of charset %s failed, resort to system default", charset().name()));
+			// resort to system-default
+			return s.getBytes();
+		}
+	}
+
+	public String fromDirstate(byte[] data, int start, int length) throws CharacterCodingException { // FIXME perhaps, log is enough, and charset() may be private?
 		return decoder.decode(ByteBuffer.wrap(data, start, length)).toString();
 	}
 
 	public Charset charset() {
 		return encoder.charset();
 	}
+
 }