Package anvil.core

Source Code of anvil.core.AnyString

/*
* $Id: AnyString.java,v 1.75 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core;

import anvil.core.runtime.AnyFunction;
import anvil.script.Context;
import anvil.script.Function;
import anvil.java.util.BindingEnumeration;
import anvil.util.Conversions;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Comparator;
import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import org.apache.oro.text.regex.Perl5Substitution;
import org.apache.oro.text.regex.StringSubstitution;
import org.apache.oro.text.regex.Substitution;
import org.apache.oro.text.regex.Util;

///
/// @class string
/// The <code>string</code> class represents character strings.
/// String is a sequence of characters.

/**
* class <code>AnyString</code>
*
* @author Jani Lehtim�ki
*/
public class AnyString extends AnySequence
{

  /// @constructor string
  /// Creates new string from the string representation of given parameter.
  /// @synopsis string(object value)
  public static final Object[] newInstance = { "value" };
  public static final Any newInstance(Any value)
  {
    return value.toAnyString();
 


  protected String  _string;
  protected int     _hashcode = 0;
  protected int     _type = IS_NULL;
  protected long    _long = 0;
  protected double  _double = 0.0;
 

  public AnyString(boolean bool)
  {
    _string = bool ? "true" : "false";
  }


  public AnyString(int integer)
  {
    _string = String.valueOf(integer);
  }


  public AnyString(double dbl)
  {
    _string = String.valueOf(dbl);
  }


  public AnyString(String string)
  {
    if (string == null) {
      _string = "";
    } else {
      _string = string;
    }
  }



  public boolean isCompatible(Any element)
  {
    int t = element.typeOf();
    return (t == IS_STRING) || (t == IS_BUFFER) || (t == IS_BINARY);
  }


  public int getSize()
  {
    return _string.length();
  }


  public AnySequence setSize(int size)
  {
    int length = _string.length();
    if (size < length) {
      return new AnyString(_string.substring(0, size));
    } else if (size > length) {
       StringBuffer buffer =new StringBuffer(size);
       buffer.append(_string);
       size -= length;
       while(size-->0) {
         buffer.append(0);
       }
       return new AnyString(buffer.toString());
    } else {
      return this;
    }
  }


  public AnySequence clear()
  {
    return new AnyString("");
  }
 
 
  public Any getElement(int index)
  {
    return ObjectPool.createChar(_string.charAt(index));
  }
 

  public AnySequence setElement(int index, Any element)
  {
    StringBuffer buffer = new StringBuffer(_string);
    buffer.setCharAt(index, element.toChar());
    return new AnyString(buffer.toString());
 


  public AnySequence crop(int start, int length)
  {
    return new AnyString(_string.substring(start, start+length));
  }
 

  public AnySequence getSlice(int start, int length)
  {
    return new AnyString(_string.substring(start, start+length));
  }


  public AnySequence deleteSlice(int start, int length)
  {
    String string = _string;
    int size = string.length();
    StringBuffer buffer = new StringBuffer(size - length);
    if (start > 0) {
      buffer.append(string.substring(0, start));
    }
    if (start + length < size) {
      buffer.append(string.substring(start+length, size));
    }
    return new AnyString(buffer.toString());   
  }


  public AnySequence setSlice(int start, int length, Any element)
  {
    String string = _string;
    int size = string.length();
    char seq = element.toChar();
    StringBuffer buffer = new StringBuffer(size + 1 - length);
    if (start > 0) {
      buffer.append(string.substring(0, start));
    }
    buffer.append(seq);
    if (start + length < size) {
      buffer.append(string.substring(start+length, size));
    }
    return new AnyString(buffer.toString());   
  }
 
 
  public AnySequence setSlice(int start, int length, AnySequence sequence)
  {
    String string = _string;
    int size = string.length();
    String seq = sequence.toString();
    int seq_length = seq.length();
    StringBuffer buffer = new StringBuffer(size + seq_length - length);
    if (start > 0) {
      buffer.append(string.substring(0, start));
    }
    if (seq_length > 0) {
      buffer.append(seq);
    }
    if (start + length < size) {
      buffer.append(string.substring(start+length, size));
    }
    return new AnyString(buffer.toString());

  }


  public AnySequence append(AnySequence sequence)
  {
    return new AnyString(_string + sequence.toString());
  }

 
  public AnySequence append(Any element)
  {
    return new AnyString(_string + element.toString());
  }
 

  public AnySequence createSequence(Any element)
  {
    return new AnyString(element.toString());
  }


  public AnySequence createEmptySequence()
  {
    return new AnyString("");
  }
 

  public int compareAt(AnySequence sequence, int start, int length)
  {
    String haystack = _string;
    String needle = sequence.toString();
    int delta;
    for(int i=0; i<length; i++) {
      delta = haystack.charAt(start+i) - needle.charAt(i);
      if (delta != 0) {
        return (delta<0) ? -1 : ((delta>0) ? 1 : 0);
      }
    }
    return 0;
 
 
 
  public int compareAt(Any element, int start)
  {
    int delta = _string.charAt(start) - element.toChar();
    return (delta<0) ? -1 : ((delta>0) ? 1 : 0);
  }   
 

  public AnySequence fill(Any fill, int start, int length)
  {
    char[] array = _string.toCharArray();
    java.util.Arrays.fill(array, start, start+length, fill.toChar());
    return new AnyString(new String(array));
  }


  public AnySequence sort(int start, int length, Comparator comparator)
  {
    char[] array = _string.toCharArray();
    java.util.Arrays.sort(array, start, start+length);
    return new AnyString(new String(array));
  }
   

  public int search(Any element, Comparator comparator)
  {
    return java.util.Arrays.binarySearch(_string.toCharArray(), element.toChar());
  }   


  public AnySequence swap(int index1, int index2)
  {
    char[] array = _string.toCharArray();
    char ch = array[index1];
    array[index1] = array[index2];
    array[index2] = ch;
    return new AnyString(new String(array));
  }
 

  public AnySequence reverse()
  {
    String string = _string;
    int size = string.length();
    StringBuffer buffer = new StringBuffer(size);
    for(int p = size - 1; p>=0; p--) {
      buffer.append(string.charAt(p));
    }
    return new AnyString(buffer.toString());
  }
   
 

  public int typeOf()
  {
    return IS_STRING;
  }

 
  public int sizeOf()
  {
    return _string.length();
  }
 
 
  public boolean isMutable()
  {
    return false;
  }


  public boolean isString()
  {
    return true;
  }
 
 
  public final anvil.script.ClassType classOf() {
    return __class__;
  }
 

  public boolean toBoolean()
  {
    return _string.length() > 0;
  }


  private void parse()
  {
    int n = _string.length();
    if (n == 0) {
      return;
    }

    char ch = 0;
    int i = 0;
   
    if (n>0) {
      ch = _string.charAt(0);
      if (ch == '-' || ch == '+') {
        i++;
      }
    }
    while(i<n && Character.isDigit((ch = _string.charAt(i)))) {
      i++;
    }

    _type = IS_STRING;

    if (i<n) {
      if (ch == '.' || ch == 'e' || ch == 'E') {
        try {
          _double = Double.parseDouble(_string);
          _long = (long)_double;
          _type = IS_DOUBLE; 
        } catch (NumberFormatException e) {
        }   
      }
    } else {
      try {
        _long = Long.parseLong(_string);
        _double = (double)_long;
        _type = IS_INT;
      } catch (NumberFormatException e) {
      }   
    }
   
  }


  public Any coerce()
  {
    if (_type == IS_NULL) {
      parse();
    }
    switch(_type) {
    case IS_INT:
      return Any.create(_long);
    case IS_DOUBLE:
      return Any.create(_double);
    case IS_STRING:
    default:
      return this;
    }
  } 
 

  public int toInt()
  {
    if (_type == IS_NULL) {
      parse();
    }
    return (int)_long;
  }


  public long toLong()
  {
    if (_type == IS_NULL) {
      parse();
    }
    return _long;
  }


  public double toDouble()
  {
    if (_type == IS_NULL) {
      parse();
    }
    return _double;
  }


  public char toChar()
  {
    return (_string.length()>0) ? _string.charAt(0) : ' ';
  }
 

  public String toString()
  {
    return _string;
  }


  public byte[] toBinary()  
  {
    return anvil.util.Conversions.getBytes(_string);
  }


  public Writer toAnvil(Writer writer) throws IOException
  {
    writer.write('"');
    writer.write(anvil.util.Conversions.escape(_string, true));
    writer.write('"');
    return writer;
  }


  public Writer toJava(Writer writer) throws IOException
  {
    writer.write("anvil.core.Any.create(\"");
    writer.write(anvil.util.Conversions.escape(_string, false));
    writer.write('"');
    writer.write(')');
    return writer;
  }
 

  public anvil.codec.Code toCode(anvil.codec.Code code)
  {
    anvil.codec.ConstantPool pool = code.getPool();
    int clazz = pool.addClass("anvil/core/AnyString");
    code.anew(clazz);
    code.dup();
    code.astring(_string);
    code.invokespecial(pool.addMethodRef(clazz, "<init>", "(Ljava/lang/String;)V"));
    return code;
  }   


  public Object toObject()
  {
    return _string;
  }


  public Any toAnyString()
  {
    return this;
  }


  public int hashCode()
  {
    if (_type == IS_NULL) {
      parse();
    }
    switch(_type) {
    case IS_INT:
      return (int)_long;
    case IS_DOUBLE:
      return (int)_double;
    default:
      if (_hashcode == 0) {
        _hashcode = _string.hashCode();
      }
      return _hashcode;
    }
  }

 
  public Any increase() {
    if (_type == IS_NULL) {
      parse();
    }
    switch(_type) {
    case IS_INT:
      return Any.create(_long + 1);
    case IS_DOUBLE:
      return Any.create(_double + 1.0);
    default:
      return this;
    }
  }

 
  public Any decrease() {
    if (_type == IS_NULL) {
      parse();
    }
    switch(_type) {
    case IS_INT:
      return Any.create(_long - 1);
    case IS_DOUBLE:
      return Any.create(_double - 1.0);
    default:
      return this;
    }
  }


  public Any minus() {
    if (_type == IS_NULL) {
      parse();
    }
    switch(_type) {
    case IS_INT:
      return Any.create(-_long);
    case IS_DOUBLE:
      return Any.create(-_double);
    default:
      return this;
    }
  }


  public Any plus() {
    if (_type == IS_NULL) {
      parse();
    }
    switch(_type) {
    case IS_INT:
      return Any.create(_long);
    case IS_DOUBLE:
      return Any.create(_double);
    default:
      return this;
    }
  }


  public Any add(Any other)
  {
    return Any.create(_string + other.toString());
  }


  public boolean equals(Object obj)
  {
    if (this == obj) {
      return true;
    }
    if (obj instanceof AnyString) {
      return _string.equals(obj.toString());
    }
    return false;
  }


  protected int compare(Any other)
  {
    return _string.compareTo(other.toString());
  }


  public void serialize(Serializer serializer) throws IOException
  {
    if (serializer.register(this)) {
      return;
    }
    String string = _string;
    serializer.write('s');
    serializer.write(string.length());
    serializer.write(':');
    serializer.writeUTF16(string);
  }
  public BindingEnumeration enumeration()
  {
    return new StringEnumeration(_string);
  }
 

  /********* Exposed methods ************/

  /// @method length
  /// Returns the length of this string.
  /// @synopsis int length()
  public Any m_length()
  {
    return Any.create(_string.length());
  }


  /// @method unquote
  /// Unquotes all html entities from this string.
  /// @synopsis string unquote()
  public Any m_unquote()
  {
    return Any.create(Conversions.decodeEntities(_string));
  }


  /// @method quote
  /// Converts all applicable characters with corresponding
  /// html entity.
  /// @synopsis string quote()
  public Any m_quote()
  {
    return Any.create(Conversions.encodeEntities(_string));
  }


  /// @method quoteMeta
  /// Converts all applicable characters under &gt;127 with corresponding
  /// html entity.
  /// @synopsis string quoteMeta()
  public Any m_quoteMeta()
  {
    return Any.create(Conversions.encodeMetaEntities(_string));
  }

  /// @method quoteText
  /// Converts all applicable characters over &gt;127 with corresponding
  /// html entity.
  /// @synopsis string quoteText()
  public Any m_quoteText()
  {
    return Any.create(Conversions.encodeText(_string));
  }


  /// @method compress
  /// Compresses consequtive white space characeters into single
  /// space.
  /// @synopsis string compress()
  public Any m_compress()
  {
    return Any.create(Conversions.compress(_string));
  }


  /// @method capitalize
  /// Capitalizes the first character of all words.
  /// @synopsis string capitalize()
  public Any m_capitalize()
  {
    return Any.create(Conversions.capitalizeAllWords(_string));
  }

  /// @method capitalizeFirst
  /// Capitalizes first character of first word.
  /// @synopsis string capitalizeFirst()
  public Any m_capitalizeFirst()
  {
    return Any.create(Conversions.capitalizeFirstWord(_string));
  }

  /// @method nowrap
  /// Converts white spaces into <code>&amp;nbsp;</code>.
  /// @synopsis string nowrap()
  public Any m_nowrap()
  {
    return Any.create(Conversions.nowrap(_string));
  }

  /// @method encodeURL
  /// URL encodes this string.
  /// @synopsis string encodeURL()
  public Any m_encodeURL()
  {
    return Any.create(Conversions.URLEncode(_string));
  }


  /// @method decodeURL
  /// Decodes URL encoding from this string.
  /// @synopsis string decodeURL()
  public Any m_decodeURL()
  {
    return Any.create(Conversions.URLDecode(_string));
  }


  /// @method encode
  /// URL encodes this string.
  /// @synopsis string encode()
  public Any m_encode()
  {
    return Any.create(Conversions.URLEncode(_string));
  }


  /// @method decode
  /// Decodes URL encoding from this string.
  /// @synopsis string decode()
  public Any m_decode()
  {
    return Any.create(Conversions.URLDecode(_string));
  }



  /// @method escape
  /// Escapes string using the rules of anvil string literal.
  /// @synopsis string escape()
  public Any m_escape()
  {
    return Any.create(Conversions.escape(_string));
  }


  /// @method unescape
  /// Unescapes backslash quotes.
  /// @synopsis string unescape()
  /// @synopsis string unescape(boolean withQuotes)
  public static final Object[] p_unescape = new Object[] { "*hasQuotes", Boolean.FALSE };
  public Any m_unescape(boolean hasQuotes)
  {
    return Any.create(Conversions.unescape(_string, hasQuotes));
  }


  /// @method nl2br
  /// Convers all line feeds into <code>&lt;br&gt;\n</code>
  /// @synopsis string nl2br()
  public Any m_nl2br()
  {
    return Any.create(Conversions.nl2br(_string));
  }


  /// @method toUpper
  /// Converts all lower case characeters into corresponding upper case
  /// characeters.
  /// @synopsis string toUpper()
  public Any m_toUpper()
  {
    return Any.create(_string.toUpperCase());
  }


  /// @method toLower
  /// Converts all upper case characeters into corresponding lower case
  /// characeters.
  /// @synopsis string toLower()
  public Any m_toLower()
  {
    return Any.create(_string.toLowerCase());
  }


  /// @method trim
  /// Removes whitespace characters from the beginning and end of this string.
  /// @synopsis string trim()
  public Any m_trim()
  {
    return Any.create(_string.trim());
  }


  /// @method trimLeft
  /// Removes whitespace characters from the beginning this string.
  /// @synopsis string trimLeft()
  public Any m_trimLeft()
  {
    String value = _string;
    int i = 0;
    int n = value.length();
    while((i<n) && Character.isWhitespace(value.charAt(i))) {
      i++;
    }
    if (i>0) {
      return Any.create(value.substring(i));
    } else {
      return this;
    }
  }


  /// @method trimRight
  /// Removes whitespace characters from the end this string.
  /// @synopsis string trimRight()
  public Any m_trimRight()
  {
    String value = _string;
    int i = value.length();
    while((i>0) && Character.isWhitespace(value.charAt(i-1))) {
      i--;
    }
    if (i<value.length()) {
      return Any.create(value.substring(0, i));
    } else {
      return this;
    }
  }


  /// @method substring
  /// Returns a substring from the given region of this string.
  /// @synopsis string substring(int start)
  /// @synopsis string substring(int start, int end)
  /// @param start Starting index, included
  /// @param end Ending index, excluded
  public static final Object[] p_substring = new Object[] { "start", "*end", null };
  public Any m_substring(int start, Any end_)
  {
    String string = _string;
    int max = string.length();
   
    if (start < 0) {
      start = 0;
    } else if (start > max) {
      start = max;
    }
   
    if (end_ != null) {
      int end = end_.toInt();
      if (end < 0) {
        end = 0;
      } else if (end > max) {
        end = max;
      }
      if (start <= end) {
        if (end - start == 1) {
          return ObjectPool.createChar(string.charAt(start));
        } else {
          return Any.create(string.substring(start, end));
        }
      } else {
        return EMPTY_STRING;
      }
    } else {
      if (start == max) {
        return EMPTY_STRING;
      } else {
        return Any.create(string.substring(start));
      }
    }
  }


  /// @method charAt
  /// Returns single character from this string.
  /// @synopsis string charAt(int index)
  /// @param index Index to string
  public static final Object[] p_charAt = new Object[] { "index" };
  public Any m_charAt(int index)
  {
    if ((index >= 0) && (index < _string.length())) {
      return Any.create(_string.charAt(index));
    } else {
      return EMPTY_STRING;
    }
  }


  /// @method charCodeAt
  /// Returns the character code at the speicified index.
  /// @synopsis int charCodeAt(int index)
  /// @param index Index to string
  public static final Object[] p_charCodeAt = new Object[] { "index" };
  public Any m_charCodeAt(int index)
  {
    if ((index >= 0) && (index < _string.length())) {
      return Any.create((int)_string.charAt(index));  
    } else {
      return ZERO;
    }
  }


  /// @method indexOf
  /// Returns the index within this string of the first occurrence of the
  /// specified string.
  /// @synopsis int indexOf(string needle)
  /// @synopsis int indexOf(string needle, int fromIndex)
  /// @param needle String to search for
  /// @param fromIndex Starting index of search
  /// @return The index of first occurence, or -1 if it doesn't occur.
  public static final Object[] p_indexOf = new Object[] { "needle", "*fromIndex", new Integer(0) };
  public Any m_indexOf(String needle, int fromIndex)
  {
    return Any.create(_string.indexOf(needle, fromIndex));
  }



  /// @method lastIndexOf
  /// Returns the index within this string of the last occurrence of the
  /// specified string.
  /// @synopsis int lastIndexOf(string needle)
  /// @synopsis int lastIndexOf(string needle, int fromIndex)
  /// @param needle String to search for
  /// @param fromIndex Starting index of search
  /// @return The index of last occurence, or -1 if it doesn't occur.
  public static final Object[] p_lastIndexOf = new Object[] { "needle", "*fromIndex", null };
  public Any m_lastIndexOf(String needle, Any fromIndex)
  {
    int start;
    if (fromIndex != null) {
      start = fromIndex.toInt();
    } else {
      start = _string.length();   
    }
    return Any.create(_string.lastIndexOf(needle, start));
  }


  /// @method startsWith
  /// Checks if this string starts with given prefix.
  /// @synopsis boolean startsWith(string prefix)
  public static final Object[] p_startsWith = new Object[] { "prefix" };
  public Any m_startsWith(String prefix)
  {
    return _string.startsWith(prefix) ? TRUE : FALSE;
  }


  /// @method endsWith
  /// Checks if this string ends with given suffix.
  /// @synopsis boolean endsWith(string suffix)
  public static final Object[] p_endsWith = new Object[] { "suffix" };
  public Any m_endsWith(String suffix)
  {
    return _string.endsWith(suffix) ? TRUE : FALSE;
  }


  /// @method compareToIgnoreCase
  /// Compares this string and given string, lower- and
  /// uppercase characters are considered equal.
  /// @synopsis int compareToIgnoreCase(string other)
  /// @return -1 if <code>this&lt;other</code>,
  ///          0 if <code>this==other</code>,
  ///          1 if <code>this&gt;other</code>,
  public static final Object[] p_compareToIgnoreCase = new Object[] { "str" };
  public Any m_compareToIgnoreCase(String str)
  {
    int delta = _string.compareToIgnoreCase(str);
    if (delta < 0) {
      return MINUS_ONE;
    } else if (delta > 0) {
      return ONE;
    } else {
      return ZERO;
    }
  }


  /// @method equalsIgnoreCase
  /// Checks if this string is equal to given string, lower- and
  /// uppercase characters are considered equal
  /// @synopsis boolean equalsIgnoreCase(string other)
  /// @param other String to compare with
  public static final Object[] p_equalsIgnoreCase = new Object[] { "str" };
  public Any m_equalsIgnoreCase(String str)
  {
    return _string.equalsIgnoreCase(str) ? TRUE: FALSE;
  }


  /// @method explode
  /// Splits this string into regions using given set of delimiter
  /// characters.
  /// @synopsis list explode(string delimiters)
  /// @synopsis list explode(string delimiters, boolean returnEmpty)
  /// @param delimiters Set of delimiter characters
  /// @param returnEmpty If <code>true</code> also empty regions are returned, if
  /// omitted or <code>false</code> empty regions are not returned.
  public static final Object[] p_explode = new Object[] { "delimiters", "*returnEmpty", Boolean.FALSE };
  public Any m_explode(String delimiters, boolean returnEmpty)
  {
    AnyList list = new AnyList(new Any[8], 0);
    if (returnEmpty) {
      String str = _string;
      int n = str.length();
      int begin = 0;
      for(int i=0; i<n; i++) {
        if (delimiters.indexOf(str.charAt(i))>=0) {
          list.append(Any.create(str.substring(begin, i)));
          begin = i+1;
        }
      }
      if (begin <= n) {
        list.append(Any.create(str.substring(begin)));
      }
    } else {
      StringTokenizer tokenizer = new StringTokenizer(_string, delimiters);
      while(tokenizer.hasMoreElements()) {
        list.append(Any.create((String)tokenizer.nextElement()));
      }
    }
    return list;
  }


  /// @method repeat
  /// Repeats this string <code>amount</code> times.
  /// @synopsis string repeat(int amount)
  public static final Object[] p_repeat = new Object[] { "count" };
  public Any m_repeat(int count)
  {
    if (count < 0) {
      count = 0;
    }
    String string = _string;
    StringBuffer buffer = new StringBuffer(string.length() * count + 1);
    for(; count > 0; count--) {
      buffer.append(string);
    }
    return Any.create(buffer.toString());
  }


  /// @method translate
  /// For each character in this string: if character appears
  /// in <code>from</code> string, converts it to character
  /// at the same index at <code>to</code>.
  /// @synopsis string translate(string from, string to)
  /// @param from Source character mapping
  /// @param to Target character mapping
  /// @return Translated string
  public static final Object[] p_translate = new Object[] { "from", "to" };
  public Any m_translate(String from, String to)
  {
    int pos;
    char ch;
    String string  = _string;
    int n = string.length();
    int max = to.length();
    StringBuffer buffer = new StringBuffer(n);
    for(int i=0; i<n; i++) {
      ch = string.charAt(i);
      pos = from.indexOf(ch);
      if (pos >= 0) {
        if (pos < max) {
          buffer.append(to.charAt(pos));
        }
      } else {
        buffer.append(ch);
      }
    }
    return Any.create(buffer.toString());
  }


  /// @method replace
  /// Replaces all occurences of <code>from</code> into <code>to</code>.
  /// @synopsis string replace(string from, string to)
  /// @param from Regions to replace
  /// @param to Replacement
  public static final Object[] p_replace = new Object[] { "from", "to" };
  public Any m_replace(String from, String to)
  {
    String string  = _string;
    int end = string.indexOf(from, 0);
    if (end < 0) {
      return this;
    }
    int max = string.length();
    int begin = 0;
    int toLen = to.length();
    int fromLen = from.length();
    StringBuffer buffer = new StringBuffer(max);
    for(;;) {
      end = string.indexOf(from, begin);
      if (end < 0) {
        end = max;
        for(;begin<end; begin++) {
          buffer.append(string.charAt(begin));
        }
        break;
      } else {
        for(; begin<end; begin++) {
          buffer.append(string.charAt(begin));
        }
        buffer.append(to);
        begin += fromLen;
      }
    }
    return Any.create(buffer.toString());
  }


  /// @method unserialize
  /// Unserializes data contained in this string.
  /// @synopsis object unserialize()
  /// @return Unserialized data
  /// @throws CorruptedSerialization If serialized data is corrupted
  public Any m_unserialize(Context context)
  {
    try {
      return Serialization.unserialize(context, _string);
    } catch (UnserializationException e) {
      throw context.CorruptedSerialization();
    }
  }


  private Any doMatch(Context context, Any pattern_, Any matches_, boolean isMatch)
  {
    Array array = null;
    AnyList list = null;
    if (matches_ != null) {
      array = matches_.toArray();
      if (matches_ instanceof AnyList) {
        list = (AnyList)matches_;
      }
    }
   
    Pattern pattern = ObjectPool.createPattern(context, pattern_);
    Perl5Matcher matcher = new Perl5Matcher();
    if (isMatch ? matcher.matches(_string, pattern)
                : matcher.contains(_string, pattern))
    {
      if (array != null) {
        MatchResult match = matcher.getMatch();
        array.clear();
        int n = match.groups();
        for(int i=0; i<n; i++) {
          array.append(Any.create(match.group(i)));
        }
        return array;

      } else if (list != null) {
        MatchResult match = matcher.getMatch();
        list.clear();
        int n = match.groups();
        for(int i=0; i<n; i++) {
          list.append(Any.create(match.group(i)));
        }
        return list;       
      }

      return TRUE;
    } else {
      return FALSE;
    }
  }
 

  /// @method matches
  /// Checks if this (whole) string matches given
  /// regular expression.
  /// @synopsis boolean matches(string pattern)
  /// @synopsis boolean matches(string pattern, array matches)
  /// @synopsis boolean matches(string pattern, list matches)
  /// @synopsis boolean matches(pattern pattern)
  /// @synopsis boolean matches(pattern pattern, array matches)
  /// @synopsis boolean matches(pattern pattern, list matches)
  /// @param pattern Regular expression pattern
  /// @return Matches or boolean
  /// @throws MalformedPattern If pattern is invalid
  public static final Object[] p_matches = new Object[] { null, "pattern", "*matches", null };
  public Any m_matches(Context context, Any pattern, Any matches)
  {
    return doMatch(context, pattern, matches, true);
  }
 
  /// @method contains
  /// Checks if some region of this string matches given
  /// regular expression.
  /// @synopsis boolean contains(string pattern)
  /// @synopsis boolean contains(string pattern, array matches)
  /// @synopsis boolean contains(string pattern, list matches)
  /// @synopsis boolean contains(pattern pattern)
  /// @synopsis boolean contains(pattern pattern, array matches)
  /// @synopsis boolean contains(pattern pattern, list matches)
  /// @param pattern Regular expression pattern
  /// @return Matches or boolean
  /// @throws MalformedPattern If pattern is invalid
  public static final Object[] p_contains = new Object[] { null, "pattern", "*matches", null };
  public Any m_contains(Context context, Any pattern, Any matches)
  {
    return doMatch(context, pattern, matches, false);
  }
   

  /// @method find
  /// Finds all regions from this string mathing given regular
  /// expression pattern.
  /// @synopsis enumeration find(string pattern)
  /// @synopsis enumeration find(pattern pattern)
  /// @param pattern Regular expression pattern
  /// @return Enumeration of strings
  /// @throws MalformedPattern If pattern is invalid
  public static final Object[] p_find = new Object[] { null, "pattern" };
  public Any m_find(Context context, Any pattern_)
  {
    Pattern pattern = ObjectPool.createPattern(context, pattern_);
    return new AnyBindingEnumeration(
      new AnyUtils.StringPatternMatcher(pattern, _string));
  }   


  /// @method split
  /// Splits this string using given regular expression pattern as
  /// delimiter.
  /// @synopsis list split(string pattern)
  /// @synopsis list split(pattern pattern)
  /// @param pattern Regular expression pattern
  /// @throws MalformedPattern If pattern is invalid
  public static final Object[] p_split = new Object[] { null, "pattern" };
  public Any m_split(Context context, Any pattern_)
  {
    Pattern pattern = ObjectPool.createPattern(context, pattern_);
    Perl5Matcher matcher = new Perl5Matcher();
    Vector parts = Util.split(matcher, pattern, _string);
    int n = parts.size();
    Any[] list = new Any[n];
    for(int i=0; i<n; i++) {
      list[i] = Any.create(parts.elementAt(i).toString());
    }
    return new AnyList(list);
  }
   

  /// @method divide
  /// Divides string to two pieces, using <code>delim</code> as delimiter.
  /// Example 1. "foo.bar.foo".divide(".") returns ("foo", "bar.foo")
  /// Example 2. "foo.bar.foo".divide("|") returns ("foo.bar.foo", null)
  /// Example 3. "foo.bar.fiu".divide(".", true) return ("fiu", "foo.bar")
  /// @synopsis list divide(string delim)
  /// @synopsis list divide(string delim, boolean dir)
  /// @param delim Delimiter character(s)
  /// @param dir Direction (default false), false = from start of the string,
  /// true = from end of the string
  public static final Object[] p_divide = new Object[] { "delim", "*dir", null };
  public Any m_divide(String delim, Any dir)
  {
    if (delim == null) {
      return UNDEFINED;
    }
    if (dir == null || !dir.toBoolean()) {
      int i = _string.indexOf(delim);
      if (i == -1) {
        return new AnyList(new Any[] { this, NULL });
      } else {
        return new AnyList(new Any[] { Any.create(_string.substring(0, i)), Any.create(_string.substring(i+1)) });
      }
    } else {
      int i = _string.lastIndexOf(delim);
      if (i == -1) {
        return new AnyList(new Any[] { this, NULL });
      } else {
        return new AnyList(new Any[] { Any.create(_string.substring(i+1)), Any.create(_string.substring(0, i)) });
      }
    }
  }
   

  private Any doSubstitute(Context context, Any pattern_, Any replacement, int flags)
  {
    Substitution substitution;
    if (replacement.isString()) {
      String s = replacement.toString();
      if (s.indexOf('$') != -1) {
        substitution = new Perl5Substitution(s);
      } else {
        substitution = new StringSubstitution(s);
      }
    } else {
      substitution = new AnyUtils.FunctionSubstitute(context, replacement);
    }
   
    Pattern pattern = ObjectPool.createPattern(context, pattern_);
    Perl5Matcher matcher = new Perl5Matcher();
    return Any.create(Util.substitute(matcher, pattern, substitution, _string, flags));
  }


  /// @method substitute
  /// Substitutes all regions from this string matching given
  /// regular expression.
  /// @synopsis string substitute(string pattern, string replacement [, int amount] )
  /// @synopsis string substitute(pattern pattern, string replacement [, int amount] )
  /// @synopsis string substitute(string pattern, Function replacer [, int amount] )
  /// @synopsis string substitute(pattern pattern, Function replacer [, int amount] )
  /// @param pattern Regular expression pattern
  /// @param replacement Replacement string
  /// @param replacer Replace function:
  /// @param amount Number of occurences to replace, if omitted, all occurences are substituted.
  /// <code>function replacer(list matchedGroups)</code>.
  /// @throws MalformedPattern If pattern is invalid
  public static final Object[] p_substitute = new Object[] { null, "pattern", "replacement", "*amount", null };
  public Any m_substitute(Context context, Any pattern, Any replacement, Any amount)
  {
    int flag = Util.SUBSTITUTE_ALL;
    if (amount != null) {
      flag = amount.toInt();
    }
    return doSubstitute(context, pattern, replacement, flag);
  }   


  /// @method substituteFirst
  /// Substitutes first region from this string matching given
  /// regular expression.
  /// @synopsis string substituteFirst(string pattern, string replacement)
  /// @synopsis string substituteFirst(pattern pattern, string replacement)
  /// @synopsis string substituteFirst(string pattern, Function replacer)
  /// @synopsis string substituteFirst(pattern pattern, Function replacer)
  /// @param pattern Regular expression pattern
  /// @param replacement Replacement string
  /// @param replacer Replace function:
  /// <code>function replacer(list matchedGroups)</code>.
  /// @throws MalformedPattern If pattern is invalid
  public static final Object[] p_substituteFirst = new Object[] { null, "pattern", "replacement" };
  public Any m_substituteFirst(Context context, Any pattern, Any replacement)
  {
    return doSubstitute(context, pattern, replacement, 1);
  }
 
 
  /// @method hexToBinary
  /// Converts string to binary,
  /// assuming that two characters produce one byte: 414243 -> binary(abc)
  /// @synopsis binary hexToBinary()
  public Any m_hexToBinary()
  {
    String string = _string;
    int n = string.length() / 2;
    byte[] array = new byte[n];
    for(int i=0; i<n; i++) {
      array[i] = (byte)((Conversions.parseHex(string.charAt(i+i)) << 4) +
        Conversions.parseHex(string.charAt(i+i+1)));
    }
    return new AnyBinary(array);
  }


  /// @method pad
  /// Pads text left or right to field.
  /// @synopsis string pad(int length)
  /// @synopsis string pad(int length, string padding)
  /// @param length Length of field, positive for right padding, negative
  ///               for left padding.
  /// @param padding Padding character, default is space.
  /// @return Given text padded to field
  public static final Object[] p_pad = new Object[] { "length", "*pad", null };
  public Any m_pad(int length, String pad)
  {
    if (pad == null) {
      pad = " ";
    }
    boolean reverse = false;
    if (length < 0) {
      reverse = true;
      length = -length;
    }
    StringBuffer buffer = new StringBuffer(length);
    int i = _string.length();
    int padlen = pad.length();
    if (reverse) {
      buffer.append(_string);
    }
    while(i < length) {
      if (i + padlen > length) {
        buffer.append(pad.substring(0, length - i));
        break;
      } else {
        buffer.append(pad);
        i += padlen;
      }
    }
    if (!reverse) {
      buffer.append(_string);
    }
    return new AnyString(buffer.toString());
  }


  /// @method chop
  /// Chops suffix out of string.
  /// @synopsis string chop() ; Chops all whitespaces
  /// @synopsis string chop(string suffix) ; Chop given suffix
  public static final Object[] p_chop = new Object[] { "*suffix", null };
  public Any m_chop(String suffix
  {
    String str = _string;
    int len = str.length();
    if (suffix != null) {
      if (str.endsWith(suffix)) {
        return Any.create(str.substring(0, len - suffix.length()));
      }
    } else {
      int i = len;
      while((i>0) && Character.isWhitespace(str.charAt(i-1))) {
        i--;
      }
      if (i < len) {
        return Any.create(str.substring(0, i));
      }
    }
    return this;
  }
 

  /// @method eat
  /// Removes given prefix out of string.
  /// @synopsis string eat() ; Removes all whitespaces
  /// @synopsis string eat(string prefix) ; Removes given prefix
  public static final Object[] p_eat = new Object[] { "*prefix", null };
  public Any m_eat(String prefix
  {
    String str = _string;
    int len = str.length();
    if (prefix != null) {
      if (str.startsWith(prefix)) {
        return Any.create(str.substring(prefix.length()));
      }
    } else {
      int i = 0;
      while((i<len) && Character.isWhitespace(str.charAt(i))) {
        i++;
      }
      if (i > 0) {
        return Any.create(str.substring(i));
      }
    }
    return this;
  }


  transient public static final anvil.script.compiler.NativeClass __class__ =
    new anvil.script.compiler.NativeClass("string", AnyString.class, AnySequence.__class__,
    //DOC{{
    ""+
      "\n" +
      " @class string\n" +
      " The <code>string</code> class represents character strings. \n" +
      " String is a sequence of characters.\n" +
      " @constructor string\n" +
      " Creates new string from the string representation of given parameter.\n" +
      " @synopsis string(object value)\n" +
      " @method length\n" +
      " Returns the length of this string.\n" +
      " @synopsis int length()\n" +
      " @method unquote\n" +
      " Unquotes all html entities from this string.\n" +
      " @synopsis string unquote()\n" +
      " @method quote\n" +
      " Converts all applicable characters with corresponding\n" +
      " html entity.\n" +
      " @synopsis string quote()\n" +
      " @method quoteMeta\n" +
      " Converts all applicable characters under &gt;127 with corresponding\n" +
      " html entity.\n" +
      " @synopsis string quoteMeta()\n" +
      " @method quoteText\n" +
      " Converts all applicable characters over &gt;127 with corresponding\n" +
      " html entity.\n" +
      " @synopsis string quoteText()\n" +
      " @method compress\n" +
      " Compresses consequtive white space characeters into single\n" +
      " space.\n" +
      " @synopsis string compress()\n" +
      " @method capitalize\n" +
      " Capitalizes the first character of all words.\n" +
      " @synopsis string capitalize()\n" +
      " @method capitalizeFirst\n" +
      " Capitalizes first character of first word.\n" +
      " @synopsis string capitalizeFirst()\n" +
      " @method nowrap\n" +
      " Converts white spaces into <code>&amp;nbsp;</code>.\n" +
      " @synopsis string nowrap()\n" +
      " @method encodeURL\n" +
      " URL encodes this string.\n" +
      " @synopsis string encodeURL()\n" +
      " @method decodeURL\n" +
      " Decodes URL encoding from this string.\n" +
      " @synopsis string decodeURL()\n" +
      " @method encode\n" +
      " URL encodes this string.\n" +
      " @synopsis string encode()\n" +
      " @method decode\n" +
      " Decodes URL encoding from this string.\n" +
      " @synopsis string decode()\n" +
      " @method escape\n" +
      " Escapes string using the rules of anvil string literal.\n" +
      " @synopsis string escape()\n" +
      " @method unescape\n" +
      " Unescapes backslash quotes.\n" +
      " @synopsis string unescape()\n" +
      " @synopsis string unescape(boolean withQuotes)\n" +
      " @method nl2br\n" +
      " Convers all line feeds into <code>&lt;br&gt;\n</code>\n" +
      " @synopsis string nl2br()\n" +
      " @method toUpper\n" +
      " Converts all lower case characeters into corresponding upper case\n" +
      " characeters.\n" +
      " @synopsis string toUpper()\n" +
      " @method toLower\n" +
      " Converts all upper case characeters into corresponding lower case\n" +
      " characeters.\n" +
      " @synopsis string toLower()\n" +
      " @method trim\n" +
      " Removes whitespace characters from the beginning and end of this string.\n" +
      " @synopsis string trim()\n" +
      " @method trimLeft\n" +
      " Removes whitespace characters from the beginning this string.\n" +
      " @synopsis string trimLeft()\n" +
      " @method trimRight\n" +
      " Removes whitespace characters from the end this string.\n" +
      " @synopsis string trimRight()\n" +
      " @method substring\n" +
      " Returns a substring from the given region of this string.\n" +
      " @synopsis string substring(int start)\n" +
      " @synopsis string substring(int start, int end)\n" +
      " @param start Starting index, included\n" +
      " @param end Ending index, excluded\n" +
      " @method charAt\n" +
      " Returns single character from this string.\n" +
      " @synopsis string charAt(int index)\n" +
      " @param index Index to string\n" +
      " @method charCodeAt\n" +
      " Returns the character code at the speicified index.\n" +
      " @synopsis int charCodeAt(int index)\n" +
      " @param index Index to string\n" +
      " @method indexOf\n" +
      " Returns the index within this string of the first occurrence of the \n" +
      " specified string.\n" +
      " @synopsis int indexOf(string needle)\n" +
      " @synopsis int indexOf(string needle, int fromIndex)\n" +
      " @param needle String to search for\n" +
      " @param fromIndex Starting index of search\n" +
      " @return The index of first occurence, or -1 if it doesn't occur.\n" +
      " @method lastIndexOf\n" +
      " Returns the index within this string of the last occurrence of the \n" +
      " specified string.\n" +
      " @synopsis int lastIndexOf(string needle)\n" +
      " @synopsis int lastIndexOf(string needle, int fromIndex)\n" +
      " @param needle String to search for\n" +
      " @param fromIndex Starting index of search\n" +
      " @return The index of last occurence, or -1 if it doesn't occur.\n" +
      " @method startsWith\n" +
      " Checks if this string starts with given prefix.\n" +
      " @synopsis boolean startsWith(string prefix)\n" +
      " @method endsWith\n" +
      " Checks if this string ends with given suffix.\n" +
      " @synopsis boolean endsWith(string suffix)\n" +
      " @method compareToIgnoreCase\n" +
      " Compares this string and given string, lower- and\n" +
      " uppercase characters are considered equal.\n" +
      " @synopsis int compareToIgnoreCase(string other)\n" +
      " @return -1 if <code>this&lt;other</code>,\n" +
      "          0 if <code>this==other</code>,\n" +
      "          1 if <code>this&gt;other</code>,\n" +
      " @method equalsIgnoreCase\n" +
      " Checks if this string is equal to given string, lower- and\n" +
      " uppercase characters are considered equal\n" +
      " @synopsis boolean equalsIgnoreCase(string other)\n" +
      " @param other String to compare with\n" +
      " @method explode\n" +
      " Splits this string into regions using given set of delimiter \n" +
      " characters.\n" +
      " @synopsis list explode(string delimiters)\n" +
      " @synopsis list explode(string delimiters, boolean returnEmpty)\n" +
      " @param delimiters Set of delimiter characters\n" +
      " @param returnEmpty If <code>true</code> also empty regions are returned, if\n" +
      " omitted or <code>false</code> empty regions are not returned.\n" +
      " @method repeat\n" +
      " Repeats this string <code>amount</code> times.\n" +
      " @synopsis string repeat(int amount)\n" +
      " @method translate\n" +
      " For each character in this string: if character appears\n" +
      " in <code>from</code> string, converts it to character \n" +
      " at the same index at <code>to</code>.\n" +
      " @synopsis string translate(string from, string to)\n" +
      " @param from Source character mapping\n" +
      " @param to Target character mapping\n" +
      " @return Translated string\n" +
      " @method replace\n" +
      " Replaces all occurences of <code>from</code> into <code>to</code>.\n" +
      " @synopsis string replace(string from, string to)\n" +
      " @param from Regions to replace\n" +
      " @param to Replacement\n" +
      " @method unserialize\n" +
      " Unserializes data contained in this string.\n" +
      " @synopsis object unserialize()\n" +
      " @return Unserialized data\n" +
      " @throws CorruptedSerialization If serialized data is corrupted\n" +
      " @method matches\n" +
      " Checks if this (whole) string matches given \n" +
      " regular expression. \n" +
      " @synopsis boolean matches(string pattern)\n" +
      " @synopsis boolean matches(string pattern, array matches)\n" +
      " @synopsis boolean matches(string pattern, list matches)\n" +
      " @synopsis boolean matches(pattern pattern)\n" +
      " @synopsis boolean matches(pattern pattern, array matches)\n" +
      " @synopsis boolean matches(pattern pattern, list matches)\n" +
      " @param pattern Regular expression pattern\n" +
      " @return Matches or boolean\n" +
      " @throws MalformedPattern If pattern is invalid\n" +
      " @method contains\n" +
      " Checks if some region of this string matches given \n" +
      " regular expression.\n" +
      " @synopsis boolean contains(string pattern)\n" +
      " @synopsis boolean contains(string pattern, array matches)\n" +
      " @synopsis boolean contains(string pattern, list matches)\n" +
      " @synopsis boolean contains(pattern pattern)\n" +
      " @synopsis boolean contains(pattern pattern, array matches)\n" +
      " @synopsis boolean contains(pattern pattern, list matches)\n" +
      " @param pattern Regular expression pattern\n" +
      " @return Matches or boolean\n" +
      " @throws MalformedPattern If pattern is invalid\n" +
      " @method find\n" +
      " Finds all regions from this string mathing given regular\n" +
      " expression pattern.\n" +
      " @synopsis enumeration find(string pattern)\n" +
      " @synopsis enumeration find(pattern pattern)\n" +
      " @param pattern Regular expression pattern\n" +
      " @return Enumeration of strings\n" +
      " @throws MalformedPattern If pattern is invalid\n" +
      " @method split\n" +
      " Splits this string using given regular expression pattern as \n" +
      " delimiter.\n" +
      " @synopsis list split(string pattern)\n" +
      " @synopsis list split(pattern pattern)\n" +
      " @param pattern Regular expression pattern\n" +
      " @throws MalformedPattern If pattern is invalid\n" +
      " @method divide\n" +
      " Divides string to two pieces, using <code>delim</code> as delimiter.\n" +
      " Example 1. \"foo.bar.foo\".divide(\".\") returns (\"foo\", \"bar.foo\")\n" +
      " Example 2. \"foo.bar.foo\".divide(\"|\") returns (\"foo.bar.foo\", null)\n" +
      " Example 3. \"foo.bar.fiu\".divide(\".\", true) return (\"fiu\", \"foo.bar\")\n" +
      " @synopsis list divide(string delim)\n" +
      " @synopsis list divide(string delim, boolean dir)\n" +
      " @param delim Delimiter character(s)\n" +
      " @param dir Direction (default false), false = from start of the string,\n" +
      " true = from end of the string\n" +
      " @method substitute\n" +
      " Substitutes all regions from this string matching given\n" +
      " regular expression.\n" +
      " @synopsis string substitute(string pattern, string replacement [, int amount] )\n" +
      " @synopsis string substitute(pattern pattern, string replacement [, int amount] )\n" +
      " @synopsis string substitute(string pattern, Function replacer [, int amount] )\n" +
      " @synopsis string substitute(pattern pattern, Function replacer [, int amount] )\n" +
      " @param pattern Regular expression pattern\n" +
      " @param replacement Replacement string\n" +
      " @param replacer Replace function: \n" +
      " @param amount Number of occurences to replace, if omitted, all occurences are substituted.\n" +
      " <code>function replacer(list matchedGroups)</code>.\n" +
      " @throws MalformedPattern If pattern is invalid\n" +
      " @method substituteFirst\n" +
      " Substitutes first region from this string matching given\n" +
      " regular expression.\n" +
      " @synopsis string substituteFirst(string pattern, string replacement)\n" +
      " @synopsis string substituteFirst(pattern pattern, string replacement)\n" +
      " @synopsis string substituteFirst(string pattern, Function replacer)\n" +
      " @synopsis string substituteFirst(pattern pattern, Function replacer)\n" +
      " @param pattern Regular expression pattern\n" +
      " @param replacement Replacement string\n" +
      " @param replacer Replace function: \n" +
      " <code>function replacer(list matchedGroups)</code>.\n" +
      " @throws MalformedPattern If pattern is invalid\n" +
      " @method hexToBinary \n" +
      " Converts string to binary, \n" +
      " assuming that two characters produce one byte: 414243 -> binary(abc) \n" +
      " @synopsis binary hexToBinary()\n" +
      " @method pad\n" +
      " Pads text left or right to field.\n" +
      " @synopsis string pad(int length)\n" +
      " @synopsis string pad(int length, string padding)\n" +
      " @param length Length of field, positive for right padding, negative\n" +
      "               for left padding.\n" +
      " @param padding Padding character, default is space.\n" +
      " @return Given text padded to field\n" +
      " @method chop\n" +
      " Chops suffix out of string.\n" +
      " @synopsis string chop() ; Chops all whitespaces\n" +
      " @synopsis string chop(string suffix) ; Chop given suffix\n" +
      " @method eat\n" +
      " Removes given prefix out of string.\n" +
      " @synopsis string eat() ; Removes all whitespaces\n" +
      " @synopsis string eat(string prefix) ; Removes given prefix\n"
    //}}DOC
    );

 
}
TOP

Related Classes of anvil.core.AnyString

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.