[Muduo Network library source Code Analysis] (net/buffer_cc_h) buffer (non-blocking IO prerequisites)

Source: Internet
Author: User
buffer (non-blocking IO prerequisites) implementation: Implementation of the Buffer class function: Buffer, temporarily storing data for non-blocking IO, achieving efficient IO Knowledge Points:String's function implementation resize ()
Resizes the string content to n characters.

If N is smaller than the "current length of" the string, the content is reduced to its A/n characters, the rest being Dr opped.

If N is greater than the ' current length ' of the string, the content is expanded by appending as many instances of the ' C cha Racter as needed to reach a size of n characters.

The second version, actually calls:resize (N,char ()), so when a string are resized to a greater size without passing a seco nd argument, the new character positions are filled with the default value of a char, which is the null character.

Swap ()
Swaps the contents of the string with those of string object str, such which is the call to this member function, the CO Ntents of this string are those which were into STR before the call, and the contents of STR are those which were in this St Ring.
Capacity ()
Returns the size of the allocated storage spaces in the string object.
copy function
Template<class Inputiterator, class outputiterator>
  outputiterator copy (Inputiterator-I, InputIterator Last, outputiterator result)
{while
  (first!=last) *result++ = *first++;
  return result;
}
MEMCHR function
Searches within the ' bytes ' of the ' block ' memory pointed by PTR for the ' the ' The ' of ' (Occurrence a s a unsigned char), and returns a pointer to it.
Application:
As a buffer for non-blocking io.
module splitting and encapsulation: The thread object module has been isolated and unified compiled using makefile, the module code address is as follows: Https://github.com/chudongfang/Learn_From_Muduo/tree/master/Buffer Code and Analysis: Buffer.h
Copyright, Shuo Chen.
All rights reserved. http://code.google.com/p/muduo////Use of the This source code is governed by a Bsd-style license//Then can be found I
n the License file.  Author:shuo Chen (chenshuo at chenshuo dot com)///This is a public header file, it must only include the public header
Files. #ifndef muduo_net_buffer_h #define Muduo_net_buffer_h #include <muduo/base/copyable.h> #include <muduo/base/
stringpiece.h> #include <muduo/base/Types.h> #include <muduo/net/Endian.h> #include <algorithm> #include <vector> #include <assert.h> #include <string.h>//#include <unistd.h>//ssize_t names Pace Muduo {namespace Net {///A buffer class modeled after Org.jboss.netty.buffer.ChannelBuffer//////@code///+---- ---------------+------------------+------------------+
/// |  Prependable bytes |  Readable bytes |
Writable bytes |                   /// |     |                  (CONTENT) |
| /// +-------------------+------------------+------------------+
/// |                  |                  |
| 0 <= readerindex <= writerindex <= size///@endcode class Buffer:public Muduo::copyab Le {public://Kcheapprepend and Kinitialsize, which defines the initial size of the prependable and writable initial size static const size_t
  = 8;
  static const size_t Kinitialsize = 1024; Initialize pointer position explicit Buffer (size_t initialsize = kinitialsize): Buffer_ (Kcheapprepend + initialsize), Readerind
    Ex_ (Kcheapprepend), Writerindex_ (kcheapprepend) {assert (readablebytes () = 0);
    ASSERT (writablebytes () = = InitialSize);
  ASSERT (prependablebytes () = = Kcheapprepend); }//implicit copy-ctor, Move-ctor, Dtor and assignment are fine//note:implicit Move-ctor are added in g++ 4.6//
    Swap Buffer void Swap (buffer& rhs) {buffer_.swap (rhs.buffer_);
    Std::swap (Readerindex_, rhs.readerindex_); Std::swap (Writerindex_, Rhs.writerinDEX_);
  //Returns the number of readable bytes size_t readablebytes () const {return writerindex_-readerindex_;}
  Returns the number of writable bytes size_t writablebytes () const {return buffer_.size ()-writerindex_;}

  Returns the number of reads size_t prependablebytes () const {return readerindex_;}

  Returns the read pointer const char* PEEK () const {return begin () + readerindex_;}
    Look for CRLF string const char* FINDCRLF () const {//Fixme:replace with Memmem () from scratch in written data
    Const char* CRLF = Std::search (Peek (), BeginWrite (), Kcrlf, kcrlf+2); return CRLF = = BeginWrite ()?
  Null:crlf;
    CRLF String Const char* FINDCRLF (const char* start) const {ASSERT (Peek () <= start) is found in the written data from start
    ASSERT (Start <= beginwrite ());
    Fixme:replace with Memmem ()?
    Const char* CRLF = Std::search (start, BeginWrite (), Kcrlf, kcrlf+2); return CRLF = = BeginWrite ()?
  Null:crlf; }//MEMCHR////searches within the "a" bytes of the block of memory//pointed by PTR for the "the" I Occurre nCE of Value (interpReted as a unsigned char),//and returns a pointer to it.
    In the written data, look for the first occurrence of ' \ n ' const char* findeol () const {CONST void* EOL = MEMCHR (Peek (), ' \ n ', readablebytes ());
  Return static_cast<const char*> (EOL);
    The ' \ n ' const char* findeol (const char* start) const {ASSERT (Peek () <= start) is first found in the written data from start
    ASSERT (Start <= beginwrite ());
    Const void* EOL = MEMCHR (start, ' \ n ', BeginWrite ()-start);
  Return static_cast<const char*> (EOL);
  }//Retrieve returns void, to prevent//String str (Retrieve (Readablebytes ()), readablebytes ());
    The evaluation of two functions are unspecified//read pointer after Len bit, if greater than readable, reinitialize buffer pointer position ' void retrieve (size_t len) {
    ASSERT (Len <= readablebytes ());
    if (Len < Readablebytes ()) {readerindex_ = Len;
    else {retrieveall ();
    }///move read pointer to end void Retrieveuntil (const char*) {ASSERT (Peek () <=); ASSERT (End <= BEGINWRITE ());
  Retrieve (End-peek ());
  ///Read pointer after a 64-bit void RetrieveInt64 () {Retrieve (sizeof (int64_t));
  ///Read pointer after a 32-bit void RetrieveInt32 () {Retrieve (sizeof (int32_t));
  ///Read pointer after a 16-bit void RetrieveInt16 () {Retrieve (sizeof (int16_t));
  ///Read pointer after a 8-bit void RetrieveInt8 () {Retrieve (sizeof (int8_t));
    }//Initialize pointer position void Retrieveall () {readerindex_ = Kcheapprepend;
  Writerindex_ = Kcheapprepend;
  //Read all content to string and return string retrieveallasstring () {returns retrieveasstring (Readablebytes ());
    //Read the string with Len length and returns string Retrieveasstring (size_t len) {assert (Len <= readablebytes ());
    String result (Peek (), Len);
    Retrieve (len);
  return result;
  } stringpiece tostringpiece () const {return stringpiece (Peek (), static_cast<int> (Readablebytes ()));
  } void Append (const stringpiece& str) {append (Str.data (), str.size ()); }//The functions copy////template<class Inputiterator, class outputiterator>//outputiterator copy (Inputiterator, Inputiterator last, Outputiterator
  Result)//{//while (first!=last) *result++ = *first++;
  return result; //First determine if there is enough space, then copy, and finally update pointer void append (const char*/*restrict*/data, size_t len) {ensurewritablebytes (
    Len);
    Std::copy (data, Data+len, BeginWrite ());
  Haswritten (len);
  } void Append (const void*/*restrict*/data, size_t len) {Append (static_cast<const char*> (data), Len); }//Confirm writable byte count is required for Len byte number, if Len is greater than its writable byte number, allocate memory void Ensurewritablebytes (size_t len) {if (Writablebytes () < le
    N) {makespace (len);
  ASSERT (Writablebytes () >= len);
  //returns write pointer char* BeginWrite () {return begin () + writerindex_;}

  Returns the Write pointer const char* BeginWrite () const {return begin () + writerindex_;}
    Move the write pointer back to Len void Haswritten (size_t len) {assert (Len <= writablebytes ());
  Writerindex_ = Len;///Move the write pointer forward by Len Void Unwrite (size_t len) {assert (Len <= readablebytes ());
  Writerindex_-= Len; //////Append int64_t using network endian//write a 64-bit void///(AppendInt64 x) {int64_t int64_t
    = Sockets::hosttonetwork64 (x);
  Append (&be64, sizeof be64); //////Append int32_t using network endian//write a 32-bit void///(AppendInt32 x) {int32_t int32_t
    = Sockets::hosttonetwork32 (x);
  Append (&be32, sizeof be32);
    //Write a 16-bit void appendInt16 (int16_t x) {int16_t Be16 = sockets::hosttonetwork16 (x);
  Append (&be16, sizeof be16);
  //Write a 16-bit void AppendInt8 (int8_t x) {append (&x, sizeof x); //////read int64_t from network endian//////require:buf->readablebytes () >= sizeof (int32_t)//Read a
    64-bit number int64_t ReadInt64 () {int64_t result = PeekInt64 ();
    RetrieveInt64 ();
  return result; }//////Read int32_t from network endian/////require:buf->readablebytes () >= sizeof (int32_t)/read a 32-bit number int32_t ReadInt32 () {int32_t result = Peek
    Int32 ();
    RetrieveInt32 ();
  return result;
    //Read a 16-digit number int16_t readInt16 () {int16_t result = peekInt16 ();
    RetrieveInt16 ();
  return result;
    //Read a 8-digit number int8_t readInt8 () {int8_t result = PeekInt8 ();
    RetrieveInt8 ();
  return result; //////Peek int64_t from network endian//////require:buf->readablebytes () >= sizeof (int64_t)/Read and return
    Back to a Int64 int64_t PeekInt64 () const {ASSERT (Readablebytes () >= sizeof (int64_t));
    int64_t be64 = 0;
    :: memcpy (&be64, Peek (), sizeof be64);
  Return Sockets::networktohost64 (BE64); //////Peek int32_t from network endian//////require:buf->readablebytes () >= sizeof (int32_t)/Read and return
    Back to a Int32 int32_t PeekInt32 () const {ASSERT (Readablebytes () >= sizeof (int32_t));
    int32_t be32 = 0; :: memcpy (&AMP;BE32, Peek (), SiZeof be32);
  Return Sockets::networktohost32 (BE32);
    //Read and return a Int16 int16_t peekInt16 () const {ASSERT (Readablebytes () >= sizeof (int16_t));
    int16_t be16 = 0;
    :: memcpy (&be16, Peek (), sizeof BE16);
  Return sockets::networktohost16 (BE16);
    //Read and return a Int8 int8_t peekInt8 () const {ASSERT (Readablebytes () >= sizeof (int8_t));
    int8_t x = *peek ();
  return x; //////prepend int64_t using network endian/////into Int64 void prepend (PrependInt64 x) {int64_t
    T be64 = sockets::hosttonetwork64 (x);
  Prepend (&be64, sizeof be64); //////prepend int32_t using network endian/////into Int32 void Prepend (PrependInt32 x) {int32_t
    _t be32 = sockets::hosttonetwork32 (x);
  Prepend (&be32, sizeof be32);
    ///Put int16 into prepend void prependInt16 (int16_t x) {int16_t Be16 = sockets::hosttonetwork16 (x);
  Prepend (&be16, sizeof be16); ///place int8 into prepend void PrependInt8 (int8_t x) {prepend (&x, sizeof x); ///Put Len's data into prepend void prepend (const void*/*restrict*/data, size_t len) {assert (Len <= Prependab
    Lebytes ());
    Readerindex_-= Len;
    Const char* d = static_cast<const char*> (data);
  Std::copy (d, D+len, Begin () +readerindex_);
  //requests the container to reduce it capacity to fit its size.
    void Shrink (size_t reserve) {//Fixme:use Vector::shrink_to_fit () in C + + one if possible.
    Buffer Other;
    Other.ensurewritablebytes (Readablebytes () +reserve);
    Other.append (Tostringpiece ());
  Swap (other);
  //Returns the number of characters that the current buffer allocated memory can hold size_t internalcapacity () const {return buffer_.capacity ();
  }///Read data directly into buffer. It may implement and READV (2)///@return result of Read (2), @c errno is saved ssize_t (int fd, READFD
 Savederrno);
  Private://Returns the pointer at the start of the buffer char* begin () {return &*buffer_.begin ();} Const CHAR* begin () const {return &AMp;*buffer_.begin (); ///When memory is not available, reassign memory void MakeSpace (size_t len) {if (writablebytes () + prependablebytes () < Len + Kcheapprepe
    nd) {//Fixme:move readable data//Allocate enough memory buffer_.resize (Writerindex_+len); else {//move readable data to the front, make space inside buffer assert (Kcheapprepend < reader
      INDEX_);
      First move the existing data to the front, freeing up the writable space size_t readable = readablebytes ();
      Std::copy () +readerindex_, Begin () +writerindex_, Begin () +kcheapprepend);
      Readerindex_ = Kcheapprepend;
      Writerindex_ = readerindex_ + readable;
    assert (Readable = = Readablebytes ());
  }} private:std::vector<char> Buffer_;
  size_t readerindex_;
  size_t writerindex_;
static const char kcrlf[];
};
 }} #endif//Muduo_net_buffer_h
buffer.cc
Copyright, Shuo Chen.
All rights reserved. http://code.google.com/p/muduo////Use of the This source code is governed by a Bsd-style license//Then can be found I

n the License file. Author:shuo Chen (chenshuo at chenshuo dot com)//#include <muduo/net/Buffer.h> #include <muduo/net/socket
sops.h> #include <errno.h> #include <sys/uio.h> using namespace Muduo;

using namespace muduo::net;

const char buffer::kcrlf[] = "\ r \ n";
Const size_t Buffer::kcheapprepend;


Const size_t Buffer::kinitialsize; Read content from FD//Returns the number of bytes read ssize_t buffer::readfd (int fd, int* savederrno) {//Saved an IOCTL ()/fionread call to tell how Mu
  Ch to read Char extrabuf[65536];
  struct Iovec vec[2];
  Const size_t writable = Writablebytes ();
  Vec[0].iov_base = Begin () +writerindex_;
  Vec[0].iov_len = writable;
  Vec[1].iov_base = Extrabuf;
  Vec[1].iov_len = sizeof Extrabuf;
  When there is enough spaces in this buffer, don ' t read into extrabuf. When Extrabuf is Used, we read 128k-1 bytes at most. const int IOVCNT = (Writable < sizeof extrabuf)?
  2:1;
  Const ssize_t n = sockets::readv (fd, VEC, iovcnt);
  if (n < 0) {*savederrno = errno;
  else if (implicit_cast<size_t> (n) <= writable) {writerindex_ + = n;
    //If buffer buffers are not mounted, add the contents of the Extrabuf to buffer else {writerindex_ = Buffer_.size ();
  Append (Extrabuf, n-writable);
  }//if (n = = writable + sizeof Extrabuf)//{//goto line_30;
} return N;

 }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.