The IO bank navigator gives uniform access to IO banks. It is
implemented with the generic bank navigator defined in
section
.
IO bank navigators are created dynamically. Now we can implement this method:
<Other public methods of off_IOBank. >+= (<-U) [<-D->]
// Returns a navigator for IOBanks.
off_Navigator *get_navigator(void);
<off_IOBank::get_navigator implementation. >= (U->)
// Returns a navigator for IOBanks.
off_Navigator *off_IOBank::get_navigator(void)
{
assert(valid());
return new off_BankNav<off_IOBank,off_IOPort>(*this);
}
<Off IO bank navigator dependencies. >= (U->) #include <hw/IOBank.h> // for IOBank. #include <hw/IOPort.h> // for IOPort. #include <hw/bnav.h> // for off_BankNav et al.
<Off IO bank dependencies. >+= (U->) [<-D->] #include <klib/nav.h> // for off_Navigator et al.
<Off IO bank implementation dependencies. >+= (U->) [<-D->] #include <hw/ionav.h>
\subsubsection{IO bank inspection}
The IO bank inspector's attribute array looks like this:
<Off IO bank inspector attribute array initializer. >= (U->)
{{ OFF_STR_ATTR , "name", &off_IOBank::nameof },
{ OFF_STR_ATTR, "class", &off_IOBank::kindof },
{ OFF_ID_ATTR, "dom", &off_IOBank::get_domain },
{ OFF_ID_ATTR, "id", &off_IOBank::get_id },
{ OFF_STR_ATTR, "url", &off_IOBank::get_url },
{ OFF_STR_ATTR, "provides", &off_IOBank::nameof },
{ OFF_STR_ATTR, NULL, NULL }, // no requeriments.
// IO bank specific attributes.
{ OFF_BOOL_ATTR, "doesiomap", &off_IOBank::is_iomapable },
{ OFF_BOOL_ATTR, "doesuserio", &off_IOBank::is_usrio},
// If this is not commented out it gets an internal gcc compiler error #40
// { OFF_NAT_ATTR, "nports", &off_IOBank::get_nports},
// { OFF_NAT_ATTR, "first", &off_IOBank::get_first},
// { OFF_NAT_ATTR, "last", &off_IOBank::get_last},
// { OFF_NAT_ATTR, "mat", &off_IOBank::get_mat},
// { OFF_NAT_ATTR, "iosize", &off_IOBank::get_iosize},
{ OFF_NULL_ATTR, NULL, NULL } } // End of attribute list.
<Off IO bank inspector attribute array length. >= (U->) const int OFF_IOINSP_NATTR=9; // not counting final NULL attr.
We have implemented neither get_url nor nameof yet.
<Other public methods of off_IOBank. >+= (<-U) [<-D->]
// Get the IO bank URL.
const char *get_url(void);
// Returns the IO bank name.
const char *nameof(void);
Given this attribute list, the IO bank inspector is defined as follows
<Off IO bank inspector. >= (U->)
// An IO bank inspector.
//
class off_IOBankInsp : public off_Inspector {
private:
static off_attr_t io_attrs[OFF_IOINSP_NATTR+1]; // for final NULL attr.
public:
off_IOBankInsp(off_IOBank *iobank) :
off_Inspector (iobank, io_attrs, OFF_IOINSP_NATTR)
{ assert(iobank && iobank->valid()); }
};
Definesoff_IOBankInsp(links are to index).
Where the attribute array is shared.
<Off IO bank inspector static members. >= (U->)
// inspector attributes for iobanks.
off_attr_t off_IOBankInsp::io_attrs[OFF_IOINSP_NATTR+1] =
<Off IO bank inspector attribute array initializer. >
;
Every time get_inspector is called, a new inspector is
created. The user should delete it whenever it is no longer
needed.
<Other public methods of off_IOBank. >+= (<-U) [<-D->]
// Returns an inspector for IOBanks.
off_Inspector *get_inspector(void);
<off_IOBank::get_inspector implementation. >= (U->)
// Returns an inspector for IOBanks.
off_Inspector *off_IOBank::get_inspector(void)
{
assert(valid());
return new off_IOBankInsp(this);
}
The URL for an IO bank is that of its node with io.html
appended. We use a new member, a character array initialized the very
first time it is needed.
<Other private members of off_IOBank. >+= (<-U) [<-D->]
static char *io_url; // URL for this IO bank.
<Off IO bank static members. >= (U->) char *off_IOBank::io_url=NULL; // URL for this IO bank.
<off_IOBank::get_url implementation. >= (U->)
// Get the IO bank URL.
const char *off_IOBank::get_url(void)
{
assert(valid());
if (!io_url){
io_url=new char[strlen(nd.get_url())+strlen(OFF_IOBANK_URL)+1]; //+1 for \0
if (io_url){
strcpy(io_url,nd.get_url());
strcat(io_url,OFF_IOBANK_URL);
}
}
return io_url;
}
Where he have to define the relative URL for IO banks.
<Off source code urls. >= [D->] const char OFF_IOBANK_URL[]="/io.html";
<Off IO bank dependencies. >+= (U->) [<-D->] #include <klib/url.h> // for OFF_IOBANK_URL
<Off IO bank implementation dependencies. >+= (U->) [<-D->] #include <string.h> // for strcat strdup et al #include <node/Node.h> // for nd
The name for an IO bank is that of its node complemented with a
little suffix. The implementation is almost the same of get_url,
however, the name is not shared among IO banks in the same node
(i.e. it is not static).
<off_IOBank::nameof implementation. >= (U->)
// Returns the IO bank name.
const char *off_IOBank::nameof(void)
{
assert(valid());
if (!io_name){
io_name = new char[strlen(nd.nameof())+strlen("/iobank")+9]; // for N...N\0
if (io_name){
char number[9];
strcpy(io_name,nd.nameof());
strcat(io_name,"/iobank");
sprintf(number,"%08x",(natural_t)get_id());
strcat(io_name,number);
}
}
return io_name;
}
<Other private members of off_IOBank. >+= (<-U) [<-D]
char *io_name; // name for this IO bank.
<Initialize other aggregate members of off_IOBank. >+= (<-U) [<-D]
io_name(NULL)
\subsubsection{IO port inspection} IO ports cannot be navigated. They can be inspected though. The attribute array of their inspectors is as follows.
<Off IO port inspector attribute array initializer. >= (U->)
{{ OFF_STR_ATTR , "name", &off_IOPort::nameof },
{ OFF_STR_ATTR, "class", &off_IOPort::kindof },
{ OFF_ID_ATTR, "dom", &off_IOPort::get_domain },
{ OFF_ID_ATTR, "id", &off_IOPort::get_id },
{ OFF_STR_ATTR, "url", &off_IOPort::get_url },
{ OFF_STR_ATTR, "provides", &off_IOPort::nameof },
{ OFF_STR_ATTR, NULL, NULL }, // no requeriments.
// Page frame specific attributes.
{ OFF_ID_ATTR, "container", &off_IOPort::get_iobank },
{ OFF_NULL_ATTR, NULL, NULL } } // End of attribute list.
<Off IO port inspector attribute array length. >= (U->) const int OFF_IOPINSP_NATTR=8; // not counting final NULL attr.
We need get_rurl and get_url_holder for ports to support
ResUnit::get_url.
<Other protected methods of off_IOPort. >= (<-U) [D->]
// Get the port URL.
virtual const char *get_rurl(void) const { return OFF_IOPORT_URL; }
// Returns the port name.
virtual char *&get_url_holder(void);
Where we must define the relative URL for ports.
<Off source code urls. >+= [<-D] const char OFF_IOPORT_URL[]="#IOPort";
DefinesOFF_IOPORT_URL(links are to index).
<Off IO port dependencies. >+= (U->) [<-D->] #include <klib/url.h> // for OFF_IOPORT_URL
<Off IO port implementation dependencies. >= (U->) [D->] #include <stdio.h> // for sprintf et al
URLs are the same for all ports.
<Other private members of off_IOPort. >= (<-U)
static char *io_url; // URL for this page frame.
<off_IOPort::get_url_holder implementation. >= (U->)
char *&off_IOPort::get_url_holder(void) { return io_url; }
<Off IO port static members. >= (U->) char *off_IOPort::io_url=NULL; // URL for IO ports.
Given the attribute list shown above, a IO port inspector is defined as follows.
<Off IO port inspector. >= (U->)
// A IO port inspector.
//
class off_IOPortInsp : public off_Inspector {
private:
static off_attr_t io_attrs[OFF_IOPINSP_NATTR+1]; // for final NULL attr.
public:
off_IOPortInsp(off_IOPort *iop) :
off_Inspector(iop, io_attrs, OFF_IOPINSP_NATTR)
{}
};
Definesoff_IOPortInsp(links are to index).
Where the attribute array is shared.
<Off IO port inspector static members. >= (U->)
// inspector attributes for IO ports.
off_attr_t off_IOPortInsp::io_attrs[OFF_IOPINSP_NATTR+1] =
<Off IO port inspector attribute array initializer. >
;
Every time get_inspector is called, a new inspector is
created. The user should delete it whenever it is no longer
needed.
<Other public methods of off_IOPort. >+= (<-U) [<-D]
// Returns an inspector for IOPorts.
off_Inspector *get_inspector(void);
<off_IOPort::get_inspector implementation. >= (U->)
// Returns an inspector for IOPorts.
off_Inspector *off_IOPort::get_inspector(void)
{
return new off_IOPortInsp(this);
}
<Off IO port implementation dependencies. >+= (U->) [<-D] #include <hw/ionav.h> // for off_IOPortInsp et al
\subsubsection{IO bank navigation and inspection \cpp{} source files}
The navigation and inspection code for IO banks is kept in
hw/ionav.h.
<ionav.h*>= <Read the literate code instead warning. > #ifndef __OFF_IOBANK_NAV_H #define __OFF_IOBANK_NAV_H 1 <Off IO bank navigator dependencies. > <Off IO bank inspector attribute array length. > <Off IO port inspector attribute array length. > #ifdef __KERNEL__ <Off IO bank inspector. > <Off IO port inspector. > #endif #endif // __OFF_IOBANK_NAV_H
<ionav.C*>= <Read the literate code instead warning. > #include <hw/ionav.h> // Exported interface. <Off IO bank inspector static members. > <Off IO port inspector static members. >