Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

wsencode.c

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /*
00058  *
00059  * wsencode.c
00060  *
00061  * Author: Markku Rossi <mtr@iki.fi>
00062  *
00063  * Copyright (c) 1999-2000 WAPIT OY LTD.
00064  *       All rights reserved.
00065  *
00066  * Encoding and decoding routines.
00067  *
00068  */
00069 
00070 #include "wsint.h"
00071 
00072 /********************* Types and definitions ****************************/
00073 
00074 #define WS_MB_CONT_BIT  0x80
00075 #define WS_MB_DATA_MASK 0x7f
00076 
00077 /********************* Global functions *********************************/
00078 
00079 unsigned char *ws_encode_mb_uint32(WsUInt32 value, unsigned char *buffer,
00080                                    size_t *len_return)
00081 {
00082     unsigned char *p = buffer + WS_MB_UINT32_MAX_ENCODED_LEN;
00083     size_t len = 1;
00084 
00085     /* Set the terminator byte. */
00086     *p = value & WS_MB_DATA_MASK;
00087     value >>= 7;
00088     p--;
00089 
00090     /* And add the data. */
00091     while (value > 0) {
00092         *p = (value & WS_MB_DATA_MASK) | WS_MB_CONT_BIT;
00093         value >>= 7;
00094         p--;
00095         len++;
00096     }
00097 
00098     *len_return = len;
00099 
00100     return p + 1;
00101 }
00102 
00103 
00104 WsUInt32 ws_decode_mb_uint32(const unsigned char *buffer, size_t *len)
00105 {
00106     WsUInt32 value = 0;
00107     size_t i;
00108 
00109     for (i = 0; i < *len; i++) {
00110         value <<= 7;
00111         value |= buffer[i] & WS_MB_DATA_MASK;
00112 
00113         if ((buffer[i] & WS_MB_CONT_BIT) == 0)
00114             break;
00115     }
00116 
00117     *len = i + 1;
00118 
00119     return value;
00120 }
00121 
00122 
00123 WsBool ws_encode_buffer(WsBuffer *buffer, ...)
00124 {
00125     va_list ap;
00126     WsEncodingSpec spec;
00127     int ival;
00128     unsigned char *p;
00129     unsigned char *cp;
00130     size_t len;
00131     WsUInt32 ui32;
00132     unsigned char data[64];
00133 
00134     va_start(ap, buffer);
00135 
00136     while ((spec = va_arg(ap, int)) != WS_ENC_END)
00137     {
00138         switch (spec)
00139         {
00140         case WS_ENC_BYTE:
00141         case WS_ENC_INT8:
00142         case WS_ENC_UINT8:
00143             ival = va_arg(ap, int);
00144 
00145             if (!ws_buffer_append_space(buffer, &p, 1))
00146                 goto error;
00147 
00148             WS_PUT_UINT8(p, ival);
00149             break;
00150 
00151         case WS_ENC_INT16:
00152         case WS_ENC_UINT16:
00153             ival = va_arg(ap, int);
00154 
00155             if (!ws_buffer_append_space(buffer, &p, 2))
00156                 goto error;
00157 
00158             WS_PUT_UINT16(p, ival);
00159             break;
00160 
00161         case WS_ENC_INT32:
00162         case WS_ENC_UINT32:
00163             ival = va_arg(ap, long);
00164 
00165             if (!ws_buffer_append_space(buffer, &p, 4))
00166                 goto error;
00167 
00168             WS_PUT_UINT32(p, ival);
00169             break;
00170 
00171         case WS_ENC_MB_UINT16:
00172         case WS_ENC_MB_UINT32:
00173             if (spec == WS_ENC_MB_UINT16)
00174                 ui32 = va_arg(ap, int);
00175             else
00176                 ui32 = va_arg(ap, long);
00177 
00178             len = sizeof(data);
00179             cp = ws_encode_mb_uint32(ui32, data, &len);
00180 
00181             if (!ws_buffer_append_space(buffer, &p, len))
00182                 goto error;
00183 
00184             memcpy(p, cp, len);
00185             break;
00186 
00187         case WS_ENC_DATA:
00188             cp = va_arg(ap, unsigned char *);
00189             len = va_arg(ap, unsigned int);
00190 
00191             if (!ws_buffer_append_space(buffer, &p, len))
00192                 goto error;
00193 
00194             memcpy(p, cp, len);
00195             break;
00196 
00197         default:
00198             ws_fatal("ws_encode_buffer(): unknown type %d: probably a missing "
00199                      "WS_ENC_END",
00200                      spec);
00201             break;
00202         }
00203     }
00204 
00205     va_end(ap);
00206 
00207     return WS_TRUE;
00208 
00209 
00210     /*
00211      * Error handling.
00212      */
00213 
00214 error:
00215 
00216     va_end(ap);
00217 
00218     return WS_FALSE;
00219 }
00220 
00221 
00222 size_t ws_decode_buffer(const unsigned char *buffer, size_t buffer_len, ...)
00223 {
00224     va_list ap;
00225     WsEncodingSpec spec;
00226     WsUInt8 *i8p;
00227     WsUInt16 *i16p;
00228     WsUInt32 *i32p;
00229     unsigned char **cpp;
00230     size_t len;
00231     size_t orig_buffer_len = buffer_len;
00232 
00233     va_start(ap, buffer_len);
00234 
00235     while ((spec = va_arg(ap, int)) != WS_ENC_END) {
00236         switch (spec) {
00237         case WS_ENC_BYTE:
00238         case WS_ENC_INT8:
00239         case WS_ENC_UINT8:
00240             if (buffer_len < 1)
00241                 goto too_short_buffer;
00242 
00243             i8p = va_arg(ap, WsUInt8 *);
00244             WS_GET_UINT8(buffer, *i8p);
00245 
00246             buffer++;
00247             buffer_len--;
00248             break;
00249 
00250         case WS_ENC_INT16:
00251         case WS_ENC_UINT16:
00252             if (buffer_len < 2)
00253                 goto too_short_buffer;
00254 
00255             i16p = va_arg(ap, WsUInt16 *);
00256             WS_GET_UINT16(buffer, *i16p);
00257 
00258             buffer += 2;
00259             buffer_len -= 2;
00260             break;
00261 
00262         case WS_ENC_INT32:
00263         case WS_ENC_UINT32:
00264             if (buffer_len < 4)
00265                 goto too_short_buffer;
00266 
00267             i32p = va_arg(ap, WsUInt32 *);
00268             WS_GET_UINT32(buffer, *i32p);
00269 
00270             buffer += 4;
00271             buffer_len -= 4;
00272             break;
00273 
00274         case WS_ENC_MB_UINT16:
00275         case WS_ENC_MB_UINT32:
00276             {
00277                 size_t len = buffer_len;
00278                 WsUInt32 i32;
00279 
00280                 if (buffer_len < 1)
00281                     goto too_short_buffer;
00282 
00283                 i32 = ws_decode_mb_uint32(buffer, &len);
00284 
00285                 if (spec == WS_ENC_MB_UINT16) {
00286                     i16p = va_arg(ap, WsUInt16 *);
00287                     *i16p = i32;
00288                 } else {
00289                     i32p = va_arg(ap, WsUInt32 *);
00290                     *i32p = i32;
00291                 }
00292 
00293                 buffer += len;
00294                 buffer_len -= len;
00295             }
00296             break;
00297 
00298         case WS_ENC_DATA:
00299             cpp = va_arg(ap, unsigned char **);
00300             len = va_arg(ap, size_t);
00301 
00302             if (buffer_len < len)
00303                 goto too_short_buffer;
00304 
00305             *cpp = (unsigned char *) buffer;
00306             buffer += len;
00307             buffer_len -= len;
00308             break;
00309 
00310         default:
00311             ws_fatal("ws_encode_buffer(): unknown type %d: probably a missing "
00312                      "WS_ENC_END",
00313                      spec);
00314             break;
00315         }
00316     }
00317     va_end(ap);
00318 
00319     return orig_buffer_len - buffer_len;
00320 
00321 too_short_buffer:
00322 
00323     va_end(ap);
00324 
00325     return 0;
00326 }
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.