Skip to content

Schemes:Notes

Christopher Ross-Gill edited this page Aug 1, 2016 · 6 revisions

Ports access external series such as files, networks, consoles, events, databases, data encoders, and data decoders.

In Rebol 3.0, the port system has be completely redesigned to make it simpler, faster, and easier to use. Substantial effort has been made to remove the majority of the complex internal mechanisms and replace it with a smart streamlined system.

Table of Contents

Architecture

The diagram below shows the basic relationship between schemes, ports, requests, and devices:

Definitions:

Scheme
specifies a type of port, such as file, TCP, event, sound, etc. The scheme creates a port, which is:
Port
a specific instance of a scheme. For example, when you read a file, the scheme is used to create a port that accesses the file and its data. Each open file has its own port.
Request
is a lower level (C) structure used to communicate between a port and a device. In the case of a file, it passes fields like the file name, date, size, and data to be transferred.
Device
is native C code that implements a standard set of access methods for a port. Example methods include open, close, read, write, create, and delete. This level is where file or network I/O actually happens.
Only ports that require native support need requests and ports. Higher level ports, such as HTTP, do not directly create requests. Typically, they use lower level ports, such a TCP, and those do use requests.

The primary benefit of this design is that it formalizes a method for accessing a wide range of devices without expanding the Rebol-to-environment API for each device. In a way, it implements a mini operating system to keep Rebol as system-independent as possible.

Schemes

A scheme specifies a type of port.

The name scheme comes from the description of a URI (URL):

http://host/path

Here HTTP is the scheme name in the URL.

Built-in schemes

A variety of schemes are built-into Rebol 3 and can be used immediately on boot.

Here is a partial list of built-in schemes:

Scheme Description
system System port (primary event dispatcher)
stdio Standard input and output
stderr Standard error
console Rebol interactive console
file Local file access
dir Local file directory access
event GUI event handling
DNS Domain name lookup
TCP Transfer control protocol
UDP User datagram protocol
HTTP Hypertext transfer protocol
shell External shell commands (call)
serial Serial port access
USB USB serial port access
mutex Mutual exclusion locks

More (such as FTP, SMTP, POP) will be included as time and user-base contributions permit.

To list the current schemes:

print words-of system/schemes

or:

foreach val get system/schemes [print [val/name val/title]]

Scheme object structure

The scheme object is defined in system/standard as:

scheme: context [
    name:       ; word of http, ftp, sound, etc.
    title:      ; user-friendly title for the scheme
    spec:       ; custom spec for scheme (if needed)
    info:       ; prototype info object returned from query
    actor:      ; standard action handler for scheme port functions
    awake:      ; standard awake handler for this scheme's ports
        none
]

Where:

name
is the type of scheme. This is the word used in the first part of the URL, such as TCP, HTTP, FTP, etc.. It must be a valid Rebol word (e.g. cannot begin with a number).
title
is the title of the scheme for user identification and documentation purposes.
spec
an object used to specify additional features of the scheme.
info
an prototype object that is instantiated for a query on the scheme.
actor
the handler function that processes standard actions a port of this scheme type. For example, open, close, read, write, etc.
awake
a callback function that is invoked when new events arrive for a port of this scheme type.

Adding a new scheme

The `make-scheme` function creates a new scheme from a block object specification.

(show example)

Ports

A port is an active instance of a scheme.

For example, when you open a file, the system creates a port from the file scheme. The port keeps track of the I/O for that specific file, as well as specific information about the file, such as date, size, and current index position.

The Rebol 3 design for ports is more streamlined than the prior version - providing faster access and with less memory.

Port object structure

The standard port object has been substantially reduced in size and complexity from Rebol 2. The new object is defined by system/standard as:

port: context [
    spec:       ; published specification of the port
    scheme:     ; scheme object used for this port
    actor:      ; port action handler (script driven)
    awake:      ; port awake function (event driven)
    state:      ; internal state values (private)
    data:       ; data buffer (usually binary or block)
        none
]

Where:

spec
is the object used to define the port. It holds the scheme name and other fields, such as the host for network ports. The format of the spec object depends on the scheme of the port.
scheme
points back to the scheme object for this port. It is normally used by lower layers that may need to check scheme related values.
actor
a function that is called for handling port actions. Normally, it is the same as that of the scheme, but it can be unique to a specific port. This function can be a native or mezzanine.
awake
a callback function called when new events arrive for the port. This is normally the same as that of the scheme, but but it can be unique to a specific port.
state
private state data. This is an object or a C-structure in the case of native port schemes. Scripts should not access the state! The format and definition of the state is allowed to change between versions.
data
a buffer that is used for the most common types of ports (those that transfer data).
This object is converted to a PORT datatype during the port's initialization sequence.

Specific types of ports (schemes) are allowed to extend this structure for their own purposes, but developers should avoid unnecessary fields (bloat).

Port specification object

Port actor functions

Port awake functions

Make note about return value. A TRUE will satisfy a WAIT, but other values do not.

Event processing

notes about system port as primary dispatcher

Devices and Requests

covered in separate document

Clone this wiki locally