/*****
 NAME
	pstring.h - header file for CString class
 VERSION
	$Id$
 CHANGELOG
	$Log$
 */

#if !defined(PSTRING_H_INCLUDED)
#define PSTRING_H_INCLUDED

#include <coconut/pset.h>
#include <coconut/perror.h>

/*****
  protocol:
    This protocol is designed for Posix Regular Expression style.
 */
@protocol PRegExp <PObject>

    /* If this bit is set, then use extended regular expression syntax.
       If not set, then use basic regular expression syntax.  */
  - setExtendedMode ;

    /* If this bit is set, then ignore case when matching.
       If not set, then case is significant.  */
  - setIgnoreCaseMode ;

    /* If this bit is set, then anchors do not match at newline
       characters in the string.
       If not set, then anchors do match at newlines.  */
  - setDotNotMatchNewlineMode ;

  - (id <PError>) compile: (const char *) pat ;

    /* the result code means
   	no_error       : the string matched with pattern
	not_mached_err : the string does not matched with pattern
        other          : internal error (use getErrorStr method)
     */
  - (id <PError>) match: (const char *) str start: (off_t *) start 
      stop:(off_t *) stop ;
  - (const char *) getErrorStr ;

@end

@protocol PStringFactory
   /* do not pass the null pointer as "str". it causes segmentation fault */
 + (utf8_char *) duplicate: (const utf8_char *) str ;
 + (utf8_char *) duplicate: (const utf8_char *) str length: (u_int) len ;
 + (u_int) length: (const utf8_char *) str ;
 + free: (utf8_char *) ptr ;

   /* if the string matched with "[a-zA-Z_][a-zA-Z0-9]*", return TRUE */
 + (boolean) isIdentifier: (const utf8_char *) str ;

   /* count the spaces started by "str". The tab code is extended as
      spaces. */
 + (u_int) countSpaces: (const utf8_char *) str tab: (u_int) tablen ;
   /* return the byte count to skip spaces given as "step". The tab code is
      extended as spaces. */
 + (u_int) stepSpaces: (const utf8_char *) str step: (u_int) step 
     tab: (u_int) tablen ;

   /* decode escaped character into character code, For examplea */
 + (utf8_char) decodeEscapeChar: (utf8_char) c ;

 + (u_int) defaultTabLength ;
 + setDefaultTabLength: (u_int) len ;
@end

@protocol PBasicStr <PIdHashElm, PDebug>
  - (const utf8_char *) setStr: (id <PBasicStr>) str ;
  - (const utf8_char *) setPtr: (const utf8_char *) str ;
  - (const utf8_char *) setPtr: (const utf8_char *) str length: (u_int) len ;
  - (const utf8_char *) ptr ;

    /* if the string contains only spaces, return TRUE. */
  - (boolean) isEmpty ;

    /* the return value does not contain '\0'. if the string is null,
       return 0 */
  - (u_int) length ;

    /* the return value contains '\0'. if the string is null, return 0 */
  - (size_t) size ;

  - (int) compare: (id <PBasicStr>) str ;
  - (int) comparePtr: (const utf8_char *) str length: (u_int) len ;
  - (int) comparePtr: (const utf8_char *) str ;

  - (int) comparePtrWoCase: (const utf8_char *) str length: (u_int) len ;
  - (int) comparePtrWoCase: (const utf8_char *) str ;
@end

/* the not mutable string */
@protocol PConstStr <PBasicStr>
  - (const utf8_char *) setPtr: (const utf8_char *) str copy: (boolean) copy 
      free: (boolean) dofree ;
  - (id <PConstStr>) duplicate ;
@end

/* the mutable string */
@protocol PString <PBasicStr>
  - (const utf8_char *) setPtr: (const utf8_char *) str ;
  - (const utf8_char *) setPtr: (const utf8_char *) str length: (u_int) len ;
  - (const utf8_char *) setFormat: (const utf8_char *) form, ... ;
  - (const utf8_char *) setFormat: (const utf8_char *) form 
      valist: (va_list) args ;

  - toUpper ;
  - toLower ;
  - replaceChar: (utf8_char) src by: (utf8_char) dst ;
  - replaceCharByStr: (utf8_char) src by: (const utf8_char *) dst 
      length: (u_int) dstlen ;
  -  replaceStrByStr: (const utf8_char*) src length: (u_int) srclen
      by: (const utf8_char *) dst length: (u_int) dstlen ;
    /* expand escaped characters in the original string */
  - expandEscape ;

  - removeChar: (utf8_char) c ;
  - removeStr: (const utf8_char *) str length: (u_int) len ;

    /* these mthods returns nil */
  - removeHeadSpaces ;
  - removeTailSpaces ;
  - removeSideSpaces ;
    /* if there are continuous multiple spaces, replace it by a blank (' '). 
       And the spaces on the head of line and tail of the string will be 
       removed. */
  - removeMultipleSpaces: (boolean) withnewline ;

    /* if "str" is nil, do nothing and return NULL */
  - (const utf8_char *) appendStr: (id <PBasicStr>) str ;
  - (const utf8_char *) appendPtr: (const utf8_char *) str ;
  - (const utf8_char *) appendPtr: (const utf8_char *) str length: (u_int) len ;
  - (const utf8_char *) appendChar: (utf8_char) c ;

    /* if "str" is nil, do nothing and return NULL */
  - (const utf8_char *) prependStr: (id <PBasicStr>) str ;
  - (const utf8_char *) prependPtr: (const utf8_char *) str ;
  - (const utf8_char *) prependPtr: (const utf8_char *) str length: (u_int) len;
  - (const utf8_char *) prependChar: (utf8_char) c ;

  - (const utf8_char *) insertStr: (u_int) pos str:(id <PBasicStr>) str ;
  - (const utf8_char *) insertPtr: (u_int) pos str:(const utf8_char *) str ;
  - (const utf8_char *) insertPtr: (u_int) pos str:(const utf8_char *) str 
      length: (u_int) len ;
  - (const utf8_char *) insertChar: (u_int) pos char:(utf8_char) c ;

  - indent: (const utf8_char *) spaces ;

    /* the current length of string is smaller than "len", do nothing */
  - changeLength: (u_int) len ;

  - (const utf8_char *) remove: (u_int) frompos length:(u_int) len ;

    /* get first word (non-space character set finished by space or EOS. */
  - (id <PString>) splitFirstWord ;
  - (id <PString>) splitLastWord ;

  - (id <PString>) duplicate ;

@end

#endif /* defined(PSTRING_H_INCLUDED) */

