1 /*
2 * Empty block test functions
3 *
4 * Copyright (c) 2006-2014, 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 "libewf_empty_block.h"
27 #include "libewf_libcerror.h"
28
29 /* Check for empty block
30 * An empty block is a block that contains the same value for every byte
31 * Returns 1 if block is empty, 0 if not or -1 on error
32 */
libewf_empty_block_test(const uint8_t * block_buffer,size_t block_size,libcerror_error_t ** error)33 int libewf_empty_block_test(
34 const uint8_t *block_buffer,
35 size_t block_size,
36 libcerror_error_t **error )
37 {
38 static char *function = "libewf_empty_block_test";
39
40 if( block_buffer == NULL )
41 {
42 libcerror_error_set(
43 error,
44 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
45 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
46 "%s: invalid block buffer.",
47 function );
48
49 return( -1 );
50 }
51 if( block_size > (size_t) SSIZE_MAX )
52 {
53 libcerror_error_set(
54 error,
55 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
56 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
57 "%s: invalid block size value exceeds maximum.",
58 function );
59
60 return( -1 );
61 }
62 if( block_size == 0 )
63 {
64 return( 0 );
65 }
66 else if( block_size == 1 )
67 {
68 return( 1 );
69 }
70 if( memory_compare(
71 block_buffer,
72 &( block_buffer[ 1 ] ),
73 block_size - 1 ) != 0 )
74 {
75 return( 0 );
76 }
77 return( 1 );
78 }
79
80 /* Previous version keep for now */
81 #ifdef TEST_EMPTY_BLOCK_MEMCMP
82
83 /* The largest primary (or scalar) available
84 * supported by a single load and store instruction
85 */
86 typedef unsigned long int libewf_aligned_t;
87
88 /* Check for empty block
89 * An empty block is a block that contains the same value for every byte
90 * Returns 1 if block is empty, 0 if not or -1 on error
91 */
libewf_empty_block_test(const uint8_t * block_buffer,size_t block_size,libcerror_error_t ** error)92 int libewf_empty_block_test(
93 const uint8_t *block_buffer,
94 size_t block_size,
95 libcerror_error_t **error )
96 {
97 uint8_t *block_iterator = NULL;
98 uint8_t *block_start = NULL;
99 static char *function = "libewf_empty_block_test";
100 size_t aligned_block_size = 0;
101
102 if( block_buffer == NULL )
103 {
104 libcerror_error_set(
105 error,
106 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
107 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
108 "%s: invalid block buffer.",
109 function );
110
111 return( -1 );
112 }
113 if( block_size > (size_t) SSIZE_MAX )
114 {
115 libcerror_error_set(
116 error,
117 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
118 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
119 "%s: invalid block size value exceeds maximum.",
120 function );
121
122 return( -1 );
123 }
124 block_start = (uint8_t *) block_buffer;
125 block_iterator = (uint8_t *) block_buffer + 1;
126 block_size -= 1;
127
128 /* Only optimize for blocks larger than the alignment
129 */
130 if( block_size > ( 2 * sizeof( libewf_aligned_t ) ) )
131 {
132 /* Align the block start
133 */
134 while( ( (intptr_t) block_start % sizeof( libewf_aligned_t ) ) != 0 )
135 {
136 if( *block_start != *block_iterator )
137 {
138 return( 0 );
139 }
140 block_start += 1;
141 block_iterator += 1;
142 block_size -= 1;
143 }
144 aligned_block_size = ( block_size / sizeof( libewf_aligned_t ) ) * sizeof( libewf_aligned_t );
145
146 if( memory_compare(
147 block_start,
148 &( block_start[ sizeof( libewf_aligned_t ) ] ),
149 aligned_block_size - sizeof( libewf_aligned_t ) ) != 0 )
150 {
151 return( 0 );
152 }
153 block_iterator = &( block_start[ aligned_block_size ] );
154 block_size -= aligned_block_size;
155 }
156 while( block_size != 0 )
157 {
158 if( *block_start != *block_iterator )
159 {
160 return( 0 );
161 }
162 block_iterator += 1;
163 block_size -= 1;
164 }
165 return( 1 );
166 }
167
168 #endif /* TEST_EMPTY_BLOCK_MEMCMP */
169
170