LibMusicXML  3.18
utilities.h
1 /*
2  MusicXML Library
3  Copyright (C) Grame 2006-2013
4 
5  This Source Code Form is subject to the terms of the Mozilla Public
6  License, v. 2.0. If a copy of the MPL was not distributed with this
7  file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9  Grame Research Laboratory, 11, cours de Verdun Gensoul 69002 Lyon - France
10  research@grame.fr
11 */
12 
13 #ifndef ___utilities___
14 #define ___utilities___
15 
16 #include <string>
17 #include <cassert>
18 
19 #include <iostream>
20 #include <sstream>
21 
22 #include <ctime>
23 
24 #include <set>
25 #include <list>
26 
27 #include <functional>
28 #include <algorithm>
29 
30 #include <string.h>
31 
32 /* JMI
33 #ifdef WIN32
34  // JMI
35 #else
36  #include <iconv.h>
37 #endif
38 */
39 
40 #include "smartpointer.h"
41 #include "basevisitor.h"
42 
43 
44 namespace MusicXML2
45 {
46 
47 //______________________________________________________________________________
48 class EXP timingItem : public smartable
49 {
50  public:
51  enum timingItemKind { kMandatory, kOptional };
52 
53  static SMARTP<timingItem> createTimingItem (
54  std::string activity,
55  std::string description,
56  timingItemKind kind,
57  std::clock_t startClock,
58  std::clock_t endClock);
59 
60  timingItem (
61  std::string activity,
62  std::string description,
63  timingItemKind kind,
64  std::clock_t startClock,
65  std::clock_t endClock);
66 
67  std::string fActivity;
68  std::string fDescription;
69  timingItemKind fKind;
70  clock_t fStartClock;
71  clock_t fEndClock;
72 };
73 
75 
76 class EXP timing {
77  public:
78  timing ();
79  virtual ~timing ();
80 
81  // global variable for general use
82  static timing gTiming;
83 
84  // add an item
85  void appendTimingItem (
86  std::string activity,
87  std::string description,
88  timingItem::timingItemKind
89  kind,
90  clock_t startClock,
91  clock_t endClock);
92 
93  // print
94  void print (std::ostream& os) const;
95 
96  private:
97 
98  std::list<S_timingItem>
99  fTimingItemsList;
100 };
101 EXP std::ostream& operator<< (std::ostream& os, const timing& tim);
102 
103 //______________________________________________________________________________
104 class EXP indenter
105 {
106  public:
107 
108  indenter (std::string spacer = " ");
109  virtual ~indenter ();
110 
111  // get the indent
112  int getIndent () const
113  { return fIndent; }
114 
115  // increase the indentation by 1
116  indenter& operator++ (const int value);
117 
118  // decrease the indentation by 1
119  indenter& operator-- (const int value);
120 
121  indenter& increment (int value);
122  indenter& decrement (int value);
123 
124  // reset the indentation
125  void resetToZero ()
126  { fIndent = 0; }
127 
128  // check indentation value
129  bool operator == (const int &value) const
130  { return fIndent == value; }
131  bool operator != (const int &value) const
132  { return fIndent != value; }
133 
134  // output as much space as specified
135  void print (std::ostream& os) const;
136 
137  // get a spacer for adhoc uses, without increasing the indentation
138  std::string getSpacer () const
139  { return fSpacer; }
140 
141  // indent a multiline 'R"(...)"' std::string
142  std::string indentMultiLineString (std::string value);
143 
144  // global variable for general use
145  static indenter gIndenter;
146 
147  private:
148  int fIndent;
149  std::string fSpacer;
150 };
151 
152 EXP std::ostream& operator<< (std::ostream& os, const indenter& idtr);
153 
154 // useful shortcut macros
155 #define gIndenter indenter::gIndenter
156 #define gTab indenter::gIndenter.getSpacer ()
157 
158 //______________________________________________________________________________
159 // a stream buffer that prefixes each line
160 // with the current indentation, i.e. spaces
161 
162 /*
163 std::endl declaration:
164 
165  std::endl for ostream
166  ostream& endl (ostream& os);
167 
168  basic template
169  template <class charT, class traits>
170  basic_ostream<charT,traits>& endl (basic_ostream<charT,traits>& os);
171 
172  Insert newline and flush
173  Inserts a new-line character and flushes the stream.
174 
175  Its behavior is equivalent to calling os.put('\n') (or os.put(os.widen('\n')) for character types other than char), and then os.flush().
176 
177 --
178 
179 Reference for this class:
180  https://stackoverflow.com/questions/2212776/overload-handling-of-stdendl
181 */
182 
183 class indentedStreamBuf: public std::stringbuf
184 {
185  private:
186 
187  std::ostream& fOutputSteam;
188  indenter& fIndenter;
189 
190  public:
191 
192  // constructor
194  std::ostream& outputStream,
195  indenter& idtr)
196  : fOutputSteam (outputStream),
197  fIndenter (idtr)
198  {}
199 
200  // indentation
201  indenter& getIndenter ()
202  { return fIndenter; }
203 
204  // flush
205  void flush ()
206  { fOutputSteam.flush (); }
207 
208  virtual int sync ();
209 };
210 
211 //______________________________________________________________________________
212 class EXP indentedOstream: public std::ostream
213 {
214 /*
215 Reference for this class:
216  https://stackoverflow.com/questions/2212776/overload-handling-of-stdendl
217 
218 Usage:
219  indentedOstream myStream (std::cout);
220 
221  myStream <<
222  1 << 2 << 3 << std::endl <<
223  5 << 6 << std::endl <<
224  7 << 8 << std::endl;
225 */
226 
227  private:
228  // indentedOstream just uses an indentedStreamBuf
229  indentedStreamBuf fIndentedStreamBuf;
230 
231  public:
232 
233  // constructor
235  std::ostream& str,
236  indenter& idtr)
237  : std::ostream (&fIndentedStreamBuf),
238  fIndentedStreamBuf (str, idtr)
239  {}
240 
241  // destructor
242  virtual ~indentedOstream ()
243  {};
244 
245  // flush
246  void flush ()
247  { fIndentedStreamBuf.flush (); }
248 
249  // indentation
250  indenter& getIndenter ()
251  { return fIndentedStreamBuf.getIndenter (); }
252 
253  void incrIdentation ()
254  { fIndentedStreamBuf.getIndenter ()++; }
255 
256  void decrIdentation ()
257  { fIndentedStreamBuf.getIndenter ()--; }
258 
259  // global variables for general use
260  static indentedOstream
261  gOutputIndentedOstream;
262  static indentedOstream
263  gLogIndentedOstream;
264  static indentedOstream
265  gNullIndentedOstream;
266 };
267 
268 // useful shortcut macros
269 #define gOutputOstream indentedOstream::gOutputIndentedOstream
270 #define gLogOstream indentedOstream::gLogIndentedOstream
271 #define gNullOstream indentedOstream::gNullIndentedOstream
272 
273 //______________________________________________________________________________
275 {
276  /* usage:
277  string dest = "";
278  for_each( source.begin (), source.end (), stringQuoteEscaper (dest));
279  */
280 
281  std::string& target;
282 
283  explicit stringQuoteEscaper (std::string& t)
284  : target (t)
285  {}
286 
287  void operator() (char ch) const
288  {
289  if( ch == '"') {
290  // or switch on any character that
291  // needs escaping like '\' itself
292  target.push_back ('\\');
293  }
294  target.push_back (ch);
295  }
296 };
297 
298 //______________________________________________________________________________
300 {
301  /* usage:
302  std::string dest = "";
303  for_each (
304  source.begin (),
305  source.end (),
306  stringSpaceRemover (dest));
307  */
308 
309  std::string& target;
310 
311  explicit stringSpaceRemover (std::string& t)
312  : target (t)
313  {}
314 
315  void operator() (char ch) const
316  {
317  if (ch != ' ') {
318  target.push_back (ch);
319  }
320  }
321 };
322 
323 //______________________________________________________________________________
325 {
326  /* usage:
327  std::string dest = "";
328  for_each (
329  source.begin (),
330  source.end (),
331  stringSpaceReplacer (dest, ersatz));
332  */
333 
334  std::string& target;
335  char ersatz;
336 
337  explicit stringSpaceReplacer (std::string& t, char ch)
338  : target (t), ersatz (ch)
339  {}
340 
341  void operator() (char ch) const
342  {
343  if (ch == ' ')
344  target.push_back (ersatz);
345  else
346  target.push_back (ch);
347  }
348 };
349 
350 //______________________________________________________________________________
351 std::string replicateString (
352  std::string str,
353  int times);
354 
355 //______________________________________________________________________________
356 std::string replaceSubstringInString (
357  std::string str,
358  std::string subString,
359  std::string ersatz);
360 
361 //______________________________________________________________________________
362 std::string int2EnglishWord (int n);
363 
364 //______________________________________________________________________________
365 std::string stringNumbersToEnglishWords (std::string str);
366 
367 //______________________________________________________________________________
368 std::set<int> decipherNaturalNumbersSetSpecification (
369  std::string theSpecification,
370  bool debugMode = false);
371 
372 //______________________________________________________________________________
373 std::set<std::string> decipherStringsSetSpecification (
374  std::string theSpecification,
375  bool debugMode = false);
376 
377 //______________________________________________________________________________
378 std::list<int> extractNumbersFromString (
379  std::string theString, // can contain "1, 2, 17"
380  bool debugMode = false);
381 
382 //______________________________________________________________________________
383 // from http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring
384 // trim string from start
385 inline std::string &ltrim (std::string &s) {
386  std::function <int (int)>
387  checkSpace =
388  [] (int x) { return isspace (x); };
389 
390  s.erase (
391  s.begin (),
392  find_if (
393  s.begin (),
394  s.end (),
395  std::not1 (checkSpace)
396  )
397  );
398 
399  return s;
400 }
401 
402 // trim string from end
403 inline std::string &rtrim (std::string &s) {
404  std::function <int (int)>
405  checkSpace =
406  [] (int x) { return isspace (x); };
407 
408  s.erase (
409  find_if (
410  s.rbegin (),
411  s.rend (),
412  std::not1 (checkSpace)
413  ).base(),
414  s.end ()
415  );
416 
417  return s;
418 }
419 
420 // trim string from both ends
421 inline std::string &trim (std::string &s) {
422  return ltrim (rtrim (s));
423 }
424 
425 //______________________________________________________________________________
426 std::pair<std::string, std::string> extractNamesPairFromString (
427  std::string theString, // may contain "P1 = Bassoon"
428  char separator,
429  bool debugMode = false);
430 
431 //______________________________________________________________________________
432 std::string doubleQuoteStringIfNonAlpha (
433  std::string theString);
434 
435 std::string quoteStringIfNonAlpha (
436  std::string theString);
437 
438 std::string doubleQuoteString (
439  std::string theString);
440 
441 std::string quoteString (
442  std::string theString);
443 
444 //______________________________________________________________________________
445 std::string booleanAsString (bool value);
446 
447 //______________________________________________________________________________
448 std::string singularOrPlural (
449  int number, std::string singularName, std::string pluralName);
450 
451 std::string singularOrPluralWithoutNumber (
452  int number, std::string singularName, std::string pluralName);
453 
454 //______________________________________________________________________________
455 void oahWarning (std::string warningMessage);
456 
457 void oahError (std::string errorMessage);
458 
459 //______________________________________________________________________________
460 std::string escapeDoubleQuotes (std::string s);
461 
462 //______________________________________________________________________________
463 void convertHTMLEntitiesToPlainCharacters (std::string& s);
464 
465 //______________________________________________________________________________
466 void splitStringIntoChunks (
467  std::string theString,
468  std::string theSeparator,
469  std::list<std::string>& chunksList);
470 
471 void splitRegularStringAtEndOfLines (
472  std::string theString,
473  std::list<std::string>& chunksList);
474 
475 void splitHTMLStringContainingEndOfLines ( // JMI
476  std::string theString,
477  std::list<std::string>& chunksList);
478 
479 //______________________________________________________________________________
480 std::string baseName (const std::string &filename);
481  // wait until c++17 for a standard library containing basename()...
482 
483 //______________________________________________________________________________
484 std::string makeSingleWordFromString (const std::string& theString);
485 
486 
487 } // namespace MusicXML2
488 
489 
490 #endif
MusicXML2::smartable
the base class for smart pointers implementation
Definition: smartpointer.h:29
MusicXML2::indenter
Definition: utilities.h:105
MusicXML2::stringSpaceRemover
Definition: utilities.h:300
MusicXML2::stringQuoteEscaper
Definition: utilities.h:275
MusicXML2::timingItem
Definition: utilities.h:49
MusicXML2::SMARTP
the smart pointer implementation
Definition: smartpointer.h:58
MusicXML2::indentedStreamBuf
Definition: utilities.h:184
MusicXML2::stringSpaceReplacer
Definition: utilities.h:325
MusicXML2::timing
Definition: utilities.h:76
MusicXML2::indentedOstream
Definition: utilities.h:213