Rev 3730 | Rev 4226 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3730 | Rev 3731 | ||
---|---|---|---|
Line 32... | Line 32... | ||
32 | */ |
32 | */ |
33 | /** @file |
33 | /** @file |
34 | */ |
34 | */ |
35 | 35 | ||
36 | #include <string.h> |
36 | #include <string.h> |
37 | #include <unistd.h> |
- | |
38 | #include <ctype.h> |
37 | #include <stdlib.h> |
39 | #include <limits.h> |
38 | #include <limits.h> |
40 | #include <align.h> |
- | |
41 | #include <sys/types.h> |
39 | #include <ctype.h> |
42 | #include <malloc.h> |
40 | #include <malloc.h> |
43 | 41 | ||
44 | /** Fill memory block with a constant value. */ |
- | |
45 | void *memset(void *dest, int b, size_t n) |
- | |
46 | { |
- | |
47 | char *pb; |
- | |
48 | unsigned long *pw; |
- | |
49 | size_t word_size; |
- | |
50 | size_t n_words; |
- | |
51 | - | ||
52 | unsigned long pattern; |
- | |
53 | size_t i; |
- | |
54 | size_t fill; |
- | |
55 | - | ||
56 | /* Fill initial segment. */ |
- | |
57 | word_size = sizeof(unsigned long); |
- | |
58 | fill = word_size - ((uintptr_t) dest & (word_size - 1)); |
- | |
59 | if (fill > n) fill = n; |
- | |
60 | - | ||
61 | pb = dest; |
- | |
62 | - | ||
63 | i = fill; |
- | |
64 | while (i-- != 0) |
- | |
65 | *pb++ = b; |
- | |
66 | - | ||
67 | /* Compute remaining size. */ |
- | |
68 | n -= fill; |
- | |
69 | if (n == 0) return dest; |
- | |
70 | - | ||
71 | n_words = n / word_size; |
- | |
72 | n = n % word_size; |
- | |
73 | pw = (unsigned long *) pb; |
- | |
74 | - | ||
75 | /* Create word-sized pattern for aligned segment. */ |
- | |
76 | pattern = 0; |
- | |
77 | i = word_size; |
- | |
78 | while (i-- != 0) |
- | |
79 | pattern = (pattern << 8) | (uint8_t) b; |
- | |
80 | - | ||
81 | /* Fill aligned segment. */ |
- | |
82 | i = n_words; |
- | |
83 | while (i-- != 0) |
- | |
84 | *pw++ = pattern; |
- | |
85 | - | ||
86 | pb = (char *) pw; |
- | |
87 | - | ||
88 | /* Fill final segment. */ |
- | |
89 | i = n; |
- | |
90 | while (i-- != 0) |
- | |
91 | *pb++ = b; |
- | |
92 | - | ||
93 | return dest; |
- | |
94 | } |
- | |
95 | - | ||
96 | struct along { |
- | |
97 | unsigned long n; |
- | |
98 | } __attribute__ ((packed)); |
- | |
99 | - | ||
100 | static void *unaligned_memcpy(void *dst, const void *src, size_t n) |
- | |
101 | { |
- | |
102 | int i, j; |
- | |
103 | struct along *adst = dst; |
- | |
104 | const struct along *asrc = src; |
- | |
105 | - | ||
106 | for (i = 0; i < n / sizeof(unsigned long); i++) |
- | |
107 | adst[i].n = asrc[i].n; |
- | |
108 | - | ||
109 | for (j = 0; j < n % sizeof(unsigned long); j++) |
- | |
110 | ((unsigned char *) (((unsigned long *) dst) + i))[j] = |
- | |
111 | ((unsigned char *) (((unsigned long *) src) + i))[j]; |
- | |
112 | - | ||
113 | return (char *) dst; |
- | |
114 | } |
- | |
115 | - | ||
116 | /** Copy memory block. */ |
- | |
117 | void *memcpy(void *dst, const void *src, size_t n) |
- | |
118 | { |
- | |
119 | size_t i; |
- | |
120 | size_t mod, fill; |
- | |
121 | size_t word_size; |
- | |
122 | size_t n_words; |
- | |
123 | - | ||
124 | const unsigned long *srcw; |
- | |
125 | unsigned long *dstw; |
- | |
126 | const uint8_t *srcb; |
- | |
127 | uint8_t *dstb; |
- | |
128 | - | ||
129 | word_size = sizeof(unsigned long); |
- | |
130 | - | ||
131 | /* |
- | |
132 | * Are source and destination addresses congruent modulo word_size? |
- | |
133 | * If not, use unaligned_memcpy(). |
- | |
134 | */ |
- | |
135 | - | ||
136 | if (((uintptr_t) dst & (word_size - 1)) != |
- | |
137 | ((uintptr_t) src & (word_size - 1))) |
- | |
138 | return unaligned_memcpy(dst, src, n); |
- | |
139 | - | ||
140 | /* |
- | |
141 | * mod is the address modulo word size. fill is the length of the |
- | |
142 | * initial buffer segment before the first word boundary. |
- | |
143 | * If the buffer is very short, use unaligned_memcpy(), too. |
- | |
144 | */ |
- | |
145 | - | ||
146 | mod = (uintptr_t) dst & (word_size - 1); |
- | |
147 | fill = word_size - mod; |
- | |
148 | if (fill > n) fill = n; |
- | |
149 | - | ||
150 | /* Copy the initial segment. */ |
- | |
151 | - | ||
152 | srcb = src; |
- | |
153 | dstb = dst; |
- | |
154 | - | ||
155 | i = fill; |
- | |
156 | while (i-- != 0) |
- | |
157 | *dstb++ = *srcb++; |
- | |
158 | - | ||
159 | /* Compute remaining length. */ |
- | |
160 | - | ||
161 | n -= fill; |
- | |
162 | if (n == 0) return dst; |
- | |
163 | - | ||
164 | /* Pointers to aligned segment. */ |
- | |
165 | - | ||
166 | dstw = (unsigned long *) dstb; |
- | |
167 | srcw = (const unsigned long *) srcb; |
- | |
168 | - | ||
169 | n_words = n / word_size; /* Number of whole words to copy. */ |
- | |
170 | n -= n_words * word_size; /* Remaining bytes at the end. */ |
- | |
171 | - | ||
172 | /* "Fast" copy. */ |
- | |
173 | i = n_words; |
- | |
174 | while (i-- != 0) |
- | |
175 | *dstw++ = *srcw++; |
- | |
176 | - | ||
177 | /* |
- | |
178 | * Copy the rest. |
- | |
179 | */ |
- | |
180 | - | ||
181 | srcb = (const uint8_t *) srcw; |
- | |
182 | dstb = (uint8_t *) dstw; |
- | |
183 | - | ||
184 | i = n; |
- | |
185 | while (i-- != 0) |
- | |
186 | *dstb++ = *srcb++; |
- | |
187 | - | ||
188 | return dst; |
- | |
189 | } |
- | |
190 | - | ||
191 | /** Move memory block with possible overlapping. */ |
- | |
192 | void *memmove(void *dst, const void *src, size_t n) |
- | |
193 | { |
- | |
194 | uint8_t *dp, *sp; |
- | |
195 | - | ||
196 | /* Nothing to do? */ |
- | |
197 | if (src == dst) |
- | |
198 | return dst; |
- | |
199 | - | ||
200 | /* Non-overlapping? */ |
- | |
201 | if (dst >= src + n || src >= dst + n) { |
- | |
202 | return memcpy(dst, src, n); |
- | |
203 | } |
- | |
204 | - | ||
205 | /* Which direction? */ |
- | |
206 | if (src > dst) { |
- | |
207 | /* Forwards. */ |
- | |
208 | sp = src; |
- | |
209 | dp = dst; |
- | |
210 | - | ||
211 | while (n-- != 0) |
- | |
212 | *dp++ = *sp++; |
- | |
213 | } else { |
- | |
214 | /* Backwards. */ |
- | |
215 | sp = src + (n - 1); |
- | |
216 | dp = dst + (n - 1); |
- | |
217 | - | ||
218 | while (n-- != 0) |
- | |
219 | *dp-- = *sp--; |
- | |
220 | } |
- | |
221 | - | ||
222 | return dst; |
- | |
223 | } |
- | |
224 | - | ||
225 | /** Compare two memory areas. |
- | |
226 | * |
- | |
227 | * @param s1 Pointer to the first area to compare. |
- | |
228 | * @param s2 Pointer to the second area to compare. |
- | |
229 | * @param len Size of the first area in bytes. Both areas must have |
- | |
230 | * the same length. |
- | |
231 | * @return If len is 0, return zero. If the areas match, return |
- | |
232 | * zero. Otherwise return non-zero. |
- | |
233 | */ |
- | |
234 | int bcmp(const char *s1, const char *s2, size_t len) |
- | |
235 | { |
- | |
236 | for (; len && *s1++ == *s2++; len--) |
- | |
237 | ; |
- | |
238 | return len; |
- | |
239 | } |
- | |
240 | - | ||
241 | /** Count the number of characters in the string, not including terminating 0. |
42 | /** Count the number of characters in the string, not including terminating 0. |
242 | * |
43 | * |
243 | * @param str String. |
44 | * @param str String. |
244 | * @return Number of characters in string. |
45 | * @return Number of characters in string. |
245 | */ |
46 | */ |