version 1.11, 2001/06/16 23:10:04
|
version 1.25, 2006/01/30 16:17:04
|
|
|
//%///////////////////////////////////////////////////////////////////////////// |
//%2006//////////////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001 The Open group, BMC Software, Tivoli Systems, IBM |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
|
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
|
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; |
|
// IBM Corp.; EMC Corporation, The Open Group. |
|
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; |
|
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
|
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// EMC Corporation; VERITAS Software Corporation; The Open Group. |
|
// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// EMC Corporation; Symantec Corporation; The Open Group. |
// | // |
// Permission is hereby granted, free of charge, to any person obtaining a copy | // Permission is hereby granted, free of charge, to any person obtaining a copy |
// of this software and associated documentation files (the "Software"), to | // of this software and associated documentation files (the "Software"), to |
|
|
// | // |
// Author: Mike Brasher (mbrasher@bmc.com) | // Author: Mike Brasher (mbrasher@bmc.com) |
// | // |
// Modified By: |
// Modified By: David Dillard, Symantec Corp. (david_dillard@symantec.com) |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include <iostream> | #include <iostream> |
#include <cstdio> | #include <cstdio> |
#include "Formatter.h" | #include "Formatter.h" |
|
#include "StrLit.h" |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
|
const Formatter::Arg Formatter::DEFAULT_ARG; |
|
|
String Formatter::Arg::toString() const | String Formatter::Arg::toString() const |
{ | { |
switch (_type) | switch (_type) |
|
|
case LINTEGER: | case LINTEGER: |
{ | { |
char buffer[32]; | char buffer[32]; |
// ATTN-B: truncation here! |
sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "d", _lInteger); |
sprintf(buffer, "%ld", long(_lInteger)); |
|
return buffer; | return buffer; |
} | } |
| |
case ULINTEGER: | case ULINTEGER: |
{ | { |
char buffer[32]; | char buffer[32]; |
// ATTN-B: truncation here: |
sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", _lUInteger); |
sprintf(buffer, "%lu", long(_lUInteger)); |
|
return buffer; | return buffer; |
} | } |
| |
case STRING: | case STRING: |
return _string; | return _string; |
| |
case VOID: |
case CSTRLIT: |
|
return String(_cstrlit->str, _cstrlit->size); |
|
break; |
|
|
|
case VOIDT: |
default: | default: |
return String(); | return String(); |
} | } |
} | } |
| |
|
struct StrRef |
|
{ |
|
const char* str; |
|
size_t size; |
|
}; |
|
|
|
static const StrRef _num_strings[] = |
|
{ |
|
{ STRLIT_ARGS("0") }, |
|
{ STRLIT_ARGS("1") }, |
|
{ STRLIT_ARGS("2") }, |
|
{ STRLIT_ARGS("3") }, |
|
{ STRLIT_ARGS("4") }, |
|
{ STRLIT_ARGS("5") }, |
|
{ STRLIT_ARGS("6") }, |
|
{ STRLIT_ARGS("7") }, |
|
{ STRLIT_ARGS("8") }, |
|
{ STRLIT_ARGS("9") }, |
|
{ STRLIT_ARGS("10") }, |
|
{ STRLIT_ARGS("11") }, |
|
{ STRLIT_ARGS("12") }, |
|
{ STRLIT_ARGS("13") }, |
|
{ STRLIT_ARGS("14") }, |
|
{ STRLIT_ARGS("15") }, |
|
{ STRLIT_ARGS("16") }, |
|
{ STRLIT_ARGS("17") }, |
|
{ STRLIT_ARGS("18") }, |
|
{ STRLIT_ARGS("19") }, |
|
{ STRLIT_ARGS("20") }, |
|
{ STRLIT_ARGS("21") }, |
|
{ STRLIT_ARGS("22") }, |
|
{ STRLIT_ARGS("23") }, |
|
{ STRLIT_ARGS("24") }, |
|
{ STRLIT_ARGS("25") }, |
|
{ STRLIT_ARGS("26") }, |
|
{ STRLIT_ARGS("27") }, |
|
{ STRLIT_ARGS("28") }, |
|
{ STRLIT_ARGS("29") }, |
|
{ STRLIT_ARGS("30") }, |
|
{ STRLIT_ARGS("31") }, |
|
{ STRLIT_ARGS("32") }, |
|
{ STRLIT_ARGS("33") }, |
|
{ STRLIT_ARGS("34") }, |
|
{ STRLIT_ARGS("35") }, |
|
{ STRLIT_ARGS("36") }, |
|
{ STRLIT_ARGS("37") }, |
|
{ STRLIT_ARGS("38") }, |
|
{ STRLIT_ARGS("39") }, |
|
{ STRLIT_ARGS("40") }, |
|
{ STRLIT_ARGS("41") }, |
|
{ STRLIT_ARGS("42") }, |
|
{ STRLIT_ARGS("43") }, |
|
{ STRLIT_ARGS("44") }, |
|
{ STRLIT_ARGS("45") }, |
|
{ STRLIT_ARGS("46") }, |
|
{ STRLIT_ARGS("47") }, |
|
{ STRLIT_ARGS("48") }, |
|
{ STRLIT_ARGS("49") }, |
|
{ STRLIT_ARGS("50") }, |
|
{ STRLIT_ARGS("51") }, |
|
{ STRLIT_ARGS("52") }, |
|
{ STRLIT_ARGS("53") }, |
|
{ STRLIT_ARGS("54") }, |
|
{ STRLIT_ARGS("55") }, |
|
{ STRLIT_ARGS("56") }, |
|
{ STRLIT_ARGS("57") }, |
|
{ STRLIT_ARGS("58") }, |
|
{ STRLIT_ARGS("59") }, |
|
{ STRLIT_ARGS("60") }, |
|
{ STRLIT_ARGS("61") }, |
|
{ STRLIT_ARGS("62") }, |
|
{ STRLIT_ARGS("63") }, |
|
{ STRLIT_ARGS("64") }, |
|
{ STRLIT_ARGS("65") }, |
|
{ STRLIT_ARGS("66") }, |
|
{ STRLIT_ARGS("67") }, |
|
{ STRLIT_ARGS("68") }, |
|
{ STRLIT_ARGS("69") }, |
|
{ STRLIT_ARGS("70") }, |
|
{ STRLIT_ARGS("71") }, |
|
{ STRLIT_ARGS("72") }, |
|
{ STRLIT_ARGS("73") }, |
|
{ STRLIT_ARGS("74") }, |
|
{ STRLIT_ARGS("75") }, |
|
{ STRLIT_ARGS("76") }, |
|
{ STRLIT_ARGS("77") }, |
|
{ STRLIT_ARGS("78") }, |
|
{ STRLIT_ARGS("79") }, |
|
{ STRLIT_ARGS("80") }, |
|
{ STRLIT_ARGS("81") }, |
|
{ STRLIT_ARGS("82") }, |
|
{ STRLIT_ARGS("83") }, |
|
{ STRLIT_ARGS("84") }, |
|
{ STRLIT_ARGS("85") }, |
|
{ STRLIT_ARGS("86") }, |
|
{ STRLIT_ARGS("87") }, |
|
{ STRLIT_ARGS("88") }, |
|
{ STRLIT_ARGS("89") }, |
|
{ STRLIT_ARGS("90") }, |
|
{ STRLIT_ARGS("91") }, |
|
{ STRLIT_ARGS("92") }, |
|
{ STRLIT_ARGS("93") }, |
|
{ STRLIT_ARGS("94") }, |
|
{ STRLIT_ARGS("95") }, |
|
{ STRLIT_ARGS("96") }, |
|
{ STRLIT_ARGS("97") }, |
|
{ STRLIT_ARGS("98") }, |
|
{ STRLIT_ARGS("99") }, |
|
{ STRLIT_ARGS("100") }, |
|
{ STRLIT_ARGS("101") }, |
|
{ STRLIT_ARGS("102") }, |
|
{ STRLIT_ARGS("103") }, |
|
{ STRLIT_ARGS("104") }, |
|
{ STRLIT_ARGS("105") }, |
|
{ STRLIT_ARGS("106") }, |
|
{ STRLIT_ARGS("107") }, |
|
{ STRLIT_ARGS("108") }, |
|
{ STRLIT_ARGS("109") }, |
|
{ STRLIT_ARGS("110") }, |
|
{ STRLIT_ARGS("111") }, |
|
{ STRLIT_ARGS("112") }, |
|
{ STRLIT_ARGS("113") }, |
|
{ STRLIT_ARGS("114") }, |
|
{ STRLIT_ARGS("115") }, |
|
{ STRLIT_ARGS("116") }, |
|
{ STRLIT_ARGS("117") }, |
|
{ STRLIT_ARGS("118") }, |
|
{ STRLIT_ARGS("119") }, |
|
{ STRLIT_ARGS("120") }, |
|
{ STRLIT_ARGS("121") }, |
|
{ STRLIT_ARGS("122") }, |
|
{ STRLIT_ARGS("123") }, |
|
{ STRLIT_ARGS("124") }, |
|
{ STRLIT_ARGS("125") }, |
|
{ STRLIT_ARGS("126") }, |
|
{ STRLIT_ARGS("127") }, |
|
}; |
|
|
|
template<class T> |
|
static inline char* _append_unsigned(char* end, T x) |
|
{ |
|
char* p = end; |
|
|
|
do |
|
{ |
|
*--p = '0' + static_cast<char>(x % 10); |
|
} |
|
while ((x /= 10) != 0); |
|
|
|
return p; |
|
} |
|
|
|
void Formatter::Arg::appendToString(String& out) const |
|
{ |
|
switch (_type) |
|
{ |
|
case INTEGER: |
|
{ |
|
Sint32 x = _integer; |
|
|
|
if (x >= 0 && x < 128) |
|
out.append(_num_strings[x].str, _num_strings[x].size); |
|
else |
|
{ |
|
char buffer[32]; |
|
int n = sprintf(buffer, "%d", x); |
|
out.append(buffer, n); |
|
} |
|
break; |
|
} |
|
|
|
case UINTEGER: |
|
{ |
|
Uint32 x = _uinteger; |
|
|
|
if (x < 128) |
|
out.append(_num_strings[x].str, _num_strings[x].size); |
|
else |
|
{ |
|
char buffer[32]; |
|
int n = sprintf(buffer, "%u", x); |
|
out.append(buffer, n); |
|
} |
|
break; |
|
} |
|
|
|
case BOOLEAN: |
|
{ |
|
if (_boolean) |
|
out.append("true", 4); |
|
else |
|
out.append("false", 5); |
|
break; |
|
} |
|
|
|
case REAL: |
|
{ |
|
char buffer[32]; |
|
int n = sprintf(buffer, "%f", _real); |
|
out.append(buffer, n); |
|
break; |
|
} |
|
|
|
case LINTEGER: |
|
{ |
|
char buffer[32]; |
|
int n = sprintf( |
|
buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "d", _lInteger); |
|
out.append(buffer, n); |
|
break; |
|
} |
|
|
|
case ULINTEGER: |
|
{ |
|
Uint64 x = _lUInteger; |
|
|
|
if (x < 128) |
|
out.append(_num_strings[x].str, _num_strings[x].size); |
|
else |
|
{ |
|
char buffer[32]; |
|
char* end = &buffer[32]; |
|
char* p = _append_unsigned(end, x); |
|
out.append(p, end - p); |
|
} |
|
break; |
|
} |
|
|
|
case STRING: |
|
{ |
|
out.append(_string); |
|
break; |
|
} |
|
|
|
case CSTRLIT: |
|
{ |
|
out.append(_cstrlit->str, _cstrlit->size); |
|
break; |
|
} |
|
|
|
case VOIDT: |
|
default: |
|
break; |
|
} |
|
} |
|
|
|
// |
|
// Non-special characters (any but these: '$', '\0', '\\') |
|
// |
|
static const Uint8 _isNonSpecial[256] = |
|
{ |
|
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, |
|
1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, |
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1, |
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, |
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, |
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, |
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, |
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, |
|
}; |
|
|
|
PEGASUS_USING_STD; |
|
|
String Formatter::format( | String Formatter::format( |
const String& formatString, |
const String& format, |
const Arg& arg0, | const Arg& arg0, |
const Arg& arg1, | const Arg& arg1, |
const Arg& arg2, | const Arg& arg2, |
|
|
const Arg& arg9) | const Arg& arg9) |
{ | { |
String result; | String result; |
const Char16* first = formatString.getData(); |
|
const Char16* last = formatString.getData() + formatString.size(); |
|
| |
for (; first != last; first++) |
#if 0 |
|
cout << format << endl; |
|
#endif |
|
|
|
result.reserveCapacity(256); |
|
|
|
const Uint16* p = (const Uint16*)format.getChar16Data(); |
|
|
|
for (;;) |
{ | { |
if (*first == '$') |
//// Skip over non-special characters: |
|
|
|
const Uint16* start = p; |
|
|
|
while (*p < 128 && _isNonSpecial[*p]) |
|
p++; |
|
|
|
//// Append any non-special characters. |
|
|
|
size_t r = p - start; |
|
|
|
if (r) |
|
result.append((const Char16*)start, r); |
|
|
|
//// Process next special character: |
|
|
|
if (*p == '$') |
{ | { |
Char16 c = *++first; |
Uint16 c = p[1]; |
| |
switch (c) |
switch (c - '0') |
{ |
{ |
case '0': result += arg0.toString(); break; |
case 0: arg0.appendToString(result); break; |
case '1': result += arg1.toString(); break; |
case 1: arg1.appendToString(result); break; |
case '2': result += arg2.toString(); break; |
case 2: arg2.appendToString(result); break; |
case '3': result += arg3.toString(); break; |
case 3: arg3.appendToString(result); break; |
case '4': result += arg4.toString(); break; |
case 4: arg4.appendToString(result); break; |
case '5': result += arg5.toString(); break; |
case 5: arg5.appendToString(result); break; |
case '6': result += arg6.toString(); break; |
case 6: arg6.appendToString(result); break; |
case '7': result += arg7.toString(); break; |
case 7: arg7.appendToString(result); break; |
case '8': result += arg8.toString(); break; |
case 8: arg8.appendToString(result); break; |
case '9': result += arg9.toString(); break; |
case 9: arg9.appendToString(result); break; |
default: break; | default: break; |
} | } |
|
|
|
p += 2; |
|
} |
|
else if (*p == '\\') |
|
{ |
|
result.append(p[1]); |
|
p += 2; |
} | } |
else if (*first == '\\') |
else if (*p == '\0') |
{ | { |
first++; |
break; |
result += *first; |
|
} | } |
else | else |
result += *first; |
{ |
|
result.append(p[0]); |
|
p++; |
} | } |
|
} |
|
|
|
#if 0 |
|
cout << result << endl; |
|
#endif |
| |
return result; | return result; |
} | } |