Drizzled Public API Documentation

bitfield.py
00001 #!/usr/bin/env python
00002 #
00003 # Drizzle Client & Protocol Library
00004 # 
00005 # Copyright (C) 2008 Eric Day (eday@oddments.org)
00006 # All rights reserved.
00007 #
00008 # Redistribution and use in source and binary forms, with or without
00009 # modification, are permitted provided that the following conditions are
00010 # met:
00011 #
00012 #     * Redistributions of source code must retain the above copyright
00013 # notice, this list of conditions and the following disclaimer.
00014 #
00015 #     * Redistributions in binary form must reproduce the above
00016 # copyright notice, this list of conditions and the following disclaimer
00017 # in the documentation and/or other materials provided with the
00018 # distribution.
00019 #
00020 #     * The names of its contributors may not be used to endorse or
00021 # promote products derived from this software without specific prior
00022 # written permission.
00023 #
00024 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00027 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035 #
00036 
00037 import unittest
00038 
00039 class BitField(object):
00040   '''Base class for managing bitfields.'''
00041 
00042   _fields = []
00043 
00044   def __init__(self, value=0):
00045     self._value = value
00046 
00047   def __getattr__(self, name):
00048     try:
00049       if name.isupper():
00050         return 1 << self._fields.index(name)
00051       elif name.islower():
00052         return self._value & (1 << self._fields.index(name.upper())) != 0
00053       raise Exception()
00054     except Exception:
00055       raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
00056 
00057   def __setattr__(self, name, value):
00058     try:
00059       if name[0] == '_':
00060         self.__dict__[name] = value
00061       else:
00062         if name.islower():
00063           if value:
00064             self._value |= (1 << self._fields.index(name.upper()))
00065           else:
00066             self._value &= ~(1 << self._fields.index(name.upper()))
00067         else:
00068           raise Exception()
00069     except Exception:
00070       raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
00071 
00072   def __str__(self):
00073     return str([(self._fields[x], 1 << x) for x in range(0, len(self._fields)) if (1 << x) & self._value])
00074 
00075   def value(self):
00076     return self._value
00077 
00078 class ExampleField(BitField):
00079   _fields = [
00080     'READ',
00081     'WRITE',
00082     'CREATE',
00083     'DIRECT'
00084   ]
00085 
00086 class TestField(unittest.TestCase):
00087 
00088   def testDefaultInit(self):
00089     f = ExampleField()
00090     self.assertEqual(f.value(), 0)
00091 
00092   def testDataInit(self):
00093     f = ExampleField(15)
00094     self.assertEqual(f.value(), 15)
00095 
00096   def testGetAttr(self):
00097     f = ExampleField(1)
00098     self.assertEqual(f.read, True)
00099     self.assertEqual(f.READ, 1)
00100     self.assertEqual(f.write, False)
00101     self.assertEqual(f.WRITE, 2)
00102 
00103   def testBadGetAttr(self):
00104     f = ExampleField()
00105     self.assertRaises(AttributeError, getattr, f, 'BAD')
00106     self.assertRaises(AttributeError, getattr, f, 'bad')
00107     self.assertRaises(AttributeError, getattr, f, 'Read')
00108 
00109   def testSetAttr(self):
00110     f = ExampleField()
00111     self.assertEqual(f.read, False)
00112     self.assertEqual(f.write, False)
00113     f.read = True
00114     self.assertEqual(f.read, True)
00115     self.assertEqual(f.write, False)
00116 
00117   def testBadSetAttr(self):
00118     f = ExampleField()
00119     self.assertRaises(AttributeError, setattr, f, 'BAD', 0)
00120     self.assertRaises(AttributeError, setattr, f, 'bad', 0)
00121     self.assertRaises(AttributeError, setattr, f, 'Read', 0)
00122     self.assertRaises(AttributeError, setattr, f, 'READ', 0)
00123 
00124 if __name__ == '__main__':
00125   unittest.main()