1 /*
2 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 #include "AEEstd.h"
30 #include "AEEsmath.h"
31
32
33
xMinSize(int a,int b)34 static int xMinSize(int a, int b)
35 {
36 if (b < a) {
37 a = b;
38 }
39 return (a >= 0 ? a : 0);
40 }
41
42
xMoveBytes(byte * pbDest,const byte * pbSrc,int cb)43 static void xMoveBytes(byte *pbDest, const byte *pbSrc, int cb)
44 {
45 if (pbDest != pbSrc) {
46 (void) std_memmove(pbDest, pbSrc, cb);
47 }
48 }
49
50
51 #ifdef AEE_BIGENDIAN
52 # define STD_COPY std_CopyBE
53 # define STD_COPY_SWAP std_CopyLE
54 #else
55 # define STD_COPY std_CopyLE
56 # define STD_COPY_SWAP std_CopyBE
57 #endif
58
59
60 // See std_CopyLE/BE for documentation. This function implements the case
61 // where host ordering != target byte ordering.
62 //
STD_COPY_SWAP(void * pvDest,int nDestSize,const void * pvSrc,int nSrcSize,const char * pszFields)63 int STD_COPY_SWAP(void * pvDest, int nDestSize,
64 const void *pvSrc, int nSrcSize,
65 const char *pszFields)
66 {
67 byte* pbDest = (byte*)pvDest;
68 byte* pbSrc = (byte*)pvSrc;
69 int cbCopied = xMinSize(nDestSize, nSrcSize);
70 const char * pszNextField;
71 int cb, nSize;
72
73 nSize = 0; // avoid warning when using RVCT2.2 with -O1
74
75 pszNextField = pszFields;
76
77 for (cb = cbCopied; cb > 0; cb -= nSize) {
78 char ch;
79
80 ch = *pszNextField++;
81 if ('\0' == ch) {
82 ch = *pszFields;
83 pszNextField = pszFields+1;
84 }
85
86 if (ch == 'S') {
87
88 // S = 2 bytes
89
90 nSize = 2;
91 if (cb < nSize) {
92 break;
93 } else {
94 byte by = pbSrc[0];
95 pbDest[0] = pbSrc[1];
96 pbDest[1] = by;
97 }
98 } else if (ch == 'L') {
99
100 // L = 4 bytes
101
102 nSize = 4;
103 if (cb < nSize) {
104 break;
105 } else {
106 byte by = pbSrc[0];
107 pbDest[0] = pbSrc[3];
108 pbDest[3] = by;
109 by = pbSrc[1];
110 pbDest[1] = pbSrc[2];
111 pbDest[2] = by;
112 }
113 } else if (ch == 'Q') {
114
115 // Q = 8 bytes
116
117 nSize = 8;
118 if (cb < nSize) {
119 break;
120 } else {
121 byte by = pbSrc[0];
122 pbDest[0] = pbSrc[7];
123 pbDest[7] = by;
124 by = pbSrc[1];
125 pbDest[1] = pbSrc[6];
126 pbDest[6] = by;
127 by = pbSrc[2];
128 pbDest[2] = pbSrc[5];
129 pbDest[5] = by;
130 by = pbSrc[3];
131 pbDest[3] = pbSrc[4];
132 pbDest[4] = by;
133 }
134 } else {
135
136 // None of the above => read decimal and copy without swap
137
138 if (ch >= '0' && ch <= '9') {
139 nSize = (int) (ch - '0');
140 while ( (ch = *pszNextField) >= '0' && ch <= '9') {
141 nSize = nSize*10 + (int)(ch - '0');
142 ++pszNextField;
143 }
144 // Check bounds & ensure progress
145 if (nSize > cb || nSize <= 0) {
146 nSize = cb;
147 }
148 } else {
149 // Unexpected character: copy rest of data
150 nSize = cb;
151 }
152
153 xMoveBytes(pbDest, pbSrc, nSize);
154 }
155
156 pbDest += nSize;
157 pbSrc += nSize;
158 }
159
160 if (cb > 0) {
161
162 // Swap could not be completed: 0 < cb < nSize <= 8
163
164 byte byBuf[8];
165
166 // If entire value is available in source, use swapped version
167 if (nSrcSize - (pbSrc - (byte*)pvSrc) >= nSize) {
168 int i;
169 for (i=0; i<cb; ++i) {
170 byBuf[i] = pbSrc[nSize-1-i];
171 }
172 pbSrc = byBuf;
173 }
174 std_memmove(pbDest, pbSrc, cb);
175 }
176
177 return cbCopied;
178 }
179
180
181 // See std_CopyLE/BE for documentation. This function implements the case
182 // where host ordering == target byte ordering.
183 //
STD_COPY(void * pvDest,int nDestSize,const void * pvSrc,int nSrcSize,const char * pszFields)184 int STD_COPY(void *pvDest, int nDestSize,
185 const void *pvSrc, int nSrcSize,
186 const char *pszFields)
187 {
188 int cb = xMinSize(nDestSize, nSrcSize);
189 (void)pszFields;
190 xMoveBytes(pvDest, pvSrc, cb);
191 return cb;
192 }
193
194
195