00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _Show_h_
00032 #define _Show_h_
00033
00034 #include "StatPages.h"
00035
00036 #define STREQ_PREFIX(_x,_s) (!strncasecmp(_x,_s,sizeof(_s)-1))
00037
00038 struct ShowCont;
00039 typedef int (ShowCont::*ShowContEventHandler) (int event, Event * data);
00040 struct ShowCont: public Continuation
00041 {
00042 private:
00043 char *buf, *start, *ebuf;
00044
00045 public:
00046 Action action;
00047 char *sarg;
00048
00049 int show(const char *s, ...)
00050 {
00051 va_list aap, va_scratch;
00052 ptrdiff_t avail = ebuf - buf;
00053 ptrdiff_t needed;
00054
00055 va_start(aap, s);
00056 va_copy(va_scratch, aap);
00057 needed = vsnprintf(buf, avail, s, va_scratch);
00058 va_end(va_scratch);
00059
00060 if (needed >= avail) {
00061 ptrdiff_t bufsz = ebuf - start;
00062 ptrdiff_t used = buf - start;
00063
00064 Debug("cache_inspector", "needed %d bytes, reallocating to %d bytes",
00065 (int)needed, (int)bufsz + (int)needed);
00066
00067 bufsz += ROUNDUP(needed, ats_pagesize());
00068 start = (char *)ats_realloc(start, bufsz);
00069 ebuf = start + bufsz;
00070 buf = start + used;
00071 avail = ebuf - buf;
00072
00073 needed = vsnprintf(buf, avail, s, aap);
00074 va_end(aap);
00075
00076 if (needed >= avail) {
00077 Debug("cache_inspector", "needed %d bytes, but had only %d",
00078 (int)needed, (int)avail + (int)needed);
00079 return EVENT_DONE;
00080 }
00081 }
00082
00083 buf += needed;
00084 return EVENT_CONT;
00085 }
00086
00087 #define CHECK_SHOW(_x) if (_x == EVENT_DONE) return complete_error(event,e);
00088
00089 int complete(int event, Event * e)
00090 {
00091 CHECK_SHOW(show("</BODY>\n</HTML>\n"));
00092 if (!action.cancelled) {
00093 StatPageData data(start, buf - start);
00094 action.continuation->handleEvent(STAT_PAGE_SUCCESS, &data);
00095 start = 0;
00096 } else {
00097 ats_free(start);
00098 start = NULL;
00099 }
00100 return done(VIO::CLOSE, event, e);
00101 }
00102
00103 int complete_error(int event, Event * e)
00104 {
00105 ats_free(start);
00106 start = NULL;
00107 if (!action.cancelled)
00108 action.continuation->handleEvent(STAT_PAGE_FAILURE, NULL);
00109 return done(VIO::ABORT, event, e);
00110 }
00111
00112 int begin(const char *name)
00113 {
00114 return show("<HTML>\n<HEAD><TITLE>%s</TITLE>\n"
00115 "<BODY BGCOLOR=\"#ffffff\" FGCOLOR=\"#00ff00\">\n" "<H1>%s</H1>\n", name, name);
00116 }
00117
00118 int showError(int event, Event * e)
00119 {
00120 return complete_error(event, e);
00121 }
00122
00123 virtual int done(int , int , void * )
00124 {
00125 delete this;
00126 return EVENT_DONE;
00127 }
00128
00129 ShowCont(Continuation * c, HTTPHdr * )
00130 : Continuation(NULL), sarg(0) {
00131 size_t sz = ats_pagesize();
00132
00133 mutex = c->mutex;
00134 action = c;
00135 buf = (char *)ats_malloc(sz);
00136 start = buf;
00137 ebuf = buf + sz;
00138 }
00139
00140 ~ShowCont() {
00141 ats_free(sarg);
00142 ats_free(start);
00143 }
00144 };
00145
00146
00147 #endif