Boost logo

Boost-Commit :

From: lists.drrngrvy_at_[hidden]
Date: 2008-03-21 13:07:32


Author: drrngrvy
Date: 2008-03-21 13:07:31 EDT (Fri, 21 Mar 2008)
New Revision: 43756
URL: http://svn.boost.org/trac/boost/changeset/43756

Log:
* Added fcgi/amortization example
* Modified fcgi/echo example to make it a bit cleaner
Added:
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/Jamfile.v2 (contents, props changed)
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.css (contents, props changed)
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.js (contents, props changed)
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.tpl (contents, props changed)
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/main.cpp (contents, props changed)
Text files modified:
   sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/main.cpp | 40 +++++++++++++++++++++++++++++-----------
   1 files changed, 29 insertions(+), 11 deletions(-)

Added: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/Jamfile.v2 2008-03-21 13:07:31 EDT (Fri, 21 Mar 2008)
@@ -0,0 +1,52 @@
+# Copyright (c) 2007 Darren Garvey
+#
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy
+# at http://www.boost.org/LICENSE_1_0.txt)
+
+# A symbolic name for this project.
+project boost.cgi.examples.fcgi.amortization ;
+
+import os ;
+
+if [ os.name ] = NT
+{
+ lib ctemplate : : <file>c:/cc/src/ctemplate/ctemplate-0.9/Release/libctemplate.lib ;
+}
+else
+{
+ lib ctemplate ;
+}
+
+
+exe fcgi_amort
+ :
+ main.cpp
+ /boost/regex/
+ :
+ <library>ctemplate
+ :
+ #<linkflags>-lctemplate
+ ;
+
+# Our install rule (builds binaries and copies them to <location>)
+install install
+ :
+ fcgi_amort
+ amortization.tpl
+ :
+ :
+ <location>$(fcgi-bin)
+ ;
+
+install install-extra
+ :
+ amortization.css
+ amortization.js
+ :
+ :
+ <location>$(htdocs)
+ ;
+
+# Only install example if you use `bjam install' or equivalent
+explicit install ;

Added: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.css
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.css 2008-03-21 13:07:31 EDT (Fri, 21 Mar 2008)
@@ -0,0 +1,94 @@
+body, table, input, select, textarea, .text {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ color: #333333;
+}
+body {
+ background-color: #CCCCCC;
+}
+h1 {
+ font-family: Georgia, Times New Roman;
+ font-weight: bold;
+ font-size: 20px;
+ font-style: normal;
+ color: #4274B7;
+ border-bottom-color: #B1AFA2;
+}
+hr {
+ color: #B1AFA2;
+}
+.ssl {
+ border: 1px solid #B1AFA2;
+}
+a{
+ color: #315688;
+}
+.color1 {
+ background-color: #BFA280;
+}
+.color2 {
+ background-color: #BFA280;
+}
+.nav {
+ background-color: #89A8E0;
+}
+.top_nav {
+ background-color: #4274B7;
+}
+.right_nav {
+ background-color: #FFFFFF;
+}
+.main_cell {
+ background-color: #FFFFFF;
+}
+.td1 {
+ background-color: #F0EAE1;
+ padding: 0cm .1cm;
+ font-weight: normal;
+ color: #000000;
+}
+.td2 {
+ background-color: #FFFFFF;
+ padding: 0cm .1cm;
+ font-weight: normal;
+ color: #000000;
+}
+.row1 {
+ background-color: #F0EAE1;
+ padding: 0cm .1cm;
+ font-weight: normal;
+ color: #000000;
+ text-align: right
+}
+.row2 {
+ background-color: #FFFFFF;
+ padding: 0cm .1cm;
+ font-weight: normal;
+ color: #000000;
+ text-align: right
+}
+.tblbase {
+ background-color: #B1AFA2;
+}
+.tblhead {
+ font-weight: bold;
+ color: #FFFFFF;
+ background-color: #315688;
+}
+
+.header a {
+ background-color: #315688;
+ color: #FFFFFF;
+}
+.header a:hover {
+ background-color: #4274B7;
+ color: #FFFFFF;
+}
+.button a {
+ background-color: #BFA280;
+ color: #FFFFFF;
+}
+.button a:hover {
+ background-color: #666666;
+ color: #FFFFFF;
+}

Added: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.js
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.js 2008-03-21 13:07:31 EDT (Fri, 21 Mar 2008)
@@ -0,0 +1,234 @@
+function printable()
+{
+ document.temps.submit();
+
+}
+
+function clearForm(form) {
+ form.income.value = "";
+ form.auto.value = "";
+ form.rate.value="";
+ form.payment.value = "";
+ form.amount.value = "";
+}
+
+function housingRatio(income, insurance) {
+ housing = eval(income * .28)
+ return housing;
+}
+
+function debtRatio(income, auto) {
+ debt = eval(income * .36) - auto;
+ return debt;
+}
+
+function checkForm(toCheck) {
+ isNum = true;
+ for (j = 0; j < toCheck.length; j++) {
+ if (((((toCheck.substring(j,j+1) < "0") || (toCheck.substring(j,j+1) > "9")) && (toCheck.substring(j,j+1) != ","))
+ || (toCheck.substring(j,j+1) > "9")) && (toCheck.substring(j,j+1) != ".")){
+ isNum = false;
+ }
+ }
+ if ((isNum == false) || (toCheck.length == 0) || (toCheck == null)) {
+ alert("Please enter only numerical data in all fields.");
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+function computeForm(form) {
+ basicedit();
+
+ income = replaceChars(form.income.value);
+ income = replaceChar(income);
+ if (income <= "0"){
+ alert("You need to be employed to finance a house!")
+ form.payment.value = "0";
+ form.payment2.value = "0";
+ form.amount.value = "0";
+ form.amount2.value = "0";
+ return false;}
+ auto = replaceChars(form.auto.value);
+ auto = replaceChar(auto);
+ var a = form.rate.value;
+ var a = replacePct(a);
+
+ if (a > 20 )
+ {
+ alert ("Interest Rate must not be greater than " + 20 + " percent");
+ form.rate.value=addPct('20');
+ a = form.rate.value;
+ a = replacePct(a);
+ }
+ else
+ if (a < 1 )
+ {
+ alert ("Interest Rate must be greater than " + 1 + " percent");
+ form.rate.value=addPct('1');
+ a = form.rate.value;
+ a = replacePct(a);
+ }
+
+if (checkForm(income) && checkForm(auto) && checkForm(a)){
+ housingRatioResult = Math.round(housingRatio(income));
+ debtRatioResult = Math.round(debtRatio(income, auto));
+
+ if (debtRatioResult <= "0")
+ {
+ alert("Either your income is too low or your debt is too high!");
+ form.payment.value = "0";
+ form.payment2.value = "0";
+ form.amount.value = "0";
+ form.amount2.value = "0";
+ return false;
+ }
+
+ if (housingRatioResult>debtRatioResult) {
+ form.payment.value = formatCurrency(debtRatioResult);
+ form.payment2.value = formatCurrency(debtRatioResult);
+ }
+ else {
+ form.payment.value = formatCurrency(housingRatioResult);
+ form.payment2.value = formatCurrency(housingRatioResult);
+ }
+
+
+ var c = debtRatioResult;
+ var d = parseFloat(a / 1200);
+ var f = parseFloat(1 + d);
+ var f2 = parseFloat(1 + d);
+ var g = parseFloat(Math.pow(f, 360));
+ var g2 = parseFloat(Math.pow(f2, 180));
+ var h = parseFloat(1 / g);
+ var h2 = parseFloat(1 / g2);
+ var i = parseFloat(1 - h);
+ var i2 = parseFloat(1 - h2);
+ var j = parseFloat(i / d);
+ var j2 = parseFloat(i2 / d);
+ var k = parseFloat(c * j);
+ var k2 = parseFloat(c * j2);
+ form.amount.value = formatCurrency(Math.round(k));
+ form.amount2.value = formatCurrency(Math.round(k2));
+
+
+}
+return;
+}
+
+
+function replaceChar(entry) {
+ out = "$";
+ add = "";
+ temp = "" + entry;
+ while (temp.indexOf(out)>-1) {
+ pos= temp.indexOf(out);
+ temp = "" + (temp.substring(0, pos) + add +
+ temp.substring((pos + out.length), temp.length));
+ }
+ return temp;
+}
+
+function replacePct(entry) {
+ out = "%";
+ add = "";
+ temp = "" + entry;
+ while (temp.indexOf(out)>-1) {
+ pos= temp.indexOf(out);
+ temp = "" + (temp.substring(0, pos) + add +
+ temp.substring((pos + out.length), temp.length));
+ }
+ return temp;
+}
+
+function replaceChars(entry) {
+ out = ",";
+ add = "";
+ temp = "" + entry;
+ while (temp.indexOf(out)>-1) {
+ pos= temp.indexOf(out);
+ temp = "" + (temp.substring(0, pos) + add +
+ temp.substring((pos + out.length), temp.length));
+ }
+ return temp;
+}
+
+function formatCurrency(num) {
+ num=replaceChar(num);
+ num=replaceChars(num);
+ if ( checkForm(num));
+{
+ num = num.toString().replace(/$|,/g,'');
+ if(isNaN(num)) num = "0";
+ num = Math.floor(num).toString();
+ for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
+ num = num.substring(0,num.length-(4*i+3))+','+num.substring(num.length-(4*i+3));
+
+ return ('$' + num );
+}
+}
+
+function basicedit()
+{
+ if (!IsMoney(document.temps.income.value) || document.temps.income.value.length ==0)
+ document.temps.income.value='$3,500';
+
+ if (!IsMoney(document.temps.auto.value) || document.temps.auto.value.length ==0)
+ document.temps.auto.value='../../btn-red27px-R.gif';
+
+ if (!IsPct(document.temps.rate.value) || document.temps.rate.value.length ==0)
+ document.temps.rate.value='7.5%';
+}
+
+function IsMoney(val)
+ {
+ var number="0123456789$,.";
+
+ for (var i=0;i<val.length;i++)
+ {
+ if (number.indexOf(val.charAt(i)) == -1)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+function IsNumber(val)
+ {
+ var number="0123456789.";
+
+ for (var i=0;i<val.length;i++)
+ {
+ if (number.indexOf(val.charAt(i)) == -1)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+function IsPct(val)
+ {
+ var number="0123456789.%,";
+
+ for (var i=0;i<val.length;i++)
+ {
+ if (number.indexOf(val.charAt(i)) == -1)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+function addPct(pct) {
+ pct=replacePct(pct);
+ pct=parseFloat(pct);
+ if (checkForm(pct));
+ {
+ return (pct + '%');
+ }
+}
+

Added: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.tpl
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/amortization.tpl 2008-03-21 13:07:31 EDT (Fri, 21 Mar 2008)
@@ -0,0 +1,174 @@
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="/amortization.css">
+
+ <title>Fixed Mortgage Loan Calculator</title>
+ <script type="text/javascript" language="JavaScript1.2" src="/amortization.js"></script>
+</head>
+
+<body>
+
+{{!--Amortization form}}
+<form name="AmortBrowser" action="{{SCRIPT_NAME}}" method="post">
+ <input type="hidden" name="Amortize" value="1">
+ <table width="550" border="0" cellpadding="0" cellspacing="1" class="tblbase">
+ <tr>
+ <td colspan=4 class=tblhead align=center>FIXED MORTGAGE LOAN CALCULATOR</td>
+ </tr>
+ <tr>
+ <td colspan=2 class=tblhead align=center>Loan Information</td>
+ <td colspan=2 class=tblhead align=center>Prepayment Information (optional)</td>
+ </tr>
+ <tr>
+ <td width="250" class="td1">Mortgage Amount</td>
+ <td class="td2">
+ <input name="LoanAmt" type="text" onBlur="this.value=formatCurrency(this.value);" value="{{LoanAmt}}" size="10">
+ </td>
+ <td width="250" class="td1">Prepayment Frequency</td>
+ <td class="td2">
+ <select name="PrePmtFreq" {{PrePmtFreqInvalid}}>{{PrePmtFreq}}</select>
+ </td>
+ </tr>
+ <tr>
+ <td class="td1">Interest (APR)</td>
+ <td class="td2">
+ <input name="YearlyIntRate" type="text" value="{{YearlyIntRate}}" size="10">
+ </td>
+ <td class="td1">Prepayment Amount</td>
+ <td class="td2">
+ <input name="PrePmtAmt" type="text" value="{{PrePmtAmt}}" size="17" {{PrePmtFreqInvalid}}>
+ </td>
+ </tr>
+ <tr>
+ {{!-- Length of Loan selection list }}
+ <td class="td1">Length of Loan</td>
+ <td class="td2">
+ <select name="TermYrs">
+ {{#SELECT_TERM_YEARS}}
+ <option value="{{TermYrs}}">{{TermYrs}} Years</option>
+ {{/SELECT_TERM_YEARS}}
+ </select>
+ </td>
+ <td class="td1">Start with Payment</td>
+ <td class="td2">
+ <input name="PrePmtBegin" type="text" value="{{PrePmtBegin}}" size="17">
+ </td>
+ </tr>
+ <tr>
+ <td class="td1"></td>
+ <td class="td2">
+ <input type="submit" value="Calculate">
+ </td>
+ </tr>
+
+ {{#NotAmortize}}
+ <tr>
+ <td colspan="4" class="td2"><span class="small">
+ DISCLAIMER: The figures above are based upon conventional program guidelines.<br>
+ Calculations by this tool are believed to be accurate, yet are not guaranteed. Further review is<br>
+ necessary to obtain an exact qualification. If you have less than 20% equity in your home, a monthly<br>
+ mortgage insurance payment may be required.
+ </span></td>
+ </tr>
+ {{/NotAmortize}}
+
+ </table>
+</FORM>
+
+{{!--Prepayment summary table}}
+{{#PrePmtSummary}}
+ <table width="550" border="0" cellpadding="0" cellspacing="1" class="tblbase">
+ <tr>
+ <td colspan=4 class=tblhead align=center>PREPAYMENT vs REGULAR PAYMENT</td>
+ </tr>
+ <tr>
+ <td colspan=2 class=tblhead align=center>Prepayment Results</td>
+ <td colspan=2 class=tblhead align=center>Regular Payment Results</td>
+ </tr>
+ <tr>
+ <td class="td1">Number of months to pay loan</td>
+ <td class="td2" width="125">
+ <center><b>{{PrePmt_iPmtNo}}</b></center>
+ </td>
+ <td class="td1"></td>
+ <td class="td2" width="125">
+ <center><b>{{RegPmt_iPmtNo}}</b></center>
+ </td>
+ </tr>
+ <tr>
+ <td class="td1">Total Interest Paid</td>
+ <td class="td2" align="right">{{PrePmt_TotalIntPd}}</td>
+ <td class="td1"></td>
+ <td class="td2" align="right">{{RegPmt_TotalIntPd}}</td>
+ </tr>
+ <tr>
+ <td width="250" class="td1">Total Payments</td>
+ <td class="td2" align="right">{{PrePmt_TotalPmts}}</td>
+ <td width="250" class="td1"></td>
+ <td class="td2" align="right">{{RegPmt_TotalPmts}}</td>
+ </tr>
+ <tr>
+ <td colspan="4" class="td2"><span class="small">
+ <br>
+ By applying the prepayments in the schedule above, you would <u>realize these savings</u>:
+ <ul>
+ <li>
+ You pay the <b>{{RegPmt_term_to_words}}</b> loan in <b>{{PrePmt_term_to_words}}</b>
+ <br><br>
+ <li>The total loan payments will be <b>{{PrePmt_TotalPmts}}</b> instead of <b>{{RegPmt_TotalPmts}}</b>
+ </ul>
+ </span></td>
+ </tr>
+ </table>
+ <br>
+{{/PrePmtSummary}}
+
+{{#RegPmtSummary}}
+ {{!--Regular Payment summary table}}
+ <table width="550" border="0" cellpadding="0" cellspacing="1" class="tblbase">
+ <tr>
+ <td colspan=4 class=tblhead align=center>REGULAR PAYMENT SUMMARY</td>
+ </tr>
+ <tr>
+ <td class="td1">Monthly Payment</td>
+ <td class="td2" width="125" align="right"><b>${{MonthlyPmt}}</b></td>
+ </tr>
+ <tr>
+ <td class="td1">Total Interest Paid</td>
+ <td class="td2" width="125" align="right">${{RegPmt_TotalIntPd}}</td>
+ </tr>
+ <tr>
+ <td class="td1">Total Payments</td>
+ <td class="td2" width="125" align="right">${{RegPmt_TotalPmts}}</td>
+ </tr>
+ </table>
+ <br>
+{{/RegPmtSummary}}
+
+{{!--Amortization table}}
+
+{{#Amortize}}
+ <table border=0 cellpadding=0 cellspacing=1 width=550 class="tblbase">
+ <tr>
+ <td colspan=6 class=tblhead align=center>AMORTIZATION TABLE</td>
+ </tr>
+ <td class=tblhead align=center>Payment</td>
+ <td class=tblhead align=center>Mo. Payment</td>
+ <td class=tblhead align=center>Interest Pd.</td>
+ <td class=tblhead align=center>Principal Pd.</td>
+ <td class=tblhead align=center>New Balance</td>
+ {{#PaymentEntry}}
+ <tr class=row{{ROW_TYPE}}>
+ <td ALIGN=CENTER>{{ROW_NUM}}</td>
+ <td>${{Payment}}</td>
+ <td>${{InterestPaid}}</td>
+ <td>${{PrincipalPaid}}</td>
+ <td>${{Balance}}</td>
+ </tr>
+ {{/PaymentEntry}}
+ </table>
+{{/Amortize}}
+
+</body>
+</html>
+

Added: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/main.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/amortization/main.cpp 2008-03-21 13:07:31 EDT (Fri, 21 Mar 2008)
@@ -0,0 +1,249 @@
+// -- main.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+//
+// Amortization Calculator
+// -----------------------
+//
+// This file uses Google cTemplate to show the benefits of using an
+// HTML template engine. The code isn't commented, but should be
+// reasonably self-explanatory.
+//
+// It is a very basic amortization calculator.
+//
+#include <iostream>
+#include <iomanip>
+#include <boost/cgi/fcgi.hpp>
+#include <boost/algorithm/string/regex.hpp>
+#include <google/template.h>
+#include <boost/high_resolution_timer.hpp>
+
+using namespace boost::fcgi;
+
+/// Convert a string like '$250,000' into one like '250000'.
+std::string string_from_currency(std::string amt)
+{
+ // this is much too hardcore, but it works fine...
+ boost::algorithm::erase_all_regex(amt, boost::regex("[$, ]"));
+ return amt;
+}
+
+/// This function fills the dictionary and sub-dictionaries with relevant values.
+template<typename Request>
+void fill_amortization_dictionary(google::TemplateDictionary& dict, Request& req)
+{
+ std::string tmp( req.POST("LoanAmt") );
+ dict.SetValue("LoanAmt", tmp.empty() ? "$250,000" : tmp);
+
+ tmp = req.POST("YearlyIntRate");
+ dict.SetValue("YearlyIntRate", tmp.empty() ? "6.000" : tmp);
+
+ boost::array<std::string, 8> year_opts
+ = {{ "5", "7", "10", "20", "30", "40", "50" }};
+
+ BOOST_FOREACH(std::string& year, year_opts)
+ {
+ dict.SetValueAndShowSection("TermYrs", year, "SELECT_TERM_YEARS");
+ }
+
+ if (req.POST("Amortize").empty())
+ dict.ShowSection("NotAmortize");
+ else
+ {
+ double P = boost::lexical_cast<double>(string_from_currency(req.POST("LoanAmt")));
+ double i = boost::lexical_cast<double>(req.POST("YearlyIntRate")) / 1200;
+ double n = boost::lexical_cast<double>(req.POST("TermYrs")) * 12;
+ double monthly_payments = (P*i) / (1 - std::pow((1+i), -n));
+
+ google::TemplateDictionary* sub_dict = dict.AddSectionDictionary("RegPmtSummary");
+ sub_dict->ShowSection("RegPmtSummary");
+ sub_dict->SetFormattedValue("MonthlyPmt", "%.2f", monthly_payments);
+
+ dict.ShowSection("Amortize");
+ dict.SetValue("SCRIPT_NAME", req.script_name());
+
+ double balance = P;
+ int row_num = 0;
+ double interest;
+ double principal_paid;
+ double total_interest = 0;
+ do{
+ google::TemplateDictionary* sub_dict2 = dict.AddSectionDictionary("PaymentEntry");
+ sub_dict2->ShowSection("PaymentEntry");
+ sub_dict2->SetFormattedValue("Payment", "%.2f", monthly_payments);
+ sub_dict2->SetIntValue("ROW_NUM", ++row_num);
+ sub_dict2->SetIntValue("ROW_TYPE", (row_num % 2) + 1);
+ interest = balance * i;
+ total_interest += interest;
+ sub_dict2->SetFormattedValue("InterestPaid", "%.2f", interest);
+ principal_paid = monthly_payments - interest;
+ sub_dict2->SetFormattedValue("PrincipalPaid", "%.2f", principal_paid);
+ balance -= principal_paid; // Note: balance can increase.
+ sub_dict2->SetFormattedValue("Balance", "%.2f", balance);
+
+ }while(balance > 0);
+
+ sub_dict->SetFormattedValue("RegPmt_TotalIntPd", "%.2f", total_interest);
+ sub_dict->SetFormattedValue("RegPmt_TotalPmts", "%.2f", total_interest + P);
+ }
+}
+
+template<typename Request>
+int write_amortization_template(Request& req, response& resp)
+{
+ google::TemplateDictionary dict("amortization");
+
+ fill_amortization_dictionary(dict, req);
+
+ google::Template* tmpl
+ = google::Template::GetTemplate("amortization.tpl", google::STRIP_WHITESPACE);
+
+ boost::high_resolution_timer t;
+
+ std::string h("Content-type: text/html\r\n\r\n");
+ write(req.client(), buffer(h));
+
+ std::string arg(req.GET("arg"));
+
+ if (arg == "1")
+ {
+ std::string output;
+ tmpl->Expand(&output, &dict);
+ resp<< output;
+ }else
+ if (arg == "2")
+ {
+ std::string output;
+ tmpl->Expand(&output, &dict);
+ write(req.client(), buffer(output));
+ }else
+ if (arg == "3")
+ {
+ std::string s;
+ std::vector<boost::asio::const_buffer> out;
+
+ tmpl->Expand(&s, &out, &dict);
+ write(req.client(), out);
+ }else
+ {
+ resp<< "Error!";
+ return 1;
+ }
+ //output.clear();
+ //<< "<b>" << t.elapsed() << "</b><p />"
+ //<< output << "<p /><p />"
+ //<< "<b>" << t.elapsed() << "</b><p />";
+ //}
+
+ //std::cout<<
+ // "<pre>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nSTARTING OTHER THINGY\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n</pre>"
+ // ;
+/*
+ std::string s;
+ std::vector<boost::asio::const_buffer> out;
+for(int i=0; i < 50000; ++i) {
+ // boost::high_resolution_timer t;
+
+ tmpl->Expand(&s, &out, &dict);
+ out.clear();
+ s.clear();
+ //std::cout<< "<b>" << t.elapsed() << "</b><p />";
+
+ //<< "<p /><p />"
+ //<< "<b>" << t.elapsed() << "</b><p />";
+ }
+
+
+ std::cerr<< "a took " << std::setiosflags(std::ios::fixed) << std::setprecision(5) << a/100000 << " secs<p />"
+ << "b took " << b/100000 << " secs<p />";
+
+
+ std::cerr
+ << "Content-type: text/html\r\n\r\n"
+ << output << "<p /><p />";
+
+ resp<< content_type("text/html");
+ resp.flush(req.client());
+ write(req.client(), buffer(output));
+ */
+ return 0;
+}
+
+int handle_request(acceptor& a)
+{
+ boost::system::error_code ec;
+
+ //std::ofstream of("/var/www/log/fcgi_reaccept.txt");
+ using std::endl;
+ //std::cerr<< "Eh?" << endl;
+ //of<< "Opening request" << endl;
+
+ request req(a.protocol_service());
+
+ int ret = 0;
+ int num = 0;
+ while(!ec && ret == 0)
+ {
+ response resp;
+ ++num;
+ //std::cerr<< endl << endl << "request num := " << num << endl << endl;
+ //of<< "Accepting now" << endl;
+ a.accept(req);
+ //of<< "Loading" << endl;
+ req.load(true);
+
+ resp<< content_type("text/html")
+ << "map size := " << req.POST().size() << "<p>";
+
+ //of<< "Writing template" << endl;
+ ret = write_amortization_template(req, resp);
+
+ //of<< "Sending" << endl;
+ resp.send(req.client(), ec);
+ //of<< "Closing" << endl;
+ ret = ret ? ret : req.close(resp.status(), 0, ec);
+ //of<< "ok. ec := " << ec.message() << endl;
+ //return 1;
+ }
+ return ret;
+}
+
+void accept_requests(acceptor& a)
+{
+ for(;;)
+ {
+ if (handle_request(a))
+ break;
+ }
+}
+
+int main()
+{
+ try{
+ //std::cout
+ // << "Content-type: text/html\r\n\r\n";
+ using std::endl;
+ service s;
+ std::cerr<< "Eh1?" << endl;
+ acceptor a(s, true);
+ //a.assign(boost::asio::ip::tcp::v4(), 0);
+ std::cerr<< "Eh2?" << endl;
+
+ accept_requests(a);
+
+ return 0;
+
+ }catch(boost::system::error_code& err){
+ std::cerr<< "CGI error(" << err.value() << "): " << err.message() << std::endl;
+ }catch(boost::system::system_error& err){
+ std::cerr<< "System error(" << err.code() << "): " << err.what() << std::endl;
+ }catch(...){
+ std::cerr<< "ERROR!! BOOM!" << std::endl;
+ }
+}
+

Modified: sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/main.cpp
==============================================================================
--- sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/main.cpp (original)
+++ sandbox/SOC/2007/cgi/branches/acceptor_work/libs/cgi/example/fcgi/echo/main.cpp 2008-03-21 13:07:31 EDT (Fri, 21 Mar 2008)
@@ -1,9 +1,25 @@
+// -- main.hpp --
+//
+// Copyright (c) Darren Garvey 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+////////////////////////////////////////////////////////////////
+//
+//[fcgi_echo
+//
+// This example simply echoes all variables back to the user. ie.
+// the environment and the parsed GET, POST and cookie variables.
+// Note that GET and cookie variables come from the environment
+// variables QUERY_STRING and HTTP_COOKIE respectively.
+//
+
 #include <fstream>
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/program_options/environment_iterator.hpp>
 
 #include <boost/cgi/fcgi.hpp>
-#include <boost/cgi/return.hpp>
 
 using namespace std;
 using namespace boost::fcgi;
@@ -25,6 +41,7 @@
   }
 }
 
+/// This function accepts and handles a single request.
 template<typename Service, typename Acceptor, typename LogStream>
 int handle_request(Service& s, Acceptor& a, LogStream& of)
 {
@@ -58,6 +75,10 @@
   format_map(req.GET(), resp, "GET Variables");
   format_map(req.cookie(), resp, "Cookie Variables");
 
+ // Response headers can be added at any time before send/flushing it:
+ resp<< "<content-length == " << content_length(resp.content_length())
+ << content_length(resp.content_length());
+
   // This funky macro finishes up:
   return_(resp, req, 0);
   // It is equivalent to the below, where the third argument is represented by
@@ -77,29 +98,25 @@
   ofstream of(LOG_FILE);
   if (!of)
   {
- std::cerr<< "Couldn't open file: \"" LOG_FILE "\"." << endl;
+ std::cerr<< "[fcgi] Couldn't open file: \"" LOG_FILE "\"." << endl;
     return 1;
   }
 
   of<< boost::posix_time::second_clock::local_time() << endl;
- of<< "Going to start acceptor" << endl;
+ of<< "Going to start acceptor." << endl;
 
   // Make a `service` (more about this in other examples).
   service s;
   // Make an `acceptor` for accepting requests through.
   acceptor a(s);
 
- // This next line may become void in the future.
- a.assign(boost::asio::ip::tcp::v4(), 0);
- of<< "[a] Assigned." << endl;
-
   // After the initial setup, we can enter a loop to handle one request at a
   // time until there's an error of some sort.
   int ret(0);
   for (;;)
   {
     ret = handle_request(s, a, of);
- of<< "handle_requests() returned: " << ret << endl;
+ of<< "handle_request() returned: " << ret << endl;
     if (ret)
       break;
   }
@@ -107,13 +124,14 @@
   return ret;
 
 }catch(boost::system::system_error& se){
- cerr<< "[hw] System error: " << se.what() << endl;
+ cerr<< "[fcgi] System error: " << se.what() << endl;
   return 1313;
 }catch(exception& e){
- cerr<< "[hw] Exception: " << e.what() << endl;
+ cerr<< "[fcgi] Exception: " << e.what() << endl;
   return 666;
 }catch(...){
- cerr<< "[hw] Uncaught exception!" << endl;
+ cerr<< "[fcgi] Uncaught exception!" << endl;
   return 667;
 }
 }
+//]


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk