home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 1999 January / dppcpro0199a.iso / January / Fp98 / SDK / WebBot / votebot / server / votecount.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-18  |  6.2 KB  |  195 lines

  1. //
  2. // Copyright (c) 1997 Vermeer Technologies, Inc., a wholly owned
  3. //               subsidiary of Microsoft Corp.  All Rights Reserved
  4.  
  5. #include <fstream.h>
  6. #include <stdlib.h>
  7. #include <fcntl.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10. #include <math.h>
  11.  
  12. #ifdef WIN32
  13. #include <io.h>
  14. #include <strstrea.h>
  15. #define IOS_BINARY ios::binary
  16. #endif
  17.  
  18. #ifdef UNIX
  19. #include <strstream.h>
  20. #define IOS_BINARY ios::bin
  21. #endif
  22.  
  23. #include "votefile.h"
  24. #include "votecount.h"
  25.  
  26. // Parse the query string.  It looks for the keys "Page"
  27. // and "Vote".  It does a case-sensitive search. 
  28. // WARNING: do not use the params string after calling ParseQueryString
  29. // because the parse method mangles the params string in the process.
  30. // this is done for efficiency to avoid copying strings.
  31. void ParseQueryString(char *params,
  32.                       char **VoteFileName,
  33.                       char **VoteResult
  34.                       )
  35. {    
  36.     
  37.     char *pKeyBegin = params;
  38.     char *pKeyEnd = NULL;    
  39.     for (char *p = params; *p;)
  40.     {
  41.         if (*p == '=')        
  42.             pKeyEnd = p;
  43.         // If it's a key divider, or the last char of the string,
  44.         // parse the entire key/value pair.  But if we're at the end
  45.         // of the string, move p there so that the rest of the code
  46.         // works as it is expecting.
  47.         if (*(p+1) == '\0')
  48.             p++;
  49.         if (*p == '&' || *p == '\0')
  50.         {            
  51.             // At this point, key is from pKeyBegin to pKeyEnd-1,
  52.             // and value is from pKeyEnd+1 to p-1.
  53.             
  54.             if (pKeyEnd)
  55.             {
  56.                 int keyLen = pKeyEnd - pKeyBegin;    
  57.                 if (keyLen >0)
  58.                 {
  59.                     // Replace the | seperator with a '\0' so we can just break
  60.                     // up this string to return the voteFileName and the
  61.                     // VoteResult strings.  That way, we don't need to
  62.                     // do a strcpy.
  63.                     *p = '\0';
  64.                     if (strncmp("Page", pKeyBegin, keyLen) == 0)            
  65.                         *VoteFileName = pKeyEnd+1;            
  66.                     else if(strncmp("Vote", pKeyBegin, keyLen) == 0)                
  67.                         *VoteResult = pKeyEnd+1;            
  68.                 }
  69.             }
  70.             // Reset the pointers:
  71.             pKeyBegin = p+1;
  72.             pKeyEnd = NULL;
  73.         }
  74.         p++;    
  75.     }
  76.  
  77. }    
  78.  
  79.  
  80. const int QueryNumDecodes = 2;
  81. const char QueryFromDecode[QueryNumDecodes] = {'+', '/'};
  82. const char QueryToDecode[QueryNumDecodes] = {' ', DIR_SEPARATOR};
  83.  
  84. // Performs in-place decoding of the query string
  85. char *QueryDecode(char *queryString)
  86. {
  87.     // Simple char by char decoding.
  88.     if (queryString == NULL)
  89.         return NULL;
  90.     for (char *p = queryString; *p; p++)
  91.     {    
  92.         for (int i=0; i<QueryNumDecodes; i++)
  93.         {
  94.             if (*p == QueryFromDecode[i])
  95.             {
  96.                 *p = QueryToDecode[i];
  97.                 break;
  98.             }
  99.         }
  100.     }
  101.     return queryString;
  102. }
  103.  
  104.  
  105. // argc and argv are unused, so they are commented out to prevent compiler
  106. // warnings.
  107. int main(
  108.     int /* argc */,
  109.     char ** /* argv */)
  110. {
  111.     div_t percentage;        // used to calculate percentage of popular opinion
  112.     char *params = QueryDecode(getenv("QUERY_STRING"));
  113.     char *path = getenv("PATH_TRANSLATED");
  114.     if (path == NULL)
  115.         path = "";
  116.  
  117.     char *pageFileName = NULL;
  118.     char *VoteResult = NULL;
  119.     
  120.     if (params == NULL)
  121.         return 1;
  122.     
  123.     // Parse the query string.  Fills imageNum with -1 if it's a
  124.     // custom image
  125.     ParseQueryString(params, &pageFileName, &VoteResult );    
  126.  
  127.     // If we didn't get a Page filename, just give up.
  128.     if (pageFileName == NULL || strlen(pageFileName) == 0)
  129.         return 1;
  130.     
  131.     // Create full votefile filename and custom image filename by
  132.     // concatenating the path and the relative filenames.
  133.     char *fullVoteFileName = new char[strlen(path) + 
  134.                                         9 +               // +9 for "_private/"
  135.                                         strlen(pageFileName) +
  136.                                         5];               // +4 for ".vot"+'\0'
  137.     sprintf(fullVoteFileName, "%s_private%c%s.vot", 
  138.             path, DIR_SEPARATOR, pageFileName);
  139.     
  140.     // The constructor waits until the file is no longer locked, then locks it.
  141.     CVote *VoteCntFile = new CVote(fullVoteFileName);        
  142.     
  143.     if (!strcmp(VoteResult,"V1"))
  144.     {    VoteCntFile->Increment("vote1type");    
  145.         percentage = div ((VoteCntFile->GetVoteCount("vote1type")* 100),
  146.                         (VoteCntFile->GetVoteCount("vote1type") +
  147.                         VoteCntFile->GetVoteCount("vote2type")));
  148.                         };    
  149.         
  150.     if (!strcmp(VoteResult,"V2"))
  151.     {    VoteCntFile->Increment("vote2type");        
  152.         percentage = div ((VoteCntFile->GetVoteCount("vote2type")* 100),
  153.                         (VoteCntFile->GetVoteCount("vote1type") +
  154.                         VoteCntFile->GetVoteCount("vote2type")));
  155.                         };    
  156.     // percentage.quot * 100 == final percentage.
  157.  
  158.     // Destruct as soon as possible to unlock the file so others can access it.
  159.     delete VoteCntFile;
  160.  
  161.     // For now, just suppose we are doing a memory file
  162.     
  163. #ifdef WIN32
  164.     _setmode( _fileno( stdout ), _O_BINARY );    // Make stdout binary
  165. #endif
  166. #ifdef UNIX
  167.     fdopen( fileno(stdout), "wb");               // Make stdout binary
  168. #endif
  169.  
  170.     // output MIME header so browsers know that we're HTML.
  171.     
  172.     fprintf(stdout, "Content-type: text/html\n\n");
  173.     
  174.     fflush(stdout);
  175.  
  176.     cout<< "<html>\n"
  177.         << "<head>\n"
  178.         << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=None\">"
  179.         << "\n<title>Vote Confirmation</title>\n</head>\n<body>\n" 
  180.         << "<h1 align=\"center\"><strong>Vote Confirmation "
  181.         << "</strong></h1>\n\n<p align=\"center\"> </p>"
  182.         << "<p align=\"center\"><font size=\"3\">\n"
  183.         << "Your ballot has been cast and your vote "
  184.         << "has been registered.</p>\n"
  185.         << "<p align=\"center\">Currently, " << (percentage.quot) 
  186.         << "% of the voting population agrees with your vote.</font></p>"
  187.         << "\n</body>\n\n</html>";
  188.         
  189.     fflush(stdout);
  190.     
  191.     delete fullVoteFileName; 
  192.  
  193.     return 0;
  194. }
  195.