blob: 164b229be22d97d1acc58976f4694997d6e50666 [file] [log] [blame]
using J2N.Text;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using WritableArrayAttribute = Lucene.Net.Support.WritableArrayAttribute;
namespace Lucene.Net.Analysis.Util
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// <summary>
/// A StringBuilder that allows one to access the array.
/// </summary>
public class OpenStringBuilder : ICharSequence
{
protected char[] m_buf;
protected int m_len;
public OpenStringBuilder()
: this(32)
{
}
bool ICharSequence.HasValue => m_buf != null;
public OpenStringBuilder(int size)
{
m_buf = new char[size];
}
public OpenStringBuilder(char[] arr, int len)
{
Set(arr, len);
}
public virtual int Length
{
get => m_len;
set => m_len = value;
}
public virtual void Set(char[] arr, int end)
{
this.m_buf = arr;
this.m_len = end;
}
[WritableArray]
[SuppressMessage("Microsoft.Performance", "CA1819", Justification = "Lucene's design requires some writable array properties")]
public virtual char[] Array => m_buf;
// LUCENENE NOTE: This is essentially a duplicate of Length (except that property can be set).
// .NET uses Length for StringBuilder anyway, so that property is preferable to this one.
//public virtual int Count // LUCENENET NOTE: This was size() in Lucene.
//{
// get{ return m_len; }
//}
public virtual int Capacity => m_buf.Length;
public virtual OpenStringBuilder Append(ICharSequence csq)
{
return Append(csq, 0, csq.Length);
}
public virtual OpenStringBuilder Append(ICharSequence csq, int start, int end) // LUCENENET TODO: API - change to startIndex/length to match .NET
{
EnsureCapacity(end - start);
for (int i = start; i < end; i++)
{
UnsafeWrite(csq[i]);
}
return this;
}
// LUCENENET specific - overload for string (more common in .NET than ICharSequence)
public virtual OpenStringBuilder Append(string csq)
{
return Append(csq, 0, csq.Length);
}
// LUCENENET specific - overload for string (more common in .NET than ICharSequence)
public virtual OpenStringBuilder Append(string csq, int start, int end) // LUCENENET TODO: API - change to startIndex/length to match .NET
{
EnsureCapacity(end - start);
for (int i = start; i < end; i++)
{
UnsafeWrite(csq[i]);
}
return this;
}
// LUCENENET specific - overload for StringBuilder
public virtual OpenStringBuilder Append(StringBuilder csq)
{
return Append(csq, 0, csq.Length);
}
// LUCENENET specific - overload for StringBuilder
public virtual OpenStringBuilder Append(StringBuilder csq, int start, int end) // LUCENENET TODO: API - change to startIndex/length to match .NET
{
EnsureCapacity(end - start);
for (int i = start; i < end; i++)
{
UnsafeWrite(csq[i]);
}
return this;
}
public virtual OpenStringBuilder Append(char c)
{
Write(c);
return this;
}
// LUCENENET specific - removed (replaced with this[])
//public virtual char CharAt(int index)
//{
// return m_buf[index];
//}
// LUCENENET specific - removed (replaced with this[])
//public virtual void SetCharAt(int index, char ch)
//{
// m_buf[index] = ch;
//}
// LUCENENET specific - added to .NETify
public virtual char this[int index]
{
get => m_buf[index];
set => m_buf[index] = value;
}
public virtual ICharSequence Subsequence(int startIndex, int length)
{
// From Apache Harmony String class
if (m_buf == null || (startIndex == 0 && length == m_buf.Length))
{
return new CharArrayCharSequence(m_buf);
}
if (startIndex < 0)
throw new ArgumentOutOfRangeException(nameof(startIndex));
if (length < 0)
throw new ArgumentOutOfRangeException(nameof(length));
if (startIndex + length > m_buf.Length)
throw new ArgumentOutOfRangeException("", $"{nameof(startIndex)} + {nameof(length)} > {nameof(Length)}");
char[] result = new char[length];
for (int i = 0, j = startIndex; i < length; i++, j++)
result[i] = m_buf[j];
return new CharArrayCharSequence(result);
}
public virtual void UnsafeWrite(char b)
{
m_buf[m_len++] = b;
}
public virtual void UnsafeWrite(int b)
{
UnsafeWrite((char)b);
}
public virtual void UnsafeWrite(char[] b, int off, int len)
{
System.Array.Copy(b, off, m_buf, this.m_len, len);
this.m_len += len;
}
// LUCENENET specific overload for StringBuilder
public virtual void UnsafeWrite(StringBuilder b, int off, int len)
{
b.CopyTo(off, m_buf, this.m_len, len);
this.m_len += len;
}
protected virtual void Resize(int len)
{
char[] newbuf = new char[Math.Max(m_buf.Length << 1, len)];
System.Array.Copy(m_buf, 0, newbuf, 0, Length);
m_buf = newbuf;
}
public virtual void EnsureCapacity(int capacity) // LUCENENET NOTE: renamed from reserve() in Lucene to match .NET StringBuilder
{
if (m_len + capacity > m_buf.Length)
{
Resize(m_len + capacity);
}
}
public virtual void Write(char b)
{
if (m_len >= m_buf.Length)
{
Resize(m_len + 1);
}
UnsafeWrite(b);
}
public virtual void Write(int b)
{
Write((char)b);
}
public void Write(char[] b)
{
Write(b, 0, b.Length);
}
public virtual void Write(char[] b, int off, int len)
{
EnsureCapacity(len);
UnsafeWrite(b, off, len);
}
public void Write(OpenStringBuilder arr)
{
Write(arr.m_buf, 0, arr.Length); // LUCENENET specific - changed to arr.m_len (original was just len - appears to be a bug)
}
// LUCENENET specific overload for StringBuilder
public void Write(StringBuilder arr)
{
EnsureCapacity(arr.Length);
UnsafeWrite(arr, 0, arr.Length);
}
public virtual void Write(string s)
{
EnsureCapacity(s.Length);
s.CopyTo(0, m_buf, m_len, s.Length - 0);
m_len += s.Length;
}
//public virtual void Flush() // LUCENENET specific - removed because this doesn't make much sense on a StringBuilder in .NET, and it is not used
//{
//}
public void Reset()
{
m_len = 0;
}
public virtual char[] ToCharArray()
{
char[] newbuf = new char[Length];
System.Array.Copy(m_buf, 0, newbuf, 0, Length);
return newbuf;
}
public override string ToString()
{
return new string(m_buf, 0, Length);
}
}
}