|
//-----------------------------------------------------------------------
//
// Microsoft Windows Client Platform
// Copyright (C) Microsoft Corporation, 2003
//
// File: CharacterBufferRange.cs
//
// Contents: A range of character buffer
//
// Spec: http://team/sites/Avalon/Specs/Text%20Formatting%20API.doc
//
// Created: 2-5-2004 Worachai Chaoweeraprasit (wchao)
//
//------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Security;
using MS.Internal;
using SR = MS.Internal.PresentationCore.SR;
using SRID = MS.Internal.PresentationCore.SRID;
namespace System.Windows.Media.TextFormatting
{
/// <summary>
/// A string of characters
/// </summary>
public struct CharacterBufferRange : IEquatable<CharacterBufferRange>
{
private CharacterBufferReference _charBufferRef;
private int _length;
#region Constructor
/// <summary>
/// Construct character buffer reference from character array
/// </summary>
/// <param name="characterArray">character array</param>
/// <param name="offsetToFirstChar">character buffer offset to the first character</param>
/// <param name="characterLength">character length</param>
public CharacterBufferRange(
char[] characterArray,
int offsetToFirstChar,
int characterLength
)
: this(
new CharacterBufferReference(characterArray, offsetToFirstChar),
characterLength
)
{}
/// <summary>
/// Construct character buffer reference from string
/// </summary>
/// <param name="characterString">character string</param>
/// <param name="offsetToFirstChar">character buffer offset to the first character</param>
/// <param name="characterLength">character length</param>
public CharacterBufferRange(
string characterString,
int offsetToFirstChar,
int characterLength
)
: this(
new CharacterBufferReference(characterString, offsetToFirstChar),
characterLength
)
{}
/// <summary>
/// Construct character buffer reference from unsafe character string
/// </summary>
/// <param name="unsafeCharacterString">pointer to character string</param>
/// <param name="characterLength">character length</param>
/// <SecurityNote>
/// Critical: this stores a pointer to an unmanaged string of characters
/// PublicOK: The caller needs unmanaged code permission in order to pass unsafe pointers to us.
/// </SecurityNote>
[SecurityCritical]
[CLSCompliant(false)]
public unsafe CharacterBufferRange(
char* unsafeCharacterString,
int characterLength
)
: this(
new CharacterBufferReference(unsafeCharacterString, characterLength),
characterLength
)
{}
/// <summary>
/// Construct a character string from character buffer reference
/// </summary>
/// <param name="characterBufferReference">character buffer reference</param>
/// <param name="characterLength">number of characters</param>
internal CharacterBufferRange(
CharacterBufferReference characterBufferReference,
int characterLength
)
{
if (characterLength < 0)
{
throw new ArgumentOutOfRangeException("characterLength", SR.Get(SRID.ParameterCannotBeNegative));
}
int maxLength = (characterBufferReference.CharacterBuffer != null) ?
characterBufferReference.CharacterBuffer.Count - characterBufferReference.OffsetToFirstChar :
0;
if (characterLength > maxLength)
{
throw new ArgumentOutOfRangeException("characterLength", SR.Get(SRID.ParameterCannotBeGreaterThan, maxLength));
}
_charBufferRef = characterBufferReference;
_length = characterLength;
}
/// <summary>
/// Construct a character string from part of another character string
/// </summary>
internal CharacterBufferRange(
CharacterBufferRange characterBufferRange,
int offsetToFirstChar,
int characterLength
) :
this (
characterBufferRange.CharacterBuffer,
characterBufferRange.OffsetToFirstChar + offsetToFirstChar,
characterLength
)
{}
/// <summary>
/// Construct a character string object from string
/// </summary>
internal CharacterBufferRange(
string charString
) :
this(
new StringCharacterBuffer(charString),
0,
charString.Length
)
{}
/// <summary>
/// Construct character buffer from memory buffer
/// </summary>
internal CharacterBufferRange(
CharacterBuffer charBuffer,
int offsetToFirstChar,
int characterLength
) :
this(
new CharacterBufferReference(charBuffer, offsetToFirstChar),
characterLength
)
{}
/// <summary>
/// Construct a character string object by extracting text info from text run
/// </summary>
internal CharacterBufferRange(TextRun textRun)
{
_charBufferRef = textRun.CharacterBufferReference;
_length = textRun.Length;
}
#endregion
/// <summary>
/// Compute hash code
/// </summary>
public override int GetHashCode()
{
return _charBufferRef.GetHashCode() ^ _length;
}
/// <summary>
/// Test equality with the input object
/// </summary>
/// <param name="obj"> The object to test </param>
public override bool Equals(object obj)
{
if (obj is CharacterBufferRange)
{
return Equals((CharacterBufferRange)obj);
}
return false;
}
/// <summary>
/// Test equality with the input CharacterBufferRange
/// </summary>
/// <param name="value"> The CharacterBufferRange value to test </param>
public bool Equals(CharacterBufferRange value)
{
return _charBufferRef.Equals(value._charBufferRef)
&& _length == value._length;
}
/// <summary>
/// Compare two CharacterBufferRange for equality
/// </summary>
/// <param name="left">left operand</param>
/// <param name="right">right operand</param>
/// <returns>whether or not two operands are equal</returns>
public static bool operator == (
CharacterBufferRange left,
CharacterBufferRange right
)
{
return left.Equals(right);
}
/// <summary>
/// Compare two CharacterBufferRange for inequality
/// </summary>
/// <param name="left">left operand</param>
/// <param name="right">right operand</param>
/// <returns>whether or not two operands are equal</returns>
public static bool operator != (
CharacterBufferRange left,
CharacterBufferRange right
)
{
return !(left == right);
}
/// <summary>
/// reference to the character buffer of a string
/// </summary>
public CharacterBufferReference CharacterBufferReference
{
get { return _charBufferRef; }
}
/// <summary>
/// number of characters in text source character store
/// </summary>
public int Length
{
get { return _length; }
}
/// <summary>
/// Getting an empty character string
/// </summary>
public static CharacterBufferRange Empty
{
get { return new CharacterBufferRange(); }
}
/// <summary>
/// Indicate whether the character string object contains no information
/// </summary>
internal bool IsEmpty
{
get { return _charBufferRef.CharacterBuffer == null || _length <= 0; }
}
/// <summary>
/// character memory buffer
/// </summary>
internal CharacterBuffer CharacterBuffer
{
get { return _charBufferRef.CharacterBuffer; }
}
/// <summary>
/// character offset relative to the beginning of buffer to
/// the first character of the run.
/// </summary>
internal int OffsetToFirstChar
{
get { return _charBufferRef.OffsetToFirstChar; }
}
/// <summary>
/// Return a character from the range, index is relative to the beginning of the range
/// </summary>
internal char this[int index]
{
get
{
Invariant.Assert(index >= 0 && index < _length);
return _charBufferRef.CharacterBuffer[_charBufferRef.OffsetToFirstChar + index];
}
}
}
}
|