<commit_before>// @(#)root/reflex:$Id$
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
# define REFLEX_BUILD
#endif

#include "Reflex/internal/TypeBase.h"

#include "Reflex/Type.h"
#include "Reflex/internal/OwnedPropertyList.h"
#include "Reflex/Object.h"
#include "Reflex/Scope.h"
#include "Reflex/internal/TypeName.h"
#include "Reflex/Base.h"
#include "Reflex/TypeTemplate.h"
#include "Reflex/DictionaryGenerator.h"

#include "Array.h"
#include "Pointer.h"
#include "PointerToMember.h"
#include "Union.h"
#include "Enum.h"
#include "Fundamental.h"
#include "Function.h"
#include "Class.h"
#include "Typedef.h"
#include "ClassTemplateInstance.h"
#include "FunctionMemberTemplateInstance.h"

#include "Reflex/Tools.h"

#include "Reflex/Builder/TypeBuilder.h"

//-------------------------------------------------------------------------------
Reflex::TypeBase::TypeBase(const char* nam,
                           size_t size,
                           TYPE typeTyp,
                           const std::type_info& ti,
                           const Type& finalType,
                           REPRESTYPE represType /*= REPRES_NOTYPE */):
   fTypeInfo(&ti),
   fRepresType(represType),
   fScope(Scope::__NIRVANA__()),
   fSize(size),
   fTypeType(typeTyp),
   fPropertyList(OwnedPropertyList(new PropertyListImpl())),
   fBasePosition(Tools::GetBasePosition(nam)),
   fFinalType(finalType.Id() ? new Type(finalType): 0),
   fRawType(0) {
//-------------------------------------------------------------------------------
// Construct the dictinary info for a type.
   Type t = TypeName::ByName(nam);

   if (t.Id() == 0) {
      fTypeName = new TypeName(nam, this, &ti);
   } else {
      fTypeName = (TypeName*) t.Id();

      if (t.Id() != TypeName::ByTypeInfo(ti).Id()) {
         fTypeName->SetTypeId(ti);
      }

      if (fTypeName->fTypeBase) {
         delete fTypeName->fTypeBase;
      }
      fTypeName->fTypeBase = this;
   }

   if (typeTyp != FUNDAMENTAL &&
       typeTyp != FUNCTION &&
       typeTyp != POINTER) {
      std::string sname = Tools::GetScopeName(nam);
      fScope = Scope::ByName(sname);

      if (fScope.Id() == 0) {
         fScope = (new ScopeName(sname.c_str(), 0))->ThisScope();
      }

      // Set declaring At
      if (fScope) {
         fScope.AddSubType(ThisType());
      }
   }
}

//-------------------------------------------------------------------------------
Reflex::TypeBase::~TypeBase() {
//-------------------------------------------------------------------------------
// Destructor.
   fPropertyList.Delete();

   if (fFinalType) {
      delete fFinalType;
   }

   if (fRawType) {
      delete fRawType;
   }

   if (fTypeName->fTypeBase == this) {
      fTypeName->fTypeBase = 0;
   }
}

//-------------------------------------------------------------------------------
Reflex::TypeBase::operator
Reflex::Scope() const {
//-------------------------------------------------------------------------------
// Conversion operator to Scope.
   switch (fTypeType) {
   case CLASS :
   case STRUCT:
   case TYPETEMPLATEINSTANCE:
   case UNION:
   case ENUM:
      return (dynamic_cast<const ScopeBase*>(this))->ThisScope();
   case TYPEDEF:
      return FinalType();
   default:
      return Dummy::Scope();
   }
}

//-------------------------------------------------------------------------------
Reflex::TypeBase::operator
Reflex::Type() const {
//-------------------------------------------------------------------------------
// Converison operator to Type.
   return ThisType();
}

//-------------------------------------------------------------------------------
void*
Reflex::TypeBase::Allocate() const {
//-------------------------------------------------------------------------------
// Allocate memory for this type.
   return malloc(fSize);
}

//-------------------------------------------------------------------------------
size_t
Reflex::TypeBase::ArrayLength() const {
//-------------------------------------------------------------------------------
// Return the length of the array type.
   return 0;
}

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::Deallocate(void* instance) const {
//-------------------------------------------------------------------------------
// Deallocate the memory for this type from instance.
   free(instance);
}

//-------------------------------------------------------------------------------
Reflex::Scope
Reflex::TypeBase::DeclaringScope() const {
//-------------------------------------------------------------------------------
// Return the declaring scope of this type.
   return fScope;
}

//-------------------------------------------------------------------------------
Reflex::Object
Reflex::TypeBase::CastObject(const Type& /* to */,
                             const Object& /* obj */) const {
//-------------------------------------------------------------------------------
// Cast this type into "to" using object "obj"
   throw RuntimeError("This function can only be called on Class/Struct");
   return Dummy::Object();
}

//-------------------------------------------------------------------------------
//const Reflex::Object &
//Reflex::TypeBase::Construct( const Type &  /*signature*/,
//                                   const std::vector < Object > & /*values*/,
//                                   void * /*mem*/ ) const {
//-------------------------------------------------------------------------------
//  return Object(ThisType(), Allocate());
//}

//-------------------------------------------------------------------------------
Reflex::Object
Reflex::TypeBase::Construct(const Type& /*signature*/,
                            const std::vector<void*>& /*values*/,
                            void* /*mem*/) const {
//-------------------------------------------------------------------------------
// Construct this type.
   return Object(ThisType(), Allocate());
}

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::Destruct(void* instance,
                           bool dealloc) const {
//-------------------------------------------------------------------------------
// Destruct this type.
   if (dealloc) {
      Deallocate(instance);
   }
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::DynamicType(const Object& /* obj */) const {
//-------------------------------------------------------------------------------
// Return the dynamic type info of this type.
   throw RuntimeError("Type::DynamicType can only be called on Class/Struct");
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::FinalType() const {
//-------------------------------------------------------------------------------
// Return the type without typedefs information.
   if (fFinalType) {
      return *fFinalType;
   }

   fFinalType = new Type(DetermineFinalType(ThisType()));
   return *fFinalType;
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::DetermineFinalType(const Type& t) const {
//-------------------------------------------------------------------------------
// Return the type t without typedefs information.

   Type retType(t);

   switch (t.TypeType()) {
   case TYPEDEF:
      retType = t.ToType().FinalType();
      break;
   case POINTER:
      retType = PointerBuilder(t.ToType().FinalType(), t.TypeInfo());
      break;
   case POINTERTOMEMBER:
      retType = PointerToMemberBuilder(t.ToType().FinalType(), t.PointerToMemberScope(), t.TypeInfo());
      break;
   case ARRAY:
      retType = ArrayBuilder(t.ToType().FinalType(), t.ArrayLength(), t.TypeInfo());
      break;
   case FUNCTION:
   {
      std::vector<Type> vecParFinal(t.FunctionParameterSize());

      for (size_t iPar = 0; iPar < t.FunctionParameterSize(); ++iPar) {
         vecParFinal[iPar] = t.FunctionParameterAt(iPar).FinalType();
      }
      retType = FunctionTypeBuilder(t.ReturnType().FinalType(), vecParFinal, t.TypeInfo());
      break;
   }
   case UNRESOLVED:
      return Dummy::Type();
   default:
      return t;
   } // switch

   // copy fModifiers
   if (t.IsConst()) {
      retType = ConstBuilder(retType);
   }

   if (t.IsReference()) {
      retType = ReferenceBuilder(retType);
   }

   if (t.IsVolatile()) {
      retType = VolatileBuilder(retType);
   }

   return retType;
} // DetermineFinalType

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::HideName() const {
//-------------------------------------------------------------------------------
// Append the string " @HIDDEN@" to a type name.
   fTypeName->HideName();
}

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::UnhideName() const {
   //-------------------------------------------------------------------------------
   // Remove the string " @HIDDEN@" to a type name.
   fTypeName->UnhideName();
}

//-------------------------------------------------------------------------------
std::string
Reflex::TypeBase::Name(unsigned int mod) const {
//-------------------------------------------------------------------------------
// Return the name of the type.
   if (0 != (mod & (SCOPED | S))) {
      return fTypeName->Name();
   }
   return std::string(fTypeName->Name(), fBasePosition);
}

//-------------------------------------------------------------------------------
const std::string&
Reflex::TypeBase::SimpleName(size_t& pos,
                             unsigned int mod) const {
//-------------------------------------------------------------------------------
// Return the name of the type.
   if (0 != (mod & (SCOPED | S))) {
      pos = 0;
      return fTypeName->Name();
   }
   pos = fBasePosition;
   return fTypeName->Name();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::FunctionParameterAt(size_t /* nth */) const {
//-------------------------------------------------------------------------------
// Return the nth function parameter type.
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
size_t
Reflex::TypeBase::FunctionParameterSize() const {
//-------------------------------------------------------------------------------
// Return the number of function parameters.
   return 0;
}

//-------------------------------------------------------------------------------
Reflex::Scope
Reflex::TypeBase::PointerToMemberScope() const {
//-------------------------------------------------------------------------------
// Return the scope of a pointer to member type.
   return Dummy::Scope();
}

//-------------------------------------------------------------------------------
Reflex::PropertyList
Reflex::TypeBase::Properties() const {
//-------------------------------------------------------------------------------
// Return the property list attached to this type.
   return fPropertyList;
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::RawType() const {
//-------------------------------------------------------------------------------
// Return the raw type of this type, removing all info of pointers, arrays, typedefs.
   if (fRawType) {
      return *fRawType;
   }

   Type rawType = ThisType();

   while (true) {
      switch (rawType.TypeType()) {
      case POINTER:
      case POINTERTOMEMBER:
      case TYPEDEF:
      case ARRAY:
         rawType = rawType.ToType();
         break;
      case UNRESOLVED:
         return Dummy::Type();
      default:
         fRawType = new Type(*rawType.ToTypeBase());
         return *fRawType;
      }
   }
} // RawType

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::ReturnType() const {
//-------------------------------------------------------------------------------
// Return the function return type.
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::TemplateArgumentAt(size_t /* nth */) const {
//-------------------------------------------------------------------------------
// Return the nth template argument.
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::ToType() const {
//-------------------------------------------------------------------------------
// Return the underlying type.
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::ThisType() const {
//-------------------------------------------------------------------------------
// Return the Type object pointing to this TypeBase.
   return fTypeName->ThisType();
}

//-------------------------------------------------------------------------------
std::string
Reflex::TypeBase::TypeTypeAsString() const {
//-------------------------------------------------------------------------------
// Return the kind of type as a string.
   switch (fTypeType) {
   case CLASS:
      return "CLASS";
      break;
   case STRUCT:
      return "STRUCT";
      break;
   case ENUM:
      return "ENUM";
      break;
   case FUNCTION:
      return "FUNCTION";
      break;
   case ARRAY:
      return "ARRAY";
      break;
   case FUNDAMENTAL:
      return "FUNDAMENTAL";
      break;
   case POINTER:
      return "POINTER";
      break;
   case TYPEDEF:
      return "TYPEDEF";
      break;
   case TYPETEMPLATEINSTANCE:
      return "TYPETEMPLATEINSTANCE";
      break;
   case MEMBERTEMPLATEINSTANCE:
      return "MEMBERTEMPLATEINSTANCE";
      break;
   case UNRESOLVED:
      return "UNRESOLVED";
      break;
   default:
      return "Type " + Name() + "is not assigned to a TYPE";
   } // switch
} // TypeTypeAsString

//-------------------------------------------------------------------------------
Reflex::TYPE
Reflex::TypeBase::TypeType() const {
//-------------------------------------------------------------------------------
// Return the kind of type as an enum.
   return fTypeType;
}

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::GenerateDict(DictionaryGenerator& /* generator */) const {
//-------------------------------------------------------------------------------
// Generate Dictionary information about itself.
}
<commit_msg>Use new / delete instead of malloc / free, to be compatible with CINT and Cintex. See e.g. http://home.fnal.gov/~cplager/log/0909/log.html#090910_Progress_with_PyRoot_Memory_Problems<commit_after>// @(#)root/reflex:$Id$
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
# define REFLEX_BUILD
#endif

#include "Reflex/internal/TypeBase.h"

#include "Reflex/Type.h"
#include "Reflex/internal/OwnedPropertyList.h"
#include "Reflex/Object.h"
#include "Reflex/Scope.h"
#include "Reflex/internal/TypeName.h"
#include "Reflex/Base.h"
#include "Reflex/TypeTemplate.h"
#include "Reflex/DictionaryGenerator.h"

#include "Array.h"
#include "Pointer.h"
#include "PointerToMember.h"
#include "Union.h"
#include "Enum.h"
#include "Fundamental.h"
#include "Function.h"
#include "Class.h"
#include "Typedef.h"
#include "ClassTemplateInstance.h"
#include "FunctionMemberTemplateInstance.h"

#include "Reflex/Tools.h"

#include "Reflex/Builder/TypeBuilder.h"

//-------------------------------------------------------------------------------
Reflex::TypeBase::TypeBase(const char* nam,
                           size_t size,
                           TYPE typeTyp,
                           const std::type_info& ti,
                           const Type& finalType,
                           REPRESTYPE represType /*= REPRES_NOTYPE */):
   fTypeInfo(&ti),
   fRepresType(represType),
   fScope(Scope::__NIRVANA__()),
   fSize(size),
   fTypeType(typeTyp),
   fPropertyList(OwnedPropertyList(new PropertyListImpl())),
   fBasePosition(Tools::GetBasePosition(nam)),
   fFinalType(finalType.Id() ? new Type(finalType): 0),
   fRawType(0) {
//-------------------------------------------------------------------------------
// Construct the dictinary info for a type.
   Type t = TypeName::ByName(nam);

   if (t.Id() == 0) {
      fTypeName = new TypeName(nam, this, &ti);
   } else {
      fTypeName = (TypeName*) t.Id();

      if (t.Id() != TypeName::ByTypeInfo(ti).Id()) {
         fTypeName->SetTypeId(ti);
      }

      if (fTypeName->fTypeBase) {
         delete fTypeName->fTypeBase;
      }
      fTypeName->fTypeBase = this;
   }

   if (typeTyp != FUNDAMENTAL &&
       typeTyp != FUNCTION &&
       typeTyp != POINTER) {
      std::string sname = Tools::GetScopeName(nam);
      fScope = Scope::ByName(sname);

      if (fScope.Id() == 0) {
         fScope = (new ScopeName(sname.c_str(), 0))->ThisScope();
      }

      // Set declaring At
      if (fScope) {
         fScope.AddSubType(ThisType());
      }
   }
}

//-------------------------------------------------------------------------------
Reflex::TypeBase::~TypeBase() {
//-------------------------------------------------------------------------------
// Destructor.
   fPropertyList.Delete();

   if (fFinalType) {
      delete fFinalType;
   }

   if (fRawType) {
      delete fRawType;
   }

   if (fTypeName->fTypeBase == this) {
      fTypeName->fTypeBase = 0;
   }
}

//-------------------------------------------------------------------------------
Reflex::TypeBase::operator
Reflex::Scope() const {
//-------------------------------------------------------------------------------
// Conversion operator to Scope.
   switch (fTypeType) {
   case CLASS :
   case STRUCT:
   case TYPETEMPLATEINSTANCE:
   case UNION:
   case ENUM:
      return (dynamic_cast<const ScopeBase*>(this))->ThisScope();
   case TYPEDEF:
      return FinalType();
   default:
      return Dummy::Scope();
   }
}

//-------------------------------------------------------------------------------
Reflex::TypeBase::operator
Reflex::Type() const {
//-------------------------------------------------------------------------------
// Converison operator to Type.
   return ThisType();
}

//-------------------------------------------------------------------------------
void*
Reflex::TypeBase::Allocate() const {
//-------------------------------------------------------------------------------
// Allocate memory for this type.
   return new char[fSize];
}

//-------------------------------------------------------------------------------
size_t
Reflex::TypeBase::ArrayLength() const {
//-------------------------------------------------------------------------------
// Return the length of the array type.
   return 0;
}

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::Deallocate(void* instance) const {
//-------------------------------------------------------------------------------
// Deallocate the memory for this type from instance.
   delete [] ((char*)instance);
}

//-------------------------------------------------------------------------------
Reflex::Scope
Reflex::TypeBase::DeclaringScope() const {
//-------------------------------------------------------------------------------
// Return the declaring scope of this type.
   return fScope;
}

//-------------------------------------------------------------------------------
Reflex::Object
Reflex::TypeBase::CastObject(const Type& /* to */,
                             const Object& /* obj */) const {
//-------------------------------------------------------------------------------
// Cast this type into "to" using object "obj"
   throw RuntimeError("This function can only be called on Class/Struct");
   return Dummy::Object();
}

//-------------------------------------------------------------------------------
//const Reflex::Object &
//Reflex::TypeBase::Construct( const Type &  /*signature*/,
//                                   const std::vector < Object > & /*values*/,
//                                   void * /*mem*/ ) const {
//-------------------------------------------------------------------------------
//  return Object(ThisType(), Allocate());
//}

//-------------------------------------------------------------------------------
Reflex::Object
Reflex::TypeBase::Construct(const Type& /*signature*/,
                            const std::vector<void*>& /*values*/,
                            void* /*mem*/) const {
//-------------------------------------------------------------------------------
// Construct this type.
   return Object(ThisType(), Allocate());
}

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::Destruct(void* instance,
                           bool dealloc) const {
//-------------------------------------------------------------------------------
// Destruct this type.
   if (dealloc) {
      Deallocate(instance);
   }
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::DynamicType(const Object& /* obj */) const {
//-------------------------------------------------------------------------------
// Return the dynamic type info of this type.
   throw RuntimeError("Type::DynamicType can only be called on Class/Struct");
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::FinalType() const {
//-------------------------------------------------------------------------------
// Return the type without typedefs information.
   if (fFinalType) {
      return *fFinalType;
   }

   fFinalType = new Type(DetermineFinalType(ThisType()));
   return *fFinalType;
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::DetermineFinalType(const Type& t) const {
//-------------------------------------------------------------------------------
// Return the type t without typedefs information.

   Type retType(t);

   switch (t.TypeType()) {
   case TYPEDEF:
      retType = t.ToType().FinalType();
      break;
   case POINTER:
      retType = PointerBuilder(t.ToType().FinalType(), t.TypeInfo());
      break;
   case POINTERTOMEMBER:
      retType = PointerToMemberBuilder(t.ToType().FinalType(), t.PointerToMemberScope(), t.TypeInfo());
      break;
   case ARRAY:
      retType = ArrayBuilder(t.ToType().FinalType(), t.ArrayLength(), t.TypeInfo());
      break;
   case FUNCTION:
   {
      std::vector<Type> vecParFinal(t.FunctionParameterSize());

      for (size_t iPar = 0; iPar < t.FunctionParameterSize(); ++iPar) {
         vecParFinal[iPar] = t.FunctionParameterAt(iPar).FinalType();
      }
      retType = FunctionTypeBuilder(t.ReturnType().FinalType(), vecParFinal, t.TypeInfo());
      break;
   }
   case UNRESOLVED:
      return Dummy::Type();
   default:
      return t;
   } // switch

   // copy fModifiers
   if (t.IsConst()) {
      retType = ConstBuilder(retType);
   }

   if (t.IsReference()) {
      retType = ReferenceBuilder(retType);
   }

   if (t.IsVolatile()) {
      retType = VolatileBuilder(retType);
   }

   return retType;
} // DetermineFinalType

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::HideName() const {
//-------------------------------------------------------------------------------
// Append the string " @HIDDEN@" to a type name.
   fTypeName->HideName();
}

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::UnhideName() const {
   //-------------------------------------------------------------------------------
   // Remove the string " @HIDDEN@" to a type name.
   fTypeName->UnhideName();
}

//-------------------------------------------------------------------------------
std::string
Reflex::TypeBase::Name(unsigned int mod) const {
//-------------------------------------------------------------------------------
// Return the name of the type.
   if (0 != (mod & (SCOPED | S))) {
      return fTypeName->Name();
   }
   return std::string(fTypeName->Name(), fBasePosition);
}

//-------------------------------------------------------------------------------
const std::string&
Reflex::TypeBase::SimpleName(size_t& pos,
                             unsigned int mod) const {
//-------------------------------------------------------------------------------
// Return the name of the type.
   if (0 != (mod & (SCOPED | S))) {
      pos = 0;
      return fTypeName->Name();
   }
   pos = fBasePosition;
   return fTypeName->Name();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::FunctionParameterAt(size_t /* nth */) const {
//-------------------------------------------------------------------------------
// Return the nth function parameter type.
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
size_t
Reflex::TypeBase::FunctionParameterSize() const {
//-------------------------------------------------------------------------------
// Return the number of function parameters.
   return 0;
}

//-------------------------------------------------------------------------------
Reflex::Scope
Reflex::TypeBase::PointerToMemberScope() const {
//-------------------------------------------------------------------------------
// Return the scope of a pointer to member type.
   return Dummy::Scope();
}

//-------------------------------------------------------------------------------
Reflex::PropertyList
Reflex::TypeBase::Properties() const {
//-------------------------------------------------------------------------------
// Return the property list attached to this type.
   return fPropertyList;
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::RawType() const {
//-------------------------------------------------------------------------------
// Return the raw type of this type, removing all info of pointers, arrays, typedefs.
   if (fRawType) {
      return *fRawType;
   }

   Type rawType = ThisType();

   while (true) {
      switch (rawType.TypeType()) {
      case POINTER:
      case POINTERTOMEMBER:
      case TYPEDEF:
      case ARRAY:
         rawType = rawType.ToType();
         break;
      case UNRESOLVED:
         return Dummy::Type();
      default:
         fRawType = new Type(*rawType.ToTypeBase());
         return *fRawType;
      }
   }
} // RawType

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::ReturnType() const {
//-------------------------------------------------------------------------------
// Return the function return type.
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::TemplateArgumentAt(size_t /* nth */) const {
//-------------------------------------------------------------------------------
// Return the nth template argument.
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::ToType() const {
//-------------------------------------------------------------------------------
// Return the underlying type.
   return Dummy::Type();
}

//-------------------------------------------------------------------------------
Reflex::Type
Reflex::TypeBase::ThisType() const {
//-------------------------------------------------------------------------------
// Return the Type object pointing to this TypeBase.
   return fTypeName->ThisType();
}

//-------------------------------------------------------------------------------
std::string
Reflex::TypeBase::TypeTypeAsString() const {
//-------------------------------------------------------------------------------
// Return the kind of type as a string.
   switch (fTypeType) {
   case CLASS:
      return "CLASS";
      break;
   case STRUCT:
      return "STRUCT";
      break;
   case ENUM:
      return "ENUM";
      break;
   case FUNCTION:
      return "FUNCTION";
      break;
   case ARRAY:
      return "ARRAY";
      break;
   case FUNDAMENTAL:
      return "FUNDAMENTAL";
      break;
   case POINTER:
      return "POINTER";
      break;
   case TYPEDEF:
      return "TYPEDEF";
      break;
   case TYPETEMPLATEINSTANCE:
      return "TYPETEMPLATEINSTANCE";
      break;
   case MEMBERTEMPLATEINSTANCE:
      return "MEMBERTEMPLATEINSTANCE";
      break;
   case UNRESOLVED:
      return "UNRESOLVED";
      break;
   default:
      return "Type " + Name() + "is not assigned to a TYPE";
   } // switch
} // TypeTypeAsString

//-------------------------------------------------------------------------------
Reflex::TYPE
Reflex::TypeBase::TypeType() const {
//-------------------------------------------------------------------------------
// Return the kind of type as an enum.
   return fTypeType;
}

//-------------------------------------------------------------------------------
void
Reflex::TypeBase::GenerateDict(DictionaryGenerator& /* generator */) const {
//-------------------------------------------------------------------------------
// Generate Dictionary information about itself.
}
<|endoftext|>


<commit_before>/**
 * PriorityManager.cc
 *
 *      Author: Sara Vallero
 *      Author: Valentina Zaccolo
 */

#include "Fass.h"
#include "FassLog.h"
//#include "PriorityManager.h"
//#include "VMPool.h"
#include "VirtualMachine.h"

// booh #include <time.h>
#include <stdexcept>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <pwd.h>
#include <pthread.h>
#include <cmath>
#include <iomanip>
#include <ctime>

using namespace std;

PriorityManager::PriorityManager(
        const string _one_xmlrpc,
	int _message_size,
	int _timeout,
	int _max_vm,
	int _max_dispatch,
	int _live_rescheds):
		one_xmlrpc(_one_xmlrpc),
		message_size(_message_size),
		timeout(_timeout),
		max_vm(_max_vm),
		max_dispatch(_max_dispatch),
		live_rescheds(_live_rescheds)

{

    xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, message_size);

};

bool PriorityManager::start()
{
    int rc;

    ifstream      file;
    ostringstream oss;

    string etc_path;
    //unsigned int machines_limit;
    //unsigned int live_rescheds;

    //pthread_attr_t pattr;
    FassLog::log("PM",Log::INFO,"Starting Priority Manager...");

    XMLRPCClient * client = XMLRPCClient::client();

    // XML-RPC Client
    try
    {

        XMLRPCClient::initialize("", one_xmlrpc, message_size, timeout);

        oss.str("");

        oss << "XML-RPC client using " << (XMLRPCClient::client())->get_message_size()
            << " bytes for response buffer.\n";

        FassLog::log("PM", Log::INFO, oss);

    }
    catch(runtime_error &)
    {
        throw;
    }

       // Get oned configuration
        try
        {
            xmlrpc_c::value result;
            vector<xmlrpc_c::value> values;

            client->call("one.system.config", "", &result);

        }
        catch (exception const& e)
        {
            ostringstream oss;

            oss << "Cannot contact oned, will retry... Error: " << e.what();

            FassLog::log("PM", Log::ERROR, oss);
        }

        FassLog::log("PM", Log::INFO, "oned successfully contacted.");

//TODO
//        do_scheduled_actions();

    rc = set_up_pools();

    if ( rc != 0 )
    {
	//ostringstream oss;

        //oss << "Cannot get the VM pool: " << strerror(errno);
        //FassLog::log("PM",Log::ERROR,oss);
        return false;
    }

//TODO
//    match_schedule();

//TODO
//    dispatch();

   do_schedule();

return true;

};

bool PriorityManager::set_up_pools()
{
    int rc;
    XMLRPCClient * client = XMLRPCClient::client();
    // VM pool
    vmpool = new VMPool(client, max_vm, live_rescheds==1);

    //Cleans the cache and gets the VM pool
    rc = vmpool->set_up();

    return 0;
};

void PriorityManager::do_schedule()
{
 VirtualMachine * vm;

    int vm_memory;
    int vm_cpu;

    const map<int, VirtualMachine*> pending_vms = vmpool->get_objects();
    int rc;

 ostringstream oss;

 time_t time_start = time(0);
 time_t time_end   = time(0);

 tm tmp_tm = *localtime(&time_start);

 tmp_tm.tm_sec  = 0;
 tmp_tm.tm_min  = 0;
 tmp_tm.tm_hour = 0;
 tmp_tm.tm_mday = 1;
 tmp_tm.tm_mon  = start_month - 1;
 tmp_tm.tm_year = start_year - 1900;
 tmp_tm.tm_isdst = -1; // Unknown daylight saving time

 time_start = mktime(&tmp_tm);

// TODO call the plugin basic + save the age from one.vmpool.accounting info

}

/*

void PriorityManager::match_schedule()
{
    VirtualMachineXML * vm;

    int vm_memory;
    int vm_cpu;
    long long vm_disk;
    vector<VectorAttribute *> vm_pci;

    int n_resources;
    int n_matched;
    int n_auth;
    int n_error;
    int n_fits;

    //HostXML * host;
    //DatastoreXML *ds;

    string m_error;

    map<int, ObjectXML*>::const_iterator  vm_it;
    map<int, ObjectXML*>::const_iterator  obj_it;

    vector<SchedulerPolicy *>::iterator it;

    const map<int, ObjectXML*> pending_vms = vmpool->get_objects();
    //const map<int, ObjectXML*> hosts       = hpool->get_objects();
    //const map<int, ObjectXML*> datastores  = dspool->get_objects();
    //const map<int, ObjectXML*> users       = upool->get_objects();

    //double total_cl_match_time = 0;
    //double total_host_match_time = 0;
    //double total_host_rank_time = 0;
    //double total_ds_match_time = 0;
    //double total_ds_rank_time = 0;

    time_t stime = time(0);

    for (vm_it=pending_vms.begin(); vm_it != pending_vms.end(); vm_it++)
    {
        vm = static_cast<VirtualMachineXML*>(vm_it->second);

        vm->get_requirements(vm_cpu, vm_memory, vm_disk, vm_pci);

        n_resources = 0;
        n_fits    = 0;
        n_matched = 0;
        n_auth    = 0;
        n_error   = 0;

    if (FassLog::log_level() >= Log::DDEBUG)
    {
        ostringstream oss;

        oss << "Match Making statistics:\n"
            << "\tNumber of VMs:            "
            << pending_vms.size() << endl
            << "\tTotal time:               "
            << one_util::float_to_str(time(0) - stime) << "s" << endl

        FassLog::log("PM", Log::DDEBUG, oss);
    }

    if (FassLog::log_level() >= Log::DDDEBUG)
    {
        ostringstream oss;

        oss << "Priority Management Results:" << endl;

        for (map<int, ObjectXML*>::const_iterator vm_it=pending_vms.begin();
            vm_it != pending_vms.end(); vm_it++)
        {
            vm = static_cast<VirtualMachineXML*>(vm_it->second);

            oss << *vm;
        }

        FassLog::log("PM", Log::DDDEBUG, oss);
    }
}

*/
/*
void PriorityManager::dispatch()
{
    //HostXML *           host;
    //DatastoreXML *      ds;
    VirtualMachineXML * vm;

    ostringstream dss;
    string        error;

    int cpu, mem;
    long long dsk;
    vector<VectorAttribute *> pci;

    int hid, dsid, cid;

    unsigned int dispatched_vms = 0;
    bool dispatched, matched;
    char * estr;

    map<int, ObjectXML*>::const_iterator vm_it;

    vector<Resource *>::const_reverse_iterator i, j;

    const map<int, ObjectXML*> pending_vms = vmpool->get_objects();

    dss << "Dispatching VMs to hosts:\n" << "\tVMID\tHost\tSystem DS\n"
        << "\t-------------------------\n";

    //--------------------------------------------------------------------------
    // Dispatch each VM till we reach the dispatch limit
    //--------------------------------------------------------------------------

    for (vm_it = pending_vms.begin();
         vm_it != pending_vms.end() &&
            ( dispatch_limit <= 0 || dispatched_vms < dispatch_limit );
         vm_it++)
    {
        dispatched = false;

        vm = static_cast<VirtualMachineXML*>(vm_it->second);

       // const vector<Resource *> resources = vm->get_match_hosts();
*/
/* Let's see what to do with this

int PriorityManager::do_scheduled_actions()
{
    VirtualMachineXML* vm;

    const map<int, ObjectXML*>  vms = vmapool->get_objects();
    map<int, ObjectXML*>::const_iterator vm_it;

    vector<Attribute *> attributes;
    vector<Attribute *>::iterator it;

    VectorAttribute* vatt;

    int action_time;
    int done_time;
    int has_time;
    int has_done;

    string action_st, error_msg;

    time_t the_time = time(0);
    string time_str = one_util::log_time(the_time);

    for (vm_it=vms.begin(); vm_it != vms.end(); vm_it++)
    {
        vm = static_cast<VirtualMachineXML*>(vm_it->second);

        vm->get_actions(attributes);

        // TODO: Sort actions by TIME
        for (it=attributes.begin(); it != attributes.end(); it++)
        {
            vatt = dynamic_cast<VectorAttribute*>(*it);

            if (vatt == 0)
            {
                delete *it;

                continue;
            }

            has_time  = vatt->vector_value("TIME", action_time);
            has_done  = vatt->vector_value("DONE", done_time);
            action_st = vatt->vector_value("ACTION");

            if (has_time == 0 && has_done == -1 && action_time < the_time)
            {
                ostringstream oss;

                int rc = VirtualMachineXML::parse_action_name(action_st);

                oss << "Executing action '" << action_st << "' for VM "
                    << vm->get_oid() << " : ";

                if ( rc != 0 )
                {
                    error_msg = "This action is not supported.";
                }
                else
                {
                    rc = vmapool->action(vm->get_oid(), action_st, error_msg);
                }

                if (rc == 0)
                {
                    vatt->remove("MESSAGE");
                    vatt->replace("DONE", static_cast<int>(the_time));

                    oss << "Success.";
                }
                else
                {
                    ostringstream oss_aux;

                    oss_aux << time_str << " : " << error_msg;

                    vatt->replace("MESSAGE", oss_aux.str());

                    oss << "Failure. " << error_msg;
                }

                NebulaLog::log("VM", Log::INFO, oss);
            }

            vm->set_attribute(vatt);
        }

        vmpool->update(vm);
    }

    return 0;
}
*/
<commit_msg>work in progress...<commit_after>/**
 * PriorityManager.cc
 *
 *      Author: Sara Vallero
 *      Author: Valentina Zaccolo
 */

#include "Fass.h"
#include "FassLog.h"
//#include "PriorityManager.h"
//#include "VMPool.h"
#include "VirtualMachine.h"

// booh #include <time.h>
#include <stdexcept>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <pwd.h>
#include <pthread.h>
#include <cmath>
#include <iomanip>
#include <ctime>

using namespace std;

PriorityManager::PriorityManager(
        const string _one_xmlrpc,
	int _message_size,
	int _timeout,
	int _max_vm,
	int _max_dispatch,
	int _live_rescheds):
		one_xmlrpc(_one_xmlrpc),
		message_size(_message_size),
		timeout(_timeout),
		max_vm(_max_vm),
		max_dispatch(_max_dispatch),
		live_rescheds(_live_rescheds)

{

    xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, message_size);

};

bool PriorityManager::start()
{
    int rc;

    ifstream      file;
    ostringstream oss;

    string etc_path;
    //unsigned int machines_limit;
    //unsigned int live_rescheds;

    //pthread_attr_t pattr;
    FassLog::log("PM",Log::INFO,"Starting Priority Manager...");

    XMLRPCClient * client = XMLRPCClient::client();

    // XML-RPC Client
    try
    {

        XMLRPCClient::initialize("", one_xmlrpc, message_size, timeout);

        oss.str("");

        oss << "XML-RPC client using " << (XMLRPCClient::client())->get_message_size()
            << " bytes for response buffer.\n";

        FassLog::log("PM", Log::INFO, oss);

    }
    catch(runtime_error &)
    {
        throw;
    }

       // Get oned configuration
        try
        {
            xmlrpc_c::value result;
            vector<xmlrpc_c::value> values;

            client->call("one.system.config", "", &result);

        }
        catch (exception const& e)
        {
            ostringstream oss;

            oss << "Cannot contact oned, will retry... Error: " << e.what();

            FassLog::log("PM", Log::ERROR, oss);
        }

        FassLog::log("PM", Log::INFO, "oned successfully contacted.");

//TODO
//        do_scheduled_actions();

    rc = set_up_pools();

    if ( rc != 0 )
    {
	//ostringstream oss;

        //oss << "Cannot get the VM pool: " << strerror(errno);
        //FassLog::log("PM",Log::ERROR,oss);
        return false;
    }

//TODO
//    match_schedule();

//TODO
//    dispatch();

   do_schedule();

return true;

};

bool PriorityManager::set_up_pools()
{
    int rc;
    XMLRPCClient * client = XMLRPCClient::client();
    // VM pool
    vmpool = new VMPool(client, max_vm, live_rescheds==1);

    //Cleans the cache and gets the VM pool
    rc = vmpool->set_up();

    return 0;
};

void PriorityManager::do_schedule()
{
 VirtualMachine * vm;

    int vm_memory;
    int vm_cpu;

    const map<int, VirtualMachine*> pending_vms = vmpool->get_objects();
    int rc;

 ostringstream oss;

 time_t time_start = time(0);
 time_t time_end   = time(0);

 tm tmp_tm = *localtime(&time_start);

 int start_month;
 int start_year;

 tmp_tm.tm_sec  = 0;
 tmp_tm.tm_min  = 0;
 tmp_tm.tm_hour = 0;
 tmp_tm.tm_mday = 1;
 tmp_tm.tm_mon  = start_month - 1;
 tmp_tm.tm_year = start_year - 1900;
 tmp_tm.tm_isdst = -1; // Unknown daylight saving time

 time_start = mktime(&tmp_tm);

 map<int, VirtualMachine*>::const_iterator  vm_it;

 for (vm_it=pending_vms.begin(); vm_it != pending_vms.end(); vm_it++)
     {
         vm = static_cast<VirtualMachine*>(vm_it->second);

         vm->get_requirements(vm_cpu, vm_memory);
     }

// TODO add float to string funcion for time
        oss << "Statistics:\n"
            << "\tNumber of VMs:            "
            << pending_vms.size() << endl
            << "\tTotal time:               "
            << one_util::float_to_str(time(0) - time_start) << "s" << endl;

        FassLog::log("PM", Log::DDEBUG, oss);

        oss << "Scheduling Results:" << endl;

        for (map<int, VirtualMachine*>::const_iterator vm_it=pending_vms.begin();
            vm_it != pending_vms.end(); vm_it++)
        {
            vm = static_cast<VirtualMachine*>(vm_it->second);

            oss << *vm;
        }

        FassLog::log("PM", Log::DDDEBUG, oss);

// TODO call the plugin basic + save the age from one.vmpool.accounting info

}

/*

void PriorityManager::match_schedule()
{
    VirtualMachineXML * vm;

    int vm_memory;
    int vm_cpu;
    long long vm_disk;
    vector<VectorAttribute *> vm_pci;

    int n_resources;
    int n_matched;
    int n_auth;
    int n_error;
    int n_fits;

    //HostXML * host;
    //DatastoreXML *ds;

    string m_error;

    map<int, ObjectXML*>::const_iterator  vm_it;
    map<int, ObjectXML*>::const_iterator  obj_it;

    vector<SchedulerPolicy *>::iterator it;

    const map<int, ObjectXML*> pending_vms = vmpool->get_objects();
    //const map<int, ObjectXML*> hosts       = hpool->get_objects();
    //const map<int, ObjectXML*> datastores  = dspool->get_objects();
    //const map<int, ObjectXML*> users       = upool->get_objects();

    //double total_cl_match_time = 0;
    //double total_host_match_time = 0;
    //double total_host_rank_time = 0;
    //double total_ds_match_time = 0;
    //double total_ds_rank_time = 0;

    time_t stime = time(0);

    for (vm_it=pending_vms.begin(); vm_it != pending_vms.end(); vm_it++)
    {
        vm = static_cast<VirtualMachineXML*>(vm_it->second);

        vm->get_requirements(vm_cpu, vm_memory, vm_disk, vm_pci);

        n_resources = 0;
        n_fits    = 0;
        n_matched = 0;
        n_auth    = 0;
        n_error   = 0;

    if (FassLog::log_level() >= Log::DDEBUG)
    {
        ostringstream oss;

        oss << "Match Making statistics:\n"
            << "\tNumber of VMs:            "
            << pending_vms.size() << endl
            << "\tTotal time:               "
            << one_util::float_to_str(time(0) - stime) << "s" << endl

        FassLog::log("PM", Log::DDEBUG, oss);
    }

    if (FassLog::log_level() >= Log::DDDEBUG)
    {
        ostringstream oss;

        oss << "Priority Management Results:" << endl;

        for (map<int, ObjectXML*>::const_iterator vm_it=pending_vms.begin();
            vm_it != pending_vms.end(); vm_it++)
        {
            vm = static_cast<VirtualMachineXML*>(vm_it->second);

            oss << *vm;
        }

        FassLog::log("PM", Log::DDDEBUG, oss);
    }
}

*/
/*
void PriorityManager::dispatch()
{
    //HostXML *           host;
    //DatastoreXML *      ds;
    VirtualMachineXML * vm;

    ostringstream dss;
    string        error;

    int cpu, mem;
    long long dsk;
    vector<VectorAttribute *> pci;

    int hid, dsid, cid;

    unsigned int dispatched_vms = 0;
    bool dispatched, matched;
    char * estr;

    map<int, ObjectXML*>::const_iterator vm_it;

    vector<Resource *>::const_reverse_iterator i, j;

    const map<int, ObjectXML*> pending_vms = vmpool->get_objects();

    dss << "Dispatching VMs to hosts:\n" << "\tVMID\tHost\tSystem DS\n"
        << "\t-------------------------\n";

    //--------------------------------------------------------------------------
    // Dispatch each VM till we reach the dispatch limit
    //--------------------------------------------------------------------------

    for (vm_it = pending_vms.begin();
         vm_it != pending_vms.end() &&
            ( dispatch_limit <= 0 || dispatched_vms < dispatch_limit );
         vm_it++)
    {
        dispatched = false;

        vm = static_cast<VirtualMachineXML*>(vm_it->second);

       // const vector<Resource *> resources = vm->get_match_hosts();
*/
/* Let's see what to do with this

int PriorityManager::do_scheduled_actions()
{
    VirtualMachineXML* vm;

    const map<int, ObjectXML*>  vms = vmapool->get_objects();
    map<int, ObjectXML*>::const_iterator vm_it;

    vector<Attribute *> attributes;
    vector<Attribute *>::iterator it;

    VectorAttribute* vatt;

    int action_time;
    int done_time;
    int has_time;
    int has_done;

    string action_st, error_msg;

    time_t the_time = time(0);
    string time_str = one_util::log_time(the_time);

    for (vm_it=vms.begin(); vm_it != vms.end(); vm_it++)
    {
        vm = static_cast<VirtualMachineXML*>(vm_it->second);

        vm->get_actions(attributes);

        // TODO: Sort actions by TIME
        for (it=attributes.begin(); it != attributes.end(); it++)
        {
            vatt = dynamic_cast<VectorAttribute*>(*it);

            if (vatt == 0)
            {
                delete *it;

                continue;
            }

            has_time  = vatt->vector_value("TIME", action_time);
            has_done  = vatt->vector_value("DONE", done_time);
            action_st = vatt->vector_value("ACTION");

            if (has_time == 0 && has_done == -1 && action_time < the_time)
            {
                ostringstream oss;

                int rc = VirtualMachineXML::parse_action_name(action_st);

                oss << "Executing action '" << action_st << "' for VM "
                    << vm->get_oid() << " : ";

                if ( rc != 0 )
                {
                    error_msg = "This action is not supported.";
                }
                else
                {
                    rc = vmapool->action(vm->get_oid(), action_st, error_msg);
                }

                if (rc == 0)
                {
                    vatt->remove("MESSAGE");
                    vatt->replace("DONE", static_cast<int>(the_time));

                    oss << "Success.";
                }
                else
                {
                    ostringstream oss_aux;

                    oss_aux << time_str << " : " << error_msg;

                    vatt->replace("MESSAGE", oss_aux.str());

                    oss << "Failure. " << error_msg;
                }

                NebulaLog::log("VM", Log::INFO, oss);
            }

            vm->set_attribute(vatt);
        }

        vmpool->update(vm);
    }

    return 0;
}
*/
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: toolbox.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 15:00:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef TOOLBOX_HXX
#define TOOLBOX_HXX

#ifndef _BASEDLGS_HXX //autogen
#include <sfx2/basedlgs.hxx>
#endif
#ifndef _SFX_CHILDWIN_HXX //autogen
#include <sfx2/childwin.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif

#ifndef _SMMOD_HXX
#include "smmod.hxx"
#endif
#ifndef CONFIG_HXX
#include "config.hxx"
#endif

#include "dialog.hrc"

#define NUM_TBX_CATEGORIES  9

class SmToolBoxWindow : public SfxFloatingWindow
{

protected:
    ToolBox     aToolBoxCat;
    FixedLine   aToolBoxCat_Delim;  // to visualy seperate the catalog part
    ToolBox    *pToolBoxCmd;
    ToolBox    *vToolBoxCategories[NUM_TBX_CATEGORIES];
    ImageList  *aImageLists [NUM_TBX_CATEGORIES + 1];   /* regular */
    ImageList  *aImageListsH[NUM_TBX_CATEGORIES + 1];   /* high contrast */
    USHORT      nActiveCategoryRID;

    virtual BOOL    Close();
    virtual void    GetFocus();

    void            ApplyImageLists( USHORT nCategoryRID );

    DECL_LINK( CategoryClickHdl, ToolBox* );
    DECL_LINK( CmdSelectHdl, ToolBox* );

    const ImageList * GetImageList( USHORT nResId, BOOL bHighContrast );

public:
    SmToolBoxWindow(SfxBindings    *pBindings,
                    SfxChildWindow *pChildWindow,
                    Window         *pParent);
    ~SmToolBoxWindow();

    // Window
    virtual void    StateChanged( StateChangedType nStateChange );
    virtual void    DataChanged( const DataChangedEvent &rEvt );

    void        AdjustPosSize( BOOL bSetPos );
    void        SetCategory(USHORT nCategory);
};

/**************************************************************************/

class SmToolBoxWrapper : public SfxChildWindow
{
    SFX_DECL_CHILDWINDOW(SmToolBoxWrapper);

protected:
    SmToolBoxWrapper(Window *pParentWindow,
                     USHORT, SfxBindings*, SfxChildWinInfo*);
};

#endif

<commit_msg>INTEGRATION: CWS tl18 (1.9.48); FILE MERGED 2006/01/24 13:02:07 tl 1.9.48.1: #i60111# avoid use of SmGetActiveView(SfxViewShell::Current) as much as possible<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: toolbox.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2006-05-05 07:58:37 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef TOOLBOX_HXX
#define TOOLBOX_HXX

#ifndef _BASEDLGS_HXX //autogen
#include <sfx2/basedlgs.hxx>
#endif
#ifndef _SFX_CHILDWIN_HXX //autogen
#include <sfx2/childwin.hxx>
#endif
#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif

#ifndef _SMMOD_HXX
#include "smmod.hxx"
#endif
#ifndef CONFIG_HXX
#include "config.hxx"
#endif

#include "dialog.hrc"

#define NUM_TBX_CATEGORIES  9

class SmToolBoxWindow : public SfxFloatingWindow
{

protected:
    ToolBox     aToolBoxCat;
    FixedLine   aToolBoxCat_Delim;  // to visualy seperate the catalog part
    ToolBox    *pToolBoxCmd;
    ToolBox    *vToolBoxCategories[NUM_TBX_CATEGORIES];
    ImageList  *aImageLists [NUM_TBX_CATEGORIES + 1];   /* regular */
    ImageList  *aImageListsH[NUM_TBX_CATEGORIES + 1];   /* high contrast */
    USHORT      nActiveCategoryRID;

    virtual BOOL    Close();
    virtual void    GetFocus();

    void            ApplyImageLists( USHORT nCategoryRID );

    DECL_LINK( CategoryClickHdl, ToolBox* );
    DECL_LINK( CmdSelectHdl, ToolBox* );

    SmViewShell * GetView();
    const ImageList * GetImageList( USHORT nResId, BOOL bHighContrast );

public:
    SmToolBoxWindow(SfxBindings    *pBindings,
                    SfxChildWindow *pChildWindow,
                    Window         *pParent);
    ~SmToolBoxWindow();

    // Window
    virtual void    StateChanged( StateChangedType nStateChange );
    virtual void    DataChanged( const DataChangedEvent &rEvt );

    void        AdjustPosSize( BOOL bSetPos );
    void        SetCategory(USHORT nCategory);
};

/**************************************************************************/

class SmToolBoxWrapper : public SfxChildWindow
{
    SFX_DECL_CHILDWINDOW(SmToolBoxWrapper);

protected:
    SmToolBoxWrapper(Window *pParentWindow,
                     USHORT, SfxBindings*, SfxChildWinInfo*);
};

#endif

<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs        */
/*                                                                            */
/* Licensed 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.                                             */
/* -------------------------------------------------------------------------- */

#include "PoolObjectSQL.h"
#include "PoolObjectAuth.h"
#include "SSLTools.h"
#include "Nebula.h"
#include "Clusterable.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& PoolObjectSQL::to_xml64(string &xml64)
{
    string *str64;

    to_xml(xml64);

    str64 = SSLTools::base64_encode(xml64);

    xml64 = *str64;

    delete str64;

    return xml64;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::select(SqlDB *db)
{
    ostringstream   oss;
    int             rc;
    int             boid;

    set_callback(
            static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));

    oss << "SELECT body FROM " << table << " WHERE oid = " << oid;

    boid = oid;
    oid  = -1;

    rc = db->exec(oss, this);

    unset_callback();

    if ((rc != 0) || (oid != boid ))
    {
        return -1;
    }

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::select(SqlDB *db, const string& _name, int _uid)
{
    ostringstream oss;

    int rc;
    char * sql_name;

    sql_name = db->escape_str(_name.c_str());

    if ( sql_name == 0 )
    {
        return -1;
    }

    set_callback(
            static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));

    oss << "SELECT body FROM " << table << " WHERE name = '" << sql_name << "'";

    if ( _uid != -1 )
    {
        oss << " AND uid = " << _uid;
    }

    name  = "";
    uid   = -1;

    rc = db->exec(oss, this);

    unset_callback();

    db->free_str(sql_name);

    if ((rc != 0) || (_name != name) || (_uid != -1 && _uid != uid))
    {
        return -1;
    }

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::drop(SqlDB *db)
{
    ostringstream oss;
    int rc;

    oss << "DELETE FROM " << table << " WHERE oid=" << oid;

    rc = db->exec(oss);

    if ( rc == 0 )
    {
        set_valid(false);
    }

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const char * PoolObjectSQL::error_attribute_name = "ERROR";

void PoolObjectSQL::set_template_error_message(const string& message)
{
    VectorAttribute *  attr;
    map<string,string> error_value;

    char   str[26];
    time_t the_time;

    the_time = time(NULL);

#ifdef SOLARIS
    ctime_r(&(the_time),str,sizeof(char)*26);
#else
    ctime_r(&(the_time),str);
#endif

    str[24] = '\0'; // Get rid of final enter character

    error_value.insert(make_pair("TIMESTAMP",str));
    error_value.insert(make_pair("MESSAGE",message));

    //Replace previous error message and insert the new one

    attr = new VectorAttribute(error_attribute_name,error_value);

    obj_template->erase(error_attribute_name);
    obj_template->set(attr);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::replace_template(const string& tmpl_str, string& error)
{
    Template * new_tmpl  = get_new_template();

    if ( new_tmpl == 0 )
    {
        error = "Cannot allocate a new template";
        return -1;
    }

    if ( new_tmpl->parse_str_or_xml(tmpl_str, error) != 0 )
    {
        delete new_tmpl;
        return -1;
    }

    if ( obj_template != 0 )
    {
        delete obj_template;
    }

    obj_template = new_tmpl;

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& PoolObjectSQL::perms_to_xml(string& xml) const
{
    ostringstream   oss;

    oss <<
        "<PERMISSIONS>" <<
            "<OWNER_U>" << owner_u << "</OWNER_U>"  <<
            "<OWNER_M>" << owner_m << "</OWNER_M>"  <<
            "<OWNER_A>" << owner_a << "</OWNER_A>"  <<
            "<GROUP_U>" << group_u << "</GROUP_U>"  <<
            "<GROUP_M>" << group_m << "</GROUP_M>"  <<
            "<GROUP_A>" << group_a << "</GROUP_A>"  <<
            "<OTHER_U>" << other_u << "</OTHER_U>"  <<
            "<OTHER_M>" << other_m << "</OTHER_M>"  <<
            "<OTHER_A>" << other_a << "</OTHER_A>"  <<
        "</PERMISSIONS>";

    xml = oss.str();
    return xml;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::perms_from_xml()
{
    int rc = 0;

    rc += xpath(owner_u, "/*/PERMISSIONS/OWNER_U", 0);
    rc += xpath(owner_m, "/*/PERMISSIONS/OWNER_M", 0);
    rc += xpath(owner_a, "/*/PERMISSIONS/OWNER_A", 0);

    rc += xpath(group_u, "/*/PERMISSIONS/GROUP_U", 0);
    rc += xpath(group_m, "/*/PERMISSIONS/GROUP_M", 0);
    rc += xpath(group_a, "/*/PERMISSIONS/GROUP_A", 0);

    rc += xpath(other_u, "/*/PERMISSIONS/OTHER_U", 0);
    rc += xpath(other_m, "/*/PERMISSIONS/OTHER_M", 0);
    rc += xpath(other_a, "/*/PERMISSIONS/OTHER_A", 0);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void PoolObjectSQL::get_permissions(PoolObjectAuth& auth)
{
    auth.obj_type = obj_type;

    auth.oid = oid;
    auth.uid = uid;
    auth.gid = gid;

    auth.owner_u = owner_u;
    auth.owner_m = owner_m;
    auth.owner_a = owner_a;

    auth.group_u = group_u;
    auth.group_m = group_m;
    auth.group_a = group_a;

    auth.other_u = other_u;
    auth.other_m = other_m;
    auth.other_a = other_a;

    Clusterable* cl = dynamic_cast<Clusterable*>(this);

    if(cl != 0)
    {
        auth.cid = cl->get_cluster_id();
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::set_permissions( int _owner_u,
                                    int _owner_m,
                                    int _owner_a,
                                    int _group_u,
                                    int _group_m,
                                    int _group_a,
                                    int _other_u,
                                    int _other_m,
                                    int _other_a,
                                    string& error_str)
{
    if ( _owner_u < -1 || _owner_u > 1 ) goto error_value;
    if ( _owner_m < -1 || _owner_m > 1 ) goto error_value;
    if ( _owner_a < -1 || _owner_a > 1 ) goto error_value;
    if ( _group_u < -1 || _group_u > 1 ) goto error_value;
    if ( _group_m < -1 || _group_m > 1 ) goto error_value;
    if ( _group_a < -1 || _group_a > 1 ) goto error_value;
    if ( _other_u < -1 || _other_u > 1 ) goto error_value;
    if ( _other_m < -1 || _other_m > 1 ) goto error_value;
    if ( _other_a < -1 || _other_a > 1 ) goto error_value;

    set_perm(owner_u, _owner_u);
    set_perm(owner_m, _owner_m);
    set_perm(owner_a, _owner_a);
    set_perm(group_u, _group_u);
    set_perm(group_m, _group_m);
    set_perm(group_a, _group_a);
    set_perm(other_u, _other_u);
    set_perm(other_m, _other_m);
    set_perm(other_a, _other_a);

    return 0;

error_value:
    error_str = "New permission values must be -1, 0 or 1";
    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void PoolObjectSQL::set_umask(int umask)
{
    int perms;
    bool enable_other;

    Nebula::instance().get_configuration_attribute(
            "ENABLE_OTHER_PERMISSIONS", enable_other);

    if (uid == 0 || gid == 0)
    {
        perms = 0777;
    }
    else if (enable_other)
    {
        perms = 0666;
    }
    else
    {
        perms = 0660;
    }

    perms = perms & ~umask;

    owner_u = ( (perms & 0400) != 0 ) ? 1 : 0;
    owner_m = ( (perms & 0200) != 0 ) ? 1 : 0;
    owner_a = ( (perms & 0100) != 0 ) ? 1 : 0;
    group_u = ( (perms & 0040) != 0 ) ? 1 : 0;
    group_m = ( (perms & 0020) != 0 ) ? 1 : 0;
    group_a = ( (perms & 0010) != 0 ) ? 1 : 0;
    other_u = ( (perms & 0004) != 0 ) ? 1 : 0;
    other_m = ( (perms & 0002) != 0 ) ? 1 : 0;
    other_a = ( (perms & 0001) != 0 ) ? 1 : 0;

}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
<commit_msg>feature #1664: Error messages as single attribute in templates (cherry picked from commit 03f77697c4a1fd996e260974b53e1e6daa44a494)<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs        */
/*                                                                            */
/* Licensed 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.                                             */
/* -------------------------------------------------------------------------- */

#include "PoolObjectSQL.h"
#include "PoolObjectAuth.h"
#include "SSLTools.h"
#include "Nebula.h"
#include "Clusterable.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& PoolObjectSQL::to_xml64(string &xml64)
{
    string *str64;

    to_xml(xml64);

    str64 = SSLTools::base64_encode(xml64);

    xml64 = *str64;

    delete str64;

    return xml64;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::select(SqlDB *db)
{
    ostringstream   oss;
    int             rc;
    int             boid;

    set_callback(
            static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));

    oss << "SELECT body FROM " << table << " WHERE oid = " << oid;

    boid = oid;
    oid  = -1;

    rc = db->exec(oss, this);

    unset_callback();

    if ((rc != 0) || (oid != boid ))
    {
        return -1;
    }

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::select(SqlDB *db, const string& _name, int _uid)
{
    ostringstream oss;

    int rc;
    char * sql_name;

    sql_name = db->escape_str(_name.c_str());

    if ( sql_name == 0 )
    {
        return -1;
    }

    set_callback(
            static_cast<Callbackable::Callback>(&PoolObjectSQL::select_cb));

    oss << "SELECT body FROM " << table << " WHERE name = '" << sql_name << "'";

    if ( _uid != -1 )
    {
        oss << " AND uid = " << _uid;
    }

    name  = "";
    uid   = -1;

    rc = db->exec(oss, this);

    unset_callback();

    db->free_str(sql_name);

    if ((rc != 0) || (_name != name) || (_uid != -1 && _uid != uid))
    {
        return -1;
    }

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::drop(SqlDB *db)
{
    ostringstream oss;
    int rc;

    oss << "DELETE FROM " << table << " WHERE oid=" << oid;

    rc = db->exec(oss);

    if ( rc == 0 )
    {
        set_valid(false);
    }

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const char * PoolObjectSQL::error_attribute_name = "ERROR";

void PoolObjectSQL::set_template_error_message(const string& message)
{
    SingleAttribute * attr;
    ostringstream     error_value;

    char   str[26];
    time_t the_time;

    the_time = time(NULL);

#ifdef SOLARIS
    ctime_r(&(the_time),str,sizeof(char)*26);
#else
    ctime_r(&(the_time),str);
#endif

    str[24] = '\0'; // Get rid of final enter character

    error_value << str << " : " << message;

    //Replace previous error message and insert the new one

    attr = new SingleAttribute(error_attribute_name, error_value.str());

    obj_template->erase(error_attribute_name);
    obj_template->set(attr);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::replace_template(const string& tmpl_str, string& error)
{
    Template * new_tmpl  = get_new_template();

    if ( new_tmpl == 0 )
    {
        error = "Cannot allocate a new template";
        return -1;
    }

    if ( new_tmpl->parse_str_or_xml(tmpl_str, error) != 0 )
    {
        delete new_tmpl;
        return -1;
    }

    if ( obj_template != 0 )
    {
        delete obj_template;
    }

    obj_template = new_tmpl;

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& PoolObjectSQL::perms_to_xml(string& xml) const
{
    ostringstream   oss;

    oss <<
        "<PERMISSIONS>" <<
            "<OWNER_U>" << owner_u << "</OWNER_U>"  <<
            "<OWNER_M>" << owner_m << "</OWNER_M>"  <<
            "<OWNER_A>" << owner_a << "</OWNER_A>"  <<
            "<GROUP_U>" << group_u << "</GROUP_U>"  <<
            "<GROUP_M>" << group_m << "</GROUP_M>"  <<
            "<GROUP_A>" << group_a << "</GROUP_A>"  <<
            "<OTHER_U>" << other_u << "</OTHER_U>"  <<
            "<OTHER_M>" << other_m << "</OTHER_M>"  <<
            "<OTHER_A>" << other_a << "</OTHER_A>"  <<
        "</PERMISSIONS>";

    xml = oss.str();
    return xml;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::perms_from_xml()
{
    int rc = 0;

    rc += xpath(owner_u, "/*/PERMISSIONS/OWNER_U", 0);
    rc += xpath(owner_m, "/*/PERMISSIONS/OWNER_M", 0);
    rc += xpath(owner_a, "/*/PERMISSIONS/OWNER_A", 0);

    rc += xpath(group_u, "/*/PERMISSIONS/GROUP_U", 0);
    rc += xpath(group_m, "/*/PERMISSIONS/GROUP_M", 0);
    rc += xpath(group_a, "/*/PERMISSIONS/GROUP_A", 0);

    rc += xpath(other_u, "/*/PERMISSIONS/OTHER_U", 0);
    rc += xpath(other_m, "/*/PERMISSIONS/OTHER_M", 0);
    rc += xpath(other_a, "/*/PERMISSIONS/OTHER_A", 0);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void PoolObjectSQL::get_permissions(PoolObjectAuth& auth)
{
    auth.obj_type = obj_type;

    auth.oid = oid;
    auth.uid = uid;
    auth.gid = gid;

    auth.owner_u = owner_u;
    auth.owner_m = owner_m;
    auth.owner_a = owner_a;

    auth.group_u = group_u;
    auth.group_m = group_m;
    auth.group_a = group_a;

    auth.other_u = other_u;
    auth.other_m = other_m;
    auth.other_a = other_a;

    Clusterable* cl = dynamic_cast<Clusterable*>(this);

    if(cl != 0)
    {
        auth.cid = cl->get_cluster_id();
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int PoolObjectSQL::set_permissions( int _owner_u,
                                    int _owner_m,
                                    int _owner_a,
                                    int _group_u,
                                    int _group_m,
                                    int _group_a,
                                    int _other_u,
                                    int _other_m,
                                    int _other_a,
                                    string& error_str)
{
    if ( _owner_u < -1 || _owner_u > 1 ) goto error_value;
    if ( _owner_m < -1 || _owner_m > 1 ) goto error_value;
    if ( _owner_a < -1 || _owner_a > 1 ) goto error_value;
    if ( _group_u < -1 || _group_u > 1 ) goto error_value;
    if ( _group_m < -1 || _group_m > 1 ) goto error_value;
    if ( _group_a < -1 || _group_a > 1 ) goto error_value;
    if ( _other_u < -1 || _other_u > 1 ) goto error_value;
    if ( _other_m < -1 || _other_m > 1 ) goto error_value;
    if ( _other_a < -1 || _other_a > 1 ) goto error_value;

    set_perm(owner_u, _owner_u);
    set_perm(owner_m, _owner_m);
    set_perm(owner_a, _owner_a);
    set_perm(group_u, _group_u);
    set_perm(group_m, _group_m);
    set_perm(group_a, _group_a);
    set_perm(other_u, _other_u);
    set_perm(other_m, _other_m);
    set_perm(other_a, _other_a);

    return 0;

error_value:
    error_str = "New permission values must be -1, 0 or 1";
    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void PoolObjectSQL::set_umask(int umask)
{
    int perms;
    bool enable_other;

    Nebula::instance().get_configuration_attribute(
            "ENABLE_OTHER_PERMISSIONS", enable_other);

    if (uid == 0 || gid == 0)
    {
        perms = 0777;
    }
    else if (enable_other)
    {
        perms = 0666;
    }
    else
    {
        perms = 0660;
    }

    perms = perms & ~umask;

    owner_u = ( (perms & 0400) != 0 ) ? 1 : 0;
    owner_m = ( (perms & 0200) != 0 ) ? 1 : 0;
    owner_a = ( (perms & 0100) != 0 ) ? 1 : 0;
    group_u = ( (perms & 0040) != 0 ) ? 1 : 0;
    group_m = ( (perms & 0020) != 0 ) ? 1 : 0;
    group_a = ( (perms & 0010) != 0 ) ? 1 : 0;
    other_u = ( (perms & 0004) != 0 ) ? 1 : 0;
    other_m = ( (perms & 0002) != 0 ) ? 1 : 0;
    other_a = ( (perms & 0001) != 0 ) ? 1 : 0;

}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
<|endoftext|>


<commit_before>// Original Author: Brian Bockelman

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "ZipLZ4.h"
#include "lz4.h"
#include "lz4hc.h"
#include <stdio.h>
#include <cinttypes>
#include <cstdint>
#include <cstring>

#include "RConfig.h"

// Pulled from liblz4; upstream library explicitly exposes the symbol but the default build
// excludes the header.
typedef unsigned long long XXH64_hash_t;
typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
extern "C" XXH64_hash_t LZ4_XXH64(const void* input, size_t length, unsigned long long seed);
extern "C" void LZ4_XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
extern "C" XXH64_hash_t LZ4_XXH64_hashFromCanonical(const XXH64_canonical_t* src);

// Header consists of:
// - 2 byte identifier "L4"
// - 1 byte LZ4 version string.
// - 3 bytes of uncompressed size
// - 3 bytes of compressed size
// - 8 byte checksum using xxhash 64.
static const int kChecksumOffset = 2 + 1 + 3 + 3;
static const int kChecksumSize = sizeof(XXH64_canonical_t);
static const int kHeaderSize = kChecksumOffset + kChecksumSize;

void R__zipLZ4(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep)
{
   int LZ4_version = LZ4_versionNumber();
   uint64_t out_size; /* compressed size */
   uint64_t in_size = (unsigned)(*srcsize);

   *irep = 0;

   if (R__unlikely(*tgtsize <= 0)) {
      return;
   }

   // Refuse to compress more than 16MB at a time -- we are only allowed 3 bytes for size info.
   if (R__unlikely(*srcsize > 0xffffff || *srcsize < 0)) {
      return;
   }

   int returnStatus;
   if (cxlevel > 9) {
      cxlevel = 9;
   }
   if (cxlevel >= 4) {
      returnStatus = LZ4_compress_HC(src, &tgt[kHeaderSize], *srcsize, *tgtsize - kHeaderSize, cxlevel);
   } else {
      returnStatus = LZ4_compress_default(src, &tgt[kHeaderSize], *srcsize, *tgtsize - kHeaderSize);
   }

   if (R__unlikely(returnStatus == 0)) { /* LZ4 compression failed */
      return;
   }
   XXH64_hash_t checksumResult = LZ4_XXH64(tgt + kHeaderSize, returnStatus, 0);

   tgt[0] = 'L';
   tgt[1] = '4';
   tgt[2] = (LZ4_version / (100 * 100));

   out_size = returnStatus + kChecksumSize; /* compressed size, including the checksum. */

   // NOTE: these next 6 bytes are required from the ROOT compressed buffer format;
   // upper layers will assume they are laid out in a specific manner.
   tgt[3] = (char)(out_size & 0xff);
   tgt[4] = (char)((out_size >> 8) & 0xff);
   tgt[5] = (char)((out_size >> 16) & 0xff);

   tgt[6] = (char)(in_size & 0xff); /* decompressed size */
   tgt[7] = (char)((in_size >> 8) & 0xff);
   tgt[8] = (char)((in_size >> 16) & 0xff);

   // Write out checksum.
   LZ4_XXH64_canonicalFromHash(reinterpret_cast<XXH64_canonical_t*>(tgt + kChecksumOffset), checksumResult);

   *irep = (int)returnStatus + kHeaderSize;
}

void R__unzipLZ4(int *srcsize, unsigned char *src, int *tgtsize, unsigned char *tgt, int *irep)
{
   // NOTE: We don't check that srcsize / tgtsize is reasonable or within the ROOT-imposed limits.
   // This is assumed to be handled by the upper layers.

   int LZ4_version = LZ4_versionNumber() / (100 * 100);
   *irep = 0;
   if (R__unlikely(src[0] != 'L' || src[1] != '4')) {
      fprintf(stderr, "R__unzipLZ4: algorithm run against buffer with incorrect header (got %d%d; expected %d%d).\n",
              src[0], src[1], 'L', '4');
      return;
   }
   if (R__unlikely(src[2] != LZ4_version)) {
      fprintf(stderr,
              "R__unzipLZ4: This version of LZ4 is incompatible with the on-disk version (got %d; expected %d).\n",
              src[2], LZ4_version);
      return;
   }

   int inputBufferSize = *srcsize - kHeaderSize;

   // TODO: The checksum followed by the decompression means we iterate through the buffer twice.
   // We should perform some performance tests to see whether we can interleave the two -- i.e., at
   // what size of chunks does interleaving (avoiding two fetches from RAM) improve enough for the
   // extra function call costs?  NOTE that ROOT limits the buffer size to 16MB.
   XXH64_hash_t checksumResult = LZ4_XXH64(src + kHeaderSize, inputBufferSize, 0);

   XXH64_hash_t checksumFromFile = LZ4_XXH64_hashFromCanonical(reinterpret_cast<XXH64_canonical_t*>(src + kChecksumOffset));
   if (R__unlikely(checksumFromFile != checksumResult)) {
      fprintf(stderr,
              "R__unzipLZ4: Buffer corruption error!  Calculated checksum %llu; checksum calculated in the file was %llu.\n",
              checksumResult, checksumFromFile);
      return;
   }
   int returnStatus = LZ4_decompress_safe((char *)(&src[kHeaderSize]), (char *)(tgt), inputBufferSize, *tgtsize);
   if (R__unlikely(returnStatus < 0)) {
      fprintf(stderr, "R__unzipLZ4: error in decompression around byte %d out of maximum %d.\n", -returnStatus,
              *tgtsize);
      return;
   }

   *irep = returnStatus;
}
<commit_msg>Adding in addition to LZ4-builtin hxxhash, support to pure xxhash API for builtin_lzma=OFF case<commit_after>// Original Author: Brian Bockelman

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "ZipLZ4.h"
#include "lz4.h"
#include "lz4hc.h"
#include <stdio.h>
#include <cinttypes>
#include <cstdint>
#include <cstring>

#include "RConfig.h"

// Pulled from liblz4; upstream library explicitly exposes the symbol but the default build
// excludes the header.
typedef unsigned long long XXH64_hash_t;
typedef struct {
   unsigned char digest[8];
} XXH64_canonical_t;

#ifdef BUILTIN_LZ4
#define XXH64 LZ4_XXH64
#define XXH64_canonicalFromHash LZ4_XXH64_canonicalFromHash
#define XXH64_hashFromCanonical LZ4_XXH64_hashFromCanonical
#endif

extern "C" XXH64_hash_t XXH64(const void *input, size_t length, unsigned long long seed);
extern "C" void XXH64_canonicalFromHash(XXH64_canonical_t *dst, XXH64_hash_t hash);
extern "C" XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t *src);

// Header consists of:
// - 2 byte identifier "L4"
// - 1 byte LZ4 version string.
// - 3 bytes of uncompressed size
// - 3 bytes of compressed size
// - 8 byte checksum using xxhash 64.
static const int kChecksumOffset = 2 + 1 + 3 + 3;
static const int kChecksumSize = sizeof(XXH64_canonical_t);
static const int kHeaderSize = kChecksumOffset + kChecksumSize;

void R__zipLZ4(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep)
{
   int LZ4_version = LZ4_versionNumber();
   uint64_t out_size; /* compressed size */
   uint64_t in_size = (unsigned)(*srcsize);

   *irep = 0;

   if (R__unlikely(*tgtsize <= 0)) {
      return;
   }

   // Refuse to compress more than 16MB at a time -- we are only allowed 3 bytes for size info.
   if (R__unlikely(*srcsize > 0xffffff || *srcsize < 0)) {
      return;
   }

   int returnStatus;
   if (cxlevel > 9) {
      cxlevel = 9;
   }
   if (cxlevel >= 4) {
      returnStatus = LZ4_compress_HC(src, &tgt[kHeaderSize], *srcsize, *tgtsize - kHeaderSize, cxlevel);
   } else {
      returnStatus = LZ4_compress_default(src, &tgt[kHeaderSize], *srcsize, *tgtsize - kHeaderSize);
   }

   if (R__unlikely(returnStatus == 0)) { /* LZ4 compression failed */
      return;
   }
   XXH64_hash_t checksumResult = XXH64(tgt + kHeaderSize, returnStatus, 0);

   tgt[0] = 'L';
   tgt[1] = '4';
   tgt[2] = (LZ4_version / (100 * 100));

   out_size = returnStatus + kChecksumSize; /* compressed size, including the checksum. */

   // NOTE: these next 6 bytes are required from the ROOT compressed buffer format;
   // upper layers will assume they are laid out in a specific manner.
   tgt[3] = (char)(out_size & 0xff);
   tgt[4] = (char)((out_size >> 8) & 0xff);
   tgt[5] = (char)((out_size >> 16) & 0xff);

   tgt[6] = (char)(in_size & 0xff); /* decompressed size */
   tgt[7] = (char)((in_size >> 8) & 0xff);
   tgt[8] = (char)((in_size >> 16) & 0xff);

   // Write out checksum.
   XXH64_canonicalFromHash(reinterpret_cast<XXH64_canonical_t *>(tgt + kChecksumOffset), checksumResult);

   *irep = (int)returnStatus + kHeaderSize;
}

void R__unzipLZ4(int *srcsize, unsigned char *src, int *tgtsize, unsigned char *tgt, int *irep)
{
   // NOTE: We don't check that srcsize / tgtsize is reasonable or within the ROOT-imposed limits.
   // This is assumed to be handled by the upper layers.

   int LZ4_version = LZ4_versionNumber() / (100 * 100);
   *irep = 0;
   if (R__unlikely(src[0] != 'L' || src[1] != '4')) {
      fprintf(stderr, "R__unzipLZ4: algorithm run against buffer with incorrect header (got %d%d; expected %d%d).\n",
              src[0], src[1], 'L', '4');
      return;
   }
   if (R__unlikely(src[2] != LZ4_version)) {
      fprintf(stderr,
              "R__unzipLZ4: This version of LZ4 is incompatible with the on-disk version (got %d; expected %d).\n",
              src[2], LZ4_version);
      return;
   }

   int inputBufferSize = *srcsize - kHeaderSize;

   // TODO: The checksum followed by the decompression means we iterate through the buffer twice.
   // We should perform some performance tests to see whether we can interleave the two -- i.e., at
   // what size of chunks does interleaving (avoiding two fetches from RAM) improve enough for the
   // extra function call costs?  NOTE that ROOT limits the buffer size to 16MB.
   XXH64_hash_t checksumResult = XXH64(src + kHeaderSize, inputBufferSize, 0);
   XXH64_hash_t checksumFromFile =
      XXH64_hashFromCanonical(reinterpret_cast<XXH64_canonical_t *>(src + kChecksumOffset));

   if (R__unlikely(checksumFromFile != checksumResult)) {
      fprintf(
         stderr,
         "R__unzipLZ4: Buffer corruption error!  Calculated checksum %llu; checksum calculated in the file was %llu.\n",
         checksumResult, checksumFromFile);
      return;
   }
   int returnStatus = LZ4_decompress_safe((char *)(&src[kHeaderSize]), (char *)(tgt), inputBufferSize, *tgtsize);
   if (R__unlikely(returnStatus < 0)) {
      fprintf(stderr, "R__unzipLZ4: error in decompression around byte %d out of maximum %d.\n", -returnStatus,
              *tgtsize);
      return;
   }

   *irep = returnStatus;
}
<|endoftext|>