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
RevLine 
[128]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
[131]15#define ASSERT_ARGS(x) \
16 if ((x)) \
17 return CF_ERROR_BITWISE_INVALID_ARGS
[128]18/**
19 * 비트열을 왼쪽으로 시프트
20 *
21 * \return 성공 시, CF_OK; 실패 시, 오류 코드
22 *
23 * \param in 시프트 할 비트열
24 * \param size 비트열 길이 (8의 배수)
25 * \param offset 시프트 할 수
[129]26 * \param out 시프트 결과
[128]27 */
28int
29CF_Bitwise_ShiftLeft (cf_byte * in,
30 size_t size,
[129]31 size_t offset,
32 cf_byte * out)
[128]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
[131]44 ASSERT_ARGS (!in || !out);
[128]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 시프트 할 수
[129]70 * \param out 시프트 결과
[128]71 */
72int
73CF_Bitwise_ShiftRight (cf_byte * in,
74 size_t size,
[129]75 size_t offset,
76 cf_byte * out)
[128]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
[131]88 ASSERT_ARGS (!in || !out);
[128]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 로테이션 할 수
[129]114 * \param out 로테이션 결과
[128]115 */
116int
117CF_Bitwise_RotateLeft (cf_byte * in,
118 size_t size,
[129]119 size_t offset,
120 cf_byte * out)
[128]121{
[138]122 cf_byte * buf = NULL;
[128]123
[131]124 ASSERT_ARGS (!in || !out);
[128]125
[138]126 /* make buffer two times of size */
127 buf = (cf_byte *) calloc (size, 2);
128 if (!buf)
129 return CF_ERROR_BITWISE_ALLOCATE_BUFFER;
[128]130
[138]131 CF_Bitwise_ShiftLeft (in, size, offset, buf);
132 CF_Bitwise_ShiftRight (in, size, size - offset, buf + size);
[128]133
[138]134 CF_Bitwise_OR (buf, buf + size, size, out);
[128]135
[138]136 free (buf);
[128]137
[138]138 return CF_OK;
[128]139}
140
141/**
142 * 비트열을 오른쪽으로 로테이션
143 *
144 * \return 성공 시, CF_OK; 실패 시, 오류 코드
145 *
146 * \param in 로테이션 할 비트열
147 * \param size 비트열 길이 (8의 배수)
148 * \param offset 로테이션 할 수
[129]149 * \param out 로테이션 결과
[128]150 */
151int
152CF_Bitwise_RotateRight (cf_byte * in,
153 size_t size,
[129]154 size_t offset,
155 cf_byte * out)
[128]156{
[138]157 cf_byte * buf = NULL;
[128]158
[131]159 ASSERT_ARGS (!in || !out);
[128]160
[138]161 /* make buffer two times of size */
162 buf = (cf_byte *) calloc (size, 2);
163 if (!buf)
164 return CF_ERROR_BITWISE_ALLOCATE_BUFFER;
[128]165
[138]166 CF_Bitwise_ShiftRight (in, size, offset, buf);
167 CF_Bitwise_ShiftLeft (in, size, size - offset, buf + size);
[128]168
[138]169 CF_Bitwise_OR (buf, buf + size, size, out);
[128]170
[138]171 free (buf);
[128]172
[138]173 return CF_OK;
[128]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
[131]195 ASSERT_ARGS (!in1 || !in2 || !out);
[128]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
[131]222 ASSERT_ARGS (!in1 || !in2 || !out);
[128]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
[131]249 ASSERT_ARGS (!in1 || !in2 || !out);
[128]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.