All Downloads are FREE. Search and download functionalities are using the official Maven repository.

prompto.compiler.Utf8Constant Maven / Gradle / Ivy

The newest version!
package prompto.compiler;

import java.util.Objects;

public class Utf8Constant implements IInternalConstant {
	
	String value;
	int index;
	
	public Utf8Constant(String value) {
		this.value = value;
	}

	@Override
	public int getTag() {
		return Tags.CONSTANT_Utf8;
	}
	
	@Override
	public String toString() {
		return this.value;
	}
	
	public String getValue() {
		return value;
	}
	
	@Override
	public int hashCode() {
		return Objects.hash(value);
	}

	@Override
	public boolean equals(Object obj) {
		return obj instanceof Utf8Constant 
				&& value.equals(((Utf8Constant)obj).value);
	}
	
	@Override
	public int getIndexInConstantPool() {
		if(index==-1)
			throw new UnsupportedOperationException();
		return index;
	}
	
	@Override
	public void register(ConstantsPool pool) {
		index = pool.registerConstant(this);
	}
	
	@Override
	public void writeTo(ByteWriter writer) {
		writer.writeU1(Tags.CONSTANT_Utf8);
		byte[] utf8 = toModifiedUtf8(value);
		writer.writeU2(utf8.length);
		writer.writeBytes(utf8);
	}

	/* need to transcode to modified UTF-8 */
	/* could not find a transcoder in the JVM so had to write one */
	/* see CONSTANT_Utf8_info at https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html */
	static byte[] toModifiedUtf8(String s) {
		char[] cc = s.toCharArray();
		byte[] bb = new byte[cc.length*6];
		int len = 0;
		for(char c : cc) {
			if(c>=0x0001 && c<=0x007F)
				bb[len++] = (byte)(c & 0x7F);
			else if(c==0x000 || (c>=0x0080 && c<=0x07FF)) {
				// ((x & 0x1f) << 6) + (y & 0x3f)
				bb[len++] = (byte)(0xC0 | ((c >> 6) & 0x1F));
				bb[len++] = (byte)(0x80 | (c & 0x3F));
			} else if(c>=0x0800 && c<=0xFFFF) {
				// ((x & 0xf) << 12) + ((y & 0x3f) << 6) + (z & 0x3f)
				bb[len++] = (byte)(0xE0 | ((c >> 12) & 0x0F));
				bb[len++] = (byte)(0x80 | ((c >> 6) & 0x3F));
				bb[len++] = (byte)(0x80 | (c & 0x3F));
			} else {
				// 0x10000 + ((v & 0x0f) << 16) + ((w & 0x3f) << 10) + ((y & 0x0f) << 6) + (z & 0x3f)
				bb[len++] = (byte)0xED;
				bb[len++] = (byte)(0xA0 | (((c-0x00001) >> 16) & 0x0F));
				bb[len++] = (byte)(0x80 | ((c >> 10) & 0x3F));
				bb[len++] = (byte)0xED;
				bb[len++] = (byte)(0x80 | ((c >> 6) & 0x3F));
				bb[len++] = (byte)(0x80 | (c & 0x3F));
			}
		}
		byte[] res = new byte[len];
		System.arraycopy(bb, 0, res, 0, len);
		return res;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy