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

aQute.lib.json.Decoder Maven / Gradle / Ivy

The newest version!
package aQute.lib.json;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.InflaterInputStream;

import aQute.lib.converter.TypeReference;
import aQute.lib.io.IO;

public class Decoder implements Closeable {
	final JSONCodec		codec;
	Reader				reader;
	int					current;
	MessageDigest		digest;
	Map	extra;
	Charset				encoding	= UTF_8;
	int					line		= 0, position = 0;

	boolean				strict;
	boolean				inflate;
	boolean				keepOpen	= false;

	Decoder(JSONCodec codec) {
		this.codec = codec;
	}

	public Decoder from(File file) throws Exception {
		return from(IO.stream(file));
	}

	public Decoder from(InputStream in) throws Exception {

		if (inflate)
			in = new InflaterInputStream(in);

		return from(new InputStreamReader(in, encoding));
	}

	public Decoder from(byte[] data) throws Exception {
		return from(new ByteArrayInputStream(data));
	}

	public Decoder charset(String encoding) {
		return charset(Charset.forName(encoding));
	}

	public Decoder charset(Charset encoding) {
		this.encoding = encoding;
		return this;
	}

	public Decoder strict() {
		this.strict = true;
		return this;
	}

	public Decoder from(Reader in) throws Exception {
		reader = in;
		read();
		return this;
	}

	public Decoder faq(String in) throws Exception {
		return from(in.replace('\'', '"'));
	}

	public Decoder from(String in) throws Exception {
		return from(new StringReader(in));
	}

	public Decoder mark() throws NoSuchAlgorithmException {
		if (digest == null)
			digest = MessageDigest.getInstance("SHA-1");
		digest.reset();
		return this;
	}

	public byte[] digest() {
		if (digest == null)
			return null;

		return digest.digest();
	}

	@SuppressWarnings("unchecked")
	public  T get(Class clazz) throws Exception {
		try {
			return (T) codec.decode(clazz, this);
		} finally {
			if (!keepOpen)
				close();
		}
	}

	public Object get(Type type) throws Exception {
		try {
			return codec.decode(type, this);
		} finally {
			if (!keepOpen)
				close();
		}
	}

	public Object get() throws Exception {
		try {
			return codec.decode(null, this);
		} finally {
			if (!keepOpen)
				close();
		}
	}

	@SuppressWarnings("unchecked")
	public  T get(TypeReference ref) throws Exception {
		try {
			return (T) codec.decode(ref.getType(), this);
		} finally {
			if (!keepOpen)
				close();
		}
	}

	public Decoder keepOpen() {
		keepOpen = true;
		return this;
	}

	int read() throws Exception {
		current = reader.read();
		if (digest != null) {
			digest.update((byte) (current / 256));
			digest.update((byte) (current % 256));
		}
		if (current == '\n') {
			line++;
			position = 0;
		} else {
			position++;
		}
		return current;
	}

	int current() {
		return current;
	}

	/**
	 * Skip any whitespace.
	 *
	 * @throws Exception
	 */
	int skipWs() throws Exception {
		while (Character.isWhitespace(current()))
			read();
		return current();
	}

	/**
	 * Skip any whitespace.
	 *
	 * @throws Exception
	 */
	int next() throws Exception {
		read();
		return skipWs();
	}

	void expect(String s) throws Exception {
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			int r= read();
			if ( r < 0)
				fatal("Expected " + s + " but got something different");

			if (!(c == r)) {
				if ( codec.promiscuous) {
					char a = Character.toLowerCase(c);
					char b = Character.toLowerCase((char) r);
					if (a == b)
						continue;
				}
				throw new IllegalArgumentException("Expected " + s + " but got something different");
			}
		}
		read();
	}

	public boolean isEof() throws Exception {
		int c = skipWs();
		return c < 0;
	}

	@Override
	public void close() throws IOException {
		reader.close();
	}

	public Map getExtra() {
		if (extra == null)
			extra = new HashMap<>();
		return extra;
	}

	public Decoder inflate() {
		if (reader != null)
			throw new IllegalStateException("Reader already set, inflate must come before from()");
		inflate = true;
		return this;
	}

	public void badJSON(String reason) {
		if (codec.promiscuous) {
			codec.fishy.incrementAndGet();
			return;
		}
		throw new IllegalArgumentException(line + "," + position + ": " + reason);
	}

	public void fatal(String message) {
		throw new IllegalArgumentException(line + "," + position + ": " + message);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy