/parser/urldecode.cpp

https://bitbucket.org/windoze/argos · C++ · 86 lines · 73 code · 6 blank · 7 comment · 19 complexity · b17a1c7b875efcb4024e96fec5741290 MD5 · raw file

  1. //
  2. // urldecode.cpp
  3. // Argos
  4. //
  5. // Created by Windoze on 12-7-6.
  6. // Copyright (c) 2012 0d0a.com. All rights reserved.
  7. //
  8. #include <stddef.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #ifdef __GNUC__
  12. #pragma GCC diagnostic ignored "-Wsign-compare"
  13. #pragma GCC diagnostic ignored "-Wsign-conversion"
  14. #endif
  15. namespace argos {
  16. namespace common {
  17. inline unsigned char hex_to_char(char c)
  18. {
  19. if (c>='0' && c<='9') {
  20. return c-'0';
  21. } else if(c>='A' && c<='F') {
  22. return c-'A'+0xA;
  23. } else if(c>='a' && c<='f') {
  24. return c-'a'+0xA;
  25. }
  26. return 0;
  27. }
  28. inline char hex_to_char(char c1, char c2)
  29. {
  30. return (char)((hex_to_char(c1)<<4) | hex_to_char(c2));
  31. }
  32. size_t urldecode_size(const char *source, size_t src_len)
  33. {
  34. if (src_len==0) {
  35. src_len=strlen(source);
  36. }
  37. size_t ret=0;
  38. for(size_t i = 0; i<src_len; i++, ret++)
  39. {
  40. if (source[i]=='%' && isxdigit(source[i + 1]) && isxdigit(source[i + 2])) {
  41. i += 2;
  42. }
  43. }
  44. return ret;
  45. }
  46. size_t urldecode(char *desc, const char *source, size_t src_len)
  47. {
  48. if (src_len==0) {
  49. src_len=strlen(source);
  50. }
  51. if (!desc) {
  52. return urldecode_size(source, src_len);
  53. }
  54. size_t ret=0;
  55. for(size_t i = 0; i<src_len; i++)
  56. {
  57. switch(source[i])
  58. {
  59. case '+':
  60. desc[ret++] = ' ';
  61. break;
  62. case '%':
  63. if(isxdigit(source[i + 1]) && isxdigit(source[i + 2]))
  64. {
  65. desc[ret++] = hex_to_char(source[i+1], source[i+2]);
  66. i += 2;
  67. }else {
  68. desc[ret++] = '%';
  69. }
  70. break;
  71. default:
  72. desc[ret++] = source[i];
  73. break;
  74. }
  75. }
  76. desc[ret]=0;
  77. return ret;
  78. }
  79. } // End of namespace common
  80. } // End of namespace argos