|
|
#include "stdafx.h"
#ifndef StdSentEnum_h
#include "stdsentenum.h"
#endif
#pragma warning (disable : 4296)
/***********************************************************************************************
* IsNumericCompactDate * *----------------------* * Description: * Checks the incoming Item's text to determine whether or not it * is a Date, and if so, which type. * * RegExp: * {[1-12]{'/' || '-' || '.'}[1-31]{'/' || '-' || '.'}[0-9999]} || * {[1-31]{'/' || '-' || '.'}[1-12]{'/' || '-' || '.'}[0-9999]} || * {[0-9999]{'/' || '-' || '.'}[1-12]{'/' || '-' || '.'}[1-31]} * * Types assigned: * Date ********************************************************************* AH **********************/ HRESULT CStdSentEnum::IsNumericCompactDate( TTSItemInfo*& pItemNormInfo, const WCHAR* Context, CSentItemMemory& MemoryManager ) { SPDBG_FUNC( "CStdSentEnum::IsNumericCompactDate" );
HRESULT hr = S_OK; WCHAR *pFirstChunk = 0, *pSecondChunk = 0, *pThirdChunk = 0, *pLeftOver = 0, *pDelimiter = 0; ULONG ulFirst = 0; ULONG ulSecond = 0; ULONG ulThird = 0; ULONG ulTokenLen = (ULONG)(m_pEndOfCurrItem - m_pNextChar); bool bThree = false, bTwo = false; bool fMonthDayYear = false, fDayMonthYear = false, fYearMonthDay = false;
//--- Max length of a string matching the regexp is 10 characters
if ( ulTokenLen > 10 ) { hr = E_INVALIDARG; } else { //--- Get the preferred order of the compact Date
if ( Context != NULL ) { if ( _wcsicmp( Context, L"Date_MDY" ) == 0 ) { fMonthDayYear = true; } else if ( _wcsicmp( Context, L"Date_DMY" ) == 0 ) { fDayMonthYear = true; } else if ( _wcsicmp( Context, L"Date_YMD" ) == 0 ) { fYearMonthDay = true; } else { if ( m_eShortDateOrder & MONTH_DAY_YEAR ) { fMonthDayYear = true; } else if ( m_eShortDateOrder & DAY_MONTH_YEAR ) { fDayMonthYear = true; } else { fYearMonthDay = true; } } } else { if ( m_eShortDateOrder & MONTH_DAY_YEAR ) { fMonthDayYear = true; } else if ( m_eShortDateOrder & DAY_MONTH_YEAR ) { fDayMonthYear = true; } else { fYearMonthDay = true; } }
pFirstChunk = (WCHAR*) m_pNextChar;
//----------------------------------------------
// First Try To Get Three Numerical Values
//----------------------------------------------
ulFirst = my_wcstoul( pFirstChunk, &pSecondChunk ); if ( pFirstChunk != pSecondChunk && ( pSecondChunk - pFirstChunk ) <= 4 ) { pDelimiter = pSecondChunk; if ( MatchDateDelimiter( &pSecondChunk ) ) { ulSecond = my_wcstoul( pSecondChunk, &pThirdChunk ); if ( pSecondChunk != pThirdChunk && ( pThirdChunk - pSecondChunk ) <= 4 ) { if ( *pThirdChunk == *pDelimiter && MatchDateDelimiter( &pThirdChunk ) ) { ulThird = my_wcstoul( pThirdChunk, &pLeftOver ); if ( pThirdChunk != pLeftOver && pLeftOver == ( pFirstChunk + ulTokenLen ) && ( pLeftOver - pThirdChunk ) <= 4 ) { //--- Successfully Matched { d+{'/' || '-' || '.'}d+{'/' || '-' || '.'}d+ }
bThree = true; } else { //--- Digit-String Delimiter Digit-String Delimiter non-digit cannot be a Date,
//--- nor can Digit-String Delimiter Digit-String Delimiter Digit-String String
hr = E_INVALIDARG; } } else { if ( pThirdChunk == m_pEndOfCurrItem ) { //--- Successfully Matched { d+{'/' || '-' || '.'}d+ }
bTwo = true; } else { //--- Digit-String Delimiter Digit-String non-delimiter cannot be a Date
hr = E_INVALIDARG; } } } } else { //--- Digit-String followed by non-delimiter cannot be a Date
hr = E_INVALIDARG; } }
//------------------------------------------------
// Now Figure Out What To Do With The Values
//------------------------------------------------
//--- Matched a Month, Day, and Year ---//
if ( SUCCEEDED( hr ) && bThree ) { //--- Try to valiDate values
ULONG ulFirstChunkLength = (ULONG)(pSecondChunk - pFirstChunk - 1); ULONG ulSecondChunkLength = (ULONG)(pThirdChunk - pSecondChunk - 1); ULONG ulThirdChunkLength = (ULONG)(pLeftOver - pThirdChunk);
//--- Preferred order is Month Day Year
if (fMonthDayYear) { //--- Try Month Day Year, then Day Month Year, then Year Month Day
if ( ( MONTHMIN <= ulFirst && ulFirst <= MONTHMAX ) && ( ulFirstChunkLength <= 3 ) && ( DAYMIN <= ulSecond && ulSecond <= DAYMAX) && ( ulSecondChunkLength <= 3 ) && ( YEARMIN <= ulThird && ulThird <= YEARMAX) && ( ulThirdChunkLength >= 2 ) ) { NULL; } else if ( ( DAYMIN <= ulFirst && ulFirst <= DAYMAX ) && ( ulFirstChunkLength <= 3 ) && ( MONTHMIN <= ulSecond && ulSecond <= MONTHMAX ) && ( ulSecondChunkLength <= 3 ) && ( YEARMIN <= ulThird && ulThird <= YEARMAX ) && ( ulThirdChunkLength >= 2 ) ) { fMonthDayYear = false; fDayMonthYear = true; } else if ( ( YEARMIN <= ulFirst && ulFirst <= YEARMAX ) && ( ulFirstChunkLength >= 2 ) && ( MONTHMIN <= ulSecond && ulSecond <= MONTHMAX ) && ( ulSecondChunkLength <= 3 ) && ( DAYMIN <= ulThird && ulThird <= DAYMAX ) && ( ulThirdChunkLength <= 3 ) ) { fMonthDayYear = false; fYearMonthDay = true; } else { hr = E_INVALIDARG; } } //--- Preferred order is Day Month Year
else if ( fDayMonthYear ) { //--- Try Day Month Year, then Month Day Year, then Year Month Day
if ( ( DAYMIN <= ulFirst && ulFirst <= DAYMAX ) && ( ulFirstChunkLength <= 3 ) && ( MONTHMIN <= ulSecond && ulSecond <= MONTHMAX ) && ( ulSecondChunkLength <= 3 ) && ( YEARMIN <= ulThird && ulThird <= YEARMAX ) && ( ulThirdChunkLength >= 2 ) ) { NULL; } else if ( ( MONTHMIN <= ulFirst && ulFirst <= MONTHMAX ) && ( ulFirstChunkLength <= 3 ) && ( DAYMIN <= ulSecond && ulSecond <= DAYMAX ) && ( ulSecondChunkLength <= 3 ) && ( YEARMIN <= ulThird && ulThird <= YEARMAX ) && ( ulThirdChunkLength >= 2 ) ) { fDayMonthYear = false; fMonthDayYear = true; } else if ( ( YEARMIN <= ulFirst && ulFirst <= YEARMAX ) && ( ulFirstChunkLength >= 2 ) && ( MONTHMIN <= ulSecond && ulSecond <= MONTHMAX ) && ( ulSecondChunkLength <= 3 ) && ( DAYMIN <= ulThird && ulThird <= DAYMAX ) && ( ulThirdChunkLength <= 3 ) ) { fDayMonthYear = false; fYearMonthDay = true; } else { hr = E_INVALIDARG; } } //--- Preferred order is Year Month Day
else if (fYearMonthDay) { //--- Try Year Month Day, then Month Day Year, then Day Month Year
if ( ( YEARMIN <= ulFirst && ulFirst <= YEARMAX ) && ( ulFirstChunkLength >= 2 ) && ( MONTHMIN <= ulSecond && ulSecond <= MONTHMAX ) && ( ulSecondChunkLength <= 3 ) && ( DAYMIN <= ulThird && ulThird <= DAYMAX ) && ( ulThirdChunkLength <= 3 ) ) { NULL; } else if ( ( MONTHMIN <= ulFirst && ulFirst <= MONTHMAX ) && ( ulFirstChunkLength <= 3 ) && ( DAYMIN <= ulSecond && ulSecond <= DAYMAX ) && ( ulSecondChunkLength <= 3 ) && ( YEARMIN <= ulThird && ulThird <= YEARMAX ) && ( ulThirdChunkLength >= 2 ) ) { fYearMonthDay = false; fMonthDayYear = true; } else if ( ( DAYMIN <= ulFirst && ulFirst <= DAYMAX ) && ( ulFirstChunkLength <= 3 ) && ( MONTHMIN <= ulSecond && ulSecond <= MONTHMAX ) && ( ulSecondChunkLength <= 3 ) && ( YEARMIN <= ulThird && ulThird <= YEARMAX ) && ( ulThirdChunkLength >= 2 ) ) { fYearMonthDay = false; fDayMonthYear = true; } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } //--- Fill out DateItemInfo structure appropriately.
if ( SUCCEEDED( hr ) ) { pItemNormInfo = (TTSDateItemInfo*) MemoryManager.GetMemory( sizeof(TTSDateItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDateItemInfo) ); pItemNormInfo->Type = eDATE; if ( fMonthDayYear ) { ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulFirst; ( (TTSDateItemInfo*) pItemNormInfo )->pDay = (TTSIntegerItemInfo*) MemoryManager.GetMemory( sizeof(TTSIntegerItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pDay, sizeof(TTSIntegerItemInfo) ); if ( *pSecondChunk == L'0' ) { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pSecondChunk + 1; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 1; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pSecondChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = ulSecondChunkLength; } ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = pSecondChunk + ulSecondChunkLength; ( (TTSDateItemInfo*) pItemNormInfo )->pYear = (TTSYearItemInfo*) MemoryManager.GetMemory( sizeof(TTSYearItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pYear, sizeof(TTSYearItemInfo) ); ( (TTSDateItemInfo*) pItemNormInfo )->pYear->pYear = pThirdChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pYear->ulNumDigits = ulThirdChunkLength; } } } else if ( fDayMonthYear ) { ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulSecond; ( (TTSDateItemInfo*) pItemNormInfo )->pDay = (TTSIntegerItemInfo*) MemoryManager.GetMemory( sizeof(TTSIntegerItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pDay, sizeof(TTSIntegerItemInfo) ); if ( *pFirstChunk == L'0' ) { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pFirstChunk + 1; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 1; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pFirstChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = ulFirstChunkLength; } ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = pFirstChunk + ulFirstChunkLength; ( (TTSDateItemInfo*) pItemNormInfo )->pYear = (TTSYearItemInfo*) MemoryManager.GetMemory( sizeof(TTSYearItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pYear, sizeof(TTSYearItemInfo) ); ( (TTSDateItemInfo*) pItemNormInfo )->pYear->pYear = pThirdChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pYear->ulNumDigits = ulThirdChunkLength; } } } else if ( fYearMonthDay ) { ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulSecond; ( (TTSDateItemInfo*) pItemNormInfo )->pDay = (TTSIntegerItemInfo*) MemoryManager.GetMemory( sizeof(TTSIntegerItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pDay, sizeof(TTSIntegerItemInfo) ); if ( *pThirdChunk == L'0' ) { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pThirdChunk + 1; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 1; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pThirdChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = ulThirdChunkLength; } ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = pThirdChunk + ulThirdChunkLength; ( (TTSDateItemInfo*) pItemNormInfo )->pYear = (TTSYearItemInfo*) MemoryManager.GetMemory( sizeof(TTSYearItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pYear, sizeof(TTSYearItemInfo) ); ( (TTSDateItemInfo*) pItemNormInfo )->pYear->pYear = pFirstChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pYear->ulNumDigits = ulFirstChunkLength; } } } } } } //--- Matched just a Month and Day, or a Month and Year ---//
else if ( SUCCEEDED( hr ) && Context && bTwo ) { ULONG ulFirstChunkLength = (ULONG)(pSecondChunk - pFirstChunk - 1); ULONG ulSecondChunkLength = (ULONG)(pThirdChunk - pSecondChunk);
if ( _wcsicmp(Context, L"Date_MD") == 0 ) { if ( ( MONTHMIN <= ulFirst && ulFirst <= MONTHMAX ) && ( ulFirstChunkLength <= 2 ) && ( DAYMIN <= ulSecond && ulSecond <= DAYMAX ) && ( ulSecondChunkLength <= 2 ) ) { //--- Successfully matched a month and day
pItemNormInfo = (TTSDateItemInfo*) MemoryManager.GetMemory( sizeof(TTSDateItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDateItemInfo) ); pItemNormInfo->Type = eDATE; ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulFirst; ( (TTSDateItemInfo*) pItemNormInfo )->pDay = (TTSIntegerItemInfo*) MemoryManager.GetMemory( sizeof(TTSIntegerItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pDay, sizeof(TTSIntegerItemInfo) ); if ( pSecondChunk[0] == L'0' ) { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pSecondChunk + 1; ulSecondChunkLength--; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pSecondChunk; } ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = ulSecondChunkLength; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar + ulSecondChunkLength; } }
} else // values out of range
{ hr = E_INVALIDARG; } } else if ( _wcsicmp(Context, L"Date_DM") == 0 ) { if ( ( DAYMIN <= ulFirst && ulFirst <= DAYMAX ) && ( ulFirstChunkLength <= 2 ) && ( MONTHMIN <= ulSecond && ulSecond <= MONTHMAX ) && ( ulSecondChunkLength <= 2 ) ) { //--- Successfully matched a month and day
pItemNormInfo = (TTSDateItemInfo*) MemoryManager.GetMemory( sizeof(TTSDateItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDateItemInfo) ); pItemNormInfo->Type = eDATE; ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulSecond; ( (TTSDateItemInfo*) pItemNormInfo )->pDay = (TTSIntegerItemInfo*) MemoryManager.GetMemory( sizeof(TTSIntegerItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pDay, sizeof(TTSIntegerItemInfo) ); if ( m_pNextChar[0] == L'0' ) { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pFirstChunk + 1; ulFirstChunkLength--; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pFirstChunk; } ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = ulFirstChunkLength; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar + ulFirstChunkLength; } } } else // values out of range
{ hr = E_INVALIDARG; } } else if ( _wcsicmp(Context, L"Date_MY") == 0 ) { if ( ( MONTHMIN <= ulFirst && ulFirst <= MONTHMAX ) && ( ulFirstChunkLength <= 2 ) && ( YEARMIN <= ulSecond && ulSecond <= YEARMAX ) && ( ulSecondChunkLength >= 2 ) ) { //--- Successfully matched a month and year
pItemNormInfo = (TTSDateItemInfo*) MemoryManager.GetMemory( sizeof(TTSDateItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDateItemInfo) ); pItemNormInfo->Type = eDATE; ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulFirst; ( (TTSDateItemInfo*) pItemNormInfo )->pYear = (TTSYearItemInfo*) MemoryManager.GetMemory( sizeof(TTSYearItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pYear, sizeof(TTSYearItemInfo) ); ( (TTSDateItemInfo*) pItemNormInfo )->pYear->pYear = pSecondChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pYear->ulNumDigits = ulSecondChunkLength; } } } else // values out of range
{ hr = E_INVALIDARG; } } else if ( _wcsicmp(Context, L"Date_YM") == 0 ) { if ( ( YEARMIN <= ulFirst && ulFirst <= YEARMAX ) && ( ulFirstChunkLength >= 2 ) && ( MONTHMIN <= ulSecond && ulSecond <= MONTHMAX ) && ( ulSecondChunkLength <= 2 ) ) { //--- Successfully matched a month and year
pItemNormInfo = (TTSDateItemInfo*) MemoryManager.GetMemory( sizeof(TTSDateItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDateItemInfo) ); pItemNormInfo->Type = eDATE; ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulSecond; ( (TTSDateItemInfo*) pItemNormInfo )->pYear = (TTSYearItemInfo*) MemoryManager.GetMemory( sizeof(TTSYearItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pYear, sizeof(TTSYearItemInfo) ); ( (TTSDateItemInfo*) pItemNormInfo )->pYear->pYear = pFirstChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pYear->ulNumDigits = ulFirstChunkLength; } } } else // values out of range
{ hr = E_INVALIDARG; } } //--- not a date unless context specifies...
else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } } return hr; } /* IsNumericCompactDate */
/***********************************************************************************************
* IsMonthStringCompactDate * *--------------------------* * Description: * Checks the incoming Item's text to determine whether or not it * is a Date with a string for the month, and if so, which type. * * RegExp: * {[MonthString]{'/' || '-' || '.'}[1-31]{'/' || '-' || '.'}[0-9999]} || * {[1-31]{'/' || '-' || '.'}[MonthString]{'/' || '-' || '.'}[0-9999]} || * {[0-9999]{'/' || '-' || '.'}[MonthString]{'/' || '-' || '.'}[1-31]} * * Types assigned: * Date ********************************************************************* AH **********************/ HRESULT CStdSentEnum::IsMonthStringCompactDate( TTSItemInfo*& pItemNormInfo, const WCHAR* Context, CSentItemMemory& MemoryManager ) { SPDBG_FUNC( "DateNorm.cpp IsMonthStringCompactDate" );
HRESULT hr = S_OK; WCHAR *pFirstChunk = 0, *pSecondChunk = 0, *pThirdChunk = 0, *pLeftOver = 0; ULONG ulFirst = 0; ULONG ulSecond = 0; ULONG ulThird = 0; ULONG ulTokenLen = (ULONG)(m_pEndOfCurrItem - m_pNextChar); ULONG ulFirstChunkLength = 0, ulSecondChunkLength = 0, ulThirdChunkLength = 0; bool fMonthDayYear = false, fDayMonthYear = false, fYearMonthDay = false;
//--- Max length of a Date matching this regexp is 17 characters
if ( ulTokenLen > 17 ) { hr = E_INVALIDARG; } else { //--- Get preferred order of Month, Day, and Year for this user
if (Context != NULL) { if ( _wcsicmp( Context, L"Date_MDY" ) == 0 ) { fMonthDayYear = true; } else if ( _wcsicmp( Context, L"Date_DMY" ) == 0 ) { fDayMonthYear = true; } else if ( _wcsicmp( Context, L"Date_YMD" ) == 0 ) { fYearMonthDay = true; } else { if ( m_eShortDateOrder & MONTH_DAY_YEAR ) { fMonthDayYear = true; } else if ( m_eShortDateOrder & DAY_MONTH_YEAR ) { fDayMonthYear = true; } else { fYearMonthDay = true; } } } else { if ( m_eShortDateOrder & MONTH_DAY_YEAR ) { fMonthDayYear = true; } else if ( m_eShortDateOrder & DAY_MONTH_YEAR ) { fDayMonthYear = true; } else { fYearMonthDay = true; } }
pFirstChunk = (WCHAR*) m_pNextChar; pSecondChunk = pFirstChunk;
//--- Try MonthString-Day-Year format
if ( iswalpha( *pFirstChunk ) ) { ulFirst = MatchMonthString( pSecondChunk, ulTokenLen ); if ( ulFirst ) { ulFirstChunkLength = (ULONG)(pSecondChunk - pFirstChunk); if ( MatchDateDelimiter( &pSecondChunk ) ) { pThirdChunk = pSecondChunk; ulSecond = my_wcstoul( pSecondChunk, &pThirdChunk ); if ( pSecondChunk != pThirdChunk && pThirdChunk - pSecondChunk <= 2 ) { ulSecondChunkLength = (ULONG)(pThirdChunk - pSecondChunk); if ( MatchDateDelimiter( &pThirdChunk ) ) { ulThird = my_wcstoul( pThirdChunk, &pLeftOver ); if ( pThirdChunk != pLeftOver && pLeftOver - pThirdChunk <= 4 ) { ulThirdChunkLength = (ULONG)(pLeftOver - pThirdChunk); //--- May have matched a month, day and year - valiDate values
if ( ( DAYMIN <= ulSecond && ulSecond <= DAYMAX ) && ( ulSecondChunkLength <= 2 ) && ( YEARMIN <= ulThird && ulThird <= YEARMAX ) && ( ulThirdChunkLength >= 2 ) ) { //--- Successfully matched a month, day and year
fMonthDayYear = true; fDayMonthYear = false; fYearMonthDay = false; } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } } else { if ( !Context || ( Context && _wcsicmp( Context, L"Date_MD" ) == 0 ) ) { if ( ( DAYMIN <= ulSecond && ulSecond <= DAYMAX ) && ( ulSecondChunkLength <= 2 ) ) { fMonthDayYear = true; fDayMonthYear = false; fYearMonthDay = false; pThirdChunk = NULL; } else { fMonthDayYear = false; fDayMonthYear = false; fYearMonthDay = true; pFirstChunk = pSecondChunk; ulFirstChunkLength = (ULONG)(pThirdChunk - pSecondChunk); ulSecond = ulFirst; pThirdChunk = NULL; } } else if ( Context && _wcsicmp( Context, L"Date_MY" ) == 0 ) { if ( ( YEARMIN <= ulSecond && ulSecond <= YEARMAX ) && ( ulSecondChunkLength <= 4 ) ) { fMonthDayYear = false; fDayMonthYear = false; fYearMonthDay = true; pFirstChunk = pSecondChunk; ulFirstChunkLength = (ULONG)(pThirdChunk - pSecondChunk); ulSecond = ulFirst; pThirdChunk = NULL; } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } } } else if ( pSecondChunk != pThirdChunk && pThirdChunk - pSecondChunk <= 4 ) { if ( ( YEARMIN <= ulSecond && ulSecond <= YEARMAX ) ) { fMonthDayYear = false; fDayMonthYear = false; fYearMonthDay = true; pFirstChunk = pSecondChunk; ulFirstChunkLength = (ULONG)(pThirdChunk - pSecondChunk); ulSecond = ulFirst; pThirdChunk = NULL; } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } } //--- Try Day-MonthString-Year and Year-MonthString-Day Formats
else if ( isdigit( *pFirstChunk ) ) { ulFirst = my_wcstoul( pFirstChunk, &pSecondChunk ); if ( pFirstChunk != pSecondChunk && pSecondChunk - pFirstChunk <= 4 ) { ulFirstChunkLength = (ULONG)(pSecondChunk - pFirstChunk); if ( MatchDateDelimiter( &pSecondChunk ) ) { pThirdChunk = pSecondChunk; ulSecond = MatchMonthString( pThirdChunk, ulTokenLen - ulFirstChunkLength ); if ( ulSecond ) { ulSecondChunkLength = (ULONG)(pThirdChunk - pSecondChunk); if ( MatchDateDelimiter( &pThirdChunk ) ) { ulThird = my_wcstoul( pThirdChunk, &pLeftOver ); if ( pThirdChunk != pLeftOver && pLeftOver - pThirdChunk <= 4 ) { ulThirdChunkLength = (ULONG)(pLeftOver - pThirdChunk); //--- May have matched a month, day, and year - valiDate values
if ( fDayMonthYear || fMonthDayYear ) { //--- Preferred format is Month Day Year, or Day Month Year - in either case
//--- Day Month Year is preferable to Year Month Day
if ( ( DAYMIN <= ulFirst && ulFirst <= DAYMAX ) && ( ulFirstChunkLength <= 2 ) && ( YEARMIN <= ulThird && ulThird <= YEARMAX ) && ( ulThirdChunkLength >= 2 ) ) { //--- Successfully matched a day, month and year
fDayMonthYear = true; fMonthDayYear = false; fYearMonthDay = false; } else if ( ( YEARMIN <= ulFirst && ulFirst <= YEARMAX ) && ( ulFirstChunkLength >= 2 ) && ( DAYMIN <= ulThird && ulThird <= DAYMAX ) && ( ulThirdChunkLength <= 2 ) ) { //--- Successfully matched a year, month and day
fYearMonthDay = true; fMonthDayYear = false; fDayMonthYear = false; } else { hr = E_INVALIDARG; } } else // fYearMonthDay
{ //--- Preferred format is Year Month Day
if ( ( YEARMIN <= ulFirst && ulFirst <= YEARMAX ) && ( ulFirstChunkLength >= 2 ) && ( DAYMIN <= ulThird && ulThird <= DAYMAX ) && ( ulThirdChunkLength <= 2 ) ) { //--- Successfully matched a year, month, and day
fYearMonthDay = true; fMonthDayYear = false; fDayMonthYear = false; } else if ( ( DAYMIN <= ulFirst && ulFirst <= DAYMAX ) && ( ulFirstChunkLength <= 2 ) && ( YEARMIN <= ulThird && ulThird <= YEARMAX ) && ( ulThirdChunkLength >= 2 ) ) { //--- Successfully matched a day, month, and year
fDayMonthYear = true; fMonthDayYear = false; fYearMonthDay = false; } else { hr = E_INVALIDARG; } } } else { hr = E_INVALIDARG; } } //--- Matched two - either Day-Monthstring or Year-Monthstring
else { if ( !Context || ( Context && _wcsicmp( Context, L"Date_DM" ) == 0 ) ) { //--- Preferred format is Month Day Year, or Day Month Year - in either case
//--- Day Month Year is preferable to Year Month Day
if ( ( DAYMIN <= ulFirst && ulFirst <= DAYMAX ) && ( ulFirstChunkLength <= 2 ) ) { //--- Successfully matched a day, month and year
fDayMonthYear = true; fMonthDayYear = false; fYearMonthDay = false; pThirdChunk = NULL; } else if ( ( YEARMIN <= ulFirst && ulFirst <= YEARMAX ) && ( ulFirstChunkLength <= 4 ) ) { //--- Successfully matched a year, month and day
fYearMonthDay = true; fMonthDayYear = false; fDayMonthYear = false; pThirdChunk = NULL; } else { hr = E_INVALIDARG; } } else if ( Context && _wcsicmp( Context, L"Date_YM" ) == 0 ) { //--- Preferred format is Year Month Day
if ( ( YEARMIN <= ulFirst && ulFirst <= YEARMAX ) && ( ulFirstChunkLength <= 4 ) ) { //--- Successfully matched a year, month, and day
fYearMonthDay = true; fMonthDayYear = false; fDayMonthYear = false; pThirdChunk = NULL; } else if ( ( DAYMIN <= ulFirst && ulFirst <= DAYMAX ) && ( ulFirstChunkLength <= 2 ) ) { //--- Successfully matched a day, month, and year
fDayMonthYear = true; fMonthDayYear = false; fYearMonthDay = false; pThirdChunk = NULL; } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } } } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } } else { hr = E_INVALIDARG; } }
//--- Fill out DateItemInfo structure appropriately.
if ( SUCCEEDED( hr ) ) { pItemNormInfo = (TTSDateItemInfo*) MemoryManager.GetMemory( sizeof(TTSDateItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDateItemInfo) ); pItemNormInfo->Type = eDATE; if ( fMonthDayYear ) { ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulFirst; ( (TTSDateItemInfo*) pItemNormInfo )->pDay = (TTSIntegerItemInfo*) MemoryManager.GetMemory( sizeof(TTSIntegerItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pDay, sizeof(TTSIntegerItemInfo) ); if ( ulSecondChunkLength == 2 ) { if ( *pSecondChunk != L'0' ) { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pSecondChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 2; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pSecondChunk + 1; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 1; } ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = pSecondChunk + 2; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pSecondChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 1; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = pSecondChunk + 1; } if ( pThirdChunk ) { ( (TTSDateItemInfo*) pItemNormInfo )->pYear = (TTSYearItemInfo*) MemoryManager.GetMemory( sizeof(TTSYearItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ( (TTSDateItemInfo*) pItemNormInfo )->pYear->pYear = pThirdChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pYear->ulNumDigits = ulThirdChunkLength; } } else { ( (TTSDateItemInfo*) pItemNormInfo )->pYear = NULL; } } } else if ( fDayMonthYear ) { ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulSecond; ( (TTSDateItemInfo*) pItemNormInfo )->pDay = (TTSIntegerItemInfo*) MemoryManager.GetMemory( sizeof(TTSIntegerItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pDay, sizeof(TTSIntegerItemInfo) ); if ( ulFirstChunkLength == 2 ) { if ( *pFirstChunk != L'0' ) { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pFirstChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 2; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pFirstChunk + 1; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 1; } ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = pFirstChunk + 2; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pFirstChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 1; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = pFirstChunk + 1; } if ( pThirdChunk ) { ( (TTSDateItemInfo*) pItemNormInfo )->pYear = (TTSYearItemInfo*) MemoryManager.GetMemory( sizeof(TTSYearItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ( (TTSDateItemInfo*) pItemNormInfo )->pYear->pYear = pThirdChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pYear->ulNumDigits = ulThirdChunkLength; } } else { ( (TTSDateItemInfo*) pItemNormInfo )->pYear = NULL; } } } else if ( fYearMonthDay ) { ( (TTSDateItemInfo*) pItemNormInfo )->ulMonthIndex = ulSecond; if ( SUCCEEDED( hr ) ) { if ( pThirdChunk ) { ( (TTSDateItemInfo*) pItemNormInfo )->pDay = (TTSIntegerItemInfo*) MemoryManager.GetMemory( sizeof(TTSIntegerItemInfo), &hr ); if ( ulThirdChunkLength == 2 ) { ZeroMemory( ( (TTSDateItemInfo*) pItemNormInfo )->pDay, sizeof(TTSIntegerItemInfo) ); if ( *pThirdChunk != L'0' ) { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pThirdChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 2; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pThirdChunk + 1; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 1; } ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = pThirdChunk + 2; } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pStartChar = pThirdChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->lLeftOver = 1; ( (TTSDateItemInfo*) pItemNormInfo )->pDay->pEndChar = pThirdChunk + 1; } } else { ( (TTSDateItemInfo*) pItemNormInfo )->pDay = NULL; } ( (TTSDateItemInfo*) pItemNormInfo )->pYear = (TTSYearItemInfo*) MemoryManager.GetMemory( sizeof(TTSYearItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ( (TTSDateItemInfo*) pItemNormInfo )->pYear->pYear = pFirstChunk; ( (TTSDateItemInfo*) pItemNormInfo )->pYear->ulNumDigits = ulFirstChunkLength; } } } else { //--- should never get here.
hr = E_UNEXPECTED; } } } return hr; } /* IsMonthStringCompactDate */
/***********************************************************************************************
* IsLongFormDate_DMDY * *---------------------* * Description: * Checks the incoming Item's text to determine whether or not it * is a long form Date. * * RegExp: * [[DayString][,]?]? [MonthString][,]? [Day][,]? [Year]? * * Types assigned: * Date ********************************************************************* AH **********************/ HRESULT CStdSentEnum::IsLongFormDate_DMDY( TTSItemInfo*& pItemNormInfo, CSentItemMemory& MemoryManager, CWordList& WordList ) { SPDBG_FUNC( "CStdSentEnum::IsLongFormDate_DMDY" ); HRESULT hr = S_OK; WCHAR *pDayString = NULL, *pMonthString = NULL, *pDay = NULL, *pYear = NULL; ULONG ulDayLength = 0, ulYearLength = 0; long lDayString = -1, lMonthString = -1, lDay = 0, lYear = 0; const WCHAR *pStartChar = m_pNextChar, *pEndOfItem = m_pEndOfCurrItem, *pEndChar = m_pEndChar; const WCHAR *pTempEndChar = NULL, *pTempEndOfItem = NULL; const SPVTEXTFRAG* pFrag = m_pCurrFrag, *pTempFrag = NULL; const SPVSTATE *pDayStringXMLState = NULL, *pMonthStringXMLState = NULL, *pDayXMLState = NULL; const SPVSTATE *pYearXMLState = NULL; CItemList PostDayStringList, PostMonthStringList, PostDayList; BOOL fNoYear = false;
//--- Try to match Day String
pDayString = (WCHAR*) pStartChar; lDayString = MatchDayString( pDayString, (WCHAR*) pEndOfItem );
//--- Failed to match a Day String
if ( lDayString == 0 ) { pDayString = NULL; } //--- Matched a Day String, but it wasn't by itself or followed by a comma
else if ( pDayString != pEndOfItem && ( pDayString != pEndOfItem - 1 || *pEndOfItem != L',' ) ) { hr = E_INVALIDARG; } //--- Matched a Day String - save XML State and move ahead in text
else { pDayString = (WCHAR*) pStartChar; pDayStringXMLState = &pFrag->State;
pStartChar = pEndOfItem; if ( *pStartChar == L',' ) { pStartChar++; } hr = SkipWhiteSpaceAndTags( pStartChar, pEndChar, pFrag, MemoryManager, true, &PostDayStringList ); if ( !pStartChar && SUCCEEDED( hr ) ) { hr = E_INVALIDARG; } else if ( pStartChar && SUCCEEDED( hr ) ) { pEndOfItem = FindTokenEnd( pStartChar, pEndChar ); } }
//--- Try to match Month String
if ( SUCCEEDED( hr ) ) { pMonthString = (WCHAR*) pStartChar; lMonthString = MatchMonthString( pMonthString, (ULONG)(pEndOfItem - pMonthString) );
//--- Failed to match Month String, or Month String was not by itself...
if ( !lMonthString || ( pMonthString != pEndOfItem && ( pMonthString != pEndOfItem - 1 || *pMonthString != L',' ) ) ) { hr = E_INVALIDARG; } //--- Matched a Month String - save XML State and move ahead in text
else { pMonthString = (WCHAR*) pStartChar; pMonthStringXMLState = &pFrag->State;
pStartChar = pEndOfItem; hr = SkipWhiteSpaceAndTags( pStartChar, pEndChar, pFrag, MemoryManager, true, &PostMonthStringList ); if ( !pStartChar && SUCCEEDED( hr ) ) { hr = E_INVALIDARG; } else if ( pStartChar && SUCCEEDED( hr ) ) { pEndOfItem = FindTokenEnd( pStartChar, pEndChar ); //--- Strip trailing punctuation, etc. since the next token could be the last one if
//--- this is just a Monthstring and Day...
while ( IsMiscPunctuation( *(pEndOfItem - 1) ) != eUNMATCHED || IsGroupEnding( *(pEndOfItem - 1) ) != eUNMATCHED || IsQuotationMark( *(pEndOfItem - 1) ) != eUNMATCHED || IsEOSItem( *(pEndOfItem - 1) ) != eUNMATCHED ) { if ( *(pEndOfItem - 1) != L',' ) { fNoYear = true; } pEndOfItem--; } } } }
//--- Try to match Day
if ( SUCCEEDED( hr ) ) { lDay = my_wcstoul( pStartChar, &pDay ); //--- Matched a Day - save XML State and move ahead in text
if ( ( DAYMIN <= lDay && lDay <= DAYMAX ) && pDay - pStartChar <= 2 && ( pDay == pEndOfItem || ( pDay == (pEndOfItem - 1) && *pDay == L',' ) ) ) { if ( pDay == pEndOfItem ) { ulDayLength = (ULONG)(pEndOfItem - pStartChar); } else if ( pDay == pEndOfItem - 1 ) { ulDayLength = (ULONG)((pEndOfItem - 1) - pStartChar); } pDay = (WCHAR*) pStartChar; pDayXMLState = &pFrag->State;
if ( !fNoYear ) { //--- Save pointers, in case there is no year present
pTempEndChar = pEndChar; pTempEndOfItem = pEndOfItem; pTempFrag = pFrag;
if ( *pEndOfItem == L',' ) { pStartChar = pEndOfItem + 1; } else { pStartChar = pEndOfItem; } hr = SkipWhiteSpaceAndTags( pStartChar, pEndChar, pFrag, MemoryManager, true, &PostDayList ); if ( !pStartChar && SUCCEEDED( hr ) ) { fNoYear = true; pYear = NULL; } else if ( pStartChar && ( SUCCEEDED( hr ) ) ) { pEndOfItem = FindTokenEnd( pStartChar, pEndChar ); //--- Strip trailing punctuation, since the next token will be the last one
//--- if this is Monthstring, Day, Year
while ( IsMiscPunctuation( *(pEndOfItem - 1) ) != eUNMATCHED || IsGroupEnding( *(pEndOfItem - 1) ) != eUNMATCHED || IsQuotationMark( *(pEndOfItem - 1) ) != eUNMATCHED || IsEOSItem( *(pEndOfItem - 1) ) != eUNMATCHED ) { pEndOfItem--; } } } } //--- Failed to match a day
else if ( ( YEARMIN <= lDay && lDay <= YEARMAX ) && pDay - pStartChar <= 4 && pDay == pEndOfItem ) { //--- Successfully matched Month String and Year
pYearXMLState = &pFrag->State; ulYearLength = (ULONG)(pEndOfItem - pStartChar); pYear = (WCHAR*) pStartChar; //--- Don't try to match a year again
fNoYear = true; } else { hr = E_INVALIDARG; } }
//--- Try to match Year
if ( SUCCEEDED( hr ) && !fNoYear ) { lYear = my_wcstoul( pStartChar, &pYear ); //--- Matched a Year
if ( ( YEARMIN <= lYear && lYear <= YEARMAX ) && pYear - pStartChar <= 4 && pYear == pEndOfItem ) { //--- Successfully matched Month String, Day, and Year (and possibly Day String)
pYearXMLState = &pFrag->State; ulYearLength = (ULONG)(pEndOfItem - pStartChar); pYear = (WCHAR*) pStartChar; } else { //--- Failed to match Year - replace pointers with previous values
pEndChar = pTempEndChar; pEndOfItem = pTempEndOfItem; pFrag = pTempFrag; pYear = NULL; } }
if ( SUCCEEDED( hr ) ) { TTSWord Word; ZeroMemory( &Word, sizeof(TTSWord) ); Word.eWordPartOfSpeech = MS_Unknown;
pItemNormInfo = (TTSItemInfo*) MemoryManager.GetMemory( sizeof(TTSItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { pItemNormInfo->Type = eDATE_LONGFORM;
//--- Insert Day String, if present
if ( pDayString ) { Word.pXmlState = pDayStringXMLState; Word.pWordText = g_days[lDayString - 1].pStr; Word.ulWordLen = g_days[lDayString - 1].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); }
//--- Insert Post Day String XML States
while ( !PostDayStringList.IsEmpty() ) { WordList.AddTail( ( PostDayStringList.RemoveHead() ).Words[0] ); }
//--- Insert Month String
Word.pXmlState = pMonthStringXMLState; Word.pWordText = g_months[lMonthString - 1].pStr; Word.ulWordLen = g_months[lMonthString - 1].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word );
//--- Insert Post Month String XML State
while ( !PostMonthStringList.IsEmpty() ) { WordList.AddTail( ( PostMonthStringList.RemoveHead() ).Words[0] ); }
SPLISTPOS WordListPos = WordList.GetTailPosition();
//--- Expand Day
if ( ulDayLength == 1 ) { NumberGroup Garbage; ExpandDigitOrdinal( *pDay, Garbage, WordList ); } else if ( ulDayLength == 2 ) { NumberGroup Garbage; ExpandTwoOrdinal( pDay, Garbage, WordList ); }
//--- Clean Up Day XML States
WordList.GetNext( WordListPos ); while ( WordListPos ) { TTSWord& TempWord = WordList.GetNext( WordListPos ); TempWord.pXmlState = pDayXMLState; }
//--- Insert Post Day XML State
while ( !PostDayList.IsEmpty() ) { WordList.AddTail( ( PostDayList.RemoveHead() ).Words[0] ); }
WordListPos = WordList.GetTailPosition();
//--- Expand Year, if present
if ( pYear ) { TTSYearItemInfo TempYearInfo; TempYearInfo.pYear = pYear; TempYearInfo.ulNumDigits = ulYearLength; hr = ExpandYear( &TempYearInfo, WordList );
if ( SUCCEEDED( hr ) ) { //--- Clean Up Year XML States
WordList.GetNext( WordListPos ); while ( WordListPos ) { TTSWord& TempWord = WordList.GetNext( WordListPos ); TempWord.pXmlState = pYearXMLState; } } } //--- Advance pointers
m_pCurrFrag = pFrag; m_pEndChar = pEndChar; m_pEndOfCurrItem = pEndOfItem; } }
return hr; } /* IsLongFormDate_DMDY */
/***********************************************************************************************
* IsLongFormDate_DDMY * *---------------------* * Description: * Checks the incoming Item's text to determine whether or not it * is a long form Date. * * RegExp: * [[DayString][,]?]? [Day][,]? [MonthString][,]? [Year]? * * Types assigned: * Date ********************************************************************* AH **********************/ HRESULT CStdSentEnum::IsLongFormDate_DDMY( TTSItemInfo*& pItemNormInfo, CSentItemMemory& MemoryManager, CWordList& WordList ) { SPDBG_FUNC( "CStdSentEnum::IsLongFormDate_DDMY" ); HRESULT hr = S_OK; WCHAR *pDayString = NULL, *pMonthString = NULL, *pDay = NULL, *pYear = NULL; ULONG ulDayLength = 0, ulYearLength = 0; long lDayString = -1, lMonthString = -1, lDay = 0, lYear = 0; const WCHAR *pStartChar = m_pNextChar, *pEndOfItem = m_pEndOfCurrItem, *pEndChar = m_pEndChar; const WCHAR *pTempEndChar = NULL, *pTempEndOfItem = NULL; const SPVTEXTFRAG* pFrag = m_pCurrFrag, *pTempFrag = NULL; const SPVSTATE *pDayStringXMLState = NULL, *pMonthStringXMLState = NULL, *pDayXMLState = NULL; const SPVSTATE *pYearXMLState = NULL; CItemList PostDayStringList, PostMonthStringList, PostDayList; BOOL fNoYear = false;
//--- Try to match Day String
pDayString = (WCHAR*) pStartChar; lDayString = MatchDayString( pDayString, (WCHAR*) pEndOfItem );
//--- Failed to match a Day String
if ( lDayString == 0 ) { pDayString = NULL; } //--- Matched a Day String, but it wasn't by itself or followed by a comma
else if ( pDayString != pEndOfItem && ( pDayString != pEndOfItem - 1 || *pEndOfItem != L',' ) ) { hr = E_INVALIDARG; } //--- Matched a Day String - save XML State and move ahead in text
else { pDayString = (WCHAR*) pStartChar; pDayStringXMLState = &pFrag->State;
pStartChar = pEndOfItem; if ( *pStartChar == L',' ) { pStartChar++; } hr = SkipWhiteSpaceAndTags( pStartChar, pEndChar, pFrag, MemoryManager, true, &PostDayStringList ); if ( !pStartChar && SUCCEEDED( hr ) ) { hr = E_INVALIDARG; } else if ( pStartChar && SUCCEEDED( hr ) ) { pEndOfItem = FindTokenEnd( pStartChar, pEndChar ); } }
//--- Try to match Day
if ( SUCCEEDED( hr ) ) { lDay = my_wcstoul( pStartChar, &pDay ); //--- Matched a Day - save XML State and move ahead in text
if ( ( DAYMIN <= lDay && lDay <= DAYMAX ) && pDay - pStartChar <= 2 && ( pDay == pEndOfItem || ( pDay == (pEndOfItem - 1) && *pDay == L',' ) ) ) { if ( pDay == pEndOfItem ) { ulDayLength = (ULONG)(pEndOfItem - pStartChar); } else if ( pDay == pEndOfItem - 1 ) { ulDayLength = (ULONG)((pEndOfItem - 1) - pStartChar); } pDay = (WCHAR*) pStartChar; pDayXMLState = &pFrag->State;
if ( *pEndOfItem == L',' ) { pStartChar = pEndOfItem + 1; } else { pStartChar = pEndOfItem; }
hr = SkipWhiteSpaceAndTags( pStartChar, pEndChar, pFrag, MemoryManager, true, &PostDayList ); if ( !pStartChar && SUCCEEDED( hr ) ) { hr = E_INVALIDARG; } else if ( pStartChar && ( SUCCEEDED( hr ) ) ) { pEndOfItem = FindTokenEnd( pStartChar, pEndChar ); //--- Strip trailing punctuation, since the next token will be the last one
//--- if this is Monthstring, Day, Year
while ( IsMiscPunctuation( *(pEndOfItem - 1) ) != eUNMATCHED || IsGroupEnding( *(pEndOfItem - 1) ) != eUNMATCHED || IsQuotationMark( *(pEndOfItem - 1) ) != eUNMATCHED || IsEOSItem( *(pEndOfItem - 1) ) != eUNMATCHED ) { if ( *(pEndOfItem - 1) != L',' ) { fNoYear = true; } pEndOfItem--; } } } //--- Failed to match a day
else { hr = E_INVALIDARG; } }
//--- Try to match Month String
if ( SUCCEEDED( hr ) ) { pMonthString = (WCHAR*) pStartChar; lMonthString = MatchMonthString( pMonthString, (ULONG)(pEndOfItem - pMonthString) );
//--- Failed to match Month String, or Month String was not by itself...
if ( !lMonthString || ( pMonthString != pEndOfItem && ( pMonthString != pEndOfItem - 1 || *pMonthString != L',' ) ) ) { hr = E_INVALIDARG; } //--- Matched a Month String - save XML State and move ahead in text
else { pMonthString = (WCHAR*) pStartChar; pMonthStringXMLState = &pFrag->State;
if ( !fNoYear ) { //--- Save pointers, in case there is no year present
pTempEndChar = pEndChar; pTempEndOfItem = pEndOfItem; pTempFrag = pFrag;
if ( *pEndOfItem == L',' ) { pStartChar = pEndOfItem + 1; } else { pStartChar = pEndOfItem; }
hr = SkipWhiteSpaceAndTags( pStartChar, pEndChar, pFrag, MemoryManager, true, &PostMonthStringList ); if ( !pStartChar && SUCCEEDED( hr ) ) { fNoYear = true; pYear = NULL; } else if ( pStartChar && SUCCEEDED( hr ) ) { pEndOfItem = FindTokenEnd( pStartChar, pEndChar ); //--- Strip trailing punctuation, etc. since the next token could be the last one if
//--- this is Day, Monthstring, Year
while ( IsMiscPunctuation( *(pEndOfItem - 1) ) != eUNMATCHED || IsGroupEnding( *(pEndOfItem - 1) ) != eUNMATCHED || IsQuotationMark( *(pEndOfItem - 1) ) != eUNMATCHED || IsEOSItem( *(pEndOfItem - 1) ) != eUNMATCHED ) { pEndOfItem--; } } } } }
//--- Try to match Year
if ( SUCCEEDED( hr ) && !fNoYear ) { lYear = my_wcstoul( pStartChar, &pYear ); //--- Matched a Year
if ( ( YEARMIN <= lYear && lYear <= YEARMAX ) && pYear - pStartChar <= 4 && pYear == pEndOfItem ) { //--- Successfully matched Month String, Day, and Year (and possibly Day String)
pYearXMLState = &pFrag->State; ulYearLength = (ULONG)(pEndOfItem - pStartChar); pYear = (WCHAR*) pStartChar; } else { //--- Failed to match Year - replace pointers with previous values
pEndChar = pTempEndChar; pEndOfItem = pTempEndOfItem; pFrag = pTempFrag; pYear = NULL; } }
if ( SUCCEEDED( hr ) ) { TTSWord Word; ZeroMemory( &Word, sizeof(TTSWord) ); Word.eWordPartOfSpeech = MS_Unknown;
pItemNormInfo = (TTSItemInfo*) MemoryManager.GetMemory( sizeof(TTSItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { pItemNormInfo->Type = eDATE_LONGFORM;
//--- Insert Day String, if present
if ( pDayString ) { Word.pXmlState = pDayStringXMLState; Word.pWordText = g_days[lDayString - 1].pStr; Word.ulWordLen = g_days[lDayString - 1].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); }
//--- Insert Post Day String XML States
while ( !PostDayStringList.IsEmpty() ) { WordList.AddTail( ( PostDayStringList.RemoveHead() ).Words[0] ); }
//--- Insert Month String
Word.pXmlState = pMonthStringXMLState; Word.pWordText = g_months[lMonthString - 1].pStr; Word.ulWordLen = g_months[lMonthString - 1].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word );
//--- Insert Post Month String XML State
while ( !PostMonthStringList.IsEmpty() ) { WordList.AddTail( ( PostMonthStringList.RemoveHead() ).Words[0] ); }
SPLISTPOS WordListPos = WordList.GetTailPosition();
//--- Expand Day
if ( ulDayLength == 1 ) { NumberGroup Garbage; ExpandDigitOrdinal( *pDay, Garbage, WordList ); } else if ( ulDayLength == 2 ) { NumberGroup Garbage; ExpandTwoOrdinal( pDay, Garbage, WordList ); }
//--- Clean Up Day XML States
WordList.GetNext( WordListPos ); while ( WordListPos ) { TTSWord& TempWord = WordList.GetNext( WordListPos ); TempWord.pXmlState = pDayXMLState; }
//--- Insert Post Day XML State
while ( !PostDayList.IsEmpty() ) { WordList.AddTail( ( PostDayList.RemoveHead() ).Words[0] ); }
WordListPos = WordList.GetTailPosition();
//--- Expand Year, if present
if ( pYear ) { TTSYearItemInfo TempYearInfo; TempYearInfo.pYear = pYear; TempYearInfo.ulNumDigits = ulYearLength; hr = ExpandYear( &TempYearInfo, WordList );
if ( SUCCEEDED( hr ) ) { //--- Clean Up Year XML States
WordList.GetNext( WordListPos ); while ( WordListPos ) { TTSWord& TempWord = WordList.GetNext( WordListPos ); TempWord.pXmlState = pYearXMLState; } } } //--- Advance pointers
m_pCurrFrag = pFrag; m_pEndChar = pEndChar; m_pEndOfCurrItem = pEndOfItem; } }
return hr; } /* IsLongFormDate_DMDY */
/***********************************************************************************************
* ExpandDate * *------------* * Description: * Expands Items previously determined to be of type Date by IsNumericCompactDate, * IsMonthStringCompactDate, or IsTwoValueDate. * * NOTE: This function does not do parameter validation. Assumed to be done by caller. ********************************************************************* AH **********************/ HRESULT CStdSentEnum::ExpandDate( TTSDateItemInfo* pItemInfo, CWordList& WordList ) { SPDBG_FUNC( "CStdSentEnum::ExpandDate" ); HRESULT hr = S_OK; TTSWord Word; ZeroMemory( &Word, sizeof(TTSWord) ); Word.pXmlState = &m_pCurrFrag->State; Word.eWordPartOfSpeech = MS_Unknown;
//--- Insert DayString, if present.
if ( pItemInfo->ulDayIndex ) { Word.pWordText = g_days[pItemInfo->ulDayIndex - 1].pStr; Word.ulWordLen = g_days[pItemInfo->ulDayIndex - 1].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); }
//--- Insert Month
Word.pWordText = g_months[pItemInfo->ulMonthIndex - 1].pStr; Word.ulWordLen = g_months[pItemInfo->ulMonthIndex - 1].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word );
//--- Expand Day, if present.
if ( pItemInfo->pDay ) { if ( pItemInfo->pDay->lLeftOver == 1 ) { NumberGroup Garbage; ExpandDigitOrdinal( *pItemInfo->pDay->pStartChar, Garbage, WordList ); } else if ( pItemInfo->pDay->lLeftOver == 2 ) { NumberGroup Garbage; ExpandTwoOrdinal( pItemInfo->pDay->pStartChar, Garbage, WordList ); } }
//--- Expand Year, if present.
if ( pItemInfo->pYear ) { ExpandYear( pItemInfo->pYear, WordList ); } return hr; } /* ExpandDate_Standard */
/***********************************************************************************************
* ExpandYear * *-------------* * Description: * Expands four digit strings into words in groups of two, and inserts them into Item List * at ListPos. Thus 1999 come out as "nineteen ninety nine" rather than "one thousand nine * hundred ninety nine"... * Note: This function does not do parameter validation. Assumed to be done by caller. ********************************************************************* AH **********************/ HRESULT CStdSentEnum::ExpandYear( TTSYearItemInfo* pItemInfo, CWordList& WordList ) { SPDBG_FUNC( "CStdSentEnum::ExpandYear" );
// 1000 - 9999
HRESULT hr = S_OK; TTSWord Word; ZeroMemory( &Word, sizeof(TTSWord) ); Word.pXmlState = &m_pCurrFrag->State; Word.eWordPartOfSpeech = MS_Unknown; NumberGroup Garbage;
switch ( pItemInfo->ulNumDigits ) { case 2:
//--- Expand as "two thousand" if the two digits are both zeroes.
if ( pItemInfo->pYear[0] == L'0' && pItemInfo->pYear[1] == L'0' ) { //--- Insert "two".
Word.pWordText = g_ones[2].pStr; Word.ulWordLen = g_ones[2].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word );
//--- Insert "thousand".
Word.pWordText = g_quantifiers[1].pStr; Word.ulWordLen = g_quantifiers[1].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); } //--- Expand as "oh number" if the first digit is zero.
else if ( pItemInfo->pYear[0] == L'0' ) { Word.pWordText = g_O.pStr; Word.ulWordLen = g_O.Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); ExpandDigit( pItemInfo->pYear[1], Garbage, WordList ); } //--- Otherwise just expand as a two digit cardinal number
else { ExpandTwoDigits( pItemInfo->pYear, Garbage, WordList ); } break;
case 3:
//--- Expand as a three digit cardinal number;
ExpandThreeDigits( pItemInfo->pYear, Garbage, WordList ); break;
case 4:
//--- If of form "[x]00[y]" expand as "x thousand y", or just "x thousand" if y is also zero.
if ( pItemInfo->pYear[1] == L'0' && pItemInfo->pYear[2] == L'0' && pItemInfo->pYear[0] != L'0' ) { //--- "x"
ExpandDigit( pItemInfo->pYear[0], Garbage, WordList );
//--- "thousand".
Word.pWordText = g_quantifiers[1].pStr; Word.ulWordLen = g_quantifiers[1].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word );
//--- "y"
if ( pItemInfo->pYear[3] != L'0' ) { ExpandDigit( pItemInfo->pYear[3], Garbage, WordList ); } } // Otherwise...
else { //--- Expand first two digits - e.g. "nineteen"
ExpandTwoDigits( pItemInfo->pYear, Garbage, WordList );
//--- Expand last two digits - e.g. "nineteen", "hundred", or "oh nine".
if ( pItemInfo->pYear[2] != '0' ) { //--- the tens is not zero - e.g. 1919 -> "nineteen nineteen"
ExpandTwoDigits( pItemInfo->pYear + 2, Garbage, WordList ); } else if ( pItemInfo->pYear[3] == '0' ) { //--- tens and ones are both zero - expand as "hundred", e.g. 1900 -> "nineteen hundred"
Word.pWordText = g_quantifiers[0].pStr; Word.ulWordLen = g_quantifiers[0].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); } else { //--- just the tens is zero, expand as "oh x" - e.g. 1909 -> "nineteen oh nine",
//--- unless both thousands and hundreds were also zero - e.g. 0002 -> "two"
if ( pItemInfo->pYear[0] != '0' || pItemInfo->pYear[1] != '0' ) { Word.pWordText = g_O.pStr; Word.ulWordLen = g_O.Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); }
ExpandDigit( pItemInfo->pYear[3], Garbage, WordList ); } } } return hr; } /* ExpandYear */
/***********************************************************************************************
* IsDecade * *----------* * Description: * Checks the incoming Item's text to determine whether or not it * is a Decade. * * RegExp: * { ddd0s || d0s || 'd0s || ddd0's || d0's } * * Types assigned: * Decade ********************************************************************* AH **********************/ HRESULT CStdSentEnum::IsDecade( TTSItemInfo*& pItemNormInfo, CSentItemMemory& MemoryManager ) { SPDBG_FUNC( "CStdSentEnum::IsDecade" );
HRESULT hr = S_OK; ULONG ulTokenLen = (ULONG)(m_pEndOfCurrItem - m_pNextChar);
if ( ulTokenLen < 3 || ulTokenLen > 6 ) { hr = E_INVALIDARG; } else { switch ( ulTokenLen ) {
case 6: if ( m_pNextChar[5] == L's' && m_pNextChar[4] == L'\'' && m_pNextChar[3] == L'0' && iswdigit( m_pNextChar[2] ) && iswdigit( m_pNextChar[1] ) && iswdigit( m_pNextChar[0] ) ) { //--- Decade of form ddd0's
pItemNormInfo = (TTSDecadeItemInfo*) MemoryManager.GetMemory( sizeof(TTSDecadeItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDecadeItemInfo) ); pItemNormInfo->Type = eDECADE; ( (TTSDecadeItemInfo*) pItemNormInfo )->pCentury = m_pNextChar; ( (TTSDecadeItemInfo*) pItemNormInfo )->ulDecade = m_pNextChar[2] - L'0'; } } else { hr = E_INVALIDARG; } break;
case 5: if ( m_pNextChar[4] == L's' && m_pNextChar[3] == L'0' && iswdigit( m_pNextChar[2] ) && iswdigit( m_pNextChar[1] ) && iswdigit( m_pNextChar[0] ) ) { //--- Decade of form ddd0s
pItemNormInfo = (TTSDecadeItemInfo*) MemoryManager.GetMemory( sizeof(TTSDecadeItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDecadeItemInfo) ); pItemNormInfo->Type = eDECADE; ( (TTSDecadeItemInfo*) pItemNormInfo )->pCentury = m_pNextChar; ( (TTSDecadeItemInfo*) pItemNormInfo )->ulDecade = m_pNextChar[2] - L'0'; } } else { hr = E_INVALIDARG; } break;
case 4: if ( m_pNextChar[3] == L's' && m_pNextChar[2] == L'0' && iswdigit( m_pNextChar[1] ) && m_pNextChar[0] == L'\'' ) { //--- Decade of form 'd0s
pItemNormInfo = (TTSDecadeItemInfo*) MemoryManager.GetMemory( sizeof(TTSDecadeItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDecadeItemInfo) ); pItemNormInfo->Type = eDECADE; ( (TTSDecadeItemInfo*) pItemNormInfo )->pCentury = NULL; ( (TTSDecadeItemInfo*) pItemNormInfo )->ulDecade = m_pNextChar[1] - L'0'; } } else if ( m_pNextChar[3] == L's' && m_pNextChar[2] == L'\'' && m_pNextChar[1] == L'0' && iswdigit( m_pNextChar[0] ) ) { //--- Decade of form d0's
pItemNormInfo = (TTSDecadeItemInfo*) MemoryManager.GetMemory( sizeof(TTSDecadeItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDecadeItemInfo) ); pItemNormInfo->Type = eDECADE; ( (TTSDecadeItemInfo*) pItemNormInfo )->pCentury = NULL; ( (TTSDecadeItemInfo*) pItemNormInfo )->ulDecade = m_pNextChar[0] - L'0'; } } else { hr = E_INVALIDARG; } break;
case 3: if ( m_pNextChar[2] == L's' && m_pNextChar[1] == L'0' && iswdigit( m_pNextChar[0] ) ) { //--- Decade of form d0s
pItemNormInfo = (TTSDecadeItemInfo*) MemoryManager.GetMemory( sizeof(TTSDecadeItemInfo), &hr ); if ( SUCCEEDED( hr ) ) { ZeroMemory( pItemNormInfo, sizeof(TTSDecadeItemInfo) ); pItemNormInfo->Type = eDECADE; ( (TTSDecadeItemInfo*) pItemNormInfo )->pCentury = NULL; ( (TTSDecadeItemInfo*) pItemNormInfo )->ulDecade = m_pNextChar[0] - L'0'; } } else { hr = E_INVALIDARG; } break;
default: hr = E_INVALIDARG; break; } } return hr; } /* IsDecade */
/***********************************************************************************************
* ExpandDecade * *--------------* * Description: * Expands Items previously determined to be of type Decade by IsDecade. * * NOTE: This function does not do parameter validation. Assumed to be done by caller. ********************************************************************* AH **********************/ HRESULT CStdSentEnum::ExpandDecade( TTSDecadeItemInfo* pItemInfo, CWordList& WordList ) { HRESULT hr = S_OK; BOOL fDone = false; TTSWord Word; ZeroMemory( &Word, sizeof(TTSWord) ); Word.pXmlState = &m_pCurrFrag->State; Word.eWordPartOfSpeech = MS_Unknown;
//--- Four digit form
if ( pItemInfo->pCentury ) { //--- Cover special cases first
//--- 00dds
if ( pItemInfo->pCentury[0] == '0' && pItemInfo->pCentury[1] == '0' ) { //--- 0000s - expand as "zeroes"
if ( pItemInfo->ulDecade == 0 ) { Word.pWordText = g_Zeroes.pStr; Word.ulWordLen = g_Zeroes.Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); fDone = true; } //--- 00d0s
else { // Just expand the decade part as we normally would
NULL; } } //--- 0dd0s - expand as "d hundreds" or "d hundred [decade part]"
else if ( pItemInfo->pCentury[0] == '0' ) { //--- insert first digit
Word.pWordText = g_ones[ pItemInfo->pCentury[0] - L'0' ].pStr; Word.ulWordLen = g_ones[ pItemInfo->pCentury[0] - L'0' ].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word );
//--- 0d00s - expand as "d hundreds"
if ( SUCCEEDED( hr ) && pItemInfo->ulDecade == 0 ) { Word.pWordText = g_Hundreds.pStr; Word.ulWordLen = g_Hundreds.Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); fDone = true; } //--- 0dd0s - expand as "d hundred [decade part]"
else if ( SUCCEEDED( hr ) ) { Word.pWordText = g_hundred.pStr; Word.ulWordLen = g_hundred.Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); } } //--- d000s, dd00s - expand as "d thousands" or "dd hundreds"
else if ( pItemInfo->ulDecade == 0 ) { //--- d000s - "d thousands" ( "thousands" will get inserted below )
if ( pItemInfo->pCentury[1] == '0' ) { Word.pWordText = g_ones[ pItemInfo->pCentury[0] - L'0' ].pStr; Word.ulWordLen = g_ones[ pItemInfo->pCentury[0] - L'0' ].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); } //--- dd00s - "dd hundreds"
else { NumberGroup Garbage; ExpandTwoDigits( pItemInfo->pCentury, Garbage, WordList );
Word.pWordText = g_Hundreds.pStr; Word.ulWordLen = g_Hundreds.Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); fDone = true; } } //--- Default case: ddd0s - expand as "dd [decade part]"
else { NumberGroup Garbage; ExpandTwoDigits( pItemInfo->pCentury, Garbage, WordList ); } } //--- Special case - 00s should expand as "two thousands"
else if ( pItemInfo->ulDecade == 0 ) { Word.pWordText = g_ones[2].pStr; Word.ulWordLen = g_ones[2].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); }
//--- Expand decade part, if necessary
if ( SUCCEEDED(hr) && !fDone ) { Word.pWordText = g_Decades[ pItemInfo->ulDecade ].pStr; Word.ulWordLen = g_Decades[ pItemInfo->ulDecade ].Len; Word.pLemma = Word.pWordText; Word.ulLemmaLen = Word.ulWordLen; WordList.AddTail( Word ); }
return hr; } /* ExpandDecade */
/***********************************************************************************************
* MatchMonthString * *------------------* * Description: * This is just a helper function - it returns the integer value of the month found in * its WCHAR string parameter ("January" is 1, "February" 2, etc.) or zero if it finds no match. * It also checks three letter abbreviations - "Jan", "Feb", etc. * Note: This function does not do parameter validation. Assumed to be done by caller * (GetNumber should be called first to get the NumberInfo structure and valiDate parameters). ********************************************************************* AH **********************/ ULONG CStdSentEnum::MatchMonthString( WCHAR*& pMonth, ULONG ulLength ) { ULONG ulMonth = 0;
//--- Check full months strings
for ( int i = 0; i < sp_countof(g_months); i++ ) { if ( ulLength >= (ULONG) g_months[i].Len && wcsnicmp( pMonth, g_months[i].pStr, g_months[i].Len ) == 0 ) { ulMonth = i + 1; pMonth = pMonth + g_months[i].Len; break; } } //--- Check month abbreviations
if ( !ulMonth ) { for ( i = 0; i < sp_countof(g_monthAbbreviations); i++ ) { if ( ulLength >= (ULONG) g_monthAbbreviations[i].Len && wcsnicmp( pMonth, g_monthAbbreviations[i].pStr, g_monthAbbreviations[i].Len ) == 0 ) { if ( i > 8 ) { ulMonth = i; } else { ulMonth = i + 1; } pMonth = pMonth + g_monthAbbreviations[i].Len; if ( *pMonth == L'.' ) { pMonth++; } break; } } }
return ulMonth; } /* MatchMonthString */
/***********************************************************************************************
* MatchDayString * *----------------* * Description: * This is just a helper function - it returns the integer value of the day found in * its WCHAR string parameter ("Monday" is 0, "Tuesday" 1, etc.) or -1 if it finds no match. * It also checks abbreviations - "Mon", "Tue", etc. * Note: This function does not do parameter validation. Assumed to be done by caller ********************************************************************* AH **********************/ ULONG CStdSentEnum::MatchDayString( WCHAR*& pDayString, WCHAR* pEndChar ) { ULONG ulDay = 0;
//--- Check full day strings
for ( int i = 0; i < sp_countof(g_days); i++ ) { if ( pEndChar - pDayString >= g_days[i].Len && wcsnicmp( pDayString, g_days[i].pStr, g_days[i].Len ) == 0 ) { ulDay = i + 1; pDayString = pDayString + g_days[i].Len; break; } } //--- Check month abbreviations
if ( !ulDay ) { for ( i = 0; i < sp_countof(g_dayAbbreviations); i++ ) { if ( pEndChar - pDayString >= g_dayAbbreviations[i].Len && wcsncmp( pDayString, g_dayAbbreviations[i].pStr, g_dayAbbreviations[i].Len ) == 0 ) { switch (i) { //--- Mon, Tues
case 0: case 1: ulDay = i + 1; break; //--- Tue, Wed, Thurs
case 2: case 3: case 4: ulDay = i; break; //--- Thur, Thu
case 5: case 6: ulDay = 4; break; //--- Fri, Sat, Sun
case 7: case 8: case 9: ulDay = i - 2; break; }
pDayString = pDayString + g_dayAbbreviations[i].Len; if ( *pDayString == L'.' ) { pDayString++; } break; } } }
return ulDay; } /* MatchDayString */
/***********************************************************************************************
* MatchDateDelimiter * *--------------------* * Description: * This is just a helper function - it returns true or false based on whether the first * character in its parameter string is a valid Date Delimiter. It also advances its parameter * string pointer one position (past the Date Delimiter) and replaces a valid delimiter with * a null terminator. * Note: This function does not do parameter validation. Assumed to be done by caller * (GetNumber should be called first to get the NumberInfo structure and valiDate parameters). ********************************************************************* AH **********************/ bool CStdSentEnum::MatchDateDelimiter( WCHAR** DateString ) { bool bIsDelimiter = false;
if (DateString) { for (int i = 0; i < sp_countof(g_DateDelimiters); i++) { if (*DateString[0] == g_DateDelimiters[i]) { bIsDelimiter = true; *DateString = *DateString + 1; break; } } }
return bIsDelimiter; } /* MatchDateDelimiter */
//------------End Of File-----------------------------------------------------------------------------
|