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

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

#1 enhance a few performance of bitwise

File size: 5.1 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 cf_byte * buf = NULL;
123
124 ASSERT_ARGS (!in || !out);
125
126 /* make buffer two times of size */
127 buf = (cf_byte *) calloc (size, 2);
128 if (!buf)
129 return CF_ERROR_BITWISE_ALLOCATE_BUFFER;
130
131 CF_Bitwise_ShiftLeft (in, size, offset, buf);
132 CF_Bitwise_ShiftRight (in, size, size - offset, buf + size);
133
134 CF_Bitwise_OR (buf, buf + size, size, out);
135
136 free (buf);
137
138 return CF_OK;
139}
140
141/**
142 * 비트열을 오른쪽으로 로테이션
143 *
144 * \return 성공 시, CF_OK; 실패 시, 오류 코드
145 *
146 * \param in 로테이션 할 비트열
147 * \param size 비트열 길이 (8의 배수)
148 * \param offset 로테이션 할 수
149 * \param out 로테이션 결과
150 */
151int
152CF_Bitwise_RotateRight (cf_byte * in,
153 size_t size,
154 size_t offset,
155 cf_byte * out)
156{
157 cf_byte * buf = NULL;
158
159 ASSERT_ARGS (!in || !out);
160
161 /* make buffer two times of size */
162 buf = (cf_byte *) calloc (size, 2);
163 if (!buf)
164 return CF_ERROR_BITWISE_ALLOCATE_BUFFER;
165
166 CF_Bitwise_ShiftRight (in, size, offset, buf);
167 CF_Bitwise_ShiftLeft (in, size, size - offset, buf + size);
168
169 CF_Bitwise_OR (buf, buf + size, size, out);
170
171 free (buf);
172
173 return CF_OK;
174}
175
176/**
177 * 두 비트열의 AND
178 *
179 * \return 성공 시, CF_OK; 실패 시, 오류 코드
180 *
181 * \param in1 입력 비트열 1
182 * \param in2 입력 비트열 2
183 * \param size 비트열 길이 (8의 배수)
184 * \param out 두 비트열의 AND 결과
185 */
186int
187CF_Bitwise_AND (cf_byte * in1,
188 cf_byte * in2,
189 size_t size,
190 cf_byte * out)
191{
192 size_t iter = 0;
193 size_t quota = size / 8;
194
195 ASSERT_ARGS (!in1 || !in2 || !out);
196
197 for (iter = 0 ; iter < quota ; iter++)
198 out[iter] = in1[iter] & in2[iter];
199
200 return 0;
201}
202
203/**
204 * 두 비트열의 OR
205 *
206 * \return 성공 시, CF_OK; 실패 시, 오류 코드
207 *
208 * \param in1 입력 비트열 1
209 * \param in2 입력 비트열 2
210 * \param size 비트열 길이 (8의 배수)
211 * \param out 두 비트열의 OR 결과
212 */
213int
214CF_Bitwise_OR (cf_byte * in1,
215 cf_byte * in2,
216 size_t size,
217 cf_byte * out)
218{
219 size_t iter = 0;
220 size_t quota = size / 8;
221
222 ASSERT_ARGS (!in1 || !in2 || !out);
223
224 for (iter = 0 ; iter < quota ; iter++)
225 out[iter] = in1[iter] | in2[iter];
226
227 return 0;
228}
229
230/**
231 * 두 비트열의 XOR
232 *
233 * \return 성공 시, CF_OK; 실패 시, 오류 코드
234 *
235 * \param in1 입력 비트열 1
236 * \param in2 입력 비트열 2
237 * \param size 비트열 길이 (8의 배수)
238 * \param out 두 비트열의 XOR 결과
239 */
240int
241CF_Bitwise_XOR (cf_byte * in1,
242 cf_byte * in2,
243 size_t size,
244 cf_byte * out)
245{
246 size_t iter = 0;
247 size_t quota = size / 8;
248
249 ASSERT_ARGS (!in1 || !in2 || !out);
250
251 for (iter = 0 ; iter < quota ; iter++)
252 out[iter] = in1[iter] ^ in2[iter];
253
254 return 0;
255}
Note: See TracBrowser for help on using the repository browser.