Initial commit
[lnanohtmltiledmap.git] / html.c
blob0e44cb9f3a1f8a8dba430998d05118c7b645944c
1 #ifndef LNANOHTMLTILEDMAP_HTML_C
2 #define LNANOHTMLTILEDMAP_HTML_C
3 #include <stdbool.h>
4 #include <stdarg.h>
5 #include <ulinux/compiler_types.h>
6 #include <ulinux/types.h>
8 #include <ulinux/utils/ascii/string/vsprintf.h>
9 #include <ulinux/utils/ascii/block/conv/decimal/decimal.h>
11 #include "config.h"
12 #include "html.h"
13 /*============================================================================*/
14 #include "common_cpp.h"
15 #include "namespace/ulinux.h"
16 /*============================================================================*/
18 * decimal longitude/latitude: sign + integer part = 3 decimal digits (180)
19 * + radix + fractional part = 9 digits (micron/overkill precision)
21 #define GEO_DECIMAL_MAX "-123.123456789"
22 #define U32_DECIMAL_DIGITS_N_MAX "4294967295"
23 #define U64_HEXA_DIGITS_N_MAX "XXXXXXXXXXXXXXXX"
25 * this is an html template
26 * p suffix means prolog/header
27 * e suffix means epilog/trailer
29 /* we cheat: we generate the http response headers here */
30 #define MAJORTBL_P "\
31 HTTP/1.1 200 OK\r\n\
32 cache-control:no-cache\r\n\
33 connection:close\r\n\
34 content-type:text/html;charset=utf-8\r\n\
35 \r\n\
36 <html>\n\
37 <body>\n\
38 <table rules=\"all\" id=\"major_layout_table\">\n\
39 <tbody>\n\
40 <tr>\n\
41 <td id=\"tiles_cell\" align=\"center\">\n"
42 #define VIEWTBL_P "\
43 <table rules=\"all\" id=\"tiles_layout_table\" cellpadding=\"0\" cellspacing=\"0\">\n\
44 <tbody>\n"
45 /* min longitude, max longitude */
46 #define VIEWTBL_VERTHDRS_P "\
47 <tr>\n"
48 #define VIEWTBL_VERTHDRS_WEST "\
49 <th scope=\"col\" align=\"left\">%s</th>\n"
50 #define VIEWTBL_VERTHDRS_EAST "\
51 <th scope=\"col\" align=\"right\">%s</th>\n"
52 #define VIEWTBL_VERTHDRS_E "\
53 <th/>\n\
54 </tr>\n"
55 #define VIEWTBL_MAINROW_P "\
56 <tr>\n"
57 /* span horizontal headers rows and vertical header columns */
58 #define VIEWTBL_TILE "\
59 <td colspan=\"2\" rowspan=\"2\" align=\"center\" valign=\"middle\">\n\
60 <img src=\"" CONFIG_TILE_SVR "\"/>\n\
61 </td>\n"
62 /* min latitude */
63 #define VIEWTBL_MAINROW_HORIZTRAILER_CELL_TOP "\
64 <th valign=\"top\">%s</th>\n"
65 #define VIEWTBL_MAINROW_E "\
66 </tr>\n"
67 /* max latitude */
68 #define VIEWTBL_HORIZTRAILER_ROW_BOT "\
69 <tr>\n\
70 <th valign=\"bottom\">%s</th>\n\
71 </tr>\n"
72 #define VIEWTBL_E "\
73 </tbody>\n\
74 </table>\n"
75 #define MAJORTBL_VIEWTBL_TO_NAVFORM "\
76 </td>\n\
77 </tr>\n\
78 <tr>\n\
79 <td id=\"navigation_cell\" align=\"center\">\n\
80 <form action=\".\" method=\"get\">\n"
81 #define URANDOM "\
82 <input type=\"hidden\" name=\"urandom\" value=\"%u\"/>\n"
83 #define NAV_X "\
84 <input type=\"hidden\" name=\"x\" value=\"%u\"/>\n"
85 #define NAV_Y "\
86 <input type=\"hidden\" name=\"y\" value=\"%u\"/>\n"
87 #define NAVTBL_P "\
88 <table rules=\"all\">\n\
89 <tbody>\n\
90 <tr>\n\
91 <td colspan=\"2\" align=\"center\">\n\
92 <fieldset>\n\
93 <legend><em>center coordinates</em></legend>\n"
94 #define NAVTBL_LO "\
95 <label>longitude = <input name=\"lo\" type=\"text\" maxlength=\"14\" value=\"%s\"/></label>\n"
96 #define NAVTBL_LA "\
97 <label>latitude = <input name=\"la\" type=\"text\" maxlength=\"14\" value=\"%s\"/></label>\n"
98 #define NAVTBL_MIDDLE "\
99 <button name=\"nav\" value=\"geo_modify\">MODIFY</button>\n\
100 </td>\n\
101 </fieldset>\n\
102 </tr>\n\
103 <tr>\n\
104 <td align=\"center\">\n\
105 <fieldset>\n\
106 <legend><em>translation</em></legend>\n\
107 <table>\n\
108 <tbody>\n\
109 <tr>\n\
110 <td colspan=\"2\" align=\"center\">\n\
111 <button name=\"nav\" value=\"translation_north\">NORTH</button>\n\
112 </td>\n\
113 </tr>\n\
114 <tr>\n\
115 <td>\n\
116 <button name=\"nav\" value=\"translation_west\">WEST</button>\n\
117 </td>\n\
118 <td>\n\
119 <button name=\"nav\" value=\"translation_east\">EAST</button>\n\
120 </td>\n\
121 </tr>\n\
122 <tr>\n\
123 <td colspan=\"2\" align=\"center\">\n\
124 <button name=\"nav\" value=\"translation_south\">SOUTH</button>\n\
125 </td>\n\
126 </tr>\n\
127 </tbody>\n\
128 </table>\n\
129 </fieldset>\n\
130 </td>\n\
131 <td align=\"center\">\n\
132 <fieldset>\n\
133 <legend><em>zoom</em></legend>\n"
134 #define NAVTBL_ZOOM "\
135 <label>level = <input name=\"zoom\" type=\"text\" maxlength=\"2\" value=\"%u\"/></label>\n"
136 #define NAVTBL_E "\
137 <button name=\"nav\" value=\"zoom_modify\">MODIFY</button>\n\
138 <button name=\"nav\" value=\"zoom_plus\">PLUS</button>\n\
139 <button name=\"nav\" value=\"zoom_minus\">MINUS</button>\n\
140 </fieldset>\n\
141 </td>\n\
142 </tr>\n\
143 </tbody>\n\
144 </table>\n"
145 #define MAJORTBL_E "\
146 </form>\n\
147 </td>\n\
148 </tr>\n\
149 </tbody>\n\
150 </table>\n\
151 </body>\n\
152 </html>"
153 /* maximum sizes of template parts */
154 #define VIEWTBL_VERTHDRS_WEST_SZ_MAX \
155 (SZ(VIEWTBL_VERTHDRS_WEST) - SZ("%s") + SZ(GEO_DECIMAL_MAX))
157 #define VIEWTBL_VERTHDRS_EAST_SZ_MAX \
158 (SZ(VIEWTBL_VERTHDRS_EAST) - SZ("%s") + SZ(GEO_DECIMAL_MAX))
160 #define VIEWTBL_TILE_SZ_MAX \
161 (SZ(VIEWTBL_TILE) - (SZ("%c") + CONFIG_HORIZS_N_MAX * SZ("%u")) \
162 + SZ(CONFIG_TILE_SVR_MAX))
164 #define VIEWTBL_MAINROW_HORIZTRAILER_CELL_TOP_SZ_MAX \
165 (SZ(VIEWTBL_MAINROW_HORIZTRAILER_CELL_TOP) - SZ("%s") + SZ(GEO_DECIMAL_MAX))
167 #define VIEWTBL_HORIZTRAILER_ROW_BOT_SZ_MAX \
168 (SZ(VIEWTBL_HORIZTRAILER_ROW_BOT) - SZ("%s") + SZ(GEO_DECIMAL_MAX))
170 #define URANDOM_SZ_MAX \
171 (SZ(URANDOM) - SZ("%u") + SZ(U64_HEXA_DIGITS_N_MAX))
173 #define NAV_X_SZ_MAX \
174 (SZ(NAV_X) - SZ("%u") + SZ(U32_DECIMAL_DIGITS_N_MAX))
176 #define NAV_Y_SZ_MAX \
177 (SZ(NAV_Y) - SZ("%u") + SZ(U32_DECIMAL_DIGITS_N_MAX))
179 #define NAVTBL_LO_SZ_MAX \
180 (SZ(NAVTBL_LO) - SZ("%s") + SZ(GEO_DECIMAL_MAX))
182 #define NAVTBL_LA_SZ_MAX \
183 (SZ(NAVTBL_LA) - SZ("%s") + SZ(GEO_DECIMAL_MAX))
185 #define NAVTBL_ZOOM_SZ_MAX \
186 (SZ(NAVTBL_ZOOM) - SZ("%u") + SZ("99"))
187 static void tmpl_to_html(struct html_ctx_t *c, u8 *tmpl, u64 tmpl_sz_max, ...)
189 va_list ap;
190 u64 sz;
192 va_start(ap, tmpl_sz_max);
193 sz = vsnprintf(c->p, tmpl_sz_max, tmpl, ap);
194 va_end(ap);
195 if (sz > tmpl_sz_max)
196 ++(c->p); /* ERROR: empty string */
197 else
198 c->p += sz;
200 /* lo or la, longitude or latitude */
201 static void tmpl_lx_to_html(struct html_ctx_t *c, u8 *tmpl, u64 tmpl_sz_max,
202 f64 lx)
204 u8 lx_str[SZ(GEO_DECIMAL_MAX) + 1];
206 f64_to_str(lx, lx_str, sizeof(lx_str));
207 tmpl_to_html(c, tmpl, tmpl_sz_max, lx_str);
209 #define TMPL_LX_TO_HTML(c,tmpl,lx) \
210 tmpl_lx_to_html(c, tmpl, tmpl##_SZ_MAX, lx)
211 #define TMPL_TO_HTML(c,tmpl,...) \
212 tmpl_to_html(c,tmpl,tmpl##_SZ_MAX, __VA_ARGS__)
213 #define TXT_TO_HTML(x) \
214 memcpy(c->p, x, SZ(x));\
215 c->p += SZ(x);
216 /* XXX: should have the best 64bits float hex value (double) for PI approx */
217 #define PI 3.141592653589793238462643383279502884
218 static void html_geo_to_tile_center(struct html_ctx_t *c)
220 f64 la_rad; /* latitude in radian */
221 f64 arsinh_tan_la_rad;
222 /* exact location in "web mercator" coords */
223 f64 x_exact;
224 f64 y_exact;
226 * degree longitude: from -180 to +180, east -> positive,
227 * west -> negative
228 * tile coordinate: x coordinate starts at the internation date line
229 * (longitude * 180) degrees and goes from east to west. x >= 0.
230 * zoom: its power of 2 is the number of divisions of the raw degree
231 * longitude.
233 * degree latitute: from 90 to -90, north -> positive
234 * south -> negative
235 * tile coordinate: y coordinate starts an the north pole, then toward
236 * the south pole. y >= 0.
237 * zoom: it the power of 2 of the number of divisions of the "web
238 * mercator" (spherical->cylindrical) latitude projection
240 x_exact = (c->lo + 180.0) / 360.0 * (f64)(1 << c->zoom);
241 c->x = (u64)floor(x_exact);
242 la_rad = c->la * PI / 180.0;
243 /* arsinh(tan(α)) = ln((1 + sin(α)) / cos(α)) */
244 arsinh_tan_la_rad = log((1 + sin(la_rad)) / cos(la_rad));
245 y_exact = (1.0 - (arsinh_tan_la_rad / PI)) / 2.0
246 * (f64)(1 << c->zoom);
247 c->y = (u64)floor(y_exact);
249 static void html_geo_modify(struct html_ctx_t *c, struct html_query_t *q)
251 c->lo = q->lo;
252 c->la = q->la;
253 c->zoom = q->zoom;
254 html_geo_to_tile_center(c);
256 static void html_tile_center_to_geo(struct html_ctx_t *c)
258 f64 x_center;
259 f64 y_center;
260 f64 tmp;
262 x_center = (f64)(c->x) + 0.5;
263 c->lo = (x_center * 360.0) / (f64)(1 << c->zoom) - 180.0;
265 y_center = (f64)(c->y) + 0.5;
266 tmp = PI - 2.0 * PI * y_center / (f64)(1 << c->zoom);
267 c->la = 180.0 / PI * atan(0.5 * (exp(tmp) - exp(-tmp)));
269 static void html_translate_north(struct html_ctx_t *c, struct html_query_t *q)
271 c->x = q->x;
272 c->y = (q->y - 1) % (u32)(1 << q->zoom);
273 c->zoom = q->zoom;
275 html_tile_center_to_geo(c);
277 static void html_translate_south(struct html_ctx_t *c, struct html_query_t *q)
279 c->x = q->x;
280 c->y = (q->y + 1) % (u32)(1 << q->zoom);
281 c->zoom = q->zoom;
283 html_tile_center_to_geo(c);
285 static void html_translate_west(struct html_ctx_t *c, struct html_query_t *q)
287 c->x = (q->x - 1) % (u32)(1 << q->zoom);
288 c->y = q->y;
289 c->zoom = q->zoom;
291 html_tile_center_to_geo(c);
293 static void html_translate_east(struct html_ctx_t *c, struct html_query_t *q)
295 c->x = (q->x + 1) % (u32)(1 << q->zoom);
296 c->y = q->y;
297 c->zoom = q->zoom;
299 html_tile_center_to_geo(c);
301 static void html_zoom_plus(struct html_ctx_t *c, struct html_query_t *q)
303 c->lo = q->lo;
304 c->la = q->la;
305 c->zoom = q->zoom + 1;
306 html_geo_to_tile_center(c);
308 static void html_zoom_minus(struct html_ctx_t *c, struct html_query_t *q)
310 c->lo = q->lo;
311 c->la = q->la;
312 if (q->zoom != 0)
313 c->zoom = q->zoom - 1;
314 else
315 c->zoom = q->zoom;
316 html_geo_to_tile_center(c);
318 static void html_zoom_modify(struct html_ctx_t *c, struct html_query_t *q)
320 html_geo_modify(c, q);
322 static void html_gen_ctx_init_from_query(struct html_ctx_t *c,
323 struct html_query_t *q, u8 *buf, u64 urandom)
325 switch (q->nav_cmd) {
326 case HTML_QUERY_NAV_CMD_TRANSLATION_NORTH:
327 html_translate_north(c, q);
328 break;
329 case HTML_QUERY_NAV_CMD_TRANSLATION_SOUTH:
330 html_translate_south(c, q);
331 break;
332 case HTML_QUERY_NAV_CMD_TRANSLATION_WEST:
333 html_translate_west(c, q);
334 break;
335 case HTML_QUERY_NAV_CMD_TRANSLATION_EAST:
336 html_translate_east(c, q);
337 break;
338 case HTML_QUERY_NAV_CMD_ZOOM_PLUS:
339 html_zoom_plus(c, q);
340 break;
341 case HTML_QUERY_NAV_CMD_ZOOM_MINUS:
342 html_zoom_minus(c, q);
343 break;
344 case HTML_QUERY_NAV_CMD_ZOOM_MODIFY:
345 html_zoom_modify(c, q);
346 break;
347 case HTML_QUERY_NAV_CMD_GEO_MODIFY:
348 default:
349 html_geo_modify(c, q);
350 break;
352 c->verts_n = CONFIG_VERTS_N_MAX;
353 c->horizs_n = CONFIG_HORIZS_N_MAX;
354 c->urandom = urandom;
355 c->p = buf;
357 static void html_viewtbl_verthdrs_gen(struct html_ctx_t *c)
359 u8 vert;
361 TXT_TO_HTML(VIEWTBL_VERTHDRS_P);
362 /*--------------------------------------------------------------------*/
363 vert = 0;
364 loop {
365 f64 x;
366 f64 lo_west;
367 f64 lo_east;
369 if (vert == c->verts_n)
370 break;
371 x = (f64)((c->x - (u64)c->verts_n / 2 + (u64)vert)
372 % (1 << c->zoom));
373 lo_west = (x * 360.0) / (f64)(1 << c->zoom) - 180.0;
374 lo_east = ((x + (CONFIG_TILE_PIXS_N_MAX - 1.0)
375 / CONFIG_TILE_PIXS_N_MAX) * 360.0) / (f64)(1 << c->zoom)
376 - 180.0;
377 TMPL_LX_TO_HTML(c, VIEWTBL_VERTHDRS_WEST, lo_west);
378 TMPL_LX_TO_HTML(c, VIEWTBL_VERTHDRS_EAST, lo_east);
379 ++vert;
381 /*--------------------------------------------------------------------*/
382 TXT_TO_HTML(VIEWTBL_VERTHDRS_E);
384 static void html_viewtbl_tile(struct html_ctx_t *c, u8 horiz)
386 u8 vert;
388 vert = 0;
389 loop {
390 u64 x;
391 u64 y;
393 if (vert == c->verts_n)
394 break;
395 x = (c->x - (u64)c->verts_n / 2 + (u64)vert) % (1 << c->zoom);
396 y = (c->y - (u64)c->horizs_n / 2 + (u64)horiz) % (1 << c->zoom);
397 TMPL_TO_HTML(c, VIEWTBL_TILE, config_row_svrs[horiz % 3],
398 c->zoom, x, y);
399 ++vert;
402 static void html_viewtbl_mainrow_horiztrailer_cell_top(struct html_ctx_t *c,
403 u8 horiz)
405 f64 y;
406 f64 tmp;
407 f64 la;
409 y = (f64)((c->y - (u64)c->horizs_n / 2 + (u64)horiz) % (1 << c->zoom));
410 tmp = PI - 2.0 * PI * y / (f64)(1 << c->zoom);
411 la = 180.0 / PI * atan(0.5 * (exp(tmp) - exp(-tmp)));
412 TMPL_LX_TO_HTML(c, VIEWTBL_MAINROW_HORIZTRAILER_CELL_TOP,la);
414 static void html_viewtbl_mainrow_gen(struct html_ctx_t *c, u8 horiz)
416 TXT_TO_HTML(VIEWTBL_MAINROW_P);
417 html_viewtbl_tile(c, horiz);
418 html_viewtbl_mainrow_horiztrailer_cell_top(c, horiz);
419 TXT_TO_HTML(VIEWTBL_MAINROW_E);
421 static void html_viewtbl_horiztrailer_row_bot(struct html_ctx_t *c, u8 horiz)
423 f64 y;
424 f64 tmp;
425 f64 la;
427 y = (f64)((c->y - (u64)c->horizs_n / 2 + (u64)horiz) % (1 << c->zoom));
428 tmp = PI - 2.0 * PI * (y + (CONFIG_TILE_PIXS_N_MAX - 1.0)
429 / CONFIG_TILE_PIXS_N_MAX) / (f64)(1 << c->zoom);
430 la = 180.0 / PI * atan(0.5 * (exp(tmp) - exp(-tmp)));
431 TMPL_LX_TO_HTML(c, VIEWTBL_HORIZTRAILER_ROW_BOT, la);
433 static void html_viewtbl_gen(struct html_ctx_t *c)
435 u8 horiz;
437 TXT_TO_HTML(VIEWTBL_P);
438 html_viewtbl_verthdrs_gen(c);
439 horiz = 0;
440 loop {
441 if (horiz == c->horizs_n)
442 break;
443 html_viewtbl_mainrow_gen(c, horiz);
444 html_viewtbl_horiztrailer_row_bot(c, horiz);
445 ++horiz;
447 TXT_TO_HTML(VIEWTBL_E);
449 static void html_navform_navtbl_gen(struct html_ctx_t *c)
451 TXT_TO_HTML(NAVTBL_P);
452 TMPL_LX_TO_HTML(c, NAVTBL_LO, c->lo);
453 TMPL_LX_TO_HTML(c, NAVTBL_LA, c->la);
454 TXT_TO_HTML(NAVTBL_MIDDLE);
455 TMPL_TO_HTML(c, NAVTBL_ZOOM, c->zoom);
456 TXT_TO_HTML(NAVTBL_E);
458 static void html_navform_gen(struct html_ctx_t *c)
460 TMPL_TO_HTML(c, URANDOM, c->urandom);
461 TMPL_TO_HTML(c, NAV_X, c->x);
462 TMPL_TO_HTML(c, NAV_Y, c->y);
463 html_navform_navtbl_gen(c);
465 static void html_majortbl_gen(struct html_ctx_t *c)
467 TXT_TO_HTML(MAJORTBL_P);
468 html_viewtbl_gen(c);
469 TXT_TO_HTML(MAJORTBL_VIEWTBL_TO_NAVFORM);
470 html_navform_gen(c);
471 TXT_TO_HTML(MAJORTBL_E);
473 static u32 html_sz_max(void)
475 return \
476 SZ(MAJORTBL_P) +
477 SZ(VIEWTBL_P) +
478 SZ(VIEWTBL_VERTHDRS_P) +
479 CONFIG_VERTS_N_MAX * (
480 VIEWTBL_VERTHDRS_WEST_SZ_MAX +
481 VIEWTBL_VERTHDRS_EAST_SZ_MAX) +
482 SZ(VIEWTBL_VERTHDRS_E) +
483 CONFIG_HORIZS_N_MAX * (
484 SZ(VIEWTBL_MAINROW_P) +
485 CONFIG_VERTS_N_MAX * VIEWTBL_TILE_SZ_MAX +
486 VIEWTBL_MAINROW_HORIZTRAILER_CELL_TOP_SZ_MAX +
487 SZ(VIEWTBL_MAINROW_E) +
488 VIEWTBL_HORIZTRAILER_ROW_BOT_SZ_MAX) +
489 SZ(VIEWTBL_E) +
490 SZ(MAJORTBL_VIEWTBL_TO_NAVFORM) +
491 URANDOM_SZ_MAX +
492 NAV_X_SZ_MAX +
493 NAV_Y_SZ_MAX +
494 SZ(NAVTBL_P) +
495 NAVTBL_LO_SZ_MAX +
496 NAVTBL_LA_SZ_MAX +
497 SZ(NAVTBL_MIDDLE) +
498 NAVTBL_ZOOM_SZ_MAX +
499 SZ(NAVTBL_E) +
500 SZ(MAJORTBL_E);
502 #define NAV_IS(x) memcmp(x, s, e - s)
503 static void html_control_nav(struct html_query_t *q, u8 *s, u8 *e)
505 if (s == e)
506 return;
507 if (NAV_IS("geo_modify")) /* default if nav is missing */
508 q->nav_cmd = HTML_QUERY_NAV_CMD_GEO_MODIFY;
509 else if (NAV_IS("translation_north"))
510 q->nav_cmd = HTML_QUERY_NAV_CMD_TRANSLATION_NORTH;
511 else if (NAV_IS("translation_south"))
512 q->nav_cmd = HTML_QUERY_NAV_CMD_TRANSLATION_SOUTH;
513 else if (NAV_IS("translation_west"))
514 q->nav_cmd = HTML_QUERY_NAV_CMD_TRANSLATION_WEST;
515 else if (NAV_IS("translation_east"))
516 q->nav_cmd = HTML_QUERY_NAV_CMD_TRANSLATION_EAST;
517 else if (NAV_IS("zoom_plus"))
518 q->nav_cmd = HTML_QUERY_NAV_CMD_ZOOM_PLUS;
519 else if (NAV_IS("zoom_minus"))
520 q->nav_cmd = HTML_QUERY_NAV_CMD_ZOOM_MINUS;
521 else if (NAV_IS("zoom_modify"))
522 q->nav_cmd = HTML_QUERY_NAV_CMD_ZOOM_MODIFY;
524 #undef NAV_IS
525 static void html_control_x(struct html_query_t *q, u8 *s, u8 *e)
527 u32 x;
529 if (s == e)
530 return;
531 if (dec2u32_blk(&x, s, e - 1))
532 q->x = x;
534 static void html_control_y(struct html_query_t *q, u8 *s, u8 *e)
536 u32 y;
538 if (s == e)
539 return;
540 if (dec2u32_blk(&y, s, e - 1))
541 q->y = y;
543 static void html_control_zoom(struct html_query_t *q, u8 *s, u8 *e)
545 u8 z;
547 if (s == e)
548 return;
549 if (dec2u8_blk(&z, s, e - 1))
550 q->zoom = z;
552 static void html_control_la(struct html_query_t *q, u8 *s, u8 *e)
554 f64 la;
556 dec_to_f64(&la, s, e - 1); /* only integers in ulinux */
557 if (-90.0 <= la && la <= 90.0)
558 q->la = la;
560 static void html_control_lo(struct html_query_t *q, u8 *s, u8 *e)
562 f64 lo;
564 dec_to_f64(&lo, s, e - 1); /* only integeres in ulinux */
565 if (-180.0 <= lo && lo <= 180.0)
566 q->lo = lo;
568 #define NAME_IS(x) memcmp(x, name, name_e - name)
569 static void html_control_decode(struct html_query_t *q, u8 *name, u8 *name_e,
570 u8 *value, u8 *value_e)
572 if (name == name_e)
573 return;
574 if (NAME_IS("nav"))
575 html_control_nav(q, value, value_e);
576 else if (NAME_IS("x"))
577 html_control_x(q, value, value_e);
578 else if (NAME_IS("y"))
579 html_control_y(q, value, value_e);
580 else if (NAME_IS("zoom"))
581 html_control_zoom(q, value, value_e);
582 else if (NAME_IS("lo"))
583 html_control_lo(q, value, value_e);
584 else if (NAME_IS("la"))
585 html_control_la(q, value, value_e);
587 #undef NAME_IS
588 static void html_query_decode(struct html_query_t *q, u8 *p, u8 *e)
589 { loop {
590 u8 *name;
591 u8 *name_e;
592 u8 *value;
593 u8 *value_e;
595 if (p == e)
596 return;
597 name = p;
598 name_e = p;
599 value = p;
600 value_e = p;
601 /* name */
602 loop {
603 if (p == e || *p == '=' || *p == '&') {
604 name_e = p;
605 break;
607 ++p;
609 if (*p == '=') { /* value if any */
610 ++p; /* skip '=' */
611 value = p;
612 loop {
613 if (p == e || *p == '&') {
614 value_e = p;
615 break;
617 ++p;
620 if (*p == '&')
621 ++p; /* skip '&' */
622 html_control_decode(q, name, name_e, value, value_e);
624 static void html_query_init(struct html_query_t *q)
626 /* sane init values */
627 q->zoom = 0;
628 q->lo = 0.0;
629 q->la = 0.0;
630 q->x = 0;
631 q->y = 0;
632 /* will ignore query x and y */
633 q->nav_cmd = HTML_QUERY_NAV_CMD_GEO_MODIFY;
635 /*----------------------------------------------------------------------------*/
636 #undef GEO_DECIMAL_MAX
637 #undef U32_DECIMAL_DIGITS_N_MAX
638 #undef U64_HEXA_DIGITS_N_MAX
639 #undef PI
640 #undef MAJORTBL_P
641 #undef VIEWTBL_P
642 #undef VIEWTBL_VERTHDRS_P
643 #undef VIEWTBL_VERTHDRS_WEST
644 #undef VIEWTBL_VERTHDRS_WEST_SZ_MAX
645 #undef VIEWTBL_VERTHDRS_EAST
646 #undef VIEWTBL_VERTHDRS_EAST_SZ_MAX
647 #undef VIEWTBL_VERTHDRS_E
648 #undef VIEWTBL_MAINROW_P
649 #undef VIEWTBL_TILE
650 #undef VIEWTBL_TILE_SZ_MAX
651 #undef VIEWTBL_MAINROW_HORIZTRAILER_CELL_TOP
652 #undef VIEWTBL_MAINROW_HORIZTRAILER_CELL_TOP_SZ_MAX
653 #undef VIEWTBL_MAINROW_E
654 #undef VIEWTBL_HORIZTRAILER_ROW_BOT
655 #undef VIEWTBL_HORIZTRAILER_ROW_BOT_SZ_MAX
656 #undef VIEWTBL_E
657 #undef MAJORTBL_VIEWTBL_TO_NAVFORM
658 #undef URANDOM
659 #undef URANDOM_SZ_MAX
660 #undef NAV_X
661 #undef NAV_X_SZ_MAX
662 #undef NAV_Y
663 #undef NAV_Y_SZ_MAX
664 #undef NAVTBL_P
665 #undef NAVTBL_LO
666 #undef NAVTBL_LO_SZ_MAX
667 #undef NAVTBL_LA_SZ
668 #undef NAVTBL_LA_SZ_MAX
669 #undef NAVTBL_MIDDLE
670 #undef NAVTBL_ZOOM
671 #undef NAVTBL_E
672 #undef MAJORTBL_E
673 #define CLEANUP
674 #include "common_cpp.h"
675 /*============================================================================*/
676 #include "namespace/ulinux.h"
677 /*============================================================================*/
678 #undef CLEANUP
679 #endif