Added UTF-8 char length lookup table
[elinks.git] / doc / dev-intro.txt
blob1fe648a85a202567bd5a60ffa4b2dbc1bc7edcf3
1 Introduction to ELinks Developing
2 ---------------------------------
4 This is an introduction to how some of the internals of ELinks work. It
5 focuses on covering the basic low level subsystems and data structures and
6 give an overview of how things are glued together. Some additional information
7 about ELinks internals are available in ELinks Hacking. Consult the README
8 file\cite{6} in the source directory to get an overview of how the different
9 parts of ELinks depend on each other.
12 Memory Management
13 ~~~~~~~~~~~~~~~~~
15 ELinks wraps access to `alloc()`, `calloc()` and `free()` in a memory
16 management layer which provides,  among other things, leak debugging, and
17 checking for out of boundary access. It is defined in `src/util/memory.h`. The
18 wrappers are `mem_alloc()`, `mem_calloc()` and `mem_free()`. Additionally,
19 it also provides wrappers for `mmap()` and `munmap()` as `mem_mmap_alloc()`
20 and `mem_mmap_free()`.
23 Configuration Options
24 ~~~~~~~~~~~~~~~~~~~~~
26 All options known by ELinks are accessible using a common interface.
27 Options can have different types, such as string, boolean, int and option
28 tree. The latter makes it possible to nest options in a hierarchy. Options
29 are statically declared using the `INIT_OPTION_<type>()` macros.
30 An example of an option declaration is:
32         INIT_OPT_INT("protocol.bittorrent.ports", N_("Minimum port"),
33                 "min", 0, LOWEST_PORT, HIGHEST_PORT, 6881,
34                 N_("The minimum port to try and listen on.")),
36 Once an option has been declared it can be accessed using the
37 `get_opt_<type>()` functions. To get the value of the option
38 declared above use:
40         int min_port = get_opt_int("protocol.bittorrent.ports.min");
43 Data Structures and Utilities
44 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46 The C language does not natively support essential data structures and
47 utilities such as lists and strings. ELinks provides interfaces for both of
48 these as described in the following section.
50 Lists
51 ^^^^^
53 In `src/util/lists.h` ELinks defines a fairly complete interface for
54 handling double-linked lists. A list item is declared by using the
55 `LIST_HEAD()` macro to put `next` and `prev` members
56 in a `struct` like this:
58 ------------------------------------------------------------------------------
59         struct bittorrent_data_structure {
60                 LIST_HEAD(struct bittorrent_data_structure);
62                 /* ... */
63         };
64 ------------------------------------------------------------------------------
66 A list of type `struct list_head` can then be declared by using
67 the `INIT_LIST_HEAD()` macro if it is statically allocated:
69         INIT_LIST_HEAD(bittorrent_list);
71 or initialised in an allocated data structure using the following:
73         init_list(bittorrent_data_structure->list);
75 When iterating a list, there are two looping macros: 
77 foreach (list-item, list-head})::
79         Iterates through all items in the list.
81 foreachsafe (list-item, next-list-item, list-head)::
83         Which is similar to the `foreach` iterator, but makes it possible
84         to delete items from the list without causing trouble.
86 For both of the above iterators there exists inverse iterators called
87 `foreachback()` and `foreachbacksafe()`, respectively.
89 Strings
90 ^^^^^^^
92 The strings library add functionality for appending character to strings
93 from various sources. Strings are maintained using the `string`
94 `struct`, and defined in `src/util/string.h` and `util/conv.h`.
95 Some of the most important functions are shown below:
97 init_string(string)::
99         Creates string.
101 done_string(string)::
103         Deallocates string.
105 add_to_string(string, char-array)::
107         Adds a `NULL`-terminated array of type `unsigned char`
108         to string.
110 add_bytes_to_string(string, char-array, char-array-length)::
112         Adds char-array-length bytes from an array of type
113         `unsigned char` to string.
116 Bitfields
117 ^^^^^^^^^
119 To handle bitfields we have made a small bitfield library available in
120 `src/util/bitfield.h`. The most important functions and macros are
121 explained below:
123 init_bitfield(size)::
125         Allocates a bitfield with the given number of bits. The bitfield
126         is deallocated by using `mem_free()`.
128 set_bitfield_bit(bitfield, bit)::
130         Sets bit in bitfield. There is also a complementary function
131         `clear_bitfield_bit()`.
133 test_bitfield_bit(bitfield, bit)::
135         Tests whether the given bit is set in the bitfield.
138 Subsystems
139 ~~~~~~~~~~
141 In the following sections various important subsystems are presented. An
142 overview of the subsystems is given in the figure below.
144 .Overview of the hierarchy of the various subsystems. At the bottom are \
145  subsystems that provide functionality used by the upper layers.
146 ------------------------------------------------------------------------------
147         +-----------------------------+ +-----------------------------+
148         |    Document Type Handling   | |       URI Downloading       |
149         +-----------------------------+ +-----------------------------+
151         +-------------------------------------------------------------+
152         |                 Protocol Implementation                     |
153         +-------------------------------------------------------------+
155         +-------------------------------------------------------------+
156         |                       Socket API                            |
157         +-------------------------------------------------------------+
159         +-------------+ +--------+ +---------------+ +----------------+
160         | Select loop | | Timers | | Bottom halves | | Simple threads |
161         +-------------+ +--------+ +---------------+ +----------------+
162 ------------------------------------------------------------------------------
165 The `select()` loop
166 ^^^^^^^^^^^^^^^^^^^
169 At the heart of ELinks is the `select()` loop which is entered after all
170 module have been initialised. It runs until ELinks is shutdown.  The
171 `select()` loop handles detecting status changes to registered file
172 descriptors, and calls the registered handlers. It is part of the lowest layer
173 in shown in the figure, and is defined in `src/main/select.h`.  It provides
174 two functions:
177 set_handlers(file-descriptor, read-handler, write-handler, error-handler, data)::
179         This function registers the read, write and error handlers for the
180         given file descriptor. The handlers will be called with data as the
181         only argument if the status of the file descriptor changes. Any of the
182         passed handlers maybe be `NULL` if no handling is required for the
183         specific status change.
185 clear_handlers(file-descriptor)::
187         Unregister all handlers for the given file descriptor.
190 Timers
191 ^^^^^^
193 The `select()` loop regularly causes timer expiration to be checked. The
194 interface is defined in `src/main/timer.h` and can be used to schedule work to
195 be performed some time in the future.
197 install_timer(timer-id, time-in-milliseconds, expiration-callback}, data)::
199         Starts a one shot timer bound to the given timer ID that will expire
200         after the given time in milliseconds. When the timer expires the
201         expiration callback will be called with data as the only argument.
203 kill_timer(timer-id)::
205         Stops the timer associated with the given timer ID.
208 Bottom Halves
209 ^^^^^^^^^^^^^
211 Work can be prosponed and scheduled for completion in the nearest future by
212 using bottom halves. This is especially useful when nested deeply in some call
213 tree and one needs to cleanup some data structure but cannot do so immidately.
214 The interface is defined in `src/main/select.h`
216 register_bottom_half(work-function, data})::
218         Schedules postponed work to be run and completed in the nearest
219         future. Note that although this helps to improve the response time it
220         requires more focus on concurrency, such as ensuring that the data
221         passed to the bottom half won't disappear while being handled.
224 Simple Threads
225 ^^^^^^^^^^^^^^
227 ELinks also supports a simple threading architecture. It is possible to start
228 a thread\footnote{(on UNIX systems this will end up using the `fork()`
229 system call} so that communication between it and the ELinks program is
230 handled via a pipe. This pipe can then be used to pass to the
231 `set_handlers()` function so that communcation is done asynchronously.
233 start_thread(thread-function, thread-data, thread-data-length)::
235         Starts a new thread which will run the given thread function. The
236         thread function is passed the given thread data as its first argument
237         and a pipe descriptor it can use for communication with the ELinks
238         program as its second argument. This function returns the pipe
239         descriptor for the other end of the pipe to the calling ELinks
240         program.
243 Socket API
244 ^^^^^^^^^^
246 This layer provides a high-level interface for socket communication
247 appropriate for protocol implementations. When initialising a socket, a
248 `struct` containing a set of callbacks is passed along with some private
249 connection data which will be associated with the socket and passed to the
250 callbacks. Among the callbacks are `set_state()` which is called when the
251 socket state changes, for instance after a successful DNS look-up. Another
252 function is  `set_timeout()` that will be called when progress is done, such
253 as during writing or reading . Finally, there is `retry()` and `done()` both
254 of which are called when an error occurs: the former is used for errors that
255 might be possible to resolve; the latter is used for fatal errors.
257 The interface is defined in `src/network/socket.h` and the most notable
258 functions are:
260 make_connection(socket, uri, connect-callback, no-dns-cache)::
262         This function handles connecting to the host and port given in the uri
263         argument. If the internal DNS cache is not to be used the
264         no-dns-cache} argument should be non-zero.  Upon successful connection
265         establishment the connect callback is called.
267 read_from_socket(socket, read-buffer, connection-state, read-callback)::
269         Reads data from socket into the given read buffer. Each time new data
270         is received the read callback is called. Changes the connection state
271         to connection-state} immediately  after it has been called.
273 write_to_socket(socket, data, datalen, connection-state, write-callback)::
275         Writes datalen bytes from the data to the given socket. Upon
276         completion the write callback is called. Changes the connection state
277         to connection state immediately after being called.
280 The buffer interface used for reading is as follows:
282 alloc_read_buffer(socket)::
284         Allocates a new read buffer which can be passed to
285         `read_from_socket()`.
287 kill_buffer_data(read-buffer, number-of-bytes)::
289         Removes the requested number of bytes from the start of the given read
290         buffer.
293 Protocol Layer and URI Loading
294 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
296 The protocol layer multiplexes over different protocol back-ends. The protocol
297 multiplexing decides what protocol back-end to use by looking at the protocol
298 string in the connection URI, i.e. `http` part of `http://127.0.0.1/` will
299 cause the HTTP protocol back-end to be selected.  Each protocol back-end
300 exports a protocol handler taking a `connection` `struct` as its only
301 argument.  The `connection` struct contains information such as the URI being
302 loaded and status about how much has been downloaded and the current
303 connection state. How the protocol back-end chooses to handle the connection
304 and load the URI it points to is entirely up to the back-end.  The interface
305 is defined in `src/protocol/protocol.h` and `src/network/connection.h`.
307 A connection can have multiple downloads attached to it. Each download struct}
308 contains information about the connection state and the connection with which
309 it is attached. Additionally, the `download struct` specifies callback data,
310 and a callback which is called each time the download progresses.  The
311 interface for downloads is defined in `src/session/download.h` and the most
312 important functions it provides are:
314 load_uri(uri, referrer, download, priority, cache-mode, offset)::
315         
316         Attaches the given download to a connection which will try to load the
317         given URI. If a connection is already in progress the download is
318         simply attached to that one.
320 change_connection(old-download, new-download, new-priority, interrupt)::
322         Removes the old download from the connection it is attached to and add
323         the new download instead. If the new download argument is `NULL`, the
324         old download is simply stopped.
326 All data loaded by a connection is put into ELinks' cache. Cache entries can
327 then used for passing data to download handler, etc. The connection will
328 create a cache entry once it starts receiving data. Each time it adds data a
329 new fragment is added to the cache entry, this means that the cache entry
330 needs to be defragmented before data in it can be processed.  From time to
331 time the cache will be shrunk and unlocked cache entries will be removed.
334 Document Type Handling
335 ^^^^^^^^^^^^^^^^^^^^^^
337 When a user asks ELinks to load a URI, ELinks  will eventually have to try and
338 figure out the document type of the URI in order to handle it properly, either
339 by using an internal renderer or by passing the document to an external
340 handler. This is done in the following function:
342 setup_download_handler(session, download, cache-entry, frame)::
344         Tries to resolve the document type of the given cache entry by first
345         looking at the protocol header it contains. If no content type is
346         found it will try to resolve the document type by looking at the file
347         extension in the loading URI. Based on the content type, either an
348         internal or an external handler is selected. The user will be queried
349         before using an external handler.