db_cls.cpp
资源名称:hp_snmp3.zip [点击查看]
上传用户:czjinwang
上传日期:2007-01-12
资源大小:2484k
文件大小:14k
源码类别:
SNMP编程
开发平台:
Visual C++
- /*============================================================================
- Copyright (c) 1996
- Hewlett-Packard Company
- ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
- Permission to use, copy, modify, distribute and/or sell this software
- and/or its documentation is hereby granted without fee. User agrees
- to display the above copyright notice and this license notice in all
- copies of the software and any documentation of the software. User
- agrees to assume all liability for the use of the software; Hewlett-Packard
- makes no representations about the suitability of this software for any
- purpose. It is provided "AS-IS without warranty of any kind,either express
- or implied. User hereby grants a royalty-free license to any and all
- derivatives based upon this software code base.
- =============================================================================*/
- //============================================================================
- // D B _ C L S . C P P
- //
- // Generic Database Class implementation file
- //
- //
- // Changes:
- //
- //============================================================================
- #include <stdio.h>
- #include <stdlib.h>
- #include <iostream.h>
- #include <io.h>
- #include <sys/locking.h>
- #include <time.h>
- #include <share.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include "db_cls.h"
- #define BUFFSIZE 4096
- // return current time in seconds
- int Db::check_current_time()
- {
- time_t long_time; // time as a long integer
- struct tm *current_time;
- time(&long_time); // get time
- current_time = localtime(&long_time); // convert to local time
- return ( current_time->tm_min * 60 + current_time->tm_sec);
- }
- int Db::frag_check()
- {
- int infile;
- ldiv_t ldivstruct;
- long int filesize, structsize;
- if((infile = open(db_name, O_RDONLY|O_BINARY)) == -1)
- {
- return DB_FILE_NOT_FOUND;
- }
- filesize = filelength(infile);
- structsize = rec_size;
- ldivstruct = ldiv((long int) filesize, (long int) structsize);
- if (ldivstruct.rem != 0)
- {
- close(infile);
- return DB_FRAG_ERROR;
- }
- else
- close(infile);
- return DB_OK;
- }
- // Db class semaphore wait
- FILE* Db::wait ( const char *mode, int shflag)
- {
- FILE * tmp_file;
- int end_time;
- if (frag_check() == DB_OK)
- {
- if ((tmp_file = _fsopen(db_name, mode, shflag)) == NULL)
- {
- end_time = check_current_time() + DB_TIMEOUT;
- do {
- if ( check_current_time() <= end_time) // check timeout
- cerr << "."; // waiting sign
- else
- return tmp_file;
- } while ((tmp_file = _fsopen(db_name, mode, shflag)) == NULL);
- cerr << endl;
- }
- }
- return tmp_file;
- };
- int Db::set_attributtes( const char *name, const long record_size)
- {
- int infile;
- long int filesize,structsize;
- ldiv_t ldivstruct;
- strcpy(db_name,name); // set the name
- rec_size = record_size;
- // frag check
- infile = open(db_name, O_RDONLY|O_BINARY);
- if (infile==-1)
- {
- current_number_of_records = 0;
- return DB_FILE_NOT_FOUND; // file does not exist
- }
- // get num recs and check for frag
- filesize = filelength(infile);
- structsize = rec_size;
- ldivstruct = ldiv((long int) filesize,(long int) structsize);
- if (ldivstruct.rem !=0)
- {
- close(infile);
- current_number_of_records = 0;
- return DB_FRAG_ERROR; // file fragmented error
- }
- current_number_of_records = (long int) ldivstruct.quot;
- close(infile);
- return DB_OK;
- };
- // perform a binary search
- int Db::binary_search(FILE * binary_search_file, // binary search file stream
- void *data, // record matched
- long int *location) // spot where found
- {
- long int look;
- int result;
- char *read_rec,*db_rec;
- Key key,mkey;
- int found = FALSE;
- long int min,max;
- read_rec = new char[(int)rec_size];
- db_rec = new char[(int)rec_size];
- memcpy(db_rec,data,(int)rec_size);
- min = 1;
- max = current_number_of_records;
- // search_file = fopen(db_name,"rb");
- if ( binary_search_file == NULL)
- return DB_OPEN_ERROR; // open error
- while ((max >=min)&&(!found))
- {
- look = min + (long int)((max-min) / 2 + 0.5);
- fseek(binary_search_file,((look-1) * rec_size), SEEK_SET);
- fread(read_rec,(int)rec_size,1,binary_search_file);
- memcpy(key,read_rec,sizeof(Key));
- memcpy(mkey,db_rec,sizeof(Key));
- result = strcmp(mkey,key);
- if (result ==0) // found !!!
- {
- memcpy(db_rec,read_rec,(int)rec_size);
- memcpy(data,db_rec,(int)rec_size);
- *location = look;
- found = TRUE;
- }
- else if (result < 0)
- max = look-1; // look in bottom half
- else
- min = look+1; // look in top half
- }
- delete read_rec;
- delete db_rec;
- if ( found)
- return DB_OK;
- else
- {
- *location = look;
- return DB_REC_NOT_FOUND;
- }
- }
- // write a record to a database
- int Db::write(const void *data)
- {
- FILE *outfile,*tmp_file;
- int result;
- long int spot;
- unsigned char *write_rec, *db_rec;
- Key wkey,ckey;
- size_t status;
- write_rec = new unsigned char[(int)rec_size];
- db_rec = new unsigned char[(int)rec_size];
- memcpy(db_rec,data,(size_t)rec_size);
- if ( access(db_name,0) != 0)
- { // file does not exist, create it and write
- outfile = fopen(db_name,"wb+");
- status = fwrite(db_rec,(size_t)rec_size,1,outfile);
- current_number_of_records++;
- fclose(outfile);
- }
- else
- {
- if ((outfile = wait("rb+", SH_DENYWR)) == NULL)
- return FILE_LOCKED;
- result = binary_search( outfile,db_rec, &spot); // binary search
- if ( result == 0)
- { // found a match
- fseek( outfile, (spot-1) * rec_size,SEEK_SET);
- status = fwrite( data,(size_t)rec_size,1,outfile);
- fclose( outfile);
- }
- else
- {
- if ( spot > current_number_of_records-1) spot--;
- fseek(outfile, (spot * rec_size) ,SEEK_SET);
- memcpy(write_rec,db_rec,(int)rec_size); // save to write_rec
- fread(db_rec,(int)rec_size,1,outfile); // read in spot
- memcpy(wkey,write_rec, sizeof(Key));
- memcpy(ckey,db_rec, sizeof(Key));
- result = strcmp(wkey,ckey);
- while (( result < 0)&& ( spot >=0))
- {
- fseek(outfile,spot * rec_size,SEEK_SET);
- fread(db_rec,(int)rec_size,1,outfile); // read in spot
- memcpy(ckey,db_rec, sizeof(Key));
- result = strcmp(wkey,ckey);
- if (result < 0) spot--;
- }
- tmp_file = fopen("TEMP.$$$","wb"); // open TEMP file
- // write to end of file
- if (( result > 0) && ((spot+1) == current_number_of_records))
- {
- fseek(outfile,0,SEEK_SET);
- append_recs(outfile,
- tmp_file,
- 0,
- spot,
- rec_size);
- fwrite(write_rec,(int)rec_size,1,tmp_file);
- }
- else
- // add to front of database file
- if ((result < 0)&&((spot-1) <= 0))
- {
- fseek(outfile,0,SEEK_SET);
- fwrite(write_rec,(int)rec_size,1,tmp_file);
- append_recs(outfile,
- tmp_file,
- 0,
- current_number_of_records-1,
- rec_size);
- }
- else // insert in the middle
- {
- fseek(outfile,0,SEEK_SET);
- append_recs(outfile,
- tmp_file,
- 0,
- spot,
- rec_size);
- fwrite(write_rec,(int)rec_size,1,tmp_file);
- append_recs( outfile,
- tmp_file,
- spot+1,
- current_number_of_records-1,
- rec_size);
- }
- current_number_of_records++;
- fclose(tmp_file);
- fclose(outfile);
- remove(db_name);
- rename("TEMP.$$$",db_name);
- }
- }
- delete [] write_rec;
- delete [] db_rec;
- return DB_OK;
- }
- // append records to a file
- int Db::append_recs( FILE *from, // copy from this file
- FILE *to, // to this file
- long int start, // from this record #
- long int stop, // to this record #
- long int recsize) // size of record
- {
- char *buffer;
- long int num_bytes;
- long int write_size;
- if ( start > stop)
- return DB_OK;
- buffer = new char[BUFFSIZE];
- fseek(from,0,SEEK_SET);
- fseek(from,(long int)(start*recsize),SEEK_SET);
- num_bytes = (stop - start + 1) * recsize;while ( num_bytes > 0)
- {
- if ( num_bytes > BUFFSIZE)
- {
- num_bytes -= BUFFSIZE;
- write_size = BUFFSIZE;
- }
- else
- {
- write_size = num_bytes;
- num_bytes = 0;
- }
- fread(buffer,(int)write_size,1,from);
- fwrite(buffer,(int)write_size,1,to);
- }
- delete buffer;
- return DB_OK;
- };
- // get a record from the DB @ spot
- int Db::retrieve( const long location, void *data)
- {
- FILE *readfile;
- if ( *db_name ==0)
- return DB_NO_NAME;
- if ((readfile = wait("rb", SH_DENYWR)) == NULL)
- return FILE_LOCKED;
- fseek(readfile,(location * rec_size),SEEK_SET);
- fread(data,(int)rec_size,1,readfile);
- fclose(readfile);
- return DB_OK;
- };
- // read a record from the database
- int Db::read ( void *data)
- {
- long int spot;
- int result;
- FILE * readfile;
- if ( *db_name == 0)
- return DB_NO_NAME;
- // do the binary search
- if ((readfile = wait("rb", SH_DENYWR)) == NULL)
- return FILE_LOCKED;
- result = binary_search(readfile, data, &spot); // binary search
- fclose (readfile);
- return ( result);
- }
- // delete a record from the database
- int Db::del( const Key key)
- {
- FILE *search_file;
- FILE *tmp_file;
- int found;
- unsigned char *data;
- long int spot;
- if ( *db_name == 0)
- return DB_NO_NAME;
- if ((search_file = wait("rb+", SH_DENYRW)) == NULL)
- return FILE_LOCKED;
- data = new unsigned char[(int)rec_size];
- memcpy(data,key,sizeof(Key));
- found = binary_search(search_file, data, &spot);
- if ( found == 0) // found a match
- {
- // remove the record
- tmp_file = fopen("TEMP.$$$","wb");
- fseek(search_file,0,SEEK_SET);
- // copy everything up to the s1>s2
- append_recs( search_file,
- tmp_file,
- 0,
- spot-2,
- rec_size);
- append_recs( search_file,
- tmp_file,
- spot,
- current_number_of_records-1,
- rec_size);
- fclose(tmp_file);
- fclose(search_file);
- remove(db_name);
- rename("TEMP.$$$",db_name);
- current_number_of_records--;
- }
- else // not found
- fclose(search_file);
- if ( current_number_of_records ==0)
- remove(db_name);
- delete data;
- return (found);
- }
- // delete the database
- int Db::delete_db()
- {
- FILE * outfile;
- if ((outfile = wait("wb", SH_DENYRW)) == NULL) // deny sharing read & write
- return FILE_LOCKED;
- if (*db_name != 0)
- remove(db_name);
- else
- return DB_NO_NAME;
- // delete database file
- strcpy(db_name,"");
- current_number_of_records = 0;
- fclose(outfile);
- return DB_OK;
- }
- // compare pattern to some string
- int Db::wild_card_compare( const char *pattern,
- const char *str)
- {
- char temp[80];
- char *tmp;
- strcpy(temp,str);
- tmp = temp;
- *(tmp+strlen(pattern)) = 0;
- if ( strcmp(pattern,tmp) == 0)
- return WC_MATCH;
- else
- return WC_NO_MATCH;
- };
- // generate a list of keys based on some pattern
- int Db::pattern(const char *pattern, Key **keys, int *keycount)
- {
- long int z;
- FILE *readfile;
- char *data;
- *keys = (Key *) new char[(int)(current_number_of_records * sizeof(Key))];
- *keycount = 0;
- if ( *keys == 0)
- return DB_KEY_NEW;
- if ( *db_name == 0)
- return DB_NO_NAME; // no name
- if ((readfile = wait("rb", SH_DENYWR)) == NULL) // deny share writing
- return FILE_LOCKED;
- fseek(readfile,0,SEEK_SET);
- data = new char[sizeof(Key)];
- for (z=0; z<=(current_number_of_records-1); z++)
- {
- fseek(readfile,(z*rec_size),SEEK_SET);
- fread(data,sizeof(Key),1,readfile);
- if ( wild_card_compare(pattern,data) == WC_MATCH)
- {
- strcpy((*keys)[*keycount],data);
- (*keycount)++;
- }
- }
- fclose(readfile);
- delete data;
- return DB_OK;
- }