/* * Pure Data Packet system implementation. Type handling interface * Copyright (c) by Tom Schouten * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ /* COMMENTS Since version 0.11 all packets have an (optional) high level type description. This can be thought of as their mime type. It has several uses: * automatic type conversion * better reuse strategy for non pure packets * debugging The description is text-encoded, in the following form: type/subtype/subsubtype/.. This is implemented using t_pdp_symbol. Type descriptors can have wildcards. This is to give some freedom to a desired type conversion. The following are all compatible: */ // image/grey/320x240 // image/*/320x240 // image/*/* /* From a user pov, the type conversion is centralized. A single object (pdp_convert) can do most of the conversions. Type conversion implementation has to be done decentralized. It is subdivided into two steps: inter-type and intra-type conversions. Intra-type is the full responsability of each type implementation and can be handled in a decentralized way (at linkage the type central intra-converter is registered at the pdp framework. Inter-type conversion is harder to do decentralized, therefore each new type should provide some conversions to the basic built in types. (internal image, bitmap or matrix types. The point of this whole business is to * enable automatic conversion from anything to a desired type for operators that combine objects. i.e. pdp_add but receive incompatible objects. * enable manual anything to anything conversion using a pdp_convert object, i.e. have a consistent package conversion api for users. The solution is type conversion programs. A program's behaviour is specified as follows: * the program is registered with a source and destination (result) template * it is passed a packet and a destination template * it can assume the source packet complies to the program's registerd source template * it should convert the packet to a packet that will comply to it's registered destination template * if for some reason a conversion fails, an invalid packet (handle == -1) should be returned about type templates: * they are hierarchical, with subtypes separated by a '/' character * they can contain a wildcard '*', meaning that a certain level in the type hierarchy is: - a don't care value, when the wildcard is used -> as a destination template in a requested conversion -> as a source template in a conversion program's specification - uspecified, when the wildcard is used -> as a destination template in a conversion program's specification NOTE: a wildcard can't be used in a source template for a conversion request this assymetry requires there be 2 kinds of template matching mechanisms: - source type description (without wildcards) to conversion program source template matching - destination type description (with wildcards) to conversion program destination template matching since a packet's type description cannot have wildcards, a symmetric matching (both sides have wildcards) can be used for matching. */ /* implementation: there are 2 lists with conversion progams: * the global list, containing all registered programs. * the cached list, containing all recently used registered programs, or combinations thereof if there is no cached, perfectly matching rule, a new one will be created, and added to the head of the conversion list. all conversion methods should keep their hand's off the source packet. it is treated as readonly. this is to ensure a more flexible operation (i.e. be able to put the conversion at the register_ro level) this will need a bit more logic in running the conversion program though.. */ #ifndef PDP_TYPE_H #define PDP_TYPE_H /* the conversion method accepts a packet (which is freed) and a destination wildcard and produces a new packet, or the invalid packet if the conversion failed */ typedef int (*t_pdp_conversion_method)(int, t_pdp_symbol *); /* a conversion program is alist of conversion methods */ typedef struct _pdp_conversion_program { t_pdp_conversion_method method; // conversion method struct _pdp_conversion_program *next; // next method in program } t_pdp_conversion_program; /* a conversion has source and dest wildcards, and a conversion program */ typedef struct _pdp_conversion { t_pdp_symbol *src_pattern; // source type pattern t_pdp_symbol *dst_pattern; // destination type pattern t_pdp_conversion_program *program; // the conversion program for this conversion struct _pdp_conversion *next; // next conversion program record } t_pdp_conversion; /* all symbols are C style */ #ifdef __cplusplus extern "C" { #endif /* pdp_packet methods */ t_pdp_symbol *pdp_packet_get_description(int packet); int pdp_packet_convert_ro(int packet, t_pdp_symbol *dest_pattern); int pdp_packet_convert_rw(int packet, t_pdp_symbol *dest_pattern); /* pdp_conversion_program methods */ void pdp_conversion_program_free(t_pdp_conversion_program *program); t_pdp_conversion_program *pdp_conversion_program_new(t_pdp_conversion_method method, ...); t_pdp_conversion_program *pdp_conversion_program_copy(t_pdp_conversion_program *program); void pdp_conversion_program_add(t_pdp_conversion_program *program, t_pdp_conversion_program *tail); /* pdp_type (central type object) methods */ int pdp_type_description_match(t_pdp_symbol *description, t_pdp_symbol *pattern); void pdp_type_register_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program); void pdp_type_register_cached_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program); //t_pdp_symbol *pdp_type_gendesc(char *desc); //generate a type description (with description list attached) t_pdp_list *pdp_type_to_list(t_pdp_symbol *type); /* pdp's (threadsafe) symbol */ t_pdp_symbol *pdp_gensym(char *s); #ifdef __cplusplus } #endif #endif