Dispatch table
|
|
In computer science, a dispatch table is a list of pointers to the actual implementation of each method. Use of such a table is a common technique when implementing late binding in object-oriented programming. Generally, OOP languages support the table as a built-in feature to provide seamless late binding.
Hand-coded implementation
Example implementation in C (Spinellis, 2003, pp. 312–313). The following structure declaration—excerpted from the FreeBSD/NetBSD implementation of the pax archive reading and writing program—contains pointers to functions used for performing archive processing operations:
typedef struct {
char *name; /* name of format, this is the name the user */
/* [...] */
int (*id)(char *, int); /* checks if a buffer is a valid header */
int (*st_rd)(void); /* initialize routine for read. */
int (*rd)(ARCHD *, char *);/* read header routine. */
off_t (*end_rd)(void); /* read cleanup. */
int (*st_wr)(void); /* initialize routine for write operations */
int (*wr)(ARCHD *); /* write archive header. */
int (*end_wr)(void); /* end write. write the trailer and do any */
int (*trail)(char *, int, int *);
/* returns 0 if a valid trailer, -1 if not */
int (*subtrail)(ARCHD *);
/* read/process file data from the archive */
int (*rd_data)(ARCHD *, int, off_t *);
/* read/process file data from the archive */
int (*wr_data)(ARCHD *, int, off_t *);
/* write/process file data to the archive */
int (*options)(void); /* process format specific options (-o) */
} FSUB;
An array of these structures is initialized with functions appropriate for each different archive type:
FSUB fsub[] = {
/* 0: OLD BINARY CPIO */
{ "bcpio", bcpio_id, cpio_strd,
bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, NULL,
cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
/* 1: OLD OCTAL CHARACTER CPIO */
{ "cpio", cpio_id, cpio_strd,
cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, NULL,
cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
/* 2: SVR4 HEX CPIO */
{ "sv4cpio", vcpio_id, cpio_strd,
vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, NULL,
cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
/* 3: SVR4 HEX CPIO WITH CRC */
{ "sv4crc", crc_id, crc_strd,
vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, NULL,
cpio_subtrail, rd_wrfile, wr_rdfile, bad_opt },
/* 4: OLD TAR */
{ "tar", tar_id, no_op,
tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail,
NULL, rd_wrfile, wr_rdfile, tar_opt },
/* 5: POSIX USTAR */
{ "ustar", ustar_id, ustar_strd,
ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail,
NULL, rd_wrfile, wr_rdfile, bad_opt }
};
At runtime, all operations are performed through a FSUB pointer—frmt
in the following example—thus dispatching control to the appropriate method for the archive
being processed:
/* * pass the format any options and start up format */ if (((*frmt->options)() < 0) || ((*frmt->st_rd)() < 0)) return;
OOP compiler implementation
In object-oriented programming languages the compiler will automatically create a dispatch table for objects with dynamically bound methods. This table is called a virtual table or vtable.
References
- Diomidis Spinellis (2003). Code Reading: The Open Source Perspective. Boston, MA: Addison-Wesley. (ISBN 0-201-79940-5)
