/* String methods common to NXConstantString and TLString.
   This file is part of TL, Tiggr's Library.
   Written by Tiggr <tiggr@es.ele.tue.nl>
   Copyright (C) 1995, 1996 Pieter J. Schoenmakers
   TL is distributed WITHOUT ANY WARRANTY.
   See the file LICENSE in the TL distribution for details.

   $Id: StringMethods.m,v 1.2 1998/04/19 07:42:19 tiggr Exp $  */

-(int) compare: (id <TLString>) o
{
  const char *ocs;
  int r, l;

  if (!o)
    return (1);

  l = [o length];
  ocs = [o cString];
  
  if (l == len)
    r = memcmp (c_string, ocs, len);
  else if (l > len)
    {
      r = memcmp (c_string, ocs, len);
      if (!r)
	r = -1;
    }
  else
    {
      r = memcmp (c_string, ocs, l);
      if (!r)
	r = 1;
    }
  return (r);
} /* -compare */

-(id <TLString>) description
{
  return (self);
} /* -description */

-(unsigned int) hash
{
  return (tol_hash_string (c_string, len));
} /* -hash */

-(TLNumber *) objectLength
{
  return ([CO_TLNumber numberWithInt: len]);
}

-(void) print: (id <TLOutputStream>) stream quoted: (BOOL) qp
 withQuotes: (BOOL) wq
{
  if (!qp)
    [stream writeBytes: len fromBuffer: c_string];
  else
    {
      int i, force_next_digit_octal;

      if (wq)
	[stream writeByte: '"'];

      for (i = force_next_digit_octal = 0; i < len; i++)
	switch (c_string[i])
	  {
	  case '"':
	    if (wq)
	      [stream writeBytes: 2 fromBuffer: "\\\""];
	    force_next_digit_octal = 0; break;
	  case '\f': [stream writeBytes: 2 fromBuffer: "\\f"];
	    force_next_digit_octal = 0; break;
	  case '\n': [stream writeBytes: 2 fromBuffer: "\\n"];
	    force_next_digit_octal = 0; break;
	  case '\r': [stream writeBytes: 2 fromBuffer: "\\r"];
	    force_next_digit_octal = 0; break;
	  case '\t': [stream writeBytes: 2 fromBuffer: "\\t"];
	    force_next_digit_octal = 0; break;
	  case '\\': [stream writeBytes: 2 fromBuffer: "\\\\"];
	    force_next_digit_octal = 0; break;
	  default:
	    if (c_string[i] < ' ' || c_string[i] >= 127
		|| (force_next_digit_octal
		    && (c_string[i] >= '0' && c_string[i] <= '7')))
	      {
		int s, done, v = (unsigned char) c_string[i];

		[stream writeByte: '\\'];
		for (s = 64; s; s /= 8)
		  [stream writeByte: '0' + ((v / s) & 7)];
		force_next_digit_octal = 1;
	      }
	    else
	      {
		[stream writeByte: c_string[i]];
		force_next_digit_octal = 0;
	      }
	    break;
	  }
      if (wq)
	[stream writeByte: '"'];
    }
} /* -print:quoted:withQuotes: */

-(void) print: (id <TLOutputStream>) stream quoted: (BOOL) qp
{
  [self print: stream quoted: qp withQuotes: YES];
} /* -print:quoted: */

-stringp
{
  return (Qt);
} /* -stringp */
