1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 from libreoffice
.util
import printing
13 from libreoffice
.util
.string
import StringPrinterHelper
15 class StringPrinter(StringPrinterHelper
):
16 '''Prints ByteString or UniString'''
18 def __init__(self
, typename
, val
, encoding
= None):
19 super(StringPrinter
, self
).__init
__(typename
, val
, encoding
)
22 data
= self
.val
['mpData']
23 # mnRefCount is not a good indicator: it seems there could be
24 # cases where it is negative (-7FFFFFED)
25 return data
#and data.dereference()['mnRefCount'] > 0
28 assert self
.val
['mpData']
29 return self
.val
['mpData'].dereference()['maStr']
32 assert self
.val
['mpData']
33 return self
.val
['mpData'].dereference()['mnLen']
35 class BigIntPrinter(object):
36 '''Prints big integer'''
38 def __init__(self
, typename
, val
):
42 if self
.val
['bIsSet']:
43 if self
.val
['bIsBig']:
46 return self
.val
['nVal']
48 return "unset %s" % self
.typename
51 len = self
.val
['nLen']
52 digits
= self
.val
['nNum']
53 dsize
= digits
.dereference().type.sizeof
* 8
55 # The least significant byte is on index 0
56 for i
in reversed(range(0, len)):
61 class ColorPrinter(object):
62 '''Prints color as rgb(r, g, b) or rgba(r, g, b, a)'''
64 def __init__(self
, typename
, val
):
68 color
= self
.val
['mnColor']
70 g
= (color
>> 8) & 0xff
71 r
= (color
>> 16) & 0xff
72 a
= (color
>> 24) & 0xff
74 return "rgba(%d, %d, %d, %d)" % (r
, g
, b
, a
)
76 return "rgb(%d, %d, %d)" % (r
, g
, b
)
78 class FractionPrinter(object):
81 def __init__(self
, typename
, val
):
82 self
.typename
= typename
86 numerator
= self
.val
['nNumerator']
87 denominator
= self
.val
['nDenominator']
89 return "%d/%d" % (numerator
, denominator
)
91 return "invalid %s" % self
.typename
93 class DateTimeImpl(object):
95 def __init__(self
, date
, time
):
102 result
+= str(self
.date
)
106 result
+= str(self
.time
)
111 return DateTimeImpl(DateImpl
.parse(val
), TimeImpl
.parse(val
))
113 class DateTimePrinter(object):
114 '''Prints date and time'''
116 def __init__(self
, typename
, val
):
120 return str(DateTimeImpl
.parse(self
.val
))
122 class DateImpl(DateTimeImpl
):
124 def __init__(self
, year
, month
, day
):
125 super(DateImpl
, self
).__init
__(self
, None)
131 return "%d-%d-%d" % (self
.year
, self
.month
, self
.day
)
137 m
= (date
/ 100) % 100
139 return DateImpl(y
, m
, d
)
141 class DatePrinter(object):
144 def __init__(self
, typename
, val
):
148 return str(DateImpl
.parse(self
.val
))
150 class TimeImpl(DateTimeImpl
):
152 def __init__(self
, hour
, minute
, second
, nanosecond
= 0):
153 super(TimeImpl
, self
).__init
__(None, self
)
157 self
.nanosecond
= nanosecond
161 if self
.nanosecond
!= 0:
162 decimal
= '.%09d' % self
.nanosecond
163 return "%02d:%02d:%02d%s" % (self
.hour
, self
.minute
, self
.second
, decimal
)
168 h
= time
/ 10000000000000
169 m
= (time
/ 100000000000) % 100
170 s
= (time
/ 1000000000) % 100
171 ns
= time
% 1000000000
172 return TimeImpl(h
, m
, s
, ns
)
174 class TimePrinter(object):
177 def __init__(self
, typename
, val
):
181 return str(TimeImpl
.parse(self
.val
))
183 class IteratorHelper(object):
184 '''Implements a container iterator useable for both 'linear'
185 containers (like DynArray or List) and Tables
188 def __init__(self
, block
, count
, type = None):
196 self
._next
_block
(block
)
198 self
._check
_invariant
()
204 if self
.pos
== self
.count
:
205 raise StopIteration()
207 if self
.block_pos
== self
.block_count
:
208 self
._next
_block
(self
.block
['pNext'])
214 self
._check
_invariant
()
217 def _next_block(self
, block
):
220 self
.block
= block
.dereference()
222 self
.block_count
= block
['nCount']
224 assert self
.block_count
<= block
['nSize']
225 assert self
.block_count
+ self
.pos
<= self
.count
227 def _check_invariant(self
):
228 assert self
.count
>= 0
230 assert self
.pos
<= self
.count
231 assert self
.block_count
>= 0
232 if self
.pos
< self
.count
:
233 assert self
.block_count
> 0
234 assert self
.block
!= None
235 assert self
.block_count
<= self
.count
236 assert self
.block_pos
>= 0
237 assert self
.block_pos
<= self
.block_count
239 class NoItemType(Exception):
242 class ContainerHelper(object):
243 '''Provides support for specialized container printers'''
245 def __init__(self
, typename
, val
, iterator
):
246 self
.typename
= typename
248 self
.iterator
= iterator
251 size
= self
.val
['nCount']
253 return "%s of length %d" % (self
.typename
, size
)
255 return "empty %s" % self
.typename
257 return "invalid %s" % self
.typename
260 count
= self
.val
.cast(gdb
.lookup_type('Container'))['nCount']
261 return self
.iterator(self
.val
['pFirstBlock'], count
)
263 class LinearIterator(IteratorHelper
):
264 '''Is iterator for 'linear' container'''
266 def __init__(self
, block
, count
, type = None):
267 super(LinearIterator
, self
).__init
__(block
, count
, type)
273 nodes
= self
.block
['pNodes']#.cast(self.type.pointer())
274 return nodes
[self
.block_pos
]
280 class LinearContainerPrinter(ContainerHelper
):
281 '''Prints 'linear' container, like DynArray or List'''
283 def __init__(self
, typename
, val
):
284 super(LinearContainerPrinter
, self
).__init
__(typename
, val
, LinearIterator
)
286 def display_hint(self
):
289 class TableIterator(IteratorHelper
):
290 '''Is iterator for Table'''
292 def __init__(self
, block
, count
, type = None):
293 super(TableIterator
, self
).__init
__(block
, count
, type)
294 # ULONG doesn't work on 64-bit for some reason (gdb says it has
295 # size 4 and it's not a typedef to sal_uIntPtr)
296 self
._key
_type
= gdb
.lookup_type('sal_uIntPtr')
303 nodes
= self
.block
['pNodes']#.cast(self.type.pointer())
304 val
= nodes
[self
.block_pos
]
306 val
= str(val
.cast(self
._key
_type
))
312 self
.is_key
= not self
.is_key
314 class TablePrinter(ContainerHelper
):
317 def __init__(self
, typename
, val
):
318 super(TablePrinter
, self
).__init
__(typename
, val
, TableIterator
)
320 def display_hint(self
):
323 class PointPrinter(object):
324 '''Prints a Point.'''
326 def __init__(self
, typename
, value
):
327 self
.typename
= typename
331 return "%s" % (self
.typename
)
336 children
= [('x', x
), ('y', y
)]
337 return children
.__iter
__()
339 class SizePrinter(object):
342 def __init__(self
, typename
, value
):
343 self
.typename
= typename
347 return "%s" % (self
.typename
)
350 width
= self
.value
['nA']
351 height
= self
.value
['nB']
352 children
= [('width', width
), ('height', height
)]
353 return children
.__iter
__()
355 class RectanglePrinter(object):
356 '''Prints a Rectangle.'''
358 def __init__(self
, typename
, value
):
359 self
.typename
= typename
363 return "%s" % (self
.typename
)
366 left
= self
.value
['nLeft']
367 top
= self
.value
['nTop']
368 right
= self
.value
['nRight']
369 bottom
= self
.value
['nBottom']
370 children
= [('left', left
), ('top', top
), ('right', right
), ('bottom', bottom
)]
371 return children
.__iter
__()
375 def build_pretty_printers():
378 printer
= printing
.Printer('libreoffice/tl')
381 printer
.add('ByteString', StringPrinter
)
382 printer
.add('String', lambda name
, val
: StringPrinter(name
, val
, 'utf-16'))
384 # old-style containers
385 printer
.add('DynArray', LinearContainerPrinter
)
386 printer
.add('List', LinearContainerPrinter
)
387 printer
.add('Stack', LinearContainerPrinter
)
388 printer
.add('Table', TablePrinter
)
391 printer
.add('BigInt', BigIntPrinter
)
392 printer
.add('Color', ColorPrinter
)
393 printer
.add('Fraction', FractionPrinter
)
394 printer
.add('DateTime', DateTimePrinter
)
395 printer
.add('Date', DatePrinter
)
396 printer
.add('Time', TimePrinter
)
397 printer
.add('Point', PointPrinter
)
398 printer
.add('Size', SizePrinter
)
399 printer
.add('Rectangle', RectanglePrinter
)
401 def register_pretty_printers(obj
):
402 printing
.register_pretty_printer(printer
, obj
)
404 build_pretty_printers()
406 # vim:set shiftwidth=4 softtabstop=4 expandtab: