2
* Pure Data Packet system implementation. Type handling interface
3
* Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
Since version 0.11 all packets have an (optional) high level type description.
25
This can be thought of as their mime type. It has several uses:
27
* automatic type conversion
28
* better reuse strategy for non pure packets
31
The description is text-encoded, in the following form:
33
type/subtype/subsubtype/..
35
This is implemented using t_pdp_symbol.
37
Type descriptors can have wildcards. This is to give some freedom to a desired
38
type conversion. The following are all compatible:
48
From a user pov, the type conversion is centralized. A single object (pdp_convert)
49
can do most of the conversions.
51
Type conversion implementation has to be done decentralized. It is subdivided into
52
two steps: inter-type and intra-type conversions.
54
Intra-type is the full responsability of each type implementation and can be handled
55
in a decentralized way (at linkage the type central intra-converter is registered
58
Inter-type conversion is harder to do decentralized, therefore each new type should
59
provide some conversions to the basic built in types. (internal image, bitmap or matrix
62
The point of this whole business is to
64
* enable automatic conversion from anything to a desired type for operators that combine objects.
65
i.e. pdp_add but receive incompatible objects.
66
* enable manual anything to anything conversion using a pdp_convert object, i.e. have a consistent
67
package conversion api for users.
70
The solution is type conversion programs. A program's behaviour is specified as follows:
72
* the program is registered with a source and destination (result) template
73
* it is passed a packet and a destination template
74
* it can assume the source packet complies to the program's registerd source template
75
* it should convert the packet to a packet that will comply to it's registered destination template
76
* if for some reason a conversion fails, an invalid packet (handle == -1) should be returned
80
* they are hierarchical, with subtypes separated by a '/' character
81
* they can contain a wildcard '*', meaning that a certain level in the type hierarchy is:
82
- a don't care value, when the wildcard is used
83
-> as a destination template in a requested conversion
84
-> as a source template in a conversion program's specification
85
- uspecified, when the wildcard is used
86
-> as a destination template in a conversion program's specification
92
a wildcard can't be used in a source template for a conversion request
93
this assymetry requires there be 2 kinds of template matching mechanisms:
95
- source type description (without wildcards) to conversion program source template matching
96
- destination type description (with wildcards) to conversion program destination template matching
98
since a packet's type description cannot have wildcards, a symmetric matching (both sides have
99
wildcards) can be used for matching.
109
there are 2 lists with conversion progams:
110
* the global list, containing all registered programs.
111
* the cached list, containing all recently used registered programs, or combinations thereof
113
if there is no cached, perfectly matching rule, a new one will be created, and added to
114
the head of the conversion list.
116
all conversion methods should keep their hand's off the source packet. it is treated as readonly.
117
this is to ensure a more flexible operation (i.e. be able to put the conversion at the register_ro
118
level) this will need a bit more logic in running the conversion program though..
126
/* the conversion method accepts a packet (which is freed) and a destination wildcard
127
and produces a new packet, or the invalid packet if the conversion failed */
128
typedef int (*t_pdp_conversion_method)(int, t_pdp_symbol *);
130
/* a conversion program is alist of conversion methods */
131
typedef struct _pdp_conversion_program
133
t_pdp_conversion_method method; // conversion method
134
struct _pdp_conversion_program *next; // next method in program
135
} t_pdp_conversion_program;
137
/* a conversion has source and dest wildcards, and a conversion program */
138
typedef struct _pdp_conversion
140
t_pdp_symbol *src_pattern; // source type pattern
141
t_pdp_symbol *dst_pattern; // destination type pattern
142
t_pdp_conversion_program *program; // the conversion program for this conversion
143
struct _pdp_conversion *next; // next conversion program record
146
/* all symbols are C style */
152
/* pdp_packet methods */
153
t_pdp_symbol *pdp_packet_get_description(int packet);
154
int pdp_packet_convert_ro(int packet, t_pdp_symbol *dest_pattern);
155
int pdp_packet_convert_rw(int packet, t_pdp_symbol *dest_pattern);
158
/* pdp_conversion_program methods */
159
void pdp_conversion_program_free(t_pdp_conversion_program *program);
160
t_pdp_conversion_program *pdp_conversion_program_new(t_pdp_conversion_method method, ...);
161
t_pdp_conversion_program *pdp_conversion_program_copy(t_pdp_conversion_program *program);
162
void pdp_conversion_program_add(t_pdp_conversion_program *program, t_pdp_conversion_program *tail);
164
/* pdp_type (central type object) methods */
165
int pdp_type_description_match(t_pdp_symbol *description, t_pdp_symbol *pattern);
166
void pdp_type_register_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program);
167
void pdp_type_register_cached_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program);
169
//t_pdp_symbol *pdp_type_gendesc(char *desc); //generate a type description (with description list attached)
170
t_pdp_list *pdp_type_to_list(t_pdp_symbol *type);
172
/* pdp's (threadsafe) symbol */
173
t_pdp_symbol *pdp_gensym(char *s);