1 //==============================================================================
2 //
3 //  This file is part of GPSTk, the GPS Toolkit.
4 //
5 //  The GPSTk is free software; you can redistribute it and/or modify
6 //  it under the terms of the GNU Lesser General Public License as published
7 //  by the Free Software Foundation; either version 3.0 of the License, or
8 //  any later version.
9 //
10 //  The GPSTk is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU Lesser General Public License for more details.
14 //
15 //  You should have received a copy of the GNU Lesser General Public
16 //  License along with GPSTk; if not, write to the Free Software Foundation,
17 //  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 //  This software was developed by Applied Research Laboratories at the
20 //  University of Texas at Austin.
21 //  Copyright 2004-2020, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 //  This software was developed by Applied Research Laboratories at the
28 //  University of Texas at Austin, under contract to an agency or agencies
29 //  within the U.S. Department of Defense. The U.S. Government retains all
30 //  rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 //  Pursuant to DoD Directive 523024
33 //
34 //  DISTRIBUTION STATEMENT A: This software has been approved for public
35 //                            release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 /**
40  * @file StringUtils.cpp
41  * Implementation of GPSTK string utility functions.
42  */
43 
44 #include "StringUtils.hpp"
45 
46 namespace gpstk
47 {
48    namespace StringUtils
49    {
50       HexDumpDataConfig ::
HexDumpDataConfig()51       HexDumpDataConfig()
52             : showIndex(true), hexIndex(true), upperHex(false),
53               idxDigits(4), indexSep(": "), groupBy(1), groupSep(" "),
54               group2By(8), group2Sep("  "), bytesPerLine(16),
55               showText(true), preText("    "),
56               showBaseData(false), showBaseIndex(false)
57       {}
58 
59 
60       HexDumpDataConfig ::
HexDumpDataConfig(bool ashowIndex,bool ahexIndex,bool aupperHex,unsigned aidxDigits,unsigned aindexWS,unsigned agroupBy,unsigned agroupWS,unsigned agroup2By,unsigned agroup2WS,unsigned abytesPerLine,bool ashowText,char aseparator,unsigned atextWS,bool aShowBaseData,bool aShowBaseIndex)61       HexDumpDataConfig(bool ashowIndex, bool ahexIndex, bool aupperHex,
62                         unsigned aidxDigits, unsigned aindexWS,
63                         unsigned agroupBy, unsigned agroupWS,
64                         unsigned agroup2By, unsigned agroup2WS,
65                         unsigned abytesPerLine, bool ashowText,
66                         char aseparator, unsigned atextWS,
67                         bool aShowBaseData, bool aShowBaseIndex)
68             : showIndex(ashowIndex), hexIndex(ahexIndex),
69          upperHex(aupperHex), idxDigits(aidxDigits),
70          groupBy(agroupBy), group2By(agroup2By),
71          bytesPerLine(abytesPerLine), showText(ashowText),
72          showBaseData(aShowBaseData), showBaseIndex(aShowBaseIndex)
73       {
74          indexSep = ":" + std::string(aindexWS, ' ');
75          groupSep = std::string(agroupWS, ' ');
76          group2Sep = std::string(agroup2WS, ' ');
77          preText = std::string(atextWS, ' ');
78          if (aseparator != 0)
79          {
80             preText += aseparator;
81             postText = std::string(1, aseparator);
82          }
83       }
84 
85 
86       HexDumpDataConfig ::
HexDumpDataConfig(bool ashowIndex,bool ahexIndex,bool aupperHex,unsigned aidxDigits,const std::string & aindexSep,unsigned agroupBy,const std::string & agroupSep,unsigned agroup2By,const std::string & agroup2Sep,unsigned abytesPerLine,bool ashowText,char aseparator,const std::string & atextSep,bool aShowBaseData,bool aShowBaseIndex,const std::string & adataEndSep,const std::string & adataFinal)87       HexDumpDataConfig(bool ashowIndex, bool ahexIndex, bool aupperHex,
88                         unsigned aidxDigits, const std::string& aindexSep,
89                         unsigned agroupBy, const std::string& agroupSep,
90                         unsigned agroup2By, const std::string& agroup2Sep,
91                         unsigned abytesPerLine, bool ashowText,
92                         char aseparator, const std::string& atextSep,
93                         bool aShowBaseData, bool aShowBaseIndex,
94                         const std::string& adataEndSep,
95                         const std::string& adataFinal)
96       : showIndex(ashowIndex), hexIndex(ahexIndex),
97          upperHex(aupperHex), idxDigits(aidxDigits),
98          groupBy(agroupBy), group2By(agroup2By),
99          bytesPerLine(abytesPerLine), showText(ashowText),
100          indexSep(aindexSep), groupSep(agroupSep), group2Sep(agroup2Sep),
101          showBaseData(aShowBaseData), showBaseIndex(aShowBaseIndex),
102          dataEndSep(adataEndSep), dataFinal(adataFinal)
103       {
104          preText = atextSep;
105          if (aseparator != 0)
106          {
107             preText += aseparator;
108             postText = std::string(1, aseparator);
109          }
110       }
111 
112 
113       HexDumpDataConfig ::
HexDumpDataConfig(bool ashowIndex,bool ahexIndex,bool aupperHex,unsigned aidxDigits,const std::string & aindexSep,unsigned agroupBy,const std::string & agroupSep,unsigned agroup2By,const std::string & agroup2Sep,unsigned abytesPerLine,bool ashowText,const std::string & apreText,const std::string & apostText,bool aShowBaseData,bool aShowBaseIndex,const std::string & adataEndSep,const std::string & adataFinal,const std::string & aprefix)114       HexDumpDataConfig(bool ashowIndex, bool ahexIndex, bool aupperHex,
115                         unsigned aidxDigits, const std::string& aindexSep,
116                         unsigned agroupBy, const std::string& agroupSep,
117                         unsigned agroup2By, const std::string& agroup2Sep,
118                         unsigned abytesPerLine, bool ashowText,
119                         const std::string& apreText,
120                         const std::string& apostText,
121                         bool aShowBaseData, bool aShowBaseIndex,
122                         const std::string& adataEndSep,
123                         const std::string& adataFinal,
124                         const std::string& aprefix)
125       : showIndex(ashowIndex), hexIndex(ahexIndex),
126          upperHex(aupperHex), idxDigits(aidxDigits),
127          groupBy(agroupBy), group2By(agroup2By),
128          bytesPerLine(abytesPerLine), showText(ashowText),
129          indexSep(aindexSep), groupSep(agroupSep), group2Sep(agroup2Sep),
130          preText(apreText), postText(apostText),
131          showBaseData(aShowBaseData), showBaseIndex(aShowBaseIndex),
132          dataEndSep(adataEndSep), dataFinal(adataFinal), prefix(aprefix)
133       {
134       }
135 
136 
137       unsigned HexDumpDataConfig ::
computeLineSize(unsigned bytesThisLine,bool lastLine) const138       computeLineSize(unsigned bytesThisLine,
139                       bool lastLine)
140          const
141       {
142          unsigned linesize = prefix.length();
143          unsigned w2 = 0;
144          unsigned w1 = 0;
145          if (this->showIndex)
146          {
147                // number of characters used by index
148             linesize += this->idxDigits + this->indexSep.length();
149             if (this->showBaseIndex)
150                linesize += 2; // "0x"
151          }
152             // 2 characters per byte for data
153          linesize += bytesThisLine * 2;
154          if (this->showBaseData)
155          {
156                // 2 characters per group 1 for base/radix "0x"
157             linesize += (bytesThisLine / this->groupBy) * 2;
158                // extra radix and groupSep for incomplete group
159             if (bytesThisLine % this->groupBy)
160             {
161                linesize += 2;
162                w1++;
163             }
164          }
165          if (this->group2By)
166          {
167             w2 += ((bytesThisLine / this->group2By) -
168                       // no group 2 separator at the end of the line
169                    ((bytesThisLine % this->group2By) == 0 ? 1 : 0));
170          }
171          if (this->groupBy)
172          {
173                // number of group 1's minus the number of group 2
174                // separators already computed and -1 for no separator
175                // at the end of the line
176             w1 += (bytesThisLine / this->groupBy) - w2 - 1;
177          }
178          if (this->groupBy > 0)
179          {
180                // characters of white space between level 1 grouped data
181             linesize += this->groupSep.length() * w1;
182          }
183          if (this->group2By > 0)
184          {
185                // characters of white space between level 2 grouped data
186             linesize += this->group2Sep.length() * w2;
187          }
188          if (lastLine)
189             linesize += this->dataFinal.length();
190          else
191             linesize += this->dataEndSep.length();
192          return linesize;
193       }
194 
195 
196       std::string HexDumpDataConfig ::
baseIndex() const197       baseIndex()
198          const
199       {
200          if (showBaseIndex && hexIndex)
201          {
202             return (upperHex ? "0X" : "0x");
203          }
204          return "";
205       }
206 
207 
208       std::string HexDumpDataConfig ::
baseData() const209       baseData()
210          const
211       {
212          if (showBaseData)
213          {
214             return (upperHex ? "0X" : "0x");
215          }
216          return "";
217       }
218    } // namespace StringUtils
219 } // namespace gpstk
220