/*
 * 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.
 */

/* $Rev$ $Date$ */


#include "commonj/sdo/SDORuntimeException.h"

#include <stdio.h>
              
// Exception safe helper function
char* makeCopy(const char* src)
{

  try {
    char* tmp;
    if (src != 0) {
      int strSize = strlen(src);
      tmp = new char[strSize + 1];
      strncpy(tmp, src, strSize + 1);
    }
    else {
      tmp = new char[1];
      tmp[0] = '\0';
    }

    return tmp;
  } catch (...) {
    return (char*)"";
  }
}

namespace commonj {

namespace sdo {

SDOExceptionInfo::SDOExceptionInfo(const char* fileNameIN, 
                                   unsigned long lineNumberIN,
                                   const char* functionNameIN)
  : lineNumber(lineNumberIN)
  , fileName(0)
  , functionName(0)
{
  fileName = makeCopy(fileNameIN);
  functionName = makeCopy(functionNameIN);
}

SDOExceptionInfo::SDOExceptionInfo(const SDOExceptionInfo& second)
  : lineNumber(second.lineNumber)
  , fileName(0)
  , functionName(0)
{
  fileName= makeCopy(second.fileName);
  functionName = makeCopy(second.functionName);
}

SDOExceptionInfo&
SDOExceptionInfo::operator=(const SDOExceptionInfo& second)
{
  if (fileName) {
    delete [] fileName;
  }
  fileName = makeCopy(second.fileName);
  
  if (functionName) {
    delete [] functionName;
  }
  functionName = makeCopy(second.functionName);
  
  lineNumber = second.lineNumber;
  return *this;
}

SDOExceptionInfo::~SDOExceptionInfo()
{
  if (fileName) {
    delete [] fileName;
  }
  if (functionName) {
    delete [] functionName;
  }
}

// ========================================================================
// Constructor
// ========================================================================
SDORuntimeException::SDORuntimeException(const SDOExceptionInfo& einfo,
                                         const char* msg_text, 
                                         const char* className)
    : info(einfo), message_text(0), class_name(className)
{
  message_text = makeCopy(msg_text);
} // end SDORuntimeException constuctor
  
// ========================================================================
// Copy constructor
// ========================================================================
SDORuntimeException::SDORuntimeException(const SDORuntimeException& c)
    : info(c.info), message_text(0), class_name(c.class_name)
{
  message_text = makeCopy(c.message_text);
}
           
// ========================================================================
// Destructor
// ========================================================================
SDORuntimeException::~SDORuntimeException()
{
   if (message_text)
   {
      delete[] message_text;
   }
} // end SDORuntimeException destructor
                    
// ========================================================================
// Return class name of this exception
// ========================================================================
const char* SDORuntimeException::getEClassName() const
{
  return class_name;
} // end getClassName()

// ========================================================================
// Return message text associated with exception
// ========================================================================
const char* SDORuntimeException::getMessageText() const
{
  return message_text;
} // end getMessageText()

// ========================================================================
// Return file name where exception was raised
// ========================================================================
const char* SDORuntimeException::getFileName() const
{
  return info.fileName;
} // end getFileName()

// ========================================================================
// Return line number where exception was raised
// ========================================================================
unsigned long SDORuntimeException :: getLineNumber() const
{
  return info.lineNumber;
} // end getLineNumber()

// ========================================================================
// Return function name where exception was raised
// ========================================================================
const char* SDORuntimeException :: getFunctionName() const
{
  return info.functionName;
} // end getFunctionName()

} // end namespace sdo
} // end namespace commonj

// ========================================================================
// ostream operator <<
// ========================================================================
SDO_API std::ostream& operator<<(std::ostream& os, const commonj::sdo::SDORuntimeException& except)
{
  os << "Exception object :" << std::endl;
  os << " class:           " << except.getEClassName() << std::endl;
  os << " file name:       " << except.getFileName() << std::endl;
  os << " line number:     " << except.getLineNumber() << std::endl;
  os << " function:        " << except.getFunctionName() << std::endl;
  os << " description:     " << except.getMessageText() << std::endl;
  return os;
} // end ostream operator <<
    
