add ColLayoutConverter
This commit is contained in:
1 parent
6e1d294202
commit
1bfa5b6854
5 files changed
+452
-2
No files matched your search
@@ -0,0 +1,233 @@
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// File: TokenizerHelper.cs
|
||||
//
|
||||
// Description: This file contains the implementation of TokenizerHelper.
|
||||
// This class should be used by most - if not all - MIL parsers.
|
||||
//
|
||||
// History:
|
||||
// 05/19/2003 : Microsoft - Created it
|
||||
// 05/20/2003 : Microsoft - Moved to Shared
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace HandyControl.Tools
|
||||
{
|
||||
internal class TokenizerHelper
|
||||
{
|
||||
private char _quoteChar;
|
||||
|
||||
private char _argSeparator;
|
||||
|
||||
private string _str;
|
||||
|
||||
private int _strLen;
|
||||
|
||||
private int _charIndex;
|
||||
|
||||
private int _currentTokenIndex;
|
||||
|
||||
private int _currentTokenLength;
|
||||
|
||||
public bool FoundSeparator { get; private set; }
|
||||
|
||||
public TokenizerHelper(string str, IFormatProvider formatProvider)
|
||||
{
|
||||
var numberSeparator = GetNumericListSeparator(formatProvider);
|
||||
Initialize(str, '\'', numberSeparator);
|
||||
}
|
||||
|
||||
private void Initialize(string str, char quoteChar, char separator)
|
||||
{
|
||||
_str = str;
|
||||
_strLen = str?.Length ?? 0;
|
||||
_currentTokenIndex = -1;
|
||||
_quoteChar = quoteChar;
|
||||
_argSeparator = separator;
|
||||
|
||||
// immediately forward past any whitespace so
|
||||
// NextToken() logic always starts on the first
|
||||
// character of the next token.
|
||||
while (_charIndex < _strLen)
|
||||
{
|
||||
if (!char.IsWhiteSpace(_str, _charIndex))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
++_charIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetCurrentToken() =>
|
||||
_currentTokenIndex < 0 ? null : _str.Substring(_currentTokenIndex, _currentTokenLength);
|
||||
|
||||
internal bool NextToken() => NextToken(false);
|
||||
|
||||
public bool NextToken(bool allowQuotedToken) => NextToken(allowQuotedToken, _argSeparator);
|
||||
|
||||
public bool NextToken(bool allowQuotedToken, char separator)
|
||||
{
|
||||
_currentTokenIndex = -1; // reset the currentTokenIndex
|
||||
FoundSeparator = false; // reset
|
||||
|
||||
// If we're at end of the string, just return false.
|
||||
if (_charIndex >= _strLen)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var currentChar = _str[_charIndex];
|
||||
|
||||
// setup the quoteCount
|
||||
var quoteCount = 0;
|
||||
|
||||
// If we are allowing a quoted token and this token begins with a quote,
|
||||
// set up the quote count and skip the initial quote
|
||||
if (allowQuotedToken &&
|
||||
currentChar == _quoteChar)
|
||||
{
|
||||
quoteCount++; // increment quote count
|
||||
++_charIndex; // move to next character
|
||||
}
|
||||
|
||||
var newTokenIndex = _charIndex;
|
||||
var newTokenLength = 0;
|
||||
|
||||
// loop until hit end of string or hit a , or whitespace
|
||||
// if at end of string ust return false.
|
||||
while (_charIndex < _strLen)
|
||||
{
|
||||
currentChar = _str[_charIndex];
|
||||
|
||||
// if have a QuoteCount and this is a quote
|
||||
// decrement the quoteCount
|
||||
if (quoteCount > 0)
|
||||
{
|
||||
// if anything but a quoteChar we move on
|
||||
if (currentChar == _quoteChar)
|
||||
{
|
||||
--quoteCount;
|
||||
|
||||
// if at zero which it always should for now
|
||||
// break out of the loop
|
||||
if (0 == quoteCount)
|
||||
{
|
||||
++_charIndex; // move past the quote
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (char.IsWhiteSpace(currentChar) || currentChar == separator)
|
||||
{
|
||||
if (currentChar == separator)
|
||||
{
|
||||
FoundSeparator = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
++_charIndex;
|
||||
++newTokenLength;
|
||||
}
|
||||
|
||||
// if quoteCount isn't zero we hit the end of the string
|
||||
// before the ending quote
|
||||
if (quoteCount > 0)
|
||||
{
|
||||
throw new InvalidOperationException("TokenizerHelperMissingEndQuote");
|
||||
}
|
||||
|
||||
ScanToNextToken(separator); // move so at the start of the nextToken for next call
|
||||
|
||||
// finally made it, update the _currentToken values
|
||||
_currentTokenIndex = newTokenIndex;
|
||||
_currentTokenLength = newTokenLength;
|
||||
|
||||
if (_currentTokenLength < 1)
|
||||
{
|
||||
throw new InvalidOperationException("TokenizerHelperEmptyToken");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ScanToNextToken(char separator)
|
||||
{
|
||||
// if already at end of the string don't bother
|
||||
if (_charIndex >= _strLen) return;
|
||||
|
||||
var currentChar = _str[_charIndex];
|
||||
|
||||
// check that the currentChar is a space or the separator. If not
|
||||
// we have an error. this can happen in the quote case
|
||||
// that the char after the quotes string isn't a char.
|
||||
if (currentChar != separator && !char.IsWhiteSpace(currentChar))
|
||||
{
|
||||
throw new InvalidOperationException("TokenizerHelperExtraDataEncountered");
|
||||
}
|
||||
|
||||
// loop until hit a character that isn't
|
||||
// an argument separator or whitespace.
|
||||
// !!!Todo: if more than one argSet throw an exception
|
||||
var argSepCount = 0;
|
||||
while (_charIndex < _strLen)
|
||||
{
|
||||
currentChar = _str[_charIndex];
|
||||
|
||||
if (currentChar == separator)
|
||||
{
|
||||
FoundSeparator = true;
|
||||
++argSepCount;
|
||||
_charIndex++;
|
||||
|
||||
if (argSepCount > 1)
|
||||
{
|
||||
throw new InvalidOperationException("TokenizerHelperEmptyToken");
|
||||
}
|
||||
}
|
||||
else if (char.IsWhiteSpace(currentChar))
|
||||
{
|
||||
++_charIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if there was a separatorChar then we shouldn't be
|
||||
// at the end of string or means there was a separator
|
||||
// but there isn't an arg
|
||||
|
||||
if (argSepCount > 0 && _charIndex >= _strLen)
|
||||
{
|
||||
throw new InvalidOperationException("TokenizerHelperEmptyToken");
|
||||
}
|
||||
}
|
||||
|
||||
internal static char GetNumericListSeparator(IFormatProvider provider)
|
||||
{
|
||||
var numericSeparator = ',';
|
||||
|
||||
// Get the NumberFormatInfo out of the provider, if possible
|
||||
// If the IFormatProvider doesn't not contain a NumberFormatInfo, then
|
||||
// this method returns the current culture's NumberFormatInfo.
|
||||
var numberFormat = NumberFormatInfo.GetInstance(provider);
|
||||
|
||||
// Is the decimal separator is the same as the list separator?
|
||||
// If so, we use the ";".
|
||||
if (numberFormat.NumberDecimalSeparator.Length > 0 && numericSeparator == numberFormat.NumberDecimalSeparator[0])
|
||||
{
|
||||
numericSeparator = ';';
|
||||
}
|
||||
|
||||
return numericSeparator;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user