// $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