The frame transfer class is to transmit data according to the fixed size of a frame, all writes are done in memory until the flush operation is invoked, and then the transport node sends out the binary block of the length of the data written to the payload after the flush operation. Allows to read at a fixed length at the other end of the receive.
Frame transfer classes are also inherited from the cache base class Tbufferbase, the implementation of the interface is basically the same, but the way to achieve a different, the following to see the specific implementation of the process and principles.
The default cache length used for this class is default_buffer_size (static const INT = 512;), one of the two basic constructors takes the default cache length, and the other can specify a desired cache length. The following is the key to the analysis of slow reading, reading frames and other operations to achieve the process:
(1) The slow reading implementation is as follows:
uint32_t
Tframedtransport::readslow (uint8_t* buf, uint32_t len) {
uint32_t want = len;//The length you want to read
uint32_t have = rbound_-rbase_;//The length of the data already in the memory cache
assert (have < want);//If the length of the data later meets the length of the need to read it does not need to be read slowly
//If we have some data in the cache, Copy it out and return it.
//We did not attempt to read more data but had to return it because we could not guarantee that
there would actually be more data at the bottom//transport layer, so you should try blocking the read it.
if (have > 0) {
memcpy (buf, Rbase_, have);//copy out of existing data in cache
Setreadbuffer (rbuf_.get (), 0);//reset Cache base Address
return have;//
}
Read another frame.
if (!readframe ()) {
//EOF. No frame available.
return 0;
}
Process the data we already have
uint32_t give = Std::min (Want, static_cast<uint32_t> (Rbound_-Rbase_));//existing data want to read the length of the
memcpy (buf, Rbase_, give)//copy
Rbase_ + = give;//Adjust cache base Address
want-= give;//calculate how much more data you want to return
(Len- Want);//return actual read length
}
When there is no data in the cache, the function readframe that reads the frame is invoked, which is implemented as follows:
BOOL Tframedtransport::readframe () {///first read the length of the next frame of data int32_t sz;//the variable that holds the length uint32_t size_bytes_read = 0;//Read length data The number of bytes while (Size_bytes_read < sizeof (SZ)) {//representing the length of the data is less than the number of bytes holding the length data uint8_t* SZP = reinterpret_cast<uint8_t*& gt; (&SZ) + size_bytes_read;//length variable conversion to pointer uint32_t bytes_read = transport_->read (SZP, sizeof (SZ)-size_bytes_re AD)//Read if (bytes_read = 0) {//if returned to 0 indicates no data, if (Size_bytes_read = = 0) {//No data read, return false retur
n false;
} else {//part of the frame head, throws an exception. Throw Ttransportexception (Ttransportexception::end_of_file, "No more data to read afte
R "" "Partial frame header.");}
Size_bytes_read + = bytes_read;//to read length} SZ = Ntohl (SZ);//Long Integer network byte order to host byte order if (SZ < 0) {//Frame length cannot be negative, throw exception
Throw ttransportexception ("Frame size has negative value");
//Read a valid data payload and reset the cache token. if (SZ > StatIc_cast<int32_t> (Rbufsize_)) {Rbuf_.reset (new Uint8_t[sz]);//Receive base Address Rbufsize_ = sz;//Cache Size} Tran
Sport_->readall (Rbuf_.get (), SZ);//Call ReadAll read the SZ length data setreadbuffer (Rbuf_.get (), SZ);/set Read cache base site return true; }