Click here to Skip to main content
15,885,244 members
Articles / Desktop Programming / Win32

How To Add Simple Web-enabled 2D/3D Dashboards to your Natively Built Application

Rate me:
Please Sign up or sign in to vote.
4.92/5 (26 votes)
29 Dec 2010CPOL6 min read 58.1K   2.7K   65  
The webonization of gnuplot
/*

example, overloads a form URL and its corresponding POST

*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <snorkel.h>

/*
 content buffer containing index
*/
char szIndex[] = {
  "<html>\r\n"
  "<body>\r\n"
  "<a href=\"example4.c\">example four source</a>\r\n"
  "</body>\r\n" "</html>\r\n"
};


char *reservedwords[] =
  { "#include", "int", "float", "struct", "long", "true",
  "bool", "false", "boolean", "double", "char", "unsigned",
    "return", "#define", "break",
  "defined", "#pragma", "union", "short", "#ifdef",
    "#ifndef", "static", "#if", "#else",
  "#endif", "endif", "if", "else", "switch", "else if",
    "#elif", "const", "size_t",
  "void", "enum", "typedef", "for", "case", "while", "do",
    "public", "private", "signed",
  "default", "goto", "volatile", "sizeof", "delete",
    "class", "inline", "friend",
  "namespace", "new", "operator", "private", "protected",
    "public", "template",
  "this", "throw", "try", "using", "abstract", "implements",
    "throws",
  "transient", "byte", "package", "synchronized", "extends",
    "instanceof", "strictfp",
  "catch", "final", "interface", "finally", "continue",
    "super", "assert", "null", "NULL",
  "exit", "extern", "public:", "private:", "protected:",
    "private", "public", "protected",
  "virtual", "false", "true", "register"
};

size_t chreservedwords =
  sizeof (reservedwords) / sizeof (char *);
typedef char urlesc_t[10];

char *
char_esc (char c, urlesc_t escp)
{

  escp[0] = 0;
  if (c < 0 || c > 255)
    return 0;

  if (isalnum ((int) c) || c == '/' || c == '*' || c == '+'
      || c == '-' || c == '#' || c == ' ' || c == '\\'
      || c == '\n' || c == '\t' || c == '\r')
    {
      return 0;
    }
#if defined(WIN32) || defined(WIN64)
  sprintf_s 
#else
  snprintf
#endif
      (escp, sizeof (urlesc_t), "&#%d;", c);

  return (char *) escp;
}




void
print_line (snorkel_obj_t obj,
            int line,
            int *pcomment,
            char *pszin, char *pszout, size_t cb)
{
  size_t i = 0;
  char *psz = pszout;
  int quot = 0;
  int backslash = 0;
  char green[] = "</font><font color=\"#008000\">";
  char black[] = "</font><font color=\"#000000\">";
  char blue[] = "</font><font color=\"#0000FF\">";
  char red[] = "</font><font color=\"#C43100\">";
  char brown[] = "</font><font color=\"#AA6600\">";
  size_t lgreen, lblue, lblack, lred, lbrown;
  urlesc_t escp;
  char *pszstart = pszin;

  memset (pszout, 0, cb);

  if (strstr (pszin, "int") != 0)
    {
      int it = 0;
      it = 1;
    }

  snorkel_printf (obj,
                  "<font color=\"#000000\">% 6d</font>    ",
                  line);
  if (*pcomment)
    snorkel_printf (obj, "<font color=\"#008000\">");
  else
    snorkel_printf (obj, "<font color=\"#000000\">");

  lgreen = strlen (green);
  lblue = strlen (blue);
  lblack = strlen (black);
  lred = strlen (red);
  lbrown = strlen (brown);

  for (; i < cb && *pszin != 0;)
    {

      if (strncmp (pszin, "/*", 2) == 0 && !*pcomment
          && !quot)
        {
          *pcomment = 1;
          if (i + lgreen + 2 > cb)
            return;
          strcat (psz, green);
          strcat (psz, "/*");
          psz += lgreen + 2;
          pszin += 2;
          i += lgreen + 2;
          backslash = 0;
        }
      else if (strncmp (pszin, "//", 2) == 0 && !*pcomment
               && !quot)
        {
          if (i + lgreen + 2 > cb)
            return;
          strcat (psz, green);
          strcat (psz, "//");
          psz += lgreen + 2;
          pszin += 2;
          i += lgreen + 2;
          backslash = 0;
        }
      else if (*pszin == '\"')
        {

          if (*pcomment || backslash)
            {
              if (i + 5 > cb)
                return;
              backslash = 0;
              strcat (psz, char_esc (*pszin++, escp));
              psz += 5;
              i += 5;
            }
          else if (!quot)
            {
              if (i + 5 + lred > cb)
                return;
              strcat (psz, red);
              strcat (psz, char_esc (*pszin++, escp));
              quot = 1;
              psz += 5 + lred;
              i += 5 + lred;
            }
          else
            {
              quot = 0;
              if (i + 5 + lblack > cb)
                return;
              strcat (psz, char_esc (*pszin++, escp));
              strcat (psz, black);
              psz += 5 + lblack;
              i += 5 + lblack;
            }

        }
      else if (strncmp (pszin, "*/", 2) == 0 && *pcomment)
        {
          backslash = 0;
          *pcomment = 0;
          if (i + lblack + 2 > cb)
            return;
          strcat (psz, "*/");
          strcat (psz, black);
          pszin += 2;
          psz += lblack + 2;
        }
      else
        {
          size_t k = chreservedwords;
          if (!*pcomment && !quot)
            {


              for (k = 0; k < chreservedwords; k++)
                {
                  if ((strncmp (pszin, reservedwords[k],
                                strlen (reservedwords[k]))
                       == 0)
                      && (pszin[strlen (reservedwords[k])]
                          == 0
                          ||
                          pszin[strlen (reservedwords[k])]
                          == '{'
                          ||
                          pszin[strlen (reservedwords[k])]
                          == '\t'
                          ||
                          pszin[strlen (reservedwords[k])]
                          == ' '
                          ||
                          pszin[strlen (reservedwords[k])]
                          == '\n'
                          ||
                          pszin[strlen (reservedwords[k])]
                          == '('
                          ||
                          pszin[strlen (reservedwords[k])]
                          == ')'
                          ||
                          pszin[strlen (reservedwords[k])]
                          == ':'
                          ||
                          pszin[strlen (reservedwords[k])]
                          == ';'
                          ||
                          pszin[strlen (reservedwords[k])]
                          == '<') && (pszin == pszstart
                                      || (pszin - 1)[0] ==
                                      ' '
                                      || (pszin - 1)[0] ==
                                      '\t'
                                      || (pszin - 1)[0] ==
                                      '('))
                    break;
                }

            }

          if (k < chreservedwords)
            {
              size_t l = strlen (reservedwords[k]);
              if (i + l + lblue + lblack > cb)
                return;
              strcat (psz, blue);
              strcat (psz, reservedwords[k]);
              strcat (psz, black);

              psz += l + lblue + lblack;
              pszin += strlen (reservedwords[k]);
              i += l + lblue + lblack;
              backslash = 0;
            }
          else
            {
              if (char_esc (*pszin, escp))
                {
                  size_t l = strlen ((char *) escp);
                  if (i + l > cb)
                    return;
                  strcat (psz, escp);
                  psz += l;
                  i += l;
                  pszin++;
                }
              else
                {
                  *psz = *pszin++;
                  if (*psz == '\\')
                    backslash = 1;
                  else
                    backslash = 0;
                  psz++;
                  i++;
                }
            }
        }
    }
  snorkel_printf (obj, "%s</font>\r\n", pszout);

  return;
}

call_status_t
CSourceMime (snorkel_obj_t http_req,
             snorkel_obj_t connection, char *pszurl)
{
  FILE *fd = fopen (pszurl, "r");
  char szbuffer[512];
  char szencoded[2048];
  int line = 0;
  int comment = 0;

  if (!fd)
    return ERROR_STRING ("could not open source file!\r\n");

  snorkel_printf (connection,
                  "<html><body>\r\n");

  while (!feof (fd))
    {
      line++;
      if (fgets (szbuffer, sizeof (szbuffer), fd))
        {
          szbuffer[strlen (szbuffer) - 1] = 0;
          print_line (connection,
                      line, &comment, szbuffer, szencoded,
                      sizeof (szencoded));
        }
    }
  fclose (fd);
  snorkel_printf (connection,
                  "</code></pre></body></html>\r\n");
  return HTTP_SUCCESS;
}

void
syntax (char *pszProg)
{
  fprintf (stderr, "syntax error:\n");
  fprintf (stderr, "%s [-p <port>] [-l <log>] -f <filename>\n", pszProg);
  exit (1);
}


void
main (int argc, char *argv[])
{
  int i = 1;
  int port = 8080;
  char *pszIndex = 0;
  char *pszLog = 0;
  char szExit[10];
  snorkel_obj_t logobj = 0;
  snorkel_obj_t http = 0;
  struct stat st;

  if (stat ("example4.c", &st) != 0)
    {
      fprintf (stderr,
         "the file example4.c is not located in the current directory!\n");
      exit (1);
    }

  for (; i < argc; i++)
    {
      if (argv[i][0] == '-' || argv[i][0] == '/')
        {
          char carg = argv[i][1];
          
          if (i+1 >= carg)
             syntax (argv[0]);

          switch (carg)
            {
            case 'p':
              port = atoi (argv[i + 1]);
              i++;
              break;
            case 'l':
              pszLog = argv[i + 1];
              i++;
              break;
            default:
              syntax (argv[0]);
              break;
            }
        }

    }


  if (pszLog)
    {
      logobj = snorkel_obj_create (snorkel_obj_log, pszLog);
      if (!logobj)
        {
          perror ("could not create log file\n");
          exit (1);
        }
      snorkel_debug (1);
    }



  if (snorkel_init () != SNORKEL_SUCCESS)
    {
      perror ("could not initialize snorkel\n");
      exit (1);
    }

  http = snorkel_obj_create (snorkel_obj_server, 2, ".");

  if (!http)
    {
      perror ("could not create http server\n");
      exit (1);
    }

  if (snorkel_obj_set (http,
                       snorkel_attrib_listener,
                       port, 0) != SNORKEL_SUCCESS)
    {
      perror ("could not create listener\n");
      snorkel_obj_destroy (http);
      if (logobj)
        snorkel_obj_destroy (logobj);
      exit (0);
    }


  /*
   *
   * overload a URL with a content buffer
   *
   */
  if (snorkel_obj_set (http, snorkel_attrib_uri_content,        /* using a content buffer */
                       GET,     /* method is GET */
                       "/index.html",   /* URL */
                       szIndex, /* content buffer */
                       SNORKEL_STORE_AS_REF)    /* store as reference */
      != SNORKEL_SUCCESS)
    {
      perror ("could not overload index.html");
      snorkel_obj_destroy (http);
      if (logobj)
        snorkel_obj_destroy (logobj);

      exit (1);
    }

  /*
   *
   * overload a mime
   *
   */
  snorkel_obj_set (http, snorkel_attrib_mime, "c",      /* extension */
                   "text/html", /* browser interpretation */
                   encodingtype_text,   /* encoded as text */
                   CSourceMime);        /* callback */

  snorkel_obj_set (http, snorkel_attrib_mime, "cpp",    /* extension */
                   "text/html", /* browser interpretation */
                   encodingtype_text,   /* encoded as text */
                   CSourceMime);        /* callback */

  snorkel_obj_set (http, snorkel_attrib_mime, "hpp",    /* extension */
                   "text/html", /* browser interpretation */
                   encodingtype_text,   /* encoded as text */
                   CSourceMime);        /* callback */

  snorkel_obj_set (http, snorkel_attrib_mime, "h",      /* extension */
                   "text/html", /* browser interpretation */
                   encodingtype_text, CSourceMime);     /* callback */

  snorkel_obj_set (http, snorkel_attrib_mime, "java",   /* extension */
                   "text/html", /* browser interpretation */
                   encodingtype_text, CSourceMime);     /* callback */


  fprintf (stderr, "\n\n[HTTP] starting on port %d....",
           port);
  if (pszLog)
    {
      fprintf (stderr, "\n[HTTP] logging messages to %s\n",
               pszLog);
    }
  if (snorkel_obj_start (http) != SNORKEL_SUCCESS)
    {
      perror ("could not start server\n");
      snorkel_obj_destroy (http);
      if (logobj)
        snorkel_obj_destroy (logobj);
      exit (1);
    }

  fprintf (stderr, "\n[HTTP] started.\n\n"
           "--hit enter to terminate--\n");
  fgets (szExit, sizeof (szExit), stdin);

  fprintf (stderr, "[HTTP] bye\n");
  snorkel_obj_destroy (http);
  if (logobj)
    snorkel_obj_destroy (logobj);
  exit (0);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
United States United States
Currently I am a Software Architect for Compuware specializing in software security
Languages: C/C++, FORTRAN, COBOL, Java
Libraries: OpenGL, MFC, X11 (X-Windows), WIN32

Platform Experience: AIX, HP-UX, SunOS, Open VMS, AS400, OSF, AIX, SGI, Linux, Windows CE, Windows

I have a strong background in 3D graphics programming, TCP/IP development, threading, cross platform development, encryption and secured communications, and system level programming.

In the early years before OpenGL made its way to the PC world, I authored one of the first high performance double buffered 3D graphics engines that supported both DOS and Windows providing real time 3D graphics for Engineering Technology Associate’s Finite Element Model Builder, FEMB. You can see their products at www.eta.com.

I also hold a US patent http://www.patentstorm.us/patents/6894690.html

Comments and Discussions