/*
 * svn_string.h:  routines to manipulate counted-length strings
 *                (svn_stringbuf_t and svn_string_t) and C strings.
 *                
 *
 * ====================================================================
 * Copyright (c) 2000-2002 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */



#include <string.h>      /* for memcpy(), memcmp(), strlen() */
#include <apr_lib.h>     /* for apr_isspace() */
#include "svn_string.h"  /* loads "svn_types.h" and <apr_pools.h> */



/* Our own realloc, since APR doesn't have one.  Note: this is a
   generic realloc for memory pools, *not* for strings. */
static void *
my__realloc (char *data, const apr_size_t oldsize, const apr_size_t request, 
             apr_pool_t *pool)
{
  void *new_area;

  /* kff todo: it's a pity APR doesn't give us this -- sometimes it
     could realloc the block merely by extending in place, sparing us
     a memcpy(), but only the pool would know enough to be able to do
     this.  We should add a realloc() to APR if someone hasn't
     already. */

  /* malloc new area */
  new_area = apr_palloc (pool, request);

  /* copy data to new area */
  memcpy (new_area, data, oldsize);

  /* I'm NOT freeing old area here -- cuz we're using pools, ugh. */
  
  /* return new area */
  return new_area;
}


/* svn_string functions */

static svn_string_t *
create_string (const char *data, apr_size_t size,
               apr_pool_t *pool)
{
  svn_string_t *new_string;

  new_string = (svn_string_t *) apr_palloc (pool, sizeof (*new_string)); 

  new_string->data = data;
  new_string->len = size;

  return new_string;
}

svn_string_t *
svn_string_ncreate (const char *bytes, const apr_size_t size, 
                    apr_pool_t *pool)
{
  char *data;

  data = apr_palloc (pool, size + 1);
  memcpy (data, bytes, size);

  /* Null termination is the convention -- even if we suspect the data
     to be binary, it's not up to us to decide, it's the caller's
     call.  Heck, that's why they call it the caller! */
  data[size] = '\0';

  /* wrap an svn_string_t around the new data */
  return create_string (data, size, pool);
}


svn_string_t *
svn_string_create (const char *cstring, apr_pool_t *pool)
{
  return svn_string_ncreate (cstring, strlen (cstring), pool);
}


svn_string_t *
svn_string_create_from_buf (const svn_stringbuf_t *strbuf, apr_pool_t *pool)
{
  return svn_string_ncreate (strbuf->data, strbuf->len, pool);
}


svn_string_t *
svn_string_createv (apr_pool_t *pool, const char *fmt, va_list ap)
{
  char *data = apr_pvsprintf (pool, fmt, ap);

  /* wrap an svn_string_t around the new data */
  return create_string (data, strlen (data), pool);
}


svn_string_t *
svn_string_createf (apr_pool_t *pool, const char *fmt, ...)
{
  svn_string_t *str;

  va_list ap;
  va_start (ap, fmt);
  str = svn_string_createv (pool, fmt, ap);
  va_end (ap);

  return str;
}


svn_boolean_t
svn_string_isempty (const svn_string_t *str)
{
  return (str->len == 0);
}


svn_string_t *
svn_string_dup (const svn_string_t *original_string, apr_pool_t *pool)
{
  return (svn_string_ncreate (original_string->data,
                              original_string->len, pool));
}



svn_boolean_t
svn_string_compare (const svn_string_t *str1, const svn_string_t *str2)
{
  /* easy way out :)  */
  if (str1->len != str2->len)
    return FALSE;

  /* now that we know they have identical lengths... */
  
  if (memcmp (str1->data, str2->data, str1->len))
    return FALSE;
  else
    return TRUE;
}



apr_size_t
svn_string_first_non_whitespace (const svn_string_t *str)
{
  apr_size_t i;

  for (i = 0; i < str->len; i++)
    {
      if (! apr_isspace (str->data[i]))
        {
          return i;
        }
    }

  /* if we get here, then the string must be entirely whitespace */
  return (-1);  
}


void
svn_string_strip_whitespace (svn_string_t *str)
{
  apr_size_t i;

  /* Find first non-whitespace character */
  apr_size_t offset = svn_string_first_non_whitespace (str);

  /* Go ahead!  Waste some RAM, we've got pools! :)  */
  str->data += offset;
  str->len -= offset;
  /* Can't adjust `blocksize' here, because svn_string_t does not
     record a blocksize independent of len, thus can't be
     realloc'd. */

  /* Now that we've chomped whitespace off the front, search backwards
     from the end for the first non-whitespace. */

  for (i = (str->len - 1); i >= 0; i--)
    {
      if (! apr_isspace (str->data[i]))
        {
          break;
        }
    }
  
  /* Mmm, waste some more RAM */
  str->len = i + 1;

  /* ### In svn_stringbuf_strip_whitespace, we reset the null
     terminator here.  But svn_string_t can have const data, so I
     don't think we can do that, unfortunately.  */
}


apr_size_t
svn_string_find_char_backward (const svn_string_t *str, char ch)
{
  int i;        /* signed! */

  for (i = (str->len - 1); i >= 0; i--)
    {
      if (str->data[i] == ch)
        return i;
    }

  return str->len;
}



/* svn_stringbuf functions */

static svn_stringbuf_t *
create_stringbuf (char *data, apr_size_t size, apr_pool_t *pool)
{
  svn_stringbuf_t *new_string;

  new_string = (svn_stringbuf_t *) apr_palloc (pool, sizeof (*new_string)); 

  new_string->data = data;
  new_string->len = size;
  new_string->blocksize = size + 1;	/* we know there is a null-term */
  new_string->pool = pool;

  return new_string;
}

svn_stringbuf_t *
svn_stringbuf_ncreate (const char *bytes, const apr_size_t size, 
                       apr_pool_t *pool)
{
  char *data;

  data = apr_palloc (pool, size + 1);
  memcpy (data, bytes, size);

  /* Null termination is the convention -- even if we suspect the data
     to be binary, it's not up to us to decide, it's the caller's
     call.  Heck, that's why they call it the caller! */
  data[size] = '\0';

  /* wrap an svn_stringbuf_t around the new data */
  return create_stringbuf (data, size, pool);
}


svn_stringbuf_t *
svn_stringbuf_create (const char *cstring, apr_pool_t *pool)
{
  return svn_stringbuf_ncreate (cstring, strlen (cstring), pool);
}


svn_stringbuf_t *
svn_stringbuf_create_from_string (const svn_string_t *str, apr_pool_t *pool)
{
  return svn_stringbuf_ncreate (str->data, str->len, pool);
}


svn_stringbuf_t *
svn_stringbuf_createv (apr_pool_t *pool, const char *fmt, va_list ap)
{
  char *data = apr_pvsprintf (pool, fmt, ap);

  /* wrap an svn_stringbuf_t around the new data */
  return create_stringbuf (data, strlen (data), pool);
}


svn_stringbuf_t *
svn_stringbuf_createf (apr_pool_t *pool, const char *fmt, ...)
{
  svn_stringbuf_t *str;

  va_list ap;
  va_start (ap, fmt);
  str = svn_stringbuf_createv (pool, fmt, ap);
  va_end (ap);

  return str;
}


void 
svn_stringbuf_fillchar (svn_stringbuf_t *str, const unsigned char c)
{
  memset (str->data, c, str->len);
}


void
svn_stringbuf_set (svn_stringbuf_t *str, const char *value)
{
  apr_size_t amt = strlen (value);

  svn_stringbuf_ensure (str, amt + 1);
  memcpy (str->data, value, amt + 1);
  str->len = amt;
}

void
svn_stringbuf_setempty (svn_stringbuf_t *str)
{
  if (str->len > 0)
    str->data[0] = '\0';

  str->len = 0;
}


void
svn_stringbuf_chop (svn_stringbuf_t *str, apr_size_t nbytes)
{
  if (nbytes > str->len)
    str->len = 0;
  else
    str->len -= nbytes;

  str->data[str->len] = '\0';
}


svn_boolean_t
svn_stringbuf_isempty (const svn_stringbuf_t *str)
{
  return (str->len == 0);
}


void
svn_stringbuf_ensure (svn_stringbuf_t *str, apr_size_t minimum_size)
{
  /* Keep doubling capacity until have enough. */
  if (str->blocksize < minimum_size)
    {
      if (str->blocksize == 0)
        str->blocksize = minimum_size;
      else
        while (str->blocksize < minimum_size)
          str->blocksize *= 2;

      str->data = (char *) my__realloc (str->data, 
                                        str->len,
                                        str->blocksize,
                                        str->pool); 
    }
}


void
svn_stringbuf_appendbytes (svn_stringbuf_t *str, const char *bytes, 
                           const apr_size_t count)
{
  apr_size_t total_len;
  void *start_address;

  total_len = str->len + count;  /* total size needed */

  /* +1 for null terminator. */
  svn_stringbuf_ensure (str, (total_len + 1));

  /* get address 1 byte beyond end of original bytestring */
  start_address = (str->data + str->len);

  memcpy (start_address, (void *) bytes, count);
  str->len = total_len;

  str->data[str->len] = '\0';  /* We don't know if this is binary
                                  data or not, but convention is
                                  to null-terminate. */
}


void
svn_stringbuf_appendstr (svn_stringbuf_t *targetstr, 
                         const svn_stringbuf_t *appendstr)
{
  svn_stringbuf_appendbytes (targetstr, appendstr->data, appendstr->len);
}


void
svn_stringbuf_appendcstr (svn_stringbuf_t *targetstr, const char *cstr)
{
  svn_stringbuf_appendbytes (targetstr, cstr, strlen(cstr));
}




svn_stringbuf_t *
svn_stringbuf_dup (const svn_stringbuf_t *original_string, apr_pool_t *pool)
{
  return (svn_stringbuf_ncreate (original_string->data,
                              original_string->len, pool));
}



svn_boolean_t
svn_stringbuf_compare (const svn_stringbuf_t *str1, 
                       const svn_stringbuf_t *str2)
{
  /* easy way out :)  */
  if (str1->len != str2->len)
    return FALSE;

  /* now that we know they have identical lengths... */
  
  if (memcmp (str1->data, str2->data, str1->len))
    return FALSE;
  else
    return TRUE;
}



apr_size_t
svn_stringbuf_first_non_whitespace (const svn_stringbuf_t *str)
{
  apr_size_t i;

  for (i = 0; i < str->len; i++)
    {
      if (! apr_isspace (str->data[i]))
        {
          return i;
        }
    }

  /* if we get here, then the string must be entirely whitespace */
  return (-1);  
}


void
svn_stringbuf_strip_whitespace (svn_stringbuf_t *str)
{
  apr_size_t i;

  /* Find first non-whitespace character */
  apr_size_t offset = svn_stringbuf_first_non_whitespace (str);

  /* Go ahead!  Waste some RAM, we've got pools! :)  */
  str->data += offset;
  str->len -= offset;
  str->blocksize -= offset;

  /* Now that we've chomped whitespace off the front, search backwards
     from the end for the first non-whitespace. */

  for (i = (str->len - 1); i >= 0; i--)
    {
      if (! apr_isspace (str->data[i]))
        {
          break;
        }
    }
  
  /* Mmm, waste some more RAM */
  str->len = i + 1;
  str->data[str->len] = '\0';
}


apr_size_t
svn_stringbuf_find_char_backward (const svn_stringbuf_t *str, char ch)
{
  int i;        /* signed! */

  for (i = (str->len - 1); i >= 0; i--)
    {
      if (str->data[i] == ch)
        return i;
    }

  return str->len;
}


apr_size_t
svn_stringbuf_chop_back_to_char (svn_stringbuf_t *str, char ch)
{
  apr_size_t i = svn_stringbuf_find_char_backward (str, ch);

  if (i < str->len)
    {
      apr_size_t nbytes = (str->len - i);
      svn_stringbuf_chop (str, nbytes);
      return nbytes;
    }

  return 0;
}


svn_boolean_t
svn_string_compare_stringbuf (const svn_string_t *str1,
                              const svn_stringbuf_t *str2)
{
  /* easy way out :)  */
  if (str1->len != str2->len)
    return FALSE;

  /* now that we know they have identical lengths... */

  if (memcmp (str1->data, str2->data, str1->len))
    return FALSE;
  else
    return TRUE;
}



/*** C string stuff. ***/

apr_array_header_t *
svn_cstring_split (const char *input,
                   char sep_char,
                   svn_boolean_t chop_whitespace,
                   apr_pool_t *pool)
{
  const char *b = input, *e = input;
  svn_boolean_t one_last_time = (! *e);
  apr_array_header_t *substrings = apr_array_make (pool, 1, sizeof (input));

  while (1)
    {
      if (chop_whitespace && (apr_isspace (*b)))
        {
          b++;

          if (e < b)
            e = b;
        }
      else if ((*e == sep_char) || (*e == '\0'))
        {
          const char *e2 = e;
          
          if (chop_whitespace)
            {
              if (e2 > b)
                {
                  while (apr_isspace (*(--e2)))
                    ;
                  e2++;
                }
            }

          *((char **) (apr_array_push (substrings)))
            = apr_pstrmemdup (pool, b, e2 - b);

          b = ++e;
        }
      else
        e++;

      if (one_last_time)
        break;

      if (*e == '\0')
        one_last_time = TRUE;
    }

  return substrings;
}




/* --------------------------------------------------------------
 * local variables:
 * eval: (load-file "../../tools/dev/svn-dev.el")
 * end:
 */

