⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wapcvt.c

📁 是一个手机功能的模拟程序
💻 C
字号:
/*
 * Copyright (C) Ericsson Mobile Communications AB, 2000.
 * Licensed to AU-System AB.
 * All rights reserved.
 *
 * This software is covered by the license agreement between
 * the end user and AU-System AB, and may be used and copied
 * only in accordance with the terms of the said agreement.
 *
 * Neither Ericsson Mobile Communications AB nor AU-System AB
 * assumes any responsibility or liability for any errors or inaccuracies in
 * this software, or any consequential, incidental or indirect damage arising
 * out of the use of the Generic WAP Client software.
 */
/*
 * wapcvt.c
 *
 * Created by Anders Edenbrandt, Mon Nov 20 15:27:30 2000.
 *
 * Revision history:
 *
 */
/************************************************************
 * Functions to convert between an external and an internal
 * representation.
 *
 * All decoding and encoding functions take a pointer to a
 * "conversion object" (see type definition below) as
 * the first argument. Usually, the second argument is a pointer
 * to an element of the type to be converted.
 *
 * There are five different conversion operations:
 *   WAP_CVT_DECODE         convert from external to internal representation
 *   WAP_CVT_DECODE_STATIC  as above, but don't allocate any memory, just
 *                            set pointers into the given buffer
 *   WAP_CVT_ENCODE         convert from internal to external representation
 *   WAP_CVT_ENCODE_SIZE    calculate the buffer size required to do an
 *                            encoding operation
 *   WAP_CVT_FREE           deallocate any vectors that were allocated as
 *                            part of a previous decoding operation
 *
 * Each function returns TRUE on success and FALSE on error.
 *
 ************************************************************/
#include "confvars.h"
#include "ansilibs.h"

#include "wapcvt.h"
#include "cmmnrsrc.h"

/************************************************************
 * Macro definitions
 ************************************************************/

#define WAP_CVT_GET_BYTE(obj)    ((obj)->data[(obj)->pos++])
#define WAP_CVT_PUT_BYTE(obj, b) ((obj)->data[(obj)->pos++] = (b))

/*
 * Return the number of bytes remaining in the buffer.
 */
#define WAP_CVT_REM_LENGTH(str) ((str)->length - (str)->pos)



/************************************************************
 * Conversion routines
 ************************************************************/

/*
 * Prepare a conversion object for a specific operation,
 * using the indicated buffer of given length.
 */
void
wap_cvt_init (wap_cvt_t *obj, UINT8 operation, BYTE *buf, UINT32 length)
{
  obj->operation = operation;
  obj->data = buf;
  obj->length = length;
  obj->pos = 0;
}

/*
 * Convert a 1-byte unsigned integer.
 */
INT16
wap_cvt_uint8 (wap_cvt_t *obj, UINT8 *p)
{
  switch (obj->operation) {
  case WAP_CVT_DECODE:
  case WAP_CVT_DECODE_STATIC:
    if (WAP_CVT_REM_LENGTH (obj) < 1)
      return FALSE;
    *p = WAP_CVT_GET_BYTE (obj);
    break;

  case WAP_CVT_ENCODE:
    if (WAP_CVT_REM_LENGTH (obj) < 1)
      return FALSE;
    WAP_CVT_PUT_BYTE (obj, *p);
    break;

  case WAP_CVT_ENCODE_SIZE:
    obj->pos += 1;
    break;

  case WAP_CVT_FREE:
    break;

  default:
    return FALSE;
  }

  return TRUE;
}

/*
 * Convert a 1-byte signed integer in two's complement format.
 */
INT16
wap_cvt_int8 (wap_cvt_t *obj, INT8 *p)
{
  BYTE a;

  switch (obj->operation) {
  case WAP_CVT_DECODE:
  case WAP_CVT_DECODE_STATIC:
    if (WAP_CVT_REM_LENGTH (obj) < 1)
      return FALSE;
    a = WAP_CVT_GET_BYTE (obj);
    if (a & 0x80) {
      /* We have a negative number */
      a = (UINT8)(a & 0x7f);
      if (a == 0)
        return FALSE; /* Error, because this might overflow */
      a = (BYTE)((0x7f - a) + 1);
      *p = -(INT8)a;
    }
    else {
      *p = (INT8)a;
    }
    break;

  case WAP_CVT_ENCODE:
    if (WAP_CVT_REM_LENGTH (obj) < 1)
      return FALSE;
    if (*p < 0) {
      a = (BYTE)((0x7f + *p) + 1);
      a |= 0x80;
    }
    else {
      a = (UINT8)*p;
    }
    WAP_CVT_PUT_BYTE (obj, a);
    break;

  case WAP_CVT_ENCODE_SIZE:
    obj->pos += 1;
    break;

  case WAP_CVT_FREE:
    break;

  default:
    return FALSE;
  }

  return TRUE;
}

/*
 * Convert a 2-byte unsigned integer in big-endian format.
 */
INT16
wap_cvt_uint16 (wap_cvt_t *obj, UINT16 *p)
{
  BYTE a, b;

  switch (obj->operation) {
  case WAP_CVT_DECODE:
  case WAP_CVT_DECODE_STATIC:
    if (WAP_CVT_REM_LENGTH (obj) < 2)
      return FALSE;
    a = WAP_CVT_GET_BYTE (obj);
    b = WAP_CVT_GET_BYTE (obj);
    *p = (UINT16)(((UINT16)a << 8) | (UINT16)b);
    break;

  case WAP_CVT_ENCODE:
    if (WAP_CVT_REM_LENGTH (obj) < 2)
      return FALSE;
    WAP_CVT_PUT_BYTE (obj, (UINT8)((*p >> 8) & 0xff));
    WAP_CVT_PUT_BYTE (obj, (UINT8)(*p & 0xff));
    break;

  case WAP_CVT_ENCODE_SIZE:
    obj->pos += 2;
    break;

  case WAP_CVT_FREE:
    break;

  default:
    return FALSE;
  }

  return TRUE;
}

/*
 * Convert a 2-byte signed integer in big-endian, two's complement format.
 */
INT16
wap_cvt_int16 (wap_cvt_t *obj, INT16 *p)
{
  BYTE   a, b;
  UINT16 n;

  switch (obj->operation) {
  case WAP_CVT_DECODE:
  case WAP_CVT_DECODE_STATIC:
    if (WAP_CVT_REM_LENGTH (obj) < 2)
      return FALSE;
    a = WAP_CVT_GET_BYTE (obj);
    b = WAP_CVT_GET_BYTE (obj);
    n = (UINT16)(((UINT16)a << 8) | (UINT16)b);
    if (n & 0x8000) {
      /* We have a negative number */
      n = (UINT16)(n & 0x7fff);
      if (n == 0)
        return FALSE; /* Error, because this might overflow */
      n = (UINT16)((0x7fff - n) + 1);
      *p = -(INT16)n;
    }
    else {
      *p = (INT16)n;
    }
    break;

  case WAP_CVT_ENCODE:
    if (WAP_CVT_REM_LENGTH (obj) < 2)
      return FALSE;
    if (*p < 0) {
      n = (UINT16)((0x7fff + *p) + 1);
      n |= 0x8000;
    }
    else {
      n = *p;
    }
    WAP_CVT_PUT_BYTE (obj, (UINT8)((n >> 8) & 0xff));
    WAP_CVT_PUT_BYTE (obj, (UINT8)(n & 0xff));
    break;

  case WAP_CVT_ENCODE_SIZE:
    obj->pos += 2;
    break;

  case WAP_CVT_FREE:
    break;

  default:
    return FALSE;
  }

  return TRUE;
}

/*
 * Convert a 4-byte unsigned integer in big-endian format.
 */
INT16
wap_cvt_uint32 (wap_cvt_t *obj, UINT32 *p)
{
  BYTE a, b, c, d;

  switch (obj->operation) {
  case WAP_CVT_DECODE:
  case WAP_CVT_DECODE_STATIC:
    if (WAP_CVT_REM_LENGTH (obj) < 4)
      return FALSE;
    a = WAP_CVT_GET_BYTE (obj);
    b = WAP_CVT_GET_BYTE (obj);
    c = WAP_CVT_GET_BYTE (obj);
    d = WAP_CVT_GET_BYTE (obj);
    *p = ((UINT32)a << 24) | ((UINT32)b << 16) | ((UINT32)c << 8) | (UINT32)d;
    break;

  case WAP_CVT_ENCODE:
    if (WAP_CVT_REM_LENGTH (obj) < 4)
      return FALSE;
    WAP_CVT_PUT_BYTE (obj, (UINT8)((*p >> 24) & 0xff));
    WAP_CVT_PUT_BYTE (obj, (UINT8)((*p >> 16) & 0xff));
    WAP_CVT_PUT_BYTE (obj, (UINT8)((*p >> 8) & 0xff));
    WAP_CVT_PUT_BYTE (obj, (UINT8)(*p & 0xff));
    break;

  case WAP_CVT_ENCODE_SIZE:
    obj->pos += 4;
    break;

  case WAP_CVT_FREE:
    break;

  default:
    return FALSE;
  }

  return TRUE;
}

/*
 * Convert a 4-byte signed integer in big-endian, two's complement format.
 */
INT16
wap_cvt_int32 (wap_cvt_t *obj, INT32 *p)
{
  BYTE   a, b, c, d;
  UINT32 n;

  switch (obj->operation) {
  case WAP_CVT_DECODE:
  case WAP_CVT_DECODE_STATIC:
    if (WAP_CVT_REM_LENGTH (obj) < 4)
      return FALSE;
    a = WAP_CVT_GET_BYTE (obj);
    b = WAP_CVT_GET_BYTE (obj);
    c = WAP_CVT_GET_BYTE (obj);
    d = WAP_CVT_GET_BYTE (obj);
    n = ((UINT32)a << 24) | ((UINT32)b << 16) | ((UINT32)c << 8) | (UINT32)d;
    if (n & 0x8000) {
      /* We have a negative number */
      n = (UINT32)(n & 0x7fffffff);
      if (n == 0)
        return FALSE; /* Error, because this might overflow */
      n = (0x7fffffff - n) + 1;
      *p = -(INT32)n;
    }
    else {
      *p = (INT32)n;
    }
    break;

  case WAP_CVT_ENCODE:
    if (WAP_CVT_REM_LENGTH (obj) < 4)
      return FALSE;
    if (*p < 0) {
      n = (0x7fffffff + *p) + 1;
      n |= 0x80000000;
    }
    else {
      n = *p;
    }
    WAP_CVT_PUT_BYTE (obj, (UINT8)((n >> 24) & 0xff));
    WAP_CVT_PUT_BYTE (obj, (UINT8)((n >> 16) & 0xff));
    WAP_CVT_PUT_BYTE (obj, (UINT8)((n >> 8) & 0xff));
    WAP_CVT_PUT_BYTE (obj, (UINT8)(n & 0xff));
    break;

  case WAP_CVT_ENCODE_SIZE:
    obj->pos += 4;
    break;

  case WAP_CVT_FREE:
    break;

  default:
    return FALSE;
  }

  return TRUE;
}

/*
 * Return the number of bytes required to store n as a Uintvar.
 */
UINT8
wap_cvt_uintvar_len (UINT32 n)
{
  if (n < 0x80)
    return 1;
  else if (n < 0x4000)
    return 2;
  else if (n < 0x200000)
    return 3;
  else if (n < 0x10000000)
    return 4;
  else
    return 5;
}

/*
 * Convert a Uintvar.
 */
INT16
wap_cvt_uintvar (wap_cvt_t *obj, UINT32 *p)
{
  switch (obj->operation) {
  case WAP_CVT_DECODE:
  case WAP_CVT_DECODE_STATIC:
    {
      UINT32 n = 0;
      UINT8  k = 0;
      BYTE   b;

      do {
        if (WAP_CVT_REM_LENGTH (obj) <= 0)
          return FALSE;
        b = WAP_CVT_GET_BYTE (obj);
        n <<= 7;
        n |= (b & 0x7f);
        k++;
        if (k > 5)
          return FALSE;
      } while (b > 0x7f);
      *p = n;
    }
    break;

  case WAP_CVT_ENCODE:
    {
      UINT32 n = *p;
      UINT8  k = wap_cvt_uintvar_len (n);
      BYTE   b;

      if (WAP_CVT_REM_LENGTH (obj) < k)
        return FALSE;
      for (; k > 0; k--) {
        b = (BYTE)((n >> ((k - 1) * 7)) & 0x7f);
        if (k > 1)
          b |= 0x80;
        WAP_CVT_PUT_BYTE (obj, b);
      }
    }
    break;

  case WAP_CVT_ENCODE_SIZE:
    obj->pos += wap_cvt_uintvar_len (*p);
    break;

  case WAP_CVT_FREE:
    break;

  default:
    return FALSE;
  }

  return TRUE;
}

/*
 * Convert a static bytevector, i.e., a vector whose internal
 * representation is a static vector (e.g., BYTE v[12];).
 */
INT16
wap_cvt_static_bytevector (wap_cvt_t *obj, UINT32 length, BYTE *p)
{
  switch (obj->operation) {
  case WAP_CVT_DECODE:
  case WAP_CVT_DECODE_STATIC:
    if (WAP_CVT_REM_LENGTH (obj) < length)
      return FALSE;
    memcpy (p, obj->data + obj->pos, length);
    obj->pos += length;
    break;

  case WAP_CVT_ENCODE:
    if (WAP_CVT_REM_LENGTH (obj) < length)
      return FALSE;
    memcpy (obj->data + obj->pos, p, length);
    /* Fall through */

  case WAP_CVT_ENCODE_SIZE:
    obj->pos += length;
    break;

  case WAP_CVT_FREE:
    break;

  default:
    return FALSE;
  }

  return TRUE;
}

/*
 * Convert a byte vector, i.e., a vector whose internal representation
 * is a pointer to a byte (BYTE *v;).
 */
INT16
wap_cvt_bytevector (wap_cvt_t *obj, UINT32 length, BYTE **p)
{
  switch (obj->operation) {
  case WAP_CVT_DECODE:
    if (WAP_CVT_REM_LENGTH (obj) < length) {
      *p = NULL;
      return FALSE;
    }
    if (length == 0) {
      *p = NULL;
      break;
    }
    *p = OSConnectorAlloc (length);
    memcpy (*p, obj->data + obj->pos, length);
    obj->pos += length;
    break;

  case WAP_CVT_DECODE_STATIC:
    if (WAP_CVT_REM_LENGTH (obj) < length) {
      *p = NULL;
      return FALSE;
    }
    if (length == 0) {
      *p = NULL;
      break;
    }
    *p = obj->data + obj->pos;
    obj->pos += length;
    break;

  case WAP_CVT_ENCODE:
    if (WAP_CVT_REM_LENGTH (obj) < length)
      return FALSE;
    memcpy (obj->data + obj->pos, *p, length);
    /* Fall through */

  case WAP_CVT_ENCODE_SIZE:
    obj->pos += length;
    break;

  case WAP_CVT_FREE:
    DEALLOC (p);
    break;

  default:
    return FALSE;
  }

  return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -