comparison tango/tango/text/Properties.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
comparison
equal deleted inserted replaced
131:5825d48b27d1 132:1700239cab2e
1 /*******************************************************************************
2
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved
4
5 license: BSD style: $(LICENSE)
6
7 version: Initial release: May 2004
8
9 author: Kris
10
11 *******************************************************************************/
12
13 module tango.text.Properties;
14
15 private import tango.io.Buffer,
16 tango.io.FilePath,
17 tango.io.FileConst,
18 tango.io.FileConduit;
19
20 private import Text = tango.text.Util;
21
22 private import tango.text.stream.LineIterator;
23
24 /*******************************************************************************
25
26 Provides load facilities for a properties file. That is, a file
27 or other medium containing lines of text with a name=value layout.
28
29 *******************************************************************************/
30
31 class Properties(T)
32 {
33 /***********************************************************************
34
35 Load properties from the named file, and pass each of them
36 to the provided delegate.
37
38 ***********************************************************************/
39
40 static void load (FilePath path, void delegate (T[] name, T[] value) dg)
41 {
42 auto fc = new FileConduit (path);
43 scope (exit)
44 fc.close;
45
46 load (fc, dg);
47 }
48
49 /***********************************************************************
50
51 Load properties from the provided buffer, and pass them to
52 the specified delegate.
53
54 We use an iterator to sweep text lines, and extract lValue
55 and rValue pairs from each one, The expected file format is
56 as follows:
57
58 ---
59 x = y
60 abc = 123
61 x.y.z = this is a single property
62
63 # this is a comment line
64 ---
65
66 ***********************************************************************/
67
68 static void load (InputStream stream, void delegate (T[] name, T[] value) dg)
69 {
70 foreach (line; new LineIterator!(T) (stream))
71 {
72 auto text = Text.trim (line);
73
74 // comments require '#' as the first non-whitespace char
75 if (text.length && (text[0] != '#'))
76 {
77 // find the '=' char
78 auto i = Text.locate (text, '=');
79
80 // ignore if not found ...
81 if (i < text.length)
82 dg (Text.trim (text[0 .. i]), Text.trim (text[i+1 .. $]));
83 }
84 }
85 }
86
87 /***********************************************************************
88
89 Write properties to the provided filepath
90
91 ***********************************************************************/
92
93 static void save (FilePath path, T[][T[]] properties)
94 {
95 auto fc = new FileConduit (path, FileConduit.WriteCreate);
96 scope (exit)
97 fc.close;
98 save (fc, properties);
99 }
100
101 /***********************************************************************
102
103 Write properties to the provided stream
104
105 ***********************************************************************/
106
107 static void save (OutputStream stream, T[][T[]] properties)
108 {
109 const T[] equals = " = ";
110 version (Win32)
111 const T[] NL = "\r\n";
112 version (Posix)
113 const T[] NL = "\n";
114
115 auto b = cast(Buffered) stream;
116 auto emit = b ? b.buffer : new Buffer (stream.conduit);
117 foreach (key, value; properties)
118 emit (key) (equals) (value) (NL);
119 emit.flush;
120 }
121 }
122
123
124 debug (Properties)
125 {
126 import tango.io.Buffer;
127 import tango.io.Console;
128
129 void main()
130 {
131 char[][char[]] aa;
132 aa ["foo"] = "something";
133 aa ["bar"] = "something else";
134 aa ["wumpus"] = "";
135
136 // write associative-array to a buffer; could use a file
137 auto props = new Properties!(char);
138 auto buffer = new Buffer (256);
139 props.save (buffer, aa);
140
141 // reset and repopulate AA from the buffer
142 aa = null;
143 props.load (buffer, (char[] name, char[] value){aa[name] = value;});
144
145 // display result
146 foreach (name, value; aa)
147 Cout (name) (" = ") (value).newline;
148 }
149 }
150