Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 7211 in orxonox.OLD for branches/std/src/lib/util/substring.cc


Ignore:
Timestamp:
Mar 10, 2006, 4:52:21 AM (18 years ago)
Author:
bensch
Message:

orxonox/trunk: new SubString class

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/std/src/lib/util/substring.cc

    r5656 r7211  
    2424#include "substring.h"
    2525
    26 #include "debug.h"
    2726#include <string.h>
    28 #include <assert.h>
    29 
    30 SubString::SubString( const char* string, char splitter)
    31 {
    32   this->splittersCount = 0;
    33   if (string == NULL)
    34   {
    35     this->strings = NULL;
    36     this->offsets = NULL;
    37     return;
    38   }
    39 
    40   for( int i = 0; i < strlen(string); i++)
    41     if( string[i] == splitter)
    42       this->splittersCount++;
    43 
    44   this->splittersCount += 1;
    45 
    46   this->strings = new char*[this->splittersCount];
    47   this->offsets = new unsigned int[this->splittersCount];
    48   assert (this->strings != NULL && this->offsets != NULL);
    49 
    50   int i = 0;
    51   int l = 0;
    52 
    53   if( this->splittersCount > 1)
    54   {
    55     const char* offset = string;
    56     const char* end = strchr( string, splitter);
    57     while( end != NULL)
    58     {
    59       assert( i < this->splittersCount);
    60       l = end - offset;
    61       this->strings[i] = new char[l + 1];
    62       assert( strings[i] != NULL);
    63       strncpy( strings[i], offset, l);
    64       strings[i][l] = '\0';
    65       this->offsets[i] = offset - string;
    66       i++;
    67       end++;
    68       offset = end;
    69       end = strchr( offset, splitter);
    70     }
    71 
    72     l = strlen( offset);
    73     strings[i] = new char[l + 1];
    74     strncpy( strings[i], offset, l);
    75     strings[i][l] = '\0';
    76     this->offsets[i] = offset - string;
    77   }
    78   else
    79   {
    80     this->strings[0] = new char[strlen(string)+1];
    81     strcpy(this->strings[0], string);
    82     this->offsets[0] = 0;
    83   }
     27#include <cassert>
     28
     29SubString::SubString(const std::string& string, char splitter)
     30{
     31  char split[2];
     32  split[0] = splitter;
     33  split[1] = '\0';
     34  SubString::splitLine(this->strings, this->offsets,
     35                       string, split);
    8436}
    8537
     
    9143 *
    9244 */
    93 SubString::SubString(const char* string, bool whiteSpaces)
    94 {
    95   this->splittersCount = 0;
    96   if (string == NULL || whiteSpaces == false)
     45SubString::SubString(const std::string& string, bool whiteSpaces)
     46{
     47  SubString::splitLine(this->strings, this->offsets,
     48                      string);
     49}
     50
     51SubString::SubString(const std::string& string, const std::string& splitters, char escapeChar,char safemode_char, char comment_char)
     52{
     53  SubString::splitLine(this->strings, this->offsets,
     54                       string, splitters, escapeChar, safemode_char);
     55}
     56
     57
     58/**
     59 * splits line into tokens and stores them in ret. Supports delimiters, escape characters,
     60 * ignores special  characters between safemode_char and between comment_char and linend '\n'.
     61 *
     62 * @returns SPLIT_LINE_STATE the parser was in when returning
     63 */
     64SPLIT_LINE_STATE SubString::splitLine(std::vector<std::string>& ret, std::vector<unsigned int>& offsets,
     65                                      const std::string& line, const std::string& delimiters,
     66                                      char escape_char, char safemode_char, char comment_char,
     67                                      SPLIT_LINE_STATE start_state)
     68{
     69  SPLIT_LINE_STATE state = start_state;
     70  unsigned int i = 0;
     71  std::string token;
     72
     73  if(start_state != SL_NORMAL && ret.size() > 0)
    9774  {
    98     this->strings = NULL;
    99     this->offsets = NULL;
    100     return;
     75    token = ret[ret.size()-1];
     76    ret.pop_back();
    10177  }
    10278
    103   // chop the input to the beginning of something usefull
    104   if (strlen(string) > 0)
    105     string = string + strspn(string, " \t\n");
    106 
    107   // count the Splitters
    108   bool lastWasWhiteSpace = false;
    109   for(unsigned int i = 0; i < strlen(string); i++)
    110     if( string[i] == ' ' || string[i] == '\t' || string[i] == '\n' )
    111       lastWasWhiteSpace = true;
    112     else
     79  while(i < line.size())
     80  {
     81    switch(state)
    11382    {
    114       if (lastWasWhiteSpace)
    115         this->splittersCount ++;
    116       lastWasWhiteSpace = false;
     83    case SL_NORMAL:
     84      if(line[i] == escape_char)
     85      {
     86        state = SL_ESCAPE;
     87      }
     88      else if(line[i] == safemode_char)
     89      {
     90        state = SL_SAFEMODE;
     91      }
     92      else if(line[i] == comment_char)
     93      {
     94        /// FINISH
     95        if(token.size() > 0)
     96        {
     97          ret.push_back(token);
     98          offsets.push_back(i);
     99          token.clear();
     100        }
     101        token += line[i];       // EAT
     102        state = SL_COMMENT;
     103      }
     104      else if(delimiters.find(line[i]) != std::string::npos)
     105      {
     106        // line[i] is a delimiter
     107        /// FINISH
     108        if(token.size() > 0)
     109        {
     110          ret.push_back(token);
     111          offsets.push_back(i);
     112          token.clear();
     113        }
     114      }
     115      else
     116      {
     117        token += line[i];       // EAT
     118      }
     119      break;
     120    case SL_ESCAPE:
     121      if(line[i] == 'n') token += '\n';
     122      else if(line[i] == 't') token += '\t';
     123      else if(line[i] == 'v') token += '\v';
     124      else if(line[i] == 'b') token += '\b';
     125      else if(line[i] == 'r') token += '\r';
     126      else if(line[i] == 'f') token += '\f';
     127      else if(line[i] == 'a') token += '\a';
     128      else if(line[i] == '?') token += '\?';
     129      else token += line[i];  // EAT
     130      state = SL_NORMAL;
     131      break;
     132    case SL_SAFEMODE:
     133      if(line[i] == safemode_char)
     134      {
     135        state = SL_NORMAL;
     136      }
     137      else if(line[i] == escape_char)
     138      {
     139        state = SL_SAFEESCAPE;
     140      }
     141      else
     142      {
     143        token += line[i];       // EAT
     144      }
     145      break;
     146    case SL_SAFEESCAPE:
     147      if(line[i] == 'n') token += '\n';
     148      else if(line[i] == 't') token += '\t';
     149      else if(line[i] == 'v') token += '\v';
     150      else if(line[i] == 'b') token += '\b';
     151      else if(line[i] == 'r') token += '\r';
     152      else if(line[i] == 'f') token += '\f';
     153      else if(line[i] == 'a') token += '\a';
     154      else if(line[i] == '?') token += '\?';
     155      else token += line[i];  // EAT
     156      state = SL_SAFEMODE;
     157      break;
     158    case SL_COMMENT:
     159      if(line[i] == '\n')
     160      {
     161        /// FINISH
     162        if(token.size() > 0)
     163        {
     164          ret.push_back(token);
     165          offsets.push_back(i);
     166          token.clear();
     167        }
     168        state = SL_NORMAL;
     169      }
     170      else
     171      {
     172        token += line[i];       // EAT
     173      }
     174      break;
     175    default:
     176      // nothing
     177      break;
    117178    }
    118   this->splittersCount += 1;
    119 
    120   // allocate memory
    121   this->strings = new char*[this->splittersCount];
    122   this->offsets = new unsigned int[this->splittersCount];
    123   assert (this->strings != NULL && this->offsets != NULL);
    124 
    125 
    126   // split the String into substrings
    127   int l = 0;
    128   unsigned int i = 0;
    129   if( this->splittersCount > 1)
     179    i++;
     180  }
     181
     182  /// FINISH
     183  if(token.size() > 0)
    130184  {
    131     const char* offset = string;
    132     const char* end = offset + strcspn(offset, " \t\n");
    133     for (i = 0; i < this->splittersCount; i++)
    134     {
    135       assert( i < this->splittersCount);
    136       l = end - offset;
    137       this->strings[i] = new char[l + 1];
    138       assert( strings[i] != NULL);
    139       strncpy( strings[i], offset, l);
    140       strings[i][l] = '\0';
    141       this->offsets[i] = offset - string;
    142       end += strspn(end, " \t\n");
    143       offset = end;
    144       end = offset + strcspn(offset, " \t\n");
    145     }
     185    ret.push_back(token);
     186    offsets.push_back(i);
     187    token.clear();
    146188  }
    147   else
    148   {
    149     unsigned int length = strcspn(string, " \t\n");
    150     this->strings[0] = new char[length+1];
    151     strncpy(this->strings[0], string, length);
    152     this->strings[0][length] = '\0';
    153     offsets[0] = 0;
    154   }
    155 }
    156 
    157 SubString::SubString(const char* string, const char* splitters, char escapeChar)
    158 {
    159   this->splittersCount = 0;
    160   if (string == NULL || splitters == NULL)
    161   {
    162     this->strings = NULL;
    163     this->offsets = NULL;
    164     return;
    165   }
    166 
    167   // chop the input to the beginning of something usefull
    168   if (strlen(string) > 0)
    169     string = string + strspn(string, splitters);
    170 
    171   // count the Splitters
    172   bool lastWasSplitter = false;
    173   for(unsigned int i = 0; i < strlen(string); i++)
    174   {
    175 
    176     if( strchr(splitters, string[i] ))
    177       lastWasSplitter = true;
    178     else
    179     {
    180       if (lastWasSplitter)
    181       {
    182         this->splittersCount ++;
    183         lastWasSplitter = false;
    184       }
    185     }
    186   }
    187   this->splittersCount += 1;
    188 
    189   // allocate memory
    190   this->strings = new char*[this->splittersCount];
    191   this->offsets = new unsigned int[this->splittersCount];
    192   assert (this->strings != NULL && this->offsets != NULL);
    193 
    194 
    195   // split the String into substrings
    196   int l = 0;
    197   unsigned int i = 0;
    198   if( this->splittersCount > 1)
    199   {
    200     const char* offset = string;
    201     const char* end = offset + strcspn(offset, splitters);
    202     for (i = 0; i < this->splittersCount; i++)
    203     {
    204       assert( i < this->splittersCount);
    205       l = end - offset;
    206       this->strings[i] = new char[l + 1];
    207       assert( strings[i] != NULL);
    208       strncpy( strings[i], offset, l);
    209       strings[i][l] = '\0';
    210       this->offsets[i] = offset - string;
    211       end += strspn(end, splitters);
    212       offset = end;
    213       end = offset + strcspn(offset, splitters);
    214     }
    215   }
    216   else
    217   {
    218     unsigned int length = strcspn(string, splitters);
    219     this->strings[0] = new char[length+1];
    220     strncpy(this->strings[0], string, length);
    221     this->strings[0][length] = '\0';
    222     offsets[0] = 0;
    223   }
    224 }
    225 
     189  return(state);
     190}
    226191
    227192/**
     
    229194*/
    230195SubString::~SubString()
    231 {
    232   if (this->strings)
    233   {
    234     for(unsigned int i = 0; i < this->splittersCount; i++)
    235       delete[] this->strings[i];
    236     delete[] this->strings;
    237   }
    238   delete[] this->offsets;
    239 }
    240 
    241 /**
    242  *  get a particular substring
    243  * @param i the ID of the substring to return
    244  * @returns the designated substring or NULL if an invalid ID was given
    245 */
    246 const char* SubString::getString(unsigned int i)
    247 {
    248   if( i < this->splittersCount && i >= 0)
    249     return this->strings[i];
    250   else
    251     return NULL;
    252 }
     196{ }
    253197
    254198/**
     
    259203unsigned int SubString::getOffset(unsigned int i)
    260204{
    261   if( i < this->splittersCount && i >= 0)
     205  if( i < this->offsets.size() && i >= 0)
    262206    return this->offsets[i];
    263207  else
     
    270214void SubString::debug() const
    271215{
    272   PRINT(0)("Substring-information::count=%d ::", this->splittersCount);
    273   if (this->strings != NULL)
    274     for (unsigned int i = 0; i < this->splittersCount; i++)
    275      PRINT(0)("s%d='%s'::", i, this->strings[i]);
    276   PRINT(0)("\n");
    277 }
     216  printf("Substring-information::count=%d ::", this->strings.size());
     217  for (unsigned int i = 0; i < this->strings.size(); i++)
     218    printf("s%d='%s'::", i, this->strings[i].c_str());
     219  printf("\n");
     220}
Note: See TracChangeset for help on using the changeset viewer.