/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
//
**********************************************************************/
/* -*-C++-*-
* ****************************************************************************
*
* File:         
* Description:  This file is intended to hold that portion of the
*               implementation of the ComDiagsArea/ComCondition classes
*               that does not belong in the "../common" directory by
*               virtue of making use of non-kosher runtime libraries.
*               Note, for example, the inclusion of the iostream.h header...
*               
* Created:      3/17/96 (St. Patrick's Day)
* Language:     C++
* Status:       Fresh out of the oven; warm to the touch; tasty?
*
*
*
* ****************************************************************************
*/
#include "Platform.h"


#include "BaseTypes.h"
#include "NAWinNT.h"
#include <ctype.h>

#include <iostream>
#include <stdarg.h>

#if !defined(__GNUC__) || __GNUC__ < 3
#include <strstream>
#endif



#include "GetErrorMessage.h"
#include "str.h"
#include "ComDiags.h"
#include "copyright.h"
#include "ErrorMessage.h"
#include "NAString.h"
#include "nawstring.h"
#include "NLSConversion.h"
#include "SqlciError.h"
#include "csconvert.h"

// What comes next are two parallel declarations: some enum values
// and an array of constant strings which we can use to refer to
// message text tokens.
//
// Let's start first with the enumerations and then give the strings.
//
// Wouldn't it be better to make this type definition a private member
// of ComCondition or is what we've done here satisfactory?
//
// ********WARNING!!!
//   This enumeration definition must match the array of char* definition
//   that comes below.
enum TOKEN_ENUM {
   STRING0, STRING1, STRING2, STRING3, STRING4,
   INT0, INT1, INT2, INT3, INT4,
   INTERNAL_SQLCODE,
   CONDITION_NUMBER,
   RETURNED_SQLSTATE,
   CLASS_ORIGIN,
   SUBCLASS_ORIGIN,
   SERVER_NAME,
   CONNECTION_NAME,
   CONSTRAINT_CATALOG,
   CONSTRAINT_SCHEMA,
   CONSTRAINT_NAME,
   TRIGGER_CATALOG,
   TRIGGER_SCHEMA,
   TRIGGER_NAME,
   CATALOG_NAME,
   SCHEMA_NAME,
   TABLE_NAME,
   COLUMN_NAME,
   CURSOR_NAME,
   ROW_NUMBER,
   NSK_CODE,
   MAX_TOKEN
};

// These names will be of full length.  The comparison will
// be made after converting a given string to all lower case,
// so these names are given in lower case internally.
//
// Wouldn't it maybe be better to make "tokens" a private
// member (albeit, static) of ComCondition, or is it
// satisfactory to use the C-language-style information hiding, such
// as we do here, using static?
//
// ******WARNING!!!
//    This char* array definition must match the enumeration definition
//    that came before.

static const NAWchar *const tokens[MAX_TOKEN] = {
   WIDE_("string0"), WIDE_("string1"), WIDE_("string2"), WIDE_("string3"), 
   WIDE_("string4"),
   WIDE_("int0"),    WIDE_("int1"),    WIDE_("int2"),    WIDE_("int3"),
   WIDE_("int4"),
   WIDE_("sqlcode"),
   WIDE_("conditionnumber"),
   WIDE_("returnedsqlstate"),
   WIDE_("classorigin"),
   WIDE_("subclassorigin"),
   WIDE_("servername"),
   WIDE_("connectionname"),
   WIDE_("constraintcatalog"),
   WIDE_("constraintschema"),
   WIDE_("constraintname"),
   WIDE_("triggercatalog"),
   WIDE_("triggerschema"),
   WIDE_("triggername"),
   WIDE_("catalogname"),
   WIDE_("schemaname"),
   WIDE_("tablename"),
   WIDE_("columnname"),
   WIDE_("cursorname"),
   WIDE_("rownumber"),
   WIDE_("nskcode")
};

// MSG_BUF_SIZE is 2K which is the maximum msg length.
// We want extra 2K to expand the parameters of the error msg.
// Note that we actually allocate more than DEST_BUF_SIZE
// which account for the size of string params.
static const UInt32 DEST_BUF_SIZE = 2 * ErrorMessage::MSG_BUF_SIZE;

// little helper method for ComSQLSTATE()

static inline void Encode36(char &dst, Int32 src)
{
  char tc = (char) src;
  dst = (tc < 10 ? '0' + tc : 'A' + tc - 10);
}

NABoolean GetSqlstateInfo(Lng32 sqlcode, char * sqlstate,
			  NABoolean &fabricatedSqlstate);
void AddSqlstateInfo(Lng32 sqlcode, char * sqlstate,
		     NABoolean fabricatedSqlstate);
NABoolean ComSQLSTATE(Lng32 theSQLCODE, char *theSQLSTATE)
{
  // ---------------------------------------------------------------------
  // Compute SQLSTATE value from SQLCODE.
  // 
  // There are basically 6 different cases for doing this:
  // 
  // 1. The easy case for SQLCODE values 0 and 100:
  // 
  //    Use a hard-coded str_cpy method.
  // 
  // All cases other than 1 will require a lookup in the message file.
  // 
  // 2. The case where a hard-coded SQLSTATE was found in the message
  //    file, and where this SQLSTATE matches the sign of SQLCODE:
  // 
  //    What we mean by "matching sign" is that SQLSTATE starts with
  //    "01" for a warning and with anything other than "00" "01" "02"
  //    for an error. In this case we return the hard-coded SQLSTATE.
  // 
  // 3. The case where a hard-coded SQLSTATE was found but it does
  //    not match the sign of the SQLCODE:
  // 
  //    In this case we "fabricate" an SQLSTATE, but we'll put a
  //    "W" into the second character of SQLSTATE if SQLCODE was < 0.
  //    That's just as a little reminder. Continue with cases 4 or 5.
  // 
  // 4. The case where the message file has a "ZZZZZ" as the SQLSTATE
  //    value, and SQLCODE is < 0 (Error):
  // 
  //    In this case we'll return Xaabb as the SQLSTATE, where aa is
  //    the SQLCODE/1000 encoded in base 36, and bb is SQLCODE % 1000
  //    encoded in base 36. Note that if we came here from case 3 the
  //    returned SQLSTATE is XWabb.
  // 
  // 5. The case where the message file has a "ZZZZZ" as the SQLSTATE
  //    value, and SQLCODE is > 0 (Warning):
  // 
  //    In this case we'll return 01abb as the SQLSTATE. a is a kludgy
  //    encoding of SQLCODE/1000 and bb is the same as in case 4. We do
  //    this because we don't have enough characters available for
  //    warnings to use the more simple encoding of step 4.
  // 
  // 6. The case where we don't find the matching message file entry:
  // 
  //    We treat this the same as cases 4 and 5.
  // 
  // The return value of this function is TRUE for all fabricated states;
  // it's FALSE for all valid states found in the message file
  // and for states we were able to map successfully on a code/state mismatch.
  //
  // Thus, the fabricated error states have SQL/MX class origin (X_)
  // while the fab warnings have ISO-9075 class origin (01) but SQL/MX
  // subclass origin.
  //
  // Please be aware of the encoding in step 5 when adding new ranges of
  // error codes. Choosing the wrong range or failing to update this code
  // may result in SQLSTATE values that are not longer unique and can't
  // always be mapped back to SQLCODE values!!!
  // ---------------------------------------------------------------------

  NABoolean fabricatedSqlstate = FALSE;
  if (theSQLCODE == 0)
  {
    str_cpy_all(theSQLSTATE,"00000",6);
    return FALSE;
  }

  if (theSQLCODE == 100)
  {
    str_cpy_all(theSQLSTATE,"02000",6);
    return FALSE;
  }

  // see if this sqlcode exists in the in-memory list
  if (GetSqlstateInfo(theSQLCODE, theSQLSTATE, fabricatedSqlstate))
    return fabricatedSqlstate;

  // We need to lookup the SQLSTATE for this SQLCODE.
  NAWchar* source;

  // Get the Message string for this error. The first field is the SQLSTATE. 
  NABoolean sourceIsNotKnown = GetErrorMessage(theSQLCODE, source, SQL_STATE);

  NABoolean sourceIsAWarning = FALSE;
  NABoolean sourceIsInverted = FALSE;

  if (!sourceIsNotKnown)
  {
    // Message found.
    // If the first field is 'ZZZZZ' then the SQLSTATE is not known,
    // and we'll fabricate a special one.
          
    if (NAWstrcmp(source, WIDE_("ZZZZZ")) == 0)
      sourceIsNotKnown = TRUE;
    else
    {
      // Not "ZZZZZ" -- it's a known SQLSTATE.

//UR2 CNTNSK. The State is always in ASCII. 
      // Add a NULL at the end.
      Int32 numBytes = 
        UnicodeStringToLocale(CharInfo::ISO88591, 
                              source, 5, theSQLSTATE, 5, FALSE);

      if (numBytes != 5) 
          *theSQLSTATE = '\0';
      else
         theSQLSTATE[5] = '\0';

      // Ok, it's known, but is it valid for this condition?
      // All Ansi warnings begin with "01... (warning)" or "02000 (no data)".
      sourceIsAWarning = (theSQLSTATE[0] == '0' &&
			 (theSQLSTATE[1] == '1' ||
			  theSQLSTATE[1] == '2'));
      if ((theSQLCODE > 0 &&  sourceIsAWarning) ||
          (theSQLCODE < 0 && !sourceIsAWarning))
	goto saveAndReturnSqlstate;      // it is valid
      //	return FALSE;				// it is valid

      // Here we have a mismatch between SQLCODE and SQLSTATE.
      // We try to map a warning state to error, and vice versa.
      // This is symmetric for "01004/22001 string data, right truncation".
      // The mapping of syntax errors (42000 etc) to generic warning (01000)
      // is NOT symmetric (of course you can't convert a generic warning
      // to any meaningful specific error state...).
      //
      if (sourceIsAWarning)
      {
        if (strcmp(theSQLSTATE, "01004") == 0) // string data, right truncation
	{
	  str_cpy_all(theSQLSTATE,"22001",6);  // warning -> error
	  goto saveAndReturnSqlstate;     
	  //	  return FALSE;
	}
      }
      else
      {
        if (strcmp(theSQLSTATE, "22001") == 0) // string data, right truncation
	{
	  str_cpy_all(theSQLSTATE,"01004",6);  // error -> warning
	  goto saveAndReturnSqlstate;     
	  //	  return FALSE;
	}
      }
      sourceIsInverted = TRUE;                 // not valid, no mapping
    } // known source
  }

  // If message is not found or a known and valid SQLSTATE was not found,
  // fabricate an implementation-defined SQLSTATE.

  // split the SQLCODE value into a left and a right part at the 1000s boundary
  #define AZ09 36
  Lng32 codeLeft;
  Lng32 codeRight;
  codeLeft  = ABS(theSQLCODE);
  codeRight = codeLeft % 1000;
  codeLeft  = codeLeft / 1000;

  // Set first the three characters of SQLSTATE, based on whether this is an
  // error or a warning, and based on the left part of the SQLCODE.
  if (theSQLCODE < 0)
  {
    // error: use a SQL/MX SQLSTATE class starting with 'X'
    theSQLSTATE[0] = 'X';
    if (sourceIsAWarning)
      theSQLSTATE[1] = 'W';
    else
      if (codeLeft / AZ09 < AZ09)
	Encode36(theSQLSTATE[1],codeLeft / AZ09);
      else
	theSQLSTATE[1] = 'Z';
    Encode36(theSQLSTATE[2],codeLeft % AZ09);
  }
  else
  {
    // warning: use ANSI SQLSTATE class '01'
    theSQLSTATE[0] = '0';
    theSQLSTATE[1] = '1';
    // sorry, not enough space to encode "sourceIsAWarning" and all
    // of codeLeft
    char state2;
    // Note the knowledge about which ranges of error codes are used.
    // Note also that if additional ranges are used, we could either go
    // to the default handling (some SQLSTATEs might be returned for two
    // different SQLCODEs, or we could add a case as long as one of the
    // characters [5-9I-Z] are still available.
    switch (codeLeft)
      {
      case 1:  // 5
      case 2:  // 6
      case 3:  // 7
      case 4:  // 8
      case 5:  // 9 - not really used
	state2 = '4' + (char) codeLeft;
	break;
      case 6:  // I
      case 7:  // J
      case 8:  // K
      case 9:  // L
      case 10: // M
      case 11: // N
      case 12: // O - not used so far (Nov 2001)
      case 13: // P
      case 14: // Q - not used so far (Nov 2001)
      case 15: // R
	state2 = 'I' + (char) (codeLeft - 6);
	break;
      case 19: // S
	state2 = 'S';
	break;
      case 20: // T
	state2 = 'T';
	break;
      case 30: // U
	state2 = 'U';
	break;

	// V, W, X are still for sale, and some of the ranges above
	// are also not yet used

      default:
	state2 = 'Y' + (char) (codeLeft % 2);
	break;
      }
    theSQLSTATE[2] = state2;
  }

  // Encode the right part of SQLCODE as 2 digits with base 36
  // and put it into the last 2 characters of the subclass.
  Encode36(theSQLSTATE[3], codeRight / AZ09);
  Encode36(theSQLSTATE[4], codeRight % AZ09);

  // add NUL terminator
  theSQLSTATE[5] = '\0';
  fabricatedSqlstate = TRUE; // it is fabricated

saveAndReturnSqlstate:
  AddSqlstateInfo(theSQLCODE, theSQLSTATE, fabricatedSqlstate);
  return fabricatedSqlstate;
  

}

static const char *returnClassOrigin(Lng32 theSQLCODE, size_t offset)
{
  char sqlstate[6];
  ComSQLSTATE(theSQLCODE,sqlstate);
  // Classes and subclasses starting with letters '0' ... '4', 'A' ... 'H' are
  // defined by ISO/ANSI SQL92. See subclause 18.1, GR 3b) and subclause 22.1.

  if ((sqlstate[offset] >= '0' && sqlstate[offset] <= '4') ||
      (sqlstate[offset] >= 'A' && sqlstate[offset] <= 'H'))
    return "ISO 9075";
  else
    return (const char *)COPYRIGHT_XTOP_PRODNAME_H;
}

const char *ComClassOrigin(Lng32 theSQLCODE)
{
  // The class is stored in the first two characters of SQLSTATE.
  return returnClassOrigin(theSQLCODE, 0);
}

const char *ComSubClassOrigin(Lng32 theSQLCODE)
{
  // The subclass is stored in the last three characters of SQLSTATE.
  return returnClassOrigin(theSQLCODE, 2);
}

void ComCondition::getSQLSTATE(char *theSQLSTATE) const
{
  if(NULL == customSQLState_){
   // If the SQLCODE shows it's a SIGNAL statement, don't call
   // the ComSQLSTATE() function - instead use the SQLSTATE value
   // supplied by the user, in optionalString_[0].
   if (theSQLCODE_ == -ComDiags_SignalSQLCODE)
	 str_cpy_all(theSQLSTATE, getOptionalString(0), 5);
   else
	 ComSQLSTATE(theSQLCODE_,theSQLSTATE);
  }
  else{
    // caller providing space in char* theSQLSSTATE.
    str_cpy_all(theSQLSTATE, customSQLState_, 6);
  }
}

const char * ComCondition::getClassOrigin() const
{
   return ComClassOrigin(theSQLCODE_);
}

const char * ComCondition::getSubClassOrigin() const
{
   return ComSubClassOrigin(theSQLCODE_);
}

// To get the message length, we first make sure that there
// indeed exists a message.  Once the message has been established,

// that guarantees that the messageLen_ member has a valid value,
// and we return that value.
//
// The octet length is just the message length --- as of this writing anyway.

ComDiagBigInt ComCondition::getMessageLength()
{
   if (!isLocked_)
      getMessageText();
   return messageLen_;
}

ComDiagBigInt ComCondition::getMessageOctetLength()
{
   return getMessageLength();
}

// Ancillary routines for ComCondition::getMessageText()
// (could be made regular ComCondition methods)

// This function is used in other pieces
// of code so that if by chance the programmer leaves NULL one
// of the char* strings used in instantiating message text,
// we don't get an assertion failure, but a more graceful result.

const char *getSafeString(const char *const cp)
{
   if (!cp)
      return "";
   else
      return cp;
}

const NAWchar *getSafeWString(const NAWchar*const cp)
{
   if (!cp)
      return WIDE_("");
   else
      return cp;
}


// Convert s into Unicode UTF16 and append to dest.
// We assume that there is space for 's' in 'dest'.
void appendSafeStringInW(NAWchar* dest, 
                         CollHeap *heap,
                         const char* s,
                         CharInfo::CharSet cs = CharInfo::ISO88591)
{
  const char* src = getSafeString(s);
  UInt32 len = strlen(src);

  if (cs == CharInfo::ISO88591)
  {
    // Keep the old "pass through" behavior so 
    // use of ISO 8859-15 characters (a.k.a., Latin-9) in
    // CHARACTER SET ISO88591 target column continues to work.

    NAWcharBuf* res = NULL; // must set this variable to NULL to force
                            // the following call to allocate space for
                            // the output buffer
    res = ISO88591ToUnicode(charBuf((unsigned char*)src, len),
                                      // const charBuf& iso88591String
                            heap,     // CollHeap *heap
                            res,      // NAWcharBuf*& unicodeString
                            TRUE);    // NABoolean addNullAtEnd
    if (res && res->getStrLen() > 0)
    {
      NAWsprintf(dest, WIDE_("%s"),  res->data()); // append to dest
    }
    else
      dest[0] = WIDE_('\0'); // so later call to NAWstrlen(dest) return 0

    NADELETE(res, NAWcharBuf, heap);

    return;  // we are done; exit the routine

  } // if (cs == CharInfo::ISO88591)

  //
  // (cs != CharInfo::ISO88591)
  //

  enum cnv_charset convCS = convertCharsetEnum(cs);
  if (convCS == cnv_UnknownCharSet)
  {
    dest[0] = WIDE_('\0'); // so later call to NAWstrlen(dest) return 0
    return;
  }

  // Allocate a temporary output buffer of len+1 NAWchar's
  NAWcharBuf* pOutputBuf = NULL;
  pOutputBuf = checkSpace(heap, len /* # of NAWchar's */,
                          pOutputBuf, TRUE /* addNullAtEnd */);
  if (pOutputBuf == NULL) // not supposed to happen...
  {
    dest[0] = WIDE_('\0'); // so later call to NAWstrlen(dest) return 0
    return;
  }

  char * pFirstUntranslatedChar = NULL;
  UInt32 outputDataLenInBytes = 0;
  UInt32 translatedtCharCount = 0;
  Int32 convStatus =
    LocaleToUTF16(cnv_version1, // const enum cnv_version version
                  src,          // const char *in_bufr
                  len,          // const int in_len -- src str len in num of bytes
                  (const char *)pOutputBuf->data(),     // const char *out_bufr
                  (const Int32)((len+1)*sizeof(NAWchar)), // output buffer size in # of bytes
                  convCS,                 // enum cnv_charset charset -- output cs
                  pFirstUntranslatedChar, // char * & first_untranslated_char
                  &outputDataLenInBytes,  // unsigned int *output_data_len_p
                  0,                      // const int cnv_flags (default is 0)
                  (const Int32)TRUE,        // const int addNullAtEnd_flag
                  &translatedtCharCount); // unsigned int *translated_char_cnt_p
  UInt32 outLenInW = outputDataLenInBytes/sizeof(NAWchar);
  pOutputBuf->data()[len] = WIDE_('\0');  // needed when conversion errors occured
  switch (convStatus)
  {
  case 0: // success
    // assert (pOutputBuf->data()[outLenInW-1] == WIDE_'\0');
    NAWsprintf(dest, WIDE_("%s"), pOutputBuf->data()); // append to dest
    break;
  case CNV_ERR_BUFFER_OVERRUN:
    if (outLenInW <= len)
      pOutputBuf->data()[outLenInW] = WIDE_('\0');
    NAWsprintf(dest, WIDE_("%s"), pOutputBuf->data()); // append to dest
    break;
  case CNV_ERR_INVALID_CHAR:
    if (outLenInW < len)
    {
      pOutputBuf->data()[outLenInW]   = WIDE_('?');    // substitute char
      pOutputBuf->data()[outLenInW+1] = WIDE_('\0');
    }
    NAWsprintf(dest, WIDE_("%s"), pOutputBuf->data()); // append to dest
    // skip the remaining characters in the source string
    break;
  case CNV_ERR_NOINPUT:       // okay
  case CNV_ERR_INVALID_CS:    // not supposed to happen
  case CNV_ERR_INVALID_VERS:  // not supposed to happen
  default:
    dest[0] = WIDE_('\0');    // so later call to NAWstrlen(dest) return 0
    break;
  }

  NADELETE(pOutputBuf, NAWcharBuf, heap);
}

NABoolean safeStringCheck(const char *const cp)
{
   if (!cp)
      return FALSE;	// False if cp is NULL
   else
      return cp != "";	// False if cp points to ""; True if non-empty string
}


// Helper method
// We compute the buffer size as
//     DEST_BUF_SIZE + size of the string parameters
//                   + size of the catalog/schema/table/etc. parameters
// String params can be long and we will show the entire params
// by allocating the memory dynamically.
UInt32 computeMsgLen(const ComCondition &cond)
{
  UInt32 totallen = DEST_BUF_SIZE, len = 0;

  for (Int32 index=0; index < ComCondition::NumOptionalParms; ++index)
  {
    CharInfo::CharSet cs = cond.getOptionalStringCharSet(index);
    if (CharInfo::isSingleByteCharSet(cs))
    {
      const char* optStr = cond.getOptionalString(index);
      len = (optStr) ? strlen(optStr) : 0;
    }
    else
    {
      const NAWchar* optWStr = cond.getOptionalWString(index);
      len = (optWStr) ? NAWstrlen(optWStr) : 0;
    }

    totallen += len;
  }

  if (cond.getConstraintCatalog()) totallen += strlen(cond.getConstraintCatalog());
  if (cond.getConstraintSchema())  totallen += strlen(cond.getConstraintSchema());
  if (cond.getConstraintName())    totallen += strlen(cond.getConstraintName());
  if (cond.getTriggerCatalog())    totallen += strlen(cond.getTriggerCatalog());
  if (cond.getTriggerSchema())     totallen += strlen(cond.getTriggerSchema());
  if (cond.getTriggerName())       totallen += strlen(cond.getTriggerName());
  if (cond.getCatalogName())       totallen += strlen(cond.getCatalogName());
  if (cond.getSchemaName())        totallen += strlen(cond.getSchemaName());
  if (cond.getTableName())         totallen += strlen(cond.getTableName());
  if (cond.getColumnName())        totallen += strlen(cond.getColumnName());
  if (((ComCondition&)cond).getCustomSQLState())
    totallen += strlen(((ComCondition&)cond).getCustomSQLState());

  return totallen;
}

NAWString* terseParamDisplay(const ComCondition &cc, CollHeap *p)
{
  NAWString* dest = NULL;
  if ( !p ) {
    dest = new NAWString;
  } else
    dest = new (p) NAWString(p);

  if ( dest == NULL )
     return NULL;

  UInt32 expandedBufferLen = computeMsgLen(cc);
  NAWchar *wbuffer = new (p) NAWchar[expandedBufferLen];

  #define STRING_TO_DEST(x_, cs_)	      \
    { *dest += L' ';                           \
      appendSafeStringInW(wbuffer,p, x_, cs_);  \
      dest -> append(wbuffer, NAWstrlen(wbuffer)); } 

  #define WSTRING_TO_DEST(x_)	              \
    { *dest += L' ';                           \
      *dest -> append(getSafeWString(x_), NAWstrlen(getSafeWString(x_))); } 

  #define INT_TO_DEST(x_)		\
    { NAWsprintf(wbuffer, WIDE_("%d"), x_); WSTRING_TO_DEST(wbuffer); }

  #define STRING_TO_DEST_IF(x_)	\
    { if (safeStringCheck(x_)) STRING_TO_DEST(x_, CharInfo::ISO88591); }

  // Always display the optional string message params (as blanks if absent).
  Int32 i=0;
  for (; i<ComCondition::NumOptionalParms; i++) {
    if (CharInfo::isSingleByteCharSet(cc.getOptionalStringCharSet(i))) {
       STRING_TO_DEST(cc.getOptionalString(i), cc.getOptionalStringCharSet(i));
    }
    else {
       WSTRING_TO_DEST(cc.getOptionalWString(i));
    }
  }

  // Display everything else only if it was passed in (initialized).

  for (i=0; i<ComCondition::NumOptionalParms; i++)
    if (cc.getOptionalInteger(i) != ComDiags_UnInitialized_Int)
      INT_TO_DEST(cc.getOptionalInteger(i));

  STRING_TO_DEST_IF(cc.getServerName());
  STRING_TO_DEST_IF(cc.getConnectionName());
  STRING_TO_DEST_IF(cc.getConstraintCatalog());
  STRING_TO_DEST_IF(cc.getConstraintSchema());
  STRING_TO_DEST_IF(cc.getConstraintName());
  STRING_TO_DEST_IF(cc.getTriggerCatalog());
  STRING_TO_DEST_IF(cc.getTriggerSchema());
  STRING_TO_DEST_IF(cc.getTriggerName());
  STRING_TO_DEST_IF(cc.getCatalogName());
  STRING_TO_DEST_IF(cc.getSchemaName());
  STRING_TO_DEST_IF(cc.getTableName());
  STRING_TO_DEST_IF(cc.getColumnName());
  STRING_TO_DEST_IF(cc.getSqlID());

  if (cc.getRowNumber() != ComCondition::INVALID_ROWNUMBER)	INT_TO_DEST(cc.getRowNumber());
  if (cc.getNskCode())	        INT_TO_DEST(cc.getNskCode());

  // For now, ignoring SQLSTATE, classOrigin, subClassOrigin

   // remove trailing blanks
   size_t j;
   if (j = dest->length()) {                      //
     for ( ; j--; )
       if (!NAWisspace((*dest)[j]))
         break;
     dest->remove(++j);
  }

  if (dest->length() > expandedBufferLen - 100)	// prevent msg overflow
    dest->remove(expandedBufferLen - 100);	// (100 is a fudge factor)

  NADELETEBASICARRAY(wbuffer, p);
  return dest;
}


#ifndef NDEBUG
Int32 displayWCHAR(NAWchar* wstr, NAWchar* wend = NULL)	// for debugging
{
  unsigned char str[2000+1];
  if (wend) *wend = '\0';
  Int32 i=0;
  for (; i<2000 && wstr[i]; i++)
    str[i] = (unsigned char)wstr[i];
  str[i] = '\0';
  cerr << "{{{" << endl << str << "}}}" << endl;
  return i;
}
#endif // NDEBUG

//
// ComCondition::getMessageEMSSeverity()
//
void ComEMSSeverity(Lng32 theSQLCODE, char *theEMSSeverity)
{
  // this function should not have been called for these
  // sqlcodes but just in case
  // "UUUUU" is an undefined severity
  if ((theSQLCODE == 0) || (theSQLCODE == 100))
  {
    str_cpy_all(theEMSSeverity,"UUUUU",6);
    return;
  }
  // if it's  a warning then lower the severity to 'informational'
  if (theSQLCODE >0) 
  {
    str_cpy_all(theEMSSeverity,"INFRM",6);
    return;
  }

  // We need to lookup the EMS_SEVERITY for this SQLCODE.
  NAWchar* source;

  // Get the Message string for this error. The fourth field is the EMS_SEVERITY. 
  NABoolean sourceIsNotKnown = GetErrorMessage(theSQLCODE, source, EMS_SEVERITY);

  if (!sourceIsNotKnown)
  {
    // Message found.
    Int32 numBytes = 
      UnicodeStringToLocale(CharInfo::ISO88591, 
                              source, 5, theEMSSeverity, 5, FALSE);

    if (numBytes != 5) 
       *theEMSSeverity = '\0';
    else
       theEMSSeverity[5] = '\0';
  }
}

//
// ComCondition::getMessageEMSEventTarget()
//
void ComEMSEventTarget(Lng32 theSQLCODE, char *theEMSEventTarget, NABoolean forceDialout)
{
  Int32 numBytes = 0;

  // this function should not have been called for these
  // sqlcodes but just in case
  // "UUUUUUU" is an undefined event target
  if ((theSQLCODE == 0) || (theSQLCODE == 100))
  {
    str_cpy_all(theEMSEventTarget,"UUUUUUU",8);
    numBytes = 7;
  }
  else if (forceDialout)
  {
    str_cpy_all(theEMSEventTarget,"DIALOUT",8);
    numBytes = 7;
  }
  else
  {
     // We need to lookup the EMS_EVENT_TARGET for this SQLCODE.
     NAWchar* source;
   
     // Get the Message string for this error. The fifth field is the EMS_EVENT_TARGET.
     NABoolean sourceIsNotKnown = GetErrorMessage(theSQLCODE, source, EMS_EVENT_TARGET);
   
     if (!sourceIsNotKnown)
     {
       // Message found.
       numBytes =
         UnicodeStringToLocale(CharInfo::ISO88591,
                                 source, 7, theEMSEventTarget, 7, FALSE);
   
       // if the message is a warning 
       //  downgrade to LOGONLY. 
       // soln10-070918-7550 and soln 10-071206-9296.
       if( theSQLCODE > 0)
       {
           str_cpy_all(theEMSEventTarget,"LOGONLY",8);
       }

     }
  }

  if (numBytes != 7)
     *theEMSEventTarget = '\0';
  else
     theEMSEventTarget[7] = '\0';
}

//
// ComCondition::getMessageEMSExperienceLevel()
//
void ComEMSExperienceLevel(Lng32 theSQLCODE, char *theEMSExperienceLevel)
{
  // this function should not have been called for these
  // sqlcodes but just in case
  // "UUUUUUUU" is an undefined experience level
  if ((theSQLCODE == 0) || (theSQLCODE == 100))
  {
    str_cpy_all(theEMSExperienceLevel,"UUUUUUUU",9);
    return;
  }

  // We need to lookup the EMS_EVENT_TARGET for this SQLCODE.
  NAWchar* source;

  // Get the Message string for this error. The third field is the EMS_EXPERIENCE_LEVEL.
  NABoolean sourceIsNotKnown = GetErrorMessage(theSQLCODE, source, EMS_EXPERIENCE_LEVEL);

  if (!sourceIsNotKnown)
  {
    // Message found.
    Int32 numBytes =
      UnicodeStringToLocale(CharInfo::ISO88591,
                              source, 8, theEMSExperienceLevel, 8, FALSE);

    if (numBytes != 8)
       *theEMSExperienceLevel = '\0';
    else
       theEMSExperienceLevel[8] = '\0';
  }
}


//
// ComCondition::getMessageText()
//
// Getting message text establishes that messageText_ points
// to a buffer, on the proper heap, that holds the instantiated
// form of the error message corresponding to the current SQLCODE value.
//
// This function just returns messageText_ if this object is already
// locked.
//
// Otherwise, the algorithm followed is:
// 1. Set isLocked_.
// 2. Get a char* pointing to a buffer holding the raw message text per
//    the SQLCODE value.
// 3. Instantiate the message text into a buffer on the global heap.
// 4. Store a pointer to that buffer in messageText_.
// 5. Store the length of that string in messageLen_.
//
// It's okay to get the message text for a ComCondition whose
// SQLCODE is zero.  You just can't insert a zero-condition ComCondition
// into a ComDiagsArea.
//
const NAWchar * ComCondition::getMessageText(NABoolean prefixAdded)
{
  return getMessageText(prefixAdded, CharInfo::ISO88591/* iso_mapping */);
}

const NAWchar *const ComCondition::getMessageText(NABoolean prefixAdded,
                                                  CharInfo::CharSet isoMapCS)
{
   if (!isLocked_) {
      isLocked_ = TRUE;
      Int32 arg = (Int32) theSQLCODE_;
      assert(arg == theSQLCODE_);
      // Ignore the contents of isoMapCS because error messages on SeaQuest
      // is always in UTF8 - Set isoMapsCS to UTF8 to avoid using conditional
      // compilations in this routine (i.e., to save me some typing);
      // i still keep a couple conditional compilations below so you see what
      // i mean - On SeaQuest, the name isoMapCS in this routine does
      // not mean ISO(88951)_MAPPING_CHARSET - Please think of it as UTF8.
      isoMapCS = CharInfo::UTF8;
      NAWchar* source;

//UR2 CNTNSK
      NABoolean msgNotFound = GetErrorMessage(arg, source, ERROR_TEXT, NULL, 0, prefixAdded);
      assert(source);

      //dbg: NAWstrcat(source, WIDE_(" $ $$ $ab $9 $~ $~~ $~0 $0~ $~a $a~ $0x $0x~int0 $int0~x # $0~int0 $int0~0 $0 $00 $0$0 $int0 $int0$int0"));

      // What we want to do here is to first allocate a buffer of some size.
      // Once that has been accomplished, we declare and construct dest,
      // an ostrstream.

      NAWchar* buffer = NULL;
      UInt32 expandedBufferLen = computeMsgLen(*this);

      if (!collHeapPtr_)
        buffer = new NAWchar[expandedBufferLen];
      else
        buffer = (NAWchar*) collHeapPtr_->allocateMemory(expandedBufferLen * sizeof(NAWchar));
      assert(buffer);
      NAWchar* dest = buffer;

      // This chunk has the code for scanning message text and replacing
      // any text retrieved for the given SQLCODE value.
      //
      // We are implementing a state machine based scanner.  The state
      // of the scanner is given by theState.  The main point is to
      // scan until $ is located and then grab whatever identifier
      // happens to come next.  We then lookup the identifier in our
      // fixed table of params which we know about. We then attempt to
      // make an intelligent choice for what string to write in place
      // of the token we just found.
      //
      // We assume on entry that source is a forward iterator over
      // the given message and that the message is null-terminated.
      //
      // It is an important point that if the str() member of dest
      // is messaged, then we own the storage returned by that buffer.

      UInt32             theState = 1;
      const  UInt32      DONE_STATE = 99;
      NAWchar              tokenBuf[256];
      NAWchar*             theToken = tokenBuf;
      tokenBuf[0] = L'\0';
      while (theState != DONE_STATE)  {
         switch (theState)  {
            case 1:
               if (*source == L'\0')
                  theState = DONE_STATE;

               else if (*source == ERRORPARAM_BEGINMARK)  {
      		  tokenBuf[0] = L'\0';
                  theToken = tokenBuf;
                  source++;
                  theState = 2;
               }
               else
                  *dest++ = *source++;
               break;

             case 2:
               if (isAlNum8859_1(*source))  {
                  *theToken++ = *source++;
                  theState = 3;
               }
               else  {
                  *dest++ = ERRORPARAM_BEGINMARK;
                  if (*source == L'\0')
                    theState = DONE_STATE;
                  else {
		    theState = 1;
		    *dest++ = *source++;
		  }
               }
               break;

            case 3:
               if (isAlNum8859_1(*source) || *source == ERRORPARAM_TYPESEP)
                 *theToken++ = *source++;
               else  {
		 // In this chunk we
		 // lookup theToken in a table of tokens and from that result
		 // determine a substitution, generally drawing on the value of
		 // a data member of a ComCondition object.
		
		 // This chunk of code takes the NAString theToken, 
		 // removes positional parameter syntax from it, does a
		 // tolower on it to convert its contents to all lower-case,
		 // and then tries to locate theToken in the tokens array.
		 // If not found, the post-condition of this chunk is tokIndex
		 // must equal MAX_TOKEN; otherwise tokIndex has a value which
		 // can be cast to TOKEN_ENUM to refer to the token which
		 // theToken represents.
		 // There are several SQLSTATE related items for which we have
		 // no values to reply, currently.

                 *theToken = L'\0';
		 FixupMessageParam(tokenBuf); // remove positional param syntax

		 for (theToken=tokenBuf; *theToken; theToken++)
		   *theToken = na_towlower(*theToken);
		 theToken = tokenBuf;
		 UInt32 tokIndex = 0;
		 while (tokIndex != MAX_TOKEN && 
		        na_wcscmp(theToken, tokens[tokIndex]))
		   tokIndex++;

		 Int32 optStrNum = 0;

		 switch (tokIndex) {
		 case MAX_TOKEN:           *dest++ = ERRORPARAM_BEGINMARK; 
		 			   na_wcscpy(dest, tokenBuf);
			break;

		 case STRING4:	optStrNum++;
		 case STRING3:	optStrNum++;
		 case STRING2:	optStrNum++;
		 case STRING1:	optStrNum++;
		 case STRING0:
			
                  {
                    UInt32 len;
                    UInt32 availChars = expandedBufferLen - (dest - buffer);

                    CharInfo::CharSet cs = optionalStringCharSet_[optStrNum];
                    if (CharInfo::isSingleByteCharSet(cs))
                    {
                      if (cs == CharInfo::ISO88591)
                      {
                        cs = CharInfo::UTF8;
                      }
                      const char* optStr = getOptionalString(optStrNum);
                      len = (optStr) ? strlen(optStr) : 0;

                      if (availChars < len+1)
                        assert(FALSE);
                      appendSafeStringInW(dest, collHeapPtr_, optStr, cs);
                    } else {
                      const NAWchar* optStrInW = 
                         getSafeWString(getOptionalWString(optStrNum));
                      len = NAWstrlen(optStrInW);
                      if (availChars < len+1)
                        assert(FALSE);
                      NAWsprintf(dest, WIDE_("%s"), optStrInW);
                    }
                  }

	            break;


		 case INT0:                NAWsprintf(dest,WIDE_("%d"),optionalInteger_[0]);			break;
		 case INT1:                NAWsprintf(dest,WIDE_("%d"),optionalInteger_[1]);			break;
		 case INT2:                NAWsprintf(dest,WIDE_("%d"),optionalInteger_[2]);			break;
		 case INT3:                NAWsprintf(dest,WIDE_("%d"),optionalInteger_[3]);			break;
		 case INT4:                NAWsprintf(dest,WIDE_("%d"),optionalInteger_[4]);			break;
		 case INTERNAL_SQLCODE:    NAWsprintf(dest,WIDE_("%d"),theSQLCODE_);				break;
		 case CONDITION_NUMBER:    NAWsprintf(dest,WIDE_("%d"),conditionNumber_);			break;
		 case SERVER_NAME:         
                   appendSafeStringInW(dest, collHeapPtr_, serverName_, isoMapCS);
                  break;
		 case CONNECTION_NAME:     
                   appendSafeStringInW(dest, collHeapPtr_, connectionName_, isoMapCS);
                   break;
		 case CONSTRAINT_CATALOG:
                   appendSafeStringInW(dest, collHeapPtr_, constraintCatalog_, CharInfo::UTF8);
                   break;
		 case CONSTRAINT_SCHEMA:   
                   appendSafeStringInW(dest, collHeapPtr_, constraintSchema_, isoMapCS);
                   break;
		 case CONSTRAINT_NAME:     
                 appendSafeStringInW(dest, collHeapPtr_, constraintName_, isoMapCS);
                 break;
		 case TRIGGER_CATALOG:  
                   appendSafeStringInW(dest, collHeapPtr_, triggerCatalog_, isoMapCS);
                   break;
		 case TRIGGER_SCHEMA:   
                   appendSafeStringInW(dest, collHeapPtr_, triggerSchema_, isoMapCS);
                   break;
		 case TRIGGER_NAME:     
                   appendSafeStringInW(dest, collHeapPtr_, triggerName_, isoMapCS);
                   break;
		 case CATALOG_NAME:        
                   appendSafeStringInW(dest, collHeapPtr_, catalogName_, isoMapCS);
                   break;
		 case SCHEMA_NAME:         
                   appendSafeStringInW(dest, collHeapPtr_, schemaName_, isoMapCS);
                   break;

		 case TABLE_NAME:          
                 appendSafeStringInW(dest, collHeapPtr_, tableName_, isoMapCS);
                 break;
		 case COLUMN_NAME:         
                 appendSafeStringInW(dest, collHeapPtr_, columnName_, isoMapCS);
                 break;

		 case CURSOR_NAME:         
                 // CursorName_ is deprecated (coopted by sqlID_)
                 break;
		 case ROW_NUMBER:          NAWsprintf(dest,WIDE_("%d"),rowNumber_);				break;
		 case NSK_CODE:            NAWsprintf(dest,WIDE_("%d"),nskCode_);				break;
	   //	 case RETURNED_SQLSTATE: dest << returnedSQLSTATE_;	break;
	   //    case CLASS_ORIGIN:      dest << classOrigin_;		break;
	   //    case SUBCLASS_ORIGIN:   dest << subClassOrigin_;	break;
		 default: assert(FALSE);
		 }
		 // Note that dest[0] will be 0 on a %S format if:
		 // - the rhs src string is the empty string (correct behavior)
		 // - the rhs src string is too big, > 1023 chars
		 //   (reasonable, but unexpected behavior!)
		 dest += NAWstrlen(dest);
		
		 if (*source == ERRORPARAM_BEGINMARK)  {
      		   tokenBuf[0] = L'\0';
                   theToken = tokenBuf;
		   source++;
		   theState = 2;
		 }
		 else if (*source == L'\0')
		   theState = DONE_STATE;
		 else {
		   theState = 1;
		   *dest++ = *source++;
		 }
               }
               break;
         default: assert(FALSE);
         }
      } // while (theState != DONE_STATE)

      // If the error text is not available, at least display the error params,
      // for debugging purposes when testing on a machine where the error file
      // is missing, incomplete, or corrupted.
      //
      // This mirrors what ErrorMessage::printErrorMessage does.
      if (msgNotFound) 
        {
	  // Remove ALL trailing newlines/carriage-returns so params will be on
	  // the same line (not quite the same as FixCarriageReturn below).
	  while (dest > buffer && (*--dest == L'\n' || *dest == L'\r')) ;

	  NAWString* msgParams = terseParamDisplay(*this, collHeapPtr_);

          if ( msgParams ) {
	     const NAWchar *p = msgParams -> data();
	     NAWchar* bufend = &buffer[expandedBufferLen-1];
	     while (++dest < bufend && *p)
	       *dest = *p++;

             NADELETE(msgParams, NAWString, collHeapPtr_);
	  }

        
	}

      *dest = L'\0';
      messageText_ = buffer;
      assert(messageText_);
      ErrorMessageOverflowCheckW(messageText_, expandedBufferLen);

      FixCarriageReturn(messageText_);
      messageLen_ = (Lng32) NAWstrlen(messageText_);
   }

   return messageText_;
}

// We create an operator<< for outputting a ComDiagsArea
// and giving a summary of its contents.

ostream &operator<<(ostream &dest, const ComDiagsArea& da)
{
   char rowCount[21];  // for row count which is Int64
   dest << "Function : " << da.getFunctionName() << endl;
   dest << "SQLCODE  : " << da.mainSQLCODE()     << endl;
   dest << "number   : " << da.getNumber()       << endl;
   dest << "are more?: " << ((da.areMore()) ? "Yes" : "No") << endl;
   convertInt64ToAscii(da.getRowCount(), rowCount);
   dest << "row count: " << rowCount     << endl;
   Lng32 i = 1;
   while (i != da.getNumber()+1)
     dest << (da[i++].getSQLCODE()) << endl;
   return dest;
}

//  stuff for error processing using variable argument list
//
void emitError( Lng32 ErrNum, char *stringType, Lng32 numArgs, ... )
{
   va_list ap;
   ComCondition currentErr;

   currentErr.clear();
   currentErr.setSQLCODE( ErrNum );

// set optional data if arguments were provided, they must be provided
// in order according to type so that the first optional integer gets
// slot 1, the second to appear gets slot 2, etc.  Same for optional
// strings

   if ( stringType && numArgs > 0 )  {
      UInt32 intIdx = 0, strIdx = 0;

      va_start( ap, numArgs );
      assert( numArgs < 11 ); // at most, 10 arguments are acceptable

      for( UInt32 argNum = 0; argNum < (UInt32)numArgs; argNum++ )
         if ( stringType[ argNum ] == 'T' )  {
            assert( strIdx < 5 );
            currentErr.setOptionalString( strIdx, va_arg( ap, const char * ) );
            strIdx++;
            }
         else  {
            assert( intIdx < 5 );
            currentErr.setOptionalInteger( intIdx,
                                           * (Lng32 *) va_arg(ap, UInt32 *) );
            intIdx++;
            }

      va_end( ap );
      }
   NAWriteConsole(currentErr.getMessageText(), cerr, TRUE/*newline*/);
}

