<commit_before>// Copyright (C) 2011 jOVAL.org.  All rights reserved.
// This software is licensed under the LGPL 3.0 license available at http://www.gnu.org/licenses/lgpl.txt

package jsaf.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.StringTokenizer;

import jsaf.intf.util.IProperty;

/**
 * A class for interpreting an ini-style config file.  Each header is treated as a section full of properties.  Comment
 * lines begin with a ';'.  Delimiters can be either ':' or '=', and can appear in the name of a Key if escaped in the file
 * using a \ character.  Key and value names are trimmed of leading and trailing white-space.  Multi-line values can be
 * created by ending the line with the \ character, in which case whitespace is not trimmed.
 *
 * @author <NAME>
 * @version %I% %G%
 * @since 1.0
 */
public class IniFile {
    private static final String SEMICOLON	= ";";
    private static final String ESC		= "\\";
    private static final String COLON		= ":";
    private static final String EQUAL		= "=";

    private Hashtable<String, IProperty> sections;

    /**
     * Create an empty IniFile.
     */
    public IniFile() {
	sections = new Hashtable<String, IProperty>();
    }

    /**
     * Create a new IniFile from a File using the default encoding.
     */
    public IniFile(File f) throws IOException {
	this();
	load(f);
    }

    /**
     * Create a new IniFile from a stream using the default encoding..
     */
    public IniFile(InputStream in) throws IOException {
	this();
	load(in);
    }

    /**
     * Create a new IniFile from a stream using the specified encoding.
     *
     * @since 1.0
     */
    public IniFile(InputStream in, Charset encoding) throws IOException {
	this();
	load(in, encoding);
    }

    /**
     * A convenience method for loading files, using the default encoding.
     *
     * @since 1.0
     */
    public void load(File f) throws IOException {
	load(new FileInputStream(f));
    }

    /**
     * Add configuration data from a stream.  If the IniFile already contains configuration information,
     * the information from the stream is added.
     *
     * @since 1.0
     */
    public void load(InputStream in) throws IOException {
	load(in, Charset.defaultCharset());
    }

    /**
     * Load using a specific encoding.
     *
     * @since 1.0
     */
    public void load(InputStream in, Charset encoding) throws IOException {
	BufferedReader br = null;
	try {
	    br = new BufferedReader(new InputStreamReader(in, encoding));
	    String line = null;
	    IProperty section = null;
	    String name = null;
	    int ptr;
	    while ((line = br.readLine()) != null) {
		if (line.startsWith("[") && line.trim().endsWith("]")) {
		    name = line.substring(1, line.length() - 1);
		    section = sections.get(name);
		    if (section == null) {
			section = new PropertyUtil();
			sections.put(name, section);
		    }
		} else if (line.startsWith(SEMICOLON)) {
		    // skip comment
		} else if ((ptr = delimIndex(line)) > 0) {
		    if (section != null) {
			String rawKey = line.substring(0,ptr).trim();
			StringTokenizer tok = new StringTokenizer(rawKey, ESC);
			StringBuffer sb = new StringBuffer(tok.nextToken());
			while(tok.hasMoreTokens()) {
			    String token = tok.nextToken();<commit_msg>Add '#' as INI file comment character.<commit_after>// Copyright (C) 2011 jOVAL.org.  All rights reserved.
// This software is licensed under the LGPL 3.0 license available at http://www.gnu.org/licenses/lgpl.txt

package jsaf.util;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.StringTokenizer;

import jsaf.intf.util.IProperty;

/**
 * A class for interpreting an ini-style config file.  Each header is treated as a section full of properties.  Comment
 * lines begin with a ';'.  Delimiters can be either ':' or '=', and can appear in the name of a Key if escaped in the file
 * using a \ character.  Key and value names are trimmed of leading and trailing white-space.  Multi-line values can be
 * created by ending the line with the \ character, in which case whitespace is not trimmed.
 *
 * @author <NAME>
 * @version %I% %G%
 * @since 1.0
 */
public class IniFile {
    private static final String SEMICOLON	= ";";
    private static final String HASH		= "#";
    private static final String ESC		= "\\";
    private static final String COLON		= ":";
    private static final String EQUAL		= "=";

    private Hashtable<String, IProperty> sections;

    /**
     * Create an empty IniFile.
     */
    public IniFile() {
	sections = new Hashtable<String, IProperty>();
    }

    /**
     * Create a new IniFile from a File using the default encoding.
     */
    public IniFile(File f) throws IOException {
	this();
	load(f);
    }

    /**
     * Create a new IniFile from a stream using the default encoding..
     */
    public IniFile(InputStream in) throws IOException {
	this();
	load(in);
    }

    /**
     * Create a new IniFile from a stream using the specified encoding.
     *
     * @since 1.0
     */
    public IniFile(InputStream in, Charset encoding) throws IOException {
	this();
	load(in, encoding);
    }

    /**
     * A convenience method for loading files, using the default encoding.
     *
     * @since 1.0
     */
    public void load(File f) throws IOException {
	load(new FileInputStream(f));
    }

    /**
     * Add configuration data from a stream.  If the IniFile already contains configuration information,
     * the information from the stream is added.
     *
     * @since 1.0
     */
    public void load(InputStream in) throws IOException {
	load(in, Charset.defaultCharset());
    }

    /**
     * Load using a specific encoding.
     *
     * @since 1.0
     */
    public void load(InputStream in, Charset encoding) throws IOException {
	BufferedReader br = null;
	try {
	    br = new BufferedReader(new InputStreamReader(in, encoding));
	    String line = null;
	    IProperty section = null;
	    String name = null;
	    int ptr;
	    while ((line = br.readLine()) != null) {
		if (line.startsWith("[") && line.trim().endsWith("]")) {
		    name = line.substring(1, line.length() - 1);
		    section = sections.get(name);
		    if (section == null) {
			section = new PropertyUtil();
			sections.put(name, section);
		    }
		} else if (line.startsWith(SEMICOLON) || line.startsWith(HASH)) {
		    // skip comment
		} else if ((ptr = delimIndex(line)) > 0) {
		    if (section != null) {
			String rawKey = line.substring(0,ptr).trim();
			StringTokenizer tok = new StringTokenizer(rawKey, ESC);
			StringBuffer sb = new StringBuffer(tok.nextToken());
			while(tok.hasMoreTokens()) {
			    String token = tok.nextToken();
{'fraction_non_alphanumeric': 0.11333422854840876, 'fraction_numerical': 0.005371290452531221, 'mean_word_length': 2.9470058293587704, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2103399', 'n_tokens_mistral': 2329, 'n_tokens_neox': 2203, 'n_words': 744}