Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.jruby.runtime.encoding;
  
 import org.jruby.Ruby;
 
 
 public final class EncodingService {
     private final CaseInsensitiveBytesHash<Entryencodings;
     private final CaseInsensitiveBytesHash<Entryaliases;
 
     // for fast lookup: encoding entry => org.jruby.RubyEncoding
     private final IRubyObject[] encodingList;
     // for fast lookup: org.joni.encoding.Encoding => org.jruby.RubyEncoding
     private RubyEncoding[] encodingIndex = new RubyEncoding[4];
     // the runtime
     private final Ruby runtime;
     
     private final Encoding ascii8bit;
     private final Encoding javaDefault;
 
     private static final ByteList LOCALE_BL = ByteList.create("locale");
     private static final ByteList EXTERNAL_BL = ByteList.create("external");
     private static final ByteList INTERNAL_BL = ByteList.create("internal");
     private static final ByteList FILESYSTEM_BL = ByteList.create("filesystem");
 
     public EncodingService (Ruby runtime) {
         this. = runtime;
          = EncodingDB.getEncodings();
          = EncodingDB.getAliases();
          = .get("ASCII-8BIT".getBytes()).getEncoding();
 
         Charset javaDefaultCharset = Charset.defaultCharset();
         ByteList javaDefaultBL = new ByteList(javaDefaultCharset.name().getBytes());
         Entry javaDefaultEntry = findEncodingOrAliasEntry(javaDefaultBL);
          = javaDefaultEntry == null ?  : javaDefaultEntry.getEncoding();
 
          = new IRubyObject[.size()];
     }

    
Since Java 1.6, class java.io.Console is available. But the encoding or codepage of the underlying connected console is currently private. Had to use Reflection to get it.

Returns:
console codepage
 
     public Encoding getConsoleEncoding() {
         if (!.return null;
 
         Encoding consoleEncoding = null;
         try {
             Console console = System.console();
             if (console != null) {
                 final String CONSOLE_CHARSET = "cs";
                 Field fcs = Console.class.getDeclaredField(CONSOLE_CHARSET);
                 fcs.setAccessible(true);
                 Charset cs = (Charsetfcs.get(console);
                 consoleEncoding = loadEncoding(ByteList.create(cs.name()));
             }
         } catch (Throwable e) { // to cover both Exceptions and Errors
             // just fall back on local encoding above
         }
         return consoleEncoding;
     }
     
     // mri: rb_usascii_encoding
     public Encoding getUSAsciiEncoding() {
         return .;
     }
 
     // mri: rb_ascii8bit_encoding
     public Encoding getAscii8bitEncoding() {
         return ;
     }
     
     // mri: rb_filesystem_encoding
    public Encoding getFileSystemEncoding(Ruby runtime) {
        return ..toEncoding(runtime);
    }
    
        return ;
    }
        return ;
    }
    public Entry findEncodingEntry(ByteList bytes) {
        return .get(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getBegin() + bytes.getRealSize());
    }
    public Entry findEncodingEntry(byte[] bytes) {
        return .get(bytes);
    }
    public Entry findAliasEntry(ByteList bytes) {
        return .get(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getBegin() + bytes.getRealSize());
    }
    public Entry findAliasEntry(byte[] bytes) {
        return .get(bytes);
    }
    public Entry findEncodingOrAliasEntry(ByteList bytes) {
        Entry e = findEncodingEntry(bytes);
        return e != null ? e : findAliasEntry(bytes);
    }
    public Entry findEncodingOrAliasEntry(byte[] bytes) {
        Entry e = findEncodingEntry(bytes);
        return e != null ? e : findAliasEntry(bytes);
    }
    // rb_locale_charmap...mostly
    public Encoding getLocaleEncoding() {
        Entry entry = findEncodingOrAliasEntry(new ByteList(Charset.defaultCharset().name().getBytes()));
        return entry == null ? . : entry.getEncoding();
    }
    public IRubyObject[] getEncodingList() {
        return ;
    }
    public Encoding loadEncoding(ByteList name) {
        Entry entry = findEncodingOrAliasEntry(name);
        if (entry == nullreturn null;
        Encoding enc = entry.getEncoding(); // load the encoding
        int index = enc.getIndex();
        if (index >= .) {
            RubyEncoding tmp[] = new RubyEncoding[index + 4];
            System.arraycopy(, 0, tmp, 0, .);
             = tmp;
        }
        [index] = (RubyEncoding)[entry.getIndex()];
        return enc;
    }
    public RubyEncoding getEncoding(Encoding enc) {
        int index = enc.getIndex();
        RubyEncoding rubyEncoding;
        if (index < . && (rubyEncoding = [index]) != null) {
            return rubyEncoding;
        }
        enc = loadEncoding(new ByteList(enc.getName(), false));
        return [enc.getIndex()];
    }
    public void defineEncodings() {
        HashEntryIterator hei = .entryIterator();
        while (hei.hasNext()) {
                ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)hei.next());
            Entry ee = e.value;
            RubyEncoding encoding = RubyEncoding.newEncoding(e.bytese.pe.endee.isDummy());
            [ee.getIndex()] = encoding;
            defineEncodingConstants(encodinge.bytese.pe.end);
        }
    }
    public void defineAliases() {
        HashEntryIterator hei = .entryIterator();
        while (hei.hasNext()) {
                ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)hei.next());
            Entry ee = e.value
            RubyEncoding encoding = (RubyEncoding)[ee.getIndex()];
            defineEncodingConstants(encodinge.bytese.pe.end);
        }
    }
    private void defineEncodingConstants(Ruby runtimeRubyEncoding encodingbyte[]nameint p,
            int end) {
        Encoding enc = .;
        int s = p;
        int code = name[s] & 0xff;
        if (enc.isDigit(code)) return;
        boolean hasUpper = false;
        boolean hasLower = false;
        if (enc.isUpper(code)) {
            hasUpper = true;
            while (++s < end && (enc.isAlnum(name[s] & 0xff) || name[s] == (byte)'_')) {
                if (enc.isLower(name[s] & 0xff)) hasLower = true;
            }
        }
        boolean isValid = false;
        if (s >= end) {
            isValid = true;
            defineEncodingConstant(runtimeencodingnamepend);
        }
        if (!isValid || hasLower) {
            if (!hasLower || !hasUpper) {
                do {
                    code = name[s] & 0xff;
                    if (enc.isLower(code)) hasLower = true;
                    if (enc.isUpper(code)) hasUpper = true;
                } while (++s < end && (!hasLower || !hasUpper));
            }
            byte[]constName = new byte[end - p];
            System.arraycopy(namepconstName, 0, end - p);
            s = 0;
            code = constName[s] & 0xff;
            if (!isValid) {
                if (enc.isLower(code)) constName[s] = .[code];
                for (; s < constName.length; ++s) {
                    if (!enc.isAlnum(constName[s] & 0xff)) constName[s] = (byte)'_';
                }
                if (hasUpper) {
                    defineEncodingConstant(runtimeencodingconstName, 0, constName.length);
                }
            }
            if (hasLower) {
                for (s = 0; s < constName.length; ++s) {
                    code = constName[s] & 0xff;
                    if (enc.isLower(code)) constName[s] = .[code];
                }
                defineEncodingConstant(runtimeencodingconstName, 0, constName.length);
            }
        }
    }
    private void defineEncodingConstant(Ruby runtimeRubyEncoding encodingbyte[]constName,
            int constPint constEnd) {
        runtime.getEncoding().defineConstant(new String(constNameconstP , constEnd), encoding);
    }
    public IRubyObject getDefaultExternal() {
        if (defaultExternal.isNil()) {
            // TODO: MRI seems to default blindly to US-ASCII and we were using Charset default from Java...which is right?
            ByteList encodingName = ByteList.create("US-ASCII");
            Encoding encoding = .getEncodingService().loadEncoding(encodingName);
            .setDefaultExternalEncoding(encoding);
            defaultExternal = convertEncodingToRubyEncoding(encoding);
        }
        return defaultExternal;
    }
    public IRubyObject getDefaultInternal() {
    }
    public IRubyObject convertEncodingToRubyEncoding(Encoding defaultEncoding) {
        return defaultEncoding != null ? getEncoding(defaultEncoding) : .getNil();
    }
    public Encoding getJavaDefault() {
        return ;
    }
        return getEncodingFromObjectCommon(argtrue);
    }
    // rb_to_encoding_index
        return getEncodingFromObjectCommon(argfalse);
    }
    private Encoding getEncodingFromObjectCommon(IRubyObject argboolean error) {
        if (arg == nullreturn null;
        if (arg instanceof RubyEncoding) {
            return ((RubyEncodingarg).getEncoding();
        } else if (arg instanceof RubyFixnum && ..containsKey((int)arg.convertToInteger().getLongValue())) {
            return getEncodingFromNKFId(arg);
        } else if ((arg = arg.checkStringType19()).isNil()) {
            return null;
        } else if (!((RubyString)arg).getEncoding().isAsciiCompatible()) {
            return null;
        } else {
            if (error) {
                return findEncoding((RubyString)arg);
            } else {
                return findEncodingNoError((RubyString)arg);
            }
        }
    }
    
    private Encoding getEncodingFromNKFId(IRubyObject id) {
        String name = ..get((int)id.convertToInteger().getLongValue());
        HashEntryIterator hei = .entryIterator();
        while (hei.hasNext()) {
                ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)hei.next());
            EncodingDB.Entry ee = e.value;
            String className = ee.getEncodingClass();
            if (className.equals(name)) {
                Encoding enc = ee.getEncoding();
                return enc;
            }
        }
        return null;   
    }
    
    public Encoding getEncodingFromString(String string) {
        if (string == nullreturn null;
        ByteList name = new ByteList(ByteList.plain(string));
        checkAsciiEncodingName(name);
        SpecialEncoding special = SpecialEncoding.valueOf(name);
        if (special != null) {
            return special.toEncoding();
        }
        return findEncodingWithError(name);
    }

    
Find an encoding given a Ruby object, coercing it to a String in the process.

Parameters:
str the object to coerce and use to look up encoding. The coerced String must be ASCII-compatible.
Returns:
the Encoding object found, nil (for internal), or raises ArgumentError
    public Encoding findEncoding(IRubyObject str) {
        return findEncodingCommon(strtrue);
    }

    
Find an encoding given a Ruby object, coercing it to a String in the process. This version does not raise a Ruby error if it can't find the encoding, and simply returns null.

Parameters:
str the object to coerce and use to look up encoding. The coerced String must be ASCII-compatible.
Returns:
the Encoding object found, nil (for internal), or raises ArgumentError
    public Encoding findEncodingNoError(IRubyObject str) {
        return findEncodingCommon(strfalse);
    }
    
    private Encoding findEncodingCommon(IRubyObject strboolean error) {
        ByteList name = str.convertToString().getByteList();
        checkAsciiEncodingName(name);
        SpecialEncoding special = SpecialEncoding.valueOf(name);
        if (special != null) {
            return special.toEncoding();
        }
        
        if (errorreturn findEncodingWithError(name);
        
        Entry e = findEncodingOrAliasEntry(name);
        if (e == nullreturn null;
        return e.getEncoding();
    }

    
Find an encoding given a Ruby object, coercing it to a String in the process.

Parameters:
str the object to coerce and use to look up encoding. The coerced String must be ASCII-compatible.
Returns:
the Encoding object found, nil (for internal), or raises ArgumentError
    public Entry findEntry(IRubyObject str) {
        ByteList name = str.convertToString().getByteList();
        checkAsciiEncodingName(name);
        SpecialEncoding special = SpecialEncoding.valueOf(name);
        if (special != null) {
            return findEntryFromEncoding(special.toEncoding());
        }
        return findEntryWithError(name);
    }
    
        if (str instanceof RubyEncoding) {
            return str;
        }
        
        Entry entry = findEntry(str);
        if (entry == nullreturn .getNil();
        return getEncodingList()[entry.getIndex()];
    }

    
Get a java.nio Charset for the given encoding, or null if impossible

Parameters:
encoding the encoding
Returns:
the charset
    public Charset charsetForEncoding(Encoding encoding) {
        Charset charset = encoding.getCharset();
        if (encoding.toString().equals("ASCII-8BIT")) {
            return Charset.forName("ISO-8859-1");
        }
        if (encoding == .) {
            return .;
        }
        try {
            return Charset.forName(encoding.toString());
        } catch (UnsupportedCharsetException uce) {
            throw .newEncodingCompatibilityError("no java.nio.charset.Charset found for encoding `" + encoding.toString() + "'");
        }
    }
    private void checkAsciiEncodingName(ByteList name) {
        if (!name.getEncoding().isAsciiCompatible()) {
            throw .newArgumentError("invalid name encoding (non ASCII)");
        }
    }

    
Represents one of the four "special" internal encoding names: internal, external, locale, or filesystem.
    private enum SpecialEncoding {
        LOCALE, EXTERNAL, INTERNAL, FILESYSTEM;
        public static SpecialEncoding valueOf(ByteList name) {
            if (name.caseInsensitiveCmp() == 0) {
                return ;
            } else if (name.caseInsensitiveCmp() == 0) {
                return ;
            } else if (name.caseInsensitiveCmp() == 0) {
                return ;
            } else if (name.caseInsensitiveCmp() == 0) {
                return ;
            }
            return null;
        }
        public Encoding toEncoding(Ruby runtime) {
            EncodingService service = runtime.getEncodingService();
            switch (this) {
            case return service.getLocaleEncoding();
            case return runtime.getDefaultExternalEncoding();
            case return runtime.getDefaultInternalEncoding();
            case :
                // This needs to do something different on Windows. See encoding.c,
                // in the enc_set_filesystem_encoding function.
                return runtime.getDefaultExternalEncoding();
            default:
                throw new RuntimeException("invalid SpecialEncoding: " + this);
            }
        }
    }

    
Find a non-special encoding, raising argument error if it does not exist.

Parameters:
name the name of the encoding to look up
Returns:
the Encoding object found, or raises ArgumentError
    public Encoding findEncodingWithError(ByteList name) {
        return findEntryWithError(name).getEncoding();
    }

    
Find a non-special encoding Entry, raising argument error if it does not exist.

Parameters:
name the name of the encoding to look up
Returns:
the EncodingDB.Entry object found, or raises ArgumentError
    private Entry findEntryWithError(ByteList name) {
        Entry e = findEncodingOrAliasEntry(name);
        if (e == nullthrow .newArgumentError("unknown encoding name - " + name);
        return e;
    }
    private Entry findEntryFromEncoding(Encoding e) {
        if (e == nullreturn null;
        return findEncodingEntry(new ByteList(e.getName()));
    }
New to GrepCode? Check out our FAQ X