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 <FS.H>
00026 #include <SRPC.H>
00027 #include <VestaLog.H>
00028 #include <Recovery.H>
00029 #include <FP.H>
00030 #include "ImmutableVal.H"
00031 #include "Derived.H"
00032 #include "VestaVal.H"
00033
00034 using std::ostream;
00035 using std::istream;
00036 using std::ios;
00037 using std::endl;
00038
00039 inline void Indent(ostream &os, int indent) throw ()
00040 {
00041 for (int i = 0; i < indent; i++) os << " ";
00042 }
00043
00044 VestaVal::T::T(char *bytebuff, int len) throw ()
00045 : len(len)
00046 {
00047 if (len < 0) this->len = strlen(bytebuff);
00048 this->bytes = NEW_PTRFREE_ARRAY(char, this->len);
00049 memcpy(this->bytes, bytebuff, this->len);
00050 this->fp = FP::Tag(this->bytes, this->len);
00051 }
00052
00053 void VestaVal::T::Log(VestaLog &log) const
00054 throw (VestaLog::Error)
00055 {
00056 this->fp.Log(log);
00057 this->dis.Log(log);
00058 this->prefixTbl.Log(log);
00059 log.write((char *)(&(this->len)), sizeof(this->len));
00060 if (this->len > 0) {
00061 log.write(this->bytes, this->len);
00062 }
00063 }
00064
00065 void VestaVal::T::Recover(RecoveryReader &rd)
00066 throw (VestaLog::Error, VestaLog::Eof)
00067 {
00068 this->fp.Recover(rd);
00069 this->dis.Recover(rd);
00070 this->prefixTbl.Recover(rd);
00071 rd.readAll((char *)(&(this->len)), sizeof(this->len));
00072 if (this->len > 0) {
00073 this->bytes = NEW_PTRFREE_ARRAY(char, this->len);
00074 rd.readAll(this->bytes, this->len);
00075 } else {
00076 this->bytes = (char *)NULL;
00077 }
00078 }
00079
00080 void VestaVal::T::Write(ostream &ofs) const
00081 throw (FS::Failure)
00082 {
00083 this->fp.Write(ofs);
00084 this->dis.Write(ofs);
00085 this->prefixTbl.Write(ofs);
00086 FS::Write(ofs, (char *)(&(this->len)), sizeof(this->len));
00087 if (this->len > 0) {
00088 FS::Write(ofs, this->bytes, this->len);
00089 }
00090 }
00091
00092 void VestaVal::T::Read(istream &ifs)
00093 throw (FS::EndOfFile, FS::Failure)
00094 {
00095 this->fp.Read(ifs);
00096 this->dis.Read(ifs);
00097 this->prefixTbl.Read(ifs);
00098 FS::Read(ifs, (char *)(&(this->len)), sizeof(this->len));
00099 if (this->len > 0) {
00100 this->bytes = NEW_PTRFREE_ARRAY(char, this->len);
00101 FS::Read(ifs, this->bytes, this->len);
00102 } else {
00103 this->bytes = (char *)NULL;
00104 }
00105 }
00106
00107 ImmutableVal* VestaVal::T::ReadImmutable(istream &ifs)
00108 throw (FS::EndOfFile, FS::Failure)
00109 {
00110 int start = FS::Posn(ifs);
00111 int dataLen = 0;
00112
00113
00114 FS::Seek(ifs, FP::ByteCnt, ios::cur);
00115 dataLen += FP::ByteCnt;
00116
00117
00118 dataLen += Derived::Indices::Skip(ifs);
00119
00120
00121 dataLen += PrefixTbl::Skip(ifs);
00122
00123
00124 int pickleLen;
00125 FS::Read(ifs, (char *)(&pickleLen), sizeof(pickleLen));
00126 dataLen += sizeof(pickleLen);
00127 FS::Seek(ifs, pickleLen, ios::cur);
00128 dataLen += pickleLen;
00129 return NEW_CONSTR(ImmutableVal, (start, dataLen));
00130 }
00131
00132 void VestaVal::T::Send(SRPC &srpc) const throw (SRPC::failure)
00133 {
00134 this->fp.Send(srpc);
00135 this->dis.Send(srpc);
00136 this->prefixTbl.Send(srpc);
00137 srpc.send_bytes(this->bytes, this->len);
00138 }
00139
00140 void VestaVal::T::Recv(SRPC &srpc) throw (SRPC::failure)
00141 {
00142 this->fp.Recv(srpc);
00143 this->dis.Recv(srpc);
00144 this->prefixTbl.Recv(srpc);
00145 this->bytes = srpc.recv_bytes( this->len);
00146 }
00147
00148 void VestaVal::T::Print(ostream &os, int indent) const throw ()
00149 {
00150 Indent(os, indent); os << "fp = " << this->fp << "\n";
00151 Indent(os, indent); os << "DIs = "; this->dis.Print(os, indent+2);
00152 Indent(os, indent); os << "tbl =";
00153 if (this->prefixTbl.NumArcs() > 0) {
00154 os << endl; this->prefixTbl.Print(os, indent+2);
00155 } else {
00156 os << " <empty>" << endl;
00157 }
00158 Indent(os, indent); os << "bytes = ";
00159 int printLen = min(this->len, (int)(((76 - (indent + 25)) * 4.0) / 9.0));
00160 for (int i = 0; i < printLen; i++) {
00161 char buff[3];
00162 int printLen = sprintf(buff, "%02x", (unsigned char)(this->bytes[i]));
00163 assert(printLen == 2);
00164 os << buff;
00165 if ((i+1) % 4 == 0) os << " ";
00166 }
00167 if (printLen < this->len) os << "...";
00168 os << " (" << this->len << " total)\n";
00169 }