/*************************************************************************** * GUrlString.cpp - String URL class * * ----------------------------------------------------------------------- * * copyright (C) 2013 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ***************************************************************************/ /** * @file GUrlString.cpp * @brief String URL class interface implementation * @author Juergen Knoedlseder */ /* __ Includes ___________________________________________________________ */ #ifdef HAVE_CONFIG_H #include #endif #include // std::va_list #include // std::memset() function #include // std::fopen, std::fgets, std::fclose, etc... #include "GUrlString.hpp" #include "GTools.hpp" #include "GException.hpp" /* __ Method name definitions ____________________________________________ */ #define G_OPEN "GUrlString::open(std::string&, std::string&)" /* __ Macros _____________________________________________________________ */ /* __ Coding definitions _________________________________________________ */ /* __ Debug definitions __________________________________________________ */ /*========================================================================== = = = Constructors/destructors = = = ==========================================================================*/ /***********************************************************************//** * @brief Void constructor ***************************************************************************/ GUrlString::GUrlString(void) : GUrl() { // Initialise members init_members(); // Return return; } /***********************************************************************//** * @brief Text string constructor * * @param[in] string Text string. * * Constructs GUrlString object by assigning a text @p string to the * object's buffer. ***************************************************************************/ GUrlString::GUrlString(const std::string& string) : GUrl() { // Initialise members init_members(); // Open URL open(string); // Return return; } /***********************************************************************//** * @brief Copy constructor * * @param[in] url Unified Resource Locator. ***************************************************************************/ GUrlString::GUrlString(const GUrlString& url) : GUrl(url) { // Initialise members init_members(); // Copy members copy_members(url); // Return return; } /***********************************************************************//** * @brief Destructor ***************************************************************************/ GUrlString::~GUrlString(void) { // Free members free_members(); // Return return; } /*========================================================================== = = = Operators = = = ==========================================================================*/ /***********************************************************************//** * @brief Assignment operator * * @param[in] url Unified Resource Locator. * @return Unified Resource Locator. ***************************************************************************/ GUrlString& GUrlString::operator=(const GUrlString& url) { // Execute only if object is not identical if (this != &url) { // Copy base class members this->GUrl::operator=(url); // Free members free_members(); // Initialise members init_members(); // Copy members copy_members(url); } // endif: object was not identical // Return return *this; } /*========================================================================== = = = Public methods = = = ==========================================================================*/ /***********************************************************************//** * @brief Clear string URL ***************************************************************************/ void GUrlString::clear(void) { // Free class members free_members(); this->GUrl::free_members(); // Initialise members this->GUrl::init_members(); init_members(); // Return return; } /***********************************************************************//** * @brief Clone string URL * * @return Pointer to deep copy of string URL. ***************************************************************************/ GUrlString* GUrlString::clone(void) const { // Clone object return new GUrlString(*this); } /***********************************************************************//** * @brief Open string URL * * @param[in] string Text string. * @param[in] mode Mode parameter (ignored). ***************************************************************************/ void GUrlString::open(const std::string& string, const std::string& mode) { // First close any existing URL close(); // Store text string and initialise index m_buffer = string; m_index = 0; // Return return; } /***********************************************************************//** * @brief Close file ***************************************************************************/ void GUrlString::close(void) { // Clear buffer m_buffer.clear(); // Initialise index m_index = 0; // Return return; } /***********************************************************************//** * @brief Read block of data from string buffer * * @param[in] buffer Data buffer. * @param[in] nbyte Number of Bytes to be read. * @return Number of Bytes that were effectively read. * * Reads @p nbyte Bytes from the string into a @p buffer. The position * indicator of the string is advanced by the total amount of bytes read. * * The total number of Bytes successfully read is returned. If this number * differs from the @p nbyte parameter, the end of the string was reached. * The proper indicator is set. * * If either @p buffer is NULL or @p nbyte is zero, the method returns zero * and both the string state and the content pointed by @p buffer remain * unchanged. * * If no string exists, the method returns zero and both the string state * and the content pointed by @p buffer remain unchanged. ***************************************************************************/ int GUrlString::read(void* buffer, const int& nbyte) { // Initialise number of Bytes read int nread = 0; // Continue only if buffer is valid and nbyte is positive if (buffer != NULL && nbyte > 0) { // Continue only if we have a string if (!m_buffer.empty()) { // Determine remaining number of Bytes in string int nremain = m_buffer.length() - m_index; // If Bytes are remaining then copy them to buffer if (nremain > 0) { // Set number of Bytes to extract nread = (nbyte < nremain) ? nbyte : nremain; // Extract Bytes const char* src = m_buffer.c_str() + m_index; char* dst = reinterpret_cast(buffer); for (int i = 0; i < nread; ++i) { *dst++ = *src++; } // Forward position indicator m_index += nread; } // endif: Bytes were remaining } // endif: there was a string } // endif: input parameters were valid // Return number of Bytes read return nread; } /***********************************************************************//** * @brief Write block of data buffer into string * * @param[in] buffer Data buffer. * @param[in] nbyte Number of Bytes to be written. * @return Number of Bytes that were effectively written. * * Writes @p nbyte Bytes from a @p buffer into the string. The position * indicator of the string is advanced by the total amount of bytes written. * * The total number of Bytes successfully written is returned. * * If either @p buffer is NULL or @p nbyte is zero, the method returns zero * and both the string state and the content pointed by @p buffer remain * unchanged. ***************************************************************************/ int GUrlString::write(const void* buffer, const int& nbyte) { // Initialise number of Bytes written int nwritten = 0; // Continue only if buffer is valid and nbyte is positive if (buffer != NULL && nbyte > 0) { // Create string to append std::string sbuffer; sbuffer.reserve(nbyte); const char* src = reinterpret_cast(buffer); for (int i = 0; i < nbyte; ++i) { sbuffer.push_back(*src++); } // Append string to buffer m_buffer.append(sbuffer); // Set number of Bytes appended nwritten = nbyte; // Forward position indicator m_index += nwritten; } // endif: input parameters were valid // Return number of Bytes written return nwritten; } /***********************************************************************//** * @brief Return next character from string * * @return Next character in string. * * Returns the character currently pointed by the internal position * indicator. The internal position indicator is then advanced to the next * character. * * If the indicator is at the end of the string when called, the function * returns EOF. * * If no string exists, the method returns EOF. ***************************************************************************/ int GUrlString::get_char(void) const { // Initialise character to EOF int character = EOF; // Continue only if we have a string and if the index has not yet reached // the end of the buffer if (!m_buffer.empty() && m_index < m_buffer.length()) { // Get next character character = m_buffer[m_index]; // Forward position indicator m_index++; } // endif: we had a string // Return character return character; } /***********************************************************************//** * @brief Write character into string * * @param[in] character Character. * * Writes a character to the string and advances the position indicator. ***************************************************************************/ void GUrlString::put_char(const int& character) { // Append character to buffer m_buffer.push_back(character); // Forward position indicator m_index++; // Return return; } /***********************************************************************//** * @brief Read formatted data from string * * @param[in] format Format. * @param[in] ... Optional parameters. * * Reads data from a string and stores them according to the parameter format * into the locations pointed by the additional arguments. The additional * arguments should point to already allocated objects of the type specified * by their corresponding format specifier within the format string. * * If no string exists, the method does nothing. * * @todo The position indicator is not forwared as I have no idea how to do * this in fact!!! ***************************************************************************/ void GUrlString::scanf(const char* format, ...) { // Continue only if we have a string and if the index has not yet reached // the end of the buffer if (!m_buffer.empty() && m_index < m_buffer.length()) { // Declare argument pointer std::va_list arg_ptr; // Set start argument va_start(arg_ptr, format); // Get pointer to source const char* src = m_buffer.c_str() + m_index; // Read data from string vsscanf(src, format, arg_ptr); // Stop argument reading va_end(arg_ptr); } // endif: we had a string // Return return; } /***********************************************************************//** * @brief Write formatted data into string * * @param[in] format Format. * @param[in] ... Optional parameters. * * Writes the C string pointed by format to the string. If format includes * format specifiers (subsequences beginning with %), the additional * arguments following format are formatted and inserted in the resulting * string replacing their respective specifiers. * * After the format parameter, the function expects at least as many * additional arguments as specified by format. ***************************************************************************/ void GUrlString::printf(const char* format, ...) { // Allocate buffer for printing. The length here is fixed, which is // not a good thing as we cannot really know how many Bytes arrive. // But how else can we deal with this??? char buffer[8192]; std::memset(&buffer, 0, sizeof(buffer)); // Declare argument pointer std::va_list arg_ptr; // Set start argument va_start(arg_ptr, format); // Write data into buffer std::vsprintf(buffer, format, arg_ptr); // Stop argument reading va_end(arg_ptr); // Convert buffer to C++ string std::string sbuffer = std::string(buffer); // If not empty then append buffer int nwritten = sbuffer.length(); if (nwritten > 0) { m_buffer.append(buffer); m_index += nwritten; } // Return return; } /***********************************************************************//** * @brief Print URL information * * @param[in] chatter Chattiness (defaults to NORMAL). * @return String containing URL information. ***************************************************************************/ std::string GUrlString::print(const GChatter& chatter) const { // Initialise result string std::string result; // Continue only if chatter is not silent if (chatter != SILENT) { // Append header result.append("=== GUrlString ==="); // Append URL information result.append("\n"+gammalib::parformat("String size")); result.append(gammalib::str(m_buffer.length())); result.append("\n"+gammalib::parformat("String position indicator")); result.append(gammalib::str(m_index)); } // endif: chatter was not silent // Return result return result; } /*========================================================================== = = = Private methods = = = ==========================================================================*/ /***********************************************************************//** * @brief Initialise class members ***************************************************************************/ void GUrlString::init_members(void) { // Initialise members m_index = 0; m_buffer.clear(); // Return return; } /***********************************************************************//** * @brief Copy class members * * @param[in] url URL. ***************************************************************************/ void GUrlString::copy_members(const GUrlString& url) { // Copy members m_index = url.m_index; m_buffer = url.m_buffer; // Return return; } /***********************************************************************//** * @brief Delete class members ***************************************************************************/ void GUrlString::free_members(void) { // Close file close(); // Return return; }