1
2
3 """
4 The ``grizzled.text`` package contains text-related classes and modules.
5 """
6
7 __docformat__ = "restructuredtext en"
8
9
10
11
12
13 from StringIO import StringIO
14
15
16
17
18
19 __all__ = ['hexdump']
20
21
22
23
24
25 REPEAT_FORMAT = '*** Repeated %d times'
26
27
28
29
30
31 -def hexdump(source, out, width=16, start=0, limit=None, show_repeats=False):
32 """
33 Produce a "standard" hexdump of the specified string or file-like
34 object. The output consists of a series of lines like this::
35
36 000000: 72 22 22 22 4f 53 20 72 6f 75 r'''OS rou
37 00000a: 74 69 6e 65 73 20 66 6f 72 20 tines for
38 000014: 4d 61 63 2c 20 4e 54 2c 20 6f Mac, NT, o
39 00001e: 72 20 50 6f 73 69 78 20 64 65 r Posix de
40 000028: 70 65 6e 64 69 6e 67 20 6f 6e pending on
41 000032: 20 77 68 61 74 20 73 79 73 74 what syst
42 00003c: 65 6d 20 77 65 27 72 65 20 6f em we're o
43 000046: 6e 2e 0a 0a 54 68 69 73 20 65 n...This e
44
45 The output width (i.e., the number of decoded characters shown on a
46 line) can be controlled with the ``width`` parameter.
47
48 Adjacent repeated lines are collapsed by default. For example::
49
50 000000: 00 00 00 00 00 00 00 00 00 00 ..........
51 *** Repeated 203 times
52 0007f8: 72 22 22 22 4f 53 20 72 6f 75 r'''OS rou
53
54 This behavior can be disabled via the ``show_repeats`` parameter.
55
56 :Parameters:
57 source : str or file
58 The object whose contents are to be dumped in hex. The
59 object can be a string or a file-like object.
60
61 out : file
62 Where to dump the hex output
63
64 width : int
65 The number of dumped characters per line
66
67 start : int
68 Offset within ``input`` where reading should begin
69
70 limit : int
71 Total number of bytes to dump. Defaults to everything from
72 ``start`` to the end.
73
74 show_repeats : bool
75 ``False`` to collapse repeated output lines, ``True`` to
76 dump all lines, even if they're repeats.
77 """
78
79 def ascii(b):
80 """Determine how to show a byte in ascii."""
81 if 32 <= b <= 126:
82 return chr(b)
83 else:
84 return '.'
85
86 pos = 0
87 ascii_map = [ ascii(c) for c in range(256) ]
88
89 lastbuf = ''
90 lastline = ''
91 repeat_count = 0
92
93 if width > 4:
94 space_col = width/2
95 else:
96 space_col = -1
97
98 if type(source) == str:
99 source = StringIO(source)
100
101 if start:
102 source.seek(start)
103 pos = start
104
105 hex_field_width = (width * 3) + 1
106
107 total_read = 0
108 while True:
109 if limit:
110 to_read = min(limit - total_read, width)
111 else:
112 to_read = width
113
114 buf = source.read(to_read)
115 length = len(buf)
116 total_read += length
117 if length == 0:
118 if repeat_count and (not show_repeats):
119 if repeat_count > 1:
120 print >> out, REPEAT_FORMAT % (repeat_count - 1)
121 elif repeat_count == 1:
122 print >> out, lastline
123 print >> out, lastline
124 break
125
126 else:
127 show_buf = True
128
129 if buf == lastbuf:
130 repeat_count += 1
131 show_buf = False
132 else:
133 if repeat_count and (not show_repeats):
134 if repeat_count == 1:
135 print >> out, lastline
136 else:
137 print >> out, REPEAT_FORMAT % (repeat_count - 1)
138 repeat_count = 0
139
140
141 hex = ""
142 asc = ""
143 for i in range(length):
144 c = buf[i]
145 if i == space_col:
146 hex = hex + " "
147 hex = hex + ("%02x" % ord(c)) + " "
148 asc = asc + ascii_map[ord(c)]
149 line = "%06x: %-*s %s" % (pos, hex_field_width, hex, asc)
150
151 if show_buf:
152 print >> out, line
153
154 pos = pos + length
155 lastbuf = buf
156 lastline = line
157
159 """
160 Convert a string to a boolean value. The supported conversions are:
161
162 +--------------+---------------+
163 | String | Boolean value |
164 +==============+===============+
165 | "false" | False |
166 +--------------+---------------+
167 | "true" | True |
168 +--------------+---------------+
169 | "f" | False |
170 +--------------+---------------+
171 | "t" + True |
172 +--------------+---------------+
173 | "0" | False |
174 +--------------+---------------+
175 | "1" + True |
176 +--------------+---------------+
177 | "n" | False |
178 +--------------+---------------+
179 | "y" + True |
180 +--------------+---------------+
181 | "no" | False |
182 +--------------+---------------+
183 | "yes" + True |
184 +--------------+---------------+
185 | "off" | False |
186 +--------------+---------------+
187 | "on" + True |
188 +--------------+---------------+
189
190 Strings are compared in a case-blind fashion.
191
192 **Note**: This function is not currently localizable.
193
194 :Parameters:
195 s : str
196 The string to convert to boolean
197
198 :rtype: bool
199 :return: the corresponding boolean value
200
201 :raise ValueError: unrecognized boolean string
202 """
203 try:
204 return {'false' : False,
205 'true' : True,
206 'f' : False,
207 't' : True,
208 '0' : False,
209 '1' : True,
210 'no' : False,
211 'yes' : True,
212 'y' : False,
213 'n' : True,
214 'off' : False,
215 'on' : True}[s.lower()]
216 except KeyError:
217 raise ValueError, 'Unrecognized boolean string: "%s"' % s
218