source: libcf/trunk/src/cf_bitwise.c@ 131

Last change on this file since 131 was 131, checked in by cheese, 11 years ago

#1 modify assertion for bitwise

File size: 5.3 KB
Line 
1/**
2 * \file cf_bitwise.c
3 *
4 * \author myusgun <myusgun@gmail.com>
5 * \author chevalier <achagun@gmail.com>
6 *
7 * \brief 비트 연산자 구현
8 */
9#include "cf_bitwise.h"
10#include "cf_error.h"
11
12#include <stdio.h>
13#include <stdlib.h>
14
15#define ASSERT_ARGS(x) \
16 if ((x)) \
17 return CF_ERROR_BITWISE_INVALID_ARGS
18/**
19 * 비트열을 왼쪽으로 시프트
20 *
21 * \return 성공 시, CF_OK; 실패 시, 오류 코드
22 *
23 * \param in 시프트 할 비트열
24 * \param size 비트열 길이 (8의 배수)
25 * \param offset 시프트 할 수
26 * \param out 시프트 결과
27 */
28int
29CF_Bitwise_ShiftLeft (cf_byte * in,
30 size_t size,
31 size_t offset,
32 cf_byte * out)
33{
34 size_t iter = 0;
35
36 size_t quota = offset / 8;
37 size_t remain = offset % 8;
38 size_t byteSize = size / 8;
39
40 size_t maskPos = 8 - remain;
41 cf_byte mask = 0;
42 cf_byte buf = 0;
43
44 ASSERT_ARGS (!in || !out);
45
46 for (iter = 0 ; iter < remain ; iter++)
47 mask |= (cf_byte)(0x80 >> iter);
48
49 out[0] = (cf_byte)(in[0 + quota] << remain);
50
51 for (iter = 1 ; iter < byteSize - quota ; iter++)
52 {
53 buf = in[iter + quota] & mask;
54
55 out[iter ] = (cf_byte)(in[iter + quota] << remain);
56 out[iter - 1] |= (cf_byte)(buf >> maskPos);
57 }
58
59 return CF_OK;
60}
61
62/**
63 * 비트열을 오른쪽으로 시프트
64 *
65 * \return 성공 시, CF_OK; 실패 시, 오류 코드
66 *
67 * \param in 시프트 할 비트열
68 * \param size 비트열 길이 (8의 배수)
69 * \param offset 시프트 할 수
70 * \param out 시프트 결과
71 */
72int
73CF_Bitwise_ShiftRight (cf_byte * in,
74 size_t size,
75 size_t offset,
76 cf_byte * out)
77{
78 size_t iter = 0;
79
80 size_t quota = offset / 8;
81 size_t remain = offset % 8;
82 size_t byteSize = size / 8;
83
84 size_t maskPos = 8 - remain;
85 cf_byte mask = 0;
86 cf_byte buf = 0;
87
88 ASSERT_ARGS (!in || !out);
89
90 for (iter = 0 ; iter < remain ; iter++)
91 mask |= (cf_byte)(0x01 << iter);
92
93 out[byteSize - 1] = (cf_byte)(in[byteSize - 1 - quota] >> remain);
94
95 for (iter = byteSize - 2 ; iter > quota - 1 ; iter--)
96 {
97 buf = in[iter - quota] & mask;
98
99 out[iter ] = (cf_byte)(in[iter - quota] >> remain);
100 out[iter + 1] |= (cf_byte)(buf << maskPos);
101 }
102
103 return CF_OK;
104}
105
106/**
107 * 비트열을 왼쪽으로 로테이션
108 *
109 * \return 성공 시, CF_OK; 실패 시, 오류 코드
110 *
111 * \param in 로테이션 할 비트열
112 * \param size 비트열 길이 (8의 배수)
113 * \param offset 로테이션 할 수
114 * \param out 로테이션 결과
115 */
116int
117CF_Bitwise_RotateLeft (cf_byte * in,
118 size_t size,
119 size_t offset,
120 cf_byte * out)
121{
122 int result = 0;
123 cf_byte * buf1 = NULL;
124 cf_byte * buf2 = NULL;
125
126 ASSERT_ARGS (!in || !out);
127
128 buf1 = (cf_byte *) calloc (size, 1);
129 buf2 = (cf_byte *) calloc (size, 1);
130
131 if (!buf1 || !buf2)
132 result = CF_ERROR_BITWISE_ALLOCATE_BUFFER;
133 else
134 {
135 CF_Bitwise_ShiftLeft (in, size, offset, buf1);
136 CF_Bitwise_ShiftRight (in, size, size - offset, buf2);
137
138 CF_Bitwise_OR (buf1, buf2, size, out);
139 }
140
141 if (buf1) free (buf1);
142 if (buf2) free (buf2);
143
144 return result;
145}
146
147/**
148 * 비트열을 오른쪽으로 로테이션
149 *
150 * \return 성공 시, CF_OK; 실패 시, 오류 코드
151 *
152 * \param in 로테이션 할 비트열
153 * \param size 비트열 길이 (8의 배수)
154 * \param offset 로테이션 할 수
155 * \param out 로테이션 결과
156 */
157int
158CF_Bitwise_RotateRight (cf_byte * in,
159 size_t size,
160 size_t offset,
161 cf_byte * out)
162{
163 int result = 0;
164 cf_byte * buf1 = NULL;
165 cf_byte * buf2 = NULL;
166
167 ASSERT_ARGS (!in || !out);
168
169 buf1 = (cf_byte *) calloc (size, 1);
170 buf2 = (cf_byte *) calloc (size, 1);
171
172 if (!buf1 || !buf2)
173 result = CF_ERROR_BITWISE_ALLOCATE_BUFFER;
174 else
175 {
176 CF_Bitwise_ShiftRight (in, size, offset, buf1);
177 CF_Bitwise_ShiftLeft (in, size, size - offset, buf2);
178
179 CF_Bitwise_OR (buf1, buf2, size, out);
180 }
181
182 if (buf1) free (buf1);
183 if (buf2) free (buf2);
184
185 return result;
186}
187
188/**
189 * 두 비트열의 AND
190 *
191 * \return 성공 시, CF_OK; 실패 시, 오류 코드
192 *
193 * \param in1 입력 비트열 1
194 * \param in2 입력 비트열 2
195 * \param size 비트열 길이 (8의 배수)
196 * \param out 두 비트열의 AND 결과
197 */
198int
199CF_Bitwise_AND (cf_byte * in1,
200 cf_byte * in2,
201 size_t size,
202 cf_byte * out)
203{
204 size_t iter = 0;
205 size_t quota = size / 8;
206
207 ASSERT_ARGS (!in1 || !in2 || !out);
208
209 for (iter = 0 ; iter < quota ; iter++)
210 out[iter] = in1[iter] & in2[iter];
211
212 return 0;
213}
214
215/**
216 * 두 비트열의 OR
217 *
218 * \return 성공 시, CF_OK; 실패 시, 오류 코드
219 *
220 * \param in1 입력 비트열 1
221 * \param in2 입력 비트열 2
222 * \param size 비트열 길이 (8의 배수)
223 * \param out 두 비트열의 OR 결과
224 */
225int
226CF_Bitwise_OR (cf_byte * in1,
227 cf_byte * in2,
228 size_t size,
229 cf_byte * out)
230{
231 size_t iter = 0;
232 size_t quota = size / 8;
233
234 ASSERT_ARGS (!in1 || !in2 || !out);
235
236 for (iter = 0 ; iter < quota ; iter++)
237 out[iter] = in1[iter] | in2[iter];
238
239 return 0;
240}
241
242/**
243 * 두 비트열의 XOR
244 *
245 * \return 성공 시, CF_OK; 실패 시, 오류 코드
246 *
247 * \param in1 입력 비트열 1
248 * \param in2 입력 비트열 2
249 * \param size 비트열 길이 (8의 배수)
250 * \param out 두 비트열의 XOR 결과
251 */
252int
253CF_Bitwise_XOR (cf_byte * in1,
254 cf_byte * in2,
255 size_t size,
256 cf_byte * out)
257{
258 size_t iter = 0;
259 size_t quota = size / 8;
260
261 ASSERT_ARGS (!in1 || !in2 || !out);
262
263 for (iter = 0 ; iter < quota ; iter++)
264 out[iter] = in1[iter] ^ in2[iter];
265
266 return 0;
267}
Note: See TracBrowser for help on using the repository browser.