reSIProcate/stack  9694
Embedded.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 
00006 #include <cassert>
00007 
00008 #include "resip/stack/Embedded.hxx"
00009 #include "rutil/Data.hxx"
00010 #include "resip/stack/Symbols.hxx"
00011 #include "rutil/WinLeakCheck.hxx"
00012 
00013 using namespace resip;
00014 
00015 char fromHex(char h1, char h2)
00016 {
00017    h1 = toupper(h1);
00018    h2 = toupper(h2);
00019 
00020    int i1;
00021    int i2;
00022 
00023    if (isdigit(h1))
00024    {
00025       i1 = h1 - '0';
00026    }
00027    else
00028    {
00029       i1 = h1 - 'A' + 10;
00030    }
00031 
00032    if (isdigit(h2))
00033    {
00034       i2 = h2 - '0';
00035    }
00036    else
00037    {
00038       i2 = h2 - 'A' + 10;
00039    }
00040    
00041    return i1*16+i2;
00042 }
00043 
00044 char*
00045 Embedded::decode(const Data& in, unsigned int& count)
00046 {
00047    const char *get = in.data();
00048    const char *end = get + in.size();
00049    char *ret = new char[in.size()];
00050    char *put = ret;
00051 
00052    count = 0;
00053    while (get < end)
00054    {
00055       if (*get == Symbols::PERCENT[0] && get+2 < end)
00056       {
00057          *put = fromHex(*(get+1), *(get+2));
00058          get += 3;
00059       }
00060       else
00061       {
00062          *put = *get;
00063          get++;
00064       }
00065       count++;
00066       put++;
00067    }
00068 
00069    return ret;
00070 }
00071 
00072 static char hexMap[] = "0123456789ABCDEF";
00073 
00074 /*
00075   This method encodes the hname and hvalue production of SIP-URI.
00076 
00077     SIP-URI          =  "sip:" [ userinfo ] hostport
00078                         uri-parameters [ headers ]
00079 
00080     headers         =  "?" header *( "&" header )
00081     header          =  hname "=" hvalue
00082     hname           =  1*( hnv-unreserved / unreserved / escaped )
00083     hvalue          =  *( hnv-unreserved / unreserved / escaped )
00084 
00085     hnv-unreserved  =  "[" / "]" / "/" / "?" / ":" / "+" / "$"
00086 
00087     unreserved  =  alphanum / mark
00088     mark        =  "-" / "_" / "." / "!" / "~" / "*" / "'"
00089                    / "(" / ")"
00090     escaped     =  "%" HEXDIG HEXDIG
00091 
00092     alphanum  =  ALPHA / DIGIT
00093 
00094   It is both unsafe and unwise to express what needs to be escaped
00095   and simply not escape everything else, because the omission of an item
00096   in need of escaping will cause mis-parsing on the remote end.
00097   Because escaping unnecessarily causes absolutely no harm, the omission
00098   of a symbol from the list of items positively allowed causes no
00099   damage whatsoever.
00100 */
00101 
00102 Data
00103 Embedded::encode(const Data& dat)
00104 {
00105    Data out((int)((dat.size()*11)/10), Data::Preallocate);
00106    
00107    {
00108       DataStream str(out);
00109       for (Data::size_type i = 0; i < dat.size(); i++)
00110       {
00111          switch (dat[i])
00112          {
00113             case '0': case '1': case '2': case '3': case '4': case '5':
00114             case '6': case '7': case '8': case '9': case 'a': case 'b':
00115             case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
00116             case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
00117             case 'o': case 'p': case 'q': case 'r': case 's': case 't':
00118             case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
00119             case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
00120             case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
00121             case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
00122             case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
00123             case 'Y': case 'Z': case '[': case ']': case ',': case '?':
00124             case ':': case '+': case '$': case '-': case '_': case '.':
00125             case '!': case '~': case '*': case '\'': case '(': case ')':
00126                str << dat[i];
00127                break;
00128 
00129             default:
00130             {
00131                str << Symbols::PERCENT;
00132 
00133                unsigned char temp = dat[i];
00134                int hi = (temp & 0xf0)>>4;
00135                int low = (temp & 0xf);
00136 
00137                str << hexMap[hi];
00138                str << hexMap[low];
00139             }
00140          }
00141       }
00142    }
00143 
00144    return out;
00145 }
00146 /* ====================================================================
00147  * The Vovida Software License, Version 1.0 
00148  * 
00149  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00150  * 
00151  * Redistribution and use in source and binary forms, with or without
00152  * modification, are permitted provided that the following conditions
00153  * are met:
00154  * 
00155  * 1. Redistributions of source code must retain the above copyright
00156  *    notice, this list of conditions and the following disclaimer.
00157  * 
00158  * 2. Redistributions in binary form must reproduce the above copyright
00159  *    notice, this list of conditions and the following disclaimer in
00160  *    the documentation and/or other materials provided with the
00161  *    distribution.
00162  * 
00163  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00164  *    and "Vovida Open Communication Application Library (VOCAL)" must
00165  *    not be used to endorse or promote products derived from this
00166  *    software without prior written permission. For written
00167  *    permission, please contact vocal@vovida.org.
00168  *
00169  * 4. Products derived from this software may not be called "VOCAL", nor
00170  *    may "VOCAL" appear in their name, without prior written
00171  *    permission of Vovida Networks, Inc.
00172  * 
00173  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00174  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00175  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00176  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00177  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00178  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00179  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00180  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00181  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00182  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00183  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00184  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00185  * DAMAGE.
00186  * 
00187  * ====================================================================
00188  * 
00189  * This software consists of voluntary contributions made by Vovida
00190  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00191  * Inc.  For more information on Vovida Networks, Inc., please see
00192  * <http://www.vovida.org/>.
00193  *
00194  */