Ignore:
Timestamp:
Nov 23, 2000, 7:36:41 PM (25 years ago)
Author:
umoeller
Message:

Updates for V0.9.6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/xstring.c

    r12 r13  
    5151 *      3) If you need the char* pointer (e.g. for a call
    5252 *         to another function), use XSTRING.psz. However,
    53  *         you should NEVER modify the psz pointer yourself
    54  *         because then these functions will get into trouble.
     53 *         you should ONLY modify the psz pointer yourself
     54 *         if the other XSTRING members are updated accordingly.
     55 *         You may, for example, change single characters
     56 *         in the psz buffer. By contrast, if you change the
     57 *         length of the string, you must update XSTRING.ulLength.
     58 *         Otherwise these functions will get into trouble.
    5559 *
    5660 *         Also, you should never assume that the "psz"
    5761 *         pointer has not changed after you have called
    5862 *         one of the xstr* functions because these can
    59  *         always reallocate the buffer if needed.
     63 *         always reallocate the buffer if more memory
     64 *         was needed.
    6065 *
    6166 *      4) If (and only if) you have a char* buffer which
     
    6873 *      The functions in this file used to be in stringh.c
    6974 *      before V0.9.3 (2000-04-01). These have been largely
    70  *      rewritten with V0.9.6 (2000-11-01).
     75 *      rewritten with V0.9.6 (2000-11-01) and are now much
     76 *      more efficient.
    7177 *
    7278 *      Note: Version numbering in this file relates to XWorkplace
     
    145151 *      the XSTRING with.
    146152 *
     153 *      This does not create a copy of pszNew. Instead,
     154 *      pszNew is used as the member string in pxstr
     155 *      directly.
     156 *
    147157 *      Do not use this on an XSTRING which is already
    148158 *      initialized. Use xstrset instead.
     159 *
     160 *      Example:
     161 *
     162 +          XSTRING str;
     163 +          xstrInitSet(&str, strdup("blah"));
    149164 *
    150165 *@@added V0.9.6 (2000-11-01) [umoeller]
     
    173188 *      of an existing string.
    174189 *
     190 *      As opposed to xstrInitSet, this does create
     191 *      a copy of pcszSource.
     192 *
    175193 *      Do not use this on an XSTRING which is already
    176194 *      initialized. Use xstrcpy instead.
     195 *
     196 *      Example:
     197 *
     198 +          XSTRING str;
     199 +          xstrInitCopy(&str, "blah");
    177200 *
    178201 *@@added V0.9.6 (2000-11-01) [umoeller]
     
    301324 +          xstrInit(&str, 0);
    302325 +          xstrcpy(&str, "blah");
     326 *
     327 *      This sequence can be abbreviated using xstrInitCopy.
    303328 *
    304329 *@@changed V0.9.2 (2000-04-01) [umoeller]: renamed from strhxcpy
     
    351376/*
    352377 *@@ xstrcat:
    353  *      appends pcszSource to pxstr, for which memory is allocated
    354  *      as necessary.
     378 *      appends pcszSource to pxstr, for which memory is
     379 *      reallocated if necessary.
    355380 *
    356381 *      If pxstr is empty, this behaves just like xstrcpy.
     
    366391 +          xstrcat(&str, "blup");
    367392 *
    368  *      would do the following:
    369  *      a)  free the old value of str ("blah");
    370  *      b)  reallocate str;
    371  *      c)  so that psz afterwards points to a new string containing
    372  *          "blahblup".
     393 *      After this, psz points to a new string containing
     394 *      "blahblup".
    373395 *
    374396 *@@changed V0.9.1 (99-12-20) [umoeller]: fixed memory leak
     
    424446
    425447            // 2) append source string:
    426             strcpy(pxstr->psz + pxstr->ulLength,
    427                    pcszSource);
     448            memcpy(pxstr->psz + pxstr->ulLength,
     449                   pcszSource,
     450                   ulSourceLength + 1);     // null terminator
    428451
    429452            // in all cases, set new length
    430453            pxstr->ulLength += ulSourceLength;
    431454            ulrc = ulSourceLength;
    432         }
     455
     456        } // end if (ulSourceLength)
    433457        // else no source specified or source is empty:
    434458        // do nothing
     
    439463
    440464/*
     465 *@@ xstrFindWord:
     466 *      searches for pstrFind in pxstr, starting at ulOfs.
     467 *      However, this only finds pstrFind if it's a "word",
     468 *      i.e. surrounded by one of the characters in the
     469 *      pcszBeginChars and pcszEndChars array.
     470 *
     471 *      This is similar to strhFindWord, but this uses
     472 *      strhmemfind for fast searching, and it doesn't
     473 *      have to calculate the string lengths because these
     474 *      already in XSTRING.
     475 *
     476 *      Returns 0 if no "word" was found, or the offset
     477 *      of the "word" in pxstr if found.
     478 *
     479 *@@added V0.9.6 (2000-11-12) [umoeller]
     480 */
     481
     482PSZ xstrFindWord(const XSTRING *pxstr,        // in: buffer to search ("haystack")
     483                 ULONG ulOfs,                 // in: where to begin search (0 = start)
     484                 const XSTRING *pstrFind,     // in: word to find ("needle")
     485                 size_t *pShiftTable,         // in: shift table (see strhmemfind)
     486                 PBOOL pfRepeatFind,          // in: repeat find? (see strhmemfind)
     487                 const char *pcszBeginChars,  // suggestion: "\x0d\x0a ()/\\-,."
     488                 const char *pcszEndChars)    // suggestion: "\x0d\x0a ()/\\-,.:;"
     489{
     490    PSZ     pReturn = 0;
     491    ULONG   ulFoundLen = pstrFind->ulLength;
     492
     493    if ((pxstr->ulLength) && (ulFoundLen))
     494    {
     495        const char *p = pxstr->psz + ulOfs;
     496
     497        do  // while p
     498        {
     499            // p = strstr(p, pstrFind->psz);
     500            p = (PSZ)strhmemfind(p,         // in: haystack
     501                                 pxstr->ulLength - (p - pxstr->psz),
     502                                            // remaining length of haystack
     503                                 pstrFind->psz,
     504                                 ulFoundLen,
     505                                 pShiftTable,
     506                                 pfRepeatFind);
     507            if (p)
     508            {
     509                // string found:
     510                // check if that's a word
     511
     512                if (strhIsWord(pxstr->psz,
     513                               p,
     514                               ulFoundLen,
     515                               pcszBeginChars,
     516                               pcszEndChars))
     517                {
     518                    // valid end char:
     519                    pReturn = (PSZ)p;
     520                    break;
     521                }
     522
     523                p += ulFoundLen;
     524            }
     525        } while (p);
     526
     527    }
     528    return (pReturn);
     529}
     530
     531/*
    441532 *@@ xstrrpl:
    442  *      replaces pstrSearch with pstrReplace in pxstr.
     533 *      replaces the first occurence of pstrSearch with
     534 *      pstrReplace in pxstr.
    443535 *
    444536 *      Starting with V0.9.6, this operates entirely on
    445537 *      XSTRING's for speed because we then know the string
    446538 *      lengths already and can use memcpy instead of strcpy.
    447  *      This new version should be magnitudes faster.
     539 *      This new version should be magnitudes faster,
     540 *      especially with large string bufffers.
    448541 *
    449542 *      None of the pointers can be NULL, but if pstrReplace
     
    454547 *      (and pxstr was therefore not changed).
    455548 *
    456  *      If the string was found and (pulAfterOfs != NULL),
    457  *      *pulAfterOfs will be set to the first character
    458  *      after the new replacement string. This allows you
    459  *      to call this func again with the same strings to
    460  *      have several occurences replaced.
    461  *
    462  *      Only the first occurence is replaced. To replace
    463  *      all occurences in a buffer, repeat calling this
    464  *      function until it returns 0.
     549 *      This starts the search at *pulOffset. If
     550 *      (*pulOffset == 0), this starts from the beginning
     551 *      of pxstr.
     552 *      If the string was found, *pulOffset will be set to the
     553 *      first character after the new replacement string. This
     554 *      allows you to call this func again with the same strings
     555 *      to have several occurences replaced (see the example below).
    465556 *
    466557 *      There are two wrappers around this function which
     
    476567 *
    477568 +          XSTRING str;
    478  +          ULONG ulPos = 0;
     569 +          ULONG ulOffset = 0;
    479570 +          xstrInit(&str, 0);
    480571 +          xstrcpy(&str, "Test phrase 1. Test phrase 2.");
    481572 +          while (xstrrpl(&str,
    482  +                         ulPos,
     573 +                         &ulPos,      // in/out: offset
    483574 +                         "Test",      // search
    484  +                         "Dummy",     // replace
    485  +                         &ulPos))
     575 +                         "Dummy")     // replace
    486576 +              ;
    487577 *
     
    493583 *@@changed V0.9.2 (2000-04-01) [umoeller]: renamed from strhxrpl
    494584 *@@changed V0.9.6 (2000-11-01) [umoeller]: rewritten
     585 *@@changed V0.9.6 (2000-11-12) [umoeller]: now using strhmemfind
    495586 */
    496587
    497588ULONG xstrrpl(PXSTRING pxstr,               // in/out: string
    498               ULONG ulOfs,                  // in: where to begin search (0 = start)
     589              PULONG pulOfs,                // in: where to begin search (0 = start);
     590                                            // out: ofs of first char after replacement string
    499591              const XSTRING *pstrSearch,    // in: search string; cannot be NULL
    500592              const XSTRING *pstrReplace,   // in: replacement string; cannot be NULL
    501               PULONG pulAfterOfs)           // out: offset where found (ptr can be NULL)
    502 {
    503     ULONG    ulrc = 0;
     593              size_t *pShiftTable,          // in: shift table (see strhmemfind)
     594              PBOOL pfRepeatFind)           // in: repeat find? (see strhmemfind)
     595{
     596    ULONG    ulrc = 0;      // default: not found
    504597
    505598    if ((pxstr) && (pstrSearch) && (pstrReplace))
     
    508601
    509602        // can we search this?
    510         if (    (ulOfs < pxstr->ulLength)
     603        if (    (*pulOfs < pxstr->ulLength)
    511604             && (cSearchLen)
    512605           )
    513606        {
    514607            // yes:
    515             PSZ     pFound = strstr(pxstr->psz + ulOfs,
    516                                     pstrSearch->psz);
    517 
     608            /* PSZ     pFound = strstr(pxstr->psz + *pulOfs,
     609                                    pstrSearch->psz);        */
     610            PSZ pFound = (PSZ)strhmemfind(pxstr->psz + *pulOfs, // in: haystack
     611                                          pxstr->ulLength - *pulOfs,
     612                                          pstrSearch->psz,
     613                                          cSearchLen,
     614                                          pShiftTable,
     615                                          pfRepeatFind);
    518616            if (pFound)
    519617            {
     
    569667                                + 1); // null terminator
    570668
     669                    // replace old buffer with new one
    571670                    free(pxstr->psz);
    572671                    pxstr->psz = pszNew;
     
    627726                // return new length
    628727                ulrc = cbNeeded - 1;
    629                 if (pulAfterOfs)
    630                     *pulAfterOfs = ulFoundOfs + cReplaceLen;
    631             }
    632         }
    633     }
     728                *pulOfs = ulFoundOfs + cReplaceLen;
     729            } // end if (pFound)
     730        } // end if (    (*pulOfs < pxstr->ulLength) ...
     731    } // end if ((pxstr) && (pstrSearch) && (pstrReplace))
    634732
    635733    return (ulrc);
     
    638736/*
    639737 *@@ xstrcrpl:
    640  *      wrapper around xstrrpl which allows using C strings
     738 *      wrapper around xstrrpl() which allows using C strings
    641739 *      for the find and replace parameters.
    642740 *
     741 *      This creates two temporary XSTRING's for pcszSearch
     742 *      pcszReplace. As a result, this is slower than xstrrpl.
     743 *      If you search with the same strings several times,
     744 *      you'll be better off using xstrrpl() directly.
     745 *
    643746 *@@added V0.9.6 (2000-11-01) [umoeller]
    644747 */
    645748
    646749ULONG xstrcrpl(PXSTRING pxstr,              // in/out: string
    647                ULONG ulOfs,                 // in: where to begin search (0 = start)
     750               PULONG pulOfs,               // in: where to begin search (0 = start);
     751                                            // out: ofs of first char after replacement string
    648752               const char *pcszSearch,      // in: search string; cannot be NULL
    649                const char *pcszReplace,     // in: replacement string; cannot be NULL
    650                PULONG pulAfterOfs)          // out: offset where found (ptr can be NULL)
    651 {
    652     ULONG   ulrc = 0;
     753               const char *pcszReplace)     // in: replacement string; cannot be NULL
     754{
     755    // ULONG   ulrc = 0;
    653756    XSTRING xstrFind,
    654757            xstrReplace;
    655     xstrInit(&xstrFind, 0);
    656     xstrset(&xstrFind, (PSZ)pcszSearch);
    657     xstrInit(&xstrReplace, 0);
    658     xstrset(&xstrReplace, (PSZ)pcszReplace);
    659 
    660     return (xstrrpl(pxstr, ulOfs, &xstrFind, &xstrReplace, pulAfterOfs));
     758    size_t  ShiftTable[256];
     759    BOOL    fRepeat = FALSE;
     760    // initialize find/replace strings... note that the
     761    // C strings are not free()'able, so we MUST NOT use xstrClear
     762    // before leaving
     763    xstrInitSet(&xstrFind, (PSZ)pcszSearch);
     764    xstrInitSet(&xstrReplace, (PSZ)pcszReplace);
     765
     766    return (xstrrpl(pxstr, pulOfs, &xstrFind, &xstrReplace, ShiftTable, &fRepeat));
    661767}
    662768
Note: See TracChangeset for help on using the changeset viewer.