Coverage Report

Created: 2026-04-04 07:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libsmraw/libsmraw/libsmraw_information_file.c
Line
Count
Source
1
/*
2
 * Information file functions
3
 *
4
 * Copyright (C) 2010-2025, 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 <file_stream.h>
24
#include <memory.h>
25
#include <narrow_string.h>
26
#include <system_string.h>
27
#include <types.h>
28
#include <wide_string.h>
29
30
#include "libsmraw_definitions.h"
31
#include "libsmraw_information_file.h"
32
#include "libsmraw_libcerror.h"
33
#include "libsmraw_libfvalue.h"
34
35
/* Creates an information file
36
 * Make sure the value information_file is referencing, is set to NULL
37
 * Returns 1 if successful or -1 on error
38
 */
39
int libsmraw_information_file_initialize(
40
     libsmraw_information_file_t **information_file,
41
     libcerror_error_t **error )
42
0
{
43
0
  static char *function = "libsmraw_information_file_initialize";
44
45
0
  if( information_file == NULL )
46
0
  {
47
0
    libcerror_error_set(
48
0
     error,
49
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51
0
     "%s: invalid information file.",
52
0
     function );
53
54
0
    return( -1 );
55
0
  }
56
0
  if( *information_file != NULL )
57
0
  {
58
0
    libcerror_error_set(
59
0
     error,
60
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
61
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62
0
     "%s: invalid information file value already set.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
0
  *information_file = memory_allocate_structure(
68
0
                       libsmraw_information_file_t );
69
70
0
  if( *information_file == NULL )
71
0
  {
72
0
    libcerror_error_set(
73
0
     error,
74
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
75
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
76
0
     "%s: unable to create information file.",
77
0
     function );
78
79
0
    goto on_error;
80
0
  }
81
0
  if( memory_set(
82
0
       *information_file,
83
0
       0,
84
0
       sizeof( libsmraw_information_file_t ) ) == NULL )
85
0
  {
86
0
    libcerror_error_set(
87
0
     error,
88
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
89
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
90
0
     "%s: unable to clear information file.",
91
0
     function );
92
93
0
    goto on_error;
94
0
  }
95
0
  return( 1 );
96
97
0
on_error:
98
0
  if( *information_file != NULL )
99
0
  {
100
0
    memory_free(
101
0
     *information_file );
102
103
0
    *information_file = NULL;
104
0
  }
105
0
  return( -1 );
106
0
}
107
108
/* Frees an information file
109
 * Returns 1 if successful or -1 on error
110
 */
111
int libsmraw_information_file_free(
112
     libsmraw_information_file_t **information_file,
113
     libcerror_error_t **error )
114
0
{
115
0
  static char *function = "libsmraw_information_file_free";
116
117
0
  if( information_file == NULL )
118
0
  {
119
0
    libcerror_error_set(
120
0
     error,
121
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
122
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
123
0
     "%s: invalid information file.",
124
0
     function );
125
126
0
    return( -1 );
127
0
  }
128
0
  if( *information_file != NULL )
129
0
  {
130
0
    if( ( *information_file )->name != NULL )
131
0
    {
132
0
      memory_free(
133
0
       ( *information_file )->name );
134
0
    }
135
0
    memory_free(
136
0
     *information_file );
137
138
0
    *information_file = NULL;
139
0
  }
140
0
  return( 1 );
141
0
}
142
143
/* Sets the filename
144
 * Returns 1 if successful or -1 on error
145
 */
146
int libsmraw_information_file_set_name(
147
     libsmraw_information_file_t *information_file,
148
     const system_character_t *name,
149
     size_t name_length,
150
     libcerror_error_t **error )
151
0
{
152
0
  static char *function = "libsmraw_information_file_set_name";
153
154
0
  if( information_file == NULL )
155
0
  {
156
0
    libcerror_error_set(
157
0
     error,
158
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
159
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
160
0
     "%s: invalid information file.",
161
0
     function );
162
163
0
    return( -1 );
164
0
  }
165
0
  if( name == NULL )
166
0
  {
167
0
    libcerror_error_set(
168
0
     error,
169
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
170
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
171
0
     "%s: invalid name.",
172
0
     function );
173
174
0
    return( -1 );
175
0
  }
176
0
  if( name_length > (size_t) SSIZE_MAX )
177
0
  {
178
0
    libcerror_error_set(
179
0
     error,
180
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
181
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
182
0
     "%s: invalid name length value exceeds maximum.",
183
0
     function );
184
185
0
    return( -1 );
186
0
  }
187
0
  information_file->name = system_string_allocate(
188
0
                            name_length + 1 );
189
190
0
  if( information_file->name == NULL )
191
0
  {
192
0
    libcerror_error_set(
193
0
     error,
194
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
195
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
196
0
     "%s: unable to allocate name.",
197
0
     function );
198
199
0
    return( -1 );
200
0
  }
201
0
  if( system_string_copy(
202
0
       information_file->name,
203
0
       name,
204
0
       name_length ) == NULL )
205
0
  {
206
0
    libcerror_error_set(
207
0
     error,
208
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
209
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
210
0
     "%s: unable to set name.",
211
0
     function );
212
213
0
    return( -1 );
214
0
  }
215
0
  information_file->name[ name_length ] = 0;
216
217
0
  information_file->name_size = name_length + 1;
218
219
0
  return( 1 );
220
0
}
221
222
/* Opens a information file
223
 * Returns 1 if successful or -1 on error
224
 */
225
int libsmraw_information_file_open(
226
     libsmraw_information_file_t *information_file,
227
     const system_character_t *filename,
228
     int access_flags,
229
     libcerror_error_t **error )
230
0
{
231
0
  const system_character_t *mode = NULL;
232
0
  static char *function          = "libsmraw_information_file_open";
233
234
0
  if( information_file == NULL )
235
0
  {
236
0
    libcerror_error_set(
237
0
     error,
238
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
239
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
240
0
     "%s: invalid information file.",
241
0
     function );
242
243
0
    return( -1 );
244
0
  }
245
0
  if( filename == NULL )
246
0
  {
247
0
    libcerror_error_set(
248
0
     error,
249
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
250
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
251
0
     "%s: invalid filename.",
252
0
     function );
253
254
0
    return( -1 );
255
0
  }
256
0
  if( information_file->file_stream != NULL )
257
0
  {
258
0
    libcerror_error_set(
259
0
     error,
260
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
261
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
262
0
     "%s: invalid information file - file stream already set.",
263
0
     function );
264
265
0
    return( -1 );
266
0
  }
267
0
  if( ( ( access_flags & LIBSMRAW_ACCESS_FLAG_READ ) == 0 )
268
0
   && ( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) == 0 ) )
269
0
  {
270
0
    libcerror_error_set(
271
0
     error,
272
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
273
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
274
0
     "%s: unsupported access flags.",
275
0
     function );
276
277
0
    return( -1 );
278
0
  }
279
0
  if( ( access_flags & LIBSMRAW_ACCESS_FLAG_WRITE ) != 0 )
280
0
  {
281
0
    mode = (system_character_t *) FILE_STREAM_OPEN_WRITE;
282
0
  }
283
0
  else
284
0
  {
285
0
    mode = (system_character_t *) FILE_STREAM_OPEN_READ;
286
0
  }
287
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
288
  information_file->file_stream = file_stream_open_wide(
289
                                   filename,
290
                                   mode );
291
#else
292
0
  information_file->file_stream = file_stream_open(
293
0
                                   filename,
294
0
                                   mode );
295
0
#endif
296
297
0
  if( information_file->file_stream == NULL )
298
0
  {
299
0
    libcerror_error_set(
300
0
     error,
301
0
     LIBCERROR_ERROR_DOMAIN_IO,
302
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
303
0
     "%s: unable to open: %" PRIs_SYSTEM ".",
304
0
     function,
305
0
     filename );
306
307
0
    return( -1 );
308
0
  }
309
0
  return( 1 );
310
0
}
311
312
/* Closes the information file
313
 * Returns the 0 if succesful or -1 on error
314
 */
315
int libsmraw_information_file_close(
316
     libsmraw_information_file_t *information_file,
317
     libcerror_error_t **error )
318
0
{
319
0
  static char *function = "libsmraw_information_file_close";
320
321
0
  if( information_file == NULL )
322
0
  {
323
0
    libcerror_error_set(
324
0
     error,
325
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
326
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
327
0
     "%s: invalid information file.",
328
0
     function );
329
330
0
    return( -1 );
331
0
  }
332
0
  if( information_file->name != NULL )
333
0
  {
334
0
    memory_free(
335
0
     information_file->name );
336
337
0
    information_file->name = NULL;
338
0
  }
339
0
  if( information_file->file_stream != NULL )
340
0
  {
341
0
    if( file_stream_close(
342
0
         information_file->file_stream ) != 0 )
343
0
    {
344
0
      libcerror_error_set(
345
0
       error,
346
0
       LIBCERROR_ERROR_DOMAIN_IO,
347
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
348
0
       "%s: unable to close file stream.",
349
0
       function );
350
351
0
      return( -1 );
352
0
    }
353
0
    information_file->file_stream = NULL;
354
0
  }
355
0
  return( 0 );
356
0
}
357
358
/* Reads a section with its values from the information file
359
 * Returns the 1 if succesful, 0 if no such section or -1 on error
360
 */
361
int libsmraw_information_file_read_section(
362
     libsmraw_information_file_t *information_file,
363
     const uint8_t *section_identifier,
364
     size_t section_identifier_length,
365
     libfvalue_table_t *values_table,
366
     libcerror_error_t **error )
367
0
{
368
0
  char input_string[ 128 ];
369
370
0
  libfvalue_value_t *value       = NULL;
371
0
  char *value_data               = NULL;
372
0
  char *value_identifier         = NULL;
373
0
  char *result_string            = NULL;
374
0
  static char *function          = "libsmraw_information_file_read_section";
375
0
  size_t input_string_index      = 0;
376
0
  size_t value_identifier_length = 0;
377
0
  size_t value_data_length       = 0;
378
0
  uint8_t in_section             = 0;
379
0
  int result                     = 0;
380
381
0
  if( information_file == NULL )
382
0
  {
383
0
    libcerror_error_set(
384
0
     error,
385
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
386
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
387
0
     "%s: invalid information file.",
388
0
     function );
389
390
0
    return( -1 );
391
0
  }
392
0
  if( information_file->file_stream == NULL )
393
0
  {
394
0
    libcerror_error_set(
395
0
     error,
396
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
397
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
398
0
     "%s: invalid information file - missing file stream.",
399
0
     function );
400
401
0
    return( -1 );
402
0
  }
403
0
  if( section_identifier == NULL )
404
0
  {
405
0
    libcerror_error_set(
406
0
     error,
407
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
408
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
409
0
     "%s: invalid section identifier.",
410
0
     function );
411
412
0
    return( -1 );
413
0
  }
414
0
  if( section_identifier_length > (size_t) SSIZE_MAX )
415
0
  {
416
0
    libcerror_error_set(
417
0
     error,
418
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
419
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
420
0
     "%s: invalid section identifier length value exceeds maximum.",
421
0
     function );
422
423
0
    return( -1 );
424
0
  }
425
  /* Reset the offset to start of the file stream
426
   */
427
0
  if( file_stream_seek_offset(
428
0
       information_file->file_stream,
429
0
       0,
430
0
       SEEK_SET ) != 0 )
431
0
  {
432
0
    libcerror_error_set(
433
0
     error,
434
0
     LIBCERROR_ERROR_DOMAIN_IO,
435
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
436
0
     "%s: unable to seek stream offset: 0.",
437
0
     function );
438
439
0
    return( -1 );
440
0
  }
441
0
  while( file_stream_at_end(
442
0
          information_file->file_stream ) == 0 )
443
0
  {
444
0
    result_string = file_stream_get_string(
445
0
                     information_file->file_stream,
446
0
                     input_string,
447
0
                     128 );
448
449
0
    if( result_string == NULL )
450
0
    {
451
0
      if( file_stream_at_end(
452
0
           information_file->file_stream ) != 0 )
453
0
      {
454
0
        break;
455
0
      }
456
0
      libcerror_error_set(
457
0
       error,
458
0
       LIBCERROR_ERROR_DOMAIN_IO,
459
0
       LIBCERROR_IO_ERROR_READ_FAILED,
460
0
       "%s: error reading string from file stream.",
461
0
       function );
462
463
0
      return( -1 );
464
0
    }
465
    /* Skip leading white space
466
     */
467
0
    for( input_string_index = 0;
468
0
         input_string_index < 128;
469
0
         input_string_index++ )
470
0
    {
471
0
      if( ( input_string[ input_string_index ] != '\t' )
472
0
       && ( input_string[ input_string_index ] != '\n' )
473
0
       && ( input_string[ input_string_index ] != '\f' )
474
0
       && ( input_string[ input_string_index ] != '\v' )
475
0
       && ( input_string[ input_string_index ] != '\r' )
476
0
       && ( input_string[ input_string_index ] != ' ' ) )
477
0
      {
478
0
        break;
479
0
      }
480
0
    }
481
    /* Skip an empty line
482
     */
483
0
    if( input_string[ input_string_index ] == 0 )
484
0
    {
485
0
      continue;
486
0
    }
487
0
    if( in_section != 0 )
488
0
    {
489
      /* Check for the end of the section
490
       */
491
0
      if( ( ( input_string_index + section_identifier_length + 2 ) < 128 )
492
0
       && ( input_string[ input_string_index ] == '<' )
493
0
       && ( input_string[ input_string_index + 1 ] == '/' )
494
0
       && ( narrow_string_compare(
495
0
             &( input_string[ input_string_index + 2 ] ),
496
0
             section_identifier,
497
0
             section_identifier_length ) == 0 )
498
0
       && ( input_string[ input_string_index + section_identifier_length + 2 ] == '>' ) )
499
0
      {
500
0
        in_section = 0;
501
0
        result     = 1;
502
503
0
        break;
504
0
      }
505
0
      if( input_string[ input_string_index ] == '<' )
506
0
      {
507
        /* Determine the value identifier
508
         */
509
0
        input_string_index++;
510
511
0
        value_identifier        = &( input_string[ input_string_index ] );
512
0
        value_identifier_length = 0;
513
514
0
        while( input_string_index < 128 )
515
0
        {
516
0
          if( ( ( input_string[ input_string_index ] >= 'A' )
517
0
            &&  ( input_string[ input_string_index ] <= 'I' ) )
518
0
           || ( ( input_string[ input_string_index ] >= 'J' )
519
0
            &&  ( input_string[ input_string_index ] <= 'R' ) )
520
0
           || ( ( input_string[ input_string_index ] >= 'S' )
521
0
            &&  ( input_string[ input_string_index ] <= 'Z' ) )
522
0
           || ( ( input_string[ input_string_index ] >= 'a' )
523
0
            &&  ( input_string[ input_string_index ] <= 'i' ) )
524
0
           || ( ( input_string[ input_string_index ] >= 'j' )
525
0
            &&  ( input_string[ input_string_index ] <= 'r' ) )
526
0
           || ( ( input_string[ input_string_index ] >= 's' )
527
0
            &&  ( input_string[ input_string_index ] <= 'z' ) )
528
0
           || ( ( input_string[ input_string_index ] >= '0' )
529
0
            &&  ( input_string[ input_string_index ] <= '9' ) )
530
0
           ||   ( input_string[ input_string_index ] == '_' ) )
531
0
          {
532
0
            value_identifier_length++;
533
0
          }
534
0
          else
535
0
          {
536
0
            break;
537
0
          }
538
0
          input_string_index++;
539
0
        }
540
0
        if( input_string_index >= 128 )
541
0
        {
542
0
          break;
543
0
        }
544
        /* Check if there is a supported value identifier
545
         */
546
0
        if( input_string[ input_string_index ] != '>' )
547
0
        {
548
0
          continue;
549
0
        }
550
        /* Make sure the value identifier is terminated by an end of string character
551
         */
552
0
        input_string[ input_string_index ] = 0;
553
554
        /* Determine the value
555
         */
556
0
        input_string_index++;
557
558
0
        value_data        = &( input_string[ input_string_index ] );
559
0
        value_data_length = 0;
560
561
0
        while( input_string_index < 128 )
562
0
        {
563
0
          if( ( input_string[ input_string_index ] == 0 )
564
0
           || ( input_string[ input_string_index ] == '<' ) )
565
0
          {
566
0
            break;
567
0
          }
568
0
          value_data_length++;
569
570
0
          input_string_index++;
571
0
        }
572
0
        if( input_string_index >= 128 )
573
0
        {
574
0
          break;
575
0
        }
576
        /* Check if there is a supported value
577
         */
578
0
        if( input_string[ input_string_index ] != '<' )
579
0
        {
580
0
          continue;
581
0
        }
582
        /* Make sure the value data is terminated by an end of string
583
         */
584
0
        input_string[ input_string_index ] = 0;
585
586
        /* Check the value identifier
587
         */
588
0
        input_string_index++;
589
590
0
        if( ( ( input_string_index + value_identifier_length + 2 ) >= 128 )
591
0
         || ( input_string[ input_string_index ] != '/' )
592
0
         || ( narrow_string_compare(
593
0
               &( input_string[ input_string_index + 1 ] ),
594
0
               value_identifier,
595
0
               value_identifier_length ) != 0 )
596
0
         || ( input_string[ input_string_index + value_identifier_length + 1 ] != '>' ) )
597
0
        {
598
0
          continue;
599
0
        }
600
0
        if( libfvalue_value_type_initialize(
601
0
             &value,
602
0
             LIBFVALUE_VALUE_TYPE_STRING_UTF8,
603
0
             error ) != 1 )
604
0
        {
605
0
          libcerror_error_set(
606
0
           error,
607
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
608
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
609
0
           "%s: unable to create value: %s.",
610
0
           function,
611
0
           value_identifier );
612
613
0
          goto on_error;
614
0
        }
615
0
        if( libfvalue_value_set_identifier(
616
0
             value,
617
0
             (uint8_t *) value_identifier,
618
0
             value_identifier_length,
619
0
             LIBFVALUE_VALUE_IDENTIFIER_FLAG_MANAGED,
620
0
             error ) != 1 )
621
0
        {
622
0
          libcerror_error_set(
623
0
           error,
624
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
625
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
626
0
           "%s: unable to set identifier in value: %d.",
627
0
           function,
628
0
           value_identifier );
629
630
0
          goto on_error;
631
0
        }
632
0
        if( libfvalue_value_set_data(
633
0
             value,
634
0
             (uint8_t *) value_data,
635
0
             value_data_length + 1,
636
0
             LIBFVALUE_ENDIAN_NATIVE,
637
0
             LIBFVALUE_VALUE_FLAG_DATA_MANAGED,
638
0
             error ) != 1 )
639
0
        {
640
0
          libcerror_error_set(
641
0
           error,
642
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
643
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
644
0
           "%s: unable to set value: %s data.",
645
0
           function,
646
0
           value_identifier );
647
648
0
          goto on_error;
649
0
        }
650
0
        if( libfvalue_table_set_value(
651
0
             values_table,
652
0
             value,
653
0
             error ) != 1 )
654
0
        {
655
0
          libcerror_error_set(
656
0
           error,
657
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
658
0
           LIBCERROR_RUNTIME_ERROR_SET_FAILED,
659
0
           "%s: unable to set value: %s in values table.",
660
0
           function,
661
0
           value_identifier );
662
663
0
          goto on_error;
664
0
        }
665
0
        value = NULL;
666
0
      }
667
0
    }
668
0
    else
669
0
    {
670
      /* Check for the start of the section
671
       */
672
0
      if( ( ( input_string_index + section_identifier_length + 1 ) < 128 )
673
0
       && ( input_string[ input_string_index ] == '<' )
674
0
       && ( narrow_string_compare(
675
0
             &( input_string[ input_string_index + 1 ] ),
676
0
             section_identifier,
677
0
             section_identifier_length ) == 0 )
678
0
       && ( input_string[ input_string_index + section_identifier_length + 1 ] == '>' ) )
679
0
      {
680
0
        in_section = 1;
681
0
      }
682
0
    }
683
0
  }
684
0
  return( result );
685
686
0
on_error:
687
0
  if( value != NULL )
688
0
  {
689
0
    libfvalue_value_free(
690
0
     &value,
691
0
     NULL );
692
0
  }
693
0
  return( -1 );
694
0
}
695
696
/* Write a section with its values to the information file
697
 * Returns the 1 if succesful or -1 on error
698
 */
699
int libsmraw_information_file_write_section(
700
     libsmraw_information_file_t *information_file,
701
     const uint8_t *section_identifier,
702
     size_t section_identifier_length,
703
     libfvalue_table_t *values_table,
704
     libcerror_error_t **error )
705
0
{
706
0
  libfvalue_value_t *value = NULL;
707
0
  static char *function    = "libsmraw_information_file_write_section";
708
0
  ssize_t write_count      = 0;
709
0
  int number_of_values     = 0;
710
0
  int print_count          = 0;
711
0
  int result               = 1;
712
0
  int value_iterator       = 0;
713
714
0
  if( information_file == NULL )
715
0
  {
716
0
    libcerror_error_set(
717
0
     error,
718
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
719
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
720
0
     "%s: invalid information file.",
721
0
     function );
722
723
0
    return( -1 );
724
0
  }
725
0
  if( information_file->file_stream == NULL )
726
0
  {
727
0
    libcerror_error_set(
728
0
     error,
729
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
730
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
731
0
     "%s: invalid information file - missing file stream.",
732
0
     function );
733
734
0
    return( -1 );
735
0
  }
736
0
  if( section_identifier == NULL )
737
0
  {
738
0
    libcerror_error_set(
739
0
     error,
740
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
741
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
742
0
     "%s: invalid section identifier.",
743
0
     function );
744
745
0
    return( -1 );
746
0
  }
747
0
  if( section_identifier_length > (size_t) SSIZE_MAX )
748
0
  {
749
0
    libcerror_error_set(
750
0
     error,
751
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
752
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
753
0
     "%s: invalid section identifier length value exceeds maximum.",
754
0
     function );
755
756
0
    return( -1 );
757
0
  }
758
0
  if( values_table == NULL )
759
0
  {
760
0
    libcerror_error_set(
761
0
     error,
762
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
763
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
764
0
     "%s: invalid values table.",
765
0
     function );
766
767
0
    return( -1 );
768
0
  }
769
  /* Write section start
770
   */
771
0
  print_count = fprintf(
772
0
                 information_file->file_stream,
773
0
                 "<%s>\n",
774
0
                 section_identifier );
775
776
0
  if( ( print_count < 0 )
777
0
   || ( (size_t) print_count > ( section_identifier_length + 3 ) ) )
778
0
  {
779
0
    libcerror_error_set(
780
0
     error,
781
0
     LIBCERROR_ERROR_DOMAIN_IO,
782
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
783
0
     "%s: unable to write section start to file stream.",
784
0
     function );
785
786
0
    return( -1 );
787
0
  }
788
  /* Write section values
789
   */
790
0
  if( libfvalue_table_get_number_of_values(
791
0
       values_table,
792
0
       &number_of_values,
793
0
       error ) != 1 )
794
0
  {
795
0
    libcerror_error_set(
796
0
     error,
797
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
798
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
799
0
     "%s: unable to retrieve number of values.",
800
0
     function );
801
802
0
    return( -1 );
803
0
  }
804
0
  for( value_iterator = 0;
805
0
       value_iterator < number_of_values;
806
0
       value_iterator++ )
807
0
  {
808
0
    print_count = fprintf(
809
0
             information_file->file_stream,
810
0
             "\t" );
811
812
0
    if( ( print_count < 0 )
813
0
     || ( (size_t) print_count > 1 ) )
814
0
    {
815
0
      libcerror_error_set(
816
0
       error,
817
0
       LIBCERROR_ERROR_DOMAIN_IO,
818
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
819
0
       "%s: unable to write to file stream.",
820
0
       function );
821
822
0
      return( -1 );
823
0
    }
824
0
    if( libfvalue_table_get_value_by_index(
825
0
         values_table,
826
0
         value_iterator,
827
0
         &value,
828
0
         error ) != 1 )
829
0
    {
830
0
      libcerror_error_set(
831
0
       error,
832
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
833
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
834
0
       "%s: unable to retrieve value: %d from values table.",
835
0
       function,
836
0
       value_iterator );
837
838
0
      result = -1;
839
840
0
      continue;
841
0
    }
842
0
    write_count = libfvalue_value_write_to_file_stream(
843
0
                   value,
844
0
                   information_file->file_stream,
845
0
                   error );
846
847
0
    if( write_count <= 0 )
848
0
    {
849
0
      libcerror_error_set(
850
0
       error,
851
0
       LIBCERROR_ERROR_DOMAIN_IO,
852
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
853
0
       "%s: unable to write value: %d to file stream.",
854
0
       function,
855
0
       value_iterator );
856
857
0
      result = -1;
858
0
    }
859
0
    print_count = fprintf(
860
0
             information_file->file_stream,
861
0
             "\n" );
862
863
0
    if( ( print_count < 0 )
864
0
     || ( (size_t) print_count > 1 ) )
865
0
    {
866
0
      libcerror_error_set(
867
0
       error,
868
0
       LIBCERROR_ERROR_DOMAIN_IO,
869
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
870
0
       "%s: unable to write to file stream.",
871
0
       function );
872
873
0
      return( -1 );
874
0
    }
875
0
  }
876
  /* Write section end
877
   */
878
0
  print_count = fprintf(
879
0
                 information_file->file_stream,
880
0
                 "</%s>\n\n",
881
0
                 section_identifier );
882
883
0
  if( ( print_count < 0 )
884
0
   || ( (size_t) print_count > ( section_identifier_length + 5 ) ) )
885
0
  {
886
0
    libcerror_error_set(
887
0
     error,
888
0
     LIBCERROR_ERROR_DOMAIN_IO,
889
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
890
0
     "%s: unable to write section end to file stream.",
891
0
     function );
892
893
0
    return( -1 );
894
0
  }
895
0
  return( result );
896
0
}
897