1  """Routines for saving, retrieving, and creating fields""" 
  2   
  3  import struct 
  4  from decimal import Decimal 
  5  from dbf.exceptions import DbfError, DataOverflow 
  6  from dbf.dates import Date, DateTime, Time 
  7   
  8   
  9   
 10  VFPTIME = 1721425 
 11   
 13          "Returns a two-bye integer from the value, or raises DbfError" 
 14           
 15          if value > 65535: 
 16              raise DateOverflow("Maximum Integer size exceeded.  Possible: 65535.  Attempted: %d" % value) 
 17          if bigendian: 
 18              return struct.pack('>H', value) 
 19          else: 
 20              return struct.pack('<H', value) 
  22          "Returns a four-bye integer from the value, or raises DbfError" 
 23           
 24          if value > 4294967295: 
 25              raise DateOverflow("Maximum Integer size exceeded.  Possible: 4294967295.  Attempted: %d" % value) 
 26          if bigendian: 
 27              return struct.pack('>L', value) 
 28          else: 
 29              return struct.pack('<L', value) 
  31          "Returns a group of three bytes, in integer form, of the date" 
 32          return "%c%c%c" % (date.year-1900, date.month, date.day) 
  34          "Returns an 11 byte, upper-cased, null padded string suitable for field names; raises DbfError if the string is bigger than 10 bytes" 
 35          if len(string) > 10: 
 36              raise DbfError("Maximum string size is ten characters -- %s has %d characters" % (string, len(string))) 
 37          return struct.pack('11s', string.upper())        
  39          "Returns the value in the two-byte integer passed in" 
 40          if bigendian: 
 41              return struct.unpack('>H', bytes)[0] 
 42          else: 
 43              return struct.unpack('<H', bytes)[0] 
  45          "Returns the value in the four-byte integer passed in" 
 46          if bigendian: 
 47              return int(struct.unpack('>L', bytes)[0]) 
 48          else: 
 49              return int(struct.unpack('<L', bytes)[0]) 
  51          "Returns a Date() of the packed three-byte date passed in" 
 52          year, month, day = struct.unpack('<BBB', bytestr) 
 53          year += 1900 
 54          return Date(year, month, day) 
  56          "Returns a normal, lower-cased string from a null-padded byte string" 
 57          return struct.unpack('%ds' % len(chars), chars)[0].replace('\x00','').lower() 
  59      """Returns boolean true or false; normal rules apply to non-string values; string values 
 60      must be 'y','t', 'yes', or 'true' (case insensitive) to be True""" 
 61      if type(value) == str: 
 62          return bool(value.lower() in ['t', 'y', 'true', 'yes']) 
 63      else: 
 64          return bool(value) 
  66      "called if a data type is not supported for that style of table" 
 67      raise DbfError('field type is not supported.') 
  69      "Returns the string in bytes with trailing white space removed" 
 70      return bytes.tostring().rstrip() 
  72      "returns the string, truncating if string is longer than it's field" 
 73      if type(string) != str: 
 74          raise DbfError("incompatible type: %s" % type(string)) 
 75      return string.rstrip() 
  77      value = struct.unpack('<q', bytes)[0] 
 78      return Decimal("%de-4" % value) 
  80      currency = int(value * 10000) 
 81      if not -9223372036854775808 < currency < 9223372036854775808: 
 82          raise DataOverflow("value %s is out of bounds" % value) 
 83      return struct.pack('<q', currency) 
  85      "Returns the ascii coded date as a Date object" 
 86      return Date.fromymd(bytes.tostring()) 
  88      "returns the Date or datetime.date object ascii-encoded (yyyymmdd)" 
 89      if moment: 
 90          return "%04d%02d%02d" % moment.timetuple()[:3] 
 91      return '        ' 
  93      return struct.unpack('<d', bytes)[0] 
  95      if not (type(value) in (int, long, float)): 
 96          raise DbfError("incompatible type: %s" % type(value)) 
 97      return struct.pack('<d', value) 
  99      "Returns the binary number stored in bytes in little-endian format" 
100      return struct.unpack('<i', bytes)[0] 
 102      "returns value in little-endian binary format" 
103      if not (type(value) in (int, long)): 
104          raise DbfError("incompatible type: %s" % type(value)) 
105      if not -2147483648 < value < 2147483647: 
106          raise DataOverflow("Integer size exceeded.  Possible: -2,147,483,648..+2,147,483,647.  Attempted: %d" % value) 
107      return struct.pack('<i', value) 
 109      "Returns True if bytes is 't', 'T', 'y', or 'Y', None if '?', and False otherwise" 
110      bytes = bytes.tostring() 
111      if bytes == '?': 
112          return None 
113      return bytes in ['t','T','y','Y'] 
 115      "Returs 'T' if logical is True, 'F' otherwise" 
116      if type(logical) != bool: 
117          logical = convertToBool(logical) 
118      if type(logical) <> bool: 
119          raise DbfError('Value %s is not logical.' % logical) 
120      return logical and 'T' or 'F' 
 122      "Returns the block of data from a memo file" 
123      stringval = bytes.tostring() 
124      if stringval.strip(): 
125          block = int(stringval.strip()) 
126      else: 
127          block = 0 
128      return memo.get_memo(block, fielddef) 
 130      "Writes string as a memo, returns the block number it was saved into" 
131      block = memo.put_memo(string) 
132      if block == 0: 
133          block = '' 
134      return "%*s" % (fielddef['length'], block) 
 136      "Returns the number stored in bytes as integer if field spec for decimals is 0, float otherwise" 
137      string = bytes.tostring() 
138      if string[0:1] == '*':   
139          return None 
140      if not string.strip(): 
141          string = '0' 
142      if fielddef['decimals'] == 0: 
143          return int(string) 
144      else: 
145          return float(string) 
 147      "returns value as ascii representation, rounding decimal portion as necessary" 
148      if not (type(value) in (int, long, float)): 
149          raise DbfError("incompatible type: %s" % type(value)) 
150      decimalsize = fielddef['decimals'] 
151      if decimalsize: 
152          decimalsize += 1 
153      maxintegersize = fielddef['length']-decimalsize 
154      integersize = len("%.0f" % value) 
155      if integersize > maxintegersize: 
156          raise DataOverflow('Integer portion too big') 
157      return "%*.*f" % (fielddef['length'], fielddef['decimals'], value) 
 176      """sets the date/time stored in moment 
177      moment must have fields year, month, day, hour, minute, second, microsecond""" 
178      bytes = [0] * 8 
179      hour = moment.hour 
180      minute = moment.minute 
181      second = moment.second 
182      millisecond = moment.microsecond // 1000        
183      time = ((hour * 3600) + (minute * 60) + second) * 1000 + millisecond 
184      bytes[4:] = updateInteger(time) 
185      bytes[:4] = updateInteger(moment.toordinal() + VFPTIME) 
186      return ''.join(bytes) 
 188      "Returns the block of data from a memo file" 
189      block = struct.unpack('<i', bytes)[0] 
190      return memo.get_memo(block, fielddef) 
 192      "Writes string as a memo, returns the block number it was saved into" 
193      block = memo.put_memo(string) 
194      return struct.pack('<i', block) 
 196      if format[1] != '(' or format[-1] != ')': 
197          raise DbfError("Format for Character field creation is C(n), not %s" % format) 
198      length = int(format[2:-1]) 
199      if not 0 < length < 255: 
200          raise ValueError 
201      decimals = 0 
202      return length, decimals 
 204      length = 8 
205      decimals = 0 
206      return length, decimals 
 208      length = 1 
209      decimals = 0 
210      return length, decimals 
 212      length = 10 
213      decimals = 0 
214      return length, decimals 
 216      if format[1] != '(' or format[-1] != ')': 
217          raise DbfError("Format for Numeric field creation is N(n,n), not %s" % format) 
218      length, decimals = format[2:-1].split(',') 
219      length = int(length) 
220      decimals = int(decimals) 
221      if not (0 < length < 18 and 0 <= decimals <= length - 2): 
222          raise ValueError 
223      return length, decimals 
 225      length = 8 
226      decimals = 0 
227      return length, decimals 
 229      length = 8 
230      decimals = 8 
231      return length, decimals 
 233      length = 8 
234      decimals = 0 
235      return length, decimals 
 237      length = 4 
238      decimals = 0 
239      return length, decimals 
 241      length = 4 
242      decimals = 0 
243      return length, decimals 
 245      if format[1] != '(' or format[-1] != ')': 
246          raise DbfError("Format for Numeric field creation is N(n,n), not %s" % format) 
247      length, decimals = format[2:-1].split(',') 
248      length = int(length) 
249      decimals = int(decimals) 
250      if not (0 < length < 21 and 0 <= decimals <= length - 2): 
251          raise ValueError 
252      return length, decimals 
 253