/
ScryMUD/mud/
ScryMUD/mud/grrmud/Boards/
ScryMUD/mud/grrmud/Help/
ScryMUD/mud/grrmud/Pfiles/
ScryMUD/mud/grrmud/PlayerSacks/
ScryMUD/mud/grrmud/PlayerShops/
ScryMUD/mud/grrmud/help_filter/
ScryMUD/mud/hegemon/
ScryMUD/mud/hegemon/data/
ScryMUD/mud/hegemon/data/help/battle/
ScryMUD/mud/hegemon/data/help/client/
ScryMUD/mud/hegemon/data/help/communications/
ScryMUD/mud/hegemon/data/help/skills/
ScryMUD/mud/hegemon/data/help/spells/
ScryMUD/mud/include/
ScryMUD/mud/lib/
ScryMUD/mud/lib/bitfield/
ScryMUD/mud/lib/log/
ScryMUD/mud/lib/string2/
// $Id: bitfield.cc,v 1.6 1999/07/23 02:54:29 greear Exp $
// $Revision: 1.6 $  $Author: greear $ $Date: 1999/07/23 02:54:29 $

//
//ScryMUD Server Code
//Copyright (C) 1998  Ben Greear
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// To contact the Author, Ben Greear:  greear@cyberhighway.net, (preferred)
//                                     greearb@agcs.com
//

///*******************  bitfield.cc  *************************///
/* nice general bitfield class, it expands as needed, so would
    not be good for something like Operating Systems w/out 
    modification */

#include "bitfield.h"
#include <iostream.h>


static const short int_len = 8 * sizeof(unsigned short int);
ofstream bitlog("./log/bitlog");
extern int core_dump(const char* msg); //misc2.cc

//static
int BitfieldNames::_cnt = 0;


/** Constructor. */
BitfieldNames::BitfieldNames(int length, const char** names,
                             const char* col_name)
      : len(length), bit_names(names), header(col_name) {
   bitlog << "BitfieldNames Constructor, length: " << length
          << " collection name -:" << col_name << ":-" << endl;
   _cnt++;
}

void BitfieldNames::listNames(String& buf) const {
   String tmp(100);

   buf = header;
   buf += " (DEFINED)\n\t";
   int sofar = 0;

   for (int i = 0; i<len; i++) {
      Sprintf(tmp, "[%i] %s, ", i, bit_names[i]);
      if ((sofar + tmp.Strlen()) > 80) {
         buf += "\n\t";
         sofar = tmp.Strlen();
      }
      else {
         sofar += tmp.Strlen();
      }
      buf += tmp;
   }
   buf += "\n";
}

const char* BitfieldNames::getName(int idx) const {
   if ((idx >= 0) && (idx < len)) {
      return bit_names[idx];
   }
   else {
      return "OUT_OF_RANGE";
   }
}



/** Returns -1 if no more. */
int bitfield::nextSet(int from_this) const {
   int mx = max_bit();
   for (int i = from_this + 1; i<mx; i++) {
      if (get(i)) {
         return i;
      }
   }//for
   return -1;
}//nextSet
 
/** Returns -1 if no more. */
int bitfield::lastSet() const {
   for (int i = max_bit(); i>= 0; i--) {
      if (get(i)) {
         return i;
      }//if
   }//for
   return -1;
}

/** Returns -1 if no more. */
int bitfield::firstSet() const {
   int mx = max_bit();
   for (int i = 0; i<mx; i++) {
      if (get(i)) {
         return i;
      }
   }//for
   return -1;
}


int bitfield::firstClear() const {
   int mx = MAX_BIT_ALLOWED;
   for (int i = 0; i<mx; i++) {
      if (!get(i)) {
         return i;
      }
   }//for
   return -1;
}



int bitfield::Assert(int boolean_val, const char* msg) {
   if (!boolean_val) {
      core_dump(msg);
   }
   return TRUE;
}

void bitfield::Clear() {
   off_all();
}//Clear()


int figure_len(int max_flag) {
   return max_flag/int_len + 1;
}


int bitfield::max_bit() const {
   return ((vect_len * int_len) - 1);
}//max_bit


int bitfield::Read(ifstream& ifile) {
   int flag;
   char buf[81];

   Clear();
   ifile >> flag;

   if (!ifile) {
      return -1;
   }

   while (flag != -1) {
      turn_on(flag);
      ifile >> flag;
      
      if (!ifile) {
         return -1;
      }
   }//while
   ifile.getline(buf,80);  //read rest of line
   return 0;
}//Read


void bitfield::Write(ofstream& ofile) const {
   for (int i = max_bit(); i >= 0; i--) {
      if (get(i)) {
         ofile << i << " ";
      }//if
   }//for
   ofile << -1 << "  -:| bitfield |:-\n";
}//Write


void bitfield::print() const {
   String buf(max_bit() + 2);
   for (int i = 0; i < max_bit(); i++) {
      if (this->get(i))
         buf.Prepend("1");
      else
         buf.Prepend("0");
   }//for
   cout << buf << endl;
}//print()


void bitfield::set(int i_th, int val) {
   if (val)
      turn_on(i_th);
   else
      turn_off(i_th);
}

void bitfield::ensureCapacity(int bit_posn) {
   //first, check for bogus values
   Assert((bit_posn <= MAX_BIT_ALLOWED), "ensureCapacity, out of range");
   
   if (bit_posn > max_bit()) {
      bitfield tmp(*this);
      delete[] vector;
      vect_len = figure_len(bit_posn);
      vector = new unsigned short[vect_len];
      *this = tmp;
   }
}//ensureCapacity

void bitfield::flip(int bit_posn) {
   ensureCapacity(bit_posn);
   if (get(bit_posn)) {
      flags_on--;
   }
   else {
      flags_on++;
   }
   vector[(bit_posn / int_len)] ^=
         (1 << (bit_posn % int_len));
}//flip()


void bitfield::init(int num_bits) {
   ensureCapacity(num_bits);
   off_all();
}//init()


void bitfield::turn_on(int bit_posn) {
   ensureCapacity(bit_posn);
   if (!get(bit_posn)) {
      flags_on--;
   }
   vector[(bit_posn / int_len)] |=
         (1 << (bit_posn % int_len));
}//on()

void bitfield::turn_off(int bit_posn) {
   if (get(bit_posn)) {
      flags_on--;
   }
   if ((bit_posn <= max_bit()) && (bit_posn >= 0)) {
      vector[(bit_posn / int_len)] &=
         ~(1 << (bit_posn % int_len));
   }//if
}//off()


void bitfield::flip_all() {
   for (int i = 0; i<vect_len; i++) {
      vector[i] = ~vector[i];
   }//for

   //TODO:  Verify this some day!!
   flags_on = max_bit() - flags_on + 1; // +1 because flags_on is ones based.
}//flip_all()


void bitfield::on_all() {
   flags_on = max_bit() + 1;
   for (int i = 0; i<vect_len; i++) {
      vector[i] = ~(0);
   }//for
}//on_all;


void bitfield::off_all() {
   flags_on = 0;
   for (int i = 0; i<vect_len; i++) {
      vector[i] = 0;
   }//for
}//off_all


int bitfield::get(int bit_posn) const {
   if ((bit_posn > max_bit()) || (bit_posn < 0)) {
      return FALSE;
   }//if
   if (vector[(bit_posn / int_len)] &
          (1 << (bit_posn % int_len)))
      return TRUE;
   else
      return FALSE;
}// get()


bitfield::bitfield() : flags_on(0) {  //default constructor
   vector = new unsigned short int[1];
   vector[0] = 0;
   vect_len = 1;
}//default constructor


bitfield::bitfield(int bit_count) : flags_on(0) {
   vect_len = figure_len(bit_count);
   vector = new unsigned short int[vect_len];
   for (int i = 0; i<vect_len; i++) {
      vector[i] = 0;
   }//for
}//constructor


bitfield::bitfield(const bitfield& b) {
   vector = new unsigned short int[b.vect_len];
   vect_len = b.vect_len;
   flags_on = b.flags_on;
   for (int i = 0; i<vect_len; i++) {
      vector[i] = b.vector[i];
   }//for
}//copy constructor



bitfield::~bitfield() {
   delete[] vector;
   vector = NULL;
}//destructor


void bitfield::operator= (const bitfield& b) {
   if (b.vect_len > vect_len) {
      delete[] vector;
      vector = new unsigned short int[b.vect_len];
      vect_len = b.vect_len;
   }//if

   off_all();  //zero it out..
   for (int i = 0; i < b.vect_len; i++) {
      vector[i] = b.vector[i];
   }//for
   flags_on = b.flags_on;
}//operator=


int bitfield::operator== (const bitfield& b) const {
   int min = b.vect_len;
   if (vect_len < b.vect_len)
      min = vect_len; 

   for (int i = 0; i<min; i++) {
      if (vector[i] != b.vector[i]) 
         return FALSE;
   }//for
   return TRUE;
}//operator==


int bitfield::operator!= (const bitfield& b) const {
   return (!(*this == b));
}//operator!=


int bitfield::is_zero() const {
   for (int i = 0; i<vect_len; i++) {
      if (vector[i] != 0)
         return FALSE;
   }//for
   return TRUE;
}//is_zero