Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

BroString.cc

Go to the documentation of this file.
00001 // $Id: BroString.cc,v 1.1 2004/07/14 20:15:40 jason Exp $
00002 //
00003 // Copyright (c) 1997, 1998, 1999, 2002, 2003
00004 //      The Regents of the University of California.  All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that: (1) source code distributions
00008 // retain the above copyright notice and this paragraph in its entirety, (2)
00009 // distributions including binary code include the above copyright notice and
00010 // this paragraph in its entirety in the documentation or other materials
00011 // provided with the distribution, and (3) all advertising materials mentioning
00012 // features or use of this software display the following acknowledgement:
00013 // ``This product includes software developed by the University of California,
00014 // Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
00015 // the University nor the names of its contributors may be used to endorse
00016 // or promote products derived from this software without specific prior
00017 // written permission.
00018 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
00019 // WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00020 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022 #include "config.h"
00023 
00024 #include <ctype.h>
00025 
00026 #include "BroString.h"
00027 
00028 // This constructor forces the user to specify arg_final_NUL.  When str
00029 // is a *normal* NUL-terminated string, make arg_n == strlen(str) and
00030 // arg_final_NUL == 1; when str is a sequence of n bytes, make
00031 // arg_final_NUL == 0.
00032 
00033 BroString::BroString(int arg_final_NUL, byte_vec str, int arg_n)
00034         {
00035         b = str;
00036         n = arg_n;
00037         final_NUL = arg_final_NUL;
00038         use_free_to_delete = 0;
00039         }
00040 
00041 BroString::BroString(const u_char* str, int arg_n, int add_NUL)
00042         {
00043         n = arg_n;
00044         b = new u_char[add_NUL ? n + 1 : n];
00045         memcpy(b, str, n);
00046 
00047         if ( add_NUL )
00048                 {
00049                 b[n] = 0;
00050                 final_NUL = 1;
00051                 }
00052         else
00053                 final_NUL = 0;
00054 
00055         use_free_to_delete = 0;
00056         }
00057 
00058 BroString::BroString(const char* str)
00059         {
00060         n = strlen(str);
00061         b = new u_char[n+1];
00062         memcpy(b, str, n+1);
00063         final_NUL = 1;
00064         use_free_to_delete = 0;
00065         }
00066 
00067 const char* BroString::CheckString() const
00068         {
00069         if ( n == 0 )
00070                 return "";
00071 
00072         if ( memchr(b, '\0', n + final_NUL) != &b[n] )
00073                 {
00074                 // Either an embedded NUL, or no final NUL.
00075                 char* exp_s = ExpandedString();
00076                 if ( b[n-1] != '\0' )
00077                         run_time("string without NUL terminator: \"%s\"", exp_s);
00078                 else
00079                         run_time("string with embedded NUL: \"%s\"", exp_s);
00080 
00081                 delete [] exp_s;
00082                 return "<string-with-NUL>";
00083                 }
00084 
00085         return (const char*) b;
00086         }
00087 
00088 char* BroString::ExpandedString(int format) const
00089         {
00090         // Maxmimum character expansion is as \xHH, so a factor of 4.
00091         char* s = new char[n*4 + 1];    // +1 is for final '\0'
00092         char* sp = s;
00093         for ( int i = 0; i < n; ++i )
00094                 {
00095                 if ( b[i] == '\0' && format == EXPANDED_STRING )
00096                         {
00097                         // Note, generating "\0" for BRO_STRING_LITERAL
00098                         // would cause ambiguity in cases like "\021".
00099                         *sp++ = '\\'; *sp++ = '0';
00100                         }
00101 
00102                 else if ( b[i] == '\x7f' && format == EXPANDED_STRING )
00103                         {
00104                         *sp++ = '^'; *sp++ = '?';
00105                         }
00106 
00107                 else if ( b[i] <= 26 && format == EXPANDED_STRING )
00108                         {
00109                         *sp++ = '^'; *sp++ = b[i] + 'A' - 1;
00110                         }
00111 
00112                 else if ( (b[i] == '\\' || b[i] == '"') &&
00113                           format == BRO_STRING_LITERAL )
00114                         {
00115                         *sp++ = '\\'; *sp++ = b[i];
00116                         }
00117 
00118                 else if ( b[i] >= ' ' && b[i] < 127 )
00119                         *sp++ = b[i];
00120 
00121                 else
00122                         {
00123                         char hex_fmt[16];
00124 
00125                         *sp++ = '\\'; *sp++ = 'x';
00126                         sprintf(hex_fmt, "%02x", b[i]);
00127                         *sp++ = hex_fmt[0]; *sp++ = hex_fmt[1];
00128                         }
00129                 }
00130 
00131         *sp = '\0';     // NUL-terminate.
00132 
00133         return s;
00134         }
00135 
00136 void BroString::ToUpper()
00137         {
00138         for ( int i = 0; i < n; ++i )
00139                 if ( islower(b[i]) )
00140                         b[i] = toupper(b[i]);
00141         }
00142 
00143 int Bstr_eq(const BroString* s1, const BroString* s2)
00144         {
00145         if ( s1->Len() != s2->Len() )
00146                 return 0;
00147 
00148         return memcmp(s1->Bytes(), s2->Bytes(), s1->Len()) == 0;
00149         }
00150 
00151 int Bstr_cmp(const BroString* s1, const BroString* s2)
00152         {
00153         int n = min(s1->Len(), s2->Len());
00154         int cmp = memcmp(s1->Bytes(), s2->Bytes(), n);
00155 
00156         if ( cmp || s1->Len() == s2->Len() )
00157                 return cmp;
00158 
00159         // Compared equal, but one was shorter than the other.  Treat
00160         // it as less than the other.
00161         if ( s1->Len() < s2->Len() )
00162                 return -1;
00163         else
00164                 return 1;
00165         }
00166 
00167 BroString* concatenate(std::vector<data_chunk_t>& v)
00168         {
00169         int n = v.size();
00170         int len = 0;
00171         int i;
00172         for ( i = 0; i < n; ++i )
00173                 len += v[i].length;
00174 
00175         char* data = new char[len+1];
00176 
00177         char* b = data;
00178         for ( i = 0; i < n; ++i )
00179                 {
00180                 memcpy(b, v[i].data, v[i].length);
00181                 b += v[i].length;
00182                 }
00183 
00184         *b = '\0';
00185 
00186         return new BroString(1, (byte_vec) data, len);
00187         }
00188 
00189 BroString* concatenate(std::vector<const BroString*>& v)
00190         {
00191         int n = v.size();
00192         int len = 0;
00193         int i;
00194         for ( i = 0; i < n; ++i )
00195                 len += v[i]->Len();
00196 
00197         char* data = new char[len+1];
00198 
00199         char* b = data;
00200         for ( i = 0; i < n; ++i )
00201                 {
00202                 memcpy(b, v[i]->Bytes(), v[i]->Len());
00203                 b += v[i]->Len();
00204                 }
00205         *b = '\0';
00206 
00207         return new BroString(1, (byte_vec) data, len);
00208         }
00209 
00210 void delete_strings(std::vector<const BroString*>& v)
00211         {
00212         for ( unsigned int i = 0; i < v.size(); ++i )
00213                 delete v[i];
00214         v.clear();
00215         }
00216 

Generated on Wed Sep 14 02:55:58 2005 for bro_docs by doxygen 1.3.5