};
// following method decodes an utf8 character from a byte buffer.
- // NOTE: If 'chars' is null, this function only counts bytes and chars
- // without writing anything.
+ // NOTE: If 'charCount' is < 0, this function only counts bytes and
+ // chars without writing anything.
// NOTE: BOM (0xEF 0xBB 0xBF) is not yet supported.
// See http://www.cl.cam.ac.uk/~mgk25/unicode.html
private unsafe static DecoderStatus InternalGetChar (
// convert this character to UTF-16
if (leftBits < (uint) 0x10000) {
- if (chars != null) {
+ if (charCount >= 0) {
if (charCount < 1)
return DecoderStatus.InsufficientSpace;
*chars = (char) leftBits;
}
charsProcessed++;
} else {
- if (chars != null) {
+ if (charCount >= 0) {
if (charCount < 2)
return DecoderStatus.InsufficientSpace;
leftBits -= (uint) 0x10000;
// This function is called when we want to flush the decoder state
// (i.e. in case of invalid UTF-8 characters or interrupted sequences)
- internal unsafe static void InternalGetChars_flush (
+ // TODO: if we run out of output space during fallback replacement an
+ // ArgumentException is thrown -- maybe this is not the correct
+ // behaviour
+ internal unsafe static void InternalGetCharsFlush (
char* chars, int charCount,
DecoderFallbackBuffer fallbackBuffer,
DecoderStatus s,
leftBits = leftBytes = procBytes = 0;
}
+ // InternalGetBytes processor. Can decode or count space needed for
+ // decoding, depending on the enabled mode:
+ // - decoder
+ // enabled when charCount >= 0 (but chars may be null)
+ // - counter
+ // enabled when chars == null && charCount < 0
internal unsafe static DecoderStatus InternalGetChars (
byte* bytes, int byteCount,
char* chars, int charCount,
else
if (byteCount > 0 && bytes == null)
throw new ArgumentNullException ("bytes");
- if (charCount < 0)
- throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_NonNegative"));
- else
- if (charCount > 0 && chars == null)
+ if (chars == null) {
+ if (charCount > 0)
throw new ArgumentNullException ("chars");
+ } else {
+ if (charCount < 0)
+ throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_NonNegative"));
+ }
// reset counters
charsProcessed = 0;
ref leftBytes, ref leftBits, ref procBytes)
: InternalGetChar (
bytes + bytesProcessed, byteCount - bytesProcessed,
- null, 0,
+ null, charCount,
out t_bytesProcessed, out t_charsProcessed,
ref leftBytes, ref leftBits, ref procBytes);
case DecoderStatus.InvalidStart:
case DecoderStatus.InvalidChar:
case DecoderStatus.SurrogateFound:
- InternalGetChars_flush (
+ InternalGetCharsFlush (
chars, charCount,
fallbackBuffer,
s,
case DecoderStatus.InputRunOut:
if (flush)
- InternalGetChars_flush (
+ InternalGetCharsFlush (
chars, charCount,
fallbackBuffer,
s,
return DecoderStatus.Ok;
}
- // Get the characters that result from decoding a byte buffer.
- internal unsafe static DecoderStatus InternalGetChars (
+ internal unsafe static DecoderStatus InternalGetCharsDecode (
+ byte* bytes, int byteCount,
+ char* chars, int charCount,
+ DecoderFallbackBuffer fallbackBuffer,
+ out int bytesProcessed, out int charsProcessed,
+ ref uint leftBytes, ref uint leftBits, ref uint procBytes,
+ bool flush)
+ {
+ if (byteCount < 0)
+ throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array"));
+ if (charCount < 0)
+ throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
+
+ return InternalGetChars (
+ bytes, byteCount,
+ chars, charCount,
+ fallbackBuffer,
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ flush);
+ }
+
+ internal unsafe static DecoderStatus InternalGetCharsDecode (
byte[] bytes, int byteIndex, int byteCount,
char[] chars, int charIndex,
DecoderFallbackBuffer fallbackBuffer,
ref uint leftBytes, ref uint leftBits, ref uint procBytes,
bool flush)
{
- // Validate the parameters.
if (bytes == null)
throw new ArgumentNullException ("bytes");
+ if (chars == null)
+ throw new ArgumentNullException ("chars");
if (byteIndex < 0 || byteIndex > bytes.Length)
throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
if (byteCount < 0 || byteCount > (bytes.Length - byteIndex))
throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array"));
- if (charIndex < 0 || charIndex > (chars != null && chars.Length > 0 ? chars.Length : 0))
+ if (charIndex < 0 || charIndex > chars.Length)
throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
fixed (char* cptr = chars) {
fixed (byte* bptr = bytes) {
return InternalGetChars (
bptr + byteIndex, byteCount,
- chars != null ? cptr + charIndex : null,
- chars != null ? chars.Length - charIndex : 0,
+ cptr + charIndex, chars.Length - charIndex,
fallbackBuffer,
out bytesProcessed, out charsProcessed,
ref leftBytes, ref leftBits, ref procBytes,
}
}
+ internal unsafe static DecoderStatus InternalGetCharsCount (
+ byte* bytes, int byteCount,
+ DecoderFallbackBuffer fallbackBuffer,
+ out int bytesProcessed, out int charsProcessed,
+ ref uint leftBytes, ref uint leftBits, ref uint procBytes,
+ bool flush)
+ {
+ if (byteCount < 0)
+ throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array"));
+
+ return InternalGetChars (
+ bytes, byteCount,
+ null, -1,
+ fallbackBuffer,
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ flush);
+ }
+
+ internal unsafe static DecoderStatus InternalGetCharsCount (
+ byte[] bytes, int byteIndex, int byteCount,
+ DecoderFallbackBuffer fallbackBuffer,
+ out int bytesProcessed, out int charsProcessed,
+ ref uint leftBytes, ref uint leftBits, ref uint procBytes,
+ bool flush)
+ {
+ if (bytes == null)
+ throw new ArgumentNullException ("bytes");
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
+ if (byteCount < 0 || byteCount > (bytes.Length - byteIndex))
+ throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_Array"));
+
+ fixed (byte* bptr = bytes) {
+ return InternalGetChars (
+ bptr + byteIndex, byteCount,
+ null, -1,
+ fallbackBuffer,
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ flush);
+ }
+ }
+
///////////////////////////////////////////////////////////////////////
// INTERNAL ENCODING FUNCTION (CHAR/UTF16 -> UTF8)
///////////////////////////////////////////////////////////////////////
// This function is called when we want to flush the decoder state
// (i.e. in case of invalid UTF-16 characters or dangling surrogates)
+ // TODO: if we run out of output space during fallback replacement an
+ // ArgumentException is thrown -- maybe this is not the correct
+ // behaviour
internal unsafe static void InternalGetBytesFlush (
byte* bytes, int byteCount,
EncoderFallbackBuffer fallbackBuffer,
else
if (charCount > 0 && chars == null)
throw new ArgumentNullException ("chars");
- if (bytes == null)
- {
+ if (bytes == null) {
if (byteCount > 0)
throw new ArgumentNullException ("bytes");
} else {
throw new ArgumentNullException ("chars");
if (bytes == null)
throw new ArgumentNullException ("bytes");
- if (charIndex < 0 || charIndex >= chars.Length)
+ if (charIndex < 0 || charIndex > chars.Length)
throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
if (charCount < 0 || charCount > (chars.Length - charIndex))
throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
{
if (chars == null)
throw new ArgumentNullException ("chars");
- if (charIndex < 0 || charIndex >= chars.Length)
+ if (charIndex < 0 || charIndex > chars.Length)
throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
if (charCount < 0 || charCount > (chars.Length - charIndex))
throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
- unsafe {
- fixed (char *cptr = chars) {
- return InternalGetBytes (
- cptr + charIndex, charCount,
- null, -1,
- fallbackBuffer,
- out charsProcessed, out bytesProcessed,
- ref leftChar,
- flush);
- }
+ fixed (char *cptr = chars) {
+ return InternalGetBytes (
+ cptr + charIndex, charCount,
+ null, -1,
+ fallbackBuffer,
+ out charsProcessed, out bytesProcessed,
+ ref leftChar,
+ flush);
}
}
{
int bytesProcessed, charsProcessed;
uint leftBytes = 0, leftBits = 0, procBytes = 0;
- InternalGetChars (
- bytes, index, count,
- null, 0,
- DecoderFallback.CreateFallbackBuffer (),
- out bytesProcessed, out charsProcessed,
- ref leftBytes, ref leftBits, ref procBytes,
- true);
+ InternalGetCharsCount (
+ bytes, index, count,
+ DecoderFallback.CreateFallbackBuffer (),
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ true);
return charsProcessed;
}
{
int bytesProcessed, charsProcessed;
uint leftBytes = 0, leftBits = 0, procBytes = 0;
- InternalGetChars (
- bytes, count,
- null, 0,
- DecoderFallback.CreateFallbackBuffer (),
- out bytesProcessed, out charsProcessed,
- ref leftBytes, ref leftBits, ref procBytes,
- true);
+ InternalGetCharsCount (
+ bytes, count,
+ DecoderFallback.CreateFallbackBuffer (),
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ true);
return charsProcessed;
}
{
int bytesProcessed, charsProcessed;
uint leftBytes = 0, leftBits = 0, procBytes = 0;
- DecoderStatus status;
-
- status = InternalGetChars (
- bytes, byteIndex, byteCount,
- chars, charIndex,
- DecoderFallback.CreateFallbackBuffer (),
- out bytesProcessed, out charsProcessed,
- ref leftBytes, ref leftBits, ref procBytes,
- true);
- if (status == DecoderStatus.InsufficientSpace)
+
+ if (InternalGetCharsDecode (
+ bytes, byteIndex, byteCount,
+ chars, charIndex,
+ DecoderFallback.CreateFallbackBuffer (),
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ true) == DecoderStatus.InsufficientSpace)
throw new ArgumentException ("Insufficient Space", "bytes");
return charsProcessed;
{
int bytesProcessed, charsProcessed;
uint leftBytes = 0, leftBits = 0, procBytes = 0;
- DecoderStatus status;
- status = InternalGetChars (
- bytes, byteCount,
- chars, charCount,
- DecoderFallback.CreateFallbackBuffer (),
- out bytesProcessed, out charsProcessed,
- ref leftBytes, ref leftBits, ref procBytes,
- true);
- if (status == DecoderStatus.InsufficientSpace)
+ if (InternalGetCharsDecode (
+ bytes, byteCount,
+ chars, charCount,
+ DecoderFallback.CreateFallbackBuffer (),
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ true) == DecoderStatus.InsufficientSpace)
throw new ArgumentException ("Insufficient Space", "bytes");
return charsProcessed;
public override int GetCharCount (byte[] bytes, int index, int count, bool flush)
{
int bytesProcessed, charsProcessed;
- InternalGetChars (
- bytes, index, count,
- null, 0,
- this.FallbackBuffer,
- out bytesProcessed, out charsProcessed,
- ref leftBytes, ref leftBits, ref procBytes,
- flush);
+ InternalGetCharsCount (
+ bytes, index, count,
+ this.FallbackBuffer,
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ flush);
return charsProcessed;
}
public unsafe override int GetCharCount (byte* bytes, int count, bool flush)
{
int bytesProcessed, charsProcessed;
- InternalGetChars (
- bytes, count,
- null, 0,
- this.FallbackBuffer,
- out bytesProcessed, out charsProcessed,
- ref leftBytes, ref leftBits, ref procBytes,
- flush);
+ InternalGetCharsCount (
+ bytes, count,
+ this.FallbackBuffer,
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ flush);
return charsProcessed;
}
char* chars, int charCount, bool flush)
{
int bytesProcessed, charsProcessed;
- DecoderStatus status;
-
- status = InternalGetChars (
- bytes, byteCount,
- chars, charCount,
- this.FallbackBuffer,
- out bytesProcessed, out charsProcessed,
- ref leftBytes, ref leftBits, ref procBytes,
- flush);
- if (status == DecoderStatus.InsufficientSpace)
+ if (InternalGetCharsDecode (
+ bytes, byteCount,
+ chars, charCount,
+ this.FallbackBuffer,
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ flush) == DecoderStatus.InsufficientSpace)
throw new ArgumentException ("Insufficient Space", "bytes");
return charsProcessed;
}
int byteCount, char[] chars, int charIndex, bool flush)
{
int bytesProcessed, charsProcessed;
- DecoderStatus status;
-
- status = InternalGetChars (
- bytes, byteIndex, byteCount,
- chars, charIndex,
- this.FallbackBuffer,
- out bytesProcessed, out charsProcessed,
- ref leftBytes, ref leftBits, ref procBytes,
- flush);
- if (status == DecoderStatus.InsufficientSpace)
+ if (InternalGetCharsDecode (
+ bytes, byteIndex, byteCount,
+ chars, charIndex,
+ this.FallbackBuffer,
+ out bytesProcessed, out charsProcessed,
+ ref leftBytes, ref leftBits, ref procBytes,
+ flush) == DecoderStatus.InsufficientSpace)
throw new ArgumentException ("Insufficient Space", "bytes");
return charsProcessed;
}
char* chars, int charCount, bool flush,
out int bytesUsed, out int charsUsed, out bool completed)
{
- UTF8Encoding.InternalGetChars (
+ InternalGetCharsDecode (
bytes, byteCount,
chars, charCount,
this.FallbackBuffer,