1 /*
2 * Python object wrapper of libolecf_property_value_t
3 *
4 * Copyright (C) 2008-2021, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <types.h>
24
25 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
26 #include <stdlib.h>
27 #endif
28
29 #include "pyolecf_datetime.h"
30 #include "pyolecf_error.h"
31 #include "pyolecf_integer.h"
32 #include "pyolecf_libcerror.h"
33 #include "pyolecf_libolecf.h"
34 #include "pyolecf_property_value.h"
35 #include "pyolecf_python.h"
36 #include "pyolecf_unused.h"
37
38 PyMethodDef pyolecf_property_value_object_methods[] = {
39
40 { "get_identifier",
41 (PyCFunction) pyolecf_property_value_get_identifier,
42 METH_NOARGS,
43 "get_identifier() -> Integer or None\n"
44 "\n"
45 "Retrieves the identifier." },
46
47 { "get_value_type",
48 (PyCFunction) pyolecf_property_value_get_value_type,
49 METH_NOARGS,
50 "get_value_type() -> Integer or None\n"
51 "\n"
52 "Retrieves the value type." },
53
54 /* Deprecated alias of value_type */
55
56 { "get_type",
57 (PyCFunction) pyolecf_property_value_get_value_type,
58 METH_NOARGS,
59 "get_type() -> Integer or None\n"
60 "\n"
61 "Retrieves the value type." },
62
63 { "get_data",
64 (PyCFunction) pyolecf_property_value_get_data,
65 METH_NOARGS,
66 "get_data() -> Binary string or None\n"
67 "\n"
68 "Retrieves the data." },
69
70 { "get_data_as_boolean",
71 (PyCFunction) pyolecf_property_value_get_data_as_boolean,
72 METH_NOARGS,
73 "get_data_as_boolean() -> Integer or None\n"
74 "\n"
75 "Retrieves the data as a boolean." },
76
77 { "get_data_as_integer",
78 (PyCFunction) pyolecf_property_value_get_data_as_integer,
79 METH_NOARGS,
80 "get_data_as_integer() -> Integer or None\n"
81 "\n"
82 "Retrieves the data as an integer." },
83
84 { "get_data_as_datetime",
85 (PyCFunction) pyolecf_property_value_get_data_as_datetime,
86 METH_NOARGS,
87 "get_data_as_datetime() -> Datetime or None\n"
88 "\n"
89 "Retrieves the data as a datetime object." },
90
91 { "get_data_as_string",
92 (PyCFunction) pyolecf_property_value_get_data_as_string,
93 METH_NOARGS,
94 "get_data_as_string() -> Unicode string or None\n"
95 "\n"
96 "Retrieves the data as a string." },
97
98 /* Sentinel */
99 { NULL, NULL, 0, NULL }
100 };
101
102 PyGetSetDef pyolecf_property_value_object_get_set_definitions[] = {
103
104 { "identifier",
105 (getter) pyolecf_property_value_get_identifier,
106 (setter) 0,
107 "The identifier.",
108 NULL },
109
110 { "value_type",
111 (getter) pyolecf_property_value_get_value_type,
112 (setter) 0,
113 "The value type.",
114 NULL },
115
116 /* Deprecated alias of value_type */
117
118 { "type",
119 (getter) pyolecf_property_value_get_value_type,
120 (setter) 0,
121 "The value type.",
122 NULL },
123
124 { "data",
125 (getter) pyolecf_property_value_get_data,
126 (setter) 0,
127 "The data.",
128 NULL },
129
130 { "data_as_boolean",
131 (getter) pyolecf_property_value_get_data_as_boolean,
132 (setter) 0,
133 "The data as a boolean.",
134 NULL },
135
136 { "data_as_integer",
137 (getter) pyolecf_property_value_get_data_as_integer,
138 (setter) 0,
139 "The data as an integer.",
140 NULL },
141
142 { "data_as_datetime",
143 (getter) pyolecf_property_value_get_data_as_datetime,
144 (setter) 0,
145 "The data as a datetime object.",
146 NULL },
147
148 { "data_as_string",
149 (getter) pyolecf_property_value_get_data_as_string,
150 (setter) 0,
151 "The data as a string.",
152 NULL },
153
154 /* Sentinel */
155 { NULL, NULL, NULL, NULL, NULL }
156 };
157
158 PyTypeObject pyolecf_property_value_type_object = {
159 PyVarObject_HEAD_INIT( NULL, 0 )
160
161 /* tp_name */
162 "pyolecf.property_value",
163 /* tp_basicsize */
164 sizeof( pyolecf_property_value_t ),
165 /* tp_itemsize */
166 0,
167 /* tp_dealloc */
168 (destructor) pyolecf_property_value_free,
169 /* tp_print */
170 0,
171 /* tp_getattr */
172 0,
173 /* tp_setattr */
174 0,
175 /* tp_compare */
176 0,
177 /* tp_repr */
178 0,
179 /* tp_as_number */
180 0,
181 /* tp_as_sequence */
182 0,
183 /* tp_as_mapping */
184 0,
185 /* tp_hash */
186 0,
187 /* tp_call */
188 0,
189 /* tp_str */
190 0,
191 /* tp_getattro */
192 0,
193 /* tp_setattro */
194 0,
195 /* tp_as_buffer */
196 0,
197 /* tp_flags */
198 Py_TPFLAGS_DEFAULT,
199 /* tp_doc */
200 "pyolecf property value object (wraps libolecf_property_value_t)",
201 /* tp_traverse */
202 0,
203 /* tp_clear */
204 0,
205 /* tp_richcompare */
206 0,
207 /* tp_weaklistoffset */
208 0,
209 /* tp_iter */
210 0,
211 /* tp_iternext */
212 0,
213 /* tp_methods */
214 pyolecf_property_value_object_methods,
215 /* tp_members */
216 0,
217 /* tp_getset */
218 pyolecf_property_value_object_get_set_definitions,
219 /* tp_base */
220 0,
221 /* tp_dict */
222 0,
223 /* tp_descr_get */
224 0,
225 /* tp_descr_set */
226 0,
227 /* tp_dictoffset */
228 0,
229 /* tp_init */
230 (initproc) pyolecf_property_value_init,
231 /* tp_alloc */
232 0,
233 /* tp_new */
234 0,
235 /* tp_free */
236 0,
237 /* tp_is_gc */
238 0,
239 /* tp_bases */
240 NULL,
241 /* tp_mro */
242 NULL,
243 /* tp_cache */
244 NULL,
245 /* tp_subclasses */
246 NULL,
247 /* tp_weaklist */
248 NULL,
249 /* tp_del */
250 0
251 };
252
253 /* Creates a new property value object
254 * Returns a Python object if successful or NULL on error
255 */
pyolecf_property_value_new(libolecf_property_value_t * property_value,PyObject * parent_object)256 PyObject *pyolecf_property_value_new(
257 libolecf_property_value_t *property_value,
258 PyObject *parent_object )
259 {
260 pyolecf_property_value_t *pyolecf_property_value = NULL;
261 static char *function = "pyolecf_property_value_new";
262
263 if( property_value == NULL )
264 {
265 PyErr_Format(
266 PyExc_ValueError,
267 "%s: invalid property value.",
268 function );
269
270 return( NULL );
271 }
272 /* PyObject_New does not invoke tp_init
273 */
274 pyolecf_property_value = PyObject_New(
275 struct pyolecf_property_value,
276 &pyolecf_property_value_type_object );
277
278 if( pyolecf_property_value == NULL )
279 {
280 PyErr_Format(
281 PyExc_MemoryError,
282 "%s: unable to initialize property value.",
283 function );
284
285 goto on_error;
286 }
287 pyolecf_property_value->property_value = property_value;
288 pyolecf_property_value->parent_object = parent_object;
289
290 if( pyolecf_property_value->parent_object != NULL )
291 {
292 Py_IncRef(
293 pyolecf_property_value->parent_object );
294 }
295 return( (PyObject *) pyolecf_property_value );
296
297 on_error:
298 if( pyolecf_property_value != NULL )
299 {
300 Py_DecRef(
301 (PyObject *) pyolecf_property_value );
302 }
303 return( NULL );
304 }
305
306 /* Initializes a property value object
307 * Returns 0 if successful or -1 on error
308 */
pyolecf_property_value_init(pyolecf_property_value_t * pyolecf_property_value)309 int pyolecf_property_value_init(
310 pyolecf_property_value_t *pyolecf_property_value )
311 {
312 static char *function = "pyolecf_property_value_init";
313
314 if( pyolecf_property_value == NULL )
315 {
316 PyErr_Format(
317 PyExc_ValueError,
318 "%s: invalid property value.",
319 function );
320
321 return( -1 );
322 }
323 /* Make sure libolecf property value is set to NULL
324 */
325 pyolecf_property_value->property_value = NULL;
326
327 PyErr_Format(
328 PyExc_NotImplementedError,
329 "%s: initialize of property value not supported.",
330 function );
331
332 return( -1 );
333 }
334
335 /* Frees a property value object
336 */
pyolecf_property_value_free(pyolecf_property_value_t * pyolecf_property_value)337 void pyolecf_property_value_free(
338 pyolecf_property_value_t *pyolecf_property_value )
339 {
340 struct _typeobject *ob_type = NULL;
341 libcerror_error_t *error = NULL;
342 static char *function = "pyolecf_property_value_free";
343 int result = 0;
344
345 if( pyolecf_property_value == NULL )
346 {
347 PyErr_Format(
348 PyExc_ValueError,
349 "%s: invalid property value.",
350 function );
351
352 return;
353 }
354 ob_type = Py_TYPE(
355 pyolecf_property_value );
356
357 if( ob_type == NULL )
358 {
359 PyErr_Format(
360 PyExc_ValueError,
361 "%s: missing ob_type.",
362 function );
363
364 return;
365 }
366 if( ob_type->tp_free == NULL )
367 {
368 PyErr_Format(
369 PyExc_ValueError,
370 "%s: invalid ob_type - missing tp_free.",
371 function );
372
373 return;
374 }
375 if( pyolecf_property_value->property_value != NULL )
376 {
377 Py_BEGIN_ALLOW_THREADS
378
379 result = libolecf_property_value_free(
380 &( pyolecf_property_value->property_value ),
381 &error );
382
383 Py_END_ALLOW_THREADS
384
385 if( result != 1 )
386 {
387 pyolecf_error_raise(
388 error,
389 PyExc_MemoryError,
390 "%s: unable to free libolecf property value.",
391 function );
392
393 libcerror_error_free(
394 &error );
395 }
396 }
397 if( pyolecf_property_value->parent_object != NULL )
398 {
399 Py_DecRef(
400 pyolecf_property_value->parent_object );
401 }
402 ob_type->tp_free(
403 (PyObject*) pyolecf_property_value );
404 }
405
406 /* Retrieves the identifier
407 * Returns a Python object if successful or NULL on error
408 */
pyolecf_property_value_get_identifier(pyolecf_property_value_t * pyolecf_property_value,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)409 PyObject *pyolecf_property_value_get_identifier(
410 pyolecf_property_value_t *pyolecf_property_value,
411 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
412 {
413 PyObject *integer_object = NULL;
414 libcerror_error_t *error = NULL;
415 static char *function = "pyolecf_property_value_get_identifier";
416 uint32_t value_32bit = 0;
417 int result = 0;
418
419 PYOLECF_UNREFERENCED_PARAMETER( arguments )
420
421 if( pyolecf_property_value == NULL )
422 {
423 PyErr_Format(
424 PyExc_ValueError,
425 "%s: invalid property value.",
426 function );
427
428 return( NULL );
429 }
430 Py_BEGIN_ALLOW_THREADS
431
432 result = libolecf_property_value_get_identifier(
433 pyolecf_property_value->property_value,
434 &value_32bit,
435 &error );
436
437 Py_END_ALLOW_THREADS
438
439 if( result == -1 )
440 {
441 pyolecf_error_raise(
442 error,
443 PyExc_IOError,
444 "%s: unable to retrieve identifier.",
445 function );
446
447 libcerror_error_free(
448 &error );
449
450 return( NULL );
451 }
452 else if( result == 0 )
453 {
454 Py_IncRef(
455 Py_None );
456
457 return( Py_None );
458 }
459 integer_object = PyLong_FromUnsignedLong(
460 (unsigned long) value_32bit );
461
462 return( integer_object );
463 }
464
465 /* Retrieves the value type
466 * Returns a Python object if successful or NULL on error
467 */
pyolecf_property_value_get_value_type(pyolecf_property_value_t * pyolecf_property_value,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)468 PyObject *pyolecf_property_value_get_value_type(
469 pyolecf_property_value_t *pyolecf_property_value,
470 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
471 {
472 PyObject *integer_object = NULL;
473 libcerror_error_t *error = NULL;
474 static char *function = "pyolecf_property_value_get_value_type";
475 uint32_t value_32bit = 0;
476 int result = 0;
477
478 PYOLECF_UNREFERENCED_PARAMETER( arguments )
479
480 if( pyolecf_property_value == NULL )
481 {
482 PyErr_Format(
483 PyExc_ValueError,
484 "%s: invalid property value.",
485 function );
486
487 return( NULL );
488 }
489 Py_BEGIN_ALLOW_THREADS
490
491 result = libolecf_property_value_get_value_type(
492 pyolecf_property_value->property_value,
493 &value_32bit,
494 &error );
495
496 Py_END_ALLOW_THREADS
497
498 if( result == -1 )
499 {
500 pyolecf_error_raise(
501 error,
502 PyExc_IOError,
503 "%s: unable to retrieve value type.",
504 function );
505
506 libcerror_error_free(
507 &error );
508
509 return( NULL );
510 }
511 else if( result == 0 )
512 {
513 Py_IncRef(
514 Py_None );
515
516 return( Py_None );
517 }
518 integer_object = PyLong_FromUnsignedLong(
519 (unsigned long) value_32bit );
520
521 return( integer_object );
522 }
523
524 /* Retrieves the data
525 * Returns a Python object if successful or NULL on error
526 */
pyolecf_property_value_get_data(pyolecf_property_value_t * pyolecf_property_value,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)527 PyObject *pyolecf_property_value_get_data(
528 pyolecf_property_value_t *pyolecf_property_value,
529 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
530 {
531 PyObject *bytes_object = NULL;
532 libcerror_error_t *error = NULL;
533 char *data = NULL;
534 static char *function = "pyolecf_property_value_get_data";
535 size_t data_size = 0;
536 int result = 0;
537
538 PYOLECF_UNREFERENCED_PARAMETER( arguments )
539
540 if( pyolecf_property_value == NULL )
541 {
542 PyErr_Format(
543 PyExc_ValueError,
544 "%s: invalid property value.",
545 function );
546
547 return( NULL );
548 }
549 Py_BEGIN_ALLOW_THREADS
550
551 result = libolecf_property_value_get_data_size(
552 pyolecf_property_value->property_value,
553 &data_size,
554 &error );
555
556 Py_END_ALLOW_THREADS
557
558 if( result == -1 )
559 {
560 pyolecf_error_raise(
561 error,
562 PyExc_IOError,
563 "%s: unable to retrieve data size.",
564 function );
565
566 libcerror_error_free(
567 &error );
568
569 goto on_error;
570 }
571 else if( ( result == 0 )
572 || ( data_size == 0 ) )
573 {
574 Py_IncRef(
575 Py_None );
576
577 return( Py_None );
578 }
579 data = (char *) PyMem_Malloc(
580 sizeof( char ) * data_size );
581
582 if( data == NULL )
583 {
584 PyErr_Format(
585 PyExc_MemoryError,
586 "%s: unable to create data.",
587 function );
588
589 goto on_error;
590 }
591 Py_BEGIN_ALLOW_THREADS
592
593 result = libolecf_property_value_get_data(
594 pyolecf_property_value->property_value,
595 (uint8_t *) data,
596 data_size,
597 &error );
598
599 Py_END_ALLOW_THREADS
600
601 if( result != 1 )
602 {
603 pyolecf_error_raise(
604 error,
605 PyExc_IOError,
606 "%s: unable to retrieve data.",
607 function );
608
609 libcerror_error_free(
610 &error );
611
612 goto on_error;
613 }
614 /* This is a binary string so include the full size
615 */
616 #if PY_MAJOR_VERSION >= 3
617 bytes_object = PyBytes_FromStringAndSize(
618 data,
619 (Py_ssize_t) data_size );
620 #else
621 bytes_object = PyString_FromStringAndSize(
622 data,
623 (Py_ssize_t) data_size );
624 #endif
625 if( bytes_object == NULL )
626 {
627 PyErr_Format(
628 PyExc_IOError,
629 "%s: unable to convert data into Bytes object.",
630 function );
631
632 goto on_error;
633 }
634 PyMem_Free(
635 data );
636
637 return( bytes_object );
638
639 on_error:
640 if( data != NULL )
641 {
642 PyMem_Free(
643 data );
644 }
645 return( NULL );
646 }
647
648 /* Retrieves the data as a boolean value
649 * Returns a Python object if successful or NULL on error
650 */
pyolecf_property_value_get_data_as_boolean(pyolecf_property_value_t * pyolecf_property_value,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)651 PyObject *pyolecf_property_value_get_data_as_boolean(
652 pyolecf_property_value_t *pyolecf_property_value,
653 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
654 {
655 libcerror_error_t *error = NULL;
656 static char *function = "pyolecf_property_value_get_data_as_boolean";
657 uint8_t value_boolean = 0;
658 int result = 0;
659
660 PYOLECF_UNREFERENCED_PARAMETER( arguments )
661
662 if( pyolecf_property_value == NULL )
663 {
664 PyErr_Format(
665 PyExc_ValueError,
666 "%s: invalid property value.",
667 function );
668
669 return( NULL );
670 }
671 Py_BEGIN_ALLOW_THREADS
672
673 result = libolecf_property_value_get_data_as_boolean(
674 pyolecf_property_value->property_value,
675 &value_boolean,
676 &error );
677
678 Py_END_ALLOW_THREADS
679
680 if( result == -1 )
681 {
682 pyolecf_error_raise(
683 error,
684 PyExc_IOError,
685 "%s: unable to retrieve boolean value.",
686 function );
687
688 libcerror_error_free(
689 &error );
690
691 return( NULL );
692 }
693 if( value_boolean != 0x00 )
694 {
695 Py_IncRef(
696 Py_True );
697
698 return( Py_True );
699 }
700 Py_IncRef(
701 Py_False );
702
703 return( Py_False );
704 }
705
706 /* Retrieves the data as an integer value
707 * Returns a Python object if successful or NULL on error
708 */
pyolecf_property_value_get_data_as_integer(pyolecf_property_value_t * pyolecf_property_value,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)709 PyObject *pyolecf_property_value_get_data_as_integer(
710 pyolecf_property_value_t *pyolecf_property_value,
711 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
712 {
713 PyObject *integer_object = NULL;
714 libcerror_error_t *error = NULL;
715 static char *function = "pyolecf_property_value_get_data_as_integer";
716 uint64_t value_64bit = 0;
717 int64_t integer_value = 0;
718 uint32_t value_32bit = 0;
719 uint32_t value_type = 0;
720 uint16_t value_16bit = 0;
721 int result = 0;
722
723 PYOLECF_UNREFERENCED_PARAMETER( arguments )
724
725 if( pyolecf_property_value == NULL )
726 {
727 PyErr_Format(
728 PyExc_ValueError,
729 "%s: invalid property value.",
730 function );
731
732 return( NULL );
733 }
734 Py_BEGIN_ALLOW_THREADS
735
736 result = libolecf_property_value_get_value_type(
737 pyolecf_property_value->property_value,
738 &value_type,
739 &error );
740
741 Py_END_ALLOW_THREADS
742
743 if( result != 1 )
744 {
745 pyolecf_error_raise(
746 error,
747 PyExc_IOError,
748 "%s: unable to retrieve value type.",
749 function );
750
751 libcerror_error_free(
752 &error );
753
754 return( NULL );
755 }
756 switch( value_type )
757 {
758 case LIBOLECF_VALUE_TYPE_INTEGER_16BIT_SIGNED:
759 case LIBOLECF_VALUE_TYPE_INTEGER_16BIT_UNSIGNED:
760 Py_BEGIN_ALLOW_THREADS
761
762 result = libolecf_property_value_get_data_as_16bit_integer(
763 pyolecf_property_value->property_value,
764 &value_16bit,
765 &error );
766
767 Py_END_ALLOW_THREADS
768
769 if( value_type == LIBOLECF_VALUE_TYPE_INTEGER_16BIT_SIGNED )
770 {
771 /* Interpret the 16-bit value as signed
772 */
773 integer_value = (int16_t) value_16bit;
774 }
775 else
776 {
777 integer_value = value_16bit;
778 }
779 break;
780
781 case LIBOLECF_VALUE_TYPE_INTEGER_32BIT_SIGNED:
782 case LIBOLECF_VALUE_TYPE_INTEGER_32BIT_UNSIGNED:
783 Py_BEGIN_ALLOW_THREADS
784
785 result = libolecf_property_value_get_data_as_32bit_integer(
786 pyolecf_property_value->property_value,
787 &value_32bit,
788 &error );
789
790 Py_END_ALLOW_THREADS
791
792 if( value_type == LIBOLECF_VALUE_TYPE_INTEGER_32BIT_SIGNED )
793 {
794 /* Interpret the 32-bit value as signed
795 */
796 integer_value = (int32_t) value_32bit;
797 }
798 else
799 {
800 integer_value = value_32bit;
801 }
802 break;
803
804 case LIBOLECF_VALUE_TYPE_INTEGER_64BIT_SIGNED:
805 case LIBOLECF_VALUE_TYPE_INTEGER_64BIT_UNSIGNED:
806 Py_BEGIN_ALLOW_THREADS
807
808 result = libolecf_property_value_get_data_as_64bit_integer(
809 pyolecf_property_value->property_value,
810 &value_64bit,
811 &error );
812
813 Py_END_ALLOW_THREADS
814
815 if( value_type == LIBOLECF_VALUE_TYPE_INTEGER_64BIT_SIGNED )
816 {
817 /* Interpret the 64-bit value as signed
818 */
819 integer_value = (int64_t) value_64bit;
820 }
821 else
822 {
823 integer_value = value_64bit;
824 }
825 break;
826
827 case LIBOLECF_VALUE_TYPE_FILETIME:
828 Py_BEGIN_ALLOW_THREADS
829
830 result = libolecf_property_value_get_data_as_filetime(
831 pyolecf_property_value->property_value,
832 &value_64bit,
833 &error );
834
835 Py_END_ALLOW_THREADS
836
837 integer_value = value_64bit;
838
839 break;
840
841 default:
842 PyErr_Format(
843 PyExc_IOError,
844 "%s: value is not an integer type.",
845 function );
846
847 return( NULL );
848 }
849 if( result == -1 )
850 {
851 pyolecf_error_raise(
852 error,
853 PyExc_IOError,
854 "%s: unable to retrieve integer value.",
855 function );
856
857 libcerror_error_free(
858 &error );
859
860 return( NULL );
861 }
862 switch( value_type )
863 {
864 case LIBOLECF_VALUE_TYPE_INTEGER_16BIT_SIGNED:
865 case LIBOLECF_VALUE_TYPE_INTEGER_32BIT_SIGNED:
866 case LIBOLECF_VALUE_TYPE_INTEGER_64BIT_SIGNED:
867 integer_object = pyolecf_integer_signed_new_from_64bit(
868 integer_value );
869 break;
870
871 case LIBOLECF_VALUE_TYPE_INTEGER_16BIT_UNSIGNED:
872 case LIBOLECF_VALUE_TYPE_INTEGER_32BIT_UNSIGNED:
873 case LIBOLECF_VALUE_TYPE_INTEGER_64BIT_UNSIGNED:
874 case LIBOLECF_VALUE_TYPE_FILETIME:
875 integer_object = pyolecf_integer_unsigned_new_from_64bit(
876 integer_value );
877 break;
878 }
879 return( integer_object );
880 }
881
882 /* Retrieves the data as an datetime value
883 * Returns a Python object if successful or NULL on error
884 */
pyolecf_property_value_get_data_as_datetime(pyolecf_property_value_t * pyolecf_property_value,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)885 PyObject *pyolecf_property_value_get_data_as_datetime(
886 pyolecf_property_value_t *pyolecf_property_value,
887 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
888 {
889 PyObject *datetime_object = NULL;
890 libcerror_error_t *error = NULL;
891 static char *function = "pyolecf_property_value_get_data_as_datetime";
892 uint64_t value_64bit = 0;
893 uint32_t value_type = 0;
894 int result = 0;
895
896 PYOLECF_UNREFERENCED_PARAMETER( arguments )
897
898 if( pyolecf_property_value == NULL )
899 {
900 PyErr_Format(
901 PyExc_ValueError,
902 "%s: invalid property value.",
903 function );
904
905 return( NULL );
906 }
907 Py_BEGIN_ALLOW_THREADS
908
909 result = libolecf_property_value_get_value_type(
910 pyolecf_property_value->property_value,
911 &value_type,
912 &error );
913
914 Py_END_ALLOW_THREADS
915
916 if( result != 1 )
917 {
918 pyolecf_error_raise(
919 error,
920 PyExc_IOError,
921 "%s: unable to retrieve value type.",
922 function );
923
924 libcerror_error_free(
925 &error );
926
927 return( NULL );
928 }
929 switch( value_type )
930 {
931 case LIBOLECF_VALUE_TYPE_FILETIME:
932 Py_BEGIN_ALLOW_THREADS
933
934 result = libolecf_property_value_get_data_as_filetime(
935 pyolecf_property_value->property_value,
936 &value_64bit,
937 &error );
938
939 Py_END_ALLOW_THREADS
940
941 datetime_object = pyolecf_datetime_new_from_filetime(
942 value_64bit );
943 break;
944
945 default:
946 PyErr_Format(
947 PyExc_IOError,
948 "%s: value is not an datetime type.",
949 function );
950
951 return( NULL );
952 }
953 if( result == -1 )
954 {
955 pyolecf_error_raise(
956 error,
957 PyExc_IOError,
958 "%s: unable to retrieve datetime value.",
959 function );
960
961 libcerror_error_free(
962 &error );
963
964 return( NULL );
965 }
966 return( datetime_object );
967 }
968
969 /* Retrieves the data as a string
970 * Returns a Python object if successful or NULL on error
971 */
pyolecf_property_value_get_data_as_string(pyolecf_property_value_t * pyolecf_property_value,PyObject * arguments PYOLECF_ATTRIBUTE_UNUSED)972 PyObject *pyolecf_property_value_get_data_as_string(
973 pyolecf_property_value_t *pyolecf_property_value,
974 PyObject *arguments PYOLECF_ATTRIBUTE_UNUSED )
975 {
976 PyObject *string_object = NULL;
977 libcerror_error_t *error = NULL;
978 const char *errors = NULL;
979 static char *function = "pyolecf_value_get_data_as_string";
980 char *utf8_string = NULL;
981 size_t utf8_string_size = 0;
982 int result = 0;
983
984 PYOLECF_UNREFERENCED_PARAMETER( arguments )
985
986 if( pyolecf_property_value == NULL )
987 {
988 PyErr_Format(
989 PyExc_ValueError,
990 "%s: invalid property value.",
991 function );
992
993 return( NULL );
994 }
995 Py_BEGIN_ALLOW_THREADS
996
997 result = libolecf_property_value_get_data_as_utf8_string_size(
998 pyolecf_property_value->property_value,
999 &utf8_string_size,
1000 &error );
1001
1002 Py_END_ALLOW_THREADS
1003
1004 if( result == -1 )
1005 {
1006 pyolecf_error_raise(
1007 error,
1008 PyExc_IOError,
1009 "%s: unable to determine size of data as UTF-8 string.",
1010 function );
1011
1012 libcerror_error_free(
1013 &error );
1014
1015 goto on_error;
1016 }
1017 else if( ( result == 0 )
1018 || ( utf8_string_size == 0 ) )
1019 {
1020 Py_IncRef(
1021 Py_None );
1022
1023 return( Py_None );
1024 }
1025 utf8_string = (char *) PyMem_Malloc(
1026 sizeof( char ) * utf8_string_size );
1027
1028 if( utf8_string == NULL )
1029 {
1030 PyErr_Format(
1031 PyExc_MemoryError,
1032 "%s: unable to create UTF-8 string.",
1033 function );
1034
1035 goto on_error;
1036 }
1037 Py_BEGIN_ALLOW_THREADS
1038
1039 result = libolecf_property_value_get_data_as_utf8_string(
1040 pyolecf_property_value->property_value,
1041 (uint8_t *) utf8_string,
1042 utf8_string_size,
1043 &error );
1044
1045 Py_END_ALLOW_THREADS
1046
1047 if( result != 1 )
1048 {
1049 pyolecf_error_raise(
1050 error,
1051 PyExc_IOError,
1052 "%s: unable to retrieve data as UTF-8 string.",
1053 function );
1054
1055 libcerror_error_free(
1056 &error );
1057
1058 goto on_error;
1059 }
1060 /* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes
1061 * the end of string character is part of the string
1062 */
1063 string_object = PyUnicode_DecodeUTF8(
1064 utf8_string,
1065 (Py_ssize_t) utf8_string_size - 1,
1066 errors );
1067
1068 if( string_object == NULL )
1069 {
1070 PyErr_Format(
1071 PyExc_IOError,
1072 "%s: unable to convert UTF-8 string into Unicode object.",
1073 function );
1074
1075 goto on_error;
1076 }
1077 PyMem_Free(
1078 utf8_string );
1079
1080 return( string_object );
1081
1082 on_error:
1083 if( utf8_string != NULL )
1084 {
1085 PyMem_Free(
1086 utf8_string );
1087 }
1088 return( NULL );
1089 }
1090
1091