/** * 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; } }