XrdOucString.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                     X r d O u c S t r i n g . h h                          */
00004 /*                                                                            */
00005 /* (c) 2005 F. Furano (INFN Padova), G. Ganis (CERN)                          */
00006 /*     All Rights Reserved. See XrdInfo.cc for complete License Terms         */
00007 /******************************************************************************/
00008 
00009 //         $Id: XrdOucString.cc 31975 2010-01-07 14:38:29Z ganis $
00010 
00011 const char *XrdOucStringCVSID = "$Id: XrdOucString.cc 31975 2010-01-07 14:38:29Z ganis $";
00012 
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <climits>
00016 
00017 #include <XrdOuc/XrdOucString.hh>
00018 
00019 /******************************************************************************/
00020 /*                                                                            */
00021 /*  Light string manipulation class                                           */
00022 /*                                                                            */
00023 /******************************************************************************/
00024 
00025 #define kMAXINT64LEN   25
00026 
00027 #if !defined(WINDOWS)
00028 //
00029 // Macro for 'form'-like operations
00030 #define XOSINTFORM(f,b) \
00031    int buf_len = 256; \
00032    va_list ap; \
00033    va_start(ap, f); \
00034 again: \
00035    b = (char *)realloc(b, buf_len); \
00036    int n = vsnprintf(b, buf_len, f, ap); \
00037    if (n == -1 || n >= buf_len) { \
00038       if (n == -1) \
00039          buf_len *= 2; \
00040       else \
00041          buf_len = n+1; \
00042       va_end(ap); \
00043       va_start(ap, f); \
00044       goto again; \
00045    } \
00046    va_end(ap);
00047 // End-Of-Macro for 'form'-like operations
00048 #endif
00049 
00050 // Default blksize for (re-)allocations; active if > 0.
00051 // Use XrdOucString::setblksize() to activate
00052 int XrdOucString::blksize = -1;
00053 
00054 //________________________________________________________________________
00055 int XrdOucString::adjust(int ls, int &j, int &k, int nmx)
00056 {
00057    // Check indeces and return effective length
00058    // If nmx > 0, indecs are adjusted to get the effective length
00059    // smaller than nmx.
00060 
00061    // Check range for beginning
00062    j = (j < 0) ? 0 : j;
00063    // Check range for end 
00064    k   = (k == -1 || k > (ls-1)) ? (ls-1) : k; 
00065    // The new length
00066    int nlen = k - j + 1;
00067    nlen = (nlen > 0) ? nlen : 0;
00068    // Check max, if required
00069    if (nmx > 0 && nmx < nlen) {
00070       k = j + 1 + nmx;
00071       nlen = nmx;
00072    }
00073    // We are done   
00074    return nlen;
00075 }
00076 
00077 //________________________________________________________________________
00078 char *XrdOucString::bufalloc(int nsz)
00079 {
00080    // Makes sure that the internal capacity is enough to contain
00081    // 'nsz' bytes (including the null-termination).
00082    // Buffer is allocated if not yet existing or reallocated if
00083    // necessary.
00084    // If 'nsz' is negative or null, existing buffer is freed, if any
00085    // Returns pointer to buffer.
00086 
00087    char *nstr = 0;
00088 
00089    // New size must be positive; if not, cleanup
00090    if (nsz <= 0) {
00091       if (str) free(str);
00092       init();
00093       return nstr;
00094    }
00095 
00096    int sz = nsz;
00097    // Check the blksize option is activated
00098    if (blksize > 1) {
00099       int blks = nsz / blksize;
00100       sz = (blks+1) * blksize;
00101    }
00102 
00103    // Resize, if different from what we have
00104    if (sz != siz) {
00105       if ((nstr = (char *)realloc(str, sz)))
00106          siz = sz;
00107    } else
00108       // Do nothing
00109       nstr = str;
00110 
00111    // We are done
00112    return nstr;
00113 }
00114 
00115 //___________________________________________________________________________
00116 XrdOucString::XrdOucString(const char c, int ls)
00117 {
00118    // Constructor
00119    // Create space to store char c as a null-terminated string.
00120    // If ls > 0 create space for ls+1 bytes.
00121 
00122    init();
00123 
00124    // If required, allocate the buffer to the requested size
00125    if (ls > 0)
00126       str = bufalloc(ls+1);
00127    else
00128       str = bufalloc(2);
00129    if (str) {
00130       str[0] = c;
00131       str[1] = 0;
00132       len = 1;
00133    }
00134 }
00135 
00136 //___________________________________________________________________________
00137 XrdOucString::XrdOucString(const char *s, int ls)
00138 {
00139    // Constructor
00140    // Create space to store the null terminated string s.
00141    // If ls > 0 create space for ls+1 bytes, store the first
00142    // ls bytes of s (truncating, if needed), and null-terminate.
00143    // This is useful to import non null-terminated string buffers
00144    // of known length.
00145 
00146    init();
00147 
00148    // If required, allocate the buffer to the requested size
00149    if (ls > 0)
00150       str = bufalloc(ls+1);
00151    int lr = s ? strlen(s) : 0;
00152    if (lr >= 0)
00153       assign(s,0,ls-1);
00154 }
00155 
00156 //___________________________________________________________________________
00157 XrdOucString::XrdOucString(const XrdOucString &s)
00158 {
00159    // Copy constructor
00160 
00161    init();
00162    assign(s.c_str(),0,-1);
00163 }
00164 
00165 //______________________________________________________________________________
00166 XrdOucString::XrdOucString(const XrdOucString &s, int j, int k, int ls)
00167 {
00168    // Copy constructor (portion of string s: from j to k, inclusive)
00169 
00170    init();
00171    // If required, allocate the buffer to the requested size
00172    if (ls > 0)
00173       str = bufalloc(ls+1);
00174 
00175    int lr = s.length();
00176    if (lr > 0) {
00177       // Adjust range (to fit in the allocated buffer, if any)
00178       if (adjust(lr, j, k, ls) > 0) 
00179          // assign the string portion
00180          assign(s.c_str(),j,k);
00181    }
00182 }
00183 
00184 //___________________________________________________________________________
00185 XrdOucString::~XrdOucString()
00186 {
00187    // Destructor
00188 
00189    if (str) free(str);
00190 }
00191 
00192 //___________________________________________________________________________
00193 void XrdOucString::setbuffer(char *buf)
00194 {
00195    // Adopt buffer 'buf'
00196 
00197    if (str) free(str);
00198    init();
00199    if (buf) {
00200       str = buf;
00201       len = strlen(buf);
00202       siz = len + 1;
00203       str = (char *)realloc(str, siz);
00204    }
00205 }
00206 
00207 #if !defined(WINDOWS)
00208 //______________________________________________________________________________
00209 int XrdOucString::form(const char *fmt, ...)
00210 {
00211    // Recreate the string according to 'fmt' and the arguments
00212    // Return -1 in case of failure, or the new length.
00213 
00214    // Decode the arguments
00215    XOSINTFORM(fmt, str);
00216    siz = buf_len;
00217 
00218    // Re-adjust the length
00219    len = strlen(str);
00220    str = bufalloc(len+1);
00221 
00222    // Return the new length (in n)
00223    return n;
00224 }
00225 
00226 //______________________________________________________________________________
00227 int XrdOucString::form(XrdOucString &str, const char *fmt, ...)
00228 {
00229    // Format a string in 'str' according to 'fmt' and the arguments
00230 
00231    // Decode the arguments
00232    char *buf = 0;
00233    XOSINTFORM(fmt, buf);
00234 
00235    // Adopt the new formatted buffer in the string
00236    str.setbuffer(buf);
00237 
00238    // Done
00239    return n;
00240 }
00241 #endif
00242 
00243 //______________________________________________________________________________
00244 int XrdOucString::find(const char c, int start, bool forward)
00245 {
00246    // Find index of first occurence of char c starting from position start
00247    // Return index if found, STR_NPOS if not.
00248 
00249    int rc = STR_NPOS;
00250 
00251    // STR_NPOS indicates start from the end
00252    if (start == STR_NPOS)
00253       start = len - 1;
00254 
00255    // Make sure start makes sense
00256    if (start < 0 || start > (len-1))
00257       return rc;
00258 
00259    // Now loop
00260    int i = start;
00261    if (forward) {
00262       // forward search
00263       for (; i < len; i++) {
00264          if (str[i] == c)
00265             return i;
00266       }
00267    } else {
00268       // backward search
00269       for (; i >= 0; i--) {
00270          if (str[i] == c)
00271             return i;
00272       }
00273    }
00274 
00275    // Nothing found
00276    return rc;
00277 }
00278 
00279 //______________________________________________________________________________
00280 int XrdOucString::find(XrdOucString s, int start)
00281 {
00282    // Find index of first occurence of string s, starting
00283    // from position start.
00284    // Return index if found, STR_NPOS if not.
00285 
00286    return find((const char *)s.c_str(),start);
00287 }
00288 
00289 //______________________________________________________________________________
00290 int XrdOucString::find(const char *s, int start)
00291 {
00292    // Find index of first occurence of null-terminated string s, starting
00293    // from position start.
00294    // Return index if found, STR_NPOS if not.
00295 
00296    int rc = STR_NPOS;
00297 
00298    // Make sure start makes sense
00299    if (start < 0 || start > (len-1))
00300       return rc;
00301 
00302    // Make sure the string is defined
00303    if (!s)
00304       return rc;
00305 
00306    // length of substring
00307    int ls = strlen(s);
00308 
00309    // if only one meaningful char, use dedicated method
00310    if (ls == 1)
00311       return find(s[0],start); 
00312 
00313    // Make sure that it can fit
00314    if (ls > (len-start))
00315       return rc;
00316 
00317    // Now loop
00318    int i = start;
00319    for (; i < len; i++) {
00320       if (str[i] == s[0])
00321          if (!strncmp(str+i+1,s+1,ls-1))
00322             return i;
00323    }
00324 
00325    // Nothing found
00326    return rc;
00327 }
00328 
00329 //______________________________________________________________________________
00330 int XrdOucString::rfind(XrdOucString s, int start)
00331 {
00332    // Find index of first occurence of string s in backward
00333    // direction starting from position start.
00334    // If start == STR_NPOS, search starts from end of string (default).
00335    // Return index if found, STR_NPOS if not.
00336 
00337    return rfind(s.c_str(),start);
00338 }
00339 
00340 //______________________________________________________________________________
00341 int XrdOucString::rfind(const char *s, int start)
00342 {
00343    // Find index of first occurence of null-terminated string s in 
00344    // backwards direction starting from position start.
00345    // If start == STR_NPOS, search starts from end of string (default).
00346    // Return index if found, STR_NPOS if not.
00347 
00348    int rc = STR_NPOS;
00349 
00350    // STR_NPOS indicates start from the end
00351    if (start == STR_NPOS)
00352       start = len - 1;
00353 
00354    // Make sure start makes sense
00355    if (start < 0 || start > (len-1))
00356       return rc;
00357 
00358    // Make sure the string is defined
00359    if (!s)
00360       return rc;
00361 
00362    // length of substring
00363    int ls = strlen(s);
00364 
00365    // if only one meaningful char, use dedicated method
00366    if (ls == 1)
00367       return find(s[0],start,0); 
00368 
00369    // Make sure that it can fit
00370    if (ls > len)
00371       return rc;
00372 
00373    // Start from the first meaningful position 
00374    if (ls > (len-start))
00375       start = len-ls;
00376 
00377    // Now loop
00378    int i = start;
00379    for (; i >= 0; i--) {
00380       if (str[i] == s[0])
00381          if (!strncmp(str+i+1,s+1,ls-1))
00382             return i;
00383    }
00384 
00385    // Nothing found
00386    return rc;
00387 }
00388 
00389 //______________________________________________________________________________
00390 bool XrdOucString::endswith(char c) 
00391 {
00392    // returns 1 if the stored string ends with string s
00393 
00394    return (rfind(c) == (int)(len-1));
00395 }
00396 
00397 //______________________________________________________________________________
00398 bool XrdOucString::endswith(const char *s) 
00399 {
00400    // returns 1 if the stored string ends with string s
00401 
00402    return (s ? (rfind(s) == (int)(len-strlen(s))) : 0);
00403 }
00404 
00405 //___________________________________________________________________________
00406 int XrdOucString::matches(const char *s, char wch)
00407 {
00408    // Check if local string is compatible with 's' which may
00409    // contain wild char wch (default: '*'). For example, if local string
00410    // is 'mouse.at.home' the match will be true for 'mouse.*',
00411    // and false for 'mouse.*.cinema' .
00412    // If does not contain wild characters, this is just a comparison
00413    // based on strncmp.
00414    // Returns the number of characters matching or 0.
00415 
00416    // Make sure s is defined and we have a local string
00417    if (!s || !str)
00418       return 0;
00419 
00420    // string size
00421    int ls = strlen(s);
00422 
00423    // If no wild card, just make a simple strcmp comparison
00424    if (!strchr(s,wch)) {
00425       if (!strcmp(str,s))
00426          return ls;
00427       else
00428          return 0;
00429    }
00430 
00431    // If s == wch the match is always true
00432    if (ls == 1)
00433       return 1;
00434 
00435    int rc = 1;
00436    // Starting position for the check
00437    int cs = 0;
00438 
00439    // token delimiters and size
00440    int tb = 0;                  // begin
00441    char *ps = (char *)strchr(s+tb,wch);
00442    bool next = 1;
00443    while (next) {
00444 
00445       // token end
00446       int te = ps ? (ps - s) : ls;
00447       // token size
00448       int ts = te - tb;
00449 
00450       if (ts) {
00451          bool found = 0;
00452          while (cs < len) {
00453             if (!strncmp(str+cs,s+tb,ts)) {
00454                cs += ts;
00455                found = 1;
00456                break;
00457             }
00458             cs++;
00459          }
00460          if (!found) {
00461             rc = 0;
00462             break;
00463          }
00464       }
00465       // next token begin, if any
00466       tb = te + 1;
00467       ps = (tb < ls) ? (char *)strchr(s+tb, wch) : 0;
00468       next = (ps || (tb < ls)) ? 1 : 0;
00469    }
00470 
00471    // If s does not end with a wild card
00472    // make sure that everything has been checked
00473    if (s[ls-1] != wch && cs < len)
00474       rc = 0;
00475 
00476    // The number of chars matching is the number of chars in s
00477    // which are not '*'
00478    int nm = 0;
00479    if (rc > 0) {
00480       nm = ls;
00481       int n = ls;
00482       while (n--) {
00483          if (s[n] == wch) nm--;
00484       }
00485    }
00486 
00487    return nm;
00488 }
00489 
00490 //______________________________________________________________________________
00491 void XrdOucString::assign(const char *s, int j, int k)
00492 {
00493    // Assign portion of buffer s to local string.
00494    // For k == -1 assign all string starting from position j (inclusive).
00495    // Use j == 0 and k == -1 to assign the full string.
00496 
00497    int ls = s ? strlen(s) : 0;
00498    if (!s) {
00499       // We are passed an empty string
00500       if (str) {
00501          // empty the local string, leaving capacity as it is
00502          str[0] = 0;
00503          len = 0;
00504       }
00505    } else {
00506       // Adjust range and get length of portion to copy
00507       int nlen = adjust(ls, j, k);
00508       // Resize, if needed
00509       if (nlen > (siz-1)) 
00510          str = bufalloc(nlen+1);
00511       if (str) {
00512          if (nlen > 0) {
00513             strncpy(str,s+j,nlen);
00514             str[nlen] = 0;
00515             len = nlen;
00516          } else {
00517             // empty the local string, leaving capacity as it is
00518             str[0] = 0;
00519             len = 0;
00520          }
00521       } 
00522    }
00523 }
00524 
00525 //______________________________________________________________________________
00526 void XrdOucString::assign(const XrdOucString s, int j, int k)
00527 {
00528    // Assign portion of buffer s to local string.
00529 
00530    assign(s.c_str(),j,k);
00531 }
00532 
00533 //___________________________________________________________________________
00534 int XrdOucString::keep(int start, int size)
00535 {
00536    // Keep size bytes starting from position start
00537    // If size == 0, keep any bytes from start on.
00538    // Return number of bytes kept ( <=size )
00539 
00540    int rc = 0;
00541 
00542    // Make sure start makes sense
00543    int st = start;
00544    if (st < 0 || st > (len-1))
00545       return rc;
00546 
00547    // Make sure size makes sense
00548    if (size < 0)
00549       return rc;
00550    int nlen = 0;
00551    if (size == 0) {
00552       nlen = len - st;
00553    } else {
00554       nlen = (size > (len - st)) ? (len - st) : size;
00555    }
00556 
00557    // Do nothing if all the bytes requested
00558    if (nlen >= len)
00559       return len;
00560 
00561    // Allocated new string
00562    if (nlen > (siz-1))
00563       str = bufalloc(nlen+1);
00564    if (str) {
00565       // Copy the bytes
00566       memmove(str,str+st,nlen);
00567       // Null terminate
00568       str[nlen] = 0;
00569       // Assign new string   
00570       len = nlen;
00571       // Return number of bytes kept
00572       return nlen;
00573    } else
00574       return rc;
00575 }
00576 
00577 //___________________________________________________________________________
00578 void XrdOucString::append(const char *s)
00579 {
00580    // Append string pointed by s to local string.
00581    // Memory is reallocated.
00582 
00583    return insert(s);
00584 }
00585 
00586 //___________________________________________________________________________
00587 void XrdOucString::append(const XrdOucString s)
00588 {
00589    // Append string s to local string.
00590    // Memory is reallocated.
00591 
00592    return insert(s);
00593 }
00594 
00595 //___________________________________________________________________________
00596 void XrdOucString::append(const char c)
00597 {
00598    // Append char c to local string.
00599    // Memory is reallocated.
00600 
00601    return insert(c);
00602 }
00603 
00604 //___________________________________________________________________________
00605 void XrdOucString::append(const int i)
00606 {
00607    // Append string representing integer i to local string.
00608 
00609    return insert(i);
00610 }
00611 
00612 //___________________________________________________________________________
00613 void XrdOucString::insert(const char *s, int start, int ls)
00614 {
00615    // Insert null-terminated string pointed by s in local string starting
00616    // at position start (default append, i.e. start == len).
00617    // Memory is reallocated.
00618    // If ls > 0, insert only the first ls bytes of s
00619 
00620    // Check start
00621    int at = start;
00622    at = (at < 0 || at > len) ? len : at; 
00623 
00624    if (s) {
00625       int lstr = (ls > 0) ? ls : strlen(s);
00626       if (str) {
00627          int lnew = len + lstr;
00628          if (lnew > (siz-1))
00629             str = bufalloc(lnew+1);
00630          if (str) {
00631             // Move the rest of the existing string, if any
00632             if (at < len)
00633                memmove(str+at+lstr,str+at,(len-at));
00634             // Add new string now
00635             memcpy(str+at,s,lstr);
00636             // Null termination
00637             str[lnew] = 0;
00638             len = lnew;
00639          }
00640       } else {
00641          if ((str = bufalloc(lstr+1))) {
00642             strncpy(str,s,lstr);
00643             str[lstr] = 0;
00644             len = lstr;
00645          }
00646       }
00647    }
00648 }
00649 
00650 //___________________________________________________________________________
00651 void XrdOucString::insert(const XrdOucString s, int start)
00652 {
00653    // Insert string s in local string starting at position start (default
00654    // append, i.e. start == len).
00655 
00656    return insert(s.c_str(), start);
00657 }
00658 
00659 //___________________________________________________________________________
00660 void XrdOucString::insert(const char c, int start)
00661 {
00662    // Insert char c in local string starting at position start (default
00663    // append, i.e. start == len).
00664 
00665    char sc[2] = {0};
00666    sc[0] = c;
00667    return insert((const char *)&sc[0], start);
00668 }
00669 
00670 //___________________________________________________________________________
00671 void XrdOucString::insert(const int i, int start)
00672 {
00673    // Insert string representing integer i in local string starting at
00674    // position start (default
00675 
00676    char si[kMAXINT64LEN] = {0};
00677    sprintf(si,"%d",i);
00678    return insert((const char *)&si[0], start);
00679 }
00680 
00681 //___________________________________________________________________________
00682 int XrdOucString::replace(const XrdOucString s1, const char *s2, int from, int to)
00683 {
00684    // Replace any occurrence of s1 with s2 from position 'from' to position
00685    // 'to' (inclusive).
00686    // Return signed size of length modification (in bytes)
00687 
00688    return replace(s1.c_str(),s2,from,to);
00689 }
00690 
00691 //___________________________________________________________________________
00692 int XrdOucString::replace(const char *s1, const XrdOucString s2, int from, int to)
00693 {
00694    // Replace any occurrence of s1 with s2 from position 'from' to position
00695    // 'to' (inclusive).
00696    // Return signed size of length modification (in bytes)
00697 
00698    return replace(s1,s2.c_str(),from,to);
00699 }
00700 
00701 //___________________________________________________________________________
00702 int XrdOucString::replace(const XrdOucString s1,
00703                            const XrdOucString s2, int from, int to)
00704 {
00705    // Replace any occurrence of s1 with s2 from position 'from' to position
00706    // 'to' (inclusive).
00707    // Return signed size of length modification (in bytes)
00708 
00709    return replace(s1.c_str(),s2.c_str(),from,to);
00710 }
00711 
00712 //___________________________________________________________________________
00713 int XrdOucString::replace(const char *s1, const char *s2, int from, int to)
00714 {
00715    // Replace any occurrence of s1 with s2 from position 'from' to position
00716    // 'to' (inclusive).
00717    // Return signed size of length modification (in bytes)
00718 
00719    // We must have something to replace
00720    if (!str || len <= 0)
00721       return 0;
00722    
00723    // The string to replace must be defined and not empty
00724    int l1 = s1 ? strlen(s1) : 0;
00725    if (l1 <= 0)
00726       return 0;
00727 
00728    // Check and adjust indeces
00729    if (adjust(len,from,to) <= 0)
00730       return 0;
00731 
00732    // length of replacing string
00733    int l2 = s2 ? strlen(s2) : 0;
00734 
00735    // If new string is longer we need number of occurencies
00736    int nr = 0;
00737    if (l1 < l2) {
00738       int at = find(s1,from);
00739       while (at > -1 && at <= (to-l1+1)) {
00740          nr++;
00741          at = find(s1,at+l1);
00742       }
00743    }
00744 
00745    // New size
00746    int nlen = (nr > 0) ? (len + nr*(l2-l1)) : len ;
00747 
00748    // Reallocate, if needed
00749    if (nlen > (siz-1))
00750       str = bufalloc(nlen+1);
00751 
00752    // Now act
00753    int dd = l2-l1;
00754    int dl = 0;
00755    if (str) {
00756       if (dd < 0) {
00757          int nc = 0;
00758          int at = find(s1,from);
00759          while (at > -1 && at <= (to-l1+1)) {
00760             int atn = find(s1,at+l1);
00761             atn = (atn == -1 || atn > (to-l1+1)) ? len : atn;
00762             int ln = atn - at - l1;
00763             char *pc = str+at+nc*dd;
00764             if (l2 > 0)
00765                memcpy(pc,s2,l2);
00766             if (ln > 0)
00767                memmove(pc+l2,str+at+l1,ln);
00768             nc++;
00769             at = atn;
00770          }
00771          dl = nc*dd;
00772       } else if (dd == 0) {
00773          int at = find(s1,from);
00774          while (at > -1 && at <= (to-l1+1)) {
00775             memcpy(str+at,s2,l2);
00776             at = find(s1,at+l1);
00777          }
00778       } else if (dd > 0) {
00779          int nc = nr;
00780          int at = rfind(s1,to);
00781          int atn = len;
00782          while (at > -1 && at >= from) {
00783             int ln = atn - at - l1;
00784             char *pc = str + at + l1 + nc*dd;
00785             if (ln > 0)
00786                memmove(pc,str+at+l1,ln);
00787             if (l2 > 0)
00788                memcpy(pc-l2,s2,l2);
00789             nc--;
00790             atn = at;
00791             at = rfind(s1,at-l1);
00792          }
00793          dl = nr*dd;
00794       }
00795    }
00796 
00797    // Variation of string length
00798    len += dl;
00799    // Insure null-termination
00800    str[len] = 0;
00801    // We are done
00802    return dl;
00803 }
00804 
00805 //___________________________________________________________________________
00806 int XrdOucString::erase(int start, int size)
00807 {
00808    // Remove size bytes starting from position start.
00809    // If size == 0, remove any bytes from start on.
00810    // Return number of bytes removed ( <=size )
00811 
00812    int rc = 0;
00813 
00814    // Make sure start makes sense
00815    int st = start;
00816    if (st < 0 || st > (len-1))
00817       return rc;
00818 
00819    // Make sure size makes sense
00820    if (size < 0)
00821       return rc;
00822    int nrem = 0;
00823    if (size == 0) {
00824       nrem = len - st;
00825    } else {
00826       nrem = (size > (len-st)) ? (len-st) : size;
00827    }
00828    // Do nothing if no byte removal has been requested
00829    if (nrem <= 0)
00830       return rc;
00831    // Calculate new length and allocated new string
00832    int nlen = len - nrem;
00833    // Copy the remaining bytes, if any
00834    if (len-st-nrem) 
00835       memmove(str+st,str+st+nrem,len-st-nrem);
00836    // Null terminate
00837    str[nlen] = 0;
00838    // Assign new length
00839    len = nlen;
00840    // Return number of bytes removed
00841    return nrem;
00842 }
00843 
00844 //___________________________________________________________________________
00845 int XrdOucString::erase(const char *s, int from, int to)
00846 {
00847    // Remove any occurence of string s within from and to inclusive.
00848    // Use from == 0 and to == -1 to remove all occurences (default).
00849    // Return number of bytes removed ( <=size )
00850 
00851    return -replace(s,0,from,to);
00852 }
00853 
00854 //___________________________________________________________________________
00855 int XrdOucString::erase(XrdOucString s, int from, int to)
00856 {
00857    // Remove any occurence of string s within from and to inclusive.
00858    // Use from == 0 and to == -1 to remove all occurences (default).
00859    // Return number of bytes removed ( <=size )
00860 
00861    return -replace(s.c_str(),0,from,to);
00862 }
00863 
00864 //___________________________________________________________________________
00865 void XrdOucString::lower(int start, int size)
00866 {
00867    // Set to lower case size chars starting from position start.
00868    // If size == 0, lower all bytes from start on.
00869 
00870    // Make sure start makes sense
00871    int st = start;
00872    if (st < 0 || st > (len-1))
00873       return;
00874 
00875    // Make sure size makes sense
00876    if (size < 0)
00877       return;
00878    int nlw = 0;
00879    if (size == 0) {
00880       nlw = len - st;
00881    } else {
00882       nlw = (size > (len-st)) ? (len-st) : size;
00883    }
00884 
00885    // Do nothing if no byte removal has been requested
00886    if (nlw <= 0)
00887       return;
00888 
00889    // Set to lower
00890    int i = st;
00891    for (; i < st + nlw ; i++ ) {
00892       if (str[i] > 0x40 && str[i] < 0x5b)
00893          str[i] += 0x20; 
00894    }
00895 }
00896 
00897 //___________________________________________________________________________
00898 void XrdOucString::upper(int start, int size)
00899 {
00900    // Set to upper case size chars starting from position start.
00901    // If size == 0, upper all bytes from start on.
00902 
00903    // Make sure start makes sense
00904    int st = start;
00905    if (st < 0 || st > (len-1))
00906       return;
00907 
00908    // Make sure size makes sense
00909    if (size < 0)
00910       return;
00911    int nup = 0;
00912    if (size == 0) {
00913       nup = len - st;
00914    } else {
00915       nup = (size > (len-st)) ? (len-st) : size;
00916    }
00917 
00918    // Do nothing if no byte removal has been requested
00919    if (nup <= 0)
00920       return;
00921 
00922    // Set to upper
00923    int i = st;
00924    for (; i < st + nup ; i++ ) {
00925       if (str[i] > 0x60 && str[i] < 0x7b)
00926          str[i] -= 0x20; 
00927    }
00928 }
00929 
00930 //___________________________________________________________________________
00931 void XrdOucString::hardreset()
00932 {
00933    // Reset string making sure to erase completely the information.
00934 
00935    if (str) {
00936       volatile char *buf = 0;
00937       for (buf = (volatile char *)str; len; buf[--len] = 0);
00938       len = 0;
00939    }
00940    len = 0;
00941 }
00942 
00943 //___________________________________________________________________________
00944 void XrdOucString::reset(const char c, int j, int k)
00945 {
00946    // Reset string making sure to erase completely the information.
00947 
00948    j = (j >= 0 && j < siz) ? j : 0;
00949    k = (k >= j && k < siz) ? k : siz-1;
00950 
00951    if (str) {
00952       volatile char *buf = (volatile char *)str;
00953       int i = j;
00954       for (; i <= k; i++)
00955          buf[i] = c;
00956    }
00957    while (str[len-1] == 0)
00958       --len; 
00959 }
00960 
00961 //______________________________________________________________________________
00962 XrdOucString& XrdOucString::operator=(const int i)
00963 {
00964    // Assign string representing integer i to local string
00965 
00966    char s[kMAXINT64LEN] = {0};
00967    sprintf(s,"%d",i);
00968    assign((const char *)&s[0],0,-1);
00969    return *this;
00970 }
00971 
00972 //______________________________________________________________________________
00973 XrdOucString& XrdOucString::operator=(const char c)
00974 {
00975    // Assign char c to local string.
00976 
00977    const char s[] = {c,0};
00978    assign(s,0,-1);
00979    return *this;
00980 }
00981 
00982 //______________________________________________________________________________
00983 XrdOucString& XrdOucString::operator=(const char *s)
00984 {
00985    // Assign buffer s to local string.
00986 
00987    assign(s,0,-1);
00988 
00989    return *this;
00990 }
00991 
00992 //______________________________________________________________________________
00993 XrdOucString& XrdOucString::operator=(const XrdOucString s)
00994 {
00995    // Assign string s to local string.
00996    assign(s.c_str(), 0, -1);
00997 
00998    return *this;
00999 }
01000 
01001 //______________________________________________________________________________
01002 char &XrdOucString::operator[](int i)
01003 {
01004    // Return charcater at location i.
01005    static char c = '\0';
01006 
01007    if (str) {
01008       if (i > -1 && i < len) 
01009          return str[i];
01010       else
01011          abort();
01012    }
01013    return c;
01014 }
01015 
01016 //______________________________________________________________________________
01017 XrdOucString operator+(const XrdOucString &s1, const char *s)
01018 {
01019    // Return string resulting from concatenation
01020 
01021    XrdOucString ns(s1);
01022    if (s && strlen(s))
01023       ns.append(s);
01024    return ns;
01025 }
01026 
01027 //______________________________________________________________________________
01028 XrdOucString operator+(const XrdOucString &s1, const XrdOucString &s)
01029 {
01030    // Return string resulting from concatenation
01031 
01032    XrdOucString ns(s1);
01033    if (s.length())
01034       ns.append(s);
01035    return ns;
01036 }
01037 
01038 //______________________________________________________________________________
01039 XrdOucString operator+(const XrdOucString &s1, const char c)
01040 {
01041    // Return string resulting from concatenation of local string
01042    // and char c
01043 
01044    XrdOucString ns(s1);
01045    ns.append(c);
01046    return ns;
01047 }
01048 
01049 //______________________________________________________________________________
01050 XrdOucString operator+(const XrdOucString &s1, const int i)
01051 {
01052    // Return string resulting from concatenation of local string
01053    // and string representing integer i.
01054 
01055    XrdOucString ns(s1);
01056    ns.append(i);
01057    return ns;
01058 }
01059 
01060 //______________________________________________________________________________
01061 XrdOucString& XrdOucString::operator+=(const char *s)
01062 {
01063    // Add string at s to local string.
01064 
01065    if (s && strlen(s))
01066       this->append(s);
01067    return *this;
01068 }
01069 
01070 //______________________________________________________________________________
01071 XrdOucString& XrdOucString::operator+=(const XrdOucString s)
01072 {
01073    // Add string s to local string.
01074 
01075    if (s.length())
01076       this->append(s);
01077    return *this;
01078 }
01079 
01080 //______________________________________________________________________________
01081 XrdOucString& XrdOucString::operator+=(const char c)
01082 {
01083    // Add char c to local string.
01084 
01085    this->append(c);
01086    return *this;
01087 }
01088 
01089 //______________________________________________________________________________
01090 XrdOucString& XrdOucString::operator+=(const int i)
01091 {
01092    // Add string representing integer i to local string.
01093 
01094    this->append(i);
01095    return *this;
01096 }
01097 
01098 
01099 //______________________________________________________________________________
01100 int XrdOucString::operator==(const char *s)
01101 {
01102    // Compare string at s to local string: return 1 if matches, 0 if not
01103 
01104    if (s && (strlen(s) == (unsigned int)len))
01105       if (!strncmp(str,s,len))
01106          return 1;
01107    return 0;
01108 }
01109 
01110 //______________________________________________________________________________
01111 int XrdOucString::operator==(const XrdOucString s)
01112 {
01113    // Compare string s to local string: return 1 if matches, 0 if not
01114 
01115    if (s.length() == len)
01116       if (!strncmp(str,s.c_str(),len))
01117          return 1;
01118    return 0;
01119 }
01120 
01121 //______________________________________________________________________________
01122 int XrdOucString::operator==(const char c)
01123 {
01124    // Compare char c to local string: return 1 if matches, 0 if not
01125 
01126    if (len == 1) {
01127       if (str[0] == c)
01128          return 1;
01129    }
01130    return 0;
01131 }
01132 
01133 //______________________________________________________________________________
01134 int XrdOucString::operator==(const int i)
01135 {
01136    // Compare string representing integer i to local string:
01137    // return 1 if matches, 0 if not
01138 
01139    char s[kMAXINT64LEN] = {0};
01140    sprintf(s,"%d",i);
01141    return (*this == ((const char *)&s[0]));
01142 }
01143 
01144 //______________________________________________________________________________
01145 ostream &operator<< (ostream &os, const XrdOucString s)
01146 {
01147    // Operator << is useful to print a string into a stream
01148 
01149    if (s.c_str()) 
01150       os << s.c_str();
01151    else
01152      os << "";
01153    return os;
01154 }
01155 
01156 //______________________________________________________________________________
01157 XrdOucString const operator+(const char *s1, const XrdOucString s2)
01158 {
01159    // Binary operator+
01160    XrdOucString res(s1,s2.length()+strlen(s1));
01161    res.insert(s2);
01162    return res;
01163 }
01164 
01165 //______________________________________________________________________________
01166 XrdOucString const operator+(const char c, const XrdOucString s)
01167 {
01168    // Binary operator+
01169    XrdOucString res(c,s.length()+1);
01170    res.insert(s);
01171    return res;
01172 }
01173 
01174 //______________________________________________________________________________
01175 XrdOucString const operator+(const int i, const XrdOucString s)
01176 {
01177    // Binary operator+
01178    XrdOucString res(s.length()+kMAXINT64LEN);
01179    res.insert(i);
01180    res.insert(s);
01181    return res;
01182 }
01183 
01184 //______________________________________________________________________________
01185 int XrdOucString::getblksize()
01186 {
01187    // Getter for the block size
01188 
01189    return XrdOucString::blksize;
01190 }
01191 
01192 //______________________________________________________________________________
01193 void XrdOucString::setblksize(int bs)
01194 {
01195    // Set for the block size
01196 
01197    XrdOucString::blksize = bs;
01198 }
01199 
01200 //______________________________________________________________________________
01201 int XrdOucString::tokenize(XrdOucString &tok, int from, char del)
01202 {
01203    // Search for tokens delimited by 'del' (def ':') in string s; search starts
01204    // from 'from' and the token is returned in 'tok'.
01205    // Returns -1 when there are no more tokens to be analyzed; the length of the
01206    // last valid token, if there are no more delimiters after 'from'; the next
01207    // position after the delimiter, when there are left delimiters in the string.
01208    //
01209    // This method allows to loop over tokens in this way:
01210    //
01211    //    XrdOucString myl = "tok1 tok2 tok3";
01212    //    char del = ' ';
01213    //    XrdOucString tok;
01214    //    int from = 1;
01215    //    while ((from = myl.tokenize(tok, from, del) != -1) {
01216    //       // Analyse tok
01217    //       ...
01218    //    } 
01219    //
01220    // Warning: it may return empty tokens (e.g. in cases like "::"), so 
01221    // the token length must always be checked.
01222 
01223    // Make sure inputs make sense
01224    if (len <= 0 || from < 0 || from > (len-1)) 
01225       return -1;
01226 
01227    // Find delimiter
01228    int pos = find(del, from);
01229 
01230    // Assign to token
01231    if (pos == -1 || pos > from) {
01232       int last = (pos > 0) ? (pos - 1) : -1;
01233       tok.assign(str, from, last);
01234    } else
01235       tok = "";
01236 
01237    int next = pos + 1;
01238    if (pos == -1) {
01239       if (tok.length() > 0)
01240          // So we can analize the last one
01241          next = len;
01242       else
01243          next = pos;
01244    }
01245 
01246    // return
01247    return next;
01248 }
01249 
01250 //______________________________________________________________________________
01251 bool XrdOucString::isdigit(int from, int to)
01252 {
01253    // Return true is all chars between from and to (included) are digits
01254 
01255    // Make sure inputs make sense
01256    if (len <= 0) return 0;
01257 
01258    // Adjust range
01259    if (from < 0 || from > (len-1)) from = 0;
01260    if (to < from) to = len - 1;
01261 
01262    char *c = str + from;
01263 
01264    // Skip initial '-'
01265    if (*c == '-') c++;
01266 
01267    while (c <= str + to) {
01268       if (*c < 48 || *c > 57) return 0;
01269       c++;
01270    }
01271 
01272    return 1;
01273 }
01274 
01275 //______________________________________________________________________________
01276 long XrdOucString::atoi(int from, int to)
01277 {
01278    // Return the long integer corresponding to the number between from and to
01279    // (included), assuming they are digits (check with 'isdigit()').
01280    // Return LONG_MAX in case they are not digits
01281 
01282    if (!isdigit(from, to)) return LONG_MAX;
01283 
01284    // Adjust range
01285    if (from < 0 || from > (len-1)) from = 0;
01286    if (to < from) to = len - 1;
01287 
01288    // Save end char
01289    char e = str[to+1];
01290    str[to+1] = '\0';
01291    long out = strtol(&str[from], 0, 10);
01292    str[to+1] = e;
01293    return out;
01294 }

Generated on Tue Jul 5 14:46:56 2011 for ROOT_528-00b_version by  doxygen 1.5.1