⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 db_cls.cpp

📁 HP公司的SNMP++的Win32版本源码
💻 CPP
字号:
/*============================================================================
  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;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -