[Webfunds-commits] java/webfunds/util FormattedFileException.java IniFileReader.java

Ian Grigg iang@cypherpunks.ai
Thu, 5 Apr 2001 13:50:42 -0400 (AST)


iang        01/04/05 13:50:42

  Added:       webfunds/util FormattedFileException.java IniFileReader.java
  Log:
  Copied IniFileReader into util, changed Ex to something generic.
  These are generally used in about 4 places, do not belong in ricardian.
  (Rest of code will migrate presently.)

Revision  Changes    Path
1.1                  java/webfunds/util/FormattedFileException.java

Index: FormattedFileException.java
===================================================================
/*
 * $Id: FormattedFileException.java,v 1.1 2001/04/05 17:50:41 iang Exp $
 *
 * Copyright (c) 2001 Systemics Inc on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */
package webfunds.util;

public class FormattedFileException
    extends ExceptionModel
{
    /**
     *  Known Formatted File failure modes detected.
     */
    public static final int
                              CATCH_ALL      = 1, // catch all for other errors
                              FILE_ERROR     = 2, // file could not be read
                              NO_DATA        = 3, // not enough contract data
                              MULTILINE      = 4; // multiline not terminated

    public static final String[] errors = {
                              "<not set, old Ex>",
                              "'miscellaneous error'",
                              "File Error",
                              "No Data",
                              "Multi-line Field Is Not Terminated"
                              };


    /**
     *  The line number where the error occurred, counting from 0 to n-1,
     *  if available (-1 is not set).
     */
    protected int line = -1;
    public int    getLine()   { return line; }


    public String getErrnoString()
    {
        if (! (0 <= number && number < errors.length) )
            return "<invalid: " + number + ">";

        String e = errors[number];

        return "(" + number + ") " + ((e == null) ? "'unknown'" : e);
    }

    public String toString()
    {
        String s = "";
        if (number > 0)
            s += getErrnoString() + ": ";
        s += super.toString();
        if (line >= 0)
            s += " [line " + line + "]";
        return s;
    }

    
    public FormattedFileException(String msg)
    {
        super(UNKNOWN, msg);
    }

    /**
     *  line number is set to default of -1
     *
     *  @param num an identified error from public constants above
     *  @param msg string interpretation
     */
    public FormattedFileException(int num, String msg)
    {
        super(num, msg);
    }

    /**
     *  @param num an identified error from public constants above
     *  @param line where (approximately) it happened in the file
     *  @param msg string interpretation
     */
    public FormattedFileException(int num, int line, String msg)
    {
        super(num, msg);
        this.line  = line;
    }
}



1.1                  java/webfunds/util/IniFileReader.java

Index: IniFileReader.java
===================================================================
/*
 * $Id: IniFileReader.java,v 1.1 2001/04/05 17:50:41 iang Exp $
 *
 * Copyright (c) Systemics Ltd 1995-1999 on behalf of
 * the WebFunds Development Team.  All Rights Reserved.
 */
package webfunds.util;

import java.util.*;
import java.io.*;


/**
 *  This class handles files in the windows ini format.
 *  Currently used by SSD and Ricardian Contracts.
 */
public class IniFileReader
{

//----------------------DATA MEMBERS------------------------------
    // data Members
    private Hashtable indextable;   // what is this used for?  only put()
    private Hashtable sections;


//----------------------CONSTRUCTORS--------------------------------
    /**
     * Default constructor creates an empty IniFileReader
     *
     */
    public IniFileReader()
    {
        startEmpty();
    }

    protected void startEmpty()
    {
        sections = new Hashtable();
        indextable = new Hashtable();
    }


    /**
     * read a ini formated file and put in the class
     * @param iniFileAsByteArray  the byte array containing the ini file
     * @except FormattedFileException bad multiline or mixed mode eolns.
     */
    public IniFileReader(byte[] data)
        throws FormattedFileException
    {
        startEmpty();
        addByteArray(data);
    }

    /**
     * Add the contents of an ini-file formated byte array.
     * @param data  the byte array containing the additional ini file
     * @except FormattedFileException bad multiline or mixed mode eolns.
     */
    public void addByteArray(byte[] data)
        throws FormattedFileException
    {
        if (data == null || data.length == 0)
            return ;

        add(data);
    }



    final static int         TRIM_WHITE_SPACE = 3;
    protected static String  lastErrors = "";
    protected static String  lastEoln = "";
    protected static int     numErrors = 0;
    public static String     getLastErrors() { return lastErrors ; }
    public static int        getNumErrors()  { return numErrors ; }

    /**
     * Take a byte array and turn it into an array of trimmed lines.
     */
    public static String[] toLines(byte[] txt)
    {
        return toLines(txt, TRIM_WHITE_SPACE);
    }

    /**
     * Take a byte array and turn it into an array of lines.
     * A line is terminated by an eoln string, which must be the
     * the same throughout the array.
     *
     * Note.  This is used because the semantics are precise, whereas
     * the equivalent in java.io.* is unclear, or sufficiently
     * murky for the hashing task.  Also, the exceptions are boring.
     *
     * @param If version >= 3 then proper trim is used.
     * @except FormattedFileException if mixed eoln strings are found
     */
    public static String[] toLines(byte[] txt, int version)
    {
        numErrors = 0; lastErrors = lastEoln = "";

        if (txt == null || txt.length == 0)
            return new String[0];

        byte[] eoln = null;
        Stack stuk = new Stack();
        int next = 0;
        int lineCount = 0;         // for diags only
        int total = txt.length;
        while (next < total)
        {
            int q = next;
            while (q < total && txt[q] != '\n' && txt[q] != '\r')
                q++;


            int end = q;
            if (version >= TRIM_WHITE_SPACE)      // for hash/sig
            {
                while (end > next && (0<=txt[end-1] && txt[end-1]<='\u0020'))
                    --end;
// System.err.println("         trimmed " + (q - end) + " chars");
            }
            
            // reached the end of line
// System.err.println("       next == " + next + " end == " + end);
            String s = new String(txt, next, end - next);
// System.err.println("       <" + s + ">");
            stuk.push(s);
            lineCount++;

            if (q == total) // no last eoln not quite an error, too common
            {
               lastErrors += " eoln? " + lineCount;
            }
            else if (eoln == null)        // first time, find out what eoln is
            {
                //
                // Need to grab the line terminator, and save it for
                // other times.
                //
                if (txt[q] == '\n')                           // \n is 'nix
                {
                    eoln = new byte[1];
                    eoln[0] = (byte)'\n';
                    lastEoln = "nix";
                }
                else if (txt[q] == '\r')                      // \r ...
                {
                    if (q+1 < total && txt[q+1] == '\n') // \r\n is Doze
                    {
                        eoln = new byte[2];
                        eoln[0] = (byte)'\r';
                        eoln[1] = (byte)'\n';
                        q++;
                        lastEoln = "doze";
                    }
                    else                                      // just \r is Mac
                    {
                        eoln = new byte[1];
                        eoln[0] = (byte)'\r';
                        lastEoln = "mac";
                    }
                }
                else
                    throw new RuntimeException("huh? no eoln at " + lineCount);
                q++;
            }
            else
            {
//System.err.println("Check ....");
                //
                // Check it is the same as the first time.
                //
                int here = q;
                boolean ok = true;
                for (int i = 0; i < eoln.length; i++)
                {
//System.err.println("q " + q + " total " + total + " i == " + i);
//if(q < total) System.err.println("byte is " + txt[q] + " against " + eoln[i]);
                    if (q >= total || txt[q++] != eoln[i])
                    {
                        ok = false;
                        break ;
                    }
                }

                //
                // Any change is a bad file, file a complaint.
                // Cannot pick up Mac with \r\n in it (sucks \r).
                //
                if (!ok)          // what the hell is it?  try all known
                {
                    q = here;     // back to the start of the newline
                    if (eoln.length == 2)      // we want Doze, got other
                    {
                        if (txt[q] == '\r')    // so q+1 != '\n', is Mac
                            lastErrors += " M" + lineCount;
                        else                   // q == \n, is 'nix.
                            lastErrors += " X" + lineCount;
                    }
                    else if (txt[q] == '\r')   // is Doze or Mac
                    {
//System.err.println("q " + q + " total " + total);
//if (q+1 < total) System.err.println("byte is " + txt[q+1]);
                        if (q+1 < total && txt[q+1] == '\n') // is Doze
                        {
                            q++;
                            lastErrors += " D" + lineCount;
                        }
                        else                                      // is Mac
                            lastErrors += " M" + lineCount;
                    }
                    else if (txt[q] == '\n')   // is 'nix, not a \r
                        lastErrors += " X" + lineCount;
                    else
                        throw new RuntimeException("cannot handle: " +
                                  txt[q] + txt[q+1] +
                                  " when using " + lastEoln + " line endings");

                    q++;                       // always at least one
                    numErrors++;
                }
            }

            next = q;
        }

        int len = stuk.size();
        String[] lines = new String[len];
        while (len-- > 0)
            lines[len] = (String)stuk.pop();
        return lines;
    }

    protected static void doLines(String desc, String test)
    {
        System.err.println(desc + ":");
        String[] lines = toLines(test.getBytes());
        for (int i = 0; i < lines.length; i++)
            System.err.println("     <" + lines[i] + ">");
        System.err.println("last eoln == " + lastEoln + ";  " +
                           getNumErrors() + " Errors: " + getLastErrors());
        System.err.println();
    }
    public static void testLines()
    {
        doLines("empty", "");
        doLines("no eoln", "no eoln");
        String[] eolns = {"\n", "\r", "\r\n"};
        for (int i = 0; i < eolns.length; i++)
        {
            System.err.println("===== " + i);
            String nl = eolns[i];
            doLines("lacks end", "one eoln" + nl + "two lines");
            doLines("3 lines only", nl + nl + nl);
            for (int j = 0; j < eolns.length; j++)
            {
                if (i == j) continue ;
                doLines("mixed " + j, "start" + nl + " change " + eolns[j]);
            }
        }
    }


    /**
     * Add a files worth to the hashtables.
     * @except FormattedFileException if a multiline could not be completed
     */
    protected void add(byte[] iniFileAsByteArray)
        throws FormattedFileException
    {
        String[] lines = toLines(iniFileAsByteArray);
    

        //
        // Read the file line by line and put data in the right place
        //
        String line;
        String sectionName = null;
        int    lineNum     = 0;
        int    numLines    = lines.length;

        while (lineNum < numLines)
        {
            line = lines[lineNum++];
    
            line.trim();
            if (line.length() == 0 )           // Skip blank lines
                continue;
    
            if (line.startsWith(";") )         // Skip comment lines
                continue;
            if(line.startsWith("#") )
                continue;

            //
            // Is it a new section?
            //
            if (line.startsWith("[") && line.endsWith("]") )
            {
                // the section should at least contain one or more 
                // characters
                // if (line.length() ==2 )
        
        
                // get the  section out of the tag
                // and put it in variable sectionName
                // sectionName is used afterwards to add items
                // to the section
    
    
                sectionName = line.substring(1,line.length() -1);
                addSection(sectionName);
                continue;
            }

            //
            // Or, it could be a vector item.
            // A vector item is one where there are many lines of the form:
            //      key += value1
            //      key += value2
            //
            int i = line.indexOf("+=");
            if (i != -1 && sectionName != null)
            {
                String key = line.substring(0,i).trim();
                String value= line.substring(i + 2).trim();
                Hashtable temp;
                // should already be there
                temp = (Hashtable) getHashOfSectionItems(sectionName);
                Vector vec = (Vector)temp.get(key);
                if(vec == null)
                    vec = new Vector();
                vec.addElement(value);
                temp.put(key, vec);
                continue;
            }

            //
            // Or, it could be an ordinary item.
            //
            i = line.indexOf('=');
            if (i != -1 && sectionName != null)
            {
                String key = line.substring(0,i).trim();
                String value;
        
                //
                // If the value starts with ' then this is multi-line.
                //
                if (line.substring(i+1).startsWith("'"))
                {
                    //remove the starting '
                    value= line.substring(i + 2);
    
                    if (!value.endsWith("'")){
                        // read until the end of the quotes
                        //are the end of the quotes on the same line
                        String temp= null;
    
                        while ((temp == null) || (!temp.endsWith("'")))
                        {
                            temp = lines[lineNum++];
                            // temp = bufr.readLine();

                            //
                            //  Wierd.  This needed to be if-else-else,
                            //  all the way through, or it would turn
                            //  empty lines into two empties.
                            //  This bug seems to have always existed.
                            //
                            if (temp.length() ==0)
                                value += "\n";
                            else if (temp.endsWith("'"))
                            {
                                value += temp.substring(0,temp.length()-1) + "\n"; 
                            }
                            else
                            {
                                value += temp + "\n"; 
                                if (lineNum >= numLines)
                                    throw new FormattedFileException(
                                      FormattedFileException.MULTILINE, lineNum,
                                      "eof reached before end of multiline");
                            }
                        }
                    }
                } 

                //
                // If the value starts with * then this is multi-line.
                //
                else if(line.substring(i+1).trim().equals("*") )
                {
                    if (lineNum + 1 > numLines)
                        throw new FormattedFileException(
                                  FormattedFileException.MULTILINE, lineNum,
                                  "Too few lines for multiline");

                    String temp = lines[lineNum++];
                    if (!temp.equals("{"))
                        throw new FormattedFileException(
                                  FormattedFileException.MULTILINE, lineNum,
                                  "No { after *");
        
                    value = "";
                    temp = null;
                    while ( ! (temp = lines[lineNum++]).trim().equals("}") )
                    {
                        value += temp + "\n";
                        if (lineNum >= numLines)
                            throw new FormattedFileException(
                                  FormattedFileException.MULTILINE, lineNum,
                                  "eof reached before end of multiline");
                    }
                }

                //
                // Else, just an ordinary value.
                //
                else
                {
                    value= line.substring(i + 1).trim();
                }
            
                //
                // Add a key / value pair to the Hashtable of the section.
                //
                Hashtable temp;
                temp = (Hashtable) getWriteHashOfSectionItems(sectionName);
                temp.put(key,value);
            }
        }
    }


//----------------------GLOBAL-------------------------------------
    /**
     *
     * @return This method returns a hash of selections<BR>
     * The has returned contains more Hashes<BR>
     * <UL><LI>
     * sections<BR>
     * (String sectionName) (Hash of items)<BR> 
     * <BR>
     * (Hash of items)<BR>
     * (String item) (String Value)<BR>
     * </LI><LI>
     * to get the items back explicit cast is needed
     * </LI></UL>
     */

    public Hashtable getIniFileHash()
    {
        return sections;
    }


    /**
     * Make a windows ini-file-formatted representation of the data
     * @return a byte array of the file
     */
    public byte[] saveToByteArray()
        throws IOException
    {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedWriter bufw = new BufferedWriter( new OutputStreamWriter(baos));
        String[] sectionNames = getSectionNames();
        Object obj;
    
        for (int i =0 ; i < getNumberOfSections() ; i++)
        {
            bufw.newLine();
            bufw.newLine();
            bufw.write("[");
            bufw.write(sectionNames[i],0, sectionNames[i].length());
            bufw.write("]");
            bufw.newLine();
            bufw.newLine();
            // get all the items in the section

            String[] items = getSectionItems(sectionNames[i]);

            for (int j=0 ; j < getNumberOfSectionItems(sectionNames[i]);j++)
            {
                obj = getSectionItemObject(sectionNames[i],items[j]);
                if(obj instanceof String)
                {
                    bufw.write(items[j] ,0,items[j].length());
                    String str = (String)obj;
                    bufw.write("=");
                    //hanlde mutlti line
                    if (str.indexOf("\n") != -1)
                        bufw.write("'");
            
                    bufw.write(str,0,str.length());
                    if (str.indexOf("\n") != -1)
                        bufw.write("'");
                    bufw.newLine();
                }
                else if (obj instanceof Vector)
                {
                    Vector vec = (Vector)obj;
                    String str = "";
                    for(Enumeration e = vec.elements(); e.hasMoreElements();)
                    {
                        bufw.write(items[j] ,0,items[j].length());
                        bufw.write("+=");
                        str = (String)e.nextElement();
                        bufw.write(str,0,str.length());
                        bufw.newLine();
                    }
                }
            }
        }
        bufw.flush();
        bufw.close();

        return baos.toByteArray();
    }
    
    /**
     * Save the IniFileReader contect to a file 
     * @param fileName the file name on wich to save
     */
    public void saveToFile (String fileName)
        throws IOException
    {
        byte [] data = saveToByteArray();
        FileOutputStream fos = new FileOutputStream(fileName);
        fos.write(data);
        fos.close();
    }
    
//----------------------SECTIONS-----------------------------------

    /**
     * this method returns the number of sections in the IniFileReader class
     * @return The number of sections
     */
    public int getNumberOfSections()
    {
        return sections.size();
    }


    /**
     *
     * @return an array of Strings  of the section names
     */
    public String[] getSectionNames()
    {

        String [] ret = new String[getNumberOfSections()];
        
        Enumeration sectionNames = sections.keys();
        int counter=0;
        while (sectionNames.hasMoreElements() )
        {
            ret[counter]  = (String) sectionNames.nextElement();
            counter++;
        }
        return ret;
    }
   
    private static final String none = "(none)";

    /**
     * This method add a section to the IniFileReader class
     *  @param sectionName the name of the new section
     */
    public void addSection(String sectionName)
    {
        if (sectionName == null || sectionName.equals(""))
            sectionName = none;
        if (sections.get(sectionName) != null)     // check for duplicates?
            return ;
        // indextable not used?
        indextable.put( sectionName, new Integer(indextable.size() ));
        sections.put(sectionName , new Hashtable());
    }


    /** This method can be used to remove sections in the IniFileReader class
     * @param sectionName the name of the section to remove
     */
    public void removeSection(String sectionName)
    {
        if (sectionName == null || sectionName.equals(""))
            sectionName = none;
        indextable.remove(sectionName);       
        sections.remove(sectionName);
    }
//----------------------SECTION ITEM-----------------------------------

    /**
     * this is used for getting the amount of items in a section
     * of a IniFileReader class
     *
     * @param section section is an existing section on the ini file
     * @return returns the number of items in the section
     */
    public int getNumberOfSectionItems( String section )
    {
        // get the specific section
        Hashtable temp = getHashOfSectionItems(section);
        if (temp == null)    // no section
            return 0 ;
        return temp.size();
    }

   /**
    * This is used to get a Hashtable of the items in the specific
    * section of the IniFileReader class for the purpose of adding
    * or setting a new key.  On return, there is a hash, even if
    * there wasn't one before.
    *
    * This changes the semantics somewhat - create on demand.
    *
    * @param section section is an existing section on the ini file
    * @return A Hashtable of Items contained in the section
    */
    public Hashtable getWriteHashOfSectionItems( String section )
    {
        if (section == null || section.equals(""))
            section = none;
        Hashtable hash = (Hashtable)sections.get(section);
        if (hash == null)
        {
            addSection(section);
            hash = (Hashtable)sections.get(section);
        }
        return hash;
    }

   /**
    * This is used to get a Hashtable of the items in the specific
    * section of the IniFileReader class
    *
    * @param section section is an existing section on the ini file
    * @return A Hashtable of Items contained in the section, or null if none.
    */
    public Hashtable getHashOfSectionItems( String section )
    {
        Hashtable hash = (Hashtable)sections.get(section);
        return hash;
    }



    /**
     * @param section section is an existing section on the ini file
     * @return an array of Strings  of the items contained by the section
     */
    public String[] getSectionItems( String section )
    {
        Hashtable temp = getHashOfSectionItems(section);
        if (temp == null)    // no section
            return new String[0] ;
      
        Enumeration sectionItemNames = temp.keys();
        String[] ret = new String[temp.size()];
        int counter=0;
        while (sectionItemNames.hasMoreElements() )
        {
            ret[counter++] = (String)sectionItemNames.nextElement();
        }
        return ret;
    }
   
    public Object getSectionItemObject(String section, String item)
    {
        Hashtable temp = getHashOfSectionItems(section);
        if (temp == null)    // no section
            return null;
        return temp.get(item);
    }
   
    /**
     * Get an item from a section.
     * Also checks for section_item, which is equivalent.
     *
     * @param section is an existing section in the ini file
     * @param item is an existing item in the section in the ini file
     * @return A Strings containing the value of the item 
     */
    public String getSectionItemValue(String section, String item)
    {
        Hashtable temp = getHashOfSectionItems(section);
        if (temp == null)    // no section
            return (String) null;

        //System.err.println("trying for " + section + " + " + item);
        if (item == null || item.length() == 0)
            return null ;

        Object obj = temp.get(item);
        
        if (obj != null)
        {
            //
            //  Hack, to allow dump to print stuff out, should be cleaned out.
            //
            String s;
            if (obj instanceof String)
                s = (String) obj;
            else if (obj instanceof Vector)    // shouldn't be called, (dump)
            {
                Vector v = (Vector) obj;
                s = (String) v.firstElement(); // first one is good enough
            }
            else
                throw new RuntimeException("("+obj.getClass().getName()+") " +
                                           obj);

            return s ;
        }

        String prefix = section + "_";    // check for section_item
        if (item.length() > prefix.length())
        {
            String check = item.substring(0, prefix.length());
            if (prefix.equals(check))
                return null ;
        }

        item = prefix + item;
        //System.err.println("trying for " + section + " + " + item);
        return (String) temp.get(item);
    }

    /**
     * This method can be used to add a item/value pair to a section
     * if the value is mutliline then you should use 
     * addMultilineSectionItem
     * @param sectionName the name of the section
     * @param item the name of the item in the section
     * @param value the value of the item
     */
    public void addSectionItem(String sectionName, String item, String value)
    {
        Hashtable temp = getWriteHashOfSectionItems(sectionName);
        temp.put (item , value);
    }

    /**
     * This method can be used to add a item/value pair to a section
     * using for mutliline
     * @param sectionName the name of the section
     * @param item the name of the item in the section
     * @param value the value of the item
     */
    public void addMultilineSectionItem(String sectionName , String item , String value)
    {
        value = "'" + value + "'";
        Hashtable temp = getWriteHashOfSectionItems(sectionName);
        temp.put (item , value);
    }

    /**
     * This method can be used to change a value pair of a item in a  section
     * @param sectionName the name of the section
     * @param item the name of the item in the section
     * @param value the value of the item
     */
    public void changeSectionItemValue(String sect, String item, String value)
    {
        Hashtable temp = getWriteHashOfSectionItems(sect);
        temp.put (item , value);
    }


    /**
     * This method can be used to remove an item form a section
     * @param sectionName the name of the section
     * @param item   the name of the item to remove
     */
    public void removeSectionItem(String sectionName, String item)
    {
        Hashtable temp = getHashOfSectionItems(sectionName);
        if (temp == null)    // no section
            return ;
        temp.remove(item);
    }
     
    public String[] getSectionItemArray(String sectionName, String item)
    {
        Hashtable temp = getHashOfSectionItems(sectionName);
        if (temp == null)    // no section
            return new String[0] ;
        Object obj = temp.get(item);
        if (obj == null)
            return new String[0] ;

        if (obj instanceof Vector)
        {
            Vector vec = (Vector)obj;
            String[] retval = new String[vec.size() ];
            vec.copyInto(retval);
            return retval ;
        }
        else if (obj instanceof String)
        {
            String[] retval = new String[1];
            retval[0] = (String)obj;
            return retval ;
        }

        throw new RuntimeException("bad obj ("+item+"): "+obj.toString());
    }
    
    public void removeSectionItemArray(String sectionName, String item, String value)
    {
        Hashtable temp = getHashOfSectionItems(sectionName);
        if (temp == null)    // no section
            return ;
        Vector vec = (Vector)temp.get(item);
        if(vec == null)
        {
            return;
        }
        vec.removeElement(value);
    }
    
     
    /*
    public void dump(OutputStream out)
    {
        PrintWriter pw = new PrintWriter(out);
        Object[][] content = new String[indextable.size()][2];
        
        int index = 0;
        String nextElement = "";
        for(Enumeration e = indextable.keys(); e.hasMoreElements();)
        {
            nextElement = e.nextElement().toString();
            content[index][0] = nextElement;
            content[index++][1] = indextable.get(nextElement).toString();
        }

        if(content.length > 1)
        {
            boolean moved; 
            int curndx=content.length;
            do
            { 
                moved=false;
                Object temp0 = null;
                Object temp1 = null;
                for (int index2=1; index2 < curndx; index2++) { 
                    if ( new Integer((String)content[index2][1]).intValue() < new Integer((String)content[index2-1][1]).intValue() )
                    { 
                        moved = true;
                        temp0 = content[index2][0];
                        temp1 = content[index2][1];
                        content[index2][0] = content[index2-1][0];
                        content[index2][1] = content[index2-1][1];
                        content[index2-1][0] = temp0;
                        content[index2-1][1] = temp1;
                    }
                }
                curndx--; 
            } while (moved);
        }
        
        for(int i = 0; i < content.length; i++)
        {

            String section = (String)content[i][0];
            pw.println( ("[" + section + "]" ) );
        
            String[] items = getSectionItems(section);

            for (int j=0 ; j < getNumberOfSectionItems(section);j++)
            {
                pw.print("\t" + items[j]);
                pw.println("\t" + getSectionItemValue(section,items[j]) );
            }
        }
        pw.flush();
    }
    */

//----------------------TEST CODE-----------------------------------

    public void dump()
    {


        System.err.println("___IniFile Dumping the Ini file___");

        //example get the number of sections 
        System.err.println("Number of sections=" + getNumberOfSections());

        // example get a array of section names
        String[] sectionNames = getSectionNames();

        for (int i =0 ; i < getNumberOfSections()  ; i++)
        {
            System.err.println(sectionNames[i]);

            // get all the items in the section
            String[] items = getSectionItems(sectionNames[i]);

            for (int j=0 ; j < getNumberOfSectionItems(sectionNames[i]);j++)
            {
                System.err.print("\t" + items[j]);
                System.err.println("\t" + getSectionItemValue(sectionNames[i],
                           items[j]));
            }
        }
    }

    /**
     * Test method requires a ini file called test.ini
     */
    public static void  main(String[] arg)
        throws IOException, FormattedFileException
    {

        if (arg.length == 0)
        {
            System.err.println("Test Usage: IniFileReader [-lines] filename");
            System.exit(1);
        }

        if ("-lines".equals(arg[0]))
        {
            testLines();
            System.exit(0);
        }

        // test the fileName constuctor
        System.err.println("1: using the fileName constructor");
        File test = new File(arg[0]);
        FileInputStream fis = new FileInputStream(test);
        byte[] data = new byte[fis.available()];
        fis.read(data);
        fis.close();

        IniFileReader ini = new IniFileReader(data);
System.err.println("Dumping content");
        ini.dump();

        // add one section
        System.err.println();
        System.err.println("3: adding a section to the IniFileReader class");

        ini.addSection("addedSection");
        ini.dump();

        //add one item 

        System.err.println();
        System.err.println("4: adding a item to the IniFileReader class");
        ini.addSectionItem("addedSection","addeditem","this is added");
        ini.dump();

        //change the value of the item

        System.err.println();
        System.err.println("5: change the value of the item");
        ini.addSectionItem("addedSection","addeditem","this is added and has chagned value");
        ini.dump();
        
        //remove the item
        System.err.println();
        System.err.println("6: remove the item");
        ini.removeSectionItem("addedSection","addeditem");
        ini.dump();

        //remove the section

        System.err.println();
        System.err.println("7: remove the section");
        ini.removeSection("addedSection");
        ini.dump();
        ini.saveToFile("keesj.ini");
    
    }
}