gim.h
A part of the GIM project
Introduction
This thread has been specifically created to discuss the gim.h routine. Hopefully, this thread does not get sidetracked. What is gim.h you ask? gim.h is the controller header file for the GIM project. What is GIM you ask? Look
here or
here for a complete discussion about the ideas and goals behind GIM.
A more complete discussion of gim.h
In my way of thinking gim.h is more a ruleset than a header file. It defines the interactions between a User Interface program and a Data Implementation program. gim.h is a middle man and does absolutely nothing by itself.
There are three main parts to any gim module. As shown in the following diagram gim.h is the middle man.
Code:
User Interface ----> gim.h <---- Data Implementation
gim.h is the controller between the two. It should be possible to link any user interface with any data implementation as long as they both adhere to the rules and prototypes given by gim.h. Therefore gim.h will *always* be included in any Data Implementation or User Interface.
gim.h is currently about 450 lines, the vast majority of these being comments. This is one file that should be verbosely commented to explain what is needed or done by certain functions. The only module currently defined is the contact module. This header file will become quite large as the ideas for other gim modules are implemented.
There is a small c file that is used in conjunction with gim.h. The only thing that it holds are literal arrays that are necessary for gim.h. I can not think of anything else that would be in there. The attached zip file has both gim.h and gim.c
This is wide open to discussion, whether you want to participate in GIM or not, I would love to hear comments, questions or even properly worded doubts.
Also, since JdS has such a cool code mark up in this forum, I decided to attach the two files inline as well
gim.h
/**********************************************************************/
/**********************************************************************/
/* The GIM project */
/**********************************************************************/
/* FILENAME: gim.h */
/* ORIGINATION DATE: Nov. 17, 2004 */
/* ORIGINATOR: dsmith */
/* MODULE: none */
/* LICENSE: gpl ([url]www.gnu.org/copyleft/gpl.html[/url]) */
/**********************************************************************/
/* DESCRIPTION: */
/* This is THE header file. It forms the small common thread between */
/* the database and the user interface. If you want to write an */
/* user interface for GIM, you need to call these functions to access */
/* the data. If you want to write a database, you need to implement */
/* these functions. */
/* This file will need to be updated for each module added as well as */
/* modifications to the type of data needed for each module. */
/* This file will be versioned and it will be necessary to match your */
/* applications with the versioning. */
/**********************************************************************/
/* HISTORY: */
/* 0.0.1 - Start of contact prototyping. */
/**********************************************************************/
/**********************************************************************/
#ifndef __GIM_H
#define __GIM_H
/*--------------------------------------------------------------------*/
/* Version Flags */
/*--------------------------------------------------------------------*/
#define GID_RELEASE 0
#define GID_FEATURE 0
#define GID_CHANGE 1
#define GID_VERSION 'A'
/*--------------------------------------------------------------------*/
/* ERROR CODES DEFINED */
/*--------------------------------------------------------------------*/
/* These are the return values that every function should return. */
/* Most functions will return this "status" value. In some cases */
/* the value will be returned in a parameter that is passed by address*/
/*--------------------------------------------------------------------*/
#define GE_OKAY 0
#define GE_CONNECT 1
#define GE_PASSWORD 2
#define GE_GENERAL 3
#define GE_FILENAME 4
#define GE_MALLOC 5
#define GE_FREE 6
#define GE_EMPTY 7
#define GE_INVALID 8
#define GE_VERSION 9
#define SORT_ASCEND 1
#define SORT_DESCEND 2
//This is the error array. It is defined externally in gim.c
//All gim functions should return an error based on the above
//definitions and associated array.
extern char* gid_error[];
/*--------------------------------------------------------------------*/
/* Overall Project Function Prototypes */
/*--------------------------------------------------------------------*/
// login
// Used for potentially logging into a database. Accepts 2 strings that would
// most likely consist of a name and a password.
// RETURNS: a status of GE_NONE, GE_CONNECT or GE_PASSWORD
int login(char* name, char* password);
// logout
// Used to logout of the database. Requires no parameters
// RETURNS: a status of GE_NONE or GE_GENERAL
int logout();
/**********************************************************************/
/**********************************************************************/
/*--------------------------------------------------------------------*/
/* Contact structures & prototypes */
/* Started in version 0.0 */
/*--------------------------------------------------------------------*/
/**********************************************************************/
/**********************************************************************/
/*** Enumerations ***/
//Used for the contact type field
enum ct_type{ALL,PERSONAL,BUSINESS,OTHER};
//This array holds the corresponding string for the ct_type. It is defined externally in
//gim.c
extern char* type_array[];
//Used to tell the ct_add function where to add the new record
enum sort_type{SORT,LAST,FIRST};
/** Contact List Structure **/
typedef struct{
/* Name containers */
char* lname; //Filter && Sort
char* fname; //Filter && Sort
char* mname; //Sort
char* cname; //Filter && Sort
/* Phone number containers */
char* home; //Filter
char* work; //Filter
char* mobil; //Filter
char* fax; //Filter
char* other1;
char* other2;
/* Mail & Web containers */
char* email; //Filter
char* url; //Filter
/* Address containers */
char* address1; //Filter
char* address2; //Filter
char* city; //Filter && Sort
char* state; //Filter && Sort
char* zipcode;
char* country; //Filter && Sort
/* Miscellaneous containers */
char* notes;
ct_type type; //Filter && Sort
}contact;
//External variables used for setting the maximum size
//NOTE: These could probably be done as non externals, but would not be
//as easy to change for the User Interface program.
//NOTE: These variables MUST be defined by the database program.
extern int MAX_NAME;
extern int MAX_PHONE;
extern int MAX_WEB;
extern int MAX_ADDRESS;
extern int MAX_COUNTRY;
extern int MAX_ZIP;
extern int MAX_NOTES;
/** Contact Function Prototypes **/
/***************************************************************************/
/* ct_new */
/***************************************************************************/
/* This function must be called before using any of the contact functions */
/* This sets the maximum sizes (to defaults or passed values). It also */
/* initializes the data storage structures */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_new( int max_name=50, int max_phone=20, int max_web=50,
int max_address=50, int max_country=25, int max_zip=15,
int max_notes=500);
/***************************************************************************/
/* ct_delete */
/***************************************************************************/
/* This function must be called when closing a contact structure. It will */
/* release all current data as well as the data structures. If properly */
/* implemented/used, there should be no memory leaks. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success */
/***************************************************************************/
int ct_delete();
/***************************************************************************/
/* ct_malloc */
/***************************************************************************/
/* Allocates a full entry based upon maximum set values. This is a helper */
/* program for the GUI to call. The GUI program MUST define the following */
/* ct_new MUST be called before using this function! */
/***************************************************************************/
/* RETURNS: a pointer to the fully allocated entry. */
/***************************************************************************/
contact* ct_malloc();
/***************************************************************************/
/* ct_free */
/***************************************************************************/
/* This is the sister function to ct_malloc. To avoid memory leaks, it */
/* must be used/implemented */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_free(contact* entry);
/***************************************************************************/
/* ct_put */
/***************************************************************************/
/* This function places the data pointed to by the contact* entry into the */
/* database. This information MUST be copied into the structure and not */
/* just use a pointer to the passed structure. This assures seperation of */
/* the data from the client. */
/* The sort_type s should rarely (probably never) be used by the client. */
/* It is added to be called by ct_load as the data is already sorted and */
/* quite a bit of time is saved by just loading it at the end. The default*/
/* value is to insert as SORT. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_put(contact* entry,sort_type s=SORT);
/***************************************************************************/
/* ct_get */
/***************************************************************************/
/* This function returns a copy of the current contact data into the passed*/
/* structure. It does NOT pass the location of the data which is important*/
/* to keep the client shielded from the actual data. */
/* contact* entry MUST be allocated by a call to ct_malloc. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_get(contact* entry);
/***************************************************************************/
/* ct_mod */
/***************************************************************************/
/* This function places the information in the passed structure into the */
/* database at the current position. Again all data is copied into the */
/* structure to maintain seperation. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_mod(contact* entry);
/***************************************************************************/
/* ct_remove */
/***************************************************************************/
/* This function removes the current record. As with all the database */
/* functions there is absolutely no verification. The client program */
/* should do all verifications before calling the function. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_remove();
/***************************************************************************/
/* ct_load */
/***************************************************************************/
/* This function loads in a database based upon the name that is passed. */
/* The storage method can be implemented in any way as long as the data */
/* is retrieved and stored properly. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/* GE_FILENAME when the file can't be found. */
/* GE_INVALID when an invalid file is passed. */
/* GE_VERSION when the file version doesn't match the program */
/***************************************************************************/
int ct_load(char* name);
/***************************************************************************/
/* ct_load */
/***************************************************************************/
/* This function saves a database based upon the name that is passed. */
/* Again, the storage method can be implemented in any way. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/* GE_FILENAME when the file can't be found. */
/***************************************************************************/
int ct_save(char* name);
/***************************************************************************/
/* ct_home */
/***************************************************************************/
/* This function places the database at the first of the list. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_home();
/***************************************************************************/
/* ct_end */
/***************************************************************************/
/* This function places the database at the last of the list. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_end();
/***************************************************************************/
/* ct_next */
/***************************************************************************/
/* This function indexes forward in the list by "count" number of times. */
/* If no number is passed, the default is 1. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_next(int count=1);
/***************************************************************************/
/* ct_prev */
/***************************************************************************/
/* This function indexes backwards in the list by "count" number of times. */
/* If no number is passed, the default is 1. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_prev(int count=1);
/***************************************************************************/
/* ct_mark */
/***************************************************************************/
/* This function returns the address of the current position in the list. */
/* This function is used when the list needs to be parsed, but needs to */
/* return to the current position. */
/***************************************************************************/
/* RETURNS: The address (void*) of the current data location. */
/***************************************************************************/
void* ct_mark();
/***************************************************************************/
/* ct_goto */
/***************************************************************************/
/* This function places the database at the address passed. This is used */
/* in conjunction with ct_mark to be able to parse the list and return to */
/* the proper position. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_goto(void* location);
/***************************************************************************/
/* ct_is_empty */
/***************************************************************************/
/* This is a query function to determine if there is data in the list. If */
/* a filter is set, this function should act on the filter data. */
/***************************************************************************/
/* RETURNS: GE_OKAY on non-empty. */
/* GE_EMPTY on empty. */
/***************************************************************************/
int ct_is_empty();
/***************************************************************************/
/* ct_filter */
/***************************************************************************/
/* This will set a filter on the data based upon the passed structure. The*/
/* filter structure will contain filter strings for each entry based upon: */
/* Empty: No filter (any data matches - similar to '*' */
/* *: Wildcard indicating 0 to many charecters. */
/* ?: Wildcard indicating exactly one charecter. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_filter(contact* filter);
/***************************************************************************/
/* ct_filter_clear */
/***************************************************************************/
/* Clears any set filters so that all data is used. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_filter_clear();
/***************************************************************************/
/* ct_sort_malloc */
/***************************************************************************/
/* This is a special function that will allocate the memory needed for a */
/* sort structure, which is much less than a standard structure. */
/***************************************************************************/
/* RETURNS: the newly allocated sort structure. */
/***************************************************************************/
contact* ct_sort_malloc();
/***************************************************************************/
/* ct_sort_free */
/***************************************************************************/
/* This is the sister function to ct_sort_malloc and must be called to */
/* release resources when done with the sort structure. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_sort_free(contact* entry);
/***************************************************************************/
/* ct_sort */
/***************************************************************************/
/* This applies the sort to all data based upon the passes sort structure. */
/* The sort is done based upon a 3-byte string defined as follows: */
/* Byte 0: The order this particular field is applied (starting at 1) */
/* Byte 1: The sort type (currently ASCENDING or DESCENDING) */
/* Byte 2: Null-terminator. */
/* If the field is not used in a sort then Byte 0 should be set to NULL */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_sort(contact* new_sort);
/***************************************************************************/
/* ct_sort_get */
/***************************************************************************/
/* Copies the private sort method into the passed sort structure. The */
/* structure must be properly allocated through a call to ct_sort_malloc. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_sort_get(contact* temp_sort);
/***************************************************************************/
/* ct_sort_default */
/***************************************************************************/
/* Copies the default sort scheme to the passed sort structure. The */
/* structure must be properly allocated through a call to ct_sort_malloc. */
/* Note that this function does NOT call ct_sort it simply returns the */
/* the default sort definition in a structure. A subsequent call to */
/* ct_sort would apply this sort. Also, the default sort is defined by the*/
/* data implementation and there are no specific rules for what it is. */
/***************************************************************************/
/* RETURNS: GE_OKAY on success. */
/***************************************************************************/
int ct_sort_default(contact* new_sort);
#endif
gim.c
/* The error array gives strings for return value */
char* gid_error[]=
{
"Okay",
"Could not connect to database.",
"Invalid username/password combination",
"General data error",
"Invalid filename",
"Memory Allocation Error",
"Memory Free Error",
"List is Empty",
"Invalid Data File",
"Incorrect Version"
};
/* They type array gives strings for the corresponding ct_type */
char* type_array[]={
"ALL",
"PERSONAL",
"BUSINESS",
"OTHER"
};