Commit d43551b9 authored by Brad King's avatar Brad King

ENH: Replaced large switch statement case list with vtkTemplateMacro.

parent f81d0c58
......@@ -18,7 +18,7 @@
#include "vtkObjectFactory.h"
#include "vtkPiecewiseFunction.h"
vtkCxxRevisionMacro(vtkColorTransferFunction, "1.55");
vtkCxxRevisionMacro(vtkColorTransferFunction, "1.56");
vtkStandardNewMacro(vtkColorTransferFunction);
//----------------------------------------------------------------------------
......@@ -894,14 +894,16 @@ void vtkColorTransferFunction::DeepCopy( vtkColorTransferFunction *f )
}
//----------------------------------------------------------------------------
// accelerate the mapping by copying the data in 32-bit chunks instead
// of 8-bit chunks
// Accelerate the mapping by copying the data in 32-bit chunks instead
// of 8-bit chunks. The extra "long" argument is to help broken
// compilers select the non-templates below for unsigned char
// and unsigned short.
template <class T>
void
vtkColorTransferFunctionMapData(vtkColorTransferFunction *self,
T *input,
unsigned char *output,
int length, int inIncr, int outFormat)
void vtkColorTransferFunctionMapData(vtkColorTransferFunction* self,
T* input,
unsigned char* output,
int length, int inIncr,
int outFormat, long)
{
double x;
int i = length;
......@@ -943,12 +945,12 @@ vtkColorTransferFunctionMapData(vtkColorTransferFunction *self,
//----------------------------------------------------------------------------
void
vtkColorTransferFunctionMapUnsignedCharData(vtkColorTransferFunction *self,
unsigned char *input,
unsigned char *output,
int length, int inIncr,
int outFormat)
// Special implementation for unsigned char input.
void vtkColorTransferFunctionMapData(vtkColorTransferFunction* self,
unsigned char* input,
unsigned char* output,
int length, int inIncr,
int outFormat, int)
{
int x;
int i = length;
......@@ -1006,12 +1008,12 @@ vtkColorTransferFunctionMapUnsignedCharData(vtkColorTransferFunction *self,
}
//----------------------------------------------------------------------------
void
vtkColorTransferFunctionMapUnsignedShortData(vtkColorTransferFunction *self,
unsigned short *input,
unsigned char *output,
int length, int inIncr,
int outFormat)
// Special implementation for unsigned short input.
void vtkColorTransferFunctionMapData(vtkColorTransferFunction* self,
unsigned short* input,
unsigned char* output,
int length, int inIncr,
int outFormat, int)
{
int x;
int i = length;
......@@ -1079,68 +1081,11 @@ void vtkColorTransferFunction::MapScalarsThroughTable2(void *input,
{
switch (inputDataType)
{
case VTK_CHAR:
vtkColorTransferFunctionMapData(this,(char *)input,output,
numberOfValues,inputIncrement,
outputFormat);
break;
case VTK_UNSIGNED_CHAR:
vtkColorTransferFunctionMapUnsignedCharData(this,(unsigned char *)input,
output,numberOfValues,
inputIncrement,outputFormat);
break;
case VTK_SHORT:
vtkColorTransferFunctionMapData(this,(short *)input,output,
numberOfValues,inputIncrement,
outputFormat);
break;
case VTK_UNSIGNED_SHORT:
vtkColorTransferFunctionMapUnsignedShortData(this,
(unsigned short *)input,
output,numberOfValues,
inputIncrement,
outputFormat);
break;
case VTK_INT:
vtkColorTransferFunctionMapData(this,(int *)input,output,
numberOfValues,inputIncrement,
outputFormat);
break;
case VTK_UNSIGNED_INT:
vtkColorTransferFunctionMapData(this,(unsigned int *)input,output,
numberOfValues,inputIncrement,
outputFormat);
break;
case VTK_LONG:
vtkColorTransferFunctionMapData(this,(long *)input,output,
numberOfValues,inputIncrement,
outputFormat);
break;
case VTK_UNSIGNED_LONG:
vtkColorTransferFunctionMapData(this,(unsigned long *)input,output,
numberOfValues,inputIncrement,
outputFormat);
break;
case VTK_FLOAT:
vtkColorTransferFunctionMapData(this,(float *)input,output,
numberOfValues,inputIncrement,
outputFormat);
break;
case VTK_DOUBLE:
vtkColorTransferFunctionMapData(this,(double *)input,output,
numberOfValues,inputIncrement,
outputFormat);
break;
vtkTemplateMacro(
vtkColorTransferFunctionMapData(this, static_cast<VTK_TT*>(input),
output, numberOfValues, inputIncrement,
outputFormat, 1)
);
default:
vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");
return;
......
......@@ -20,7 +20,7 @@
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
vtkCxxRevisionMacro(vtkBMPReader, "1.52");
vtkCxxRevisionMacro(vtkBMPReader, "1.53");
vtkStandardNewMacro(vtkBMPReader);
#ifdef read
......@@ -539,36 +539,9 @@ void vtkBMPReader::ExecuteData(vtkDataObject *output)
outPtr = data->GetScalarPointer();
switch (data->GetScalarType())
{
case VTK_DOUBLE:
vtkBMPReaderUpdate2(this, data, (double *)(outPtr));
break;
case VTK_FLOAT:
vtkBMPReaderUpdate2(this, data, (float *)(outPtr));
break;
case VTK_UNSIGNED_LONG:
vtkBMPReaderUpdate2(this, data, (unsigned long *)(outPtr));
break;
case VTK_LONG:
vtkBMPReaderUpdate2(this, data, (long *)(outPtr));
break;
case VTK_UNSIGNED_INT:
vtkBMPReaderUpdate2(this, data, (unsigned int *)(outPtr));
break;
case VTK_INT:
vtkBMPReaderUpdate2(this, data, (int *)(outPtr));
break;
case VTK_SHORT:
vtkBMPReaderUpdate2(this, data, (short *)(outPtr));
break;
case VTK_UNSIGNED_SHORT:
vtkBMPReaderUpdate2(this, data, (unsigned short *)(outPtr));
break;
case VTK_UNSIGNED_CHAR:
vtkBMPReaderUpdate2(this, data, (unsigned char *)(outPtr));
break;
case VTK_CHAR:
vtkBMPReaderUpdate2(this, data, (char *)(outPtr));
break;
vtkTemplateMacro(
vtkBMPReaderUpdate2(this, data, static_cast<VTK_TT*>(outPtr))
);
default:
vtkErrorMacro(<< "Execute: Unknown data type");
}
......
......@@ -24,7 +24,7 @@
#include <sys/stat.h>
vtkCxxRevisionMacro(vtkImageReader2, "1.35");
vtkCxxRevisionMacro(vtkImageReader2, "1.36");
vtkStandardNewMacro(vtkImageReader2);
#ifdef read
......@@ -459,6 +459,13 @@ void vtkImageReader2::SetHeaderSize(unsigned long size)
}
//----------------------------------------------------------------------------
template <class T>
unsigned long vtkImageReader2GetSize(T*)
{
return sizeof(T);
}
//----------------------------------------------------------------------------
// This function opens a file to determine the file size, and to
// automatically determine the header size.
......@@ -470,36 +477,9 @@ void vtkImageReader2::ComputeDataIncrements()
// Determine the expected length of the data ...
switch (this->DataScalarType)
{
case VTK_FLOAT:
fileDataLength = sizeof(float);
break;
case VTK_DOUBLE:
fileDataLength = sizeof(double);
break;
case VTK_INT:
fileDataLength = sizeof(int);
break;
case VTK_UNSIGNED_INT:
fileDataLength = sizeof(unsigned int);
break;
case VTK_LONG:
fileDataLength = sizeof(long);
break;
case VTK_UNSIGNED_LONG:
fileDataLength = sizeof(unsigned long);
break;
case VTK_SHORT:
fileDataLength = sizeof(short);
break;
case VTK_UNSIGNED_SHORT:
fileDataLength = sizeof(unsigned short);
break;
case VTK_CHAR:
fileDataLength = sizeof(char);
break;
case VTK_UNSIGNED_CHAR:
fileDataLength = sizeof(unsigned char);
break;
vtkTemplateMacro(
fileDataLength = vtkImageReader2GetSize(static_cast<VTK_TT*>(0))
);
default:
vtkErrorMacro(<< "Unknown DataScalarType");
return;
......
......@@ -28,7 +28,7 @@
# include <io.h> /* unlink */
#endif
vtkCxxRevisionMacro(vtkImageWriter, "1.58");
vtkCxxRevisionMacro(vtkImageWriter, "1.59");
vtkStandardNewMacro(vtkImageWriter);
#ifdef write
......@@ -411,6 +411,13 @@ void vtkImageWriter::RecursiveWrite(int axis, vtkImageData *cache,
}
//----------------------------------------------------------------------------
template <class T>
unsigned long vtkImageWriterGetSize(T*)
{
return sizeof(T);
}
//----------------------------------------------------------------------------
// Writes a region in a file. Subclasses can override this method
// to produce a header. This method only hanldes 3d data (plus components).
......@@ -436,36 +443,9 @@ void vtkImageWriter::WriteFile(ofstream *file, vtkImageData *data,
// take into consideration the scalar type
switch (data->GetScalarType())
{
case VTK_DOUBLE:
rowLength = sizeof(double);
break;
case VTK_FLOAT:
rowLength = sizeof(float);
break;
case VTK_LONG:
rowLength = sizeof(long);
break;
case VTK_UNSIGNED_LONG:
rowLength = sizeof(unsigned long);
break;
case VTK_INT:
rowLength = sizeof(int);
break;
case VTK_UNSIGNED_INT:
rowLength = sizeof(unsigned int);
break;
case VTK_SHORT:
rowLength = sizeof(short);
break;
case VTK_UNSIGNED_SHORT:
rowLength = sizeof(unsigned short);
break;
case VTK_CHAR:
rowLength = sizeof(char);
break;
case VTK_UNSIGNED_CHAR:
rowLength = sizeof(unsigned char);
break;
vtkTemplateMacro(
rowLength = vtkImageWriterGetSize(static_cast<VTK_TT*>(0))
);
default:
vtkErrorMacro(<< "Execute: Unknown output ScalarType");
return;
......
......@@ -22,7 +22,7 @@
#include "vtkObjectFactory.h"
#include "vtkXMLDataElement.h"
vtkCxxRevisionMacro(vtkXMLDataParser, "1.26");
vtkCxxRevisionMacro(vtkXMLDataParser, "1.27");
vtkStandardNewMacro(vtkXMLDataParser);
vtkCxxSetObjectMacro(vtkXMLDataParser, Compressor, vtkDataCompressor);
......@@ -363,23 +363,22 @@ int vtkXMLDataParser::ParseBuffer(const char* buffer, unsigned int count)
return 1;
}
//----------------------------------------------------------------------------
template <class T>
unsigned long vtkXMLDataParserGetWordTypeSize(T*)
{
return sizeof(T);
}
//----------------------------------------------------------------------------
unsigned long vtkXMLDataParser::GetWordTypeSize(int wordType)
{
unsigned long size = 1;
switch (wordType)
{
case VTK_ID_TYPE: size = sizeof(vtkIdType); break;
case VTK_FLOAT: size = sizeof(float); break;
case VTK_DOUBLE: size = sizeof(double); break;
case VTK_INT: size = sizeof(int); break;
case VTK_UNSIGNED_INT: size = sizeof(unsigned int); break;
case VTK_LONG: size = sizeof(long); break;
case VTK_UNSIGNED_LONG: size = sizeof(unsigned long); break;
case VTK_SHORT: size = sizeof(short); break;
case VTK_UNSIGNED_SHORT: size = sizeof(unsigned short); break;
case VTK_UNSIGNED_CHAR: size = sizeof(unsigned char); break;
case VTK_CHAR: size = sizeof(char); break;
vtkTemplateMacro(
size = vtkXMLDataParserGetWordTypeSize(static_cast<VTK_TT*>(0))
);
default:
{ vtkWarningMacro("Unsupported data type: " << wordType); } break;
}
......@@ -846,8 +845,12 @@ unsigned long vtkXMLDataParser::ReadAppendedData(unsigned long offset,
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Define a parsing function template. The extra "long" argument is used
// to help broken compilers select the non-templates below for char and
// unsigned char by making them a better conversion than the template.
template <class T>
T* vtkXMLParseAsciiData(istream& is, int* length, T* vtkNotUsed(dummy))
T* vtkXMLParseAsciiData(istream& is, int* length, T*, long)
{
int dataLength = 0;
int dataBufferSize = 64;
......@@ -878,7 +881,7 @@ T* vtkXMLParseAsciiData(istream& is, int* length, T* vtkNotUsed(dummy))
}
//----------------------------------------------------------------------------
char* vtkXMLParseAsciiDataChar(istream& is, int* length)
char* vtkXMLParseAsciiData(istream& is, int* length, char*, int)
{
int dataLength = 0;
int dataBufferSize = 64;
......@@ -911,7 +914,8 @@ char* vtkXMLParseAsciiDataChar(istream& is, int* length)
}
//----------------------------------------------------------------------------
unsigned char* vtkXMLParseAsciiDataUnsignedChar(istream& is, int* length)
unsigned char* vtkXMLParseAsciiData(istream& is, int* length, unsigned char*,
int)
{
int dataLength = 0;
int dataBufferSize = 64;
......@@ -962,28 +966,9 @@ int vtkXMLDataParser::ParseAsciiData(int wordType)
void* buffer = 0;
switch (wordType)
{
case VTK_ID_TYPE:
buffer = vtkXMLParseAsciiData(is, &length, static_cast<vtkIdType*>(0)); break;
case VTK_DOUBLE:
buffer = vtkXMLParseAsciiData(is, &length, static_cast<double*>(0)); break;
case VTK_FLOAT:
buffer = vtkXMLParseAsciiData(is, &length, static_cast<float*>(0)); break;
case VTK_LONG:
buffer = vtkXMLParseAsciiData(is, &length, static_cast<long*>(0)); break;
case VTK_UNSIGNED_LONG:
buffer = vtkXMLParseAsciiData(is, &length, static_cast<unsigned long*>(0)); break;
case VTK_INT:
buffer = vtkXMLParseAsciiData(is, &length, static_cast<int*>(0)); break;
case VTK_UNSIGNED_INT:
buffer = vtkXMLParseAsciiData(is, &length, static_cast<unsigned int*>(0)); break;
case VTK_SHORT:
buffer = vtkXMLParseAsciiData(is, &length, static_cast<short*>(0)); break;
case VTK_UNSIGNED_SHORT:
buffer = vtkXMLParseAsciiData(is, &length, static_cast<unsigned short*>(0)); break;
case VTK_CHAR:
buffer = vtkXMLParseAsciiDataChar(is, &length); break;
case VTK_UNSIGNED_CHAR:
buffer = vtkXMLParseAsciiDataUnsignedChar(is, &length); break;
vtkTemplateMacro(
buffer = vtkXMLParseAsciiData(is, &length, static_cast<VTK_TT*>(0), 1)
);
}
// Read terminated from failure. Clear the fail bit so another read
......@@ -997,34 +982,22 @@ int vtkXMLDataParser::ParseAsciiData(int wordType)
return (this->AsciiDataBuffer? 1:0);
}
//----------------------------------------------------------------------------
template <class T>
void vtkXMLDataParserFreeAsciiBuffer(T* buffer)
{
delete [] buffer;
}
//----------------------------------------------------------------------------
void vtkXMLDataParser::FreeAsciiBuffer()
{
void* buffer = this->AsciiDataBuffer;
switch (this->AsciiDataWordType)
{
case VTK_ID_TYPE:
delete [] reinterpret_cast<vtkIdType*>(buffer); break;
case VTK_FLOAT:
delete [] reinterpret_cast<float*>(buffer); break;
case VTK_DOUBLE:
delete [] reinterpret_cast<double*>(buffer); break;
case VTK_INT:
delete [] reinterpret_cast<int*>(buffer); break;
case VTK_UNSIGNED_INT:
delete [] reinterpret_cast<unsigned int*>(buffer); break;
case VTK_LONG:
delete [] reinterpret_cast<long*>(buffer); break;
case VTK_UNSIGNED_LONG:
delete [] reinterpret_cast<unsigned long*>(buffer); break;
case VTK_SHORT:
delete [] reinterpret_cast<short*>(buffer); break;
case VTK_UNSIGNED_SHORT:
delete [] reinterpret_cast<unsigned short*>(buffer); break;
case VTK_UNSIGNED_CHAR:
delete [] reinterpret_cast<unsigned char*>(buffer); break;
case VTK_CHAR:
delete [] reinterpret_cast<char*>(buffer); break;
vtkTemplateMacro(
vtkXMLDataParserFreeAsciiBuffer(static_cast<VTK_TT*>(buffer))
);
}
this->AsciiDataBuffer = 0;
}
......
......@@ -37,7 +37,7 @@
# include <io.h> /* unlink */
#endif
vtkCxxRevisionMacro(vtkXMLWriter, "1.43");
vtkCxxRevisionMacro(vtkXMLWriter, "1.44");
vtkCxxSetObjectMacro(vtkXMLWriter, Compressor, vtkDataCompressor);
//----------------------------------------------------------------------------
......@@ -1040,23 +1040,22 @@ unsigned long vtkXMLWriter::GetOutputWordTypeSize(int dataType)
return this->GetWordTypeSize(dataType);
}
//----------------------------------------------------------------------------
template <class T>
unsigned long vtkXMLWriterGetWordTypeSize(T*)
{
return sizeof(T);
}
//----------------------------------------------------------------------------
unsigned long vtkXMLWriter::GetWordTypeSize(int dataType)
{
unsigned long size = 1;
switch (dataType)
{
case VTK_ID_TYPE: size = sizeof(vtkIdType); break;
case VTK_FLOAT: size = sizeof(float); break;
case VTK_DOUBLE: size = sizeof(double); break;
case VTK_INT: size = sizeof(int); break;
case VTK_UNSIGNED_INT: size = sizeof(unsigned int); break;
case VTK_LONG: size = sizeof(long); break;
case VTK_UNSIGNED_LONG: size = sizeof(unsigned long); break;
case VTK_SHORT: size = sizeof(short); break;
case VTK_UNSIGNED_SHORT: size = sizeof(unsigned short); break;
case VTK_UNSIGNED_CHAR: size = sizeof(unsigned char); break;
case VTK_CHAR: size = sizeof(char); break;
vtkTemplateMacro(
size = vtkXMLWriterGetWordTypeSize(static_cast<VTK_TT*>(0))
);
default:
{ vtkWarningMacro("Unsupported data type: " << dataType); } break;
}
......@@ -1273,7 +1272,8 @@ int vtkXMLWriter::WriteStringAttribute(const char* name, const char* value)
//----------------------------------------------------------------------------
template <class T>
int vtkXMLWriteAsciiData(ostream& os, T* data, int length, vtkIndent indent)
int vtkXMLWriteAsciiData(ostream& os, T* data, int length, vtkIndent indent,
long)
{
int columns = 6;
int rows = length/columns;
......@@ -1302,8 +1302,8 @@ int vtkXMLWriteAsciiData(ostream& os, T* data, int length, vtkIndent indent)
}
//----------------------------------------------------------------------------
int vtkXMLWriteAsciiDataChar(ostream& os, char* data, int length,
vtkIndent indent)
int vtkXMLWriteAsciiData(ostream& os, char* data, int length, vtkIndent indent,
int)
{
int columns = 6;
int rows = length/columns;
......@@ -1332,8 +1332,8 @@ int vtkXMLWriteAsciiDataChar(ostream& os, char* data, int length,
}
//----------------------------------------------------------------------------
int vtkXMLWriteAsciiDataUnsignedChar(ostream& os, unsigned char* data,
unsigned long length, vtkIndent indent)
int vtkXMLWriteAsciiData(ostream& os, unsigned char* data, int length,
vtkIndent indent, int)
{
int columns = 6;
int rows = length/columns;
......@@ -1373,29 +1373,9 @@ int vtkXMLWriter::WriteAsciiData(void* data, int numWords, int wordType,
ostream& os = *(this->Stream);
switch(wordType)
{
case VTK_ID_TYPE:
return vtkXMLWriteAsciiData(os, reinterpret_cast<vtkIdType*>(b), nw, i);
case VTK_DOUBLE:
return vtkXMLWriteAsciiData(os, reinterpret_cast<double*>(b), nw, i);
case VTK_FLOAT:
return vtkXMLWriteAsciiData(os, reinterpret_cast<float*>(b), nw, i);
case VTK_LONG:
return vtkXMLWriteAsciiData(os, reinterpret_cast<long*>(b), nw, i);
case VTK_UNSIGNED_LONG:
return vtkXMLWriteAsciiData(os, reinterpret_cast<unsigned long*>(b), nw, i);
case VTK_INT:
return vtkXMLWriteAsciiData(os, reinterpret_cast<int*>(b), nw, i);
case VTK_UNSIGNED_INT:
return vtkXMLWriteAsciiData(os, reinterpret_cast<unsigned int*>(b), nw, i);
case VTK_SHORT:
return vtkXMLWriteAsciiData(os, reinterpret_cast<short*>(b), nw, i);
case VTK_UNSIGNED_SHORT:
return vtkXMLWriteAsciiData(os, reinterpret_cast<unsigned short*>(b), nw, i);
case VTK_CHAR:
return vtkXMLWriteAsciiDataChar(os, reinterpret_cast<char*>(b), nw, i);
case VTK_UNSIGNED_CHAR:
return vtkXMLWriteAsciiDataUnsignedChar(
os, reinterpret_cast<unsigned char*>(b), nw, i);
vtkTemplateMacro(
return vtkXMLWriteAsciiData(os, static_cast<VTK_TT*>(b), nw, i, 1)
);
default:
return 0;
}
......
......@@ -32,7 +32,7 @@
#include <math.h>
vtkCxxRevisionMacro(vtkFiniteDifferenceGradientEstimator, "1.1");
vtkCxxRevisionMacro(vtkFiniteDifferenceGradientEstimator, "1.2");
vtkStandardNewMacro(vtkFiniteDifferenceGradientEstimator);
// This is the templated function that actually computes the EncodedNormal
......@@ -342,70 +342,11 @@ static VTK_THREAD_RETURN_TYPE vtkSwitchOnDataType( void *arg )
switch ( scalars->GetDataType() )
{
case VTK_CHAR:
{
char *ptr = ((vtkCharArray *) scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
case VTK_UNSIGNED_CHAR:
{
unsigned char *ptr = ((vtkUnsignedCharArray *)
scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
case VTK_SHORT:
{
short *ptr = ((vtkShortArray *) scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
case VTK_UNSIGNED_SHORT:
{
unsigned short *ptr = ((vtkUnsignedShortArray *)
scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
case VTK_INT:
{
int *ptr = ((vtkIntArray *) scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
case VTK_UNSIGNED_INT:
{
unsigned int *ptr = ((vtkUnsignedIntArray *)
scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
case VTK_LONG:
{
long *ptr = ((vtkLongArray *) scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
case VTK_UNSIGNED_LONG:
{
unsigned long *ptr = ((vtkUnsignedLongArray *)
scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
case VTK_FLOAT:
{
float *ptr = ((vtkFloatArray *) scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
case VTK_DOUBLE:
{
double *ptr = ((vtkDoubleArray *) scalars)->GetPointer(0);
vtkComputeGradients( estimator, ptr, thread_id, thread_count );
}
break;
vtkTemplateMacro(
vtkComputeGradients(estimator,
static_cast<VTK_TT*>(scalars->GetVoidPointer(0)),
thread_id, thread_count)
);
default:
vtkGenericWarningMacro("unable to encode scalar type!");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment