home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Troubleshooting Netware Systems
/
CSTRIAL0196.BIN
/
attach
/
msj
/
v10n04
/
multilin.exe
/
PICTURE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-01
|
9KB
|
393 lines
// Implement Numeric pictures
#include "stdafx.h"
#include "picture.h"
//
// This file implements the class CPicture that can convert
// between the NUMBERFMT struct and a "picture" format of
// expressing numeric formatting. It is used by the overloaded
// GetNumberFormat() function in numform.cpp
//
// Pieces of the lpInput string that form the picture for
// an individual number and are converted to the lpInput
// required by the built-in GetNumberFormat. The CPicture
// class, and which is derived form the NUMBERFMT class that
// is the lpInput to the built-in GetNumberFormat handles the
// conversion. The constructor
// CPicture::CPicture is where the picture definition is
// parsed and translated into the field values in the
// NUMBERFMT structure. This is the syntax for numeric
// pictures
// [-][(][{#|0},][{#|0}+][.][{#|0}+][)][-]
// where
// 0 means a digit position including leading zeros
// # means a non-zero digit position
// . means the decimal separator of the active locale
// , means the thousands separator ...
// - means placeholder for the sign string
// ( means use of () instead of - sign
// and the number of repetitions (+ in syntax)
// is counted to determine grouping and fraction
// width.
// The default constructor creates a picture from the active
// locale. Another overloaded constructor is provided to create
// pictures for any given locale. This latter constructor is
// used when GetNumberFormat is called without an lpFormat string.
/* As a reminder: this is the NUMBERFMT structure
typedef struct _NUMBERFMT {
UINT NumDigits; // number of fractional digits
UINT LeadingZero; // Boolean for leading 0
UINT Grouping; // Grouping 0-9 (3 or 4 are common)
LPTSTR lpDecimalSep; // string for same
LPTSTR lpThousandSep; // string for same
UINT NegativeOrder; //??
} NUMBERFMT;
*/
// Default constructor contructs picture from
// GetLocaleInfo
CPicture::CPicture(LCID lcid/*=LOCALE_SYSTEMDEFAULT*/, DWORD dwFlags /*=LOCALE_WITHOVERRIDE*/)
{
if( lcid == LOCALE_SYSTEM_DEFAULT)
{
lcid = GetThreadLocale(); // NT only
// put Chicago specific code here
}
GetFieldValue(lcid,LOCALE_IDIGITS|dwFlags, NumDigits);
GetFieldValue(lcid,LOCALE_ILZERO|dwFlags, LeadingZero);
GetFieldValue(LOCALE_INEGNUMBER|dwFlags, NegativeOrder);
// Grouping is really a string value as LCTYPE
// just use the first entry in the Grouping string
GetFieldValue(LOCALE_SGROUPING|dwFlags, Grouping);
// These are string values
lpDecimalSep = m_DecSep;
lpThousandSep = m_ThouSep;
GetFieldValue(LOCALE_SDECIMAL|dwFlags, lpDecimalSep);
GetFieldValue(LOCALE_STHOUSAND|dwFlags, lpThousandSep);
m_Length = BuildUp(); // if we can delay build-up we can overload
}
void CPicture::GetFieldValue(LCTYPE lctype, UINT& uiVal)
{
LCID lcid = GetThreadLocale();
GetFieldValue(lcid, lctype, uiVal);
}
void CPicture::GetFieldValue(LCID lcid, LCTYPE lctype, UINT& uiVal)
{
const int cch=8 ;
TCHAR ach[cch];
GetLocaleInfo(lcid, lctype, ach, cch);
uiVal = _ttoi(ach);
}
void CPicture::GetFieldValue(LCTYPE lctype, LPTSTR str)
{
LCID lcid = GetThreadLocale();
GetFieldValue(lcid, lctype, str);
}
void CPicture::GetFieldValue(LCID lcid, LCTYPE lctype, LPTSTR str)
{
GetLocaleInfo(lcid, lctype, str, MAXSEP );
}
int CPicture::BuildUp()
{
int count=0;
switch(NegativeOrder)
{
case 0:
m_Picture[count++]=_T('(');
BuildUpPositive(count);
m_Picture[count++]=_T(')');
break;
case 1:
m_Picture[count++]=_T('-');
BuildUpPositive(count);
break;
case 2:
m_Picture[count++]=_T('-');
m_Picture[count++]=_T(' ');
BuildUpPositive(count);
break;
case 3:
BuildUpPositive(count);
m_Picture[count++]=_T('-');
break;
case 4:
BuildUpPositive(count);
m_Picture[count++]=_T(' ');
m_Picture[count++]=_T('-');
break;
default:
ASSERT(0); // Can't happen
}
m_Picture[count]=_T('\0'); //TERMINATE
return count;
}
void CPicture::BuildUpPositive(int& count)
{
TCHAR ch;
if( LeadingZero )
{
ch= _T('0');
}
else
{
ch= _T('#');
}
m_Picture[count++]=ch;
int j=Grouping;
if( j )
{
m_Picture[count++]=_T(',');
while(j-->0)
{
m_Picture[count++]=ch;
}
}
int k= NumDigits;
if(k)
{
m_Picture[count++]=_T('.');
while(k-->0)
{
m_Picture[count++]=ch;
}
}
}
CPicture::CPicture( LPCTSTR lpInp, LCID lcid, DWORD dwFlags)
{
dwFlags &= ~LOCALE_NOUSEROVERRIDE; // limit to this flag
if( lcid == LOCALE_SYSTEM_DEFAULT )
{
lcid=GetThreadLocale();
}
// These are string values
lpDecimalSep = m_DecSep;
lpThousandSep = m_ThouSep;
GetFieldValue(lcid, LOCALE_SDECIMAL|dwFlags, lpDecimalSep);
GetFieldValue(LOCALE_STHOUSAND|dwFlags, lpThousandSep);
if(lpInp)
{
m_Length=Parse(lpInp);
}
else
{
GetFieldValue(lcid,LOCALE_IDIGITS|dwFlags, NumDigits);
GetFieldValue(lcid,LOCALE_ILZERO|dwFlags, LeadingZero);
GetFieldValue(LOCALE_INEGNUMBER|dwFlags, NegativeOrder);
// Grouping is really a string value as LCTYPE
// just use the first entry in the Grouping string
GetFieldValue(LOCALE_SGROUPING|dwFlags, Grouping);
}
}
// This and the next few functions parse the number specifier
// They return the number of character consumed from the input
// specification in lpInp
int CPicture::Parse(LPCTSTR lpInp)
{
const unsigned int UNDEFINED = 5;
// Sign part
NegativeOrder=UNDEFINED; // == no sign seen so far
int count=Sign(lpInp);
// Number part
TCHAR chDigit=_T('#');
count+=Integer(lpInp, chDigit);
LeadingZero=(chDigit==_T('0')? 1 : 0);
// Fraction part
count+=Fraction(lpInp, chDigit);
// Check for trailing sign
if( NegativeOrder == UNDEFINED )
{
count+=AltSign(lpInp);
}
else if( NegativeOrder == 0)
{
count=ParSign(lpInp, count);
}
NegativeOrder%=4; // 1 is default, use if no sign specified
return count;
}
int CPicture::Sign(LPCTSTR& lpInp)
{
int count=0;
if( *lpInp == _T('-') )
{
lpInp++;
count++;
NegativeOrder=1;
if(*lpInp==_T(' '))
{
count++;
lpInp++;
NegativeOrder=2;
}
}
else if( *lpInp == _T('('))
{
NegativeOrder=0;
lpInp++;
count++;
}
return count;
}
int CPicture::ParSign(LPCTSTR& lpInp,int count)
{
if (NegativeOrder==0)
{
if(*lpInp == _T(')'))
{
lpInp++;
count++ ;
return count;
}
else
{
lpInp-=count;
return (-count);
}
}
return(0);
}
int CPicture::AltSign(LPCTSTR& lpInp)
{
int count=0;
if( *lpInp == _T(' ') )
{
lpInp++;
count++;
if(*lpInp==_T('-'))
{
count++;
lpInp++;
NegativeOrder=4;
}
else
{
count--;
lpInp--;
}
}
else if(*lpInp ==_T('-') )
{
lpInp++;
count++;
NegativeOrder=3;
}
return count;
}
int CPicture::Integer(LPCTSTR& lpInp, TCHAR& chDigit)
{
int count=0;
Grouping=0;
if( *lpInp == _T('0') )
{
chDigit=*lpInp;
count = PosNum(lpInp, chDigit);
}
else if( *lpInp == _T('#') )
{
chDigit=*lpInp;
count = PosNum(lpInp, chDigit);
}
else
{
return(0);
}
ASSERT(count>=1);
if(*lpInp==_T(',') )
{
lpInp++;
count++;
Grouping=PosNum(lpInp, chDigit);
if(Grouping ==0)
{
// back up over ','
lpInp--;
count--;
}
}
return(count+Grouping);
}
int CPicture::PosNum(LPCTSTR& lpInp, TCHAR chDigit)
{
int count = 0;
while(*lpInp == chDigit)
{
count++;
lpInp++;
}
return count;
}
int CPicture::Fraction(LPCTSTR& lpInp, TCHAR chDigit)
{
NumDigits=0;
if(*lpInp == _T('.'))
{
lpInp++ ;
return (NumDigits=PosNum(lpInp, chDigit))+1;
}
return 0;
}
#if _DEBUG
#ifndef _UNICODE
// Test works for ANSI only
void Test()
{
TCHAR test[25];
CPicture pc;
::MessageBox(NULL, pc.m_Picture, "TEST", MB_OK);
CPicture pc0("(00.00)");
GetNumberFormat(GetThreadLocale(),NULL,
_T("-123456789"),&pc0, test, 25);
::MessageBox(NULL, test, "TEST", MB_OK);
CPicture pc1("-00,00)");
GetNumberFormat(GetThreadLocale(),NULL,
_T("-123456789"), &pc1,test, 25);
::MessageBox(NULL, test, "TEST", MB_OK);
CPicture pc2("- 0,0#0)");
GetNumberFormat(GetThreadLocale(),NULL,
_T("-123456789"),&pc2, test, 25);
::MessageBox(NULL, test, "TEST", MB_OK);
CPicture pc3("0,0.00-");
GetNumberFormat(GetThreadLocale(),NULL,
_T("-123456789"),&pc3, test, 25);
::MessageBox(NULL, test, "TEST", MB_OK);
CPicture pc4(".######### -");
GetNumberFormat(GetThreadLocale(),NULL,
_T("-.123456789"), &pc4, test, 25);
::MessageBox(NULL, test, "TEST", MB_OK);
}
#endif
#endif //DEBUG