While the ASPIniFile component is included for backward compatibility and
support for applications that "understand" only INI files, ConfigFile
object goes further. It supports so called (internally) Unified Structured Data
(USD). USD is just a thing every programmer needs one day. Many programmers
waited for XML - we not. We used it for many years in our C++ application, but
ConfigFile makes it available for script applications.
Abstract data structure defined by USD is a tree of data. It consists of
Sections, Records and Values. Each section may contain subsections and records.
Each record may contain one or more values (named or unnamed). The values are
strictly typed - e.g. their type is known and this makes them more convenient
for pure programming purposes than the document oriented XML. The ConfigFile
represents the data using VarDictionary collections. When data is loaded from a
certain source it appears to the application as a tree - collection of
collections. Then the application may walk the tree, search through it and
use/alter the contained values, add/remove parts of it, clone some branches and
so on.
What are the benefits? Current version supports 3 formats - textual,
binary and Windows registry. This means the application is able to obtain its
data from different sources but packed in the same manner! The other
benefits are the structure - tree like structure allows any complexity of the
configuration. INI files do not support sub sections for example. The parts of
different configurations can be cut/copied and moved to another configuration
and then saved somewhere. If the object is created as free threaded then the
loaded data can be assigned to an Application or Session variable in ASP. This
allows to load it once and keep it in memory, thus treat it as some kind of
memory data base. Let us take a little sample.
Load the data (probably in global.asa):
Set CfgObj = Server.CreateObject("newObjects.utilctls.ConfigFile.free")
' Load some data.
' From a text file
Set Application("TextConfig") = SfgObj.Read(Server.MapPath("config.cfg"))
' From registry
Set Application("RegConfig") = SfgObj.ReadFromRegistry(cRegLocalMachine, _
"software\MyCompany\MyApp")
' From a binary file
Set sf = Server.CreateObject("newObjects.utilctls.SFMain")
Set f = sf.OpenFile(Server.MapPath("somefile.bin"))
Set Application("BinConfig") = SfgObj.ReadFromBinaryStream(f)
' Save the CfgObj in Application
Set Application("ConfigFile") = CfgObj
And let use some a data tree in a regular ASP page
Set cfg = Application("RegConfig")
' Get the DB init string for example
db.Open cfg("DataBase")("InitString")
' Enum the values in a branch
For I = 1 To cfg("Names")
current = cfg("Names")(I)
' Do something with it
Next
' Set a value
cfg("Settings")("FontSize") = 7
' Create a branch. In this case if we save
' it back to the registry it will create a key,
' if it is saved to text file the branch will
' correspond to a { Section ... }
Set newSection = Application("ConfigFile").CreateSection
' See above - we saved the object to an Application variable
' for convenience.
' Now add something to the section
Set rec = Application("ConfigFile").CreateRecord
rec("Alpha") = "something"
rec("Beta") = 100
newSection.Add "Record1", rec
cfg("Settings").Add "NewBranch", newSection
' Well but the system registry does not support such thing
' like Value "Record1" with two sub values named "Alpha" and "Beta"
' Thus with this we made it impossible to save it back to
' the registry, but the other formats are still available.
' To make it good for the registry we can use another way
Set newSection = Application("ConfigFile").CreateSection
newSection("Alpha") = "something"
newSection("Beta") = 100
' We skipped the record creation and this is legal. It will prevent
' us from assigning many values to each record, but this is enough
' in the most cases and is much shorter.
' What about many unnamed values in one record?
Set newSection = Application("ConfigFile").CreateSection
Set rec = Application("ConfigFile").CreateRecord
rec.Add "", "Blah"
rec.Add "", 100
rec.Add "", 3.14
newSection.Add "MyRecord", rec
' Now what will return the:
aVariable = newSection("MyRecord")
' The first value - it is "Blah" in this case
' If we want to reach other value
aVariable = newSection("MyRecord")(3)
' Will return 3.14
' Note that this is not compatible with the system registry too
' In general the registry supports a subset of the types
' and capabilities of the USD thus we cannot keep
' the data tree an actual copy of the registry branch
' and use all the features at the same time. However
' this limitation is much less important than the benefits.
Script programmers should be careful when assigning values. VarDictionary
will permit any kind of value, but not all the values can be saved. For example
imagine an object - there is no way to understand how to save it or what to save
the object or its default property. Therefore you will need to use strict type
conversion when assigning/adding values in cases where the type conversion is ambiguous.
This comes from the C++ roots of the architecture. To keep the size of the
object small it uses the VarDictionary for data representation. We are going to
supply later this year more powerful version of the object which will coexist
with this one but in a separate DLL. Thus treat this version as light weight way
to access the USD data and please excuse us for the little inconvenience caused
by the need to use the CLng, CDbl, CStr etc. functions too much.