/* -*-c++-*-

stringhandle.inl -- implement String_handle

source file of Flower lib

(c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/

#ifndef STRINGHANDLE_INL
#define STRINGHANDLE_INL

#include <cassert>
#include <memory>
using namespace std;

#include "string-data.hh"
#include "string-handle.hh"

INLINE void
String_handle::down ()
{
  if (! (--data->ref_count_))
    delete data;
  data = 0;
}

/*
  increase ref count

  THIS does not have to be initialized.
*/
INLINE void
String_handle::up (String_data *d)
{
  data = d;
  data->ref_count_++;
}

INLINE void
String_handle::copy ()
{
  if (data->ref_count_ != 1)
    {
      String_data *newdata = new String_data (*data);
      down ();
      up (newdata);
    }
}

INLINE
String_handle::String_handle ()
{
  up (new String_data);
}

INLINE
String_handle::~String_handle ()
{
  down ();
}

INLINE
String_handle::String_handle (String_handle const &src)
{
  up (src.data);
}

INLINE Byte *
String_handle::get_bytes ()
{
  copy ();
  return data->get_bytes ();
}

INLINE char *
String_handle::get_str0 ()
{
  copy ();
  return (char *)data->get_bytes ();
}

INLINE Byte
const *String_handle::to_bytes () const
{
  return data->to_bytes ();
}

INLINE char const *
String_handle::to_str0 () const
{
  return (char const *)data->to_bytes ();
}

INLINE void
String_handle::operator = (String_handle const &src)
{
  if (this == &src)
    return;
  down ();
  up (src.data);
}

INLINE void
String_handle::operator += (char const *s)
{
  copy ();
  *data += s;
}

INLINE Byte
String_handle::operator [] (int j) const
{
  return (*data)[j];
}

// !NOT SAFE!
// don't use this for loops. Use to_bytes ()
INLINE Byte &
String_handle::operator [] (int j)
{
  copy (); 	// hmm. Not efficient
  return data->get_bytes ()[j];
}

INLINE void
String_handle::append (Byte const *byte, int length_i)
{
  copy ();
  data->append (byte, length_i);
}

INLINE void
String_handle::set (Byte const *byte, int length_i)
{
  copy ();
  data->set (byte, length_i);
}

INLINE void
String_handle::operator = (char const *p)
{
  copy ();
  data->set (p);
}

INLINE void
String_handle::trunc (int j)
{
  copy (); data->trunc (j);
}

INLINE int
String_handle::length () const
{
  return data->length_;
}

INLINE bool
String_handle::is_binary_bo () const
{
  return data->is_binary_bo ();
}

#endif
