Prefsfile module

Copyright © 1995-2012 Opera Software ASA. All rights reserved. This file is part of the Opera web browser. It may not be distributed under any circumstances.

Introduction

The Prefsfile module provides APIs for reading and writing the Opera configuration file formats directly, and support for language files. This is used mainly by the Preferences module, but also several other parts of the code.

Current information about the Prefsfile module and its releases is available on the developer wiki.

Interface overview and API documentation

API documentation

The API documentation is extracted automatically by Doxygen.

Overview

The PrefsFile is the general-purpose configuration storage API used by the Preferences module (and others) to store configuration options on disk. Platforms that want to re-implement the reading of preferences (for instance using system APIs) can implement new file formats inside the PrefsFile framework by implementing the PrefsAccessor interface.

The PrefsFile class implements support for cascading preferences using several preferences files.

Use-cases

Reading auxiliary INI files/file sets

To read an auxiliary preferences file (normally in INI or LNG format), an instance of PrefsFile class is constructed and initialised. When creating the object, the type of the file must be supplied. For core code, the special constant PREFS_STD should always be used when it needs to access files, as this will always select the platform default type (configurable through the tweak system).

After performing a PrefsFile::LoadAllL(), the instance of PrefsFile permits direct access to the settings stored in the INI (or LNG) file using the various Read*() methods, and to write (not LNG) using the Write* methods. To store the modified file to disk, PrefsFile::CommitL() is called.

Please note that as long as the PrefsFile object is not flushed, either by PrefsFile::CommitL() or a direct call to PrefsFile::Flush(), any changes done to the file on-disk will be ignored.

For more details on how to use preferences files and an explanation of how the design is supposed to work, please see the background information.

Changing file formats

The PrefsFile class is not tied to using a specific file format for storing its preferences, all reading and writing to the actual files is performed by the PrefsAccessor interface. The requirement when changing both the file format and storage method is that data can be stored keyed to a section and key, and that the data types that can be written are at least strings and numbers (in PrefsAccessor and associated classes, all preferences are written as strings).

Supported standards

The file format used by IniAccessor is based on the standard Windows INI file format, with some extensions. The language file format is an extended INI file format with embedded encoding information, and is used by the locale code.

Implementation and design

See also the API documentation.

Memory management

Heap usage

Footprint usage can be decreased by disabling hashing code. Memory usage will decrease as well, as the data associated with the hash tables is no longer used. Memory and footprint usage will be decreased further when enabling case sensitive preference key names.

These settings also affect performance, and can be manually tuned, see "Performance" below for more details.

Stack usage

There are no recursive calls.

Static memory usage

There is one global PrefsHashFunctions pointer, which is live for the entire lifetime of Opera (under certain circumstances it might even be initialised before the call InitL).

There is also a temporary buffer used for case conversion and environment variable expansion. This buffer is of 4096 uni_chars if expansion of environment variables is enabled, or of 2048 uni_chars if case insensitive name look-up are used. If neither expansion nor case insensitivity is enabled, this buffer is not enabled.

OOM policies

The vast majority of functions that require memory to be allocated is using the TRAP/LEAVE convention.

Performance

Caching

To make reading and writing from preference files faster, the files are cached inside the PrefsFile class.

Hashing

Furthermore, PrefsFile uses hash tables to make lookup into the parsed files faster. For small machines, this should probably be disabled, and the linear search used. The coded needs to retain the linear ordering of the preferences anyway.

For most devices with large ini files it is probably a good idea to enabled FEATURE_PREFS_ENTRIES_HASH (hashing of keys in a section) and FEATURE_PREFS_SECTION_HASH (hashing of sections), if the increased memory usage can be afforded. Hashing of sections is not normally necessary unless ini files with a large number of sections is used (e.g skinning files).

Language files are read sequentially by the LanguageManager implementation, so no performance penalty is induced for language files if hashing is removed, even for large language files.

Case sensitivity

Normally the section and key names in the preference files are case insensitive (in a normal Windows INI file, case is not considered), to make it easier to edit these files by hand. If you enable TWEAK_PF_CASE_SENSITIVE, the strings are made case sensitive, speeding up the related string comparisons. For devices where the user or other software will not be touching the preference files this should probably be enabled. This is especially useful when hashing is disabled.

References