Value Space clients read from the Application Object layer's shared memory region directly. A kernel lock is acquired for each read to prevent corruption. While the layer supports concurrent readers, it is possible that a faulty or malicious application could acquire and refuse to release this lock causing any layer updates to be delayed indefinately.
Only the Value Space server ever writes to the shared memory region. When clients attempt to add items to the layer, their changes are transmitted via the /tmp/qtopia-N/valuespace_applayer Unix domain socket to the server where the update is performed. Updates are batched in-process and sent when the process re-enters the Qt event loop. Transmission and synchronization of changes can be forced manually by the QValueSpaceObject::sync() call, although as this requires a round trip between the client and server, doing so frequently may significantly degrade performance.
Change notifications are transmitted to clients in the form of "something has changed" messages. Nodes within the shared memory region are versioned, which allows clients to quickly determine exactly what has changed without the need for a bulkier change notification protocol.
INI layer
The INI layer maps INI files from disk into the Value Space. The INI layer supports arbitrary mappings, fallback paths and partial change notification.
As the unified path structure of the Value Space doesn't allow the INI layer to transparently determine which INI file to access off disk, a INI layer configuration file (an INI file itself) is used to dictate how INI files are located. The INI file identified by Trolltech/IniValueSpace using the QSettings resolution rules is used for this purpose.
The general form of the INI layer configuration file is:
[General]
Translations=<Directory to INI translations>
LanguageItem=<Value Space Item for current language>
Mappings=<Number of mappings that follow>
[Mapping<x>]
ValueSpacePath=(Required)
FileSystemPath=(One of FileSystemPath or FileSystemPaths required)
FileSystemPaths=(One of FileSystemPath or FileSystemPaths required)
FileSystemPath<x>=(Required if FileSystemPaths specified)
FileSystemExtension=(Optional. Required if DirectoryDepth is specified)
DirectoryDepth=(Optional. Only allowed if FileSystemExtension specified)
The General/Mappings key simply specifies the number of mappings that follow, which are grouped as Mapping0 - Mapping<n>. Each mapping consists of a single required field, ValueSpacePath, and a number of optional and interdependant keys.
The {ValueSpacePath} key specifies the point of mapping in the value space. This is called a "terminal" point. There may be only a single mapping for each distinct terminal point. Two /Device mappings are not allowed, but a /Device and a /Device/Buttons mapping is fine. Each terminal mapping is either a "depth mapping" or a "file mapping".
File mappings are identified by the lack of the FileSystemExtension and DirectoryDepth keys. File mappings map a single INI file to a single Value Space node. For example, in following mapping
[Mapping0]
ValueSpacePath=/Device/Buttons
FileSystemPath=/opt/Qtopia/etc/defaultbuttons.conf
if the /opt/Qtopia/etc/defaultbuttons.conf file contained a Mode/Type key, the corresponding Value Space item /Device/Buttons/Mode/Type would exist.
Using the FileSystemPaths list, fallback file mappings may be created. For example
[Mapping0]
ValueSpacePath=/Device/Buttons
FileSystemPaths=2
FileSystemPath0=/tmp/qtembedded-0/defaultbuttons.conf
FileSystemPath1=/opt/Qtopia/etc/defaultbuttons.conf
will first attempt to map /tmp/qtembedded-0/defaultbuttons.conf and then, if this doesn't exist, /opt/Qtopia/etc/defaultbuttons.conf. Fallback mappings completely obscure each other. That is, the two files /tmp/qtembedded-0/defaultbuttons.conf and /opt/Qtopia/etc/defaultbuttons.conf are not unified, but whichever exists is used and the other ignored. Fallbacks are monitored for change, so if the /tmp/qtembedded-0/defaultbuttons.conf file is created sometime later the INI layer will update accordingly.
Depth mappings allow groups of ini files to be mapped into the Value Space dynamically. Depth mappings are identified by the presence of the FileExtension key. In the case of depth mappings, the ValueSpacePath point specifies the beginning of the mapping. The next DirectoryDepth sub-paths are treated as directory specifiers, and the subsequent sub-path a file name with the FileSystemExtension extension. For example
[Mapping0]
ValueSpacePath=/Applications
FileSystemPath=/opt/Qtopia/apps
FileSystemExtension=desktop
DirectoryDepth=1
[Mapping1]
ValueSpacePath=/GamesApplications
FileSystemPath=/opt/Qtopia/apps/Games
FileSystemExtension=desktop
DirectoryDepth=0
creates two mappings. In the above both the Value Space items /Applications/Games/parashoot and /GamesApplications/parashoot map to the /opt/Qtopia/apps/Games/parashoot.desktop INI file. Thus if this file contained Desktop Entry/Name, the corresponding Value Space paths /Applications/Games/parashoot/Desktop Entry/Name and /GamesApplications/parashoot/Desktop Entry/Name would also exist.
As with file mappings, depth mapping support fallback paths. For example
[Mapping0]
ValueSpacePath=/Settings
FileSystemPaths=2
FileSystemPath0=/home/username/.config
FileSystemPath1=/etc/
FileSystemExtension=conf
DirectoryDepth=1
will map /Settings/Trolltech/qpe first to /home/username/.config/Trolltech/qpe.conf and then to /etc/Trolltech/qpe.conf. Like file mappings, the fallback paths are monitored in case the file is later created.
Keys within an INI file can be marked as translatable by appending the "[]" token to them. For example, the following file contains one translatable key, /Example/Translatable and one non-translatable key, /Example/NonTranslatable.
[Translation]
File=ExampleTranslation
Context=ExampleContext
[Example]
Translatable[]=Translatable Value
NonTranslatable=Non-Translatable Value
In both cases the "[]" token is omitted from the key name when accessed through the QValueSpaceItem class.
INI translation files must be stored under a directory structure rooted at the General/Translations directory provided in the INI layer's configuration file. If this configuration entry is omitted, translation is disabled. To provide accurate translations, the INI layer also needs to know the current system language. This information is accesses through the Value Space itself, from the item path specified by General/LanguageItem. Together the translations directory, and the current system language are combined to form the root under which the INI layer looks for translations files.
INI files that include translatable keys, must also include the special Translation INI group that dictates how the INI layer locates translations for the key's value. The Translation/File key specifies the file to open under the translations root directory discussed above, and the Translation/Context key the Qt translation context to use within that file. The INI layer supports change notifications on language change.
Currently the INI layer only supports partial change notification. Change notifications will occur for keys that exist within mapped INI files, but these notifications will not be propagated up the Value Space tree. For example with the previous mapping, should the qpe.conf file change,
QValueSpaceItem item("/Settings/Trolltech/qpe/Desktop Entry/Name");
QValueSpaceItem item2("/Settings/Trolltech/qpe");
QValueSpaceItem item3("/Settings/Trolltech");
.
This limitation may be removed in future versions.