BitSet.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2003  The Pentagram Team
00003 
00004 This program is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU General Public License
00006 as published by the Free Software Foundation; either version 2
00007 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 */
00018 
00019 #include "pent_include.h"
00020 #include "BitSet.h"
00021 
00022 #include "IDataSource.h"
00023 #include "ODataSource.h"
00024 
00025 BitSet::BitSet() : size(0), bytes(0), data(0)
00026 {
00027 
00028 }
00029 
00030 
00031 BitSet::BitSet(unsigned int size_)
00032 {
00033         data = 0;
00034         setSize(size_);
00035 }
00036 
00037 BitSet::~BitSet()
00038 {
00039         delete[] data;
00040 }
00041 
00042 void BitSet::setSize(unsigned int size_)
00043 {
00044         if (data) delete[] data;
00045 
00046         size = size_;
00047         bytes = 0;
00048         bytes = size / 8;
00049         if (size % 8 != 0) bytes++;
00050 
00051         data = new uint8[bytes];
00052         for (unsigned int i = 0; i < bytes; ++i)
00053                 data[i] = 0;
00054 }
00055 
00056 uint32 BitSet::getBits(unsigned int pos, unsigned int n)
00057 {
00058         assert(n <= 32);
00059         assert(pos + n <= size);
00060         if (n == 0) return 0;
00061 
00062         unsigned int firstbyte = pos / 8;
00063         unsigned int lastbyte = (pos + n - 1) / 8;
00064 
00065         if (firstbyte == lastbyte) {
00066                 return ((data[firstbyte] >> (pos % 8)) & ((1 << n) - 1));
00067         }
00068 
00069         unsigned int firstbits = 8 - (pos % 8);
00070         unsigned int lastbits = ((pos + n - 1) % 8) + 1;
00071 
00072         unsigned int firstmask = ((1 << firstbits) - 1) << (8 - firstbits);
00073         unsigned int lastmask = ((1 << lastbits) - 1);
00074 
00075         uint32 ret = 0;
00076 
00077         ret |= (data[firstbyte] & firstmask) >> (8 - firstbits);
00078         unsigned int shift = firstbits;
00079         for (unsigned int i = firstbyte + 1; i < lastbyte; ++i) {
00080                 ret |= (data[i] << shift);
00081                 shift += 8;
00082         }
00083         ret |= (data[lastbyte] & lastmask) << shift;
00084 
00085         return ret;
00086 }
00087 
00088 void BitSet::setBits(unsigned int pos, unsigned int n, uint32 bits)
00089 {
00090         assert(n <= 32);
00091         assert(pos + n <= size);
00092         if (n == 0) return;
00093 
00094         unsigned int firstbyte = pos / 8;
00095         unsigned int lastbyte = (pos + n - 1) / 8;
00096 
00097         if (firstbyte == lastbyte) {
00098                 data[firstbyte] &= ~(((1 << n) - 1) << (pos % 8));
00099                 data[firstbyte] |= (bits & ((1 << n) - 1)) << (pos % 8);
00100                 return;
00101         }
00102 
00103         unsigned int firstbits = 8 - (pos % 8);
00104         unsigned int lastbits = ((pos + n - 1) % 8) + 1;
00105 
00106         unsigned int firstmask = ((1 << firstbits) - 1) << (8 - firstbits);
00107         unsigned int lastmask = ((1 << lastbits) - 1);
00108 
00109         data[firstbyte] &= ~firstmask;
00110         data[firstbyte] |= (bits << (8 - firstbits)) & firstmask;
00111         unsigned int shift = firstbits;
00112         for (unsigned int i = firstbyte + 1; i < lastbyte; ++i) {
00113                 data[i] = (bits >> shift);
00114                 shift += 8;
00115         }
00116         data[lastbyte] &= ~lastmask;
00117         data[lastbyte] |= (bits >> shift) & lastmask;
00118 }
00119 
00120 void BitSet::save(ODataSource* ods)
00121 {
00122         ods->write4(size);
00123         ods->write(data, bytes);
00124 }
00125 
00126 bool BitSet::load(IDataSource* ids, uint32 version)
00127 {
00128         uint32 s = ids->read4();
00129         setSize(s);
00130         ids->read(data, bytes);
00131 
00132         return true;
00133 }

Generated on Fri Jul 27 22:27:10 2007 for pentagram by  doxygen 1.4.7