1 /*
2 * Split wide string functions
3 *
4 * Copyright (C) 2008-2018, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This software 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 software 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 software. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <memory.h>
24 #include <wide_string.h>
25 #include <types.h>
26
27 #include "libcsplit_libcerror.h"
28 #include "libcsplit_wide_split_string.h"
29 #include "libcsplit_types.h"
30
31 #if defined( HAVE_WIDE_CHARACTER_TYPE )
32
33 /* Creates a split string
34 * Make sure the value split_string is referencing, is set to NULL
35 * Returns 1 if successful or -1 on error
36 */
libcsplit_wide_split_string_initialize(libcsplit_wide_split_string_t ** split_string,const wchar_t * string,size_t string_size,int number_of_segments,libcerror_error_t ** error)37 int libcsplit_wide_split_string_initialize(
38 libcsplit_wide_split_string_t **split_string,
39 const wchar_t *string,
40 size_t string_size,
41 int number_of_segments,
42 libcerror_error_t **error )
43 {
44 libcsplit_internal_wide_split_string_t *internal_split_string = NULL;
45 static char *function = "libcsplit_wide_split_string_initialize";
46
47 if( split_string == NULL )
48 {
49 libcerror_error_set(
50 error,
51 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53 "%s: invalid split string.",
54 function );
55
56 return( -1 );
57 }
58 if( *split_string != NULL )
59 {
60 libcerror_error_set(
61 error,
62 LIBCERROR_ERROR_DOMAIN_RUNTIME,
63 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64 "%s: invalid split string value already set.",
65 function );
66
67 return( -1 );
68 }
69 if( number_of_segments < 0 )
70 {
71 libcerror_error_set(
72 error,
73 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
74 LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
75 "%s: invalid number of segments less than zero.",
76 function );
77
78 return( -1 );
79 }
80 internal_split_string = memory_allocate_structure(
81 libcsplit_internal_wide_split_string_t );
82
83 if( internal_split_string == NULL )
84 {
85 libcerror_error_set(
86 error,
87 LIBCERROR_ERROR_DOMAIN_MEMORY,
88 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
89 "%s: unable to create split string.",
90 function );
91
92 goto on_error;
93 }
94 if( memory_set(
95 internal_split_string,
96 0,
97 sizeof( libcsplit_internal_wide_split_string_t ) ) == NULL )
98 {
99 libcerror_error_set(
100 error,
101 LIBCERROR_ERROR_DOMAIN_MEMORY,
102 LIBCERROR_MEMORY_ERROR_SET_FAILED,
103 "%s: unable to clear split string.",
104 function );
105
106 memory_free(
107 internal_split_string );
108
109 return( -1 );
110 }
111 if( ( string != NULL )
112 && ( string_size > 0 ) )
113 {
114 internal_split_string->string = wide_string_allocate(
115 string_size );
116
117 if( internal_split_string->string == NULL )
118 {
119 libcerror_error_set(
120 error,
121 LIBCERROR_ERROR_DOMAIN_MEMORY,
122 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
123 "%s: unable to create string.",
124 function );
125
126 goto on_error;
127 }
128 if( memory_copy(
129 internal_split_string->string,
130 string,
131 sizeof( wchar_t ) * ( string_size - 1 ) ) == NULL )
132 {
133 libcerror_error_set(
134 error,
135 LIBCERROR_ERROR_DOMAIN_MEMORY,
136 LIBCERROR_MEMORY_ERROR_SET_FAILED,
137 "%s: unable to copy string.",
138 function );
139
140 goto on_error;
141 }
142 internal_split_string->string[ string_size - 1 ] = 0;
143 internal_split_string->string_size = string_size;
144 }
145 if( number_of_segments > 0 )
146 {
147 internal_split_string->segments = (wchar_t **) memory_allocate(
148 sizeof( wchar_t * ) * number_of_segments );
149
150 if( internal_split_string->segments == NULL )
151 {
152 libcerror_error_set(
153 error,
154 LIBCERROR_ERROR_DOMAIN_MEMORY,
155 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
156 "%s: unable to create segments.",
157 function );
158
159 goto on_error;
160 }
161 if( memory_set(
162 internal_split_string->segments,
163 0,
164 sizeof( wchar_t * ) * number_of_segments ) == NULL )
165 {
166 libcerror_error_set(
167 error,
168 LIBCERROR_ERROR_DOMAIN_MEMORY,
169 LIBCERROR_MEMORY_ERROR_SET_FAILED,
170 "%s: unable to clear segments.",
171 function );
172
173 goto on_error;
174 }
175 internal_split_string->segment_sizes = (size_t *) memory_allocate(
176 sizeof( size_t ) * number_of_segments );
177
178 if( internal_split_string->segment_sizes == NULL )
179 {
180 libcerror_error_set(
181 error,
182 LIBCERROR_ERROR_DOMAIN_MEMORY,
183 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
184 "%s: unable to create segment sizes.",
185 function );
186
187 goto on_error;
188 }
189 if( memory_set(
190 internal_split_string->segment_sizes,
191 0,
192 sizeof( size_t ) * number_of_segments ) == NULL )
193 {
194 libcerror_error_set(
195 error,
196 LIBCERROR_ERROR_DOMAIN_MEMORY,
197 LIBCERROR_MEMORY_ERROR_SET_FAILED,
198 "%s: unable to clear segment sizes.",
199 function );
200
201 goto on_error;
202 }
203 }
204 internal_split_string->number_of_segments = number_of_segments;
205
206 *split_string = (libcsplit_wide_split_string_t *) internal_split_string;
207
208 return( 1 );
209
210 on_error:
211 if( internal_split_string != NULL )
212 {
213 if( internal_split_string->segment_sizes != NULL )
214 {
215 memory_free(
216 internal_split_string->segment_sizes );
217 }
218 if( internal_split_string->segments != NULL )
219 {
220 memory_free(
221 internal_split_string->segments );
222 }
223 if( internal_split_string->string != NULL )
224 {
225 memory_free(
226 internal_split_string->string );
227 }
228 memory_free(
229 internal_split_string );
230 }
231 return( -1 );
232 }
233
234 /* Frees a split string
235 * Returns 1 if successful or -1 on error
236 */
libcsplit_wide_split_string_free(libcsplit_wide_split_string_t ** split_string,libcerror_error_t ** error)237 int libcsplit_wide_split_string_free(
238 libcsplit_wide_split_string_t **split_string,
239 libcerror_error_t **error )
240 {
241 libcsplit_internal_wide_split_string_t *internal_split_string = NULL;
242 static char *function = "libcsplit_wide_split_string_free";
243
244 if( split_string == NULL )
245 {
246 libcerror_error_set(
247 error,
248 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
249 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
250 "%s: invalid split string.",
251 function );
252
253 return( -1 );
254 }
255 if( *split_string != NULL )
256 {
257 internal_split_string = (libcsplit_internal_wide_split_string_t *) *split_string;
258 *split_string = NULL;
259
260 if( internal_split_string->string != NULL )
261 {
262 memory_free(
263 internal_split_string->string );
264 }
265 if( internal_split_string->segments != NULL )
266 {
267 memory_free(
268 internal_split_string->segments );
269 }
270 if( internal_split_string->segment_sizes != NULL )
271 {
272 memory_free(
273 internal_split_string->segment_sizes );
274 }
275 memory_free(
276 internal_split_string );
277 }
278 return( 1 );
279 }
280
281 /* Retrieves the string
282 * Returns 1 if successful or -1 on error
283 */
libcsplit_wide_split_string_get_string(libcsplit_wide_split_string_t * split_string,wchar_t ** string,size_t * string_size,libcerror_error_t ** error)284 int libcsplit_wide_split_string_get_string(
285 libcsplit_wide_split_string_t *split_string,
286 wchar_t **string,
287 size_t *string_size,
288 libcerror_error_t **error )
289 {
290 libcsplit_internal_wide_split_string_t *internal_split_string = NULL;
291 static char *function = "libcsplit_wide_split_string_get_string";
292
293 if( split_string == NULL )
294 {
295 libcerror_error_set(
296 error,
297 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
298 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
299 "%s: invalid split string.",
300 function );
301
302 return( -1 );
303 }
304 internal_split_string = (libcsplit_internal_wide_split_string_t *) split_string;
305
306 if( string == NULL )
307 {
308 libcerror_error_set(
309 error,
310 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
311 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
312 "%s: invalid string.",
313 function );
314
315 return( -1 );
316 }
317 if( string_size == NULL )
318 {
319 libcerror_error_set(
320 error,
321 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
322 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
323 "%s: invalid string size.",
324 function );
325
326 return( -1 );
327 }
328 *string = internal_split_string->string;
329 *string_size = internal_split_string->string_size;
330
331 return( 1 );
332 }
333
334 /* Retrieves the number of segments
335 * Returns 1 if successful or -1 on error
336 */
libcsplit_wide_split_string_get_number_of_segments(libcsplit_wide_split_string_t * split_string,int * number_of_segments,libcerror_error_t ** error)337 int libcsplit_wide_split_string_get_number_of_segments(
338 libcsplit_wide_split_string_t *split_string,
339 int *number_of_segments,
340 libcerror_error_t **error )
341 {
342 libcsplit_internal_wide_split_string_t *internal_split_string = NULL;
343 static char *function = "libcsplit_wide_split_string_get_number_of_segments";
344
345 if( split_string == NULL )
346 {
347 libcerror_error_set(
348 error,
349 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
350 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
351 "%s: invalid split string.",
352 function );
353
354 return( -1 );
355 }
356 internal_split_string = (libcsplit_internal_wide_split_string_t *) split_string;
357
358 if( number_of_segments == NULL )
359 {
360 libcerror_error_set(
361 error,
362 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
363 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
364 "%s: invalid number of segments.",
365 function );
366
367 return( -1 );
368 }
369 *number_of_segments = internal_split_string->number_of_segments;
370
371 return( 1 );
372 }
373
374 /* Retrieves a specific segment
375 * Returns 1 if successful or -1 on error
376 */
libcsplit_wide_split_string_get_segment_by_index(libcsplit_wide_split_string_t * split_string,int segment_index,wchar_t ** string_segment,size_t * string_segment_size,libcerror_error_t ** error)377 int libcsplit_wide_split_string_get_segment_by_index(
378 libcsplit_wide_split_string_t *split_string,
379 int segment_index,
380 wchar_t **string_segment,
381 size_t *string_segment_size,
382 libcerror_error_t **error )
383 {
384 libcsplit_internal_wide_split_string_t *internal_split_string = NULL;
385 static char *function = "libcsplit_wide_split_string_get_segment_by_index";
386
387 if( split_string == NULL )
388 {
389 libcerror_error_set(
390 error,
391 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
392 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
393 "%s: invalid split string.",
394 function );
395
396 return( -1 );
397 }
398 internal_split_string = (libcsplit_internal_wide_split_string_t *) split_string;
399
400 if( ( segment_index < 0 )
401 || ( segment_index >= internal_split_string->number_of_segments ) )
402 {
403 libcerror_error_set(
404 error,
405 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
406 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
407 "%s: invalid segment index value out of bounds.",
408 function );
409
410 return( -1 );
411 }
412 if( string_segment == NULL )
413 {
414 libcerror_error_set(
415 error,
416 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
417 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
418 "%s: invalid string segment.",
419 function );
420
421 return( -1 );
422 }
423 if( string_segment_size == NULL )
424 {
425 libcerror_error_set(
426 error,
427 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
428 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
429 "%s: invalid string segment size.",
430 function );
431
432 return( -1 );
433 }
434 *string_segment = internal_split_string->segments[ segment_index ];
435 *string_segment_size = internal_split_string->segment_sizes[ segment_index ];
436
437 return( 1 );
438 }
439
440 /* Sets a specific segment
441 * Returns 1 if successful or -1 on error
442 */
libcsplit_wide_split_string_set_segment_by_index(libcsplit_wide_split_string_t * split_string,int segment_index,wchar_t * string_segment,size_t string_segment_size,libcerror_error_t ** error)443 int libcsplit_wide_split_string_set_segment_by_index(
444 libcsplit_wide_split_string_t *split_string,
445 int segment_index,
446 wchar_t *string_segment,
447 size_t string_segment_size,
448 libcerror_error_t **error )
449 {
450 libcsplit_internal_wide_split_string_t *internal_split_string = NULL;
451 static char *function = "libcsplit_wide_split_string_set_segment_by_index";
452 size_t string_segment_offset = 0;
453
454 if( split_string == NULL )
455 {
456 libcerror_error_set(
457 error,
458 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
459 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
460 "%s: invalid split string.",
461 function );
462
463 return( -1 );
464 }
465 internal_split_string = (libcsplit_internal_wide_split_string_t *) split_string;
466
467 if( ( segment_index < 0 )
468 || ( segment_index >= internal_split_string->number_of_segments ) )
469 {
470 libcerror_error_set(
471 error,
472 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
473 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
474 "%s: invalid segment index value out of bounds.",
475 function );
476
477 return( -1 );
478 }
479 if( string_segment_size > (size_t) SSIZE_MAX )
480 {
481 libcerror_error_set(
482 error,
483 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
484 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
485 "%s: invalid string segment size value exceeds maximum.",
486 function );
487
488 return( -1 );
489 }
490 if( string_segment == NULL )
491 {
492 if( string_segment_size != 0 )
493 {
494 libcerror_error_set(
495 error,
496 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
497 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
498 "%s: invalid string segment size value out of bounds.",
499 function );
500
501 return( -1 );
502 }
503 }
504 else
505 {
506 if( string_segment < internal_split_string->string )
507 {
508 libcerror_error_set(
509 error,
510 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
511 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
512 "%s: invalid string segment value out of bounds.",
513 function );
514
515 return( -1 );
516 }
517 string_segment_offset = (size_t) ( string_segment - internal_split_string->string );
518
519 if( string_segment_offset >= internal_split_string->string_size )
520 {
521 libcerror_error_set(
522 error,
523 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
524 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
525 "%s: invalid string segment value out of bounds.",
526 function );
527
528 return( -1 );
529 }
530 string_segment_offset += string_segment_size;
531
532 if( string_segment_offset > internal_split_string->string_size )
533 {
534 libcerror_error_set(
535 error,
536 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
537 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
538 "%s: invalid string segment value out of bounds.",
539 function );
540
541 return( -1 );
542 }
543 }
544 internal_split_string->segments[ segment_index ] = string_segment;
545 internal_split_string->segment_sizes[ segment_index ] = string_segment_size;
546
547 return( 1 );
548 }
549
550 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
551
552