Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

INI files

Moderators: larsivi kris

Posted: 09/12/08 00:05:31

Ok, I know that there is the properties class and MapStream. But why isnt there a class for working with straight clean INI files? And is there an example for using MapStream? Cause I can't really figure it out.

-Rayne thanks in advance.

Author Message

Posted: 09/12/08 01:42:08

At this time there's no support for .ini files, though we'd probably welcome one :)

Posted: 09/12/08 01:55:25

Well, is there an example for using MapStream? It says Properties are depreciated.

Posted: 09/12/08 01:59:36 -- Modified: 09/13/08 02:16:12 by
schveiguy -- Modified 3 Times

DiscipleRayne wrote:

Ok, I know that there is the properties class and MapStream.

FYI, Properties class is being deprecated in favor of MapStream, please use MapStream

[edit] I wrote this before seeing your other response, sorry for the redundancy...

DiscipleRayne wrote:

And is there an example for using MapStream? Cause I can't really figure it out.

Here is a simple one:

properties file:

property.name = value
property.name2 = value2

code to parse a file:

import tango.io.stream.MapStream;
import tango.io.stream.FileStream;
import tango.io.Stdout;

void main()
{
  char[][char[]] props;
  (new MapInput!(char)(new FileInput("mypropfile.props"))).load(props);

  // show all values
  foreach(key, value; props)
     Stdout.formatln("{} = {}", key, value);

  // get a single value
  Stdout.formatln("the value for property.name is {}", props["property.name"]);

}

Enjoy!

-Steve

Posted: 09/12/08 02:12:11 -- Modified: 09/12/08 04:59:19 by
DiscipleRayne -- Modified 2 Times

Thanks alot man.

[EDIT] Sorry for my stupidty I'm used to using Nini with C#, I just recently started using D, and Tango. How do I get the value of one of the keys?

[EDIT2]And when I use your code I get this error:

found '.' when expecting ';' following 'statement'

Posted: 09/12/08 16:01:09

to get a value, use the associative array:

props["keyname"]

And yeah, I probably made a mistake, that's what happens when you post untested code :)

I've edited it to fix that problem forgot some parens, and I also made it a standalone compilable file.

You should visit the Tango tutorials if you are starting from scratch without knowing D.

-Steve

Posted: 09/12/08 23:18:35 -- Modified: 09/13/08 01:53:08 by
DiscipleRayne

Thanks man, I just started learning it like 2 days ago, I'm just happy I have nice people like you guys to help me out when I need it :) Thanks.

[edit] By the way you screwed up the code again ;) Stdout.formatln("{} = {}", name<---Key not name ;p, value);

Posted: 09/13/08 02:17:04

So I did :) Fixed it so others who read this thread won't be confused...

And maybe it can be included in the docs?

Posted: 09/13/08 02:19:43 -- Modified: 09/13/08 02:27:00 by
DiscipleRayne -- Modified 2 Times

Yeah kris, I vote it in, the whole properties thing confused me so I'm sure it confused other tango newbies, I'd put it in.

[edit] By the way, you might want to change the name of the file to .txt instead of .props, it gave me an error when I used it like that.

Posted: 09/13/08 03:03:01

Much of the documentation is hosted as a wiki, specifically so that other/many people can update it ;)

Posted: 09/13/08 19:35:58

Sorry to say this, but the wiki feature of the API docs is not useful at all. When 99% of the wiki links I click on are empty, I don't bother clicking on them. The only way that might be useful is if there was something on the doc page that said 'there is actual stuff behind this wiki link'. Even if wiki links that pointed to exiting stuff had some indicator (like how Wiki links are auto-created for camel case, but have a question mark if they are empty).

Just my opinion.

-Steve

Posted: 09/13/08 20:41:34

oh, wasn't referring to the API documentation, but instead to all the examples, chapters and various other wiki-based documentation. We're using a wiki explicitly so that others can add to the doc as they see fit, or fill in the gaps as needed (and there certainly are gaps to fill).

I thought documented examples were the cause for concern here, and we use the wiki for that purpose.

Hope that helps

Posted: 09/14/08 08:32:20

kris wrote:

At this time there's no support for .ini files, though we'd probably welcome one :)

So when you wrote that you never intended it to be for ini files. I haven't seen much use of what you like to call a properties file or an ini file without sections. Could this be turned into a sort of ini api but if anyone intended to use it like before that it doesnt care if the data is not in a section.

Posted: 09/17/08 17:29:21

Property files can be used in the same way as ini files, There really isnt much use for sections in the first place, I mean ini files basicly just get a value from a key same thing this does, sections are just lables you can put those in the form of comments, if you need them.

All in all a property file is just any file with a key = value format in it, which is another useful thing. I can find many uses for it, when you just need to get somekind of variable that's not hard coded into the program or need human configuration, then XML and JSON is not needed, ya know?

Posted: 09/23/08 11:20:07

DiscipleRayne wrote:

Property files can be used in the same way as ini files, There really isnt much use for sections in the first place, I mean ini files basicly just get a value from a key same thing this does, sections are just lables you can put those in the form of comments, if you need them.

All in all a property file is just any file with a key = value format in it, which is another useful thing. I can find many uses for it, when you just need to get somekind of variable that's not hard coded into the program or need human configuration, then XML and JSON is not needed, ya know?

http://en.wikipedia.org/wiki/INI_file Yes its like that. I'm one of those lucky few that didn't choose ini files over xml but happen to have to read in someones ini that has same named properties in different sections and also re write values to the correct section so the other software still works.

Posted: 09/27/08 11:55:41

Hey schveiguy,

thanks for the code sample, which is quite useful. I created a Config_init class, which just reads the configuration and stores them as properties of the class. All the properties are then accessed via get and set. An additional function writes the internal properties to the INI file.

Now I can simply use this class to access all configuration parameter. I have just a single issue, which I'm not sure how to solve. What would be the best way to make the class/object accessible to all classes. I don't like to create a configuration object in each class, where I need access to the configuration parameter.

Would be great to get any ideas. I'm still finding my path through D.

ciao Lars

Some thoughts about switching from PHP to D: http://www.lars-kirchhoff.de/go/journal/section/from-php-to-d/

Posted: 09/27/08 12:17:33

The easiest probably would be using the Singleton pattern, or put your Config_init instance as a global (module scope) variable in one of your modules.

Posted: 09/27/08 12:43:02 -- Modified: 09/27/08 12:43:31 by
lars_kirchhoff

Hey larsivi,

thanks for the quick answer.

A singleton pattern is exactly what I'm looking for, because I used it a lot in PHP, but I don't know how to create a singleton in D. Would be great to have an example.

ciao Lars

Some thoughts about switching from PHP to D: http://www.lars-kirchhoff.de/go/journal/section/from-php-to-d/

Posted: 09/30/08 02:52:37

Easiest way to create a singleton is static this, which can be in a module or in a class:

// in a module:
module x;
import module.that.defines.Config_init;

Config_init globalConfig;

static this()
{
  globalConfig = new Config_init(params, to, read, config);
}

// in the class

class Config_init
{
  static Config_init instance;
  static this()
  {
     instance = new Config_init(params, to, read, config);
  }
  ...
}

Note I left the details of how Config_init works up to you, since you already have it written. To use the instance, just reference it. static this ensures that it will be initialized before you use it.

Posted: 10/01/08 14:45:36 -- Modified: 10/01/08 16:57:54 by
lars_kirchhoff

Thanks Steve,

I'm not sure about the constructor, as in my implementation I'm reading the configuration in constructor. Do I need to add the static constructor additionally?. I've just pasted the whole class below.

/lars

module          lib.util.config_init;



/*******************************************************************************

        imports

*******************************************************************************/

private         import          tango.io.stream.MapStream,
                                tango.io.stream.FileStream,
                                tango.io.FilePath;

private         import          tango.io.Stdout;



/*******************************************************************************

        constant definitions

*******************************************************************************/
char[]          CONF_FILE_NOT_FOUND             = "Configuration file not found.";
char[]          PRINT_END_INI_CONFIGURATION     = "----- END INI Configuration --------\n\n";
char[]          PRINT_INI_CONFIGURATION         = "----- INI Configuration --------\nNumber of parameter(s):";



class Config_init
{

    private     char[]              configuration_file  = "etc/conf.ini";
    
    static      Config_init         instance;
    
    private     char[][char[]]      properties;
    
        
    static this()
    {
        instance = new Config_init();
    }

    
    /**
     * Constructor
     *
     * Reads the content of the INI file and stores it in the internal array.
     */
	this ()
	{
        this.read();
    }



    /**
     * Get function
     *
     * Params:
     *   key = name of the property to get
     *
     * Returns:
     *   The value of a property
     */
    public char[] get(char[] key)
    {
        if (key in this.properties) {
            return this.properties[key];
        }
    }



    /**
     * Set function
     *
     * Params:
     *   key = name of the property to set
     *   value = value of the property
     */
    public void set(char[] key, char[] value)
    {
        this.properties[key] = value;
    }



    /**
     * Reads all configuration parameter from INI file
     *
     */
    public void read()
    {
        this.properties = null;

        if ((new FilePath)(this.configuration_file).exists) {
            (new MapInput!(char)(new FileInput(this.configuration_file))).load(this.properties);
        }
        else {
            Stdout.formatln(CONF_FILE_NOT_FOUND);
        }
    }



    /**
     * Writes all configuration parameter to INI file
     */
    public void write()
    {
        auto map = new MapOutput!(char)(new FileOutput(this.configuration_file));
        map.append(this.properties);
        map.flush();
        map.close();
    }



    /**
     * Prints all configuration properties
     *
     */
    public void print()
    {
        Stdout.format("{} {}\n\n", PRINT_INI_CONFIGURATION, this.properties.length);

        foreach(key, value; this.properties) {
            Stdout.formatln("{} = {}", key, value);
        }

        Stdout.format(PRINT_END_INI_CONFIGURATION);
    }
}

// end class

Some thoughts about switching from PHP to D: http://www.lars-kirchhoff.de/go/journal/section/from-php-to-d/

Posted: 10/01/08 16:20:45

What you have seems like it should work.

-Steve