def _makeCharEncoder(field): nullvalue = coding.getNullvalue(field, lambda _: True) if nullvalue is not None: nullvalue = repr(struct.pack("c", str(nullvalue))) return _addNullvalueCode(field, nullvalue, ["tokens.append(struct.pack('c', str(val)))"])
def makeIntEncoder(field): nullvalue = coding.getNullvalue(field, int) if nullvalue is not None: nullvalue = repr(struct.pack(fmtCode, int(nullvalue))) return _addNullvalueCode( field, nullvalue, ["tokens.append(struct.pack('%s', val))" % fmtCode])
def _makeUnicodeCharEncoder(field): nullvalue = coding.getNullvalue(field, lambda _: True) if nullvalue is not None: coded = nullvalue.encode("utf-16be") nullvalue = repr(struct.pack("%ds" % len(coded), coded)) return _addNullvalueCode(field, nullvalue, [ "coded = val.encode('utf-16be')", "tokens.append(struct.pack('%ds'%len(coded), coded))" ])
def _makeUnsignedByteEncoder(field): # allow these to come from strings, too (db type bytea) nullvalue = coding.getNullvalue(field, int) if nullvalue is not None: nullvalue = repr(struct.pack("B", int(nullvalue))) return _addNullvalueCode(field, nullvalue, [ "if isinstance(val, int):", " tokens.append(struct.pack('B', val))", "else:", " tokens.append(struct.pack('c', val[:1]))" ])
def _addNullvalueCode(field, src, validator): """adds code to catch nullvalues if required by field. validator must be a function returning a valid python literal for a nullvalue attribute or raise an exception. This is security critical since whatever validator returns gets embedded into natively-run source code. """ nullvalue = coding.getNullvalue(field, validator) if nullvalue: src.extend([ 'if val==%s:' % validator(nullvalue), ' row.append(None)', 'else:', ' row.append(val)', ]) else: src.append('row.append(val)') return src
def _makeShortcutCode(field, type): """returns None or code to quickly decode field array. Fast decoding for whatever is mentioned in _typemap and no nullvalues are defined. """ if type not in _typemap: return None if coding.getNullvalue(field, str) is not None: return None numBytes, typecode = _typemap[type] src = _getArraysizeCode(field) src.append( 'vals = struct.unpack("!%%d%s"%%arraysize, inF.read(arraysize*%d))' % (typecode, numBytes)) if type == 'float' or type == 'double': src.append('row.append([v!=v and None or v for v in vals])') else: src.append('row.append(list(vals))')
def _addNullvalueCode(field, src, validator, defaultNullValue=None): """adds code handle null values where not default representation exists. """ nullvalue = coding.getNullvalue(field, validator) if nullvalue is None: if defaultNullValue is None: action = (" raise common.BadVOTableData('None passed for field" " that has no NULL value', None, '%s', hint='Integers in VOTable" " have no natural serializations for missing values. You need to" " define one using values null to allow for NULL in integer columns')" )%field.getDesignation() else: action = (" tokens.append(%r)"%stanxml.escapePCDATA(defaultNullValue)) else: action = " tokens.append(%r)"%stanxml.escapePCDATA(nullvalue) return [ 'if val is None:', action, 'else:']+coding.indentList(src, " ")
def _makeCharArrayEncoder(field): # special handling for character arrays, since we don't want to treat # those as character arrays in python. if field.isMultiDim(): # String arrays -- implement some other day raise NotImplementedError("Cannot do string arrays yet. Could you" " help out?") nullvalue = coding.getNullvalue(field, lambda _: True, default="") src = [] if field.datatype == "char": src.extend([ 'if isinstance(val, unicode):', ' val = val.encode("ascii", "replace")' ]) if field.hasVarLength(): src.extend(common.getXtypeCode(field)) src.append("tokens.append(struct.pack('!i', len(val)))") if nullvalue is None: nullvalue = repr('\0\0\0\0') else: # The str in the next line allows nullvalue to be unicode (containing # ascii, of course) nullvalue = repr( struct.pack("!i%ds" % len(nullvalue), len(nullvalue), str(nullvalue))) else: src.append("val = coding.trimString(val, %d)" % field.getLength()) if nullvalue is not None: nullvalue = repr( struct.pack( "%ds" % field.getLength(), str(coding.trimString(nullvalue, field.getLength())))) # no predefined nullvalue for constant-length strings if field.datatype == "unicodeChar": src.append("val = val.encode('utf-16be')") src.append("tokens.append(struct.pack('%ds'%len(val), val))") return _addNullvalueCode(field, nullvalue, src)