1 """
2 Encoding to tabledata.
3 """
4
5
6
7
8
9
10
11 import datetime
12
13 from gavo import utils
14 from gavo.utils import stanxml
15 from gavo.utils import pgsphere
16 from gavo.votable import coding
17 from gavo.votable import common
18
19
21 """returns common code for almost all array serialization.
22
23 Field must describe an array (as opposed to a single value).
24
25 padder must be python-source for whatever is used to pad
26 arrays that are too short.
27 """
28 base = [
29 "if val is None: val = []"]
30 if field.isMultiDim():
31
32 base.append("val = coding.ravel(val)")
33 if field.hasVarLength():
34 return base
35 else:
36 return base+["val = coding.trim(val, %s, %s)"%(
37 field.getLength(), padder)]
38
39
41 """adds code handle null values where not default representation exists.
42 """
43 nullvalue = coding.getNullvalue(field, validator)
44 if nullvalue is None:
45 if defaultNullValue is None:
46 action = (" raise common.BadVOTableData('None passed for field"
47 " that has no NULL value', None, '%s', hint='Integers in VOTable"
48 " have no natural serializations for missing values. You need to"
49 " define one using values null to allow for NULL in integer columns')"
50 )%field.getDesignation()
51 else:
52 action = (" tokens.append(%r)"%stanxml.escapePCDATA(defaultNullValue))
53 else:
54 action = " tokens.append(%r)"%stanxml.escapePCDATA(nullvalue)
55 return [
56 'if val is None:',
57 action,
58 'else:']+common.indentList(src, " ")
59
60
62 return [
63 "if val is None or val!=val:",
64 " tokens.append('NaN')",
65 "else:",
66 " tokens.append(repr(float(val)))"]
67
68
70 return [
71 "if val is None:",
72 " tokens.append('NaN NaN')",
73 "else:",
74 " try:",
75 " tokens.append('%s %s'%(repr(val.real), repr(val.imag)))",
76 " except AttributeError:",
77 " tokens.append(repr(val))",]
78
79
81 return [
82 "if val is None:",
83 " tokens.append('?')",
84 "elif val:",
85 " tokens.append('1')",
86 "else:",
87 " tokens.append('0')",]
88
89
91 return _addNullvalueCode(field, [
92 "if isinstance(val, int):",
93 ' tokens.append(str(val))',
94 "else:",
95 ' tokens.append(str(ord(val[:1])))',],
96 common.validateVOTInt, "")
97
98
103
104
106 src = []
107
108 src.extend(common.getXtypeEncoderCode(field))
109 src.append("val = coding.trimString(val, %s)"%repr(field.arraysize))
110
111 if field.datatype=="char":
112 src.extend([
113 'if isinstance(val, unicode):',
114 ' val = val.encode("ascii", "replace")'])
115
116 src.extend([
117 "tokens.append(stanxml.escapePCDATA(val))"])
118
119 return _addNullvalueCode(field, src, lambda _: True, "")
120
121
122 _encoders = {
123 'boolean': _makeBooleanEncoder,
124 'bit': _makeIntEncoder,
125 'unsignedByte': _makeUByteEncoder,
126 'short': _makeIntEncoder,
127 'int': _makeIntEncoder,
128 'long': _makeIntEncoder,
129 'char': _makeCharEncoder,
130 'unicodeChar': _makeCharEncoder,
131 'float': _makeFloatEncoder,
132 'double': _makeFloatEncoder,
133 'floatComplex': _makeComplexEncoder,
134 'doubleComplex': _makeComplexEncoder,
135 }
136
137
139 """returns python lines to encode array values of field.
140
141 Again, the specs are a bit nuts, so we end up special casing almost
142 everything.
143
144 For fixed-length arrays we enforce the given length by
145 cropping or adding nulls (except, currently, for bit and char arrays).
146 """
147 type = field.datatype
148
149 if type=="bit":
150 return ['tokens.append(utils.toBinary(val))']
151
152 if type=='char' or type=='unicodeChar':
153 return _makeCharEncoder(field)
154
155 src = common.getXtypeEncoderCode(field)
156 src.extend(_getArrayShapingCode(field, '[None]'))
157 src.extend([
158 'fullTokens = tokens',
159 'tokens = []',
160 'arr = val'])
161
162 src.extend(['for val in coding.ravel(arr):']+common.indentList(
163 _encoders[type](field), " "))
164 src.append("fullTokens.append(' '.join(tokens))")
165 src.append("tokens = fullTokens")
166 return src
167
168
170 """returns python lines to encode array values of field.
171
172 This will encode NULL array as empty strings.
173 """
174 return [
175 "if val is None:",
176 " tokens.append('')",
177 "else:",]+common.indentList(_getArrayEncoderLinesNotNULL(field), " ")
178
179
181 """returns a sequence of python source lines to encode values described
182 by field into tabledata.
183 """
184 if field.isScalar():
185 return _encoders[field.datatype](field)
186 else:
187 return _getArrayEncoderLines(field)
188
189
190 -def getPostamble(tableDefinition):
191 return [
192 "return '<TR>%s</TR>'%(''.join('<TD>%s</TD>'%v for v in tokens))"]
193
194
197