The Bank.cpp File
// Bank.cpp: The source file for the main classes of the Bank side of
// the application. It contains all of the method and global data
// definitions these classes need.
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include ''bank.hpp''
Account::Account(char* acc_name, char* p, double amount)
{
strcpy(account_name, acc_name);
strcpy(pin, p);
balance = amount;
}
// Currently used solely by the Balance::get_balance method for
// retrieving the account balance for the users of the ATM that
// request it.
double
Account::get_balance()
{
return(balance);
}
// This method verifies that the account name and PIN number of a
// transaction match the account. This method would be more
// sophisticated in the real world. There is no doubt that, at a
// minimum, an encryption algorithm would be employed on the PIN
// number. The friendly Bank of Heuristics can easily leave it out
// for demonstration purposes.
int
Account::verify_account(char* acc_name, char* p)
{
return(!strncmp(account_name, acc_name, 7) &&
!strncmp(pin, p, 4));
}
int
Account::check_balance(double amount)
{
return(amount <= balance);
}
//Note: Withdraw objects modify with negative amounts, while
// Deposit objects use positive amounts. Tranfers use one of each.
void
Account::modify_balance(double amount)
{
balance += amount;
}
// This method is used by the find_account method of the AccountList
//class.
int
Account::equal(char* acc_name)
{
return(!strncmp(account_name, acc_name, 7));
}
void
Account::print(FILE* fd)
{
fprintf(fd, ''%s %s %4.21f\n'', account_name, pin, balance);
}
AccountList::AccountList(unsigned sz)
{
accountList = new Account*[size = sz];
accountnum = 0;
}
// The AccountFile is assumed to consist of an arbitrary
// number of lines, each of which is a seven-numeric-character
// string, a space, a four-digit PIN number, a space, and
// an initial balance.
AccountList::AccountList(unsigned sz, const char* AccountFile)
{
FILE* fd;
char buffer[large_string];
char* account_num,*pin,*amount;
accountList = new Account*[size = sz];
accountnum =0;
if ((fd = fopen(AccountFile, ''r'')) == NULL) {
cerr << ''AccountList Error: Cannot read \'' ''<<
AccountFile;
cerr << ''\'' to initialize accounts.\n'';
}
while(fgets(buffer, large_string, fd) != NULL) {
account_num = &buffer[0];
pin = &buffer[8];
amount = &buffer[13];
buffer[12] = buffer[7] = '\0';
if (add_account(new Account(account_num, pin,
atof(amount)))) {
cerr << ''AccountList Error: Ran out of
space for the AccountList.\n'';
break;
}
}
fclose(fd);
}
AccountList::~AccountList()
{
int i;
for (i=0; i < accountnum; i++) {
delete accountList[i];
}
delete accountList;
}
Account*
AccountList::find_account(char* acc_name)
{
int i;
for (i=0; i < accountnum; i++) {
if (accountList[i]->equal(acc_name)) {
return(accountList[i]);
}
}
return(NULL);
}
int
AccountList::add_account(Account* a)
{
if (accountnum < size) {
accountList[accountnum++] = a;
return(0);
}
else {
return(1);
}
}
void
AccountList::print(FILE* fd)
{
int i;
for (i=0; i < accountnum; i++) {
accountList[i]->print(fd);
}
}
ATMProxy::ATMProxy(Bank* b, Network* n)
{
bank = b;
network = n;
}
// This method drives the entire Bank side of the application. The
// ATMProxy waits for a transaction to be taken off the network.
// When such an object comes through the network, the method gives
// it to the Bank to process and then ships the return status back to
// the caller. If a NULL transaction is received, it is determined
// to be a Quit, and the Bank application terminates.
void
ATMProxy::activate()
{
Transaction* t;
int status;
while (1) {
if ((t = network->receive()) == NULL) {
break;
}
status = bank->process(t);
network->send(status, t);
}
}
Bank::Bank(unsigned sz, const char* accounts_file)
{
accountList = new AccountList(sz, accounts_file);
transList = new TransactionList(max_transaction_bank);
};
Bank::~Bank()
{
cout << ''Bank is being destroyed!!!\n'';
accountList->print(stdout);
transList->print(stdout);
delete accountList;
delete transList;
}
int
Bank::add_account(char* account_num, char* pin, double balance)
{
return(accountList->add_account(new Account(account_num,
pin, balance)));
}
// When a bank processes a transaction, it first adds the
// transaction to its daily list of transactions. It then asks the
// transaction (polymorphically) to process itself. The bank
// hands its whole AccountList to the transaction since the bank
// does not know which, or how many, accounts the transaction
// requires. In this simulation, all of the accounts live in memory.
// In a real-world implementation, the accounts would live in a
// database. This change would impact only the implementation
// of the AccountList class and is irrelevant to any other code in
// our system. This is very beneficial since it implies that, at design
// time, we can pretend all objects live in memory. If in reality
// they live on disk in some database, then one of our classes, a
// wrapper, will isolate that fact from the rest of our application.
int
Bank::process(Transaction* t)
{
transList->add_trans(t);
return(t->process(accountList));
}
|