RSeries astromech firmware
URLQueryString.h
Go to the documentation of this file.
1 #ifndef URLQueryString_h
2 #define URLQueryString_h
3 
5 {
6 public:
7  URLQueryString(String query)
8  {
9  strncpy(fQueryBuffer, query.c_str(), sizeof(fQueryBuffer)-1);
10  fNumParams = parse(fQueryBuffer, '&', fParams, SizeOfArray(fParams));
11  }
12 
13  bool getOptional(const char* id, String& value)
14  {
15  return get(id, value, false);
16  }
17 
18  bool get(const char* id, String& value, bool expected = true)
19  {
20  for (int i = 0; i < fNumParams; i++)
21  {
22  if (strcmp(id, fParams[i].key) == 0)
23  {
24  value = String(fParams[i].val);
25  return true;
26  }
27  }
28  if (expected)
29  {
30  DEBUG_PRINT("QUERY ARG NOT FOUND: \""); DEBUG_PRINT(id); DEBUG_PRINTLN("\"");
31  }
32  return false;
33  }
34 
35 private:
36  struct Param
37  {
38  char* key;
39  char* val;
40  };
41 
42  char fQueryBuffer[1024];
43  Param fParams[10];
44  int fNumParams;
45 
46  static void unescape(char* str)
47  {
48  char* e;
49  while ((e = strchr(str, '%')) != NULL)
50  {
51  unsigned i = 0;
52  uint8_t ch = 0;
53  uint8_t ec = e[1];
54  if ((ec >= '0' && ec <= '9')) {
55  ch = ec - '0'; i++;
56  } else if (ec >= 'a' && ec <= 'f') {
57  ch = ec - 'a' + 10; i++;
58  } else if (ec >= 'A' && ec <= 'F') {
59  ch = ec - 'a' + 10; i++;
60  }
61  ec = e[2];
62  if ((ec >= '0' && ec <= '9')) {
63  ch = (ch << 4) | (ec - '0'); i++;
64  } else if (ec >= 'a' && ec <= 'f') {
65  ch = (ch << 4) | (ec - 'a' + 10); i++;
66  }
67  else if (ec >= 'A' && ec <= 'F') {
68  ch = (ch << 4) | (ec - 'A' + 10); i++;
69  }
70  if (i != 0)
71  {
72  e[0] = ch;
73  memmove(&e[1], &e[3], strlen(&e[3])+1);
74  }
75  }
76  while ((e = strchr(str, '+')) != NULL)
77  {
78  *e = ' ';
79  }
80  }
81 
82  static int parse(char *query, char delimiter, Param* params, int max_params)
83  {
84  int i = 0;
85 
86  if (NULL == query || '\0' == *query) {
87  return -1;
88  }
89 
90  params[i++].key = query;
91  while (i < max_params && NULL != (query = strchr(query, delimiter)))
92  {
93  *query = '\0';
94  params[i].key = ++query;
95  params[i].val = NULL;
96 
97  /* Go back and split previous param */
98  if (i > 0)
99  {
100  if ((params[i - 1].val = strchr(params[i - 1].key, '=')) != NULL)
101  {
102  *(params[i - 1].val)++ = '\0';
103  unescape(params[i - 1].val);
104  }
105  }
106  i++;
107  }
108 
109  /* Go back and split last param */
110  if ((params[i - 1].val = strchr(params[i - 1].key, '=')) != NULL)
111  {
112  *(params[i - 1].val)++ = '\0';
113  unescape(params[i - 1].val);
114  }
115  return i;
116  }
117 };
118 #endif
URLQueryString::URLQueryString
URLQueryString(String query)
Definition: URLQueryString.h:7
URLQueryString::getOptional
bool getOptional(const char *id, String &value)
Definition: URLQueryString.h:13
DEBUG_PRINT
#define DEBUG_PRINT(s)
Definition: ReelTwo.h:189
DEBUG_PRINTLN
#define DEBUG_PRINTLN(s)
Definition: ReelTwo.h:188
URLQueryString::get
bool get(const char *id, String &value, bool expected=true)
Definition: URLQueryString.h:18
URLQueryString
Definition: URLQueryString.h:4
SizeOfArray
#define SizeOfArray(arr)
Definition: ReelTwo.h:213