00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <Basics.H>
00025 #include <SRPC.H>
00026 #include <FP.H>
00027
00028 #include "PKPrefix.H"
00029
00030 using std::ostream;
00031 using std::istream;
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 static const int NumGranularities = 2;
00046 static const int Granularities[NumGranularities] = { 16, 24 };
00047
00048 int PKPrefix::Granularity() throw ()
00049 {
00050 return Granularities[0];
00051 }
00052
00053 static const int WdBits = 8 * sizeof(Word);
00054
00055
00056
00057 void PKPrefix::T::Init(int gran) throw ()
00058 {
00059 assert(gran <= WdBits);
00060
00061 if (gran > 0) {
00062
00063 register Word mask = ~((Word) 0);
00064 mask <<= WdBits - gran;
00065 this->w &= mask;
00066 }
00067 }
00068
00069 Text PKPrefix::T::Pathname(int sigBits, int arcBits) const throw ()
00070 {
00071 assert(sigBits <= WdBits);
00072 Text res;
00073 Word mask1, mask2;
00074 const int fieldWidth = (arcBits + 3) / 4;
00075 char buff[65];
00076 int i = 0;
00077 while (i < sigBits) {
00078 int n = min(arcBits, sigBits - i);
00079 int loBit = i % WdBits;
00080 int hiBit = loBit + n;
00081
00082
00083 Word mask = this->w;
00084 assert(hiBit <= WdBits);
00085 mask <<= loBit;
00086 mask >>= loBit + (WdBits - hiBit);
00087 Text arc((i > 0) ? "/" : "");
00088 int bytesWritten = sprintf(buff, "%0*" FORMAT_LENGTH_INT_64 "x",
00089 fieldWidth, mask);
00090 assert(bytesWritten <= fieldWidth);
00091 arc += buff;
00092 res += arc;
00093 i += n;
00094 }
00095 return res;
00096 }
00097
00098 ostream& operator << (ostream &os, const PKPrefix::T &pfx) throw ()
00099 {
00100 char buff[17];
00101 sprintf(buff, "%016" FORMAT_LENGTH_INT_64 "x", pfx.w);
00102 os << buff;
00103 return os;
00104 }
00105
00106
00107
00108 void PKPrefix::List::Write(ostream &ofs) const throw (FS::Failure)
00109 {
00110 FS::Write(ofs, (char *)(&(this->len)), sizeof(this->len));
00111 for (int i = 0; i < len; i++) {
00112 pfx[i].Write(ofs);
00113 }
00114 }
00115
00116 void PKPrefix::List::Read(istream &ifs) throw (FS::EndOfFile, FS::Failure)
00117 {
00118 FS::Read(ifs, (char *)(&(this->len)), sizeof(this->len));
00119 if (len > 0) {
00120 pfx = NEW_PTRFREE_ARRAY(PKPrefix::T, len);
00121 for (int i = 0; i < len; i++) {
00122 pfx[i].Read(ifs);
00123 }
00124 } else {
00125 pfx = (PKPrefix::T *)NULL;
00126 }
00127 }
00128
00129 void PKPrefix::List::Send(SRPC &srpc) const throw (SRPC::failure)
00130 {
00131 srpc.send_seq_start(this->len);
00132 for (int i = 0; i < this->len; i++) {
00133 this->pfx[i].Send(srpc);
00134 }
00135 srpc.send_seq_end();
00136 }
00137
00138 void PKPrefix::List::Recv(SRPC &srpc) throw (SRPC::failure)
00139 {
00140 srpc.recv_seq_start(&(this->len), NULL);
00141 pfx = NEW_PTRFREE_ARRAY(PKPrefix::T, this->len);
00142 for (int i = 0; i < this->len; i++) {
00143 this->pfx[i].Recv(srpc);
00144 }
00145 srpc.recv_seq_end();
00146 }
00147
00148 inline void Indent(ostream &os, int indent) throw ()
00149 {
00150 for (int i = 0; i < indent; i++) os << " ";
00151 }
00152
00153 void PKPrefix::List::Print(ostream &os, int indent) const throw ()
00154 {
00155 if (this->len == 0) {
00156 os << " <<None>>\n";
00157 } else {
00158 os << '\n';
00159 for (int i = 0; i < this->len; i++) {
00160 Indent(os, indent);
00161 os << "pfx[" << i << "] = " << this->pfx[i] << "\n";
00162 }
00163 }
00164 }