Provides some Design Patterns. Design Patterns were introduced mainly by the Gang of Four in their great book: Design Patterns -- Elements of Reusable Object-Oriented Software (E. Gamma et al.) We also use the book Design Patterns and Contracts (J.-M. Ézéquiel et al.)
The currently available Design Patterns are:
FACTORY
;CHAIN_OF_RESPONSIBILITY
CHAIN_HANDLER
that can handle a request from the Chain;
Creating a PROCESS
object starts an asynchronous process. The
standard streams of that process are redirected to the caller via three streams.
HTML is the HyperText Markup Language, defined with tags such as <p>...</p>
.
This cluster contains two important classes:
HTML_OUTPUT_STREAM
used to write some HTML
correctly laid out. Instead of a generic put_string
, this class offers a lot of features that
control opening and closing of tags;HTML_PARSER
used to read HTML and split it in a
semantic tree. This tree is a Composite made of HTML_ELEMENT
s.When creating streams, one should procede as follows:
connect_to
feature of
filter streams;Taken together, interconnected filters and terminal make a filtered stream; one reads and/or writes from one side of the "pipe", while the terminal reads/writes at the other side.
First of all, input and output streams have symmetrical hierarchies. They also have a common ancestor.
Those classes are split in two hierarchies: on the one hand, filters, on the other hand, terminals.
Filtered streams are in fact a double-linked objects: each filter points to an underlying
stream
(be it another filter or a terminal) while each stream points to a
filter
. The "stream-to-filter" back-link is used for assertions, to ensure one does not bypass
filters.
Filters are stuck in front of a stream (be it another filter or a terminal). They provide extra functionality: compression, buffers, and so on.
Note: you cannot directly use streams that are connected to a filter; use that filter instead.
Terminals are back-end bytes readers and/or writers. There are many such terminals: files, sockets, strings
and so on. There are even the equivalent of the good old Unix /dev/null
device, which eats bytes
and provides zeroes.
There are three kinds of terminal streams: TERMINAL_INPUT_STREAM
, TERMINAL_OUTPUT_STREAM
, and TERMINAL_INPUT_OUTPUT_STREAM
Note that there are only terminal input-output streams. Filters do not have this notion: you use either an input or an output stream, even if the underlying resource has input-output capabilities.
The class STANDARD_STREAMS
provides access to the
standard streams. GENERAL
provides an access to a
STANDARD_STREAMS
once object, along with shortcuts to the most used features: the standard
streams std_input
, std_output
, std_error
, and the most used
io
which is but a centralized access to the former two.
STANDARD_STREAMS
provides features to dynamically
change standard streams. It allows to:
The easiest way for reading characters on an input_stream is as follow:
from
-- connect my_input_stream if needed here
my_input_stream.read_character
until
my_input_stream.end_of_input
loop
-- use my_input_stream.last_character
my_input_stream.read_character
end
my_input_stream.disconnect
The easiest way for reading lines on an input_stream is as follow:
from
-- connect my_input_stream if needed here
until
my_input_stream.end_of_input
loop
my_input_stream.read_line
if my_input_stream.end_of_input then
-- The last line of the file does not end with a new line
-- character. Remove this test if you don't care.
-- use my_input_stream.last_string
else
-- use my_input_stream.last_string
end
end
my_input_stream.disconnect
Note:
FILE_TOOLS
for some basic file management (rename,
delete, access to size, date, permissions...);DIRECTORY
for directory exploration (see also the more
low-level BASIC_DIRECTORY
in the low_level
cluster.Provides iterators on various containers. See Adding external iterators to an existing Eiffel class library.
Examples can be found in directory SmartEiffel/tutorial/iterator.
Provides the very basic functionalities the compiler could not dream of working without.
Provides miscellaneous classes.
This page is divided into the following sections:
Access | A word used by this cluster to design a server access on a host. |
Address | A word used by this cluster to design a host. |
Host | A machine connected to a network. Such a machine has an address and, usually, a name. |
Server | A program that runs on a host. Such a programs listens on a "port number". |
To be client means trying to reach some server and getting some data from it.
There are two concepts to grasp before making a connection:
To be a client, you have to do three things, in that order:
In SmartEiffel, you would write it this way:
connect_to_funet: TERMINAL_INPUT_OUTPUT_STREAM is local funet: HOST tcp: TCP_ACCESS do create funet.make(once "ftp.funet.fi") create tcp.make(funet, 21) Result := tcp.stream end
(See also the tutorial: class SOCKETS
)
To be a server, things are a bit more complex but not tremendously so.
First note that you must know something of the lib/sequencer
cluster. You must also be familiar with
agents.
To create a server, start by creating an address and an access. The address will filter which connections are allowed1, and the access port will determine which port the server will listen to.
Now you must create a SOCKET_SERVER
, give it one or more
agents using the `when_connect'
feature. Those agents are called whenever a new client connects;
each agent is given the same stream that represents the connection to the client.
Note that having multiple agents is potentially dangerous. Either all the agents cooperate, either having one registered is enough. Remember that all agents share the same stream.
This cluster contains two very intersting classes since they provide a framework to build multiplexing servers.
SERVER
is a multiplexing server. IT can either start its
own stand-alone stack or use an existing stack. You give it an access and it listens onto it and starts
connections when a new client connects.CONNECTION
is a connection started by the server
whenever a client connects. A stream connected to that client is provided.Provides numeric classes. There are three kinds of classes:
MUTABLE_BIG_INTEGER
provides infinite-precision
integers, while the NUMBER
classes provide infinite-precision
integers and decimals (see also their Factory: NUMBER_TOOLS
)Provides random numbers generators.
Originally written by : Bruce Wielinga
TIME_EVENTS centralize time events management because INTEGER, TIME and MICROSECOND_TIME are mutable expanded objects.
Other events are directly managed by their creating object: INPUT_STREAM, OUTPUT_STREAM and SOCKET_SERVER directly create their associated event.
Provides collection sorters.
Provides storage classes of all kind. We call "storage objects" instances of classes that can store many objects of the same kind.
There are many kinds of storage classes:
Storage objects all provide the same kind of features regarding to the access to elements (iteration). In fact, they provide two iteration patterns:
lib/iterator
cluster. This cluster also provides natural differenciation between abstractions and their implementations. All the
abstractions are in the lib/storage
cluster, while the
implementations reside each in a sub-cluster reflecting the abstraction their classes refer to. The exceptions
are STACK
and QUEUE
which stand on their own.
Collections are sequences of object than can be directly accessed by their index. That's what is called "lists" in other libraries. See also collection2 (indexed matrices) and collection3 (indexed 3D matrices)
On the implementation side, we have the classical ARRAY
s, but
also lists (single- or double-linked). There is also the FAST_ARRAY
, a zero-bound array, and the RING_ARRAY
which is a ring buffer.
Dictionaries are sets of couples (key, value). Each key is unique in the dictionany. Bijective-dictionaries have a stronger constraint: each value is also unique.
There are two families of implementation: hashed-based
dictionaries (using hashable objects, see the lib/abilities
cluster) and AVL-based dictionaries (using comparable objects in a balanced tree, and
ensuring the iteration order to be growing).
Sets are groups of objects. Each object can only be once in a set; all that can be known about an object is, is it in the set or not. Multi-sets allow objects to be several times in the group, associationg a counter with each object (note: multi-sets are not yet available).
The implementations are quite similar to the dictionaries: there are hashed-based and AVL-based sets, with the same constraints and properties than the dictionaries.
Repositories are very special objects. They are designed to contain STORABLE
objects. Those objects can be stored or retrieve, usign
resp. the update
command which updates the repository, and the commit
command which
commits the repository to its underlying medium (whatever that is: stream, database, and so on).
Where and how those objects are retrieved, is of no concern of this deferred class. There is currently one available implementation: a stream-based, XML-based repository.
Provides strings, which are sequences of characters. There are two kinds of strings: the standard ASCII strings (using 8-bit characters), and Unicode strings.
Note that the compiler accepts a special notation for manifest Unicode strings: U"example"
Provides time facilities, allowing to:
Provides tools for unicode string support. See also http:www.unicode.org to view character code chart.
See also the lib/string
cluster, and especially
the UNICODE_STRING
class.
XML is the eXtended Markup Language, defined by the World-Wide Web Consortium.
This cluster contains an XML parser and all the classes to allow simple XML manipulation.
There is also a namespace-aware cluster.
Provides "abilities". Those classes are best used via inheritance. They give extra functionality to a class.
The currently available abilities are:
COMPARABLE
for objects that can be compared between themselves;HASHABLE
for objects that want to interact with the Garbage Collector when they are about to be collected;HASHABLE
for objects that provide a hash code (e.g. useful for hashed dictionaries and sets);OBSERVABLE
for objects that can notify observers when their state changes (that's the Observer Design Pattern);RECYCLABLE
for objects that can be reused via aRECYCLING_POOOL
;STORABLE
for objects that want to be put on an external medium, to be retrieved again later;TRAVERSABLE
for objects that provide traversal facilities;VISITABLE
for objects that can be visited using the Visitor Design Pattern.