gb2312_to_ucs2.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**************************************************************************
  2. * Copyright (C), AirM2M Tech. Co., Ltd.
  3. *
  4. * Name: gb2312_to_ucs2.c
  5. * Author: liweiqiang
  6. * Version: V0.1
  7. * Date: 2013/11/26
  8. *
  9. * Description:
  10. * gb2312 ת»» ucs2
  11. **************************************************************************/
  12. #include <stdint.h>
  13. #include "stdio.h"
  14. #include "errno.h"
  15. #include "gb2312_to_ucs2_table.h"
  16. uint16_t gb2312_to_ucs(uint16_t gb2312)
  17. {
  18. uint16_t ucs;
  19. uint8_t gb = gb2312;
  20. if (gb < 0x80)
  21. {
  22. ucs = gb;
  23. }
  24. else
  25. {
  26. uint16_t offset = ((gb2312 >> 8) - 0xA0) * 94 + ((gb2312 & 0x00ff) - 0xA1);
  27. ucs = gb2312_to_ucs2_table[offset];
  28. }
  29. return ucs;
  30. }
  31. size_t iconv_gb2312_to_ucs2_endian(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft, int endian)
  32. {
  33. uint16_t offset,gb2312;
  34. char *gbbuf = *_inbuf;
  35. uint16_t *ucs2buf = (uint16_t*)*_outbuf;
  36. uint16_t ucs2;
  37. size_t ucs2len = 0;
  38. size_t inlen = *inbytesleft;
  39. size_t outlen = *outbytesleft;
  40. size_t ret = 0;
  41. while(inlen > 0)
  42. {
  43. if(ucs2len+2 > outlen)
  44. {
  45. errno = E2BIG;
  46. ret = -1;
  47. goto gb2312_to_ucs2_exit;
  48. }
  49. gb2312 = *gbbuf++;
  50. if(gb2312 < 0x80)
  51. {
  52. ucs2 = gb2312;
  53. inlen--;
  54. }
  55. else if(inlen >= 2)
  56. {
  57. gb2312 = (gb2312<<8) + ((*gbbuf++)&0x00ff);
  58. inlen -= 2;
  59. offset = ((gb2312>>8) - 0xA0)*94/*(0xFE-0xA1+1)*/ + ((gb2312&0x00ff) - 0xA1);
  60. ucs2 = gb2312_to_ucs2_table[offset];
  61. }
  62. else
  63. {
  64. break;
  65. }
  66. if(endian == 1)
  67. ucs2 = (ucs2<<8)|(ucs2>>8);
  68. *ucs2buf++ = ucs2;
  69. ucs2len += 2;
  70. }
  71. if(inlen > 0)
  72. {
  73. errno = EINVAL;
  74. ret = -1;
  75. }
  76. gb2312_to_ucs2_exit:
  77. *_inbuf = gbbuf;
  78. *inbytesleft = inlen;
  79. *outbytesleft -= ucs2len;
  80. return ret;
  81. }
  82. size_t iconv_gb2312_to_ucs2(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft)
  83. {
  84. return iconv_gb2312_to_ucs2_endian(_inbuf, inbytesleft, _outbuf, outbytesleft, 0);
  85. }
  86. size_t iconv_gb2312_to_ucs2be(char **_inbuf, size_t *inbytesleft, char **_outbuf, size_t *outbytesleft)
  87. {
  88. return iconv_gb2312_to_ucs2_endian(_inbuf, inbytesleft, _outbuf, outbytesleft, 1);
  89. }