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

com.github.bloodshura.ignitium.cfg.props.serial.PropertiesLexer Maven / Gradle / Ivy

Go to download

A collection of configuration and serialization readers and writers, like JSON, internationalization (I18n), and CSV.

There is a newer version: 1.0.1
Show newest version
package com.github.bloodshura.ignitium.cfg.props.serial;

import com.github.bloodshura.ignitium.charset.TextBuilder;
import com.github.bloodshura.ignitium.collection.list.XList;
import com.github.bloodshura.ignitium.collection.list.impl.XLinkedList;
import com.github.bloodshura.ignitium.io.stream.TextReader;
import com.github.bloodshura.ignitium.worker.StringWorker;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;

public class PropertiesLexer {
	private final PropertySerializationAttributes attributes;
	private PropertyEntry cachedNext;
	private boolean lastWasKey;
	private final TextReader reader;

	public PropertiesLexer(@Nonnull PropertySerializationAttributes attributes, @Nonnull TextReader reader) {
		this.attributes = attributes;
		this.reader = reader;
	}

	@Nonnull
	public PropertySerializationAttributes getAttributes() {
		return attributes;
	}

	public boolean hasNext() throws IOException {
		return cachedNext != null || (this.cachedNext = next()) != null;
	}

	@Nullable
	public PropertyEntry next() throws IOException {
		if (cachedNext != null) {
			PropertyEntry entry = cachedNext;

			this.cachedNext = null;

			return entry;
		}

		TextBuilder builder = new TextBuilder();
		XList list = null;
		boolean hadQuotes = false;
		boolean insideQuotes = false;
		boolean isCommented = false;
		boolean lastSlash = false;
		boolean simpleQuote = false;

		while (true) {
			int read = reader.readChar();

			if (read == -1) {
				if (lastWasKey && !builder.isEmpty() && list == null) {
					this.lastWasKey = false;

					return new PropertyEntry(PropertyEntry.Type.VALUE_DEF, builder.toString(), hadQuotes, builder.length() == 1 && simpleQuote);
				}

				return null;
			}

			char ch = (char) read;

			if (isCommented) {
				if (ch == '\n') {
					isCommented = false;

					if (lastWasKey && !builder.isEmpty() && list == null) {
						this.lastWasKey = false;

						return new PropertyEntry(PropertyEntry.Type.VALUE_DEF, builder.toString(), hadQuotes, builder.length() == 1 && simpleQuote);
					}
				}
			} else if (ch == getAttributes().getCommenter() && !insideQuotes) {
				isCommented = true;
			} else if (ch == getAttributes().getListOpener() && !insideQuotes && lastWasKey) {
				list = new XLinkedList<>();
				builder.clear();
			} else if (ch == getAttributes().getListCloser() && !insideQuotes && list != null) {
				if (!builder.isEmpty()) {
					list.add(builder.toStringAndClear());
				}

				this.lastWasKey = false;

				return new PropertyEntry(PropertyEntry.Type.VALUE_DEF, list, PropertyEntry.ENFORCE_NONE);
			} else if (ch == getAttributes().getListSeparator() && !insideQuotes && list != null) {
				list.add(builder.toStringAndClear());
			} else if (ch == '\n') {
				if (lastWasKey && list == null) {
					this.lastWasKey = false;

					if (builder.isEmpty()) {
						return next();
					}

					return new PropertyEntry(PropertyEntry.Type.VALUE_DEF, builder.toString(), hadQuotes, builder.length() == 1 && simpleQuote);
				}
			} else if (ch == getAttributes().getSeparator() && !insideQuotes && !lastWasKey && !builder.isEmpty()) {
				this.lastWasKey = true;

				return new PropertyEntry(PropertyEntry.Type.KEY_DEF, builder.toString(), PropertyEntry.ENFORCE_STRING);
			} else if ((ch == getAttributes().getStringIndexer() && !lastSlash) && (!insideQuotes || !simpleQuote)) {
				hadQuotes = true;
				insideQuotes = !insideQuotes;
			} else if ((ch == getAttributes().getCharIndexer() && !lastSlash) && (!insideQuotes || simpleQuote)) {
				hadQuotes = true;
				insideQuotes = !insideQuotes;
				simpleQuote = true;
			} else if (lastSlash) {
				builder.append(StringWorker.unescape("\\" + ch));
			} else if (ch == '\\') {
				lastSlash = true;

				continue;
			} else if (ch != '\r' && (insideQuotes || (ch != ' ' && ch != '\t'))) {
				builder.append(ch);
			}

			lastSlash = false;
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy