1 /*
2 * Copyright (c) 2007 - 2015 Joseph Gaeddert
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23 //
24 // shift_array.c
25 //
26 // byte-wise array shifting
27 //
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "liquid.internal.h"
34
35
36 // shift array to the left _b bytes, filling in zeros
37 // _src : source address [size: _n x 1]
38 // _n : input data array size
39 // _b : number of bytes to shift
liquid_lshift(unsigned char * _src,unsigned int _n,unsigned int _b)40 void liquid_lshift(unsigned char * _src,
41 unsigned int _n,
42 unsigned int _b)
43 {
44 // shift amount exceeds buffer size; fill with zeros
45 if (_b >= _n) {
46 memset(_src, 0x00, _n*sizeof(unsigned char));
47 return;
48 }
49
50 // move memory
51 memmove(_src, &_src[_b], (_n-_b)*sizeof(unsigned char));
52
53 // fill remaining buffer with zeros
54 memset(&_src[_n-_b], 0x00, _b*sizeof(unsigned char));
55 }
56
57 // shift array to the right _b bytes, filling in zeros
58 // _src : source address [size: _n x 1]
59 // _n : input data array size
60 // _b : number of bytes to shift
liquid_rshift(unsigned char * _src,unsigned int _n,unsigned int _b)61 void liquid_rshift(unsigned char * _src,
62 unsigned int _n,
63 unsigned int _b)
64 {
65 // shift amount exceeds buffer size; fill with zeros
66 if (_b >= _n) {
67 memset(_src, 0x00, _n*sizeof(unsigned char));
68 return;
69 }
70
71 // move memory
72 memmove(&_src[_b], _src, (_n-_b)*sizeof(unsigned char));
73
74 // fill remaining buffer with zeros
75 memset(_src, 0x00, _b*sizeof(unsigned char));
76 }
77
78
79 // circular shift array to the left _n bytes
80 // _src : source address [size: _n x 1]
81 // _n : input data array size
82 // _b : number of bytes to shift
liquid_lcircshift(unsigned char * _src,unsigned int _n,unsigned int _b)83 void liquid_lcircshift(unsigned char * _src,
84 unsigned int _n,
85 unsigned int _b)
86 {
87 // validate input
88 if (_n == 0)
89 return;
90
91 // ensure 0 <= _b < _n
92 _b = _b % _n;
93
94 // check if less memory is used with rcircshift
95 if (_b > (_n>>1)) {
96 liquid_rcircshift(_src, _n, _n-_b);
97 return;
98 }
99
100 // allocate memory for temporary array
101 unsigned char * tmp = (unsigned char*) malloc(_b*sizeof(unsigned char));
102
103 // copy to temporary array
104 memmove(tmp, _src, _b*sizeof(unsigned char));
105
106 // shift left
107 memmove(_src, &_src[_b], (_n-_b)*sizeof(unsigned char));
108
109 // copy from temporary array
110 memmove(&_src[_n-_b], tmp, _b*sizeof(unsigned char));
111
112 // free temporary array
113 free(tmp);
114 }
115
116
117 // circular shift array to the right _n bytes
118 // _src : source address [size: _n x 1]
119 // _n : input data array size
120 // _b : number of bytes to shift
liquid_rcircshift(unsigned char * _src,unsigned int _n,unsigned int _b)121 void liquid_rcircshift(unsigned char * _src,
122 unsigned int _n,
123 unsigned int _b)
124 {
125 // validate input
126 if (_n == 0)
127 return;
128
129 // ensure 0 <= _b < _n
130 _b = _b % _n;
131
132 // check if less memory is used with lcircshift
133 if (_b > (_n>>1)) {
134 liquid_lcircshift(_src, _n, _n-_b);
135 return;
136 }
137
138 // allocate memory for temporary array
139 unsigned char * tmp = (unsigned char*) malloc(_b*sizeof(unsigned char));
140
141 // copy to temporary array
142 memmove(tmp, &_src[_n-_b], _b*sizeof(unsigned char));
143
144 // shift right
145 memmove(&_src[_b], _src, (_n-_b)*sizeof(unsigned char));
146
147 // copy from temporary array
148 memmove(_src, tmp, _b*sizeof(unsigned char));
149
150 // free temporary array
151 free(tmp);
152 }
153
154