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