Advertisement.h
 1 #ifndef ADVERTISEMENT_H
 2 #define ADVERTISEMENT_H
 3 
 4 #include <queue>
 5 #include <iostream>
 6 #include <string>
 7 #include "Date.h"
 8 #include "Bid.h"
 9 
10 using namespace std;
11 
12 class Advertisement;
13 
14 istream &operator>>(istream &stream, Advertisement &a);
15 
16 class Advertisement {
17 
18   private:
19     
20     int number;
21     int quantity;
22     string title;
23     string seller_email;
24     string body;
25 
26     Date start;
27     Date close;
28     priority_queue<Bid> bids;
29 
30   public:
31 
32     Advertisement(void);
33     Advertisement(const Advertisement &a);
34     Advertisement (string title, string seller_email, string body, 
35                    Date start, Date close, int quantity);
36 
37     virtual void setStart (const Date &start);
38     virtual void setClose (const Date &close);
39     virtual void setTitle (string title);
40     virtual void setBody (string body);
41     virtual void setNumber (int number);
42     virtual void setEmail (string email);
43     virtual void setQuantity (int quantity);
44 
45     virtual Date getStart () const;
46     virtual Date getClose () const;
47     virtual string getTitle() const;
48     virtual string getBody() const;
49     virtual string getEmail() const;
50     virtual int getNumber () const;
51     virtual int getQuantity() const;
52     
53     virtual bool operator==(const Advertisement&) const;
54 
55     virtual priority_queue<Bid>& getBids(void);
56     virtual vector<Bid> getTopDutchBids (void) const;
57 
58 };
59 
60 #endif
Advertisement.cpp
  1 #include "Advertisement.h"
  2     Advertisement::Advertisement()
  3         {
  4             int number=0;
  5             int quantity=0;
  6             string title;
  7             string seller_email;
  8             string body;
  9             Date start;
 10             Date close;
 11 
 12         }
 13     Advertisement::Advertisement(const Advertisement &a)
 14     {
 15         this->body=a.getBody();
 16         this->close=a.getClose();
 17         this->number=a.getNumber();
 18         this->quantity=a.getQuantity();
 19         this->seller_email=a.getEmail();
 20         this->start=a.getStart();
 21         this->title=a.getTitle();
 22     }
 23     Advertisement::Advertisement (string title, string seller_email, string body, 
 24                    Date start, Date close, int quantity)
 25     {
 26         this->title=title;
 27         this->seller_email=seller_email;
 28         this->body=body;
 29         this->start=start;
 30         this->close=close;
 31         this->quantity=quantity;
 32     }
 33     void Advertisement::setStart(const Date &start)
 34     {
 35         this->start=start;
 36     }
 37     void Advertisement::setClose (const Date &close)
 38     {
 39         this->close=close;
 40     }
 41     void Advertisement::setTitle (string title)
 42     {
 43         this->title=title;
 44     }
 45     void Advertisement::setBody (string body)
 46     {
 47         this->body=body;
 48     }
 49     void Advertisement::setNumber (int number)
 50     {
 51         this->number=number;
 52     }
 53     void Advertisement::setEmail (string email)
 54     {
 55         this->seller_email=email;
 56     }
 57     void Advertisement::setQuantity (int quantity)
 58     {
 59         this->quantity=quantity;
 60     }
 61     Date Advertisement::getStart () const
 62     {
 63         return this->start;
 64     }
 65     Date Advertisement::getClose () const
 66     {
 67         return this->close;
 68     }
 69     string Advertisement::getTitle() const
 70     {
 71         return this->title;
 72     }
 73     string Advertisement::getBody() const
 74     {
 75         return this->body;
 76     }
 77     string Advertisement::getEmail() const
 78     {
 79         return this->seller_email;
 80     }
 81     int Advertisement::getNumber() const
 82     {
 83         return this->number;
 84     }
 85     int Advertisement::getQuantity() const
 86     {
 87         return this->quantity;
 88     }
 89     bool Advertisement::operator ==(const Advertisement &a) const
 90     {
 91         if(this->number==a.getNumber()&&this->quantity==a.getQuantity()&&this->title==a.getTitle()&&this->seller_email==a.getEmail()&&this->body==a.getBody()&&this->getStart()==a.getStart()&&this->getClose()==a.getClose())
 92         {
 93             return true;
 94         }
 95         else
 96         {
 97             return false;
 98         }
 99     }
100     istream &operator>>(istream &stream, Advertisement &a)
101     {
102             int number=0;
103             int quantity=0;
104             string title;
105             string seller_email;
106             string body;
107             Date start;
108             Date close;
109         
110         stream>>title;
111         stream>>seller_email;
112         stream>>quantity;
113         stream>>start;
114         stream>>close;
115         stream>>body;
116         a.setTitle(title);
117         a.setEmail(seller_email);
118         a.setQuantity(quantity);
119         a.setStart(start);
120         a.setClose(close);
121         a.setBody(body);
122             return stream;
123     }
124     priority_queue<Bid>& Advertisement::getBids(void)
125     {
126         return this->bids;
127     }
128     //maybe some troubles
129     vector<Bid> Advertisement::getTopDutchBids(void) const
130     {
131         int Aq=this->quantity;
132         vector<Bid> a;
133         int count=0;
134         priority_queue<Bid> test;
135         test=this->bids;
136         while(Aq>0&&!test.empty())
137         {
138 
139             if(Aq>test.top().getQuantity())
140             {
141             Aq=Aq-test.top().getQuantity();
142             a.push_back(test.top());
143             test.pop();
144             }
145             else 
146             {
147                 if(Aq<test.top().getQuantity())
148                 {
149                     test.top().setQuantity(Aq);
150                     a.push_back(test.top());
151                     test.pop();
152                     Aq=0;
153                     break;
154                 }
155                 break;
156             }    
157         }
158     return a;
159 }
Bid.h
 1 #ifndef BID_H
 2 #define BID_H
 3 
 4 #include <iostream>
 5 #include <string>
 6 #include "Date.h"
 7 
 8 using namespace std;
 9 
10 class Bid;
11 
12 istream &operator>>(istream &stream, Bid &b);
13 
14 class Bid {
15 
16   private:
17 
18     string email;
19     float amount;
20     int quantity;
21     Date date;
22 
23   public:
24   
25     Bid(void);
26     Bid(const Bid &b);
27     Bid (string email, float amount, int quantity, Date date);
28 
29     virtual string getEmail () const ;
30     virtual float getAmount () const;
31     virtual int getQuantity () const;
32     virtual Date getDate () const;
33     
34     virtual void setEmail(const string&);
35     virtual void setAmount(const float&);
36     virtual void setQuantity(const int&);
37     virtual void setDate(const Date&);
38 
39     virtual bool operator< (const Bid &rhs) const;
40     virtual bool operator== (const Bid &rhs) const;
41 };
42 
43 #endif
Bid.cpp
 1 #include"Bid.h"
 2 Bid::Bid()
 3 {
 4     this->email;
 5     this->amount=0;
 6     this->quantity=0;
 7     this->date;
 8 }
 9 Bid::Bid(string email, float amount, int quantity, Date date)
10 {
11     this->email=email;
12     this->amount=amount;
13     this->quantity=quantity;
14     this->date=date;
15 }
16 Bid::Bid(const Bid &b)
17 {
18     this->email=b.getEmail();
19     this->amount=b.getAmount();
20     this->quantity=b.getQuantity();
21     this->date=b.getDate();
22 
23 }
24 string Bid::getEmail() const
25 {
26     return this->email;
27 }
28 float Bid::getAmount() const
29 {
30     return this->amount;
31 }
32 int Bid::getQuantity() const
33 {
34     return this->quantity;
35 }
36 Date Bid::getDate() const
37 {
38     return this->date;
39 }
40 void Bid::setEmail(const string &email)
41 {
42     this->email=email;
43 }
44 void Bid::setAmount(const float &amount)
45 {
46     this->amount=amount;
47 }
48 void Bid::setQuantity(const int &quantity)
49 {
50     this->quantity=quantity;
51 }
52 void Bid::setDate(const Date &date)
53 {
54     this->date=date;
55 }
56 bool Bid::operator< (const Bid &rhs) const
57 {
58     if(this->amount<rhs.getAmount())
59         return true;
60     else
61         return false;
62 }
63 bool Bid::operator==(const Bid &rhs) const
64 {
65     if(this->amount==rhs.getAmount())
66         return true;
67     else
68         return false;
69     
70 
71 }
72 istream &operator>>(istream &stream, Bid &b)
73 {
74     string email;
75     float amount;
76     int quantity;
77     Date date;
78     stream>>email;
79     stream>>amount;
80     stream>>quantity;
81     stream>>date;
82     b.setAmount(amount);
83     b.setEmail(email);
84     b.setQuantity(quantity);
85     b.setDate(date);
86     return stream;
87     
88     
89 }
bidhistory.h
 1 #ifndef BIDHISTORY_H
 2 #define BIDHISTORY_H
 3 
 4 #include <sstream>
 5 
 6 using namespace std;
 7 
 8 void displayBidHistory(ostringstream &oss, Advertisement* ad);
 9 
10 #endif
bidhistory.cpp
 1 #include "main.h"
 2 #include "bidhistory.h"
 3 
 4 using namespace std;
 5 
 6 void displayBidHistory(ostringstream &oss, Advertisement* ad)
 7 {
 8     priority_queue<Bid> bids=ad->getBids();
 9     Client *client=users[ad->getEmail()];
10     int count=0;
11     oss<<"Advertisement Information"<<"<br><br>"<<endl;
12     oss <<"First name:"<<client->getFname()<<"<br>"<< endl;
13     oss<<"Last name:"<<client->getLname()<<"<br>"<<endl;
14     oss <<"Quantity:"<<ad->getQuantity()<<"<br>"<<endl;
15     oss<<"Total number of bids:"<<ad->getBids().size()<<"<br>"<<endl;
16     if(ad->getQuantity()==1)
17     {  
18         if(!bids.empty())
19         {
20         Bid b=bids.top();
21         
22         oss<<"highest bid"<<"<br>"<<endl;
23         oss<<"bidder's  email of highest bid:"<<b.getEmail()<<"<br>"<<endl;
24         oss<<"Dollar amount:"<<b.getAmount()<<"<br>"<<endl;
25         }
26     }
27     if(ad->getQuantity()>1)
28     {
29         vector<Bid> b=ad->getTopDutchBids();
30         oss<<"winning bids"<<"<br>"<<endl;
31         for(vector<Bid> ::iterator aaa=b.begin();aaa!=b.end();aaa++)
32         {
33             oss<<"-------------------------------------------------<br>";
34             oss<<"bidder's email address:"<<(*aaa).getEmail()<<"<br>";
35             oss<<"dollar amount of the bid:"<<(*aaa).getAmount()<<"<br>";
36             int size=bids.size();
37             int qq=0;
38             for(int i =0;i<size;i++)
39             {
40                 Bid rhs=bids.top();
41                 if(rhs.getEmail()==(*aaa).getEmail())
42                 {
43                     qq=qq+rhs.getQuantity();
44                 }
45                     bids.pop();
46             }
47             oss<<"the number of items bid on:"<<qq<<"<br>";
48             oss<<"The number of items winning: "<<(*aaa).getQuantity()<<"<br>";
49             count=count+(*aaa).getQuantity();
50             oss<<"-------------------------------------------------<br>";
51         }
52         oss<<"<br><br>";
53         oss<<"advertisement that have not been bid on:"<<ad->getQuantity()-count<<"<br>";
54     }
55 }
buildbidpage.h
 1 #ifndef BUILDBIDPAGE_H
 2 #define BUILDBIDPAGE_H
 3 
 4 #include <sstream>
 5 
 6 using namespace std;
 7 
 8 void buildbidpage (ostringstream &oss, int port, int number);
 9 void displayBidForm(ostringstream &oss, struct in_addr ip, int port, int number);
10 
11 #define CLASSIFIED_CGI "classified.cgi"
12 
13 #endif
buildbidpage.cpp
 1 #include <sstream>
 2 #include <winsock2.h>
 3 #include <ws2tcpip.h>
 4 #include <signal.h>
 5 #include <cstdio>
 6 
 7 #include "main.h"
 8 #include "buildpage.h"
 9 #include "buildbidpage.h"
10 #include "bidhistory.h"
11 #include "Client.h"
12 #include "Advertisement.h"
13 #include "Listing.h"
14 #include "Group.h"
15 
16 using namespace std;
17 
18 void buildbidpage (ostringstream &oss, int port, int number) {
19     
20     in_addr ip;
21     ip = getIP();
22 
23     displayPageHeader(oss);
24 
25     Advertisement *ad = NULL;
26     ad = advertisements[number];
27    
28     oss << "<table border=0 width=100%>" << endl;
29     oss << "<tr><td valign=top width=50%>" << endl;
30     oss << "<b>" << ad->getTitle() << "</b><br>" << endl;
31     displayBidHistory(oss, ad);
32 
33     oss << "<td valign=top>" << endl;
34     displayBidForm(oss, ip, port, number);
35     oss << "</tr></table>" << endl;
36  
37     oss << "</body>" << endl;
38     oss << "</html>" << endl;
39 }
40 
41 void displayBidForm(ostringstream &oss, struct in_addr ip, int port, int number) {
42 
43     Advertisement *ad = NULL;
44     ad = advertisements[number];
45 
46     oss << "<FORM ACTION=" << CLASSIFIED_CGI << " METHOD=POST>" << endl;
47     oss << "<INPUT NAME=PORT TYPE=hidden VALUE=" << port << ">" << endl;
48     oss << "<INPUT NAME=IP TYPE=hidden VALUE=" << inet_ntoa(ip) << ">" << endl;
49     oss << "<INPUT NAME=email TYPE=hidden VALUE=" << active_user << ">" << endl;
50     oss << "<INPUT NAME=number TYPE=hidden VALUE=" << number << ">" << endl;
51 
52     oss << "<b><center>Place Bid</center></b><br>" << endl;
53     oss << "<table border=0 width=100%>" << endl;
54     oss << "<tr><td align=right>Bid amount:" << endl;
55 
56     float high_bid = 0;
57     if (ad->getBids().size() > 0) {
58         high_bid = ad->getBids().top().getAmount();
59     }
60     oss << "<td><INPUT NAME=amount TYPE=text SIZE=5 VALUE="
61         << high_bid + 1 << "></tr>" << endl;
62  
63     oss << "<tr><td align=right>Quantity:" << endl;
64     if  (ad->getQuantity() > 1) {
65         oss << "<td><INPUT NAME=quantity SIZE=5 TYPE=text VALUE=1></tr>" << endl;
66     }
67     else {
68         oss << "<td><INPUT NAME=quantity TYPE=hidden VALUE=1>1</tr>" << endl;
69     }
70 
71     oss << "<tr><td align=center colspan=2>" << endl;
72     oss << "<INPUT NAME=COMMAND TYPE=submit VALUE=\"Submit bid\">" << endl;
73     oss << "</FORM>" << "</tr></table>" << endl;
74 }
buildpage.h
 1 #ifndef BUILDPAGE_H
 2 #define BUILDPAGE_H
 3 
 4 #include <sstream>
 5 #include "Listing.h"
 6 
 7 using namespace std;
 8 
 9 in_addr getIP(void);
10 void displayPageHeader(ostringstream &oss);
11 
12 void displaySortFind (ostringstream &oss, struct in_addr ip, int port);
13 void displayCategoryFilter(ostringstream &oss, struct in_addr ip, int port);
14 void displayPostItem (ostringstream &oss, struct in_addr ip, int port);
15 void displayRegister (ostringstream &oss, struct in_addr ip, int port);
16 void displayLogin (ostringstream &oss, struct in_addr ip, int port);
17 void displayLogout (ostringstream &oss, struct in_addr ip, int port);
18 void displayControlPanel (ostringstream &oss, struct in_addr ip, int port);
19 void displayAdvertisement (ostringstream &oss, Advertisement* ad, struct in_addr ip, 
20              int port);
21 void displayBidButton(ostringstream &oss, Advertisement* ad, struct in_addr ip, 
22                       int port);
23 
24 void buildpage (ostringstream &oss, int port, Listing::iterator start,
25                 Listing::iterator finish);
26 
27 #define CLASSIFIED_CGI "classified.cgi"
28 
29 #endif
buildpage.cpp
  1 #include <sstream>
  2 #include <winsock2.h>
  3 #include <ws2tcpip.h>
  4 #include <signal.h>
  5 #include <stdio.h>
  6 #include <ctime>
  7 
  8 #include "main.h"
  9 #include "buildpage.h"
 10 #include "Client.h"
 11 #include "Advertisement.h"
 12 #include "Listing.h"
 13 #include "Group.h"
 14 
 15 using namespace std;
 16 
 17 void buildpage (ostringstream &oss, int port,  Listing::iterator start, 
 18                 Listing::iterator finish) {
 19 
 20     in_addr ip;
 21     ip = getIP();
 22 
 23     displayPageHeader(oss);
 24 
 25     oss << "<TABLE width=100% cellpadding=3 cellspacing=3>" << endl;
 26     oss << "<TR>" << endl;
 27     oss << "<td width=50% class=advertisement>" << endl;
 28     displaySortFind(oss, ip, port);
 29     displayCategoryFilter(oss, ip, port);
 30  
 31     oss << "<table width=100%>" << endl;
 32     if (start == finish) {
 33         oss << "<tr><td><b>No items</b></td></tr>" << endl;  
 34     }
 35     else {
 36         for (Listing::iterator it = start; it != finish; it++) {
 37             oss << "<tr><td class=advertisement>" << endl;
 38             displayAdvertisement (oss, *it, ip, port);       
 39             oss << "</td></tr>" << endl;
 40         }
 41     }
 42     oss << "</table>";
 43           
 44     oss << "<td class=controlpanel>" << endl;
 45     displayControlPanel(oss, ip, port);
 46     oss << "</td></tr>" << endl;
 47 
 48     // Page Footer
 49     oss << "</TABLE>" << endl;
 50     oss << "</BODY>" << endl;
 51     oss << "</HTML>" << endl;
 52 
 53 }
 54 
 55 void displayPageHeader(ostringstream &oss) {
 56 
 57     // HTTP Content-type header
 58     oss << "Content-type: text/html" << "\r\n\r\n";
 59 
 60     // Start generating the page
 61     oss << "<HTML>" << endl;
 62     oss << "<HEAD>" << endl;
 63     oss << "<TITLE>" << endl;
 64     oss << "iCarnegie Auctions" << endl;
 65     oss << "</TITLE>" << endl;
 66     oss << "<link rel=\"stylesheet\" type=\"text/css\" href=\"/auction.css\" />" << endl;
 67     oss << "</HEAD>" << endl;
 68     oss << endl;
 69     oss << "<BODY>" << endl;
 70     oss << "<CENTER><H2>iCarnegie Auctions</H2></CENTER>" << endl;
 71 }
 72 
 73 void displayPostItem (ostringstream &oss, struct in_addr ip, int port) {
 74 
 75     oss << "<B><CENTER>" << "Post an Ad" << "</CENTER></B><BR>" << endl;
 76 
 77     oss << "<FORM ACTION=" << CLASSIFIED_CGI << " METHOD=POST>" << endl;
 78     oss << "<table border=0 width=100%>" << endl;
 79     oss << "<INPUT NAME=PORT TYPE=hidden VALUE=" << port << ">" << endl;
 80     oss << "<INPUT NAME=IP TYPE=hidden VALUE=" << inet_ntoa(ip) << ">" << endl;
 81     oss << "<INPUT NAME=email TYPE=hidden VALUE=" << active_user << ">" << endl;
 82     oss << "<tr><td align=right>Title:<td>" << endl;
 83     oss << "<INPUT NAME=title TYPE=text WIDTH=20 MAXWIDTH=20></tr>" << endl;
 84 
 85     oss << "<tr><td align=right>Category:<td>" << endl;
 86     oss << "<SELECT NAME=category>" << endl;
 87   
 88     for (Categories::iterator it = categories.begin();
 89        it != categories.end();
 90        it++) {
 91             
 92         oss << "<OPTION value=\"" << (*it)->getNumber() << "\">" 
 93             << (*it)->getName() << "</OPTION>" << endl;
 94     }
 95     oss << "</SELECT></tr>" << endl;
 96 
 97     oss << "<tr><td align=right>Length:<td><SELECT NAME=days>" << endl;
 98     oss << "<OPTION value=3>3 days" << endl;
 99     oss << "<OPTION SELECTED value=5>5 days" << endl;
100     oss << "<OPTION value=7>7 days" << endl;
101     oss << "</SELECT></tr>" << endl;
102     oss << "<tr><td align=right>Quantity:<td>" << endl;
103     oss << "<INPUT NAME=quantity VALUE=1 TYPE=text SIZE=5 MAXLENGTH=4></tr>" << endl;
104     oss << "<tr><td valign=top align=right>Description:<td>" << endl;
105     oss << "<TEXTAREA NAME=body COLS=20 ROWS=4>" << endl;
106     oss << "</TEXTAREA></tr>" << endl;
107     oss << "<tr><td align=center colspan=2><INPUT NAME=COMMAND VALUE=Add TYPE=submit></tr>" << endl;
108     oss << "</FORM></table>" << endl;
109 }
110 
111 void displaySortFind (ostringstream &oss, struct in_addr ip, int port) {
112 
113     oss << "<FORM ACTION=" << CLASSIFIED_CGI << " METHOD=POST>" << endl;
114     oss << "<INPUT NAME=PORT TYPE=hidden VALUE=" << port << ">" << endl;
115     oss << "<INPUT NAME=IP TYPE=hidden VALUE=" << inet_ntoa(ip) << ">" << endl;
116     oss << "<INPUT NAME=COMMAND VALUE=\"Sort\" TYPE=submit>" << endl;
117     oss << "&nbsp;&nbsp;" << endl;
118     oss << "<SELECT NAME=field>" << endl;
119     oss << "<OPTION value=\"close\">By close date" << endl;
120     oss << "<OPTION value=\"start\">By start date" << endl;
121     oss << "<OPTION value=\"email\">By seller email" << endl;  
122     oss << "<OPTION value=\"quantity\">By quantity" << endl;  
123     oss << "<OPTION value=\"highest\">By highest Bid" << endl;  
124     oss << "<OPTION value=\"lowest\">By lowest Bid" << endl;    
125     oss << "</SELECT>" << endl;
126     oss << "&nbsp;&nbsp;&nbsp;&nbsp;" << endl;
127     oss << "<INPUT NAME=COMMAND VALUE=\"Find\" TYPE=submit>" << endl;
128     oss << "&nbsp;&nbsp;" << endl;
129     oss << "<INPUT NAME=keyword TYPE=text SIZE=15 MAXLENGTH=20>" << endl;
130     oss << "</FORM>" << endl;
131 }
132 
133 void displayCategoryAdd(ostringstream &oss, struct in_addr ip, int port) {
134 
135   oss << "<B><CENTER>" << "Add Sub-Category" << "</CENTER></B><BR>" << endl;
136   oss << "<FORM ACTION=" << CLASSIFIED_CGI << " METHOD=POST>" << endl;
137   oss << "<INPUT NAME=PORT TYPE=hidden VALUE=" << port << ">" << endl;
138   oss << "<INPUT NAME=IP TYPE=hidden VALUE=" << inet_ntoa(ip) << ">" << endl;
139 
140   oss << "<table width=100%><tr><td align=right>Parent category:<td>" << endl;
141   oss << "<SELECT NAME=parent>" << endl;
142 
143   for (Categories::iterator it = categories.begin();
144        it != categories.end();
145        it++) {
146            
147     oss << "<OPTION value=\"" << (*it)->getNumber() << "\">" 
148         << (*it)->getName() << "</OPTION>" << endl;
149   }
150   oss << "</SELECT></tr>" << endl;
151 
152   oss << "<tr><td align=right>New category:<td>" << endl;
153   oss << "<INPUT NAME=newcategory TYPE=text></tr>" << endl;
154   oss << "<tr><td colspan=2 align=center>" << endl;
155   oss << "<INPUT NAME=COMMAND TYPE=submit VALUE=\"Add subcategory\">" << endl;
156   oss << "</tr></table></FORM>" << endl;
157 }
158 
159 void displayCategoryFilter(ostringstream &oss, struct in_addr ip, int port) {
160 
161     oss << "<FORM ACTION=" << CLASSIFIED_CGI << " METHOD=POST>" << endl;
162     oss << "<INPUT NAME=PORT TYPE=hidden VALUE=" << port << ">" << endl;
163     oss << "<INPUT NAME=IP TYPE=hidden VALUE=" << inet_ntoa(ip) << ">" << endl;
164     oss << "Category: " << endl;
165     oss << "<SELECT NAME=category>" << endl;
166   
167     for (Categories::iterator it = categories.begin();
168        it != categories.end();
169        it++) {
170         oss << "<OPTION value=\"" << (*it)->getNumber() << "\">" 
171             << (*it)->getName() << "</OPTION>" << endl;
172     }
173     oss << "</SELECT>" << endl;
174 
175     oss << "<INPUT NAME=COMMAND VALUE=\"Top Only\" TYPE=submit>" << endl;
176     oss << "<INPUT NAME=COMMAND VALUE=\"Recursive\" TYPE=submit>" << endl;
177     oss << "</FORM>" << endl;
178 }
179 
180 void displayRegister (ostringstream &oss, struct in_addr ip, int port) {
181 
182     oss << "<B><CENTER>Create Account</CENTER></B><BR>" << endl;
183     if (!create_verified) {
184       oss << "<FONT COLOR=red>Passwords didn't match.</FONT>" << endl;
185       create_verified = true;
186     }
187     oss << "<table width=100%>" << endl;
188     oss << "<FORM ACTION=" << CLASSIFIED_CGI << " METHOD=POST>" << endl;
189     oss << "<INPUT NAME=PORT TYPE=hidden VALUE=" << port << ">" << endl;
190     oss << "<INPUT NAME=IP TYPE=hidden VALUE=" << inet_ntoa(ip) << ">" << endl;
191     oss << "<tr><td align=right>Email:<td><INPUT NAME=email TYPE=text SIZE=20 MAXLENGTH=30></tr>" 
192         << endl;
193     oss << "<tr><td align=right>Last name:<td><INPUT NAME=lname TYPE=text SIZE=20 MAXLENGTH=20></tr>" 
194         << endl;
195     oss << "<tr><td align=right>First name:<td><INPUT NAME=fname TYPE=text SIZE=20 MAXLENGTH=20></tr>" 
196         << endl;
197     oss << "<tr><td align=right>Password:<td><INPUT NAME=passwd TYPE=password SIZE=20 MAXLENGTH=60></tr>" << endl;
198     oss << "<tr><td align=right>Password (again):<td><INPUT NAME=passwd2 TYPE=password SIZE=20 MAXLENGTH=60></tr>" << endl;
199     oss << "<tr><td align=center colspan=2><INPUT NAME=COMMAND VALUE=\"Create\" TYPE=submit></tr>" << endl;
200     oss << "</FORM>" << endl;
201 }
202 
203 void displayControlPanel (ostringstream &oss, struct in_addr ip, int port) {
204 
205     // If someone is logged in
206     if ("" != active_user) {
207 
208         displayLogout(oss, ip, port);
209         oss << "<hr>" << endl;
210 
211         displayPostItem(oss, ip, port);
212         oss << "<hr>" << endl;
213 
214         displayCategoryAdd(oss, ip, port);
215     }
216     else {
217 
218         displayLogin(oss, ip, port);
219         oss << "<hr>" << endl;
220 
221         displayRegister(oss, ip, port);
222     }
223 }
224 
225 void displayLogout (ostringstream &oss, struct in_addr ip, int port) {
226 
227     oss << "<center>" << endl;
228     oss << "Your userid: " << active_user << "&nbsp;&nbsp;&nbsp;" << endl;
229     oss << "<FORM ACTION=" << CLASSIFIED_CGI << " METHOD=POST>" << endl;
230     oss << "<INPUT NAME=PORT TYPE=hidden VALUE=" << port << ">" << endl;
231     oss << "<INPUT NAME=IP TYPE=hidden VALUE=" << inet_ntoa(ip) << ">" << endl;
232     oss << "<INPUT NAME=COMMAND VALUE=Logout TYPE=submit>" << endl;
233     oss << "</FORM></center>" << endl;
234 }
235 
236 void displayLogin (ostringstream &oss, struct in_addr ip, int port) {
237 
238     oss << "<center>" << endl;
239     if (login_failed) {
240       oss << "<b><FONT COLOR=red>Login failed.</FONT></b></br>" << endl;
241       login_failed = false;
242     }
243     else {
244       oss << "<b>Login</b></br>" << endl;
245     }
246     oss << "</center>" << endl;
247 
248     oss << "<table border=0 width=100%>" << endl;
249     oss << "<FORM ACTION=" << CLASSIFIED_CGI << " METHOD=POST>" << endl;
250     oss << "<INPUT NAME=PORT TYPE=hidden VALUE=" << port << ">" << endl;
251     oss << "<INPUT NAME=IP TYPE=hidden VALUE=" << inet_ntoa(ip) << ">" << endl;
252     oss << "<tr><td align=right>Email:" << endl;
253     oss << "<td><INPUT NAME=email TYPE=text SIZE=12 MAXLENGTH=30></tr>" << endl; 
254     oss << "<tr><td align=right>Password:" << endl;
255     oss << "<td><INPUT NAME=passwd TYPE=password SIZE=12 MAXWLENGTH=10></tr>" << endl;
256     oss << "<tr><td colspan=2 align=center>" << endl;
257     oss << "<INPUT NAME=COMMAND VALUE=\"Login\" TYPE=submit>" << endl;
258     oss << "</FORM></tr></table>" << endl;
259 
260 }
261 
262 void displayAdvertisement (ostringstream &oss, Advertisement* ad, struct in_addr ip, 
263              int port) {
264 
265     Client* seller = NULL;
266     seller = users[ad->getEmail()];
267 
268     oss << "<table border=0 width=100%><tr><td align=center width=15%>" << endl;     
269     if ("" != active_user) {
270         displayBidButton(oss, ad, ip, port);
271     }
272     else {
273         oss << "&nbsp;" << endl;
274     }
275     oss << "<td>" << endl;
276     oss << "<B>" << ad->getTitle() << "</B><br>" << endl;
277     oss << "Posted by: <A HREF=mailto:" << ad->getEmail() << ">";  
278     oss << seller->getLname() << ", " << seller->getFname() << "</a><br>" << endl;
279     oss << "Posted: " << ad->getStart() << "<br>" << endl;
280     oss << "Closes: " << ad->getClose() << "<br>" << endl;
281     oss << "Quantity: "    << ad->getQuantity() << "<br>" << endl;
282     oss << "Number of bids: " << ad->getBids().size() << "<br>" << endl;
283     
284     if (ad->getBids().size() > 0) {
285         oss << "High bid: $" << ad->getBids().top().getAmount() << "<br>" << endl;
286     }
287     
288     oss << ad->getBody() << endl;
289     oss << "</tr></table>" << endl;
290 } 
291 
292 void displayBidButton(ostringstream &oss, Advertisement* ad, struct in_addr ip, 
293                       int port) {
294 
295     oss << "<FORM ACTION=" << CLASSIFIED_CGI << " METHOD=POST>" << endl;
296     oss << "<INPUT NAME=PORT TYPE=hidden VALUE=" << port << ">" << endl;
297     oss << "<INPUT NAME=IP TYPE=hidden VALUE=" << inet_ntoa(ip) << ">" << endl;
298     oss << "<INPUT NAME=email TYPE=hidden VALUE=" << active_user << ">" << endl;
299     oss << "<INPUT NAME=number VALUE=" << ad->getNumber() << " TYPE=hidden>" << endl;
300     oss << "<INPUT NAME=COMMAND VALUE=Bid TYPE=submit></FORM>" << endl;
301 }
302 
303 in_addr getIP(void) {
304 
305     // Find self for form parm
306     char hostname_str[256];
307     gethostname (hostname_str, 256);
308     hostent *he = gethostbyname (hostname_str);
309     in_addr ip;
310     memcpy (&ip.s_addr, he->h_addr_list[0], sizeof(ip.s_addr));
311 
312     return ip;
313 }
Categories.h
 1 #ifndef CATEGORIES_H
 2 #define CATEGORIES_H
 3 
 4 #include <string>
 5 #include <vector>
 6 
 7 #include "Category.h"
 8 #include "Listing.h"
 9 
10 using namespace std;
11 
12 class Categories {
13 
14   protected:
15     typedef vector<Category*> Container;
16 
17   public:
18     typedef Container::iterator iterator;
19 
20   protected:
21     Container objects;
22 
23   public:
24     static const int TOP_LEVEL=0;
25     static const int NO_PARENT=0;
26     
27     virtual Category* operator[](const int& number);
28     virtual void add(Category* ptr);
29 
30     virtual iterator begin();
31     virtual iterator end();
32 
33 };
34 
35 
36 #endif
Categories.cpp
 1 #include "Categories.h"
 2 Category* Categories::operator[](const int& number)
 3 {
 4     for(vector<Category*>::iterator aa=objects.begin();aa!=objects.end();aa++)
 5     {
 6         if((*aa)->getNumber()==number)
 7         {
 8             return *aa;
 9         }
10         
11     }
12     return NULL;
13 }
14 void Categories::add(Category* ptr)
15 {
16             objects.push_back(ptr);
17 }
18 vector<Category*>::iterator Categories::begin()
19 {
20     return objects.begin();
21 }
22 vector<Category*>::iterator Categories::end()
23 {
24     return objects.end();
25 }
Category.h
 1 #ifndef CATEGORY_H
 2 #define CATEGORY_H
 3 
 4 #include <string>
 5 #include <vector>
 6 
 7 #include "Listing.h"
 8 
 9 using namespace std;
10 
11 class Category;
12 
13 istream &operator>>(istream &stream, Category &c);
14 
15 class Category {
16 
17 public:
18     int number;
19     int parent;
20     string name;
21 
22     vector<Category*> sub_categories;
23     vector<int> items;
24 
25 
26     
27     Category(void);
28     Category(int parent, string name);
29 
30     virtual int getNumber(void) const;
31     virtual int getParent(void) const;
32     virtual string getName(void) const;
33     
34     virtual void setNumber(int);
35     virtual void setParent(int);
36     virtual void setName(string);
37 
38     virtual void addSubCategory(Category*);
39     virtual void addItem(int);
40 
41     virtual void findOfferings (Listing::iterator start, 
42                     Listing::iterator finish, Listing &matches);
43     virtual void findOfferingsRecursive (Listing::iterator start, 
44                     Listing::iterator finish, Listing &matches);
45 
46     virtual vector<int>::iterator itemsBegin();
47     virtual vector<int>::iterator itemsEnd();
48     virtual vector<Category*>::iterator subCategoriesBegin();
49     virtual vector<Category*>::iterator subCategoriesEnd();
50 
51     virtual bool operator==(const Category& rhs);
52 
53 };
54 
55 #endif
Category.cpp
  1 #include "Category.h"
  2 
  3 Category::Category()
  4 {
  5     this->number=0;
  6     this->parent=0;
  7     this->name;
  8 
  9 }
 10 int Category::getNumber(void) const
 11 {
 12     return this->number;
 13 }
 14 int Category::getParent(void) const
 15 {
 16     return this->parent;
 17 }
 18 string Category::getName(void) const
 19 {
 20     return this->name;
 21 }
 22 void Category::setNumber(int a)
 23 {
 24     this->number=a;
 25 }
 26 void Category::setParent(int a)
 27 {
 28     this->parent=a;
 29 }
 30 void Category::setName(string a)
 31 {
 32     this->name=a;
 33 }
 34 Category::Category(int parent, string name)
 35 {
 36     this->parent=parent;
 37     this->name=name;
 38 }
 39 vector<int>::iterator Category::itemsBegin()
 40 {
 41     return items.begin();
 42 }
 43 vector<int>::iterator Category::itemsEnd()
 44 {
 45     return items.end();
 46 }
 47 vector<Category*>::iterator Category::subCategoriesBegin()
 48 {
 49     return sub_categories.begin();
 50 }
 51 vector<Category*>::iterator Category::subCategoriesEnd()
 52 {
 53     return sub_categories.end();
 54 }
 55 void Category::addItem(int item)
 56 {
 57     items.push_back(item);
 58 }
 59 void Category::addSubCategory(Category* ptr)
 60 {
 61     
 62         sub_categories.push_back(ptr);
 63     
 64     
 65 }
 66 void Category::findOfferings(Listing::iterator start, Listing::iterator finish, Listing &matches)
 67 {
 68     Listing::iterator aa;
 69 
 70     for(aa=start;aa!=finish;aa++)
 71     {
 72         matches.add(*aa);
 73     }
 74 }
 75 void Category::findOfferingsRecursive (Listing::iterator start, Listing::iterator finish, Listing &matches)
 76 {
 77     findOfferings(start,finish,matches);
 78     vector<Category*> ::iterator aaa;
 79     for(aaa=sub_categories.begin();aaa!=sub_categories.end();aaa++)
 80     {
 81         (*aaa)->findOfferingsRecursive(start,finish,matches);
 82     }
 83 }
 84 istream &operator>>(istream &stream, Category &b)
 85 {
 86     int a;
 87     string bb;
 88     stream>>a;
 89     stream>>bb;
 90     b.setNumber(a);
 91     b.setName(bb);
 92     return stream;
 93 }
 94 bool Category::operator==(const Category& rhs)
 95 {
 96     if(this->getNumber()==rhs.getNumber())
 97     {
 98         return true;
 99     }
100     return false;
101 }
Client.h
 1 #ifndef CLIENT_H
 2 #define CLIENT_H
 3 
 4 #include <string>
 5 #include <vector>
 6 #include "Date.h"
 7 
 8 using namespace std;
 9 
10 class Client;
11 
12 istream &operator>>(istream &stream, Client &c);
13 
14 class Client {
15 
16   private:
17 
18     string fname;
19     string lname;
20     string email;
21     string passwd;
22     vector<int> offerings;
23     vector<int> bids;
24 
25   public:
26   
27     Client(void);
28     Client(Client const &c);
29     Client (string &fname, string &lname, string &email, string &passwd);
30 
31     virtual void setFname(const string&);
32     virtual void setLname(const string&);
33     virtual void setEmail(const string&);
34     virtual void setPasswd(const string&);
35 
36     virtual string getFname () const;
37     virtual string getLname () const;
38     virtual string getEmail () const;
39     virtual string getPasswd () const;
40 
41     virtual vector<int>::iterator beginOfferings();
42     virtual vector<int>::iterator endOfferings();
43     virtual vector<int>::iterator beginBids();
44     virtual vector<int>::iterator endBids();
45 
46     virtual void addBid (int item);
47     virtual void addOffering (int item);
48     virtual bool verifyPasswd(string passwd);
49 
50 };
51 
52 #endif
Client.cpp
  1 #include "Client.h"
  2 Client::Client()
  3 {
  4     string fname;
  5     string lname;
  6     string email;
  7     string passwd;
  8 }
  9 Client::Client(string &fname, string &lname, string &email, string &passwd)
 10 {
 11     this->fname=fname;
 12     this->lname=lname;
 13     this->email=email;
 14     this->passwd=passwd;
 15 }
 16 Client::Client(Client const &c)
 17 {
 18     this->fname=c.getFname();
 19     this->lname=c.getLname();
 20     this->email=c.getEmail();
 21     this->passwd=c.getPasswd();
 22 }
 23 void Client::setFname(const string &c)
 24 {
 25     this->fname=c;
 26 }
 27 void Client::setLname(const string &d)
 28 {
 29     this->lname=d;
 30 }
 31 void Client::setEmail(const string &e)
 32 {
 33     this->email=e;
 34 }
 35 void Client::setPasswd(const string &f)
 36 {
 37     this->passwd=f;
 38 }
 39 string Client::getFname () const
 40 {
 41     return this->fname;
 42 }
 43 string Client::getLname () const
 44 {
 45     return this->lname;
 46 }
 47 string Client::getEmail () const
 48 {
 49     return this->email;
 50 }
 51 string Client::getPasswd () const
 52 {
 53     return this->passwd;
 54 }
 55 bool Client::verifyPasswd(string passwd)
 56 {
 57     if(this->passwd==passwd)
 58     {
 59         return true;
 60     }
 61     else
 62     {
 63         return false;
 64     }
 65 }
 66 istream &operator>>(istream &stream, Client &c)
 67 {
 68     string fname;
 69     string lname;
 70     string email;
 71     string passwd;
 72     stream>>fname;
 73     stream>>lname;
 74     stream>>email;
 75     stream>>passwd;
 76     c.setFname(fname);
 77     c.setLname(lname);
 78     c.setEmail(email);
 79     c.setPasswd(passwd);
 80     return stream;
 81         
 82 }
 83 vector<int>::iterator Client::beginOfferings()
 84 {
 85     return this->offerings.begin();
 86 }
 87 vector<int>::iterator Client::endOfferings()
 88 {
 89     return this->offerings.end();
 90 }
 91 vector<int>::iterator Client::beginBids()
 92 {
 93     return this->bids.begin();
 94 }
 95 vector<int>::iterator Client::endBids()
 96 {
 97     return this->bids.end();
 98 }
 99 void Client::addBid(int item)
100 {
101     this->bids.push_back(item);
102 }
103 void Client::addOffering(int item)
104 {
105     this->offerings.push_back(item);
106 }
Date.h
 1 #ifndef DATE_H
 2 #define DATE_H
 3 
 4 #include <iostream>
 5 
 6 using namespace std;
 7 
 8 class Date;
 9 
10 ostream &operator<<(ostream&, const Date&);
11 istream &operator>>(istream&, Date&);
12 
13 class Date {
14 
15   private:
16     int month;
17     int day;
18     int year;
19     int hour;
20     int minute;
21     int second;
22 
23   public:
24     
25     Date(void);
26     Date (int month, int day, int year, int hour, int minute, int second);
27     
28     virtual void setMonth(int&);        
29     virtual void setDay(int&);
30     virtual void setYear(int&);
31     virtual void setHour(int&);
32     virtual void setMinute(int&);
33     virtual void setSecond(int&);
34     
35     virtual int getMonth(void) const;        
36     virtual int getDay(void) const;        
37     virtual int getYear(void) const;        
38     virtual int getHour(void) const;        
39     virtual int getMinute(void) const;        
40     virtual int getSecond(void) const;        
41 
42     virtual bool operator== (const Date &rhs);
43     virtual bool operator< (const Date &left);
44 
45 };
46 
47 #endif
Date.cpp
  1 #include <iostream>
  2 #include <string>
  3 #include <cstdlib>
  4 #include <sstream>
  5 #include "Date.h"
  6 
  7     Date::Date()
  8     {
  9         this->month=0;
 10         this->day=0;
 11         this->year=0;
 12         this->hour=0;
 13         this->minute=0;
 14         this->second=0;
 15     }
 16     Date::Date(int month, int day, int year, int hour, int minute, int second)
 17     {
 18         this->month=month;
 19         this->day=day;
 20         this->year=year;
 21         this->hour=hour;
 22         this->minute=minute;
 23         this->second=second;
 24     }
 25     
 26     void Date::setDay(int &day)
 27     {
 28         this->day=day;
 29     }
 30     void Date::setHour(int &hour)
 31     {
 32         this->hour=hour;
 33     }
 34     void Date::setMinute(int &minute)
 35     {
 36         this->minute=minute;
 37     }
 38     void Date::setMonth(int &month)
 39     {
 40         this->month=month;
 41     }
 42     void Date::setSecond(int &second)
 43     {
 44         this->second=second;
 45     }
 46     void Date::setYear(int &year)
 47     {
 48         this->year=year;
 49     }
 50     int Date::getDay(void) const
 51     {
 52         return this->day;
 53     }
 54     int Date::getHour(void)const
 55     {
 56         return this->hour;
 57     }
 58     int Date::getMinute(void)const
 59     {
 60         return this->minute;
 61     }
 62     int Date::getMonth(void)const
 63     {
 64         return this->month;
 65     }
 66     int Date::getSecond(void)const
 67     {
 68         return this->second;
 69     }
 70     int Date::getYear(void)const
 71     {
 72         return this->year;
 73     }
 74     bool Date::operator ==(const Date &rhs)
 75     {
 76         if(this->day==rhs.getDay()&&this->hour==rhs.getHour()&&this->minute==rhs.getMinute()&&this->month==rhs.getMonth()&&this->year==rhs.getYear())
 77         {
 78             return true;
 79         }
 80         else
 81         {
 82             return false;
 83         }
 84     }
 85     bool Date::operator< (const Date &rhs)
 86     {
 87         if(this->year!=rhs.getYear())
 88         {
 89             if(this->year<rhs.getYear())
 90                 return true;
 91             else
 92                 return false;
 93         }
 94         else if(this->month!=rhs.getMonth())
 95         {
 96             if(this->month<rhs.getMonth())
 97                 return true;
 98             else
 99                 return false;
100         }
101         else if(this->day!=rhs.getDay())
102         {
103             if(this->day<rhs.getDay())
104                 return true;
105             else 
106                 return false;
107         }
108         else if(this->hour!=rhs.getHour())
109         {
110             if(this->hour<rhs.getHour())
111                 return true;
112             else 
113                 return false;
114         }
115         else if(this->minute!=rhs.getMinute())
116         {
117             if(this->minute<rhs.getMinute())
118                 return true;
119             else
120                 return false;
121         }
122         else if(this->second!=rhs.getSecond())
123         {
124             if(this->second<rhs.getSecond())
125                 return true;
126             else
127                 return false;
128         }
129         else
130         {
131             return false;
132         }
133 
134     }
135     ostream &operator<<(ostream &out, const Date &c)
136     {
137         out<<c.getMonth()<<"/"<<c.getDay()<<"/"<<c.getYear()<<" "<<c.getHour()<<":"<<c.getMinute()<<":"<<c.getSecond();
138         return out;
139     }
140 istream &operator>>(istream& stream, Date &c)
141 {
142     int month;
143     int day;
144     int year;
145     int hour;
146     int minute;
147     int second;
148     char a;
149     char b;
150     char cx;
151     char d;
152     char e;
153     
154     stream>>month;
155     stream>>a;
156     stream>>day;
157     stream>>b;
158     stream>>year;
159     
160     stream>>hour;
161     stream>>d;
162     stream>>minute;
163     stream>>e;
164     stream>>second;
165     c.setDay(day);
166     c.setHour(hour);
167     c.setMinute(minute);
168     c.setMonth(month);
169     c.setSecond(second);
170     c.setYear(year);
171     return stream;
172 }
Group.h
 1 #ifndef GROUP_H
 2 #define GROUP_H
 3 
 4 #include <iostream>
 5 #include <vector>
 6 #include <iterator>
 7 #include <algorithm>
 8 #include <functional>
 9 
10 #include "Client.h"
11 
12 using namespace std;
13 
14 class Group;
15 
16 class Group {
17 
18 protected:
19     typedef vector<Client*> Container;
20 
21 public:
22     typedef Container::iterator iterator;
23 
24 protected:
25     Container objects;
26 
27 public:
28     Client *operator[](const string& email);
29 
30     virtual void add(Client* ptr);
31 
32     virtual iterator begin();
33     virtual iterator end();
34 
35 };
36 
37 #endif
Group.cpp
 1 #include "Group.h"
 2 void Group::add(Client* ptr)
 3 {
 4     objects.push_back(ptr);
 5 }
 6 vector<Client*> ::iterator Group::begin()
 7 {
 8     return objects.begin();
 9 }
10 vector<Client*> ::iterator Group::end()
11 {
12     return objects.end();
13 }
14 Client * Group::operator[](const string& email)
15 {
16     for(vector<Client*> ::iterator aaa=objects.begin();aaa!=objects.end();aaa++)
17     {
18         if((*aaa)->getEmail()==email)
19         {
20             return *aaa;
21         }
22     }
23     return NULL;
24 }
Listing.h
 1 #ifndef LISTING_H
 2 #define LISTING_H
 3 
 4 #include <iostream>
 5 #include <vector>
 6 #include <iterator>
 7 #include <algorithm>
 8 #include <functional>
 9 
10 #include "Advertisement.h"
11 
12 using namespace std;
13 
14 class Listing;
15 
16 class Listing {
17 
18 protected:
19     typedef vector<Advertisement*> Container;
20 
21 public:
22     typedef Container::iterator iterator;
23 
24 protected:
25     Container objects;
26 
27 public:
28     virtual Advertisement* operator[](const int& number);
29 
30     virtual void add(Advertisement* ptr);
31 
32     virtual iterator begin();
33     virtual iterator end();
34 
35     // return a sorted copy of this Listing
36     virtual Listing sort(string field);
37 
38     // return a filtered by keyword copy of this Listing
39     virtual Listing filter(string keyword);
40 };
41 
42 #endif
Listing.cpp
  1 #include "Listing.h"
  2 
  3 
  4 void Listing::add(Advertisement* ptr)
  5 {
  6     objects.push_back(ptr);
  7     
  8 }
  9 vector<Advertisement*>::iterator Listing::begin()
 10 {
 11     
 12     return objects.begin();
 13 }
 14 vector<Advertisement*>::iterator Listing::end()
 15 {
 16     return objects.end();
 17 }
 18 Advertisement* Listing::operator[](const int& number)
 19 {
 20     for(vector<Advertisement*> ::iterator aa=objects.begin();aa!=objects.end();aa++)
 21     {
 22         if((*aa)->getNumber()==number)
 23         {
 24             return *aa;
 25         }
 26     }
 27     return NULL;
 28 }
 29 bool cmp4(Advertisement *m1,Advertisement *m2)
 30 {
 31     if(m1->getQuantity()<m2->getQuantity())
 32     {
 33         return true;
 34     }
 35     return false;
 36 }
 37 bool cmp1(Advertisement *m1,Advertisement *m2)
 38 {
 39     int a=m1->getEmail().compare(m2->getEmail());
 40     if(a<0)
 41     {
 42         return true;
 43     }
 44     else
 45     {
 46         return false;
 47     }
 48 }
 49 bool cmp2(Advertisement *m1,Advertisement *m2)
 50 {
 51     return m1->getStart()<m2->getStart();
 52 }
 53 bool cmp3(Advertisement *m1,Advertisement *m2)
 54 {
 55     return m1->getClose()<m2->getClose();
 56 }
 57 Listing Listing::sort(string field)
 58 {
 59     Listing cp;
 60     cp.objects=this->objects;
 61     if(field=="email")
 62     {
 63         std::sort(cp.objects.begin(),cp.objects.end(),cmp1);
 64         return cp;
 65     }
 66     else if(field=="start")
 67     {
 68         std::sort(cp.objects.begin(),cp.objects.end(),cmp2);
 69         return cp;
 70     }
 71     else if(field=="end")
 72     {
 73         std::sort(cp.objects.begin(),cp.objects.end(),cmp3);
 74         return cp;
 75     }
 76     else
 77     {
 78         std::sort(cp.objects.begin(),cp.objects.end(),cmp4);
 79         return cp;
 80     }
 81 }
 82 Listing l;
 83 struct F
 84 {
 85     string key;
 86     
 87     F(string keyword):key(keyword){}
 88     void operator() (Advertisement* a)
 89     {
 90         if(a->getTitle().find(key)!=string::npos||a->getBody().find(key)!=string::npos)
 91         {
 92             l.add(a);
 93         }
 94     }
 95         
 96 };
 97 Listing Listing::filter(string keyword)
 98 {
 99     
100     
101     if(keyword=="")
102     {
103         return l;
104     }
105     else
106     {
107         l.objects.clear();
108         std::for_each(this->begin(),this->end(),F(keyword));
109         return l;
110     }
111     
112 }
main.h
 1 #ifndef MAIN_H
 2 #define MAIN_H
 3 
 4 #include "Listing.h"
 5 #include "Categories.h"
 6 #include "Group.h"
 7 
 8 #define BACKLOG 11
 9 #define REQ_MAX 8192
10 
11 extern Categories categories;
12 extern Listing advertisements;
13 extern Group users;
14 
15 extern string active_user;
16 
17 extern int category_counter;
18 extern int advertisement_counter;
19 
20 extern bool create_verified;
21 extern bool login_failed;
22 
23 #endif
main.cpp
  1 #include <winsock2.h>
  2 #include <ws2tcpip.h>
  3 #include <signal.h>
  4 #include <cstdio>
  5 
  6 #include <string>
  7 #include <fcntl.h>
  8 #include <errno.h>
  9 #include <iostream>
 10 #include <sstream>
 11 
 12 #include "Listing.h"
 13 #include "Group.h"
 14 #include "Categories.h"
 15 #include "processrequest.h"
 16 #include "main.h"
 17 
 18 using namespace std;
 19 
 20 Categories categories;
 21 Listing advertisements;
 22 Group users;
 23 
 24 int category_counter = 0;
 25 int advertisement_counter = 0;
 26 
 27 string active_user = "";
 28 bool create_verified = true;
 29 bool login_failed = false;
 30 
 31 
 32 /*
 33  * Not this is explicitly not concurrent -- the auction data structures
 34  * are not necessarily concurrency safe
 35  */
 36 
 37 int main (int argc, char *argv[]) {
 38 
 39     
 40 
 41   /*
 42    * argv[1] should be the port number
 43    */
 44   if (2 != argc) {
 45     cout << "Usage: " << argv[0] << " [port]" << endl << endl;
 46     return -1;
 47   }
 48 
 49   int port = atoi(argv[1]);
 50 
 51 
 52     WORD wVersionRequested;
 53     WSADATA wsaData;
 54     int err;
 55  
 56     wVersionRequested = MAKEWORD( 2, 2 );
 57  
 58     err = WSAStartup( wVersionRequested, &wsaData );
 59     if ( err != 0 ) {
 60         /* Tell the user that we could not find a usable */
 61         /* WinSock DLL.                                  */
 62         return 0;
 63     }
 64 
 65 
 66 
 67   /*
 68    * Create and configure the socket
 69    */
 70   int connfd = -1;
 71   int listenfd = -1; 
 72   
 73   struct sockaddr_in cliaddr;
 74   struct sockaddr_in servaddr;
 75   int clilen = sizeof (cliaddr);
 76 
 77   listenfd = socket (AF_INET, SOCK_STREAM, 0); 
 78 
 79   memset(&servaddr, 0, sizeof(servaddr));
 80   servaddr.sin_family = AF_INET;
 81   servaddr.sin_addr.s_addr = htonl (INADDR_ANY);
 82   servaddr.sin_port = htons(port);
 83 
 84 
 85   /*
 86    * Bind to the socket
 87    */
 88   ::bind (listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
 89 
 90 
 91   /*
 92    * Configure the listen queue
 93    */
 94   listen (listenfd, BACKLOG);
 95   
 96   /*
 97    * Main work loop:
 98    * Listen for connection, accept it, process request, print html page
 99    */
100 
101   Category top_level(Categories::NO_PARENT, "Top Level");
102   top_level.setNumber(category_counter);
103   category_counter++;
104   
105   categories.add(new Category(top_level));
106 
107   
108   while (true) {
109 
110     // Wait for the knock at the door
111     if (0 > (connfd = accept (listenfd, 
112                               (struct sockaddr *) &cliaddr, &clilen)) ) {
113 
114      if (errno == EINTR)
115         continue;
116      else {
117         cerr << "unknown error: " << errno << " " << connfd << endl;
118         exit(-1); // Who knows? Bad foo. Maybe continue for roubustness?
119         
120         }
121 
122     }
123 
124     // Process the request
125     char req_buffer[REQ_MAX];
126     int count;
127 
128 
129  
130     for (count=0; count<REQ_MAX; count++) {
131       int retval = recv (connfd, req_buffer+count, 1, 0);
132 
133       if (4 == req_buffer[count]) { // 4 is EOT, a.ka. CTRL-D 
134         req_buffer[count] = '\0';
135         break;
136       }
137     }
138 
139   
140     // Move request to stream for C++ style processing
141     ostringstream oss;
142     oss.str("");
143     oss << req_buffer;
144     memset (req_buffer, 0, REQ_MAX);
145 
146     cerr << oss.str() << endl;
147 
148     istringstream iss (oss.str());
149 
150     processrequest (iss, connfd, port);
151     
152     // Done with this request
153     closesocket (connfd);
154     connfd = -1;
155   }
156 
157 }
processrequest.h
 1 #ifndef PROCESS_REQUEST_H
 2 #define PROCESS_REQUEST_H
 3 
 4 #include <sstream>
 5 #include "buildpage.h"
 6 #include "buildbidpage.h"
 7 
 8 using namespace std;
 9 
10 void processrequest(istringstream &iss, int connfd, int port);
11 
12 #endif
processrequest.cpp
  1 #pragma warning(disable:4786)
  2 
  3 #include <sstream>
  4 #include <set>
  5 #include <string>
  6 #include <winsock2.h>
  7 #include <ws2tcpip.h>
  8 #include <fcntl.h>
  9 #include <errno.h>
 10 
 11 #include "processrequest.h"
 12 #include "main.h"
 13 #include "Advertisement.h"
 14 #include "Listing.h"
 15 #include "Client.h"
 16 #include "Categories.h"
 17 //#include "CopyByKeyword.h"
 18 //#include "SortBy.h"
 19 
 20 using namespace std;
 21 
 22 void displayListing(int connfd, int port, 
 23                     Listing::iterator begin, Listing::iterator end) {
 24 
 25     ostringstream oss ("");
 26     buildpage (oss, port, begin, end);
 27     send (connfd, oss.str().c_str(), strlen (oss.str().c_str()), 0);
 28 }
 29 
 30 
 31 
 32 
 33 void processrequest(istringstream &iss, int connfd, int port) {
 34 
 35   char request[80];
 36   memset (request, 0, 80);
 37   iss.getline (request, 80);
 38   string req(request); 
 39   
 40   // instead of the above, we could have
 41   // just as easily done
 42   // getline(iss, req)
 43   // but there is a bug in MSVC++ getline, so
 44   // using the C-style string here is more portable
 45   
 46   if (req == "LOGIN") {
 47 
 48     string email;
 49     string passwd;
 50 
 51     iss >> email;
 52     iss >> passwd;
 53 
 54     /*
 55      * Find the client's record in the set
 56      */
 57     Client* search_results = users[email];
 58    
 59     if (search_results != NULL) {
 60         
 61         if (search_results->verifyPasswd(passwd)) {
 62             active_user = email;
 63             login_failed = false;
 64         }
 65         else {
 66             login_failed = true;
 67         }
 68     }
 69     else {
 70         login_failed = true;
 71     }
 72 
 73     displayListing(connfd, port, advertisements.begin(), advertisements.end());
 74   }
 75 
 76   else if (req == "LOGOUT") {
 77     active_user = "";
 78     displayListing(connfd, port, advertisements.begin(), advertisements.end());
 79   }
 80 
 81   else if (req == "BID_REQUEST") {
 82 
 83     int number;
 84     iss.getline(request, 80);
 85     number = atoi(request);
 86 
 87     ostringstream oss ("");
 88     buildbidpage (oss, port, number);
 89     send (connfd, oss.str().c_str(), strlen (oss.str().c_str()), 0);
 90 
 91   }
 92 
 93   else if (req == "BID_SUBMIT") {
 94 
 95     // Add the bid
 96     int number;
 97     iss.getline(request, 80);
 98     number = atoi(request);
 99       
100     Bid newBid;
101     iss >> newBid;
102     Advertisement* ad = advertisements[number];
103 
104     if (newBid.getQuantity() < 1) {
105         newBid.setQuantity(1);
106     } else if (newBid.getQuantity() > ad->getQuantity()) {
107         newBid.setQuantity(ad->getQuantity());
108     }
109 
110     ad->getBids().push(newBid);
111 
112     // Take care of accounting in client record
113     Client* client = users[active_user];
114     client->addBid(number);
115 
116     displayListing(connfd, port, advertisements.begin(), advertisements.end());
117   }
118 
119   else if (req == "CREATE") {
120 
121     string verify;
122     Client client;
123     iss >> client;
124     iss >> verify;
125 
126     /*
127      * Check for existing user
128      */
129     Client* search_results = users[client.getEmail()];
130 
131     if ( (client.verifyPasswd (verify)) && (search_results == NULL) ){
132 
133       active_user = client.getEmail();
134       Client* new_client = new Client(client);
135       
136       users.add (new_client);
137       create_verified = true;
138     }
139     else {
140       create_verified = false;
141     }
142     
143     displayListing(connfd, port, advertisements.begin(), advertisements.end());
144   }
145 
146   else if (req == "ADD") {
147 
148     int category;
149     iss.getline(request, 80);
150     category = atoi(request);
151 
152     Advertisement ad;
153     iss >> ad;
154     ad.setNumber(advertisement_counter);
155     advertisement_counter++;
156 
157     advertisements.add(new Advertisement(ad));
158     
159     Category* cat = categories[category];
160     cat->addItem(ad.getNumber());
161 
162     Client* client = users[ad.getEmail()];
163     client->addOffering(ad.getNumber());
164 
165     displayListing(connfd, port, advertisements.begin(), advertisements.end());
166   }
167 
168    else if (req == "CATEGORY_ADD") {
169 
170     Category cat;
171     iss >> cat;
172 
173     Category* p = categories[cat.getParent()];
174     Category* a=p;
175     
176             cat.setName(p->getName() + " / " + cat.getName());
177 
178     cat.setNumber(category_counter);
179     category_counter++;    
180 
181     Category* c = new Category(cat);
182     categories.add(c);
183     p->addSubCategory(c);
184         
185         
186     
187     
188     
189 
190     displayListing(connfd, port, advertisements.begin(), advertisements.end());
191   }
192 
193   else if (req == "TOP_ONLY") {
194         
195     int category;
196     iss.getline(request, 80);
197     category = atoi(request);
198 
199     Listing filteredByCategory;
200     Category* c = categories[category];
201     
202     c->findOfferings (advertisements.begin(), advertisements.end(), 
203                       filteredByCategory );
204     displayListing(connfd, port, filteredByCategory.begin(), filteredByCategory.end());
205     
206   }
207   else if (req == "RECURSIVE") {
208         
209     int category;
210     iss.getline(request, 80);
211     category = atoi(request);
212 
213 
214     Listing filteredByCategory;
215     Category* c = categories[category];
216      
217     c->findOfferingsRecursive (advertisements.begin(),
218                         advertisements.end(), filteredByCategory );
219     displayListing(connfd, port, filteredByCategory.begin(), filteredByCategory.end());
220     
221   }
222 
223 
224   else if (req == "SORT") {
225 
226     string field;
227     iss >> field;
228 
229     Listing sorted = advertisements.sort(field);
230     displayListing(connfd, port, sorted.begin(), sorted.end());
231   }
232   else if (req == "FIND") {
233 
234     string keyword;
235     iss >> keyword;
236 
237     Listing filtered = advertisements.filter(keyword);
238 
239     displayListing(connfd, port, filtered.begin(), filtered.end());
240   }
241  
242 
243   else if (req == "" || req == "LIST") {
244     displayListing(connfd, port, advertisements.begin(), advertisements.end());
245   }
246 
247   else {
248     // unknown command! Let's just list to play it safe...
249     displayListing(connfd, port, advertisements.begin(), advertisements.end());
250   }
251 
252 }