The little things give you away... A collection of various small helper stuff
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

115 lignes
3.3 KiB

  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <https://www.gnu.org/licenses/>.
  12. */
  13. // OrIdow6, late November 2021
  14. // stdin - a urlencoded string
  15. // stdout - the decoded string
  16. #define _GNU_SOURCE
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <stdint.h>
  20. #define BUFFER_SIZE 1024 * 300
  21. int main() {
  22. uint8_t* inbuf = malloc(sizeof(uint8_t) * BUFFER_SIZE);
  23. uint8_t* outbuf = malloc(sizeof(uint8_t) * BUFFER_SIZE + 2);
  24. size_t outp = 0;
  25. int state = -1;
  26. int8_t digita = 0x0;
  27. int8_t digitb = 0x0;
  28. uint8_t digita_real;
  29. uint8_t digitb_real;
  30. // https://stackoverflow.com/questions/10324/convert-a-hexadecimal-string-to-an-integer-efficiently-in-c
  31. // Because I can't be bothered to generate this manually
  32. // Could be faster if you had a table for 16-bit integers, depending on caching
  33. static const int8_t hextable[] = {
  34. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  35. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  36. -1,-1, 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1,
  37. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  38. -1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  39. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  40. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  41. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  42. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  43. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  44. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
  45. };
  46. while (1) {
  47. size_t readS = fread(inbuf, sizeof(char), BUFFER_SIZE, stdin);
  48. if (readS == 0) {
  49. break;
  50. }
  51. for (size_t p = 0; p < readS; p++) {
  52. if (state == -1) {
  53. if (inbuf[p] != '%') {
  54. outbuf[outp++] = inbuf[p];
  55. } else {
  56. state = 0;
  57. }
  58. } else if (state == 0) {
  59. digita = hextable[inbuf[p]];
  60. if (digita == (int8_t)-1 ) {
  61. outbuf[outp++] = '%';
  62. if (inbuf[p] != '%') {
  63. outbuf[outp++] = inbuf[p];
  64. state = -1;
  65. } // else state remains 0
  66. continue;
  67. }
  68. digita_real = inbuf[p];
  69. state = 1;
  70. } else {
  71. digitb = hextable[inbuf[p]];
  72. if (digitb == (int8_t)-1 ) {
  73. digitb_real = inbuf[p];
  74. outbuf[outp++] = '%';
  75. outbuf[outp++] = digita_real;
  76. if (inbuf[p] != '%') {
  77. outbuf[outp++] = digitb_real;
  78. state = -1;
  79. } else {
  80. state = 0;
  81. }
  82. continue;
  83. }
  84. outbuf[outp++] = digita << 4 | digitb;
  85. state = -1;
  86. }
  87. }
  88. fwrite(outbuf, outp, 1, stdout);
  89. outp = 0;
  90. if (readS < BUFFER_SIZE) {
  91. break;
  92. }
  93. }
  94. if (state == 0 || state == 1) {
  95. fwrite("%", 1, 1, stdout);
  96. }
  97. if (state == 1) {
  98. fwrite(&digita_real, 1, 1, stdout);
  99. }
  100. }