📄 imagemap.c
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include "httpd.h"#include "httpsrv.h"typedef struct Point Point;typedef struct OkPoint OkPoint;typedef struct Strings Strings;struct Point { int x; int y;};struct OkPoint { Point p; int ok;};struct Strings{ char *s1; char *s2;};static char *me;int polytest(int, Point, Point, Point);Strings getfield(char*);OkPoint pt(char*);char* translate(HConnect*, char*, char*);Point sub(Point, Point);float dist(Point, Point);voidmain(int argc, char **argv){ HConnect *c; Hio *hout; char *dest; me = "imagemap"; c = init(argc, argv); hout = &c->hout; if(hparseheaders(c, HSTIMEOUT) < 0) exits("failed"); anonymous(c); if(strcmp(c->req.meth, "GET") != 0 && strcmp(c->req.meth, "HEAD") != 0){ hunallowed(c, "GET, HEAD"); exits("unallowed"); } if(c->head.expectother || c->head.expectcont){ hfail(c, HExpectFail, nil); exits("failed"); } dest = translate(c, c->req.uri, c->req.search); if(dest == nil){ if(c->req.vermaj){ hokheaders(c); hprint(hout, "Content-type: text/html\r\n"); hprint(hout, "\r\n"); } hprint(hout, "<head><title>Nothing Found</title></head><body>\n"); hprint(hout, "Nothing satisfying your search request could be found.\n</body>\n"); hflush(hout); writelog(c, "Reply: 200 imagemap %ld %ld\n", hout->seek, hout->seek); exits(nil); } if(http11(c) && strcmp(c->req.meth, "POST") == 0) hredirected(c, "303 See Other", dest); else hredirected(c, "302 Found", dest); exits(nil);}char*translate(HConnect *c, char *uri, char *search){ Biobuf *b; Strings ss; OkPoint okp; Point p, cen, q, start; float close, d; char *line, *to, *def, *s, *dst; int n, inside, r, ncsa; if(search == nil){ hfail(c, HNoData, me); exits("failed"); } okp = pt(search); if(!okp.ok){ hfail(c, HBadSearch, me); exits("failed"); } p = okp.p; b = Bopen(uri, OREAD); if(b == nil){ hfail(c, HNotFound, uri); exits("failed"); } to = nil; def = nil; dst = nil; close = 0.; ncsa = 1; while(line = Brdline(b, '\n')){ line[Blinelen(b)-1] = 0; ss = getfield(line); s = ss.s1; line = ss.s2; if(ncsa){ ss = getfield(line); dst = ss.s1; line = ss.s2; } if(strcmp(s, "#cern") == 0){ ncsa = 0; continue; } if(strcmp(s, "rect") == 0){ ss = getfield(line); s = ss.s1; line = ss.s2; okp = pt(s); q = okp.p; if(!okp.ok || q.x > p.x || q.y > p.y) continue; ss = getfield(line); s = ss.s1; line = ss.s2; okp = pt(s); q = okp.p; if(!okp.ok || q.x < p.x || q.y < p.y) continue; if(!ncsa){ ss = getfield(line); dst = ss.s1; } return dst; }else if(strcmp(s, "circle") == 0){ ss = getfield(line); s = ss.s1; line = ss.s2; okp = pt(s); cen = okp.p; if(!okp.ok) continue; ss = getfield(line); s = ss.s1; line = ss.s2; if(ncsa){ okp = pt(s); if(!okp.ok) continue; if(dist(okp.p, cen) >= dist(p, cen)) return dst; }else{ r = strtol(s, nil, 10); ss = getfield(line); dst = ss.s1; d = (float)r * r; if(d >= dist(p, cen)) return dst; } }else if(strcmp(s, "poly") == 0){ ss = getfield(line); s = ss.s1; line = ss.s2; okp = pt(s); start = okp.p; if(!okp.ok) continue; inside = 0; cen = start; for(n = 1; ; n++){ ss = getfield(line); s = ss.s1; line = ss.s2; okp = pt(s); q = okp.p; if(!okp.ok) break; inside = polytest(inside, p, cen, q); cen = q; } inside = polytest(inside, p, cen, start); if(!ncsa) dst = s; if(n >= 3 && inside) return dst; }else if(strcmp(s, "point") == 0){ ss = getfield(line); s = ss.s1; line = ss.s2; okp = pt(s); q = okp.p; if(!okp.ok) continue; d = dist(p, q); if(!ncsa){ ss = getfield(line); dst = ss.s1; } if(d == 0.) return dst; if(close == 0. || d < close){ close = d; to = dst; } }else if(strcmp(s, "default") == 0){ if(!ncsa){ ss = getfield(line); dst = ss.s1; } def = dst; } } if(to == nil) to = def; return to;}intpolytest(int inside, Point p, Point b, Point a){ Point pa, ba; if(b.y>a.y){ pa=sub(p, a); ba=sub(b, a); }else{ pa=sub(p, b); ba=sub(a, b); } if(0<=pa.y && pa.y<ba.y && pa.y*ba.x<=pa.x*ba.y) inside = !inside; return inside;}Pointsub(Point p, Point q){ p.x -= q.x; p.y -= q.y; return p;}floatdist(Point p, Point q){ p.x -= q.x; p.y -= q.y; return (float)p.x * p.x + (float)p.y * p.y;}OkPointpt(char *s){ OkPoint okp; Point p; char *t, *e; if(*s == '(') s++; t = strchr(s, ')'); if(t != nil) *t = 0; p.x = 0; p.y = 0; t = strchr(s, ','); if(t == nil){ okp.p = p; okp.ok = 0; return okp; } e = nil; p.x = strtol(s, &e, 10); if(e != t){ okp.p = p; okp.ok = 0; return okp; } p.y = strtol(t+1, &e, 10); if(e == nil || *e != 0){ okp.p = p; okp.ok = 0; return okp; } okp.p = p; okp.ok = 1; return okp;}Stringsgetfield(char *s){ Strings ss; char *f; while(*s == '\t' || *s == ' ') s++; f = s; while(*s && *s != '\t' && *s != ' ') s++; if(*s) *s++ = 0; ss.s1 = f; ss.s2 = s; return ss;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -