Coverage Report

Created: 2024-02-25 07:20

/src/libnk2/libcdata/libcdata_list_element.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * List element functions
3
 *
4
 * Copyright (C) 2006-2024, 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 <memory.h>
24
#include <types.h>
25
26
#include "libcdata_libcerror.h"
27
#include "libcdata_libcthreads.h"
28
#include "libcdata_list_element.h"
29
#include "libcdata_types.h"
30
31
/* Creates a list element
32
 * Make sure the value element is referencing, is set to NULL
33
 * Returns 1 if successful or -1 on error
34
 */
35
int libcdata_list_element_initialize(
36
     libcdata_list_element_t **element,
37
     libcerror_error_t **error )
38
25.7M
{
39
25.7M
  libcdata_internal_list_element_t *internal_element = NULL;
40
25.7M
  static char *function                              = "libcdata_list_element_initialize";
41
42
25.7M
  if( element == NULL )
43
0
  {
44
0
    libcerror_error_set(
45
0
     error,
46
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
47
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
48
0
     "%s: invalid list element.",
49
0
     function );
50
51
0
    return( -1 );
52
0
  }
53
25.7M
  if( *element != NULL )
54
0
  {
55
0
    libcerror_error_set(
56
0
     error,
57
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
58
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
59
0
     "%s: invalid element value already set.",
60
0
     function );
61
62
0
    return( -1 );
63
0
  }
64
25.7M
  internal_element = memory_allocate_structure(
65
25.7M
                      libcdata_internal_list_element_t );
66
67
25.7M
  if( internal_element == NULL )
68
0
  {
69
0
    libcerror_error_set(
70
0
     error,
71
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
72
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
73
0
     "%s: unable to create list element.",
74
0
     function );
75
76
0
    goto on_error;
77
0
  }
78
25.7M
  if( memory_set(
79
25.7M
       internal_element,
80
25.7M
       0,
81
25.7M
       sizeof( libcdata_internal_list_element_t ) ) == NULL )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
86
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
87
0
     "%s: unable to clear list element.",
88
0
     function );
89
90
0
    memory_free(
91
0
     internal_element );
92
93
0
    return( -1 );
94
0
  }
95
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
96
  if( libcthreads_read_write_lock_initialize(
97
       &( internal_element->read_write_lock ),
98
       error ) != 1 )
99
  {
100
    libcerror_error_set(
101
     error,
102
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
103
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
104
     "%s: unable to initialize read/write lock.",
105
     function );
106
107
    goto on_error;
108
  }
109
#endif
110
25.7M
  *element = (libcdata_list_element_t *) internal_element;
111
112
25.7M
  return( 1 );
113
114
0
on_error:
115
0
  if( internal_element != NULL )
116
0
  {
117
0
    memory_free(
118
0
     internal_element );
119
0
  }
120
0
  return( -1 );
121
25.7M
}
122
123
/* Frees a list element
124
 * Uses the value_free_function to free the element value
125
 * Returns 1 if successful or -1 on error
126
 */
127
int libcdata_list_element_free(
128
     libcdata_list_element_t **element,
129
     int (*value_free_function)(
130
            intptr_t **value,
131
            libcerror_error_t **error ),
132
     libcerror_error_t **error )
133
25.7M
{
134
25.7M
  libcdata_internal_list_element_t *internal_element = NULL;
135
25.7M
  static char *function                              = "libcdata_list_element_free";
136
25.7M
  int result                                         = 1;
137
138
25.7M
  if( element == NULL )
139
0
  {
140
0
    libcerror_error_set(
141
0
     error,
142
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
143
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
144
0
     "%s: invalid list element.",
145
0
     function );
146
147
0
    return( -1 );
148
0
  }
149
25.7M
  if( *element != NULL )
150
25.7M
  {
151
25.7M
    internal_element = (libcdata_internal_list_element_t *) *element;
152
153
25.7M
    if( ( internal_element->previous_element != NULL )
154
25.7M
     || ( internal_element->next_element != NULL ) )
155
0
    {
156
0
      libcerror_error_set(
157
0
       error,
158
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
159
0
       LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
160
0
       "%s: list element part of a list.",
161
0
       function );
162
163
0
      return( -1 );
164
0
    }
165
25.7M
    *element = NULL;
166
167
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
168
    if( libcthreads_read_write_lock_free(
169
         &( internal_element->read_write_lock ),
170
         error ) != 1 )
171
    {
172
      libcerror_error_set(
173
       error,
174
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
175
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
176
       "%s: unable to free read/write lock.",
177
       function );
178
179
      result = -1;
180
    }
181
#endif
182
25.7M
    if( value_free_function != NULL )
183
968k
    {
184
968k
      if( value_free_function(
185
968k
           &( internal_element->value ),
186
968k
           error ) != 1 )
187
0
      {
188
0
        libcerror_error_set(
189
0
         error,
190
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
191
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
192
0
         "%s: unable to free value.",
193
0
         function );
194
195
0
        result = -1;
196
0
      }
197
968k
    }
198
25.7M
    memory_free(
199
25.7M
     internal_element );
200
25.7M
  }
201
25.7M
  return( result );
202
25.7M
}
203
204
/* Retrieves the parent list from the list element
205
 * Returns 1 if successful or -1 on error
206
 */
207
int libcdata_list_element_get_parent_list(
208
     libcdata_list_element_t *element,
209
     intptr_t **parent_list,
210
     libcerror_error_t **error )
211
0
{
212
0
  libcdata_internal_list_element_t *internal_element = NULL;
213
0
  static char *function                              = "libcdata_list_element_get_parent_list";
214
215
0
  if( element == NULL )
216
0
  {
217
0
    libcerror_error_set(
218
0
     error,
219
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
220
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
221
0
     "%s: invalid list element.",
222
0
     function );
223
224
0
    return( -1 );
225
0
  }
226
0
  internal_element = (libcdata_internal_list_element_t *) element;
227
228
0
  if( parent_list == NULL )
229
0
  {
230
0
    libcerror_error_set(
231
0
     error,
232
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
233
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
234
0
     "%s: invalid parent list.",
235
0
     function );
236
237
0
    return( -1 );
238
0
  }
239
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
240
  if( libcthreads_read_write_lock_grab_for_read(
241
       internal_element->read_write_lock,
242
       error ) != 1 )
243
  {
244
    libcerror_error_set(
245
     error,
246
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
247
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
248
     "%s: unable to grab read/write lock for reading.",
249
     function );
250
251
    return( -1 );
252
  }
253
#endif
254
0
  *parent_list = internal_element->parent_list;
255
256
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
257
  if( libcthreads_read_write_lock_release_for_read(
258
       internal_element->read_write_lock,
259
       error ) != 1 )
260
  {
261
    libcerror_error_set(
262
     error,
263
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
264
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
265
     "%s: unable to release read/write lock for reading.",
266
     function );
267
268
    return( -1 );
269
  }
270
#endif
271
0
  return( 1 );
272
0
}
273
274
/* Sets the parent list in the list element
275
 * Returns 1 if successful or -1 on error
276
 */
277
int libcdata_list_element_set_parent_list(
278
     libcdata_list_element_t *element,
279
     intptr_t *parent_list,
280
     libcerror_error_t **error )
281
0
{
282
0
  libcdata_internal_list_element_t *internal_element = NULL;
283
0
  static char *function                              = "libcdata_list_element_set_parent_list";
284
285
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
286
  intptr_t *backup_parent_list                       = NULL;
287
#endif
288
289
0
  if( element == NULL )
290
0
  {
291
0
    libcerror_error_set(
292
0
     error,
293
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
294
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
295
0
     "%s: invalid list element.",
296
0
     function );
297
298
0
    return( -1 );
299
0
  }
300
0
  internal_element = (libcdata_internal_list_element_t *) element;
301
302
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
303
  if( libcthreads_read_write_lock_grab_for_write(
304
       internal_element->read_write_lock,
305
       error ) != 1 )
306
  {
307
    libcerror_error_set(
308
     error,
309
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
310
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
311
     "%s: unable to grab read/write lock for writing.",
312
     function );
313
314
    return( -1 );
315
  }
316
  backup_parent_list = internal_element->parent_list;
317
#endif
318
0
  internal_element->parent_list = parent_list;
319
320
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
321
  if( libcthreads_read_write_lock_release_for_write(
322
       internal_element->read_write_lock,
323
       error ) != 1 )
324
  {
325
    libcerror_error_set(
326
     error,
327
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
328
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
329
     "%s: unable to release read/write lock for writing.",
330
     function );
331
332
    goto on_error;
333
  }
334
#endif
335
0
  return( 1 );
336
337
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
338
on_error:
339
  internal_element->parent_list = backup_parent_list;
340
341
  return( -1 );
342
#endif
343
0
}
344
345
/* Retrieves the previous element from the list element
346
 * Returns 1 if successful or -1 on error
347
 */
348
int libcdata_list_element_get_previous_element(
349
     libcdata_list_element_t *element,
350
     libcdata_list_element_t **previous_element,
351
     libcerror_error_t **error )
352
24.5M
{
353
24.5M
  libcdata_internal_list_element_t *internal_element = NULL;
354
24.5M
  static char *function                              = "libcdata_list_element_get_previous_element";
355
356
24.5M
  if( element == NULL )
357
0
  {
358
0
    libcerror_error_set(
359
0
     error,
360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
362
0
     "%s: invalid list element.",
363
0
     function );
364
365
0
    return( -1 );
366
0
  }
367
24.5M
  internal_element = (libcdata_internal_list_element_t *) element;
368
369
24.5M
  if( previous_element == NULL )
370
0
  {
371
0
    libcerror_error_set(
372
0
     error,
373
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
374
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
375
0
     "%s: invalid previous element.",
376
0
     function );
377
378
0
    return( -1 );
379
0
  }
380
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
381
  if( libcthreads_read_write_lock_grab_for_read(
382
       internal_element->read_write_lock,
383
       error ) != 1 )
384
  {
385
    libcerror_error_set(
386
     error,
387
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
388
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
389
     "%s: unable to grab read/write lock for reading.",
390
     function );
391
392
    return( -1 );
393
  }
394
#endif
395
24.5M
  *previous_element = internal_element->previous_element;
396
397
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
398
  if( libcthreads_read_write_lock_release_for_read(
399
       internal_element->read_write_lock,
400
       error ) != 1 )
401
  {
402
    libcerror_error_set(
403
     error,
404
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
405
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
406
     "%s: unable to release read/write lock for reading.",
407
     function );
408
409
    return( -1 );
410
  }
411
#endif
412
24.5M
  return( 1 );
413
24.5M
}
414
415
/* Sets the previous element in the list element
416
 * Returns 1 if successful or -1 on error
417
 */
418
int libcdata_list_element_set_previous_element(
419
     libcdata_list_element_t *element,
420
     libcdata_list_element_t *previous_element,
421
     libcerror_error_t **error )
422
52.5M
{
423
52.5M
  libcdata_internal_list_element_t *internal_element = NULL;
424
52.5M
  static char *function                              = "libcdata_list_element_set_previous_element";
425
426
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
427
  libcdata_list_element_t *backup_previous_element   = NULL;
428
#endif
429
430
52.5M
  if( element == NULL )
431
0
  {
432
0
    libcerror_error_set(
433
0
     error,
434
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
435
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
436
0
     "%s: invalid list element.",
437
0
     function );
438
439
0
    return( -1 );
440
0
  }
441
52.5M
  internal_element = (libcdata_internal_list_element_t *) element;
442
443
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
444
  if( libcthreads_read_write_lock_grab_for_write(
445
       internal_element->read_write_lock,
446
       error ) != 1 )
447
  {
448
    libcerror_error_set(
449
     error,
450
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
451
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
452
     "%s: unable to grab read/write lock for writing.",
453
     function );
454
455
    return( -1 );
456
  }
457
  backup_previous_element = internal_element->previous_element;
458
#endif
459
52.5M
  internal_element->previous_element = previous_element;
460
461
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
462
  if( libcthreads_read_write_lock_release_for_write(
463
       internal_element->read_write_lock,
464
       error ) != 1 )
465
  {
466
    libcerror_error_set(
467
     error,
468
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
469
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
470
     "%s: unable to release read/write lock for writing.",
471
     function );
472
473
    goto on_error;
474
  }
475
#endif
476
52.5M
  return( 1 );
477
478
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
479
on_error:
480
  internal_element->previous_element = backup_previous_element;
481
482
  return( -1 );
483
#endif
484
52.5M
}
485
486
/* Retrieves the next element from the list element
487
 * Returns 1 if successful or -1 on error
488
 */
489
int libcdata_list_element_get_next_element(
490
     libcdata_list_element_t *element,
491
     libcdata_list_element_t **next_element,
492
     libcerror_error_t **error )
493
139M
{
494
139M
  libcdata_internal_list_element_t *internal_element = NULL;
495
139M
  static char *function                              = "libcdata_list_element_get_next_element";
496
497
139M
  if( element == NULL )
498
0
  {
499
0
    libcerror_error_set(
500
0
     error,
501
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
502
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
503
0
     "%s: invalid list element.",
504
0
     function );
505
506
0
    return( -1 );
507
0
  }
508
139M
  internal_element = (libcdata_internal_list_element_t *) element;
509
510
139M
  if( next_element == NULL )
511
0
  {
512
0
    libcerror_error_set(
513
0
     error,
514
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
515
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
516
0
     "%s: invalid next element.",
517
0
     function );
518
519
0
    return( -1 );
520
0
  }
521
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
522
  if( libcthreads_read_write_lock_grab_for_read(
523
       internal_element->read_write_lock,
524
       error ) != 1 )
525
  {
526
    libcerror_error_set(
527
     error,
528
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
529
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
530
     "%s: unable to grab read/write lock for reading.",
531
     function );
532
533
    return( -1 );
534
  }
535
#endif
536
139M
  *next_element = internal_element->next_element;
537
538
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
539
  if( libcthreads_read_write_lock_release_for_read(
540
       internal_element->read_write_lock,
541
       error ) != 1 )
542
  {
543
    libcerror_error_set(
544
     error,
545
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
546
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
547
     "%s: unable to release read/write lock for reading.",
548
     function );
549
550
    return( -1 );
551
  }
552
#endif
553
139M
  return( 1 );
554
139M
}
555
556
/* Sets the next element in the list element
557
 * Returns 1 if successful or -1 on error
558
 */
559
int libcdata_list_element_set_next_element(
560
     libcdata_list_element_t *element,
561
     libcdata_list_element_t *next_element,
562
     libcerror_error_t **error )
563
52.5M
{
564
52.5M
  libcdata_internal_list_element_t *internal_element = NULL;
565
52.5M
  static char *function                              = "libcdata_list_element_set_next_element";
566
567
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
568
  libcdata_list_element_t *backup_next_element       = NULL;
569
#endif
570
571
52.5M
  if( element == NULL )
572
0
  {
573
0
    libcerror_error_set(
574
0
     error,
575
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
576
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
577
0
     "%s: invalid list element.",
578
0
     function );
579
580
0
    return( -1 );
581
0
  }
582
52.5M
  internal_element = (libcdata_internal_list_element_t *) element;
583
584
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
585
  if( libcthreads_read_write_lock_grab_for_write(
586
       internal_element->read_write_lock,
587
       error ) != 1 )
588
  {
589
    libcerror_error_set(
590
     error,
591
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
592
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
593
     "%s: unable to grab read/write lock for writing.",
594
     function );
595
596
    return( -1 );
597
  }
598
  backup_next_element = internal_element->next_element;
599
#endif
600
52.5M
  internal_element->next_element = next_element;
601
602
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
603
  if( libcthreads_read_write_lock_release_for_write(
604
       internal_element->read_write_lock,
605
       error ) != 1 )
606
  {
607
    libcerror_error_set(
608
     error,
609
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
610
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
611
     "%s: unable to release read/write lock for writing.",
612
     function );
613
614
    goto on_error;
615
  }
616
#endif
617
52.5M
  return( 1 );
618
619
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
620
on_error:
621
  internal_element->next_element = backup_next_element;
622
623
  return( -1 );
624
#endif
625
52.5M
}
626
627
/* Retrieves the previous and next element from the list element
628
 * Returns 1 if successful or -1 on error
629
 */
630
int libcdata_list_element_get_elements(
631
     libcdata_list_element_t *element,
632
     libcdata_list_element_t **previous_element,
633
     libcdata_list_element_t **next_element,
634
     libcerror_error_t **error )
635
3.51M
{
636
3.51M
  libcdata_internal_list_element_t *internal_element = NULL;
637
3.51M
  static char *function                              = "libcdata_list_element_get_elements";
638
639
3.51M
  if( element == NULL )
640
0
  {
641
0
    libcerror_error_set(
642
0
     error,
643
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
644
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
645
0
     "%s: invalid list element.",
646
0
     function );
647
648
0
    return( -1 );
649
0
  }
650
3.51M
  internal_element = (libcdata_internal_list_element_t *) element;
651
652
3.51M
  if( previous_element == NULL )
653
0
  {
654
0
    libcerror_error_set(
655
0
     error,
656
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
657
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
658
0
     "%s: invalid previous element.",
659
0
     function );
660
661
0
    return( -1 );
662
0
  }
663
3.51M
  if( next_element == NULL )
664
0
  {
665
0
    libcerror_error_set(
666
0
     error,
667
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
668
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
669
0
     "%s: invalid next element.",
670
0
     function );
671
672
0
    return( -1 );
673
0
  }
674
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
675
  if( libcthreads_read_write_lock_grab_for_read(
676
       internal_element->read_write_lock,
677
       error ) != 1 )
678
  {
679
    libcerror_error_set(
680
     error,
681
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
682
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
683
     "%s: unable to grab read/write lock for reading.",
684
     function );
685
686
    return( -1 );
687
  }
688
#endif
689
3.51M
  *previous_element = internal_element->previous_element;
690
3.51M
  *next_element     = internal_element->next_element;
691
692
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
693
  if( libcthreads_read_write_lock_release_for_read(
694
       internal_element->read_write_lock,
695
       error ) != 1 )
696
  {
697
    libcerror_error_set(
698
     error,
699
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
700
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
701
     "%s: unable to release read/write lock for reading.",
702
     function );
703
704
    return( -1 );
705
  }
706
#endif
707
3.51M
  return( 1 );
708
3.51M
}
709
710
/* Sets the previous and next element in the list element
711
 * Returns 1 if successful or -1 on error
712
 */
713
int libcdata_list_element_set_elements(
714
     libcdata_list_element_t *element,
715
     libcdata_list_element_t *previous_element,
716
     libcdata_list_element_t *next_element,
717
     libcerror_error_t **error )
718
1.12M
{
719
1.12M
  libcdata_internal_list_element_t *internal_element = NULL;
720
1.12M
  static char *function                              = "libcdata_list_element_set_elements";
721
722
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
723
  libcdata_list_element_t *backup_next_element       = NULL;
724
  libcdata_list_element_t *backup_previous_element   = NULL;
725
#endif
726
727
1.12M
  if( element == NULL )
728
0
  {
729
0
    libcerror_error_set(
730
0
     error,
731
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
732
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
733
0
     "%s: invalid list element.",
734
0
     function );
735
736
0
    return( -1 );
737
0
  }
738
1.12M
  internal_element = (libcdata_internal_list_element_t *) element;
739
740
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
741
  if( libcthreads_read_write_lock_grab_for_write(
742
       internal_element->read_write_lock,
743
       error ) != 1 )
744
  {
745
    libcerror_error_set(
746
     error,
747
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
748
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
749
     "%s: unable to grab read/write lock for writing.",
750
     function );
751
752
    return( -1 );
753
  }
754
  backup_previous_element = internal_element->previous_element;
755
  backup_next_element     = internal_element->next_element;
756
#endif
757
1.12M
  internal_element->previous_element = previous_element;
758
1.12M
  internal_element->next_element     = next_element;
759
760
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
761
  if( libcthreads_read_write_lock_release_for_write(
762
       internal_element->read_write_lock,
763
       error ) != 1 )
764
  {
765
    libcerror_error_set(
766
     error,
767
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
768
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
769
     "%s: unable to release read/write lock for writing.",
770
     function );
771
772
    goto on_error;
773
  }
774
#endif
775
1.12M
  return( 1 );
776
777
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
778
on_error:
779
  internal_element->previous_element = backup_previous_element;
780
  internal_element->next_element     = backup_next_element;
781
782
  return( -1 );
783
#endif
784
1.12M
}
785
786
/* Retrieves the value from the list element
787
 * Returns 1 if successful or -1 on error
788
 */
789
int libcdata_list_element_get_value(
790
     libcdata_list_element_t *element,
791
     intptr_t **value,
792
     libcerror_error_t **error )
793
164M
{
794
164M
  libcdata_internal_list_element_t *internal_element = NULL;
795
164M
  static char *function                              = "libcdata_list_element_get_value";
796
797
164M
  if( element == NULL )
798
0
  {
799
0
    libcerror_error_set(
800
0
     error,
801
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
802
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
803
0
     "%s: invalid list element.",
804
0
     function );
805
806
0
    return( -1 );
807
0
  }
808
164M
  internal_element = (libcdata_internal_list_element_t *) element;
809
810
164M
  if( value == NULL )
811
0
  {
812
0
    libcerror_error_set(
813
0
     error,
814
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
815
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
816
0
     "%s: invalid value.",
817
0
     function );
818
819
0
    return( -1 );
820
0
  }
821
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
822
  if( libcthreads_read_write_lock_grab_for_read(
823
       internal_element->read_write_lock,
824
       error ) != 1 )
825
  {
826
    libcerror_error_set(
827
     error,
828
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
829
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
830
     "%s: unable to grab read/write lock for reading.",
831
     function );
832
833
    return( -1 );
834
  }
835
#endif
836
164M
  *value = internal_element->value;
837
838
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
839
  if( libcthreads_read_write_lock_release_for_read(
840
       internal_element->read_write_lock,
841
       error ) != 1 )
842
  {
843
    libcerror_error_set(
844
     error,
845
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
846
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
847
     "%s: unable to release read/write lock for reading.",
848
     function );
849
850
    return( -1 );
851
  }
852
#endif
853
164M
  return( 1 );
854
164M
}
855
856
/* Sets the value in the list element
857
 * Returns 1 if successful or -1 on error
858
 */
859
int libcdata_list_element_set_value(
860
     libcdata_list_element_t *element,
861
     intptr_t *value,
862
     libcerror_error_t **error )
863
25.7M
{
864
25.7M
  libcdata_internal_list_element_t *internal_element = NULL;
865
25.7M
  static char *function                              = "libcdata_list_element_set_value";
866
867
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
868
  intptr_t *backup_value                             = NULL;
869
#endif
870
871
25.7M
  if( element == NULL )
872
0
  {
873
0
    libcerror_error_set(
874
0
     error,
875
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
876
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
877
0
     "%s: invalid list element.",
878
0
     function );
879
880
0
    return( -1 );
881
0
  }
882
25.7M
  internal_element = (libcdata_internal_list_element_t *) element;
883
884
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
885
  if( libcthreads_read_write_lock_grab_for_write(
886
       internal_element->read_write_lock,
887
       error ) != 1 )
888
  {
889
    libcerror_error_set(
890
     error,
891
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
892
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
893
     "%s: unable to grab read/write lock for writing.",
894
     function );
895
896
    return( -1 );
897
  }
898
  backup_value = internal_element->value;
899
#endif
900
25.7M
  internal_element->value = value;
901
902
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
903
  if( libcthreads_read_write_lock_release_for_write(
904
       internal_element->read_write_lock,
905
       error ) != 1 )
906
  {
907
    libcerror_error_set(
908
     error,
909
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
910
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
911
     "%s: unable to release read/write lock for writing.",
912
     function );
913
914
    goto on_error;
915
  }
916
#endif
917
25.7M
  return( 1 );
918
919
#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA )
920
on_error:
921
  internal_element->value = backup_value;
922
923
  return( -1 );
924
#endif
925
25.7M
}
926