mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 16:40:04 +00:00 
			
		
		
		
	Initial QFileBuffer implementation
This commit is contained in:
		
							parent
							
								
									779d03c576
								
							
						
					
					
						commit
						08965aa7f3
					
				
					 3 changed files with 501 additions and 2 deletions
				
			
		|  | @ -160,12 +160,14 @@ set(HDR_UTIL source/scwx/qt/util/color.hpp | ||||||
|              source/scwx/qt/util/font_buffer.hpp |              source/scwx/qt/util/font_buffer.hpp | ||||||
|              source/scwx/qt/util/json.hpp |              source/scwx/qt/util/json.hpp | ||||||
|              source/scwx/qt/util/streams.hpp |              source/scwx/qt/util/streams.hpp | ||||||
|              source/scwx/qt/util/texture_atlas.hpp) |              source/scwx/qt/util/texture_atlas.hpp | ||||||
|  |              source/scwx/qt/util/q_file_buffer.hpp) | ||||||
| set(SRC_UTIL source/scwx/qt/util/color.cpp | set(SRC_UTIL source/scwx/qt/util/color.cpp | ||||||
|              source/scwx/qt/util/font.cpp |              source/scwx/qt/util/font.cpp | ||||||
|              source/scwx/qt/util/font_buffer.cpp |              source/scwx/qt/util/font_buffer.cpp | ||||||
|              source/scwx/qt/util/json.cpp |              source/scwx/qt/util/json.cpp | ||||||
|              source/scwx/qt/util/texture_atlas.cpp) |              source/scwx/qt/util/texture_atlas.cpp | ||||||
|  |              source/scwx/qt/util/q_file_buffer.cpp) | ||||||
| set(HDR_VIEW source/scwx/qt/view/level2_product_view.hpp | set(HDR_VIEW source/scwx/qt/view/level2_product_view.hpp | ||||||
|              source/scwx/qt/view/level3_product_view.hpp |              source/scwx/qt/view/level3_product_view.hpp | ||||||
|              source/scwx/qt/view/level3_radial_view.hpp |              source/scwx/qt/view/level3_radial_view.hpp | ||||||
|  |  | ||||||
							
								
								
									
										306
									
								
								scwx-qt/source/scwx/qt/util/q_file_buffer.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								scwx-qt/source/scwx/qt/util/q_file_buffer.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,306 @@ | ||||||
|  | #include <scwx/qt/util/q_file_buffer.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | 
 | ||||||
|  | #include <QFile> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace util | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = "scwx::qt::util::q_file_buffer"; | ||||||
|  | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
|  | // Adapted from Microsoft filebuf reference implementation
 | ||||||
|  | // Copyright (c) Microsoft Corporation.
 | ||||||
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | ||||||
|  | 
 | ||||||
|  | class QFileBuffer::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Impl(QFileBuffer* self) : self_ {self} {}; | ||||||
|  |    ~Impl() = default; | ||||||
|  | 
 | ||||||
|  |    void ResetPutback(); | ||||||
|  |    void SetPutback(); | ||||||
|  | 
 | ||||||
|  |    QFileBuffer* self_; | ||||||
|  |    QFile        file_ {}; | ||||||
|  |    char_type    putbackChar_ {}; | ||||||
|  |    char_type*   putbackEback_ {nullptr}; | ||||||
|  |    char_type*   putbackEgptr_ {nullptr}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void QFileBuffer::Impl::ResetPutback() | ||||||
|  | { | ||||||
|  |    if (self_->eback() == &putbackChar_) | ||||||
|  |    { | ||||||
|  |       // Restore get buffer after putback
 | ||||||
|  |       self_->setg(putbackEback_, putbackEback_, putbackEgptr_); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void QFileBuffer::Impl::SetPutback() | ||||||
|  | { | ||||||
|  |    if (self_->eback() != &putbackChar_) | ||||||
|  |    { | ||||||
|  |       // Save current get buffer
 | ||||||
|  |       putbackEback_ = self_->eback(); | ||||||
|  |       putbackEgptr_ = self_->egptr(); | ||||||
|  |    } | ||||||
|  |    self_->setg(&putbackChar_, &putbackChar_, &putbackChar_ + 1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer::QFileBuffer() : std::streambuf(), p(std::make_unique<Impl>(this)) | ||||||
|  | { | ||||||
|  |    // Initialize read/write pointers
 | ||||||
|  |    setg(0, 0, 0); | ||||||
|  |    setp(0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer::QFileBuffer(const std::string&      filename, | ||||||
|  |                          std::ios_base::openmode mode) : | ||||||
|  |     QFileBuffer() | ||||||
|  | { | ||||||
|  |    open(filename, mode); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer::~QFileBuffer() = default; | ||||||
|  | 
 | ||||||
|  | QFileBuffer::QFileBuffer(QFileBuffer&&) noexcept            = default; | ||||||
|  | QFileBuffer& QFileBuffer::operator=(QFileBuffer&&) noexcept = default; | ||||||
|  | 
 | ||||||
|  | bool QFileBuffer::is_open() const | ||||||
|  | { | ||||||
|  |    return p->file_.isOpen(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer* QFileBuffer::open(const std::string&      filename, | ||||||
|  |                                std::ios_base::openmode mode) | ||||||
|  | { | ||||||
|  |    // If the associated file is already open, return a null pointer right away
 | ||||||
|  |    if (is_open()) | ||||||
|  |    { | ||||||
|  |       return nullptr; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Validate supported modes
 | ||||||
|  |    if (mode & std::ios_base::out || mode & std::ios_base::app || | ||||||
|  |        mode & std::ios_base::trunc) | ||||||
|  |    { | ||||||
|  |       logger_->error("open(): write mode not supported"); | ||||||
|  |       return nullptr; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Convert std iostream flags to Qt flags
 | ||||||
|  |    QIODeviceBase::OpenMode flags {}; | ||||||
|  |    if (mode & std::ios_base::in) | ||||||
|  |    { | ||||||
|  |       flags |= QIODeviceBase::OpenModeFlag::ReadOnly; | ||||||
|  |    } | ||||||
|  |    if ((mode & std::ios_base::binary) != std::ios_base::binary) | ||||||
|  |    { | ||||||
|  |       flags |= QIODeviceBase::OpenModeFlag::Text; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Set the filename and open the file
 | ||||||
|  |    p->file_.setFileName(QString::fromStdString(filename)); | ||||||
|  |    bool isOpen = p->file_.open(flags); | ||||||
|  | 
 | ||||||
|  |    if (isOpen) | ||||||
|  |    { | ||||||
|  |       // Seek to end if requested
 | ||||||
|  |       if (mode & std::ios_base::ate) | ||||||
|  |       { | ||||||
|  |          // Seek to end
 | ||||||
|  |          p->file_.seek(p->file_.size()); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Initialize read/write pointers
 | ||||||
|  |       setg(0, 0, 0); | ||||||
|  |       setp(0, 0); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return isOpen ? this : nullptr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer* QFileBuffer::close() | ||||||
|  | { | ||||||
|  |    // If the associated file is already closed, return a null pointer right away
 | ||||||
|  |    if (!p->file_.isOpen()) | ||||||
|  |    { | ||||||
|  |       return nullptr; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // Close the file
 | ||||||
|  |    p->file_.close(); | ||||||
|  | 
 | ||||||
|  |    return this; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer::int_type QFileBuffer::pbackfail(int_type c) | ||||||
|  | { | ||||||
|  |    if (gptr() && eback() < gptr() && | ||||||
|  |        (traits_type::eq_int_type(traits_type::eof(), c) || | ||||||
|  |         traits_type::eq_int_type(traits_type::to_int_type(gptr()[-1]), c))) | ||||||
|  |    { | ||||||
|  |       // Just back up position
 | ||||||
|  |       gbump(static_cast<int>(sizeof(char_type)) * -1); | ||||||
|  |       return traits_type::not_eof(c); | ||||||
|  |    } | ||||||
|  |    else if (!is_open() || traits_type::eq_int_type(traits_type::eof(), c)) | ||||||
|  |    { | ||||||
|  |       // No open QFile or EOF, fail
 | ||||||
|  |       return traits_type::eof(); | ||||||
|  |    } | ||||||
|  |    else if (gptr() != &p->putbackChar_) | ||||||
|  |    { | ||||||
|  |       // Put back to buffer
 | ||||||
|  |       p->putbackChar_ = traits_type::to_char_type(c); | ||||||
|  |       p->SetPutback(); | ||||||
|  |       return c; | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       // Nowhere to put back
 | ||||||
|  |       return traits_type::eof(); | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer::pos_type QFileBuffer::seekoff(off_type               off, | ||||||
|  |                                            std::ios_base::seekdir dir, | ||||||
|  |                                            std::ios_base::openmode /* which */) | ||||||
|  | { | ||||||
|  |    pos_type newPos {pos_type(off_type(-1))}; | ||||||
|  | 
 | ||||||
|  |    switch (dir) | ||||||
|  |    { | ||||||
|  |    case std::ios_base::beg: | ||||||
|  |       // Seek using absolute position
 | ||||||
|  |       newPos = seekpos(off, std::ios_base::in); | ||||||
|  |       break; | ||||||
|  | 
 | ||||||
|  |    case std::ios_base::cur: | ||||||
|  |    { | ||||||
|  |       const pos_type currentPos {p->file_.pos() - (egptr() - gptr())}; | ||||||
|  |       pos_type       updatePos {currentPos + off}; | ||||||
|  | 
 | ||||||
|  |       // If the putback buffer is not empty, decrement the offset
 | ||||||
|  |       if (gptr() == &p->putbackChar_) | ||||||
|  |       { | ||||||
|  |          updatePos -= static_cast<off_type>(sizeof(char_type)); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Seek the file
 | ||||||
|  |       if (p->file_.seek(updatePos)) | ||||||
|  |       { | ||||||
|  |          // Record updated position
 | ||||||
|  |          newPos = updatePos; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       break; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    case std::ios_base::end: | ||||||
|  |    { | ||||||
|  |       const pos_type endPos {p->file_.size()}; | ||||||
|  |       const pos_type updatePos {endPos + off}; | ||||||
|  | 
 | ||||||
|  |       // Seek the file
 | ||||||
|  |       if (p->file_.seek(updatePos)) | ||||||
|  |       { | ||||||
|  |          // Record updated position
 | ||||||
|  |          newPos = updatePos; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       break; | ||||||
|  |    } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (newPos != static_cast<off_type>(-1)) | ||||||
|  |    { | ||||||
|  |       p->ResetPutback(); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return newPos; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer::pos_type QFileBuffer::seekpos(pos_type pos, | ||||||
|  |                                            std::ios_base::openmode /* which */) | ||||||
|  | { | ||||||
|  |    pos_type newPos {pos_type(off_type(-1))}; | ||||||
|  | 
 | ||||||
|  |    // Seek the file
 | ||||||
|  |    if (p->file_.seek(pos)) | ||||||
|  |    { | ||||||
|  |       // Record updated position
 | ||||||
|  |       newPos = pos; | ||||||
|  | 
 | ||||||
|  |       p->ResetPutback(); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return newPos; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer::int_type QFileBuffer::underflow() | ||||||
|  | { | ||||||
|  |    // This function is only called if gptr() == nullptr or gptr() > egptr()
 | ||||||
|  |    // (i.e., all buffer data has been read)
 | ||||||
|  |    int_type c; | ||||||
|  | 
 | ||||||
|  |    if (gptr() && gptr() < egptr()) | ||||||
|  |    { | ||||||
|  |       // Return buffered
 | ||||||
|  |       return traits_type::to_int_type(*gptr()); | ||||||
|  |    } | ||||||
|  |    else if (traits_type::eq_int_type(traits_type::eof(), c = uflow())) | ||||||
|  |    { | ||||||
|  |       // uflow failed, return EOF
 | ||||||
|  |       return c; | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       // Get a character, don't point past it
 | ||||||
|  |       pbackfail(c); | ||||||
|  |       return c; | ||||||
|  |    } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QFileBuffer::int_type QFileBuffer::uflow() | ||||||
|  | { | ||||||
|  |    if (gptr() && gptr() < egptr()) | ||||||
|  |    { | ||||||
|  |       // Return buffered
 | ||||||
|  |       int_type c = traits_type::to_int_type(*gptr()); | ||||||
|  |       gbump(sizeof(char_type)); | ||||||
|  |       return c; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (!p->file_.isOpen()) | ||||||
|  |    { | ||||||
|  |       // No open QFile, fail
 | ||||||
|  |       return traits_type::eof(); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    p->ResetPutback(); | ||||||
|  | 
 | ||||||
|  |    // Read the next character
 | ||||||
|  |    char_type c; | ||||||
|  |    return p->file_.read(reinterpret_cast<char*>(&c), sizeof(char_type)) > 0 ? | ||||||
|  |              traits_type::to_int_type(c) : | ||||||
|  |              traits_type::eof(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::streamsize QFileBuffer::xsgetn(char_type* s, std::streamsize count) | ||||||
|  | { | ||||||
|  |    // Read up to count bytes, forwarding the return value from QFile::read
 | ||||||
|  |    // (return negative values as zero)
 | ||||||
|  |    return std::max<std::streamsize>( | ||||||
|  |       p->file_.read(reinterpret_cast<char*>(s), count * sizeof(char_type)), 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace util
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
							
								
								
									
										191
									
								
								scwx-qt/source/scwx/qt/util/q_file_buffer.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								scwx-qt/source/scwx/qt/util/q_file_buffer.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,191 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <streambuf> | ||||||
|  | 
 | ||||||
|  | namespace scwx | ||||||
|  | { | ||||||
|  | namespace qt | ||||||
|  | { | ||||||
|  | namespace util | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * The QFileBuffer class is a std::streambuf interface to a QFile, allowing use | ||||||
|  |  * with C++ stream-based I/O. | ||||||
|  |  * | ||||||
|  |  * QFileBuffer has read-only support. Locales are ignored, and no conversions | ||||||
|  |  * are performed. | ||||||
|  |  * | ||||||
|  |  * Documentation for functions derived from | ||||||
|  |  * https://en.cppreference.com/ SPDX-License-Identifier: CC BY-SA 3.0
 | ||||||
|  |  */ | ||||||
|  | class QFileBuffer : public std::streambuf | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    /**
 | ||||||
|  |     * Constructs a new QFileBuffer object. The created object is not associated | ||||||
|  |     * with a file, and is_open() returns false. | ||||||
|  |     */ | ||||||
|  |    explicit QFileBuffer(); | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * Constructs a new QFileBuffer object, then associated the object with a | ||||||
|  |     * file by calling open(filename, mode). If the open call is successful, | ||||||
|  |     * is_open() returns true. | ||||||
|  |     */ | ||||||
|  |    explicit QFileBuffer(const std::string&      filename, | ||||||
|  |                         std::ios_base::openmode mode = std::ios_base::in); | ||||||
|  |    ~QFileBuffer(); | ||||||
|  | 
 | ||||||
|  |    QFileBuffer(const QFileBuffer&)            = delete; | ||||||
|  |    QFileBuffer& operator=(const QFileBuffer&) = delete; | ||||||
|  | 
 | ||||||
|  |    QFileBuffer(QFileBuffer&&) noexcept; | ||||||
|  |    QFileBuffer& operator=(QFileBuffer&&) noexcept; | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * @brief Checks if the associated file is open | ||||||
|  |     * | ||||||
|  |     * Returns true if the most recent call to open() succeeded and there has | ||||||
|  |     * been no call to close() since then. | ||||||
|  |     * | ||||||
|  |     * @return true if the associated file is open, false otherwise | ||||||
|  |     */ | ||||||
|  |    bool is_open() const; | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * @brief Opens a file and configures it as the associated character sequence | ||||||
|  |     * | ||||||
|  |     * Opens the file with the given name. If the associated file was already | ||||||
|  |     * open, returns a null pointer right away. | ||||||
|  |     * | ||||||
|  |     * @param filename The file name to open | ||||||
|  |     * @param openmode The file opening mode, a binary OR of the std::ios_base | ||||||
|  |     * modes | ||||||
|  |     * | ||||||
|  |     * @return this on success, a null pointer on failure | ||||||
|  |     */ | ||||||
|  |    QFileBuffer* open(const std::string&      filename, | ||||||
|  |                      std::ios_base::openmode mode = std::ios_base::in); | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * @brief Flushes the put area buffer and closes the associated file | ||||||
|  |     * | ||||||
|  |     * Closes the file, regardless of whether any of the preceding calls | ||||||
|  |     * succeeded or failed. | ||||||
|  |     * | ||||||
|  |     * If any of the function calls made fails, returns a null pointer. If any of | ||||||
|  |     * the function calls made throws an exception, the exception is caught and | ||||||
|  |     * rethrown after closing. If the file is already closed, returns a null | ||||||
|  |     * pointer right away. | ||||||
|  |     * | ||||||
|  |     * @return this on success, a null pointer on failure | ||||||
|  |     */ | ||||||
|  |    QFileBuffer* close(); | ||||||
|  | 
 | ||||||
|  | protected: | ||||||
|  |    /**
 | ||||||
|  |     * @brief Backs out the input sequence to unget a character, not affecting | ||||||
|  |     * the associated file | ||||||
|  |     * | ||||||
|  |     * @param c The character to put back, or Traits::eof() to indicate that | ||||||
|  |     * backing up of the get area is requested | ||||||
|  |     * | ||||||
|  |     * @return c on success except if c was Traits::eof(), in which case | ||||||
|  |     * Traits::not_eof(c) is returned. Traits::eof() on failure. | ||||||
|  |     */ | ||||||
|  |    virtual int_type pbackfail(int_type c = traits_type::eof()) override; | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * @brief Repositions the file position, using relative addressing | ||||||
|  |     * | ||||||
|  |     * Sets the position indicator of the input and/or output sequence relative | ||||||
|  |     * to some other position. | ||||||
|  |     * | ||||||
|  |     * @param off Relative position to set the position indicator to | ||||||
|  |     * @param dir Defines base position to apply the relative offset to | ||||||
|  |     * @param which Defines which of the input and/or output sequences to affect | ||||||
|  |     * | ||||||
|  |     * @return The resulting absolute position as defined by the position | ||||||
|  |     * indicator. | ||||||
|  |     */ | ||||||
|  |    virtual pos_type | ||||||
|  |    seekoff(off_type                off, | ||||||
|  |            std::ios_base::seekdir  dir, | ||||||
|  |            std::ios_base::openmode which = std::ios_base::in | | ||||||
|  |                                            std::ios_base::out) override; | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * @brief Repositions the file position, using absolute addressing | ||||||
|  |     * | ||||||
|  |     * Sets the position indicator of the input and/or output sequence to an | ||||||
|  |     * absolute position. | ||||||
|  |     * | ||||||
|  |     * @param pos Absolute position to set the position indicator to | ||||||
|  |     * @param which Defines which of the input and/or output sequences to affect | ||||||
|  |     * | ||||||
|  |     * @return The resulting absolute position as defined by the position | ||||||
|  |     * indicator. | ||||||
|  |     */ | ||||||
|  |    virtual pos_type | ||||||
|  |    seekpos(pos_type                pos, | ||||||
|  |            std::ios_base::openmode which = std::ios_base::in | | ||||||
|  |                                            std::ios_base::out) override; | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * @brief Reads from the associated file | ||||||
|  |     * | ||||||
|  |     * Ensures that at least one character is available in the input area by | ||||||
|  |     * updating the pointers to the input area (if needed) and reading more data | ||||||
|  |     * in from the input sequence (if applicable). Returns the value of that | ||||||
|  |     * character (converted to int_type with Traits::to_int_type(c)) on success | ||||||
|  |     * or Traits::eof() on failure. | ||||||
|  |     * | ||||||
|  |     * The function may update gptr, egptr and eback pointers to define the | ||||||
|  |     * location of newly loaded data (if any). On failure, the function ensures | ||||||
|  |     * that either gptr() == nullptr or gptr() == egptr. | ||||||
|  |     * | ||||||
|  |     * @return The value of the character pointed to by the get pointer after the | ||||||
|  |     * call on success, or Traits::eof() otherwise. | ||||||
|  |     */ | ||||||
|  |    virtual int_type underflow() override; | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * @brief Reads from the associated file and advances the next pointer in the | ||||||
|  |     * get area | ||||||
|  |     * | ||||||
|  |     * Behaves like the underflow(), except that if underflow() succeeds (does | ||||||
|  |     * not return Traits::eof()), then advances the next pointer for the get | ||||||
|  |     * area. In orther words, consumes one of the characters obtained by | ||||||
|  |     * underflow(). | ||||||
|  |     * | ||||||
|  |     * @return The value of the character that was read and consumed in case of | ||||||
|  |     * success, or Traits::eof() in case of failure. | ||||||
|  |     */ | ||||||
|  |    virtual int_type uflow() override; | ||||||
|  | 
 | ||||||
|  |    /**
 | ||||||
|  |     * @brief Reads multiple characters from the input sequence | ||||||
|  |     * | ||||||
|  |     * Reads count characters from the input sequence and stores them into a | ||||||
|  |     * character array pointed to by s. The characters are read as if by repeated | ||||||
|  |     * calls to sbumpc(). That is, if less than count characters are immediately | ||||||
|  |     * available, the function calls uflow() to provide more until Traits::eof() | ||||||
|  |     * is returned. | ||||||
|  |     * | ||||||
|  |     * @param s Pointer to the beginning of a char_type array | ||||||
|  |     * @param count Maximum number of characters to read | ||||||
|  |     * | ||||||
|  |     * @return The number of characters successfully read. If it is less than | ||||||
|  |     * count the input sequence has reached the end. | ||||||
|  |     */ | ||||||
|  |    virtual std::streamsize xsgetn(char_type* s, std::streamsize count) override; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace util
 | ||||||
|  | } // namespace qt
 | ||||||
|  | } // namespace scwx
 | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat