version 1.126, 2005/10/31 18:21:55
|
version 1.153.2.3, 2008/02/28 00:21:08
|
|
|
//%2005//////////////////////////////////////////////////////////////////////// |
//%2006//////////////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development | // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. | // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
|
|
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. | // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; | // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
// EMC Corporation; VERITAS Software Corporation; The Open Group. | // 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) |
|
// |
|
// Modified By: Nitin Upasani, Hewlett-Packard Company (Nitin_Upasani@hp.com) |
|
// Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com) |
|
// Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) |
|
// Carol Ann Krug Graves, Hewlett-Packard Company |
|
// (carolann_graves@hp.com) |
|
// Amit K Arora, IBM (amita@in.ibm.com) for PEP#101 |
|
// Brian G. Campbell, EMC (campbell_brian@emc.com) - PEP140/phase1 |
|
// Willis White (whiwill@us.ibm.com) PEP 127 and 128 |
|
// Brian G. Campbell, EMC (campbell_brian@emc.com) - PEP140/phase2 |
|
// Dave Sudlik, IBM (dsudlik@us.ibm.com) |
|
// David Dillard, VERITAS Software Corp. |
|
// (david.dillard@veritas.com) |
|
// Vijay Eli, vijayeli@in.ibm.com, fix for #2571 |
|
// |
|
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#include <Pegasus/Common/Config.h> | #include <Pegasus/Common/Config.h> |
|
|
#include <Pegasus/Common/StatisticalData.h> | #include <Pegasus/Common/StatisticalData.h> |
#include "CommonUTF.h" | #include "CommonUTF.h" |
#include "Buffer.h" | #include "Buffer.h" |
// For a future optimization: |
#include "StrLit.h" |
#define STRLIT(X) X |
#include "LanguageParser.h" |
|
#include "IDFactory.h" |
|
#include "StringConversion.h" |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
// This is a shortcut macro for outputing content length. This |
|
// pads the output number to the max characters representing a Uint32 number |
|
// so that it can be overwritten easily with a transfer encoding line later |
|
// on in HTTPConnection if required. This is strictly for performance since |
|
// messages can be very large. This overwriting shortcut allows us to NOT have |
|
// to repackage a large message later. |
|
|
|
#define OUTPUT_CONTENTLENGTH \ |
|
{ \ |
|
char contentLengthP[11]; \ |
|
sprintf(contentLengthP,"%.10u", contentLength); \ |
|
out << STRLIT("content-length: ") << contentLengthP << STRLIT("\r\n"); \ |
|
} |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// SpecialChar and table. |
|
// |
|
//////////////////////////////////////////////////////////////////////////////// |
|
|
|
struct SpecialChar |
|
{ |
|
const char* str; |
|
size_t size; |
|
}; |
|
|
|
// Defines encodings of special characters. Just use a 7-bit ASCII character |
|
// as an index into this array to retrieve its string encoding and encoding |
|
// length in bytes. |
|
static const SpecialChar _specialChars[] = |
|
{ |
|
{ "�", 4 }, |
|
{ "", 4 }, |
|
{ "", 4 }, |
|
{ "", 4 }, |
|
{ "", 4 }, |
|
{ "", 4 }, |
|
{ "", 4 }, |
|
{ "", 4 }, |
|
{ "", 4 }, |
|
{ "	", 4 }, |
|
{ " ", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ " ", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ "", 5 }, |
|
{ " ", 1 }, |
|
{ "!", 1 }, |
|
{ """, 6 }, |
|
{ "#", 1 }, |
|
{ "$", 1 }, |
|
{ "%", 1 }, |
|
{ "&", 5 }, |
|
{ "'", 6 }, |
|
{ "(", 1 }, |
|
{ ")", 1 }, |
|
{ "*", 1 }, |
|
{ "+", 1 }, |
|
{ ",", 1 }, |
|
{ "-", 1 }, |
|
{ ".", 1 }, |
|
{ "/", 1 }, |
|
{ "0", 1 }, |
|
{ "1", 1 }, |
|
{ "2", 1 }, |
|
{ "3", 1 }, |
|
{ "4", 1 }, |
|
{ "5", 1 }, |
|
{ "6", 1 }, |
|
{ "7", 1 }, |
|
{ "8", 1 }, |
|
{ "9", 1 }, |
|
{ ":", 1 }, |
|
{ ";", 1 }, |
|
{ "<", 4 }, |
|
{ "=", 1 }, |
|
{ ">", 4 }, |
|
{ "?", 1 }, |
|
{ "@", 1 }, |
|
{ "A", 1 }, |
|
{ "B", 1 }, |
|
{ "C", 1 }, |
|
{ "D", 1 }, |
|
{ "E", 1 }, |
|
{ "F", 1 }, |
|
{ "G", 1 }, |
|
{ "H", 1 }, |
|
{ "I", 1 }, |
|
{ "J", 1 }, |
|
{ "K", 1 }, |
|
{ "L", 1 }, |
|
{ "M", 1 }, |
|
{ "N", 1 }, |
|
{ "O", 1 }, |
|
{ "P", 1 }, |
|
{ "Q", 1 }, |
|
{ "R", 1 }, |
|
{ "S", 1 }, |
|
{ "T", 1 }, |
|
{ "U", 1 }, |
|
{ "V", 1 }, |
|
{ "W", 1 }, |
|
{ "X", 1 }, |
|
{ "Y", 1 }, |
|
{ "Z", 1 }, |
|
{ "[", 1 }, |
|
{ "\\", 1 }, |
|
{ "]", 1 }, |
|
{ "^", 1 }, |
|
{ "_", 1 }, |
|
{ "`", 1 }, |
|
{ "a", 1 }, |
|
{ "b", 1 }, |
|
{ "c", 1 }, |
|
{ "d", 1 }, |
|
{ "e", 1 }, |
|
{ "f", 1 }, |
|
{ "g", 1 }, |
|
{ "h", 1 }, |
|
{ "i", 1 }, |
|
{ "j", 1 }, |
|
{ "k", 1 }, |
|
{ "l", 1 }, |
|
{ "m", 1 }, |
|
{ "n", 1 }, |
|
{ "o", 1 }, |
|
{ "p", 1 }, |
|
{ "q", 1 }, |
|
{ "r", 1 }, |
|
{ "s", 1 }, |
|
{ "t", 1 }, |
|
{ "u", 1 }, |
|
{ "v", 1 }, |
|
{ "w", 1 }, |
|
{ "x", 1 }, |
|
{ "y", 1 }, |
|
{ "z", 1 }, |
|
{ "{", 1 }, |
|
{ "|", 1 }, |
|
{ "}", 1 }, |
|
{ "~", 1 }, |
|
{ "", 6 }, |
|
}; |
|
|
|
// If _isSpecialChar7[ch] is true, then ch is a special character, which must |
|
// have a special encoding in XML. But only use 7-bit ASCII characters to |
|
// index this array. |
|
static const int _isSpecialChar7[] = |
|
{ |
|
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,0,1,0,0, |
|
0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, |
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, |
|
}; |
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
|
|
Buffer& operator<<(Buffer& out, const char* x) |
|
{ |
|
XmlWriter::append(out, x); |
|
return out; |
|
} |
|
|
|
Buffer& operator<<(Buffer& out, char x) |
|
{ |
|
XmlWriter::append(out, x); |
|
return out; |
|
} |
|
|
|
Buffer& operator<<(Buffer& out, const Char16& x) |
|
{ |
|
XmlWriter::append(out, x); |
|
return out; |
|
} |
|
|
|
Buffer& operator<<(Buffer& out, const String& x) |
|
{ |
|
XmlWriter::append(out, x); |
|
return out; |
|
} |
|
|
|
Buffer& operator<<(Buffer& out, const Indentor& x) |
|
{ |
|
XmlWriter::append(out, x); |
|
return out; |
|
} |
|
|
|
Buffer& operator<<(Buffer& out, const Buffer& x) |
|
{ |
|
out.append(x.getData(), x.size()); |
|
return out; |
|
} |
|
|
|
Buffer& operator<<(Buffer& out, Uint32 x) |
|
{ |
|
XmlWriter::append(out, x); |
|
return out; |
|
} |
|
|
|
Buffer& operator<<(Buffer& out, const CIMName& name) |
|
{ |
|
XmlWriter::append(out, name.getString ()); |
|
return out; |
|
} |
|
|
|
|
|
// l10n |
|
Buffer& operator<<(Buffer& out, const AcceptLanguages& al) |
|
{ |
|
XmlWriter::append(out, al.toString ()); |
|
return out; |
|
} |
|
|
|
// l10n |
|
Buffer& operator<<(Buffer& out, const ContentLanguages& cl) |
|
{ |
|
XmlWriter::append(out, cl.toString ()); |
|
return out; |
|
} |
|
|
|
|
|
PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const CIMDateTime& x) |
|
{ |
|
return os << x.toString(); |
|
} |
|
|
|
PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, const CIMName& name) |
|
{ |
|
os << name.getString(); |
|
return os; |
|
} |
|
|
|
PEGASUS_STD(ostream)& operator<<(PEGASUS_STD(ostream)& os, |
|
const CIMNamespaceName& name) |
|
{ |
|
os << name.getString(); |
|
return os; |
|
} |
|
|
|
static void _xmlWritter_appendChar(Buffer& out, const Char16& c) |
|
{ |
|
// We need to convert the Char16 to UTF8 then append the UTF8 |
|
// character into the array. |
|
// NOTE: The UTF8 character could be several bytes long. |
|
// WARNING: This function will put in replacement character for |
|
// all characters that have surogate pairs. |
|
char str[6]; |
|
memset(str,0x00,sizeof(str)); |
|
Uint8* charIN = (Uint8 *)&c; |
|
|
|
const Uint16 *strsrc = (Uint16 *)charIN; |
|
Uint16 *endsrc = (Uint16 *)&charIN[1]; |
|
|
|
Uint8 *strtgt = (Uint8 *)str; |
|
Uint8 *endtgt = (Uint8 *)&str[5]; |
|
|
|
UTF16toUTF8(&strsrc, |
|
endsrc, |
|
&strtgt, |
|
endtgt); |
|
|
|
out.append(str, UTF_8_COUNT_TRAIL_BYTES(str[0]) + 1); |
|
} |
|
|
|
inline void _appendSpecialChar7(Buffer& out, char c) |
|
{ |
|
if (_isSpecialChar7[int(c)]) |
|
out.append(_specialChars[int(c)].str, _specialChars[int(c)].size); |
|
else |
|
out.append(c); |
|
} |
|
|
|
inline void _xmlWritter_appendSpecialChar(Buffer& out, const Char16& c) |
|
{ |
|
if (c < 128) |
|
_appendSpecialChar7(out, char(c)); |
|
else |
|
_xmlWritter_appendChar(out, c); |
|
} |
|
|
|
static void _xmlWritter_appendSpecialChar(PEGASUS_STD(ostream)& os, char c) |
|
{ |
|
if ( ((c < 0x20) && (c >= 0)) || (c == 0x7f) ) |
|
{ |
|
char charref[7]; |
|
sprintf(charref, "&#%u;", static_cast<Uint8>(c)); |
|
os << charref; |
|
} |
|
else |
|
{ |
|
switch (c) |
|
{ |
|
case '&': |
|
os << "&"; |
|
break; |
|
|
|
case '<': |
|
os << "<"; |
|
break; |
|
|
|
case '>': |
|
os << ">"; |
|
break; |
|
|
|
case '"': |
|
os << """; |
|
break; |
|
|
|
case '\'': |
|
os << "'"; |
|
break; |
|
|
|
default: |
|
os << c; |
|
} |
|
} |
|
} |
|
|
|
void _xmlWritter_appendSurrogatePair(Buffer& out, Uint16 high, Uint16 low) |
|
{ |
|
char str[6]; |
|
Uint8 charIN[5]; |
|
memset(str,0x00,sizeof(str)); |
|
memcpy(&charIN,&high,2); |
|
memcpy(&charIN[2],&low,2); |
|
const Uint16 *strsrc = (Uint16 *)charIN; |
|
Uint16 *endsrc = (Uint16 *)&charIN[3]; |
|
|
|
Uint8 *strtgt = (Uint8 *)str; |
|
Uint8 *endtgt = (Uint8 *)&str[5]; |
|
|
|
UTF16toUTF8(&strsrc, |
|
endsrc, |
|
&strtgt, |
|
endtgt); |
|
|
|
Uint32 number1 = UTF_8_COUNT_TRAIL_BYTES(str[0]) + 1; |
|
out.append(str,number1); |
|
} |
|
|
|
inline void _xmlWritter_appendSpecial(PEGASUS_STD(ostream)& os, const char* str) |
|
{ |
|
while (*str) |
|
_xmlWritter_appendSpecialChar(os, *str++); |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, const Char16& x) |
|
{ |
|
_xmlWritter_appendChar(out, x); |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, Boolean x) |
|
{ |
|
append(out, (x ? "TRUE" : "FALSE")); |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, Uint32 x) |
|
{ |
|
char buffer[32]; |
|
sprintf(buffer, "%u", x); |
|
append(out, buffer); |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, Sint32 x) |
|
{ |
|
char buffer[32]; |
|
sprintf(buffer, "%d", x); |
|
append(out, buffer); |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, Uint64 x) |
|
{ |
|
char buffer[32]; // Should need 21 chars max |
|
sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", x); |
|
append(out, buffer); |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, Sint64 x) |
|
{ |
|
char buffer[32]; // Should need 21 chars max |
|
sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "d", x); |
|
append(out, buffer); |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, Real32 x) |
|
{ |
|
char buffer[128]; |
|
// %.7e gives '[-]m.ddddddde+/-xx', which seems compatible with the format |
|
// given in the CIM/XML spec, and the precision required by the CIM 2.2 spec |
|
// (4 byte IEEE floating point) |
|
sprintf(buffer, "%.7e", x); |
|
append(out, buffer); |
|
} |
|
| |
void XmlWriter::append(Buffer& out, Real64 x) |
|
{ |
|
char buffer[128]; |
|
// %.16e gives '[-]m.dddddddddddddddde+/-xx', which seems compatible with the format |
|
// given in the CIM/XML spec, and the precision required by the CIM 2.2 spec |
|
// (8 byte IEEE floating point) |
|
sprintf(buffer, "%.16e", x); |
|
append(out, buffer); |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, const char* str) |
|
{ |
|
size_t n = strlen(str); |
|
out.append(str, n); |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, const String& str) |
|
{ |
|
const Uint16* p = (const Uint16*)str.getChar16Data(); |
|
size_t n = str.size(); |
|
|
|
// Handle leading ASCII 7 characers in these next two loops (use unrolling). |
|
|
|
while (n >= 8 && ((p[0]|p[1]|p[2]|p[3]|p[4]|p[5]|p[6]|p[7]) & 0xFF80) == 0) |
|
{ |
|
out.append(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); |
|
p += 8; |
|
n -= 8; |
|
} |
|
|
|
while (n >= 4 && ((p[0]|p[1]|p[2]|p[3]) & 0xFF80) == 0) |
|
{ |
|
out.append(p[0], p[1], p[2], p[3]); |
|
p += 4; |
|
n -= 4; |
|
} |
|
|
|
while (n--) |
|
{ |
|
Uint16 c = *p++; |
|
|
|
// Special processing for UTF8 case: |
|
|
|
if (c < 128) |
|
{ |
|
out.append(c); |
|
continue; |
|
} |
|
|
|
// Hanlde UTF8 case (if reached). |
|
|
|
if(((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) || |
|
((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) |
|
{ |
|
Char16 highSurrogate = p[-1]; |
|
Char16 lowSurrogate = p[0]; |
|
p++; |
|
n--; |
|
|
|
_xmlWritter_appendSurrogatePair( |
|
out, Uint16(highSurrogate),Uint16(lowSurrogate)); |
|
} |
|
else |
|
{ |
|
_xmlWritter_appendChar(out, c); |
|
} |
|
} |
|
} |
|
|
|
void XmlWriter::append(Buffer& out, const Indentor& x) |
|
{ |
|
for (Uint32 i = 0; i < 4 * x.getLevel(); i++) |
|
out.append(' '); |
|
} |
|
|
|
void XmlWriter::appendSpecial(Buffer& out, const Char16& x) |
|
{ |
|
_xmlWritter_appendSpecialChar(out, x); |
|
} |
|
|
|
void XmlWriter::appendSpecial(Buffer& out, char x) |
|
{ |
|
_appendSpecialChar7(out, x); |
|
} |
|
|
|
void XmlWriter::appendSpecial(Buffer& out, const char* str) |
|
{ |
|
while (*str) |
|
_appendSpecialChar7(out, *str++); |
|
} |
|
|
|
void XmlWriter::appendSpecial(Buffer& out, const String& str) |
|
{ |
|
const Uint16* p = (const Uint16*)str.getChar16Data(); |
|
size_t n = str.size(); |
|
|
|
// Handle leading ASCII 7 characers in these next two loops (use unrolling). |
|
|
|
while (n >= 8) |
|
{ |
|
// The following condition is equivalent to this: |
|
// (p[0] < 128 && p[1] < 128 && p[2] < 128 && p[3] < 128 && |
|
// p[4] < 128 && p[5] < 128 && p[6] < 128 && p[7] < 128) |
|
|
|
if (((p[0]|p[1]|p[2]|p[3]|p[4]|p[5]|p[6]|p[7]) & 0xFF80) == 0) |
|
{ |
|
// Note: "|" is faster than "||" and achieves the same effect |
|
// since p[i] is either 0 or 1. |
|
|
|
if (_isSpecialChar7[p[0]] | _isSpecialChar7[p[1]] | |
|
_isSpecialChar7[p[2]] | _isSpecialChar7[p[3]] | |
|
_isSpecialChar7[p[4]] | _isSpecialChar7[p[5]] | |
|
_isSpecialChar7[p[6]] | _isSpecialChar7[p[7]]) |
|
{ |
|
// Rare case. |
|
_appendSpecialChar7(out, p[0]); |
|
_appendSpecialChar7(out, p[1]); |
|
_appendSpecialChar7(out, p[2]); |
|
_appendSpecialChar7(out, p[3]); |
|
_appendSpecialChar7(out, p[4]); |
|
_appendSpecialChar7(out, p[5]); |
|
_appendSpecialChar7(out, p[6]); |
|
_appendSpecialChar7(out, p[7]); |
|
} |
|
else |
|
{ |
|
// Common case. |
|
out.append(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); |
|
} |
|
p += 8; |
|
n -= 8; |
|
} |
|
else |
|
break; |
|
} |
|
|
|
while (n >= 4) |
|
{ |
|
// The following condition is equivalent to this: |
|
// (p[0] < 128 && p[1] < 128 && p[2] < 128 && p[3] < 128) |
|
|
|
if (((p[0]|p[1]|p[2]|p[3]) & 0xFF80) == 0) |
|
{ |
|
if (_isSpecialChar7[p[0]] | _isSpecialChar7[p[1]] | |
|
_isSpecialChar7[p[2]] | _isSpecialChar7[p[3]]) |
|
{ |
|
// Rare case: |
|
_appendSpecialChar7(out, p[0]); |
|
_appendSpecialChar7(out, p[1]); |
|
_appendSpecialChar7(out, p[2]); |
|
_appendSpecialChar7(out, p[3]); |
|
} |
|
else |
|
{ |
|
// Common case: |
|
out.append(p[0], p[1], p[2], p[3]); |
|
} |
|
|
|
p += 4; |
|
n -= 4; |
|
} |
|
else |
|
break; |
|
} |
|
|
|
// Process remaining characters. A UTF8 character must have been |
|
// encountered or this would have never been reached. |
|
|
|
while (n--) |
|
{ |
|
Uint16 c = *p++; |
|
|
|
// Special processing for UTF8 case: |
|
|
|
if (c < 128) |
|
{ |
|
_appendSpecialChar7(out, c); |
|
continue; |
|
} |
|
|
|
// Hanlde UTF8 case (if reached). |
|
|
|
if(((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) || |
|
((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) |
|
{ |
|
Char16 highSurrogate = p[-1]; |
|
Char16 lowSurrogate = p[0]; |
|
p++; |
|
n--; |
|
|
|
_xmlWritter_appendSurrogatePair( |
|
out, Uint16(highSurrogate),Uint16(lowSurrogate)); |
|
} |
|
else |
|
{ |
|
_xmlWritter_appendSpecialChar(out, c); |
|
} |
|
} |
|
} |
|
|
|
// See http://www.ietf.org/rfc/rfc2396.txt section 2 |
|
// Reserved characters = ';' '/' '?' ':' '@' '&' '=' '+' '$' ',' |
|
// Excluded characters: |
|
// Control characters = 0x00-0x1f, 0x7f |
|
// Space character = 0x20 |
|
// Delimiters = '<' '>' '#' '%' '"' |
|
// Unwise = '{' '}' '|' '\\' '^' '[' ']' '`' |
|
// |
|
|
|
static const char _is_uri[128] = |
|
{ |
|
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,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, |
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
|
0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1, |
|
}; |
|
|
|
static void _xmlWritter_encodeURIChar(String& outString, Sint8 char8) |
|
{ |
|
Uint8 c = (Uint8)char8; |
|
|
|
#ifndef PEGASUS_DO_NOT_IMPLEMENT_URI_ENCODING |
|
if (c > 127 || _is_uri[int(c)]) |
|
{ |
|
char hexencoding[4]; |
|
int n = sprintf(hexencoding, "%%%X%X", c/16, c%16); |
|
#ifdef PEGASUS_USE_STRING_EXTENSIONS |
|
outString.append(hexencoding, n); |
|
#else /* PEGASUS_USE_STRING_EXTENSIONS */ |
|
outString.append(hexencoding); |
|
#endif /* PEGASUS_USE_STRING_EXTENSIONS */ |
|
} |
|
else |
|
#endif |
|
{ |
|
outString.append((Uint16)c); |
|
} |
|
} |
|
|
|
String XmlWriter::encodeURICharacters(const Buffer& uriString) |
|
{ |
|
String encodedString; |
|
|
|
for (Uint32 i=0; i<uriString.size(); i++) |
|
{ |
|
_xmlWritter_encodeURIChar(encodedString, uriString[i]); |
|
} |
|
|
|
return encodedString; |
|
} |
|
|
|
String XmlWriter::encodeURICharacters(const String& uriString) |
|
{ |
|
String encodedString; |
|
|
|
/* i18n remove - did not handle surrogate pairs |
|
for (Uint32 i=0; i<uriString.size(); i++) |
|
{ |
|
_xmlWritter_encodeURIChar(encodedString, uriString[i]); |
|
} |
|
*/ |
|
|
|
// See the "CIM Operations over HTTP" spec, section 3.3.2 and |
|
// 3.3.3, for the treatment of non US-ASCII (UTF-8) chars |
|
|
|
// First, convert to UTF-8 (include handling of surrogate pairs) |
|
Buffer utf8; |
|
for (Uint32 i = 0; i < uriString.size(); i++) |
|
{ |
|
Uint16 c = uriString[i]; |
|
|
|
if(((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) || |
|
((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) |
|
{ |
|
Char16 highSurrogate = uriString[i]; |
|
Char16 lowSurrogate = uriString[++i]; |
|
|
|
_xmlWritter_appendSurrogatePair(utf8, Uint16(highSurrogate),Uint16(lowSurrogate)); |
|
} |
|
else |
|
{ |
|
_xmlWritter_appendChar(utf8, uriString[i]); |
|
} |
|
} |
|
|
|
// Second, escape the non HTTP-safe chars |
|
for (Uint32 i=0; i<utf8.size(); i++) |
|
{ |
|
_xmlWritter_encodeURIChar(encodedString, utf8[i]); |
|
} |
|
|
|
return encodedString; |
|
} |
|
| |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
// | // |
|
|
| |
char* nameSpaceCopy = strdup(nameSpace.getString().getCString()); | char* nameSpaceCopy = strdup(nameSpace.getString().getCString()); |
| |
#if defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) || \ |
#if !defined(PEGASUS_COMPILER_MSVC) && !defined(PEGASUS_OS_ZOS) |
defined(PEGASUS_OS_HPUX) || \ |
|
defined(PEGASUS_OS_LINUX) |
|
char *last; | char *last; |
for (const char* p = strtok_r(nameSpaceCopy, "/", &last); p; | for (const char* p = strtok_r(nameSpaceCopy, "/", &last); p; |
p = strtok_r(NULL, "/", &last)) | p = strtok_r(NULL, "/", &last)) |
|
|
CIMObjectPath ref = keyBindings[i].getValue(); | CIMObjectPath ref = keyBindings[i].getValue(); |
appendValueReferenceElement(out, ref, true); | appendValueReferenceElement(out, ref, true); |
} | } |
else { |
else |
|
{ |
out << STRLIT("<KEYVALUE VALUETYPE=\""); | out << STRLIT("<KEYVALUE VALUETYPE=\""); |
out << keyBindingTypeToString(keyBindings[i].getType()); | out << keyBindingTypeToString(keyBindings[i].getType()); |
out << STRLIT("\">"); | out << STRLIT("\">"); |
|
|
| |
inline void _xmlWritter_appendValue(Buffer& out, const CIMDateTime& x) | inline void _xmlWritter_appendValue(Buffer& out, const CIMDateTime& x) |
{ | { |
out << x.toString(); //ATTN: append() method? |
// It is not necessary to use XmlWriter::appendSpecial(), because |
|
// CIMDateTime values do not contain special characters. |
|
out << x.toString(); |
} | } |
| |
inline void _xmlWritter_appendValue(Buffer& out, const CIMObjectPath& x) | inline void _xmlWritter_appendValue(Buffer& out, const CIMObjectPath& x) |
|
|
_xmlWritter_appendValueArray(out, a.getData(), a.size()); | _xmlWritter_appendValueArray(out, a.getData(), a.size()); |
break; | break; |
} | } |
|
#ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT |
|
case CIMTYPE_INSTANCE: |
|
{ |
|
Array<CIMInstance> a; |
|
value.get(a); |
|
_xmlWritter_appendValueArray(out, a.getData(), a.size()); |
|
break; |
|
} |
|
#endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT |
default: | default: |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
} | } |
|
|
_xmlWritter_appendValue(out, v); | _xmlWritter_appendValue(out, v); |
break; | break; |
} | } |
|
#ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT |
|
case CIMTYPE_INSTANCE: |
|
{ |
|
CIMInstance v; |
|
value.get(v); |
|
_xmlWritter_appendValue(out, v); |
|
break; |
|
} |
|
#endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT |
default: | default: |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
} | } |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendValueElement(tmp, value); | appendValueElement(tmp, value); |
tmp.append('\0'); |
|
os << tmp.getData() << PEGASUS_STD(endl); | os << tmp.getData() << PEGASUS_STD(endl); |
} | } |
| |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendValueReferenceElement(tmp, reference, true); | appendValueReferenceElement(tmp, reference, true); |
tmp.append('\0'); |
XmlUtils::indentedPrint(os, tmp.getData()); |
indentedPrint(os, tmp.getData()); |
|
} | } |
| |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
|
|
Buffer& out, | Buffer& out, |
const CIMConstClass& cimclass) | const CIMConstClass& cimclass) |
{ | { |
cimclass._checkRep(); |
CheckRep(cimclass._rep); |
cimclass._rep->toXml(out); | cimclass._rep->toXml(out); |
} | } |
| |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendClassElement(tmp, cimclass); | appendClassElement(tmp, cimclass); |
tmp.append('\0'); |
XmlUtils::indentedPrint(os, tmp.getData(), 4); |
indentedPrint(os, tmp.getData(), 4); |
|
} | } |
| |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
|
|
Buffer& out, | Buffer& out, |
const CIMConstInstance& instance) | const CIMConstInstance& instance) |
{ | { |
instance._checkRep(); |
CheckRep(instance._rep); |
instance._rep->toXml(out); | instance._rep->toXml(out); |
} | } |
| |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendInstanceElement(tmp, instance); | appendInstanceElement(tmp, instance); |
tmp.append('\0'); |
|
os << tmp.getData() << PEGASUS_STD(endl); | os << tmp.getData() << PEGASUS_STD(endl); |
} | } |
| |
|
|
Buffer& out, | Buffer& out, |
const CIMConstProperty& property) | const CIMConstProperty& property) |
{ | { |
property._checkRep(); |
CheckRep(property._rep); |
property._rep->toXml(out); | property._rep->toXml(out); |
} | } |
| |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendPropertyElement(tmp, property); | appendPropertyElement(tmp, property); |
tmp.append('\0'); |
|
os << tmp.getData() << PEGASUS_STD(endl); | os << tmp.getData() << PEGASUS_STD(endl); |
} | } |
| |
|
|
Buffer& out, | Buffer& out, |
const CIMConstMethod& method) | const CIMConstMethod& method) |
{ | { |
method._checkRep(); |
CheckRep(method._rep); |
method._rep->toXml(out); | method._rep->toXml(out); |
} | } |
| |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendMethodElement(tmp, method); | appendMethodElement(tmp, method); |
tmp.append('\0'); |
|
os << tmp.getData() << PEGASUS_STD(endl); | os << tmp.getData() << PEGASUS_STD(endl); |
} | } |
| |
|
|
Buffer& out, | Buffer& out, |
const CIMConstParameter& parameter) | const CIMConstParameter& parameter) |
{ | { |
parameter._checkRep(); |
CheckRep(parameter._rep); |
parameter._rep->toXml(out); | parameter._rep->toXml(out); |
} | } |
| |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendParameterElement(tmp, parameter); | appendParameterElement(tmp, parameter); |
tmp.append('\0'); |
|
os << tmp.getData() << PEGASUS_STD(endl); | os << tmp.getData() << PEGASUS_STD(endl); |
} | } |
| |
|
|
Buffer& out, | Buffer& out, |
const CIMParamValue& paramValue) | const CIMParamValue& paramValue) |
{ | { |
paramValue._checkRep(); |
CheckRep(paramValue._rep); |
paramValue._rep->toXml(out); | paramValue._rep->toXml(out); |
} | } |
| |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendParamValueElement(tmp, paramValue); | appendParamValueElement(tmp, paramValue); |
tmp.append('\0'); |
|
os << tmp.getData() << PEGASUS_STD(endl); | os << tmp.getData() << PEGASUS_STD(endl); |
} | } |
| |
|
|
Buffer& out, | Buffer& out, |
const CIMConstQualifier& qualifier) | const CIMConstQualifier& qualifier) |
{ | { |
qualifier._checkRep(); |
CheckRep(qualifier._rep); |
qualifier._rep->toXml(out); | qualifier._rep->toXml(out); |
} | } |
| |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendQualifierElement(tmp, qualifier); | appendQualifierElement(tmp, qualifier); |
tmp.append('\0'); |
|
os << tmp.getData() << PEGASUS_STD(endl); | os << tmp.getData() << PEGASUS_STD(endl); |
} | } |
| |
|
|
Buffer& out, | Buffer& out, |
const CIMConstQualifierDecl& qualifierDecl) | const CIMConstQualifierDecl& qualifierDecl) |
{ | { |
qualifierDecl._checkRep(); |
CheckRep(qualifierDecl._rep); |
qualifierDecl._rep->toXml(out); | qualifierDecl._rep->toXml(out); |
} | } |
| |
|
|
{ | { |
Buffer tmp; | Buffer tmp; |
appendQualifierDeclElement(tmp, qualifierDecl); | appendQualifierDeclElement(tmp, qualifierDecl); |
tmp.append('\0'); |
|
os << tmp.getData() << PEGASUS_STD(endl); | os << tmp.getData() << PEGASUS_STD(endl); |
} | } |
| |
|
|
const String& cimObject, | const String& cimObject, |
const String& authenticationHeader, | const String& authenticationHeader, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const AcceptLanguages & acceptLanguages, |
const AcceptLanguageList& acceptLanguages, |
const ContentLanguages & contentLanguages, |
const ContentLanguageList& contentLanguages, |
Uint32 contentLength) | Uint32 contentLength) |
{ | { |
char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' }; | char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' }; |
|
|
} | } |
if (contentLanguages.size() > 0) | if (contentLanguages.size() > 0) |
{ | { |
out << STRLIT("Content-Language: ") << contentLanguages << STRLIT("\r\n"); |
out << STRLIT("Content-Language: ") << contentLanguages << |
|
STRLIT("\r\n"); |
} | } |
| |
#ifdef PEGASUS_DEBUG | #ifdef PEGASUS_DEBUG |
|
|
| |
static const char *clientTransferEncodingOff = | static const char *clientTransferEncodingOff = |
getenv("PEGASUS_HTTP_TRANSFER_ENCODING_REQUEST"); | getenv("PEGASUS_HTTP_TRANSFER_ENCODING_REQUEST"); |
|
|
if (!clientTransferEncodingOff || *clientTransferEncodingOff != '0') | if (!clientTransferEncodingOff || *clientTransferEncodingOff != '0') |
#endif | #endif |
| |
|
|
out << nn << STRLIT("\r\n"); | out << nn << STRLIT("\r\n"); |
out << nn << STRLIT("-CIMOperation: MethodCall\r\n"); | out << nn << STRLIT("-CIMOperation: MethodCall\r\n"); |
out << nn << STRLIT("-CIMMethod: ") | out << nn << STRLIT("-CIMMethod: ") |
<< encodeURICharacters(cimMethod.getString()) << STRLIT("\r\n"); |
<< XmlUtils::encodeURICharacters(cimMethod.getString()) |
out << nn << STRLIT("-CIMObject: ") << encodeURICharacters(cimObject) |
<< STRLIT("\r\n"); |
|
out << nn << STRLIT("-CIMObject: ") |
|
<< XmlUtils::encodeURICharacters(cimObject) |
<< STRLIT("\r\n"); | << STRLIT("\r\n"); |
} | } |
else | else |
{ | { |
out << STRLIT("CIMOperation: MethodCall\r\n"); | out << STRLIT("CIMOperation: MethodCall\r\n"); |
out << STRLIT("CIMMethod: ") << encodeURICharacters(cimMethod.getString()) |
out << STRLIT("CIMMethod: ") |
|
<< XmlUtils::encodeURICharacters(cimMethod.getString()) |
<< STRLIT("\r\n"); | << STRLIT("\r\n"); |
out << STRLIT("CIMObject: ") << encodeURICharacters(cimObject) |
out << STRLIT("CIMObject: ") << XmlUtils::encodeURICharacters(cimObject) |
<< STRLIT("\r\n"); | << STRLIT("\r\n"); |
} | } |
| |
|
|
void XmlWriter::appendMethodResponseHeader( | void XmlWriter::appendMethodResponseHeader( |
Buffer& out, | Buffer& out, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const ContentLanguages & contentLanguages, |
const ContentLanguageList& contentLanguages, |
Uint32 contentLength, | Uint32 contentLength, |
Uint32 serverResponseTime) |
Uint64 serverResponseTime) |
{ | { |
char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' }; | char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' }; |
out << STRLIT("HTTP/1.1 " HTTP_STATUS_OK "\r\n"); | out << STRLIT("HTTP/1.1 " HTTP_STATUS_OK "\r\n"); |
STAT_SERVERTIME |
|
|
#ifndef PEGASUS_DISABLE_PERFINST |
|
if (StatisticalData::current()->copyGSD) |
|
{ |
|
out << STRLIT("WBEMServerResponseTime: ") << |
|
CIMValue(serverResponseTime).toString() << STRLIT("\r\n"); |
|
} |
|
#endif |
|
|
out << STRLIT("Content-Type: application/xml; charset=\"utf-8\"\r\n"); | out << STRLIT("Content-Type: application/xml; charset=\"utf-8\"\r\n"); |
OUTPUT_CONTENTLENGTH; | OUTPUT_CONTENTLENGTH; |
| |
if (contentLanguages.size() > 0) | if (contentLanguages.size() > 0) |
{ | { |
out << STRLIT("Content-Language: ") << contentLanguages << STRLIT("\r\n"); |
out << STRLIT("Content-Language: ") << contentLanguages << |
|
STRLIT("\r\n"); |
} | } |
if (httpMethod == HTTP_METHOD_M_POST) | if (httpMethod == HTTP_METHOD_M_POST) |
{ | { |
|
|
} | } |
if (errorDetail != String::EMPTY) | if (errorDetail != String::EMPTY) |
{ | { |
// ATTN-RK-P3-20020404: It is critical that this text not contain '\n' |
|
// ATTN-RK-P3-20020404: Need to encode this value properly. (See |
|
// CIM/HTTP Specification section 3.3.2 |
|
out << STRLIT(PEGASUS_HTTPHEADERTAG_ERRORDETAIL ": ") | out << STRLIT(PEGASUS_HTTPHEADERTAG_ERRORDETAIL ": ") |
<< encodeURICharacters(errorDetail) << STRLIT("\r\n"); |
<< XmlUtils::encodeURICharacters(errorDetail) << STRLIT("\r\n"); |
} | } |
out << STRLIT("\r\n"); | out << STRLIT("\r\n"); |
} | } |
|
|
const String& content) | const String& content) |
{ | { |
out << STRLIT("HTTP/1.1 " HTTP_STATUS_UNAUTHORIZED "\r\n"); | out << STRLIT("HTTP/1.1 " HTTP_STATUS_UNAUTHORIZED "\r\n"); |
|
Uint32 contentLength = 0; |
|
OUTPUT_CONTENTLENGTH; |
out << content << STRLIT("\r\n"); | out << content << STRLIT("\r\n"); |
out << STRLIT("\r\n"); | out << STRLIT("\r\n"); |
| |
|
|
out << STRLIT("<ERROR"); | out << STRLIT("<ERROR"); |
out << STRLIT(" CODE=\"") << Uint32(cimException.getCode()); | out << STRLIT(" CODE=\"") << Uint32(cimException.getCode()); |
out.append('"'); | out.append('"'); |
|
|
String description = TraceableCIMException(cimException).getDescription(); | String description = TraceableCIMException(cimException).getDescription(); |
|
|
if (description != String::EMPTY) | if (description != String::EMPTY) |
{ | { |
out << STRLIT(" DESCRIPTION=\""); | out << STRLIT(" DESCRIPTION=\""); |
appendSpecial(out, description); | appendSpecial(out, description); |
out.append('"'); | out.append('"'); |
} | } |
|
|
|
if (cimException.getErrorCount()) |
|
{ |
|
out << STRLIT(">"); |
|
|
|
for (Uint32 i = 0, n = cimException.getErrorCount(); i < n; i++) |
|
appendInstanceElement(out, cimException.getError(i)); |
|
|
|
out << STRLIT("</ERROR>"); |
|
} |
|
else |
out << STRLIT("/>"); | out << STRLIT("/>"); |
} | } |
| |
|
|
| |
CIMType type = value.getType(); | CIMType type = value.getType(); |
// If the property type is CIMObject, then | // If the property type is CIMObject, then |
// encode the property in CIM-XML as a string with the EMBEDDEDOBJECT attribute |
// encode the property in CIM-XML as a string with the EMBEDDEDOBJECT |
// (there is not currently a CIM-XML "object" datatype) |
// attribute (there is not currently a CIM-XML "object" datatype) |
// else | // else |
// output the real type | // output the real type |
if (type == CIMTYPE_OBJECT) | if (type == CIMTYPE_OBJECT) |
|
|
out << STRLIT(" PARAMTYPE=\"string\""); | out << STRLIT(" PARAMTYPE=\"string\""); |
out << STRLIT(" EMBEDDEDOBJECT=\"object\""); | out << STRLIT(" EMBEDDEDOBJECT=\"object\""); |
} | } |
|
#ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT |
|
else if (type == CIMTYPE_INSTANCE) |
|
{ |
|
out << STRLIT(" PARAMTYPE=\"string\""); |
|
out << STRLIT(" EMBEDDEDOBJECT=\"instance\""); |
|
} |
|
#endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT |
else | else |
{ | { |
out << STRLIT(" PARAMTYPE=\"") << cimTypeToString (type); | out << STRLIT(" PARAMTYPE=\"") << cimTypeToString (type); |
|
|
| |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
// | // |
// appendQualifierNameIParameter() |
|
// |
|
//------------------------------------------------------------------------------ |
|
|
|
void XmlWriter::appendQualifierNameIParameter( |
|
Buffer& out, |
|
const char* name, |
|
const String& qualifierName) |
|
{ |
|
// <!ELEMENT IPARAMVALUE (VALUE|VALUE.ARRAY|VALUE.REFERENCE |
|
// |INSTANCENAME|CLASSNAME|QUALIFIER.DECLARATION |
|
// |CLASS|INSTANCE|VALUE.NAMEDINSTANCE)?> |
|
// |
|
// ATTN: notice that there is really no way to pass a qualifier name |
|
// as an IPARAMVALUE element according to the spec (look above). So we |
|
// just pass it as a class name. An answer must be obtained later. |
|
|
|
_appendIParamValueElementBegin(out, name); |
|
appendClassNameElement(out, qualifierName); |
|
_appendIParamValueElementEnd(out); |
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// |
|
// appendClassNameIParameter() | // appendClassNameIParameter() |
// | // |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
|
|
const String& messageId, | const String& messageId, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const String& authenticationHeader, | const String& authenticationHeader, |
const AcceptLanguages& httpAcceptLanguages, |
const AcceptLanguageList& httpAcceptLanguages, |
const ContentLanguages& httpContentLanguages) |
const ContentLanguageList& httpContentLanguages) |
{ | { |
Buffer out; | Buffer out; |
Buffer tmp; | Buffer tmp; |
|
|
const CIMName& methodName, | const CIMName& methodName, |
const String& messageId, | const String& messageId, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const ContentLanguages & httpContentLanguages, |
const ContentLanguageList& httpContentLanguages, |
const Buffer& body, | const Buffer& body, |
Uint32 serverResponseTime, |
Uint64 serverResponseTime, |
Boolean isFirst, | Boolean isFirst, |
Boolean isLast) | Boolean isLast) |
{ | { |
|
|
{ | { |
// NOTE: temporarily put zero for content length. the http code | // NOTE: temporarily put zero for content length. the http code |
// will later decide to fill in the length or remove it altogether | // will later decide to fill in the length or remove it altogether |
appendMethodResponseHeader(out, httpMethod, httpContentLanguages, 0, |
appendMethodResponseHeader( |
serverResponseTime); |
out, httpMethod, httpContentLanguages, 0, serverResponseTime); |
_appendMessageElementBegin(out, messageId); | _appendMessageElementBegin(out, messageId); |
_appendSimpleRspElementBegin(out); | _appendSimpleRspElementBegin(out); |
_appendMethodResponseElementBegin(out, methodName); | _appendMethodResponseElementBegin(out, methodName); |
|
|
} | } |
| |
| |
|
|
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
// | // |
// XmlWriter::formatSimpleMethodErrorRspMessage() | // XmlWriter::formatSimpleMethodErrorRspMessage() |
|
|
_appendSimpleRspElementEnd(out); | _appendSimpleRspElementEnd(out); |
_appendMessageElementEnd(out); | _appendMessageElementEnd(out); |
| |
// l10n |
appendMethodResponseHeader( |
appendMethodResponseHeader(tmp, |
tmp, |
httpMethod, | httpMethod, |
cimException.getContentLanguages(), | cimException.getContentLanguages(), |
out.size()); | out.size()); |
|
|
const String& messageId, | const String& messageId, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const String& authenticationHeader, | const String& authenticationHeader, |
const AcceptLanguages& httpAcceptLanguages, |
const AcceptLanguageList& httpAcceptLanguages, |
const ContentLanguages& httpContentLanguages, |
const ContentLanguageList& httpContentLanguages, |
const Buffer& body) | const Buffer& body) |
{ | { |
Buffer out; | Buffer out; |
|
|
const CIMName& iMethodName, | const CIMName& iMethodName, |
const String& messageId, | const String& messageId, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const ContentLanguages & httpContentLanguages, |
const ContentLanguageList& httpContentLanguages, |
const Buffer& body, | const Buffer& body, |
Uint32 serverResponseTime, |
Uint64 serverResponseTime, |
Boolean isFirst, | Boolean isFirst, |
Boolean isLast) | Boolean isLast) |
{ | { |
|
|
{ | { |
// NOTE: temporarily put zero for content length. the http code | // NOTE: temporarily put zero for content length. the http code |
// will later decide to fill in the length or remove it altogether | // will later decide to fill in the length or remove it altogether |
appendMethodResponseHeader(out, httpMethod, httpContentLanguages, 0, |
appendMethodResponseHeader( |
serverResponseTime); |
out, httpMethod, httpContentLanguages, 0, serverResponseTime); |
_appendMessageElementBegin(out, messageId); | _appendMessageElementBegin(out, messageId); |
_appendSimpleRspElementBegin(out); | _appendSimpleRspElementBegin(out); |
_appendIMethodResponseElementBegin(out, iMethodName); | _appendIMethodResponseElementBegin(out, iMethodName); |
| |
// output the start of the return tag. Test if there is response data by: |
// output the start of the return tag. Test if there is response data |
|
// by: |
// 1. there is data on the first chunk OR | // 1. there is data on the first chunk OR |
// 2. there is no data on the first chunk but isLast is false implying | // 2. there is no data on the first chunk but isLast is false implying |
// there is more non-empty data to come. If all subsequent chunks | // there is more non-empty data to come. If all subsequent chunks |
|
|
_appendSimpleRspElementEnd(out); | _appendSimpleRspElementEnd(out); |
_appendMessageElementEnd(out); | _appendMessageElementEnd(out); |
| |
// l10n |
|
appendMethodResponseHeader(tmp, | appendMethodResponseHeader(tmp, |
httpMethod, | httpMethod, |
cimException.getContentLanguages(), | cimException.getContentLanguages(), |
|
|
const CIMName& cimMethod, | const CIMName& cimMethod, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const String& authenticationHeader, | const String& authenticationHeader, |
const AcceptLanguages& acceptLanguages, |
const AcceptLanguageList& acceptLanguages, |
const ContentLanguages& contentLanguages, |
const ContentLanguageList& contentLanguages, |
Uint32 contentLength) | Uint32 contentLength) |
{ | { |
char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' }; | char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' }; |
|
|
} | } |
if (contentLanguages.size() > 0) | if (contentLanguages.size() > 0) |
{ | { |
out << STRLIT("Content-Language: ") << contentLanguages << STRLIT("\r\n"); |
out << STRLIT("Content-Language: ") << contentLanguages << |
|
STRLIT("\r\n"); |
} | } |
| |
#ifdef PEGASUS_DEBUG | #ifdef PEGASUS_DEBUG |
|
|
out << STRLIT("Man: http://www.dmtf.org/cim/mapping/http/v1.0; ns="); | out << STRLIT("Man: http://www.dmtf.org/cim/mapping/http/v1.0; ns="); |
out << nn << STRLIT("\r\n"); | out << nn << STRLIT("\r\n"); |
out << nn << STRLIT("-CIMExport: MethodRequest\r\n"); | out << nn << STRLIT("-CIMExport: MethodRequest\r\n"); |
out << nn << STRLIT("-CIMExportMethod: ") << cimMethod << STRLIT("\r\n"); |
out << nn << STRLIT("-CIMExportMethod: ") << cimMethod << |
|
STRLIT("\r\n"); |
} | } |
else | else |
{ | { |
|
|
void XmlWriter::appendEMethodResponseHeader( | void XmlWriter::appendEMethodResponseHeader( |
Buffer& out, | Buffer& out, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const ContentLanguages& contentLanguages, |
const ContentLanguageList& contentLanguages, |
Uint32 contentLength) | Uint32 contentLength) |
{ | { |
char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' }; | char nn[] = { '0' + (rand() % 10), '0' + (rand() % 10), '\0' }; |
|
|
| |
if (contentLanguages.size() > 0) | if (contentLanguages.size() > 0) |
{ | { |
out << STRLIT("Content-Language: ") << contentLanguages << STRLIT("\r\n"); |
out << STRLIT("Content-Language: ") << contentLanguages << |
|
STRLIT("\r\n"); |
} | } |
if (httpMethod == HTTP_METHOD_M_POST) | if (httpMethod == HTTP_METHOD_M_POST) |
{ | { |
|
|
const String& messageId, | const String& messageId, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const String& authenticationHeader, | const String& authenticationHeader, |
const AcceptLanguages& httpAcceptLanguages, |
const AcceptLanguageList& httpAcceptLanguages, |
const ContentLanguages& httpContentLanguages, |
const ContentLanguageList& httpContentLanguages, |
const Buffer& body) | const Buffer& body) |
{ | { |
Buffer out; | Buffer out; |
|
|
const CIMName& eMethodName, | const CIMName& eMethodName, |
const String& messageId, | const String& messageId, |
HttpMethod httpMethod, | HttpMethod httpMethod, |
const ContentLanguages& httpContentLanguages, |
const ContentLanguageList& httpContentLanguages, |
const Buffer& body) | const Buffer& body) |
{ | { |
Buffer out; | Buffer out; |
|
|
_appendSimpleExportRspElementEnd(out); | _appendSimpleExportRspElementEnd(out); |
_appendMessageElementEnd(out); | _appendMessageElementEnd(out); |
| |
// l10n |
appendEMethodResponseHeader( |
appendEMethodResponseHeader(tmp, |
tmp, |
httpMethod, | httpMethod, |
cimException.getContentLanguages(), | cimException.getContentLanguages(), |
out.size()); | out.size()); |
|
|
| |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
// | // |
// _xmlWritter_printAttributes() |
|
// |
|
//------------------------------------------------------------------------------ |
|
|
|
void _xmlWritter_printAttributes( |
|
PEGASUS_STD(ostream)& os, |
|
const XmlAttribute* attributes, |
|
Uint32 attributeCount) |
|
{ |
|
for (Uint32 i = 0; i < attributeCount; i++) |
|
{ |
|
os << attributes[i].name << "="; |
|
|
|
os << '"'; |
|
_xmlWritter_appendSpecial(os, attributes[i].value); |
|
os << '"'; |
|
|
|
if (i + 1 != attributeCount) |
|
os << ' '; |
|
} |
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// |
|
// _xmlWritter_indent() |
|
// |
|
//------------------------------------------------------------------------------ |
|
|
|
void _xmlWritter_indent(PEGASUS_STD(ostream)& os, Uint32 level, Uint32 indentChars) |
|
{ |
|
Uint32 n = level * indentChars; |
|
|
|
for (Uint32 i = 0; i < n; i++) |
|
os << ' '; |
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// |
|
// indentedPrint() |
|
// |
|
//------------------------------------------------------------------------------ |
|
|
|
void XmlWriter::indentedPrint( |
|
PEGASUS_STD(ostream)& os, |
|
const char* text, |
|
Uint32 indentChars) |
|
{ |
|
AutoArrayPtr<char> tmp(strcpy(new char[strlen(text) + 1], text)); |
|
|
|
XmlParser parser(tmp.get()); |
|
XmlEntry entry; |
|
Stack<const char*> stack; |
|
|
|
while (parser.next(entry)) |
|
{ |
|
switch (entry.type) |
|
{ |
|
case XmlEntry::XML_DECLARATION: |
|
{ |
|
_xmlWritter_indent(os, stack.size(), indentChars); |
|
|
|
os << "<?" << entry.text << " "; |
|
_xmlWritter_printAttributes(os, entry.attributes, entry.attributeCount); |
|
os << "?>"; |
|
break; |
|
} |
|
|
|
case XmlEntry::START_TAG: |
|
{ |
|
_xmlWritter_indent(os, stack.size(), indentChars); |
|
|
|
os << "<" << entry.text; |
|
|
|
if (entry.attributeCount) |
|
os << ' '; |
|
|
|
_xmlWritter_printAttributes(os, entry.attributes, entry.attributeCount); |
|
os << ">"; |
|
stack.push(entry.text); |
|
break; |
|
} |
|
|
|
case XmlEntry::EMPTY_TAG: |
|
{ |
|
_xmlWritter_indent(os, stack.size(), indentChars); |
|
|
|
os << "<" << entry.text << " "; |
|
_xmlWritter_printAttributes(os, entry.attributes, entry.attributeCount); |
|
os << "/>"; |
|
break; |
|
} |
|
|
|
case XmlEntry::END_TAG: |
|
{ |
|
if (!stack.isEmpty() && strcmp(stack.top(), entry.text) == 0) |
|
stack.pop(); |
|
|
|
_xmlWritter_indent(os, stack.size(), indentChars); |
|
|
|
os << "</" << entry.text << ">"; |
|
break; |
|
} |
|
|
|
case XmlEntry::COMMENT: |
|
{ |
|
|
|
_xmlWritter_indent(os, stack.size(), indentChars); |
|
os << "<!--"; |
|
_xmlWritter_appendSpecial(os, entry.text); |
|
os << "-->"; |
|
break; |
|
} |
|
|
|
case XmlEntry::CONTENT: |
|
{ |
|
_xmlWritter_indent(os, stack.size(), indentChars); |
|
_xmlWritter_appendSpecial(os, entry.text); |
|
break; |
|
} |
|
|
|
case XmlEntry::CDATA: |
|
{ |
|
_xmlWritter_indent(os, stack.size(), indentChars); |
|
os << "<![CDATA[...]]>"; |
|
break; |
|
} |
|
|
|
case XmlEntry::DOCTYPE: |
|
{ |
|
_xmlWritter_indent(os, stack.size(), indentChars); |
|
os << "<!DOCTYPE...>"; |
|
break; |
|
} |
|
} |
|
|
|
os << PEGASUS_STD(endl); |
|
} |
|
|
|
} |
|
|
|
//------------------------------------------------------------------------------ |
|
// |
|
// XmlWriter::getNextMessageId() | // XmlWriter::getNextMessageId() |
// | // |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |
| |
|
static IDFactory _messageIDFactory(1000); |
|
|
String XmlWriter::getNextMessageId() | String XmlWriter::getNextMessageId() |
{ | { |
// ATTN: make thread-safe: |
char scratchBuffer[22]; |
static Uint32 messageId = 1000; |
Uint32 n; |
|
const char * startP = Uint32ToString(scratchBuffer, |
messageId++; |
_messageIDFactory.getID(), |
|
n); |
if (messageId < 1000) |
return String(startP, n); |
messageId = 1001; |
|
|
|
char buffer[16]; |
|
sprintf(buffer, "%d", messageId); |
|
return buffer; |
|
} | } |
| |
//------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ |