00001 #ifndef _PUP_C_H 00002 #define _PUP_C_H 00003 00004 /* 00005 Pack/UnPack Library for UIUC Parallel Programming Lab 00006 C Bindings version 00007 Orion Sky Lawlor, olawlor@uiuc.edu, 9/11/2000 00008 00009 This library allows you to easily pack an array, structure, 00010 or object into a memory buffer or disk file, and then read 00011 the object back later. The library will also handle translating 00012 between different machine representations for integers and floats. 00013 00014 This is the C binding-- the main library is in C++. 00015 From C, you can write a pup routine (the client part of the 00016 library), but you can't make pup_er's (the system part). 00017 00018 Typically, the user has to write separate functions for buffer 00019 sizing, pack to memory, unpack from memory, pack to disk, and 00020 unpack from disk. These functions all perform the exact same function-- 00021 namely, they list the members of the array, struct, or object. 00022 Further, all the functions must agree, or the unpacked data will 00023 be garbage. This library allows the user to write *one* function, 00024 which will perform all needed packing/unpacking. 00025 00026 A simple example is: 00027 typedef struct foo { 00028 int x; 00029 char y; 00030 unsigned long z; 00031 float q[3]; 00032 } foo; 00033 00034 void pup_foo(pup_er p,foo *f) 00035 { 00036 pup_int(p,&f->x); 00037 pup_char(p,&f->y); 00038 pup_ulong(p,&f->z); 00039 pup_floats(p,f->q,3); 00040 } 00041 00042 A more complex example is: 00043 typedef struct bar { 00044 foo f; 00045 int nArr; <- Length of array below 00046 double *arr; <- Heap-allocated array 00047 } bar; 00048 00049 void pup_bar(pup_er p,bar *b) 00050 { 00051 pup_foo(p,&b->f); 00052 pup_int(p,&b->nArr); 00053 if (pup_isUnpacking(p)) 00054 b->arr=(double *)malloc(b->nArr*sizeof(double)); 00055 pup_doubles(p,b->arr,b->nArr); 00056 } 00057 00058 */ 00059 00060 #include "conv-config.h" 00061 #include <stddef.h> 00062 00063 #ifdef __cplusplus 00064 extern "C" { 00065 #endif 00066 00067 /*This is actually a PUP::er *, cast to void *. 00068 From C++, you can pass "&p" as a pup_er. 00069 */ 00070 typedef void *pup_er; 00071 00072 00073 #ifndef AMPI_INTERNAL_SKIP_FUNCTIONS 00074 00075 #define AMPI_CUSTOM_FUNC(return_type, function_name, ...) \ 00076 extern return_type function_name(__VA_ARGS__); 00077 00078 #include "pup_c_functions.h" 00079 00080 #undef AMPI_CUSTOM_FUNC 00081 00082 #endif /* !defined AMPI_INTERNAL_SKIP_FUNCTIONS */ 00083 00084 00085 /* These MUST match the sync declarations in pup.h */ 00086 enum { 00087 pup_sync_builtin=0x70000000, /* Built-in, standard sync codes begin here */ 00088 pup_sync_begin=pup_sync_builtin+0x01000000, /* Sync code at start of collection */ 00089 pup_sync_end=pup_sync_builtin+0x02000000, /* Sync code at end of collection */ 00090 pup_sync_last_system=pup_sync_builtin+0x09000000, /* Sync code at end of "system" portion of object */ 00091 pup_sync_array_m=0x00100000, /* Linear-indexed (0..n) array-- use item to separate */ 00092 pup_sync_list_m=0x00200000, /* Some other collection-- use index and item */ 00093 pup_sync_object_m=0x00300000, /* Sync mask for general object */ 00094 00095 pup_sync_begin_array=pup_sync_begin+pup_sync_array_m, 00096 pup_sync_begin_list=pup_sync_begin+pup_sync_list_m, 00097 pup_sync_begin_object=pup_sync_begin+pup_sync_object_m, 00098 00099 pup_sync_end_array=pup_sync_end+pup_sync_array_m, 00100 pup_sync_end_list=pup_sync_end+pup_sync_list_m, 00101 pup_sync_end_object=pup_sync_end+pup_sync_object_m, 00102 00103 pup_sync_item=pup_sync_builtin+0x00110000, /* Sync code for a list or array item */ 00104 pup_sync_index=pup_sync_builtin+0x00120000, /* Sync code for index of item in a list */ 00105 00106 pup_sync_last 00107 }; 00108 00109 #ifdef __cplusplus 00110 } 00111 #endif 00112 00113 #endif