xref: /aosp_15_r20/external/fastrpc/src/std_SwapBytes.c (revision 418b791d679beb2078b579a3b6936cf330c41799)
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