/**
* Copyright (C) 2004, 2005, 2006 Aelitis SAS, All rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details ( see the LICENSE file ).
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* AELITIS, SAS au capital de 46,603.30 euros,
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*/
package com.frostwire.torrent;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
final class LocaleUtil {
private static final String systemEncoding = System.getProperty("file.encoding");
private static final String[] manual_charset = { systemEncoding, // must be first entry due to code below that gets the system decoder
"Big5", "EUC-JP", "EUC-KR", "GB18030", "GB2312", "GBK", "ISO-2022-JP", "ISO-2022-KR", "Shift_JIS", "KOI8-R", "TIS-620", // added for bug #1008848
Constants.DEFAULT_ENCODING, "windows-1251", Constants.BYTE_ENCODING };
// the general ones *must* also be members of the above manual ones
protected static final String[] generalCharsets = { Constants.BYTE_ENCODING, Constants.DEFAULT_ENCODING, systemEncoding };
private static LocaleUtil singleton = new LocaleUtil();
public static LocaleUtil getSingleton() {
return (singleton);
}
private LocaleUtilDecoder[] all_decoders;
private LocaleUtilDecoder[] general_decoders;
private LocaleUtilDecoder system_decoder;
private LocaleUtilDecoder fallback_decoder;
private LocaleUtil() {
List<LocaleUtilDecoder> decoders = new ArrayList<LocaleUtilDecoder>();
List<String> decoder_names = new ArrayList<String>();
for (int i = 0; i < manual_charset.length; i++) {
try {
String name = manual_charset[i];
CharsetDecoder decoder = Charset.forName(name).newDecoder();
if (decoder != null) {
LocaleUtilDecoder lu_decoder = new LocaleUtilDecoderReal(decoders.size(), decoder);
decoder_names.add(lu_decoder.getName());
if (i == 0) {
system_decoder = lu_decoder;
}
decoders.add(lu_decoder);
} else if (i == 0) {
Debug.out("System decoder failed to be found!!!!");
}
} catch (Exception ignore) {
}
}
general_decoders = new LocaleUtilDecoder[generalCharsets.length];
for (int i = 0; i < general_decoders.length; i++) {
int gi = decoder_names.indexOf(generalCharsets[i]);
if (gi != -1) {
general_decoders[i] = (LocaleUtilDecoder) decoders.get(gi);
}
}
boolean show_all = true;
if (show_all) {
Map<String, Charset> m = Charset.availableCharsets();
Iterator<String> it = m.keySet().iterator();
while (it.hasNext()) {
String charset_name = (String) it.next();
if (!decoder_names.contains(charset_name)) {
try {
CharsetDecoder decoder = Charset.forName(charset_name).newDecoder();
if (decoder != null) {
LocaleUtilDecoder lu_decoder = new LocaleUtilDecoderReal(decoders.size(), decoder);
decoders.add(lu_decoder);
decoder_names.add(lu_decoder.getName());
}
} catch (Exception ignore) {
}
}
}
}
fallback_decoder = new LocaleUtilDecoderFallback(decoders.size());
decoders.add(fallback_decoder);
all_decoders = new LocaleUtilDecoder[decoders.size()];
decoders.toArray(all_decoders);
}
public String getSystemEncoding() {
return (systemEncoding);
}
public LocaleUtilDecoder[] getDecoders() {
return (all_decoders);
}
public LocaleUtilDecoder getFallBackDecoder() {
return fallback_decoder;
}
public LocaleUtilDecoder getSystemDecoder() {
return (system_decoder);
}
/**
* Determine which locales are candidates for handling the supplied type of
* string
*
* @param array String in an byte array
* @return list of candidates. Valid candidates have getDecoder() non-null
*/
protected LocaleUtilDecoderCandidate[] getCandidates(byte[] array) {
LocaleUtilDecoderCandidate[] candidates = new LocaleUtilDecoderCandidate[all_decoders.length];
boolean show_less_likely_conversions = false;//COConfigurationManager.getBooleanParameter("File.Decoder.ShowLax" );
for (int i = 0; i < all_decoders.length; i++) {
candidates[i] = new LocaleUtilDecoderCandidate(i);
try {
LocaleUtilDecoder decoder = all_decoders[i];
String str = decoder.tryDecode(array, show_less_likely_conversions);
if (str != null) {
candidates[i].setDetails(decoder, str);
}
} catch (Exception ignore) {
}
}
/*
System.out.println( "getCandidates: = " + candidates.length );
for (int i=0;i<candidates.length;i++){
LocaleUtilDecoderCandidate cand = candidates[i];
if ( cand != null ){
String value = cand.getValue();
if ( value != null ){
System.out.println( cand.getDecoder().getName() + "/" + (value==null?-1:value.length()) + "/" + value );
}
}
}
*/
return candidates;
}
/**
* Determine which decoders are candidates for handling the supplied type of
* string
*
* @param array String in a byte array
* @return list of possibly valid decoders. LocaleUtilDecoder
*/
protected List<LocaleUtilDecoder> getCandidateDecoders(byte[] array) {
LocaleUtilDecoderCandidate[] candidates = getCandidates(array);
List<LocaleUtilDecoder> decoders = new ArrayList<LocaleUtilDecoder>();
for (int i = 0; i < candidates.length; i++) {
LocaleUtilDecoder d = candidates[i].getDecoder();
if (d != null)
decoders.add(d);
}
return decoders;
}
/**
*
* @param array
* @return List of LocaleUtilDecoderCandidate
*/
protected List<LocaleUtilDecoderCandidate> getCandidatesAsList(byte[] array) {
LocaleUtilDecoderCandidate[] candidates = getCandidates(array);
List<LocaleUtilDecoderCandidate> candidatesList = new ArrayList<LocaleUtilDecoderCandidate>();
for (int i = 0; i < candidates.length; i++) {
if (candidates[i].getDecoder() != null)
candidatesList.add(candidates[i]);
}
return candidatesList;
}
}