dencode.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  */
00032 
00033 /*
00034  * $Log: dencode.c,v $
00035  * Revision 1.6  2006/03/16 15:25:38  haraldkipp
00036  * Changed human readable strings from u_char to char to stop GCC 4 from
00037  * nagging about signedness.
00038  *
00039  * Revision 1.5  2004/03/16 16:48:46  haraldkipp
00040  * Added Jan Dubiec's H8/300 port.
00041  *
00042  * Revision 1.4  2004/01/16 10:27:55  drsung
00043  * Another code size improvement.
00044  *
00045  * Revision 1.3  2003/11/27 08:46:41  drsung
00046  * Code size improvement
00047  *
00048  * Revision 1.2  2003/11/27 08:30:54  drsung
00049  * Bug fix
00050  *
00051  */
00052  
00053 #include "dencode.h"
00054 
00055 /* Base-64 decoding.  This represents binary data as printable ASCII
00056 ** characters.  Three 8-bit binary bytes are turned into four 6-bit
00057 ** values, like so:
00058 **
00059 **   [11111111]  [22222222]  [33333333]
00060 **
00061 **   [111111] [112222] [222233] [333333]
00062 **
00063 ** Then the 6-bit values are represented using the characters "A-Za-z0-9+/".
00064 */
00065 
00066 /* Since base-64 encodes strings do not have any character above 127,
00067  * we need just the first 128 bytes. Furthermore there is no char
00068  * below 32, so we can save 32 additional bytes of flash.
00069  */
00070 static prog_char base64dtab[96] = {
00071 /*
00072     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00073     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00074 */
00075     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
00076     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
00077     -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
00078     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
00079     -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
00080     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
00081 /*
00082     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00083     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00084     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00085     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00086     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00087     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00088     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00089     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 */
00090 };
00091 
00092 /*
00093  * Do base-64 decoding on a string. Ignore any non-base64 bytes.
00094  * Return the actual number of bytes generated. The decoded size will
00095  * be at most 3/4 the size of the encoded, and may be smaller if there
00096  * are padding characters (blanks, newlines).
00097  */
00098 char *NutDecodeBase64(char * str)
00099 {
00100     /* bug fix from Damian Slee. */
00101     char code;
00102     char *sp;
00103     char *tp;
00104     char last = -1;
00105     char step = 0;
00106 
00107     for (tp = sp = str; *sp; ++sp) {
00108         if (*sp < 32)
00109             continue;
00110         if ((code = PRG_RDB(&base64dtab[(int) *sp - 32])) == (char)-1)
00111             continue;
00112         switch (step++) {
00113         case 1:
00114             *tp++ = ((last << 2) | ((code & 0x30) >> 4));
00115             break;
00116         case 2:
00117             *tp++ = (((last & 0xf) << 4) | ((code & 0x3c) >> 2));
00118             break;
00119         case 3:
00120             *tp++ = (((last & 0x03) << 6) | code);
00121             step = 0;
00122             break;
00123         }
00124         last = code;
00125     }
00126     *tp = 0;
00127     return str;
00128 }
00129 
00130 int NutDecodeHex(char c)
00131 {
00132     if (c >= '0' && c <= '9')
00133         return c - '0';
00134     if (c >= 'a' && c <= 'f')
00135         return c - 'a' + 10;
00136     if (c >= 'A' && c <= 'F')
00137         return c - 'A' + 10;
00138     return -1;
00139 }
00140 
00141 char *NutDecodePath(char *path)
00142 {
00143     int x1;
00144     int x2;
00145     char *src = path;
00146     char *dst = path;
00147     char last = *path;
00148 
00149     if (last != '/')
00150         return 0;
00151     while (*++src) {
00152         if (*src == '%' &&
00153             (x1 = NutDecodeHex(*(src + 1))) >= 0 &&
00154             (x2 = NutDecodeHex(*(src + 2))) >= 0) {
00155             src += 2;
00156             if ((*src = x1 * 16 + x2) == 0)
00157                 break;
00158         }
00159         if (*src == '\\')
00160             *src = '/';
00161         if ((last != '.' && last != '/') || (*src != '.' && *src != '/'))
00162             *dst++ = last = *src;
00163 
00164     }
00165     *dst = 0;
00166 
00167     return path;
00168 }

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/