GammaLib  2.1.0.dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GUrlString.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * GUrlString.cpp - String URL class *
3  * ----------------------------------------------------------------------- *
4  * copyright (C) 2013 by Juergen Knoedlseder *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 /**
22  * @file GUrlString.cpp
23  * @brief String URL class interface implementation
24  * @author Juergen Knoedlseder
25  */
26 
27 /* __ Includes ___________________________________________________________ */
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <cstdarg> // std::va_list
32 #include <cstring> // std::memset() function
33 #include <cstdio> // std::fopen, std::fgets, std::fclose, etc...
34 #include "GUrlString.hpp"
35 #include "GTools.hpp"
36 #include "GException.hpp"
37 
38 /* __ Method name definitions ____________________________________________ */
39 #define G_OPEN "GUrlString::open(std::string&, std::string&)"
40 
41 /* __ Macros _____________________________________________________________ */
42 
43 /* __ Coding definitions _________________________________________________ */
44 
45 /* __ Debug definitions __________________________________________________ */
46 
47 
48 /*==========================================================================
49  = =
50  = Constructors/destructors =
51  = =
52  ==========================================================================*/
53 
54 /***********************************************************************//**
55  * @brief Void constructor
56  ***************************************************************************/
58 {
59  // Initialise members
60  init_members();
61 
62  // Return
63  return;
64 }
65 
66 
67 /***********************************************************************//**
68  * @brief Text string constructor
69  *
70  * @param[in] string Text string.
71  *
72  * Constructs GUrlString object by assigning a text @p string to the
73  * object's buffer.
74  ***************************************************************************/
75 GUrlString::GUrlString(const std::string& string) : GUrl()
76 {
77  // Initialise members
78  init_members();
79 
80  // Open URL
81  open(string);
82 
83  // Return
84  return;
85 }
86 
87 
88 /***********************************************************************//**
89  * @brief Copy constructor
90  *
91  * @param[in] url Unified Resource Locator.
92  ***************************************************************************/
94 {
95  // Initialise members
96  init_members();
97 
98  // Copy members
99  copy_members(url);
100 
101  // Return
102  return;
103 }
104 
105 
106 /***********************************************************************//**
107  * @brief Destructor
108  ***************************************************************************/
110 {
111  // Free members
112  free_members();
113 
114  // Return
115  return;
116 }
117 
118 
119 /*==========================================================================
120  = =
121  = Operators =
122  = =
123  ==========================================================================*/
124 
125 /***********************************************************************//**
126  * @brief Assignment operator
127  *
128  * @param[in] url Unified Resource Locator.
129  * @return Unified Resource Locator.
130  ***************************************************************************/
132 {
133  // Execute only if object is not identical
134  if (this != &url) {
135 
136  // Copy base class members
137  this->GUrl::operator=(url);
138 
139  // Free members
140  free_members();
141 
142  // Initialise members
143  init_members();
144 
145  // Copy members
146  copy_members(url);
147 
148  } // endif: object was not identical
149 
150  // Return
151  return *this;
152 }
153 
154 
155 /*==========================================================================
156  = =
157  = Public methods =
158  = =
159  ==========================================================================*/
160 
161 /***********************************************************************//**
162  * @brief Clear string URL
163  ***************************************************************************/
165 {
166  // Free class members
167  free_members();
168  this->GUrl::free_members();
169 
170  // Initialise members
171  this->GUrl::init_members();
172  init_members();
173 
174  // Return
175  return;
176 }
177 
178 
179 /***********************************************************************//**
180  * @brief Clone string URL
181  *
182  * @return Pointer to deep copy of string URL.
183  ***************************************************************************/
185 {
186  // Clone object
187  return new GUrlString(*this);
188 }
189 
190 
191 /***********************************************************************//**
192  * @brief Open string URL
193  *
194  * @param[in] string Text string.
195  * @param[in] mode Mode parameter (ignored).
196  ***************************************************************************/
197 void GUrlString::open(const std::string& string, const std::string& mode)
198 {
199  // First close any existing URL
200  close();
201 
202  // Store text string and initialise index
203  m_buffer = string;
204  m_index = 0;
205 
206  // Return
207  return;
208 }
209 
210 
211 /***********************************************************************//**
212  * @brief Close file
213  ***************************************************************************/
215 {
216  // Clear buffer
217  m_buffer.clear();
218 
219  // Initialise index
220  m_index = 0;
221 
222  // Return
223  return;
224 }
225 
226 
227 /***********************************************************************//**
228  * @brief Read block of data from string buffer
229  *
230  * @param[in] buffer Data buffer.
231  * @param[in] nbyte Number of Bytes to be read.
232  * @return Number of Bytes that were effectively read.
233  *
234  * Reads @p nbyte Bytes from the string into a @p buffer. The position
235  * indicator of the string is advanced by the total amount of bytes read.
236  *
237  * The total number of Bytes successfully read is returned. If this number
238  * differs from the @p nbyte parameter, the end of the string was reached.
239  * The proper indicator is set.
240  *
241  * If either @p buffer is NULL or @p nbyte is zero, the method returns zero
242  * and both the string state and the content pointed by @p buffer remain
243  * unchanged.
244  *
245  * If no string exists, the method returns zero and both the string state
246  * and the content pointed by @p buffer remain unchanged.
247  ***************************************************************************/
248 int GUrlString::read(void* buffer, const int& nbyte)
249 {
250  // Initialise number of Bytes read
251  int nread = 0;
252 
253  // Continue only if buffer is valid and nbyte is positive
254  if (buffer != NULL && nbyte > 0) {
255 
256  // Continue only if we have a string
257  if (!m_buffer.empty()) {
258 
259  // Determine remaining number of Bytes in string
260  int nremain = m_buffer.length() - m_index;
261 
262  // If Bytes are remaining then copy them to buffer
263  if (nremain > 0) {
264 
265  // Set number of Bytes to extract
266  nread = (nbyte < nremain) ? nbyte : nremain;
267 
268  // Extract Bytes
269  const char* src = m_buffer.c_str() + m_index;
270  char* dst = reinterpret_cast<char*>(buffer);
271  for (int i = 0; i < nread; ++i) {
272  *dst++ = *src++;
273  }
274 
275  // Forward position indicator
276  m_index += nread;
277 
278  } // endif: Bytes were remaining
279 
280  } // endif: there was a string
281 
282  } // endif: input parameters were valid
283 
284  // Return number of Bytes read
285  return nread;
286 }
287 
288 
289 /***********************************************************************//**
290  * @brief Write block of data buffer into string
291  *
292  * @param[in] buffer Data buffer.
293  * @param[in] nbyte Number of Bytes to be written.
294  * @return Number of Bytes that were effectively written.
295  *
296  * Writes @p nbyte Bytes from a @p buffer into the string. The position
297  * indicator of the string is advanced by the total amount of bytes written.
298  *
299  * The total number of Bytes successfully written is returned.
300  *
301  * If either @p buffer is NULL or @p nbyte is zero, the method returns zero
302  * and both the string state and the content pointed by @p buffer remain
303  * unchanged.
304  ***************************************************************************/
305 int GUrlString::write(const void* buffer, const int& nbyte)
306 {
307  // Initialise number of Bytes written
308  int nwritten = 0;
309 
310  // Continue only if buffer is valid and nbyte is positive
311  if (buffer != NULL && nbyte > 0) {
312 
313  // Create string to append
314  std::string sbuffer;
315  sbuffer.reserve(nbyte);
316  const char* src = reinterpret_cast<const char*>(buffer);
317  for (int i = 0; i < nbyte; ++i) {
318  sbuffer.push_back(*src++);
319  }
320 
321  // Append string to buffer
322  m_buffer.append(sbuffer);
323 
324  // Set number of Bytes appended
325  nwritten = nbyte;
326 
327  // Forward position indicator
328  m_index += nwritten;
329 
330  } // endif: input parameters were valid
331 
332  // Return number of Bytes written
333  return nwritten;
334 }
335 
336 
337 /***********************************************************************//**
338  * @brief Return next character from string
339  *
340  * @return Next character in string.
341  *
342  * Returns the character currently pointed by the internal position
343  * indicator. The internal position indicator is then advanced to the next
344  * character.
345  *
346  * If the indicator is at the end of the string when called, the function
347  * returns EOF.
348  *
349  * If no string exists, the method returns EOF.
350  ***************************************************************************/
351 int GUrlString::get_char(void) const
352 {
353  // Initialise character to EOF
354  int character = EOF;
355 
356  // Continue only if we have a string and if the index has not yet reached
357  // the end of the buffer
358  if (!m_buffer.empty() && m_index < m_buffer.length()) {
359 
360  // Get next character
361  character = m_buffer[m_index];
362 
363  // Forward position indicator
364  m_index++;
365 
366  } // endif: we had a string
367 
368  // Return character
369  return character;
370 }
371 
372 
373 /***********************************************************************//**
374  * @brief Write character into string
375  *
376  * @param[in] character Character.
377  *
378  * Writes a character to the string and advances the position indicator.
379  ***************************************************************************/
380 void GUrlString::put_char(const int& character)
381 {
382  // Append character to buffer
383  m_buffer.push_back(character);
384 
385  // Forward position indicator
386  m_index++;
387 
388  // Return
389  return;
390 }
391 
392 
393 /***********************************************************************//**
394  * @brief Read formatted data from string
395  *
396  * @param[in] format Format.
397  * @param[in] ... Optional parameters.
398  *
399  * Reads data from a string and stores them according to the parameter format
400  * into the locations pointed by the additional arguments. The additional
401  * arguments should point to already allocated objects of the type specified
402  * by their corresponding format specifier within the format string.
403  *
404  * If no string exists, the method does nothing.
405  *
406  * @todo The position indicator is not forwared as I have no idea how to do
407  * this in fact!!!
408  ***************************************************************************/
409 void GUrlString::scanf(const char* format, ...)
410 {
411  // Continue only if we have a string and if the index has not yet reached
412  // the end of the buffer
413  if (!m_buffer.empty() && m_index < m_buffer.length()) {
414 
415  // Declare argument pointer
416  std::va_list arg_ptr;
417 
418  // Set start argument
419  va_start(arg_ptr, format);
420 
421  // Get pointer to source
422  const char* src = m_buffer.c_str() + m_index;
423 
424  // Read data from string
425  vsscanf(src, format, arg_ptr);
426 
427  // Stop argument reading
428  va_end(arg_ptr);
429 
430  } // endif: we had a string
431 
432  // Return
433  return;
434 }
435 
436 
437 /***********************************************************************//**
438  * @brief Write formatted data into string
439  *
440  * @param[in] format Format.
441  * @param[in] ... Optional parameters.
442  *
443  * Writes the C string pointed by format to the string. If format includes
444  * format specifiers (subsequences beginning with %), the additional
445  * arguments following format are formatted and inserted in the resulting
446  * string replacing their respective specifiers.
447  *
448  * After the format parameter, the function expects at least as many
449  * additional arguments as specified by format.
450  ***************************************************************************/
451 void GUrlString::printf(const char* format, ...)
452 {
453  // Allocate buffer for printing. The length here is fixed, which is
454  // not a good thing as we cannot really know how many Bytes arrive.
455  // But how else can we deal with this???
456  char buffer[8192];
457  std::memset(&buffer, 0, sizeof(buffer));
458 
459  // Declare argument pointer
460  std::va_list arg_ptr;
461 
462  // Set start argument
463  va_start(arg_ptr, format);
464 
465  // Write data into buffer
466  std::vsprintf(buffer, format, arg_ptr);
467 
468  // Stop argument reading
469  va_end(arg_ptr);
470 
471  // Convert buffer to C++ string
472  std::string sbuffer = std::string(buffer);
473 
474  // If not empty then append buffer
475  int nwritten = sbuffer.length();
476  if (nwritten > 0) {
477  m_buffer.append(buffer);
478  m_index += nwritten;
479  }
480 
481  // Return
482  return;
483 }
484 
485 
486 /***********************************************************************//**
487  * @brief Print URL information
488  *
489  * @param[in] chatter Chattiness (defaults to NORMAL).
490  * @return String containing URL information.
491  ***************************************************************************/
492 std::string GUrlString::print(const GChatter& chatter) const
493 {
494  // Initialise result string
495  std::string result;
496 
497  // Continue only if chatter is not silent
498  if (chatter != SILENT) {
499 
500  // Append header
501  result.append("=== GUrlString ===");
502 
503  // Append URL information
504  result.append("\n"+gammalib::parformat("String size"));
505  result.append(gammalib::str(m_buffer.length()));
506  result.append("\n"+gammalib::parformat("String position indicator"));
507  result.append(gammalib::str(m_index));
508 
509  } // endif: chatter was not silent
510 
511  // Return result
512  return result;
513 }
514 
515 
516 
517 
518 /*==========================================================================
519  = =
520  = Private methods =
521  = =
522  ==========================================================================*/
523 
524 /***********************************************************************//**
525  * @brief Initialise class members
526  ***************************************************************************/
528 {
529  // Initialise members
530  m_index = 0;
531  m_buffer.clear();
532 
533  // Return
534  return;
535 }
536 
537 
538 /***********************************************************************//**
539  * @brief Copy class members
540  *
541  * @param[in] url URL.
542  ***************************************************************************/
544 {
545  // Copy members
546  m_index = url.m_index;
547  m_buffer = url.m_buffer;
548 
549  // Return
550  return;
551 }
552 
553 
554 /***********************************************************************//**
555  * @brief Delete class members
556  ***************************************************************************/
558 {
559  // Close file
560  close();
561 
562  // Return
563  return;
564 }
virtual int read(void *buffer, const int &nbyte)
Read block of data from string buffer.
Definition: GUrlString.cpp:248
GUrlString & operator=(const GUrlString &url)
Assignment operator.
Definition: GUrlString.cpp:131
virtual void printf(const char *format,...)
Write formatted data into string.
Definition: GUrlString.cpp:451
void free_members(void)
Delete class members.
Definition: GUrlString.cpp:557
String URL class.
Definition: GUrlString.hpp:42
std::string m_buffer
Text string.
Definition: GUrlString.hpp:80
virtual void scanf(const char *format,...)
Read formatted data from string.
Definition: GUrlString.cpp:409
GUrl & operator=(const GUrl &url)
Assignment operator.
Definition: GUrl.cpp:104
void copy_members(const GUrlString &url)
Copy class members.
Definition: GUrlString.cpp:543
Gammalib tools definition.
virtual void put_char(const int &character)
Write character into string.
Definition: GUrlString.cpp:380
Abstract URL base class.
Definition: GUrl.hpp:44
virtual int get_char(void) const
Return next character from string.
Definition: GUrlString.cpp:351
virtual std::string print(const GChatter &chatter=NORMAL) const
Print URL information.
Definition: GUrlString.cpp:492
virtual void clear(void)
Clear string URL.
Definition: GUrlString.cpp:164
virtual void close(void)
Close file.
Definition: GUrlString.cpp:214
GChatter
Definition: GTypemaps.hpp:33
void free_members(void)
Delete class members.
Definition: GUrl.cpp:163
GUrlString(void)
Void constructor.
Definition: GUrlString.cpp:57
const std::string & string(void) const
Definition: GUrlString.hpp:69
int m_index
String position indicator.
Definition: GUrlString.hpp:79
Exception handler interface definition.
virtual void open(const std::string &string, const std::string &mode="")
Open string URL.
Definition: GUrlString.cpp:197
virtual GUrlString * clone(void) const
Clone string URL.
Definition: GUrlString.cpp:184
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition: GTools.cpp:1143
void init_members(void)
Initialise class members.
Definition: GUrlString.cpp:527
String URL class interface definition.
virtual ~GUrlString(void)
Destructor.
Definition: GUrlString.cpp:109
void init_members(void)
Initialise class members.
Definition: GUrl.cpp:141
virtual int write(const void *buffer, const int &nbyte)
Write block of data buffer into string.
Definition: GUrlString.cpp:305
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition: GTools.cpp:489