// copy from source // return the number of bytes actually copied bytes_t Stream :: copy ( const Stream & src ) const { FUNC_ENTRY (); // a null ref should act like nothing was there // the behavior of /dev/null is a different concept if ( null_ref () ) return bytes_t ( 0 ); // access stream StreamItf * itf = get_itf ( CAP_PROP_READ | CAP_WRITE ); // allocate buffer bytes_t mtu = itf -> get_mtu (); Mem buffer = rsrc -> mmgr . alloc ( mtu, false ); // read from source bytes_t num_read = src . read ( mtu, buffer, 0 ); if ( num_read == ( U64 ) 0 ) return num_read; // write everything read return write_all ( num_read, buffer, 0 ); }
bytes_t Stream :: write_all ( const Mem & src, index_t start ) const { FUNC_ENTRY (); if ( start < 0 ) THROW ( xc_param_err, "bad start index: %ld", start ); bytes_t size = src . size (); if ( ( U64 ) start >= size ) return bytes_t ( 0 ); bytes_t all_bytes = size - ( U64 ) start; if ( null_ref () ) THROW ( xc_null_self_err, "wrote 0 of %lu bytes", ( U64 ) all_bytes ); StreamItf * itf = get_itf ( CAP_WRITE ); bytes_t mtu = itf -> get_mtu (); bytes_t to_write = ( mtu < all_bytes ) ? mtu : all_bytes; bytes_t total = itf -> write ( to_write, src, start ); while ( total < all_bytes ) { to_write = all_bytes - total; if ( mtu < to_write ) to_write = mtu; bytes_t num_writ = itf -> write ( to_write, src, start + ( U64 ) total ); if ( num_writ == ( U64 ) 0 ) THROW ( xc_transfer_incomplete_err, "wrote %lu of %lu bytes", ( U64 ) total, ( U64 ) all_bytes ); total += num_writ; } return total; }
bytes_t Stream :: read ( const bytes_t & num_bytes, Mem & dst, index_t start ) const { FUNC_ENTRY (); if ( start < 0 ) THROW ( xc_param_err, "bad start index: %ld", start ); bytes_t size = dst . size (); if ( ( U64 ) start >= size ) return bytes_t ( 0 ); bytes_t to_read = size - ( U64 ) start; if ( to_read > num_bytes ) to_read = num_bytes; if ( null_ref () ) return bytes_t ( 0 ); StreamItf * itf = get_itf ( CAP_PROP_READ | CAP_READ ); bytes_t mtu = itf -> get_mtu (); if ( mtu < to_read ) to_read = mtu; return itf -> read ( to_read, dst, start ); }
bytes_t Stream :: copy_all ( const bytes_t & num_bytes, const Stream & src ) const { FUNC_ENTRY (); // a null ref should act like nothing was there // the behavior of /dev/null is a different concept if ( null_ref () ) return bytes_t ( 0 ); // access stream StreamItf * itf = get_itf ( CAP_PROP_READ | CAP_WRITE ); // allocate buffer bytes_t mtu = itf -> get_mtu (); if ( num_bytes < mtu ) mtu = num_bytes; Mem buffer = rsrc -> mmgr . alloc ( mtu, false ); // read from source bytes_t num_read = src . read ( mtu, buffer, 0 ); if ( num_read == ( U64 ) 0 ) return num_read; // write everything read bytes_t total = write_all ( num_read, buffer, 0 ); assert ( total == num_read ); // enter loop to copy until end of stream while ( 1 ) { // TBD - must read with non-blocking timeout num_read = src . read ( mtu, buffer, 0 ); if ( num_read == ( U64 ) 0 ) break; bytes_t num_writ = write_all ( num_read, buffer, 0 ); assert ( num_writ == num_read ); total += num_writ; } return total; }
bytes_t Stream :: write ( const Mem & src, index_t start ) const { FUNC_ENTRY (); if ( start < 0 ) THROW ( xc_param_err, "bad start index: %ld", start ); bytes_t size = src . size (); if ( ( U64 ) start >= size ) return bytes_t ( 0 ); bytes_t to_write = size - ( U64 ) start; if ( null_ref () ) return bytes_t ( 0 ); StreamItf * itf = get_itf ( CAP_WRITE ); bytes_t mtu = itf -> get_mtu (); if ( mtu < to_write ) to_write = mtu; return itf -> write ( to_write, src, start ); }
namespace vmime { /** "Null" (empty) string. */ const string NULL_STRING; /** "Null" (empty) text. */ const text NULL_TEXT; /** "Null" (empty) word. */ const word NULL_WORD("", vmime::charset(vmime::charsets::US_ASCII)); /** Return the library name (eg: "libvmime"). * * @return library name */ const string libname() { return (VMIME_PACKAGE); } /** Return the library version (eg: "0.5.2"). * * @return library version */ const string libversion() { return (VMIME_VERSION " (" __DATE__ " " __TIME__ ")"); } /** Return the library API version (eg: "6:1:6"). * * @return library API version */ const string libapi() { return (VMIME_API); } // New line sequence to be used when folding header fields. const string NEW_LINE_SEQUENCE = "\r\n "; const string::size_type NEW_LINE_SEQUENCE_LENGTH = 1; // space /** The CR-LF sequence. */ const string CRLF = "\r\n"; /** The current MIME version supported by VMime. */ const string SUPPORTED_MIME_VERSION = "1.0"; /** Null reference. */ const null_ref null = null_ref(); // Line length limits namespace lineLengthLimits { const string::size_type infinite = std::numeric_limits <string::size_type>::max(); } #ifndef VMIME_BUILDING_DOC // // V-Mime Initializer // ==================== // // Force instanciation of singletons. This is to prevent problems that might // happen in multithreaded applications... // // WARNING: we put the initializer at the end of this compilation unit. This // ensures this object is initialized _after_ all other global variables in // the same compilation unit (in particular "lineLengthLimits::infinite", // which is used by the generate() function (called from "textPartFactory" // constructor, for example). // class initializer { public: initializer() { options::getInstance(); utility::encoder::encoderFactory::getInstance(); headerFieldFactory::getInstance(); textPartFactory::getInstance(); #if VMIME_HAVE_MESSAGING_FEATURES net::serviceFactory::getInstance(); #endif } }; initializer theInitializer; #endif // VMIME_BUILDING_DOC } // vmime