Back to index

lightning-sunbird  0.9+nobinonly
nsEscape.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Sean Su <ssu@netscape.com>
00024  *   Revision checked in on 01/03/30 by ssu@netscape.com, derived from:
00025  *   mozilla/xpcom/io/nsEscape.h
00026  *   mozilla/xpcom/io/nsEscape.cpp
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either of the GNU General Public License Version 2 or later (the "GPL"),
00030  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #ifdef __cplusplus
00043 extern "C"
00044 {
00045 #endif /* __cplusplus */
00046 
00047 #include "extern.h"
00048 #include "extra.h"
00049 
00050 #ifdef __cplusplus
00051 }
00052 #endif /* __cplusplus */
00053 
00054 #include "nsEscape.h"
00055 
00056 typedef int PRInt32;
00057 
00058 const int netCharType[256] =
00059 /*     Bit 0         xalpha        -- the alphas
00060 **     Bit 1         xpalpha              -- as xalpha but 
00061 **                             converts spaces to plus and plus to %20
00062 **     Bit 3 ...     path          -- as xalphas but doesn't escape '/'
00063 */
00064     /*   0 1 2 3 4 5 6 7 8 9 A B C D E F */
00065     {    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */
00066                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  /* 1x */
00067                0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4,  /* 2x   !"#$%&'()*+,-./      */
00068          7,7,7,7,7,7,7,7,7,7,0,0,0,7,0,0, /* 3x  0123456789:;<=>?      */
00069             0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,     /* 4x  @ABCDEFGHIJKLMNO  */
00070             /* bits for '@' changed from 7 to 0 so '@' can be escaped   */
00071             /* in usernames and passwords in publishing.                */
00072             7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7,     /* 5X  PQRSTUVWXYZ[\]^_      */
00073             0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,     /* 6x  `abcdefghijklmno      */
00074             7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,     /* 7X  pqrstuvwxyz{\}~      DEL */
00075                0, };
00076 
00077 /* decode % escaped hex codes into character values
00078  */
00079 #define UNHEX(C) \
00080     ((C >= '0' && C <= '9') ? C - '0' : \
00081      ((C >= 'A' && C <= 'F') ? C - 'A' + 10 : \
00082      ((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)))
00083 
00084 
00085 #define IS_OK(C) (netCharType[((unsigned int) (C))] & (mask))
00086 #define HEX_ESCAPE '%'
00087 
00088 //----------------------------------------------------------------------------------------
00089 NS_COM char* nsEscape(const char * str, nsEscapeMask mask)
00090 //----------------------------------------------------------------------------------------
00091 {
00092     if(!str)
00093         return NULL;
00094     return nsEscapeCount(str, strlen(str), mask, NULL);
00095 }
00096 
00097 //----------------------------------------------------------------------------------------
00098 NS_COM char* nsEscapeCount(
00099     const char * str,
00100     PRInt32 len,
00101     nsEscapeMask mask,
00102     PRInt32* out_len)
00103 //----------------------------------------------------------------------------------------
00104 {
00105        if (!str)
00106               return 0;
00107 
00108     int i, extra = 0;
00109     char* hexChars = "0123456789ABCDEF";
00110 
00111        register const unsigned char* src = (const unsigned char *) str;
00112     for (i = 0; i < len; i++)
00113        {
00114         if (!IS_OK(*src++))
00115             extra += 2; /* the escape, plus an extra byte for each nibble */
00116        }
00117 
00118        char* result = (char *)NS_GlobalAlloc(len + extra + 1);
00119     if (!result)
00120         return 0;
00121 
00122     register unsigned char* dst = (unsigned char *) result;
00123        src = (const unsigned char *) str;
00124        if (mask == url_XPAlphas)
00125        {
00126            for (i = 0; i < len; i++)
00127               {
00128                      unsigned char c = *src++;
00129                      if (IS_OK(c))
00130                             *dst++ = c;
00131                      else if (c == ' ')
00132                             *dst++ = '+'; /* convert spaces to pluses */
00133                      else 
00134                      {
00135                             *dst++ = HEX_ESCAPE;
00136                             *dst++ = hexChars[c >> 4];  /* high nibble */
00137                             *dst++ = hexChars[c & 0x0f];       /* low nibble */
00138                      }
00139               }
00140        }
00141        else
00142        {
00143            for (i = 0; i < len; i++)
00144               {
00145                      unsigned char c = *src++;
00146                      if (IS_OK(c))
00147                             *dst++ = c;
00148                      else 
00149                      {
00150                             *dst++ = HEX_ESCAPE;
00151                             *dst++ = hexChars[c >> 4];  /* high nibble */
00152                             *dst++ = hexChars[c & 0x0f];       /* low nibble */
00153                      }
00154               }
00155        }
00156 
00157     *dst = '\0';     /* tack on eos */
00158        if(out_len)
00159               *out_len = dst - (unsigned char *) result;
00160     return result;
00161 }
00162 
00163 //----------------------------------------------------------------------------------------
00164 NS_COM char* nsUnescape(char * str)
00165 //----------------------------------------------------------------------------------------
00166 {
00167        nsUnescapeCount(str);
00168        return str;
00169 }
00170 
00171 //----------------------------------------------------------------------------------------
00172 NS_COM PRInt32 nsUnescapeCount(char * str)
00173 //----------------------------------------------------------------------------------------
00174 {
00175     register char *src = str;
00176     register char *dst = str;
00177 
00178     while (*src)
00179         if (*src != HEX_ESCAPE)
00180               *dst++ = *src++;
00181         else  
00182               {
00183               src++; /* walk over escape */
00184               if (*src)
00185             {
00186               *dst = UNHEX(*src) << 4;
00187               src++;
00188             }
00189               if (*src)
00190             {
00191               *dst = (*dst + UNHEX(*src));
00192               src++;
00193             }
00194               dst++;
00195         }
00196 
00197     *dst = 0;
00198     return (int)(dst - str);
00199 
00200 } /* NET_UnEscapeCnt */
00201