/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef nsXPCOMPrivate_h__
#define nsXPCOMPrivate_h__

#include "nscore.h"
#include "nsXPCOM.h"
#include "nsXPCOMStrings.h"
#include "xptcall.h"

class nsStringContainer;
class nsCStringContainer;
class nsPurpleBufferEntry;

/**
 * During this shutdown notification all threads which run XPCOM code must
 * be joined.
 */
#define NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID "xpcom-shutdown-threads"

/**
 * During this shutdown notification all module loaders must unload XPCOM
 * modules.
 */
#define NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID "xpcom-shutdown-loaders"

// PUBLIC
typedef nsresult   (*InitFunc)(nsIServiceManager** aResult,
                               nsIFile* aBinDirectory,
                               nsIDirectoryServiceProvider* aAppFileLocationProvider);
typedef nsresult   (*ShutdownFunc)(nsIServiceManager* aServMgr);
typedef nsresult   (*GetServiceManagerFunc)(nsIServiceManager** aResult);
typedef nsresult   (*GetComponentManagerFunc)(nsIComponentManager** aResult);
typedef nsresult   (*GetComponentRegistrarFunc)(nsIComponentRegistrar** aResult);
typedef nsresult   (*GetMemoryManagerFunc)(nsIMemory** aResult);
typedef nsresult   (*NewLocalFileFunc)(const nsAString& aPath,
                                       bool aFollowLinks, nsIFile** aResult);
typedef nsresult   (*NewNativeLocalFileFunc)(const nsACString& aPath,
                                             bool aFollowLinks,
                                             nsIFile** aResult);

typedef nsresult   (*GetDebugFunc)(nsIDebug2** aResult);

typedef nsresult   (*StringContainerInitFunc)(nsStringContainer&);
typedef nsresult   (*StringContainerInit2Func)(nsStringContainer&,
                                               const char16_t*,
                                               uint32_t, uint32_t);
typedef void       (*StringContainerFinishFunc)(nsStringContainer&);
typedef uint32_t   (*StringGetDataFunc)(const nsAString&, const char16_t**,
                                        bool*);
typedef uint32_t   (*StringGetMutableDataFunc)(nsAString&, uint32_t,
                                               char16_t**);
typedef char16_t*  (*StringCloneDataFunc)(const nsAString&);
typedef nsresult   (*StringSetDataFunc)(nsAString&, const char16_t*, uint32_t);
typedef nsresult   (*StringSetDataRangeFunc)(nsAString&, uint32_t, uint32_t,
                                             const char16_t*, uint32_t);
typedef nsresult   (*StringCopyFunc)(nsAString&, const nsAString&);
typedef void       (*StringSetIsVoidFunc)(nsAString&, const bool);
typedef bool       (*StringGetIsVoidFunc)(const nsAString&);

typedef nsresult   (*CStringContainerInitFunc)(nsCStringContainer&);
typedef nsresult   (*CStringContainerInit2Func)(nsCStringContainer&,
                                                const char*,
                                                uint32_t, uint32_t);
typedef void       (*CStringContainerFinishFunc)(nsCStringContainer&);
typedef uint32_t   (*CStringGetDataFunc)(const nsACString&, const char**,
                                         bool*);
typedef uint32_t   (*CStringGetMutableDataFunc)(nsACString&, uint32_t, char**);
typedef char*      (*CStringCloneDataFunc)(const nsACString&);
typedef nsresult   (*CStringSetDataFunc)(nsACString&, const char*, uint32_t);
typedef nsresult   (*CStringSetDataRangeFunc)(nsACString&, uint32_t, uint32_t,
                                              const char*, uint32_t);
typedef nsresult   (*CStringCopyFunc)(nsACString&, const nsACString&);
typedef void       (*CStringSetIsVoidFunc)(nsACString&, const bool);
typedef bool       (*CStringGetIsVoidFunc)(const nsACString&);

typedef nsresult   (*CStringToUTF16)(const nsACString&, nsCStringEncoding,
                                     nsAString&);
typedef nsresult   (*UTF16ToCString)(const nsAString&, nsCStringEncoding,
                                     nsACString&);

typedef void*      (*AllocFunc)(size_t aSize);
typedef void*      (*ReallocFunc)(void* aPtr, size_t aSize);
typedef void       (*FreeFunc)(void* aPtr);

typedef void       (*DebugBreakFunc)(uint32_t aSeverity,
                                     const char* aStr, const char* aExpr,
                                     const char* aFile, int32_t aLine);

typedef void       (*xpcomVoidFunc)();
typedef void       (*LogAddRefFunc)(void*, nsrefcnt, const char*, uint32_t);
typedef void       (*LogReleaseFunc)(void*, nsrefcnt, const char*);
typedef void       (*LogCtorFunc)(void*, const char*, uint32_t);
typedef void       (*LogCOMPtrFunc)(void*, nsISupports*);

typedef nsresult   (*GetXPTCallStubFunc)(REFNSIID, nsIXPTCProxy*,
                                         nsISomeInterface**);
typedef void       (*DestroyXPTCallStubFunc)(nsISomeInterface*);
typedef nsresult   (*InvokeByIndexFunc)(nsISupports*, uint32_t, uint32_t,
                                        nsXPTCVariant*);
typedef bool       (*CycleCollectorFunc)(nsISupports*);
typedef nsPurpleBufferEntry*
                   (*CycleCollectorSuspect2Func)(void*,
                                                 nsCycleCollectionParticipant*);
typedef bool       (*CycleCollectorForget2Func)(nsPurpleBufferEntry*);
typedef void       (*CycleCollectorSuspect3Func)(void*,
                                                 nsCycleCollectionParticipant*,
                                                 nsCycleCollectingAutoRefCnt*,
                                                 bool*);
// PRIVATE AND DEPRECATED
typedef NS_CALLBACK(XPCOMExitRoutine)(void);

typedef nsresult   (*RegisterXPCOMExitRoutineFunc)(XPCOMExitRoutine aExitRoutine,
                                                   uint32_t aPriority);
typedef nsresult   (*UnregisterXPCOMExitRoutineFunc)(XPCOMExitRoutine aExitRoutine);

typedef struct XPCOMFunctions
{
  uint32_t version;
  uint32_t size;

  InitFunc init;
  ShutdownFunc shutdown;
  GetServiceManagerFunc getServiceManager;
  GetComponentManagerFunc getComponentManager;
  GetComponentRegistrarFunc getComponentRegistrar;
  GetMemoryManagerFunc getMemoryManager;
  NewLocalFileFunc newLocalFile;
  NewNativeLocalFileFunc newNativeLocalFile;

  RegisterXPCOMExitRoutineFunc registerExitRoutine;
  UnregisterXPCOMExitRoutineFunc unregisterExitRoutine;

  // Added for Mozilla 1.5
  GetDebugFunc getDebug;
  void* getTraceRefcnt;

  // Added for Mozilla 1.7
  StringContainerInitFunc stringContainerInit;
  StringContainerFinishFunc stringContainerFinish;
  StringGetDataFunc stringGetData;
  StringSetDataFunc stringSetData;
  StringSetDataRangeFunc stringSetDataRange;
  StringCopyFunc stringCopy;
  CStringContainerInitFunc cstringContainerInit;
  CStringContainerFinishFunc cstringContainerFinish;
  CStringGetDataFunc cstringGetData;
  CStringSetDataFunc cstringSetData;
  CStringSetDataRangeFunc cstringSetDataRange;
  CStringCopyFunc cstringCopy;
  CStringToUTF16 cstringToUTF16;
  UTF16ToCString utf16ToCString;
  StringCloneDataFunc stringCloneData;
  CStringCloneDataFunc cstringCloneData;

  // Added for Mozilla 1.8
  AllocFunc allocFunc;
  ReallocFunc reallocFunc;
  FreeFunc freeFunc;
  StringContainerInit2Func stringContainerInit2;
  CStringContainerInit2Func cstringContainerInit2;
  StringGetMutableDataFunc stringGetMutableData;
  CStringGetMutableDataFunc cstringGetMutableData;
  void* init3; // obsolete

  // Added for Mozilla 1.9
  DebugBreakFunc debugBreakFunc;
  xpcomVoidFunc logInitFunc;
  xpcomVoidFunc logTermFunc;
  LogAddRefFunc logAddRefFunc;
  LogReleaseFunc logReleaseFunc;
  LogCtorFunc logCtorFunc;
  LogCtorFunc logDtorFunc;
  LogCOMPtrFunc logCOMPtrAddRefFunc;
  LogCOMPtrFunc logCOMPtrReleaseFunc;
  GetXPTCallStubFunc getXPTCallStubFunc;
  DestroyXPTCallStubFunc destroyXPTCallStubFunc;
  InvokeByIndexFunc invokeByIndexFunc;
  CycleCollectorFunc cycleSuspectFunc; // obsolete: use cycleSuspect3Func
  CycleCollectorFunc cycleForgetFunc; // obsolete
  StringSetIsVoidFunc stringSetIsVoid;
  StringGetIsVoidFunc stringGetIsVoid;
  CStringSetIsVoidFunc cstringSetIsVoid;
  CStringGetIsVoidFunc cstringGetIsVoid;

  // Added for Mozilla 1.9.1
  CycleCollectorSuspect2Func cycleSuspect2Func; // obsolete: use cycleSuspect3Func
  CycleCollectorForget2Func cycleForget2Func; // obsolete

  CycleCollectorSuspect3Func cycleSuspect3Func;

} XPCOMFunctions;

typedef nsresult (*GetFrozenFunctionsFunc)(XPCOMFunctions* aEntryPoints,
                                           const char* aLibraryPath);
XPCOM_API(nsresult) NS_GetFrozenFunctions(XPCOMFunctions* aEntryPoints,
                                          const char* aLibraryPath);


namespace mozilla {

/**
 * Shutdown XPCOM. You must call this method after you are finished
 * using xpcom.
 *
 * @param aServMgr          The service manager which was returned by NS_InitXPCOM.
 *                          This will release servMgr.  You may pass null.
 *
 * @return NS_OK for success;
 *         other error codes indicate a failure during shutdown
 *
 */
nsresult
ShutdownXPCOM(nsIServiceManager* aServMgr);

void SetICUMemoryFunctions();

/**
 * C++ namespaced version of NS_LogTerm.
 */
void LogTerm();

} // namespace mozilla


// think hard before changing this
#define XPCOM_GLUE_VERSION 1


/* XPCOM Specific Defines
 *
 * XPCOM_DLL              - name of the loadable xpcom library on disk.
 * XUL_DLL                - name of the loadable XUL library on disk
 * XPCOM_SEARCH_KEY       - name of the environment variable that can be
 *                          modified to include additional search paths.
 * GRE_CONF_NAME          - Name of the GRE Configuration file
 */

#if defined(XP_WIN32)

#define XPCOM_SEARCH_KEY  "PATH"
#define GRE_CONF_NAME     "gre.config"
#define GRE_WIN_REG_LOC   L"Software\\mozilla.org\\GRE"
#define XPCOM_DLL         XUL_DLL
#define LXPCOM_DLL        LXUL_DLL
#define XUL_DLL           "xul.dll"
#define LXUL_DLL          L"xul.dll"

#else // Unix
#include <limits.h> // for PATH_MAX

#define XPCOM_DLL         XUL_DLL

// you have to love apple..
#ifdef XP_MACOSX
#define XPCOM_SEARCH_KEY  "DYLD_LIBRARY_PATH"
#define GRE_FRAMEWORK_NAME "XUL.framework"
#define XUL_DLL            "XUL"
#else
#define XPCOM_SEARCH_KEY  "LD_LIBRARY_PATH"
#define XUL_DLL   "libxul" MOZ_DLL_SUFFIX
#endif

#define GRE_CONF_NAME ".gre.config"
#define GRE_CONF_PATH "/etc/gre.conf"
#define GRE_CONF_DIR  "/etc/gre.d"
#define GRE_USER_CONF_DIR ".gre.d"
#endif

#if defined(XP_WIN)
  #define XPCOM_FILE_PATH_SEPARATOR       "\\"
  #define XPCOM_ENV_PATH_SEPARATOR        ";"
#elif defined(XP_UNIX)
  #define XPCOM_FILE_PATH_SEPARATOR       "/"
  #define XPCOM_ENV_PATH_SEPARATOR        ":"
#else
  #error need_to_define_your_file_path_separator_and_illegal_characters
#endif

#ifndef MAXPATHLEN
#ifdef PATH_MAX
#define MAXPATHLEN PATH_MAX
#elif defined(_MAX_PATH)
#define MAXPATHLEN _MAX_PATH
#elif defined(CCHMAXPATH)
#define MAXPATHLEN CCHMAXPATH
#else
#define MAXPATHLEN 1024
#endif
#endif

extern bool gXPCOMShuttingDown;
extern bool gXPCOMThreadsShutDown;

// Needed by the IPC layer from off the main thread
extern char16_t* gGREBinPath;

namespace mozilla {
namespace services {

/**
 * Clears service cache, sets gXPCOMShuttingDown
 */
void Shutdown();

} // namespace services
} // namespace mozilla

#endif
