Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: EPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Eclipse Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.eclipse.org/legal/epl-v10.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the EPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the EPL, the GPL or the LGPL. END LICENSE BLOCK ***
 
 package org.jruby;
 
 
 import static org.jruby.CompatVersion.*;
 
 @JRubyClass(name="Encoding")
 public class RubyEncoding extends RubyObject {
     public static final Charset UTF8 = Charset.forName("UTF-8");
     public static final Charset UTF16 = Charset.forName("UTF-16");
     public static final Charset ISO = Charset.forName("ISO-8859-1");
     public static final ByteList LOCALE = ByteList.create("locale");
     public static final ByteList EXTERNAL = ByteList.create("external");
 
     public static RubyClass createEncodingClass(Ruby runtime) {
         RubyClass encodingc = runtime.defineClass("Encoding"runtime.getObject(), .);
         runtime.setEncoding(encodingc);
         encodingc.index = .;
         encodingc.setReifiedClass(RubyEncoding.class);
         encodingc.kindOf = new RubyModule.JavaClassKindOf(RubyEncoding.class);
 
         encodingc.getSingletonClass().undefineMethod("allocate");
         encodingc.defineAnnotatedMethods(RubyEncoding.class);
 
         return encodingc;
     }
 
     private Encoding encoding;
     private final ByteList name;
     private final boolean isDummy;
 
     private RubyEncoding(Ruby runtimebyte[] nameint pint endboolean isDummy) {
         super(runtimeruntime.getEncoding());
         this. = new ByteList(namepend);
         this. = isDummy;
     }
     
     private RubyEncoding(Ruby runtimebyte[] nameboolean isDummy) {
         this(runtimename, 0, name.lengthisDummy);
     }
 
     private RubyEncoding(Ruby runtimeEncoding encoding) {
         super(runtimeruntime.getEncoding());
         this. = new ByteList(encoding.getName());
         this. = false;
         this. = encoding;
     }
 
     private RubyEncoding(Ruby runtimebyte[] nameEncoding encodingboolean isDummy) {
         super(runtimeruntime.getEncoding());
        this. = new ByteList(name);
        this. = isDummy;
        this. = encoding;
    }
    public static RubyEncoding newEncoding(Ruby runtimebyte[] nameint pint endboolean isDummy) {
        return new RubyEncoding(runtimenamependisDummy);
    }
    public static RubyEncoding newEncoding(Ruby runtimebyte[] nameboolean isDummy) {
        return new RubyEncoding(runtimenameisDummy);
    }
    public static RubyEncoding newEncoding(Ruby runtimeEncoding encoding) {
        return new RubyEncoding(runtimeencoding);
    }
    public final Encoding getEncoding() {
        // TODO: make threadsafe
        if ( == null = getRuntime().getEncodingService().loadEncoding();
        return ;
    }
    
    private static Encoding extractEncodingFromObject(IRubyObject obj) {
        if (obj instanceof RubyEncodingreturn ((RubyEncodingobj).getEncoding();
        if (obj instanceof RubySymbolreturn ((RubySymbolobj).asString().getEncoding();
        if (obj instanceof EncodingCapablereturn ((EncodingCapableobj).getEncoding();
        
        return null;
    }
    public static Encoding areCompatible(IRubyObject obj1IRubyObject obj2) {
        Encoding enc1 = extractEncodingFromObject(obj1);
        Encoding enc2 = extractEncodingFromObject(obj2);
        
        if (enc1 == null || enc2 == nullreturn null;
        if (enc1 == enc2return enc1;
        if (obj2 instanceof RubyString && ((RubyStringobj2).getByteList().getRealSize() == 0) return enc1;
        if (obj1 instanceof RubyString && ((RubyStringobj1).getByteList().getRealSize() == 0) {
            return enc1.isAsciiCompatible() && obj2 instanceof RubyString && 
                    ((RubyStringobj2).isAsciiOnly() ? enc1 : enc2;
        }
        
        if (!enc1.isAsciiCompatible() || !enc2.isAsciiCompatible()) return null;
        if (!(obj2 instanceof RubyString) && enc2 instanceof USASCIIEncodingreturn enc1;
        if (!(obj1 instanceof RubyString) && enc1 instanceof USASCIIEncodingreturn enc2;
        if (!(obj1 instanceof RubyString)) {
            IRubyObject objTmp = obj1// swap1 obj1 & obj2
            obj1 = obj2;
            obj2 = objTmp;
            Encoding encTmp = enc1;  // swap their encodings
            enc1 = enc2;
            enc2 = encTmp;
        }
        if (obj1 instanceof RubyString) {
            int cr1 = ((RubyString)obj1).scanForCodeRange();
            if (obj2 instanceof RubyString) {
                int cr2 = ((RubyString)obj2).scanForCodeRange();
                return areCompatible(enc1cr1enc2cr2);
            }
            if (cr1 == .return enc2;
        }
        return null;
    }
    // last block in rb_enc_compatible
    static Encoding areCompatible(Encoding enc1int cr1Encoding enc2int cr2) {
        if (cr1 != cr2) {
            /* may need to handle ENC_CODERANGE_BROKEN */
            if (cr1 == .return enc2;
            if (cr2 == .return enc1;
        }
        if (cr2 == .return enc1;
        if (cr1 == .return enc2;
        return null;
    }
    public static byte[] encodeUTF8(CharSequence cs) {
        return getUTF8Coder().encode(cs);
    }
    public static byte[] encodeUTF8(String str) {
        return getUTF8Coder().encode(str);
    }
    private static final int CHAR_ARRAY_BASE;
    private static final int BYTE_ARRAY_BASE;
    private static final Field VALUE_FIELD;
    private static final long VALUE_FIELD_OFFSET;
    static {
        Field valueField = null;
        try {
            valueField = String.class.getDeclaredField("value");
        } catch (Exception e) {
        }
         = valueField;
        long valueFieldOffset = -1;
        try {
            valueFieldOffset = ..objectFieldOffset();
        } catch (Exception e) {
        }
         = valueFieldOffset;
        int charArrayBase = -1;
        try {
            charArrayBase = ..arrayBaseOffset(char[].class);
        } catch (Exception e) {
        }
         = charArrayBase;
        int byteArrayBase = -1;
        try {
            byteArrayBase = ..arrayBaseOffset(byte[].class);
        } catch (Exception e) {
        }
         = byteArrayBase;
    }
    public static byte[] encodeUTF16(String str) {
        if ( == -1) return encode(str);
        char[] chars = (char[]) ..getObject(str);
        int length = chars.length * 2;
        byte[] bytes = new byte[length];
        ..copyMemory(charsbyteslength);
        return bytes;
    }
    public static byte[] encodeUTF16(CharSequence str) {
        return encodeUTF16(str.toString());
    }
    public static byte[] encode(CharSequence csCharset charset) {
        ByteBuffer buffer = charset.encode(cs.toString());
        byte[] bytes = new byte[buffer.limit()];
        buffer.get(bytes);
        return bytes;
    }
    public static byte[] encode(String strCharset charset) {
        ByteBuffer buffer = charset.encode(str);
        byte[] bytes = new byte[buffer.limit()];
        buffer.get(bytes);
        return bytes;
    }
    public static String decodeUTF8(byte[] bytesint startint length) {
        return getUTF8Coder().decode(bytesstartlength);
    }
    public static String decodeUTF8(byte[] bytes) {
        return getUTF8Coder().decode(bytes);
    }
    public static String decode(byte[] bytesint startint lengthCharset charset) {
        return charset.decode(ByteBuffer.wrap(bytesstartlength)).toString();
    }
    public static String decode(byte[] bytesCharset charset) {
        return charset.decode(ByteBuffer.wrap(bytes)).toString();
    }
    
    private static class UTF8Coder {
        private final CharsetEncoder encoder = .newEncoder();
        private final CharsetDecoder decoder = .newDecoder();
        
The maximum number of characters we can encode/decode in our cached buffers
        private static final int CHAR_THRESHOLD = 1024;
        
The resulting encode/decode buffer sized by the max number of characters (using 4 bytes per char possible for utf-8)
        private static final int BUF_SIZE =  * 4;
        private final ByteBuffer byteBuffer = ByteBuffer.allocate();
        private final CharBuffer charBuffer = CharBuffer.allocate();
        public UTF8Coder() {
        }
        public byte[] encode(CharSequence cs) {
            ByteBuffer buffer;
            if (cs.length() > ) {
                buffer = .encode(cs.toString());
            } else {
                buffer = ;
                CharBuffer cbuffer = ;
                buffer.clear();
                cbuffer.clear();
                cbuffer.put(cs.toString());
                cbuffer.flip();
                .encode(cbufferbuffertrue);
                buffer.flip();
            }
            
            byte[] bytes = new byte[buffer.limit()];
            buffer.get(bytes);
            return bytes;
        }
        
        public String decode(byte[] bytesint startint length) {
            CharBuffer cbuffer;
            if (length > ) {
                cbuffer = .decode(ByteBuffer.wrap(bytesstartlength));
            } else {
                cbuffer = ;
                ByteBuffer buffer = ;
                cbuffer.clear();
                buffer.clear();
                buffer.put(bytesstartlength);
                buffer.flip();
                .decode(buffercbuffertrue);
                cbuffer.flip();
            }
            
            return cbuffer.toString();
        }
        
        public String decode(byte[] bytes) {
            return decode(bytes, 0, bytes.length);
        }
    }

    
UTF8Coder wrapped in a SoftReference to avoid possible ClassLoader leak. See JRUBY-6522
    private static final ThreadLocal<SoftReference<UTF8Coder>> UTF8_CODER =
        new ThreadLocal<SoftReference<UTF8Coder>>();
    private static UTF8Coder getUTF8Coder() {
        UTF8Coder coder;
        SoftReference<UTF8Coderref = .get();
        if (ref == null || (coder = ref.get()) == null) {
            coder = new UTF8Coder();
            ref = new SoftReference<UTF8Coder>(coder);
            .set(ref);
        }
        
        return coder;
    }
    @JRubyMethod(name = "list", meta = true)
    public static IRubyObject list(ThreadContext contextIRubyObject recv) {
        Ruby runtime = context.runtime;
        return RubyArray.newArrayNoCopy(runtimeruntime.getEncodingService().getEncodingList(), 0);
    }
    @JRubyMethod(name = "locale_charmap", meta = true)
    public static IRubyObject locale_charmap(ThreadContext contextIRubyObject recv) {
        Ruby runtime = context.runtime;
        EncodingService service = runtime.getEncodingService();
        ByteList name = new ByteList(service.getLocaleEncoding().getName());
        
        return RubyString.newUsAsciiStringNoCopy(runtimename);
    }
    @SuppressWarnings("unchecked")
    @JRubyMethod(name = "name_list", meta = true)
    public static IRubyObject name_list(ThreadContext contextIRubyObject recv) {
        Ruby runtime = context.runtime;
        EncodingService service = runtime.getEncodingService();
        
        RubyArray result = runtime.newArray(service.getEncodings().size() + service.getAliases().size());
        HashEntryIterator i;
        i = service.getEncodings().entryIterator();
        while (i.hasNext()) {
                ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)i.next());
            result.append(RubyString.newUsAsciiStringShared(runtimee.bytese.pe.end - e.p).freeze(context));
        }
        i = service.getAliases().entryIterator();        
        while (i.hasNext()) {
                ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)i.next());
            result.append(RubyString.newUsAsciiStringShared(runtimee.bytese.pe.end - e.p).freeze(context));
        }
        result.append(runtime.newString());
        result.append(runtime.newString());
        
        return result;
    }
    @SuppressWarnings("unchecked")
    @JRubyMethod(name = "aliases", meta = true)
    public static IRubyObject aliases(ThreadContext contextIRubyObject recv) {
        Ruby runtime = context.runtime;
        EncodingService service = runtime.getEncodingService();
        IRubyObject list[] = service.getEncodingList();
        HashEntryIterator i = service.getAliases().entryIterator();
        RubyHash result = RubyHash.newHash(runtime);
        while (i.hasNext()) {
                ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)i.next());
            IRubyObject alias = RubyString.newUsAsciiStringShared(runtimee.bytese.pe.end - e.p).freeze(context);
            IRubyObject name = RubyString.newUsAsciiStringShared(runtime
                                ((RubyEncoding)list[e.value.getIndex()]).).freeze(context);
            result.fastASet(aliasname);
        }
        result.fastASet(runtime.newString(),
                runtime.newString(new ByteList(runtime.getDefaultExternalEncoding().getName())));
        result.fastASet(runtime.newString(),
                runtime.newString(new ByteList(service.getLocaleEncoding().getName())));
        return result;
    }
    @JRubyMethod(name = "find", meta = true)
    public static IRubyObject find(ThreadContext contextIRubyObject recvIRubyObject str) {
        Ruby runtime = context.runtime;
        // Wacky but true...return arg if it is an encoding looking for itself
        if (str instanceof RubyEncodingreturn str;
        return runtime.getEncodingService().rubyEncodingFromObject(str);
    }
    @JRubyMethod(name = "replicate")
    public IRubyObject replicate(ThreadContext contextIRubyObject arg) {
        return new RubyEncoding(context.runtimearg.convertToString().getBytes(), getEncoding(), );
    }
    @JRubyMethod(name = "_dump")
    public IRubyObject _dump(ThreadContext contextIRubyObject arg) {
        return to_s(context);
    }
    @JRubyMethod(name = "_load", meta = true)
    public static IRubyObject _load(ThreadContext contextIRubyObject recvIRubyObject str) {
        return find(contextrecvstr);
    }
    @JRubyMethod(name = "ascii_compatible?")
    public IRubyObject asciiCompatible_p(ThreadContext context) {
        return context.runtime.newBoolean(getEncoding().isAsciiCompatible());
    }
    @JRubyMethod(name = {"to_s""name"})
    public IRubyObject to_s(ThreadContext context) {
        // TODO: rb_usascii_str_new2
        return RubyString.newUsAsciiStringShared(context.runtime);
    }
    @JRubyMethod(name = "inspect")
    public IRubyObject inspect(ThreadContext context) {
        ByteList bytes = new ByteList();
        bytes.append("#<Encoding:".getBytes());
        bytes.append();
        if (bytes.append(" (dummy)".getBytes());
        bytes.append('>');
        return RubyString.newUsAsciiStringNoCopy(context.runtimebytes);
    }
    @SuppressWarnings("unchecked")
    @JRubyMethod(name = "names")
    public IRubyObject names(ThreadContext context) {
        Ruby runtime = context.runtime;
        EncodingService service = runtime.getEncodingService();
        Entry entry = service.findEncodingOrAliasEntry();
        RubyArray result = runtime.newArray();
        HashEntryIterator i;
        i = service.getEncodings().entryIterator();
        while (i.hasNext()) {
                ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)i.next());
            if (e.value == entry) {
                result.append(RubyString.newUsAsciiStringShared(runtimee.bytese.pe.end - e.p).freeze(context));
            }
        }
        i = service.getAliases().entryIterator();        
        while (i.hasNext()) {
                ((CaseInsensitiveBytesHash.CaseInsensitiveBytesHashEntry<Entry>)i.next());
            if (e.value == entry) {
                result.append(RubyString.newUsAsciiStringShared(runtimee.bytese.pe.end - e.p).freeze(context));
            }
        }
        result.append(runtime.newString());
        result.append(runtime.newString());
        
        return result;
    }
    @JRubyMethod(name = "dummy?")
    public IRubyObject dummy_p(ThreadContext context) {
        return context.runtime.newBoolean();
    }
    @JRubyMethod(name = "compatible?", meta = true)
    public static IRubyObject compatible_p(ThreadContext contextIRubyObject selfIRubyObject firstIRubyObject second) {
        Ruby runtime = context.runtime;
        Encoding enc = areCompatible(firstsecond);
        return enc == null ? runtime.getNil() : runtime.getEncodingService().getEncoding(enc);
    }
    @JRubyMethod(name = "default_external", meta = true, compat = )
    public static IRubyObject getDefaultExternal(ThreadContext contextIRubyObject recv) {
        return context.runtime.getEncodingService().getDefaultExternal();
    }
    @JRubyMethod(name = "default_external=", meta = true, compat = )
    public static IRubyObject setDefaultExternal(ThreadContext contextIRubyObject recvIRubyObject encoding) {
        if (context.runtime.isVerbose()) context.runtime.getWarnings().warning("setting Encoding.default_external");
        EncodingUtils.rbEncSetDefaultExternal(contextencoding);
        return encoding;
    }
    @JRubyMethod(name = "default_internal", meta = true, compat = )
    public static IRubyObject getDefaultInternal(ThreadContext contextIRubyObject recv) {
        return context.runtime.getEncodingService().getDefaultInternal();
    }
    @JRubyMethod(name = "default_internal=", required = 1, meta = true, compat = )
    public static IRubyObject setDefaultInternal(ThreadContext contextIRubyObject recvIRubyObject encoding) {
        if (context.runtime.isVerbose()) context.runtime.getWarnings().warning("setting Encoding.default_internal");
        EncodingUtils.rbEncSetDefaultInternal(contextencoding);
        return encoding;
    }
    
    @Deprecated
    public static IRubyObject getDefaultInternal(IRubyObject recv) {
        return getDefaultExternal(recv.getRuntime().getCurrentContext(), recv);
    }
    
    @Deprecated
    public static IRubyObject setDefaultInternal(IRubyObject recvIRubyObject encoding) {
        return setDefaultExternal(recv.getRuntime().getCurrentContext(), recvencoding);
    }
    @Deprecated
    public static IRubyObject getDefaultExternal(Ruby runtime) {
        return runtime.getEncodingService().getDefaultExternal();
    }
    @Deprecated
    public static IRubyObject getDefaultInternal(Ruby runtime) {
        return runtime.getEncodingService().getDefaultInternal();
    }
    @Deprecated
    public static IRubyObject convertEncodingToRubyEncoding(Ruby runtimeEncoding defaultEncoding) {
        return runtime.getEncodingService().convertEncodingToRubyEncoding(defaultEncoding);
    }
    @Deprecated
    public static Encoding getEncodingFromObject(Ruby runtimeIRubyObject arg) {
        return runtime.getEncodingService().getEncodingFromObject(arg);
    }