Main Page Modules Data Structures File List Data Fields Globals Related Pages

# beecrypt/endianness.c

Go to the documentation of this file.

    00001 /*
    00002  * endianness.c
    00003  *
    00004  * Endianness-dependant encoding/decoding - implementation
    00005  *
    00006  * Copyright (c) 1998, 1999, 2000, 2001 Virtual Unlimited B.V.
    00007  *
    00008  * Author: Bob Deblier <bob@virtualunlimited.com>
    00009  *
    00010  * This library is free software; you can redistribute it and/or
    00011  * modify it under the terms of the GNU Lesser General Public
    00012  * License as published by the Free Software Foundation; either
    00013  * version 2.1 of the License, or (at your option) any later version.
    00014  *
    00015  * This library is distributed in the hope that it will be useful,
    00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00018  * Lesser General Public License for more details.
    00019  *
    00020  * You should have received a copy of the GNU Lesser General Public
    00021  * License along with this library; if not, write to the Free Software
    00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00023  *
    00024  */
    00025
    00026 #include "system.h"
    00027 #include "endianness.h"
    00028 #include "debug.h"
    00029
    00030 /*@-shiftimplementation@*/
    00031 int16 swap16(int16 n)
    00032 {
    00033         return (    ((n & 0xff) << 8) |
    00034                                 ((n & 0xff00) >> 8) );
    00035 }
    00036
    00037 uint16 swapu16(uint16 n)
    00038 {
    00039         return (    ((n & 0xffU) << 8) |
    00040                                 ((n & 0xff00U) >> 8) );
    00041 }
    00042
    00043 int32 swap32(int32 n)
    00044 {
    00045         return (    ((n & 0xff) << 24) |
    00046                                 ((n & 0xff00) << 8) |
    00047                                 ((n & 0xff0000) >> 8) |
    00048                                 ((n & 0xff000000) >> 24) );
    00049 }
    00050
    00051 uint32 swapu32(uint32 n)
    00052 {
    00053         return (    ((n & 0xffU) << 24) |
    00054                                 ((n & 0xff00U) << 8) |
    00055                                 ((n & 0xff0000U) >> 8) |
    00056                                 ((n & 0xff000000U) >> 24) );
    00057 }
    00058
    00059 int64 swap64(int64 n)
    00060 {
    00061         #if HAVE_LONG_LONG
    00062         return (    ((n & 0xffLL) << 56) |
    00063                                 ((n & 0xff00LL) << 40) |
    00064                                 ((n & 0xff0000LL) << 24) |
    00065                                 ((n & 0xff000000LL) << 8) |
    00066                                 ((n & 0xff00000000LL) >> 8) |
    00067                                 ((n & 0xff0000000000LL) >> 24) |
    00068                                 ((n & 0xff000000000000LL) >> 40) |
    00069                                 ((n & 0xff00000000000000LL) >> 56) );
    00070         #else
    00071         return (    ((n & 0xffL) << 56) |
    00072                                 ((n & 0xff00L) << 40) |
    00073                                 ((n & 0xff0000L) << 24) |
    00074                                 ((n & 0xff000000L) << 8) |
    00075                                 ((n & 0xff00000000L) >> 8) |
    00076                                 ((n & 0xff0000000000L) >> 24) |
    00077                                 ((n & 0xff000000000000L) >> 40) |
    00078                                 ((n & 0xff00000000000000L) >> 56) );
    00079         #endif
    00080 }
    00081 /*@=shiftimplementation@*/
    00082
    00083 /*@-boundswrite@*/
    00084 int encodeByte(javabyte b, byte *data)
    00085 {
    00086         *data = b;
    00087         return 1;
    00088 }
    00089 /*@=boundswrite@*/
    00090
    00091 /*@-boundswrite@*/
    00092 int encodeShort(javashort s, byte *data)
    00093 {
    00094         #if (!WORDS_BIGENDIAN)
    00095         s = swap16(s);
    00096         #endif
    00097         memcpy(data, &s, 2);
    00098         return 2;
    00099 }
    00100 /*@=boundswrite@*/
    00101
    00102 /*@-boundswrite@*/
    00103 int encodeInt(javaint i, byte* data)
    00104 {
    00105         #if (!WORDS_BIGENDIAN)
    00106         i = swap32(i);
    00107         #endif
    00108         memcpy(data, &i, 4);
    00109         return 4;
    00110 }
    00111 /*@=boundswrite@*/
    00112
    00113 /*@-boundswrite@*/
    00114 int encodeLong(javalong l, byte* data)
    00115 {
    00116         #if (!WORDS_BIGENDIAN)
    00117         l = swap64(l);
    00118         #endif
    00119         memcpy(data, &l, 8);
    00120         return 8;
    00121 }
    00122 /*@=boundswrite@*/
    00123
    00124 /*@-boundswrite@*/
    00125 int encodeFloat(javafloat f, byte* data)
    00126 {
    00127         #if (!WORDS_BIGENDIAN)
    00128         register const byte* src = ((const byte*) &f) + 3;
    00129         register int i;
    00130         for (i = 0; i < 4; i++)
    00131                 data[i] = *(src--);
    00132         #else
    00133         memcpy(data, &f, 4);
    00134         #endif
    00135         return 4;
    00136 }
    00137 /*@=boundswrite@*/
    00138
    00139 /*@-boundswrite@*/
    00140 int encodeDouble(javadouble d, byte* data)
    00141 {
    00142         #if (!WORDS_BIGENDIAN)
    00143         register const byte* src = ((byte*) &d) + 7;
    00144         register int i;
    00145         for (i = 0; i < 8; i++)
    00146                 data[i] = *(src--);
    00147         #else
    00148         memcpy(data, &d, 8);
    00149         #endif
    00150         return 8;
    00151 }
    00152 /*@=boundswrite@*/
    00153
    00154 /*@-boundswrite@*/
    00155 int encodeChar(javachar c, byte* data)
    00156 {
    00157         #if (!WORDS_BIGENDIAN)
    00158         c = swapu16(c);
    00159         #endif
    00160         memcpy(data, &c, 2);
    00161         return 2;
    00162 }
    00163 /*@=boundswrite@*/
    00164
    00165 /*@-boundswrite@*/
    00166 int encodeInts(const javaint* i, byte* data, int count)
    00167 {
    00168         register int rc = ((uint32)count) << 2;
    00169         #if (WORDS_BIGENDIAN)
    00170         memcpy(data, i, rc);
    00171         #else
    00172         javaint tmp;
    00173         while (count--)
    00174         {
    00175                 tmp = swap32(*(i++));
    00176                 memcpy(data, &tmp, 4);
    00177                 data += 4;
    00178         }
    00179         #endif
    00180         return rc;
    00181 }
    00182 /*@=boundswrite@*/
    00183
    00184 /*@-boundswrite@*/
    00185 int encodeIntsPartial(const javaint* i, byte* data, int bytecount)
    00186 {
    00187         register int rc = bytecount;
    00188         #if (WORDS_BIGENDIAN)
    00189         memcpy(data, i, rc);
    00190         #else
    00191         javaint tmp;
    00192
    00193         while (bytecount > 0)
    00194         {
    00195                 tmp = swap32(*(i++));
    00196                 memcpy(data, &tmp, (bytecount > 4) ? 4 : bytecount);
    00197                 data += 4;
    00198                 bytecount -= 4;
    00199         }
    00200         #endif
    00201         return rc;
    00202 }
    00203 /*@=boundswrite@*/
    00204
    00205 /*@-boundswrite@*/
    00206 int encodeIntsPartialPad(const javaint* i, byte* data, int bytecount, byte padvalue)
    00207 {
    00208         register int rc = bytecount;
    00209
    00210         #if (WORDS_BIGENDIAN)
    00211         memcpy(data, i, rc);
    00212         if (rc & 0x3)
    00213                 memset(data+rc, padvalue, 4 -(rc & 0x3));
    00214         #else
    00215         javaint tmp;
    00216
    00217         while (bytecount > 0)
    00218         {
    00219                 tmp = swap32(*(i++));
    00220                 memcpy(data, &tmp, (bytecount > 4) ? 4 : bytecount);
    00221                 data += 4;
    00222                 bytecount -= 4;
    00223         }
    00224         if (bytecount)
    00225                 memset(data+bytecount, padvalue, -bytecount);
    00226         #endif
    00227         return rc;
    00228 }
    00229 /*@=boundswrite@*/
    00230
    00231 /*@-boundswrite@*/
    00232 int encodeChars(const javachar* c, byte* data, int count)
    00233 {
    00234         register int rc = ((uint32)count) << 1;
    00235         #if (WORDS_BIGENDIAN)
    00236         memcpy(data, c, rc);
    00237         #else
    00238         javaint tmp;
    00239         while (count--)
    00240         {
    00241                 tmp = swapu16(*(c++));
    00242                 memcpy(data, &tmp, 2);
    00243                 data += 2;
    00244         }
    00245         #endif
    00246         return rc;
    00247 }
    00248 /*@=boundswrite@*/
    00249
    00250 /*@-boundswrite@*/
    00251 int decodeByte(javabyte* b, const byte* data)
    00252 {
    00253         *b = *data;
    00254         return 1;
    00255 }
    00256 /*@=boundswrite@*/
    00257
    00258 /*@-boundswrite@*/
    00259 int decodeShort(javashort* s, const byte* data)
    00260 {
    00261         #if (WORDS_BIGENDIAN)
    00262         memcpy(s, data, 2);
    00263         #else
    00264         javashort tmp;
    00265         memcpy(&tmp, data, 2);
    00266         *s = swap16(tmp);
    00267         #endif
    00268         return 2;
    00269 }
    00270 /*@=boundswrite@*/
    00271
    00272 /*@-boundswrite@*/
    00273 int decodeInt(javaint* i, const byte* data)
    00274 {
    00275         #if (WORDS_BIGENDIAN)
    00276         memcpy(i, data, 4);
    00277         #else
    00278         javaint tmp;
    00279         memcpy(&tmp, data, 4);
    00280         *i = swap32(tmp);
    00281         #endif
    00282         return 4;
    00283 }
    00284 /*@=boundswrite@*/
    00285
    00286 /*@-boundswrite@*/
    00287 int decodeLong(javalong* l, const byte* data)
    00288 {
    00289         #if (WORDS_BIGENDIAN)
    00290         memcpy(l, data, 8);
    00291         #else
    00292         javalong tmp;
    00293         memcpy(&tmp, data, 8);
    00294         *l = swap64(tmp);
    00295         #endif
    00296         return 8;
    00297 }
    00298 /*@=boundswrite@*/
    00299
    00300 /*@-boundswrite@*/
    00301 int decodeFloat(javafloat* f, const byte* data)
    00302 {
    00303         #if (WORDS_BIGENDIAN)
    00304         memcpy(f, data, 4);
    00305         #else
    00306         register byte *dst = ((byte*) f) + 3;
    00307         register int i;
    00308         for (i = 0; i < 4; i++)
    00309                 *(dst--) = data[i];
    00310         #endif
    00311         return 4;
    00312 }
    00313 /*@=boundswrite@*/
    00314
    00315 /*@-boundswrite@*/
    00316 int decodeDouble(javadouble* d, const byte* data)
    00317 {
    00318         #if (WORDS_BIGENDIAN)
    00319         memcpy(d, data, 8);
    00320         #else
    00321         register byte *dst = ((byte*) d) + 7;
    00322         register int i;
    00323         for (i = 0; i < 8; i++)
    00324                 *(dst--) = data[i];
    00325         #endif
    00326         return 8;
    00327 }
    00328 /*@=boundswrite@*/
    00329
    00330 /*@-boundswrite@*/
    00331 int decodeChar(javachar* c, const byte* data)
    00332 {
    00333         #if (WORDS_BIGENDIAN)
    00334         memcpy(c, data, 2);
    00335         #else
    00336         javachar tmp;
    00337         memcpy(&tmp, data, 2);
    00338         *c = swapu16(tmp);
    00339         #endif
    00340         return 2;
    00341 }
    00342 /*@=boundswrite@*/
    00343
    00344 /*@-boundswrite@*/
    00345 int decodeInts(javaint* i, const byte* data, int count)
    00346 {
    00347         register int rc = ((uint32)count) << 2;
    00348         #if (WORDS_BIGENDIAN)
    00349         memcpy(i, data, rc);
    00350         #else
    00351         javaint tmp;
    00352         while (count--)
    00353         {
    00354                 memcpy(&tmp, data, 4);
    00355                 *(i++) = swap32(tmp);
    00356                 data += 4;
    00357         }
    00358         #endif
    00359         return rc;
    00360 }
    00361 /*@=boundswrite@*/
    00362
    00363 /*@-boundswrite@*/
    00364 int decodeIntsPartial(javaint* i, const byte* data, int bytecount)
    00365 {
    00366         register int rc = bytecount;
    00367         #if (WORDS_BIGENDIAN)
    00368         memcpy(i, data, rc);
    00369         if (rc & 0x3)
    00370                 memset(i + (rc >> 2), 0, 4 - (rc & 0x3));
    00371         #else
    00372         javaint tmp;
    00373         while (bytecount >= 4)
    00374         {
    00375                 memcpy(&tmp, data, 4);
    00376                 *(i++) = swap32(tmp);
    00377                 data += 4;
    00378                 bytecount -= 4;
    00379         }
    00380         if (bytecount)
    00381         {
    00382                 tmp = 0;
    00383                 memcpy(&tmp, data, bytecount);
    00384                 *(i++) = swap32(tmp);
    00385         }
    00386         #endif
    00387         return rc;
    00388 }
    00389 /*@=boundswrite@*/
    00390
    00391 /*@-boundswrite@*/
    00392 int decodeChars(javachar* c, const byte* data, int count)
    00393 {
    00394         register int rc = ((uint32)count) << 1;
    00395         #if (WORDS_BIGENDIAN)
    00396         memcpy(c, data, rc);
    00397         #else
    00398         javachar tmp;
    00399         while (count--)
    00400         {
    00401                 memcpy(&tmp, data, 2);
    00402                 *(c++) = swapu16(tmp);
    00403                 data += 2;
    00404         }
    00405         #endif
    00406         return rc;
    00407 }
    00408 /*@=boundswrite@*/
    00409
    00410 int readByte(javabyte* b, FILE* ifp)
    00411 {
    00412         return fread(b, 1, 1, ifp);
    00413 }
    00414
    00415 /*@-boundswrite@*/
    00416 int readShort(javashort* s, FILE* ifp)
    00417 {
    00418         register int rc = fread(s, 2, 1, ifp);
    00419         #if !(WORDS_BIGENDIAN)
    00420         if (rc == 1)
    00421         {
    00422                 register javashort tmp = *s;
    00423                 *s = swap16(tmp);
    00424         }
    00425         #endif
    00426         return rc;
    00427 }
    00428 /*@=boundswrite@*/
    00429
    00430 /*@-boundswrite@*/
    00431 int readInt(javaint* i, FILE* ifp)
    00432 {
    00433         register int rc = fread(i, 4, 1, ifp);
    00434         #if !(WORDS_BIGENDIAN)
    00435         if (rc == 1)
    00436         {
    00437                 register javaint tmp = *i;
    00438                 *i = swap32(tmp);
    00439         }
    00440         #endif
    00441         return rc;
    00442 }
    00443 /*@=boundswrite@*/
    00444
    00445 /*@-boundswrite@*/
    00446 int readLong(javalong* l, FILE* ifp)
    00447 {
    00448         register int rc = fread(l, 8, 1, ifp);
    00449         #if !(WORDS_BIGENDIAN)
    00450         if (rc == 1)
    00451         {
    00452                 register javalong tmp = *l;
    00453                 *l = swap64(tmp);
    00454         }
    00455         #endif
    00456         return rc;
    00457 }
    00458 /*@=boundswrite@*/
    00459
    00460 /*@-boundswrite@*/
    00461 int readChar(javachar* c, FILE* ifp)
    00462 {
    00463         register int rc = fread(c, 2, 1, ifp);
    00464         #if !(WORDS_BIGENDIAN)
    00465         if (rc == 1)
    00466         {
    00467                 register javachar tmp = *c;
    00468                 *c = swapu16(tmp);
    00469         }
    00470         #endif
    00471         return rc;
    00472 }
    00473 /*@=boundswrite@*/
    00474
    00475 /*@-boundswrite@*/
    00476 int readInts(javaint* i, FILE* ifp, int count)
    00477 {
    00478         register int rc = fread(i, 4, count, ifp);
    00479         #if !(WORDS_BIGENDIAN)
    00480         if (rc == count)
    00481         {
    00482                 while (count > 0)
    00483                 {
    00484                         register javaint tmp = *i;
    00485                         *(i++) = swap32(tmp);
    00486                         count--;
    00487                 }
    00488         }
    00489         #endif
    00490         return rc;
    00491 }
    00492 /*@=boundswrite@*/
    00493
    00494 /*@-boundswrite@*/
    00495 int readChars(javachar* c, FILE* ifp, int count)
    00496 {
    00497         register int rc = fread(c, 2, count, ifp);
    00498         #if !(WORDS_BIGENDIAN)
    00499         if (rc == count)
    00500         {
    00501                 while (count > 0)
    00502                 {
    00503                         register javachar tmp = *c;
    00504                         *(c++) = swap16(tmp);
    00505                         count--;
    00506                 }
    00507         }
    00508         #endif
    00509         return rc;
    00510 }
    00511 /*@=boundswrite@*/
    00512
    00513 int writeByte(javabyte b, FILE* ofp)
    00514 {
    00515 /*@-boundsread@*/
    00516         return fwrite(&b, 1, 1, ofp);
    00517 /*@=boundsread@*/
    00518 }
    00519
    00520 int writeShort(javashort s, FILE* ofp)
    00521 {
    00522         #if !(WORDS_BIGENDIAN)
    00523         s = swap16(s);
    00524         #endif
    00525 /*@-boundsread@*/
    00526         return fwrite(&s, 2, 1, ofp);
    00527 /*@=boundsread@*/
    00528 }
    00529
    00530 int writeInt(javaint i, FILE* ofp)
    00531 {
    00532         #if !(WORDS_BIGENDIAN)
    00533         i = swap32(i);
    00534         #endif
    00535 /*@-boundsread@*/
    00536         return fwrite(&i, 4, 1, ofp);
    00537 /*@=boundsread@*/
    00538 }
    00539
    00540 int writeLong(javalong l, FILE* ofp)
    00541 {
    00542         #if !(WORDS_BIGENDIAN)
    00543         l = swap64(l);
    00544         #endif
    00545 /*@-boundsread@*/
    00546         return fwrite(&l, 8, 1, ofp);
    00547 /*@=boundsread@*/
    00548 }
    00549
    00550 int writeChar(javachar c, FILE* ofp)
    00551 {
    00552         #if !(WORDS_BIGENDIAN)
    00553         c = swap16(c);
    00554         #endif
    00555 /*@-boundsread@*/
    00556         return fwrite(&c, 2, 1, ofp);
    00557 /*@=boundsread@*/
    00558 }
    00559
    00560 int writeInts(const javaint* i, FILE* ofp, int count)
    00561 {
    00562         #if WORDS_BIGENDIAN
    00563         return fwrite(i, 4, count, ofp);
    00564         #else
    00565         register int total = 0;
    00566         while (count-- > 0)
    00567         {
    00568 /*@-boundsread@*/
    00569                 register int rc = writeInt(*(i++), ofp);
    00570 /*@=boundsread@*/
    00571                 if (rc < 0)
    00572                         break;
    00573                 total += rc;
    00574         }
    00575         return total;
    00576         #endif
    00577 }
    00578
    00579 int writeChars(const javachar* c, FILE* ofp, int count)
    00580 {
    00581         #if WORDS_BIGENDIAN
    00582         return fwrite(c, 2, count, ofp);
    00583         #else
    00584         register int total = 0;
    00585         while (count-- > 0)
    00586         {
    00587 /*@-boundsread@*/
    00588                 register int rc = writeChar(*(c++), ofp);
    00589 /*@=boundsread@*/
    00590                 if (rc < 0)
    00591                         break;
    00592                 total += rc;
    00593         }
    00594         return total;
    00595         #endif
    00596 }