Merge changes from the-witness.
Fix DXT5n compressor.
This commit is contained in:
1076
src/nvcore/Debug.cpp
1076
src/nvcore/Debug.cpp
File diff suppressed because it is too large
Load Diff
@ -1,173 +1,173 @@
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_DEBUG_H
|
||||
#define NV_CORE_DEBUG_H
|
||||
|
||||
#include "nvcore.h"
|
||||
|
||||
#if defined(HAVE_STDARG_H)
|
||||
# include <stdarg.h> // va_list
|
||||
#endif
|
||||
|
||||
#define NV_ABORT_DEBUG 1
|
||||
#define NV_ABORT_IGNORE 2
|
||||
#define NV_ABORT_EXIT 3
|
||||
|
||||
#define nvNoAssert(exp) \
|
||||
do { \
|
||||
(void)sizeof(exp); \
|
||||
} while(0)
|
||||
|
||||
#if NV_NO_ASSERT
|
||||
|
||||
# define nvAssert(exp) nvNoAssert(exp)
|
||||
# define nvCheck(exp) nvNoAssert(exp)
|
||||
# define nvDebugAssert(exp) nvNoAssert(exp)
|
||||
# define nvDebugCheck(exp) nvNoAssert(exp)
|
||||
# define nvDebugBreak() nvNoAssert(0)
|
||||
|
||||
#else // NV_NO_ASSERT
|
||||
|
||||
# if NV_CC_MSVC
|
||||
// @@ Does this work in msvc-6 and earlier?
|
||||
# define nvDebugBreak() __debugbreak()
|
||||
//# define nvDebugBreak() __asm { int 3 }
|
||||
# elif NV_CC_GNUC && NV_CPU_PPC && NV_OS_DARWIN
|
||||
// @@ Use __builtin_trap() on GCC
|
||||
# define nvDebugBreak() __asm__ volatile ("trap");
|
||||
# elif NV_CC_GNUC && NV_CPU_X86 && NV_OS_DARWIN
|
||||
# define nvDebugBreak() __asm__ volatile ("int3");
|
||||
# elif NV_CC_GNUC && NV_CPU_X86
|
||||
# define nvDebugBreak() __asm__ ( "int %0" : :"I"(3) )
|
||||
# else
|
||||
# include <signal.h>
|
||||
# define nvDebugBreak() raise(SIGTRAP);
|
||||
// define nvDebugBreak() *((int *)(0)) = 0
|
||||
# endif
|
||||
|
||||
#define nvDebugBreakOnce() \
|
||||
do { \
|
||||
static bool firstTime = true; \
|
||||
if (firstTime) { firstTime = false; nvDebugBreak(); } \
|
||||
} while(false)
|
||||
|
||||
# define nvAssertMacro(exp) \
|
||||
do { \
|
||||
if (!(exp)) { \
|
||||
if (nvAbort(#exp, __FILE__, __LINE__, __FUNC__) == NV_ABORT_DEBUG) { \
|
||||
nvDebugBreak(); \
|
||||
} \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
# define nvAssertMacroWithIgnoreAll(exp) \
|
||||
do { \
|
||||
static bool ignoreAll = false; \
|
||||
if (!ignoreAll && !(exp)) { \
|
||||
if (nvAbort(#exp, __FILE__, __LINE__, __FUNC__) == NV_ABORT_DEBUG) { \
|
||||
nvDebugBreak(); \
|
||||
} else { \
|
||||
ignoreAll = true; \
|
||||
} \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
# define nvAssert(exp) nvAssertMacro(exp)
|
||||
# define nvCheck(exp) nvAssertMacro(exp)
|
||||
|
||||
# if defined(_DEBUG)
|
||||
# define nvDebugAssert(exp) nvAssertMacro(exp)
|
||||
# define nvDebugCheck(exp) nvAssertMacro(exp)
|
||||
# else // _DEBUG
|
||||
# define nvDebugAssert(exp) nvNoAssert(exp)
|
||||
# define nvDebugCheck(exp) nvNoAssert(exp)
|
||||
# endif // _DEBUG
|
||||
|
||||
#endif // NV_NO_ASSERT
|
||||
|
||||
// Use nvAssume for very simple expresions only: nvAssume(0), nvAssume(value == true), etc.
|
||||
#if !defined(_DEBUG)
|
||||
# if NV_CC_MSVC
|
||||
# define nvAssume(exp) __assume(exp)
|
||||
# else
|
||||
# define nvAssume(exp) nvCheck(exp)
|
||||
# endif
|
||||
#else
|
||||
# define nvAssume(exp) nvCheck(exp)
|
||||
#endif
|
||||
|
||||
|
||||
#define nvError(x) nvAbort(x, __FILE__, __LINE__, __FUNC__)
|
||||
#define nvWarning(x) nvDebugPrint("*** Warning %s/%d: %s\n", __FILE__, __LINE__, (x))
|
||||
|
||||
#ifndef NV_DEBUG_PRINT
|
||||
#define NV_DEBUG_PRINT 1 //defined(_DEBUG)
|
||||
#endif
|
||||
|
||||
#if NV_DEBUG_PRINT
|
||||
#define nvDebug(...) nvDebugPrint(__VA_ARGS__)
|
||||
#else
|
||||
#if NV_CC_MSVC
|
||||
#define nvDebug(...) __noop(__VA_ARGS__)
|
||||
#else
|
||||
#define nvDebug(...) ((void)0) // Non-msvc platforms do not evaluate arguments?
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if __cplusplus > 199711L
|
||||
#define nvStaticCheck(x) static_assert(x)
|
||||
#else
|
||||
#define nvStaticCheck(x) typedef char NV_DO_STRING_JOIN2(__static_assert_,__LINE__)[(x)]
|
||||
#endif
|
||||
|
||||
NVCORE_API int nvAbort(const char *exp, const char *file, int line, const char * func = NULL);
|
||||
NVCORE_API void NV_CDECL nvDebugPrint( const char *msg, ... ) __attribute__((format (printf, 1, 2)));
|
||||
|
||||
namespace nv
|
||||
{
|
||||
inline bool isValidPtr(const void * ptr) {
|
||||
#if NV_CPU_X86_64
|
||||
if (ptr == NULL) return true;
|
||||
if (reinterpret_cast<uint64>(ptr) < 0x10000ULL) return false;
|
||||
if (reinterpret_cast<uint64>(ptr) >= 0x000007FFFFFEFFFFULL) return false;
|
||||
#else
|
||||
if (reinterpret_cast<uint>(ptr) == 0xcccccccc) return false;
|
||||
if (reinterpret_cast<uint>(ptr) == 0xcdcdcdcd) return false;
|
||||
if (reinterpret_cast<uint>(ptr) == 0xdddddddd) return false;
|
||||
if (reinterpret_cast<uint>(ptr) == 0xffffffff) return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Message handler interface.
|
||||
struct MessageHandler {
|
||||
virtual void log(const char * str, va_list arg) = 0;
|
||||
virtual ~MessageHandler() {}
|
||||
};
|
||||
|
||||
/// Assert handler interface.
|
||||
struct AssertHandler {
|
||||
virtual int assertion(const char *exp, const char *file, int line, const char *func = NULL) = 0;
|
||||
virtual ~AssertHandler() {}
|
||||
};
|
||||
|
||||
|
||||
namespace debug
|
||||
{
|
||||
NVCORE_API void dumpInfo();
|
||||
|
||||
NVCORE_API void setMessageHandler( MessageHandler * messageHandler );
|
||||
NVCORE_API void resetMessageHandler();
|
||||
|
||||
NVCORE_API void setAssertHandler( AssertHandler * assertHanlder );
|
||||
NVCORE_API void resetAssertHandler();
|
||||
|
||||
NVCORE_API void enableSigHandler();
|
||||
NVCORE_API void disableSigHandler();
|
||||
}
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_DEBUG_H
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_DEBUG_H
|
||||
#define NV_CORE_DEBUG_H
|
||||
|
||||
#include "nvcore.h"
|
||||
|
||||
#if defined(HAVE_STDARG_H)
|
||||
# include <stdarg.h> // va_list
|
||||
#endif
|
||||
|
||||
#define NV_ABORT_DEBUG 1
|
||||
#define NV_ABORT_IGNORE 2
|
||||
#define NV_ABORT_EXIT 3
|
||||
|
||||
#define nvNoAssert(exp) \
|
||||
do { \
|
||||
(void)sizeof(exp); \
|
||||
} while(0)
|
||||
|
||||
#if NV_NO_ASSERT
|
||||
|
||||
# define nvAssert(exp) nvNoAssert(exp)
|
||||
# define nvCheck(exp) nvNoAssert(exp)
|
||||
# define nvDebugAssert(exp) nvNoAssert(exp)
|
||||
# define nvDebugCheck(exp) nvNoAssert(exp)
|
||||
# define nvDebugBreak() nvNoAssert(0)
|
||||
|
||||
#else // NV_NO_ASSERT
|
||||
|
||||
# if NV_CC_MSVC
|
||||
// @@ Does this work in msvc-6 and earlier?
|
||||
# define nvDebugBreak() __debugbreak()
|
||||
//# define nvDebugBreak() __asm { int 3 }
|
||||
# elif NV_CC_GNUC && NV_CPU_PPC && NV_OS_DARWIN
|
||||
// @@ Use __builtin_trap() on GCC
|
||||
# define nvDebugBreak() __asm__ volatile ("trap");
|
||||
# elif NV_CC_GNUC && NV_CPU_X86 && NV_OS_DARWIN
|
||||
# define nvDebugBreak() __asm__ volatile ("int3");
|
||||
# elif NV_CC_GNUC && NV_CPU_X86
|
||||
# define nvDebugBreak() __asm__ ( "int %0" : :"I"(3) )
|
||||
# else
|
||||
# include <signal.h>
|
||||
# define nvDebugBreak() raise(SIGTRAP);
|
||||
// define nvDebugBreak() *((int *)(0)) = 0
|
||||
# endif
|
||||
|
||||
#define nvDebugBreakOnce() \
|
||||
do { \
|
||||
static bool firstTime = true; \
|
||||
if (firstTime) { firstTime = false; nvDebugBreak(); } \
|
||||
} while(false)
|
||||
|
||||
# define nvAssertMacro(exp) \
|
||||
do { \
|
||||
if (!(exp)) { \
|
||||
if (nvAbort(#exp, __FILE__, __LINE__, __FUNC__) == NV_ABORT_DEBUG) { \
|
||||
nvDebugBreak(); \
|
||||
} \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
# define nvAssertMacroWithIgnoreAll(exp) \
|
||||
do { \
|
||||
static bool ignoreAll = false; \
|
||||
if (!ignoreAll && !(exp)) { \
|
||||
if (nvAbort(#exp, __FILE__, __LINE__, __FUNC__) == NV_ABORT_DEBUG) { \
|
||||
nvDebugBreak(); \
|
||||
} else { \
|
||||
ignoreAll = true; \
|
||||
} \
|
||||
} \
|
||||
} while(false)
|
||||
|
||||
# define nvAssert(exp) nvAssertMacro(exp)
|
||||
# define nvCheck(exp) nvAssertMacro(exp)
|
||||
|
||||
# if defined(_DEBUG)
|
||||
# define nvDebugAssert(exp) nvAssertMacro(exp)
|
||||
# define nvDebugCheck(exp) nvAssertMacro(exp)
|
||||
# else // _DEBUG
|
||||
# define nvDebugAssert(exp) nvNoAssert(exp)
|
||||
# define nvDebugCheck(exp) nvNoAssert(exp)
|
||||
# endif // _DEBUG
|
||||
|
||||
#endif // NV_NO_ASSERT
|
||||
|
||||
// Use nvAssume for very simple expresions only: nvAssume(0), nvAssume(value == true), etc.
|
||||
#if !defined(_DEBUG)
|
||||
# if NV_CC_MSVC
|
||||
# define nvAssume(exp) __assume(exp)
|
||||
# else
|
||||
# define nvAssume(exp) nvCheck(exp)
|
||||
# endif
|
||||
#else
|
||||
# define nvAssume(exp) nvCheck(exp)
|
||||
#endif
|
||||
|
||||
|
||||
#define nvError(x) nvAbort(x, __FILE__, __LINE__, __FUNC__)
|
||||
#define nvWarning(x) nvDebugPrint("*** Warning %s/%d: %s\n", __FILE__, __LINE__, (x))
|
||||
|
||||
#ifndef NV_DEBUG_PRINT
|
||||
#define NV_DEBUG_PRINT 1 //defined(_DEBUG)
|
||||
#endif
|
||||
|
||||
#if NV_DEBUG_PRINT
|
||||
#define nvDebug(...) nvDebugPrint(__VA_ARGS__)
|
||||
#else
|
||||
#if NV_CC_MSVC
|
||||
#define nvDebug(...) __noop(__VA_ARGS__)
|
||||
#else
|
||||
#define nvDebug(...) ((void)0) // Non-msvc platforms do not evaluate arguments?
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if __cplusplus > 199711L
|
||||
#define nvStaticCheck(x) static_assert(x)
|
||||
#else
|
||||
#define nvStaticCheck(x) typedef char NV_DO_STRING_JOIN2(__static_assert_,__LINE__)[(x)]
|
||||
#endif
|
||||
|
||||
NVCORE_API int nvAbort(const char *exp, const char *file, int line, const char * func = NULL);
|
||||
NVCORE_API void NV_CDECL nvDebugPrint( const char *msg, ... ) __attribute__((format (printf, 1, 2)));
|
||||
|
||||
namespace nv
|
||||
{
|
||||
inline bool isValidPtr(const void * ptr) {
|
||||
#if NV_CPU_X86_64
|
||||
if (ptr == NULL) return true;
|
||||
if (reinterpret_cast<uint64>(ptr) < 0x10000ULL) return false;
|
||||
if (reinterpret_cast<uint64>(ptr) >= 0x000007FFFFFEFFFFULL) return false;
|
||||
#else
|
||||
if (reinterpret_cast<uint>(ptr) == 0xcccccccc) return false;
|
||||
if (reinterpret_cast<uint>(ptr) == 0xcdcdcdcd) return false;
|
||||
if (reinterpret_cast<uint>(ptr) == 0xdddddddd) return false;
|
||||
if (reinterpret_cast<uint>(ptr) == 0xffffffff) return false;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Message handler interface.
|
||||
struct MessageHandler {
|
||||
virtual void log(const char * str, va_list arg) = 0;
|
||||
virtual ~MessageHandler() {}
|
||||
};
|
||||
|
||||
/// Assert handler interface.
|
||||
struct AssertHandler {
|
||||
virtual int assertion(const char *exp, const char *file, int line, const char *func = NULL) = 0;
|
||||
virtual ~AssertHandler() {}
|
||||
};
|
||||
|
||||
|
||||
namespace debug
|
||||
{
|
||||
NVCORE_API void dumpInfo();
|
||||
|
||||
NVCORE_API void setMessageHandler( MessageHandler * messageHandler );
|
||||
NVCORE_API void resetMessageHandler();
|
||||
|
||||
NVCORE_API void setAssertHandler( AssertHandler * assertHanlder );
|
||||
NVCORE_API void resetAssertHandler();
|
||||
|
||||
NVCORE_API void enableSigHandler();
|
||||
NVCORE_API void disableSigHandler();
|
||||
}
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_DEBUG_H
|
||||
|
@ -1,69 +1,69 @@
|
||||
#ifndef NV_CORE_H
|
||||
#error "Do not include this file directly."
|
||||
#endif
|
||||
|
||||
#include <stdint.h> // uint8_t, int8_t, ...
|
||||
#include <cstddef> // size_t, NULL
|
||||
|
||||
// Function linkage
|
||||
#define DLL_IMPORT
|
||||
#if __GNUC__ >= 4
|
||||
# define DLL_EXPORT __attribute__((visibility("default")))
|
||||
# define DLL_EXPORT_CLASS DLL_EXPORT
|
||||
#else
|
||||
# define DLL_EXPORT
|
||||
# define DLL_EXPORT_CLASS
|
||||
#endif
|
||||
|
||||
// Function calling modes
|
||||
#if NV_CPU_X86
|
||||
# define NV_CDECL __attribute__((cdecl))
|
||||
# define NV_STDCALL __attribute__((stdcall))
|
||||
#else
|
||||
# define NV_CDECL
|
||||
# define NV_STDCALL
|
||||
#endif
|
||||
|
||||
#define NV_FASTCALL __attribute__((fastcall))
|
||||
#define NV_FORCEINLINE __attribute__((always_inline))
|
||||
#define NV_DEPRECATED __attribute__((deprecated))
|
||||
|
||||
#if __GNUC__ > 2
|
||||
#define NV_PURE __attribute__((pure))
|
||||
#define NV_CONST __attribute__((const))
|
||||
#else
|
||||
#define NV_PURE
|
||||
#define NV_CONST
|
||||
#endif
|
||||
|
||||
#define NV_NOINLINE __attribute__((noinline))
|
||||
|
||||
// Define __FUNC__ properly.
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
# if __GNUC__ >= 2
|
||||
# define __FUNC__ __PRETTY_FUNCTION__ // __FUNCTION__
|
||||
# else
|
||||
# define __FUNC__ "<unknown>"
|
||||
# endif
|
||||
#else
|
||||
# define __FUNC__ __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
|
||||
|
||||
// Type definitions
|
||||
typedef uint8_t uint8;
|
||||
typedef int8_t int8;
|
||||
|
||||
typedef uint16_t uint16;
|
||||
typedef int16_t int16;
|
||||
|
||||
typedef uint32_t uint32;
|
||||
typedef int32_t int32;
|
||||
|
||||
typedef uint64_t uint64;
|
||||
typedef int64_t int64;
|
||||
|
||||
// Aliases
|
||||
typedef uint32 uint;
|
||||
#ifndef NV_CORE_H
|
||||
#error "Do not include this file directly."
|
||||
#endif
|
||||
|
||||
#include <stdint.h> // uint8_t, int8_t, ...
|
||||
#include <cstddef> // size_t, NULL
|
||||
|
||||
// Function linkage
|
||||
#define DLL_IMPORT
|
||||
#if __GNUC__ >= 4
|
||||
# define DLL_EXPORT __attribute__((visibility("default")))
|
||||
# define DLL_EXPORT_CLASS DLL_EXPORT
|
||||
#else
|
||||
# define DLL_EXPORT
|
||||
# define DLL_EXPORT_CLASS
|
||||
#endif
|
||||
|
||||
// Function calling modes
|
||||
#if NV_CPU_X86
|
||||
# define NV_CDECL __attribute__((cdecl))
|
||||
# define NV_STDCALL __attribute__((stdcall))
|
||||
#else
|
||||
# define NV_CDECL
|
||||
# define NV_STDCALL
|
||||
#endif
|
||||
|
||||
#define NV_FASTCALL __attribute__((fastcall))
|
||||
#define NV_FORCEINLINE __attribute__((always_inline))
|
||||
#define NV_DEPRECATED __attribute__((deprecated))
|
||||
|
||||
#if __GNUC__ > 2
|
||||
#define NV_PURE __attribute__((pure))
|
||||
#define NV_CONST __attribute__((const))
|
||||
#else
|
||||
#define NV_PURE
|
||||
#define NV_CONST
|
||||
#endif
|
||||
|
||||
#define NV_NOINLINE __attribute__((noinline))
|
||||
|
||||
// Define __FUNC__ properly.
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
# if __GNUC__ >= 2
|
||||
# define __FUNC__ __PRETTY_FUNCTION__ // __FUNCTION__
|
||||
# else
|
||||
# define __FUNC__ "<unknown>"
|
||||
# endif
|
||||
#else
|
||||
# define __FUNC__ __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
|
||||
|
||||
// Type definitions
|
||||
typedef uint8_t uint8;
|
||||
typedef int8_t int8;
|
||||
|
||||
typedef uint16_t uint16;
|
||||
typedef int16_t int16;
|
||||
|
||||
typedef uint32_t uint32;
|
||||
typedef int32_t int32;
|
||||
|
||||
typedef uint64_t uint64;
|
||||
typedef int64_t int64;
|
||||
|
||||
// Aliases
|
||||
typedef uint32 uint;
|
||||
|
@ -1,69 +1,69 @@
|
||||
#ifndef NV_CORE_H
|
||||
#error "Do not include this file directly."
|
||||
#endif
|
||||
|
||||
#include <cstddef> // size_t, NULL
|
||||
|
||||
// Function linkage
|
||||
#define DLL_IMPORT
|
||||
#if __GNUC__ >= 4
|
||||
# define DLL_EXPORT __attribute__((visibility("default")))
|
||||
# define DLL_EXPORT_CLASS DLL_EXPORT
|
||||
#else
|
||||
# define DLL_EXPORT
|
||||
# define DLL_EXPORT_CLASS
|
||||
#endif
|
||||
|
||||
// Function calling modes
|
||||
#if NV_CPU_X86
|
||||
# define NV_CDECL __attribute__((cdecl))
|
||||
# define NV_STDCALL __attribute__((stdcall))
|
||||
#else
|
||||
# define NV_CDECL
|
||||
# define NV_STDCALL
|
||||
#endif
|
||||
|
||||
#define NV_FASTCALL __attribute__((fastcall))
|
||||
#define NV_FORCEINLINE __attribute__((always_inline))
|
||||
#define NV_DEPRECATED __attribute__((deprecated))
|
||||
|
||||
|
||||
#if __GNUC__ > 2
|
||||
#define NV_PURE __attribute__((pure))
|
||||
#define NV_CONST __attribute__((const))
|
||||
#else
|
||||
#define NV_PURE
|
||||
#define NV_CONST
|
||||
#endif
|
||||
|
||||
#define NV_NOINLINE __attribute__((noinline))
|
||||
|
||||
// Define __FUNC__ properly.
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
# if __GNUC__ >= 2
|
||||
# define __FUNC__ __PRETTY_FUNCTION__ // __FUNCTION__
|
||||
# else
|
||||
# define __FUNC__ "<unknown>"
|
||||
# endif
|
||||
#else
|
||||
# define __FUNC__ __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
|
||||
|
||||
// Type definitions
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short int16;
|
||||
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
|
||||
typedef unsigned long long uint64;
|
||||
typedef signed long long int64;
|
||||
|
||||
// Aliases
|
||||
typedef uint32 uint;
|
||||
#ifndef NV_CORE_H
|
||||
#error "Do not include this file directly."
|
||||
#endif
|
||||
|
||||
#include <cstddef> // size_t, NULL
|
||||
|
||||
// Function linkage
|
||||
#define DLL_IMPORT
|
||||
#if __GNUC__ >= 4
|
||||
# define DLL_EXPORT __attribute__((visibility("default")))
|
||||
# define DLL_EXPORT_CLASS DLL_EXPORT
|
||||
#else
|
||||
# define DLL_EXPORT
|
||||
# define DLL_EXPORT_CLASS
|
||||
#endif
|
||||
|
||||
// Function calling modes
|
||||
#if NV_CPU_X86
|
||||
# define NV_CDECL __attribute__((cdecl))
|
||||
# define NV_STDCALL __attribute__((stdcall))
|
||||
#else
|
||||
# define NV_CDECL
|
||||
# define NV_STDCALL
|
||||
#endif
|
||||
|
||||
#define NV_FASTCALL __attribute__((fastcall))
|
||||
#define NV_FORCEINLINE __attribute__((always_inline))
|
||||
#define NV_DEPRECATED __attribute__((deprecated))
|
||||
|
||||
|
||||
#if __GNUC__ > 2
|
||||
#define NV_PURE __attribute__((pure))
|
||||
#define NV_CONST __attribute__((const))
|
||||
#else
|
||||
#define NV_PURE
|
||||
#define NV_CONST
|
||||
#endif
|
||||
|
||||
#define NV_NOINLINE __attribute__((noinline))
|
||||
|
||||
// Define __FUNC__ properly.
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
# if __GNUC__ >= 2
|
||||
# define __FUNC__ __PRETTY_FUNCTION__ // __FUNCTION__
|
||||
# else
|
||||
# define __FUNC__ "<unknown>"
|
||||
# endif
|
||||
#else
|
||||
# define __FUNC__ __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
|
||||
|
||||
// Type definitions
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short int16;
|
||||
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
|
||||
typedef unsigned long long uint64;
|
||||
typedef signed long long int64;
|
||||
|
||||
// Aliases
|
||||
typedef uint32 uint;
|
||||
|
@ -1,63 +1,63 @@
|
||||
#ifndef NV_CORE_H
|
||||
#error "Do not include this file directly."
|
||||
#endif
|
||||
|
||||
#include <cstddef> // size_t, NULL
|
||||
|
||||
// Function linkage
|
||||
#define DLL_IMPORT __declspec(dllimport)
|
||||
#define DLL_EXPORT __declspec(dllexport)
|
||||
#define DLL_EXPORT_CLASS DLL_EXPORT
|
||||
|
||||
// Function calling modes
|
||||
#if NV_CPU_X86
|
||||
# define NV_CDECL __attribute__((cdecl))
|
||||
# define NV_STDCALL __attribute__((stdcall))
|
||||
#else
|
||||
# define NV_CDECL
|
||||
# define NV_STDCALL
|
||||
#endif
|
||||
|
||||
#define NV_FASTCALL __attribute__((fastcall))
|
||||
#define NV_FORCEINLINE __attribute__((always_inline))
|
||||
#define NV_DEPRECATED __attribute__((deprecated))
|
||||
|
||||
#if __GNUC__ > 2
|
||||
#define NV_PURE __attribute__((pure))
|
||||
#define NV_CONST __attribute__((const))
|
||||
#else
|
||||
#define NV_PURE
|
||||
#define NV_CONST
|
||||
#endif
|
||||
|
||||
#define NV_NOINLINE __attribute__((noinline))
|
||||
|
||||
// Define __FUNC__ properly.
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
# if __GNUC__ >= 2
|
||||
# define __FUNC__ __PRETTY_FUNCTION__ // __FUNCTION__
|
||||
# else
|
||||
# define __FUNC__ "<unknown>"
|
||||
# endif
|
||||
#else
|
||||
# define __FUNC__ __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
|
||||
|
||||
// Type definitions
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short int16;
|
||||
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
|
||||
typedef unsigned long long uint64;
|
||||
typedef signed long long int64;
|
||||
|
||||
// Aliases
|
||||
typedef uint32 uint;
|
||||
#ifndef NV_CORE_H
|
||||
#error "Do not include this file directly."
|
||||
#endif
|
||||
|
||||
#include <cstddef> // size_t, NULL
|
||||
|
||||
// Function linkage
|
||||
#define DLL_IMPORT __declspec(dllimport)
|
||||
#define DLL_EXPORT __declspec(dllexport)
|
||||
#define DLL_EXPORT_CLASS DLL_EXPORT
|
||||
|
||||
// Function calling modes
|
||||
#if NV_CPU_X86
|
||||
# define NV_CDECL __attribute__((cdecl))
|
||||
# define NV_STDCALL __attribute__((stdcall))
|
||||
#else
|
||||
# define NV_CDECL
|
||||
# define NV_STDCALL
|
||||
#endif
|
||||
|
||||
#define NV_FASTCALL __attribute__((fastcall))
|
||||
#define NV_FORCEINLINE __attribute__((always_inline))
|
||||
#define NV_DEPRECATED __attribute__((deprecated))
|
||||
|
||||
#if __GNUC__ > 2
|
||||
#define NV_PURE __attribute__((pure))
|
||||
#define NV_CONST __attribute__((const))
|
||||
#else
|
||||
#define NV_PURE
|
||||
#define NV_CONST
|
||||
#endif
|
||||
|
||||
#define NV_NOINLINE __attribute__((noinline))
|
||||
|
||||
// Define __FUNC__ properly.
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
# if __GNUC__ >= 2
|
||||
# define __FUNC__ __PRETTY_FUNCTION__ // __FUNCTION__
|
||||
# else
|
||||
# define __FUNC__ "<unknown>"
|
||||
# endif
|
||||
#else
|
||||
# define __FUNC__ __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
#define restrict __restrict__
|
||||
|
||||
|
||||
// Type definitions
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short int16;
|
||||
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
|
||||
typedef unsigned long long uint64;
|
||||
typedef signed long long int64;
|
||||
|
||||
// Aliases
|
||||
typedef uint32 uint;
|
||||
|
@ -1,82 +1,82 @@
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#ifndef NV_CORE_H
|
||||
#error "Do not include this file directly."
|
||||
#endif
|
||||
|
||||
// Function linkage
|
||||
#define DLL_IMPORT __declspec(dllimport)
|
||||
#define DLL_EXPORT __declspec(dllexport)
|
||||
#define DLL_EXPORT_CLASS DLL_EXPORT
|
||||
|
||||
// Function calling modes
|
||||
#define NV_CDECL __cdecl
|
||||
#define NV_STDCALL __stdcall
|
||||
#define NV_FASTCALL __fastcall
|
||||
#define NV_FORCEINLINE __forceinline
|
||||
#define NV_DEPRECATED
|
||||
|
||||
#define NV_PURE
|
||||
#define NV_CONST
|
||||
|
||||
// Set standard function names.
|
||||
#define snprintf _snprintf
|
||||
#if _MSC_VER < 1500
|
||||
# define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define chdir _chdir
|
||||
#define getcwd _getcwd
|
||||
|
||||
#ifndef va_copy
|
||||
#define va_copy(a, b) (a) = (b)
|
||||
#endif
|
||||
|
||||
#if !defined restrict
|
||||
#define restrict
|
||||
#endif
|
||||
|
||||
// Ignore gcc attributes.
|
||||
#define __attribute__(X)
|
||||
|
||||
#if !defined __FUNC__
|
||||
#define __FUNC__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
#define NV_NOINLINE __declspec(noinline)
|
||||
|
||||
// Type definitions
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short int16;
|
||||
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef signed __int64 int64;
|
||||
|
||||
// Aliases
|
||||
typedef uint32 uint;
|
||||
|
||||
|
||||
// Unwanted VC++ warnings to disable.
|
||||
/*
|
||||
#pragma warning(disable : 4244) // conversion to float, possible loss of data
|
||||
#pragma warning(disable : 4245) // conversion from 'enum ' to 'unsigned long', signed/unsigned mismatch
|
||||
#pragma warning(disable : 4100) // unreferenced formal parameter
|
||||
#pragma warning(disable : 4514) // unreferenced inline function has been removed
|
||||
#pragma warning(disable : 4710) // inline function not expanded
|
||||
#pragma warning(disable : 4127) // Conditional expression is constant
|
||||
#pragma warning(disable : 4305) // truncation from 'const double' to 'float'
|
||||
#pragma warning(disable : 4505) // unreferenced local function has been removed
|
||||
|
||||
#pragma warning(disable : 4702) // unreachable code in inline expanded function
|
||||
#pragma warning(disable : 4711) // function selected for automatic inlining
|
||||
#pragma warning(disable : 4725) // Pentium fdiv bug
|
||||
|
||||
#pragma warning(disable : 4786) // Identifier was truncated and cannot be debugged.
|
||||
|
||||
#pragma warning(disable : 4675) // resolved overload was found by argument-dependent lookup
|
||||
*/
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#ifndef NV_CORE_H
|
||||
#error "Do not include this file directly."
|
||||
#endif
|
||||
|
||||
// Function linkage
|
||||
#define DLL_IMPORT __declspec(dllimport)
|
||||
#define DLL_EXPORT __declspec(dllexport)
|
||||
#define DLL_EXPORT_CLASS DLL_EXPORT
|
||||
|
||||
// Function calling modes
|
||||
#define NV_CDECL __cdecl
|
||||
#define NV_STDCALL __stdcall
|
||||
#define NV_FASTCALL __fastcall
|
||||
#define NV_FORCEINLINE __forceinline
|
||||
#define NV_DEPRECATED
|
||||
|
||||
#define NV_PURE
|
||||
#define NV_CONST
|
||||
|
||||
// Set standard function names.
|
||||
#define snprintf _snprintf
|
||||
#if _MSC_VER < 1500
|
||||
# define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define chdir _chdir
|
||||
#define getcwd _getcwd
|
||||
|
||||
#ifndef va_copy
|
||||
#define va_copy(a, b) (a) = (b)
|
||||
#endif
|
||||
|
||||
#if !defined restrict
|
||||
#define restrict
|
||||
#endif
|
||||
|
||||
// Ignore gcc attributes.
|
||||
#define __attribute__(X)
|
||||
|
||||
#if !defined __FUNC__
|
||||
#define __FUNC__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
#define NV_NOINLINE __declspec(noinline)
|
||||
|
||||
// Type definitions
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short int16;
|
||||
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef signed __int64 int64;
|
||||
|
||||
// Aliases
|
||||
typedef uint32 uint;
|
||||
|
||||
|
||||
// Unwanted VC++ warnings to disable.
|
||||
/*
|
||||
#pragma warning(disable : 4244) // conversion to float, possible loss of data
|
||||
#pragma warning(disable : 4245) // conversion from 'enum ' to 'unsigned long', signed/unsigned mismatch
|
||||
#pragma warning(disable : 4100) // unreferenced formal parameter
|
||||
#pragma warning(disable : 4514) // unreferenced inline function has been removed
|
||||
#pragma warning(disable : 4710) // inline function not expanded
|
||||
#pragma warning(disable : 4127) // Conditional expression is constant
|
||||
#pragma warning(disable : 4305) // truncation from 'const double' to 'float'
|
||||
#pragma warning(disable : 4505) // unreferenced local function has been removed
|
||||
|
||||
#pragma warning(disable : 4702) // unreachable code in inline expanded function
|
||||
#pragma warning(disable : 4711) // function selected for automatic inlining
|
||||
#pragma warning(disable : 4725) // Pentium fdiv bug
|
||||
|
||||
#pragma warning(disable : 4786) // Identifier was truncated and cannot be debugged.
|
||||
|
||||
#pragma warning(disable : 4675) // resolved overload was found by argument-dependent lookup
|
||||
*/
|
||||
|
@ -1,41 +1,41 @@
|
||||
|
||||
#include "Library.h"
|
||||
#include "Debug.h"
|
||||
|
||||
#if NV_OS_WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define VC_EXTRALEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void * nvLoadLibrary(const char * name)
|
||||
{
|
||||
#if NV_OS_WIN32
|
||||
return (void *)LoadLibraryExA( name, NULL, 0 );
|
||||
#else
|
||||
return dlopen(name, RTLD_LAZY);
|
||||
#endif
|
||||
}
|
||||
|
||||
void nvUnloadLibrary(void * handle)
|
||||
{
|
||||
nvDebugCheck(handle != NULL);
|
||||
#if NV_OS_WIN32
|
||||
FreeLibrary((HMODULE)handle);
|
||||
#else
|
||||
dlclose(handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
void * nvBindSymbol(void * handle, const char * symbol)
|
||||
{
|
||||
#if NV_OS_WIN32
|
||||
return (void *)GetProcAddress((HMODULE)handle, symbol);
|
||||
#else
|
||||
return (void *)dlsym(handle, symbol);
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "Library.h"
|
||||
#include "Debug.h"
|
||||
|
||||
#if NV_OS_WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define VC_EXTRALEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void * nvLoadLibrary(const char * name)
|
||||
{
|
||||
#if NV_OS_WIN32
|
||||
return (void *)LoadLibraryExA( name, NULL, 0 );
|
||||
#else
|
||||
return dlopen(name, RTLD_LAZY);
|
||||
#endif
|
||||
}
|
||||
|
||||
void nvUnloadLibrary(void * handle)
|
||||
{
|
||||
nvDebugCheck(handle != NULL);
|
||||
#if NV_OS_WIN32
|
||||
FreeLibrary((HMODULE)handle);
|
||||
#else
|
||||
dlclose(handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
void * nvBindSymbol(void * handle, const char * symbol)
|
||||
{
|
||||
#if NV_OS_WIN32
|
||||
return (void *)GetProcAddress((HMODULE)handle, symbol);
|
||||
#else
|
||||
return (void *)dlsym(handle, symbol);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,51 +1,51 @@
|
||||
// This code is in the public domain -- castano@gmail.com
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_LIBRARY_H
|
||||
#define NV_CORE_LIBRARY_H
|
||||
|
||||
#include "nvcore.h"
|
||||
|
||||
#if NV_OS_WIN32
|
||||
#define LIBRARY_NAME(name) #name ".dll"
|
||||
#elif NV_OS_DARWIN
|
||||
#define NV_LIBRARY_NAME(name) "lib" #name ".dylib"
|
||||
#else
|
||||
#define NV_LIBRARY_NAME(name) "lib" #name ".so"
|
||||
#endif
|
||||
|
||||
NVCORE_API void * nvLoadLibrary(const char * name);
|
||||
NVCORE_API void nvUnloadLibrary(void * lib);
|
||||
NVCORE_API void * nvBindSymbol(void * lib, const char * symbol);
|
||||
|
||||
class NVCORE_CLASS Library
|
||||
{
|
||||
public:
|
||||
Library(const char * name)
|
||||
{
|
||||
handle = nvLoadLibrary(name);
|
||||
}
|
||||
~Library()
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
nvUnloadLibrary(handle);
|
||||
}
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return handle != NULL;
|
||||
}
|
||||
|
||||
void * bindSymbol(const char * symbol)
|
||||
{
|
||||
return nvBindSymbol(handle, symbol);
|
||||
}
|
||||
|
||||
private:
|
||||
void * handle;
|
||||
};
|
||||
|
||||
|
||||
#endif // NV_CORE_LIBRARY_H
|
||||
// This code is in the public domain -- castano@gmail.com
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_LIBRARY_H
|
||||
#define NV_CORE_LIBRARY_H
|
||||
|
||||
#include "nvcore.h"
|
||||
|
||||
#if NV_OS_WIN32
|
||||
#define LIBRARY_NAME(name) #name ".dll"
|
||||
#elif NV_OS_DARWIN
|
||||
#define NV_LIBRARY_NAME(name) "lib" #name ".dylib"
|
||||
#else
|
||||
#define NV_LIBRARY_NAME(name) "lib" #name ".so"
|
||||
#endif
|
||||
|
||||
NVCORE_API void * nvLoadLibrary(const char * name);
|
||||
NVCORE_API void nvUnloadLibrary(void * lib);
|
||||
NVCORE_API void * nvBindSymbol(void * lib, const char * symbol);
|
||||
|
||||
class NVCORE_CLASS Library
|
||||
{
|
||||
public:
|
||||
Library(const char * name)
|
||||
{
|
||||
handle = nvLoadLibrary(name);
|
||||
}
|
||||
~Library()
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
nvUnloadLibrary(handle);
|
||||
}
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return handle != NULL;
|
||||
}
|
||||
|
||||
void * bindSymbol(const char * symbol)
|
||||
{
|
||||
return nvBindSymbol(handle, symbol);
|
||||
}
|
||||
|
||||
private:
|
||||
void * handle;
|
||||
};
|
||||
|
||||
|
||||
#endif // NV_CORE_LIBRARY_H
|
||||
|
@ -1,37 +1,37 @@
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#include "Memory.h"
|
||||
#include "Debug.h"
|
||||
|
||||
//#if HAVE_MALLOC_H
|
||||
//#include <malloc.h>
|
||||
//#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
using namespace nv;
|
||||
|
||||
void * nv::mem::malloc(size_t size)
|
||||
{
|
||||
return ::malloc(size);
|
||||
}
|
||||
|
||||
void * nv::mem::malloc(size_t size, const char * file, int line)
|
||||
{
|
||||
NV_UNUSED(file);
|
||||
NV_UNUSED(line);
|
||||
return ::malloc(size);
|
||||
}
|
||||
|
||||
void nv::mem::free(const void * ptr)
|
||||
{
|
||||
::free(const_cast<void *>(ptr));
|
||||
}
|
||||
|
||||
void * nv::mem::realloc(void * ptr, size_t size)
|
||||
{
|
||||
nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior.
|
||||
return ::realloc(ptr, size);
|
||||
}
|
||||
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#include "Memory.h"
|
||||
#include "Debug.h"
|
||||
|
||||
//#if HAVE_MALLOC_H
|
||||
//#include <malloc.h>
|
||||
//#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
using namespace nv;
|
||||
|
||||
void * nv::mem::malloc(size_t size)
|
||||
{
|
||||
return ::malloc(size);
|
||||
}
|
||||
|
||||
void * nv::mem::malloc(size_t size, const char * file, int line)
|
||||
{
|
||||
NV_UNUSED(file);
|
||||
NV_UNUSED(line);
|
||||
return ::malloc(size);
|
||||
}
|
||||
|
||||
void nv::mem::free(const void * ptr)
|
||||
{
|
||||
::free(const_cast<void *>(ptr));
|
||||
}
|
||||
|
||||
void * nv::mem::realloc(void * ptr, size_t size)
|
||||
{
|
||||
nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior.
|
||||
return ::realloc(ptr, size);
|
||||
}
|
||||
|
||||
|
@ -1,187 +1,187 @@
|
||||
// This code is in the public domain -- Ignacio Castaño <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_MEMORY_H
|
||||
#define NV_CORE_MEMORY_H
|
||||
|
||||
#include "nvcore.h"
|
||||
|
||||
#include <stdlib.h> // malloc(), realloc() and free()
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#include <new> // new and delete
|
||||
|
||||
// Custom memory allocator
|
||||
namespace nv
|
||||
{
|
||||
namespace mem
|
||||
{
|
||||
NVCORE_API void * malloc(size_t size);
|
||||
NVCORE_API void * malloc(size_t size, const char * file, int line);
|
||||
|
||||
NVCORE_API void free(const void * ptr);
|
||||
NVCORE_API void * realloc(void * ptr, size_t size);
|
||||
|
||||
} // mem namespace
|
||||
|
||||
} // nv namespace
|
||||
|
||||
|
||||
// Override new/delete
|
||||
|
||||
inline void * operator new (size_t size) throw()
|
||||
{
|
||||
return nv::mem::malloc(size);
|
||||
}
|
||||
|
||||
inline void operator delete (void *p) throw()
|
||||
{
|
||||
nv::mem::free(p);
|
||||
}
|
||||
|
||||
inline void * operator new [] (size_t size) throw()
|
||||
{
|
||||
return nv::mem::malloc(size);
|
||||
}
|
||||
|
||||
inline void operator delete [] (void * p) throw()
|
||||
{
|
||||
nv::mem::free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
#ifdef _DEBUG
|
||||
#define new new(__FILE__, __LINE__)
|
||||
#define malloc(i) malloc(i, __FILE__, __LINE__)
|
||||
#endif
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
File: main.cpp
|
||||
|
||||
Version: 1.0
|
||||
|
||||
Abstract: Overrides the C++ 'operator new' and 'operator delete'.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under Apple’s
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright © 2006 Apple Computer, Inc., All Rights Reserved
|
||||
*/
|
||||
|
||||
/* This sample shows how to override the C++ global 'new' and 'delete' operators. */
|
||||
#include <new>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <locale>
|
||||
|
||||
/* Some variables and code to make the example do something. */
|
||||
namespace {
|
||||
unsigned long long gNewCounter; // number of times 'new' was called
|
||||
unsigned long long gDeleteCounter; // number of times 'delete' was called
|
||||
|
||||
void printCounters() // print the counters above
|
||||
{
|
||||
std::cout << "new was called " << gNewCounter << " times and delete was called " << gDeleteCounter << " times\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* These are the overridden new and delete routines.
|
||||
Most applications will want to override at least these four versions of new/delete if they override any of them.
|
||||
|
||||
In Mac OS, it's not necessary to override the array versions of operator new and delete if all
|
||||
they would do is call the non-array versions; the C++ standard library, as an extension
|
||||
to the C++ standard, does this for you.
|
||||
|
||||
Developers should consult the section [lib.support.dynamic] in the C++ standard to see the requirements
|
||||
on the generic operators new and delete; the system may expect that your overridden operators meet all these
|
||||
requirements.
|
||||
|
||||
Your operators may be called by the system, even early in start-up before constructors have been executed. */
|
||||
void* operator new(std::size_t sz) throw (std::bad_alloc)
|
||||
{
|
||||
void *result = std::malloc (sz == 0 ? 1 : sz);
|
||||
if (result == NULL)
|
||||
throw std::bad_alloc();
|
||||
gNewCounter++;
|
||||
return result;
|
||||
}
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
if (p == NULL)
|
||||
return;
|
||||
std::free (p);
|
||||
gDeleteCounter++;
|
||||
}
|
||||
|
||||
/* These are the 'nothrow' versions of the above operators.
|
||||
The system version will try to call a std::new_handler if they
|
||||
fail, but your overriding versions are not required to do this. */
|
||||
void* operator new(std::size_t sz, const std::nothrow_t&) throw()
|
||||
{
|
||||
try {
|
||||
void * result = ::operator new (sz); // calls our overridden operator new
|
||||
return result;
|
||||
} catch (std::bad_alloc &) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
void operator delete(void* p, const std::nothrow_t&) throw()
|
||||
{
|
||||
::operator delete (p);
|
||||
}
|
||||
|
||||
/* Bug 4067110 is that if your program has no weak symbols at all, the linker will not set the
|
||||
WEAK_DEFINES bit in the Mach-O header and as a result the new and delete operators above won't
|
||||
be seen by system libraries. This is mostly a problem for test programs and small examples,
|
||||
since almost all real C++ programs complicated enough to override new and delete will have at
|
||||
least one weak symbol. However, this is a small example, so: */
|
||||
void __attribute__((weak, visibility("default"))) workaroundFor4067110 () { }
|
||||
|
||||
/* This is a simple test program that causes the runtime library to call new and delete. */
|
||||
int main()
|
||||
{
|
||||
atexit (printCounters);
|
||||
try {
|
||||
std::locale example("does_not_exist");
|
||||
} catch (std::runtime_error &x) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
#endif // NV_CORE_MEMORY_H
|
||||
// This code is in the public domain -- Ignacio Castaño <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_MEMORY_H
|
||||
#define NV_CORE_MEMORY_H
|
||||
|
||||
#include "nvcore.h"
|
||||
|
||||
#include <stdlib.h> // malloc(), realloc() and free()
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#include <new> // new and delete
|
||||
|
||||
// Custom memory allocator
|
||||
namespace nv
|
||||
{
|
||||
namespace mem
|
||||
{
|
||||
NVCORE_API void * malloc(size_t size);
|
||||
NVCORE_API void * malloc(size_t size, const char * file, int line);
|
||||
|
||||
NVCORE_API void free(const void * ptr);
|
||||
NVCORE_API void * realloc(void * ptr, size_t size);
|
||||
|
||||
} // mem namespace
|
||||
|
||||
} // nv namespace
|
||||
|
||||
|
||||
// Override new/delete
|
||||
|
||||
inline void * operator new (size_t size) throw()
|
||||
{
|
||||
return nv::mem::malloc(size);
|
||||
}
|
||||
|
||||
inline void operator delete (void *p) throw()
|
||||
{
|
||||
nv::mem::free(p);
|
||||
}
|
||||
|
||||
inline void * operator new [] (size_t size) throw()
|
||||
{
|
||||
return nv::mem::malloc(size);
|
||||
}
|
||||
|
||||
inline void operator delete [] (void * p) throw()
|
||||
{
|
||||
nv::mem::free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
#ifdef _DEBUG
|
||||
#define new new(__FILE__, __LINE__)
|
||||
#define malloc(i) malloc(i, __FILE__, __LINE__)
|
||||
#endif
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
File: main.cpp
|
||||
|
||||
Version: 1.0
|
||||
|
||||
Abstract: Overrides the C++ 'operator new' and 'operator delete'.
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
|
||||
("Apple") in consideration of your agreement to the following terms, and your
|
||||
use, installation, modification or redistribution of this Apple software
|
||||
constitutes acceptance of these terms. If you do not agree with these terms,
|
||||
please do not use, install, modify or redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and subject
|
||||
to these terms, Apple grants you a personal, non-exclusive license, under Apple’s
|
||||
copyrights in this original Apple software (the "Apple Software"), to use,
|
||||
reproduce, modify and redistribute the Apple Software, with or without
|
||||
modifications, in source and/or binary forms; provided that if you redistribute
|
||||
the Apple Software in its entirety and without modifications, you must retain
|
||||
this notice and the following text and disclaimers in all such redistributions of
|
||||
the Apple Software. Neither the name, trademarks, service marks or logos of
|
||||
Apple Computer, Inc. may be used to endorse or promote products derived from the
|
||||
Apple Software without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or implied,
|
||||
are granted by Apple herein, including but not limited to any patent rights that
|
||||
may be infringed by your derivative works or by other works in which the Apple
|
||||
Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
|
||||
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
|
||||
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
|
||||
COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
|
||||
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
|
||||
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright © 2006 Apple Computer, Inc., All Rights Reserved
|
||||
*/
|
||||
|
||||
/* This sample shows how to override the C++ global 'new' and 'delete' operators. */
|
||||
#include <new>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <locale>
|
||||
|
||||
/* Some variables and code to make the example do something. */
|
||||
namespace {
|
||||
unsigned long long gNewCounter; // number of times 'new' was called
|
||||
unsigned long long gDeleteCounter; // number of times 'delete' was called
|
||||
|
||||
void printCounters() // print the counters above
|
||||
{
|
||||
std::cout << "new was called " << gNewCounter << " times and delete was called " << gDeleteCounter << " times\n";
|
||||
}
|
||||
}
|
||||
|
||||
/* These are the overridden new and delete routines.
|
||||
Most applications will want to override at least these four versions of new/delete if they override any of them.
|
||||
|
||||
In Mac OS, it's not necessary to override the array versions of operator new and delete if all
|
||||
they would do is call the non-array versions; the C++ standard library, as an extension
|
||||
to the C++ standard, does this for you.
|
||||
|
||||
Developers should consult the section [lib.support.dynamic] in the C++ standard to see the requirements
|
||||
on the generic operators new and delete; the system may expect that your overridden operators meet all these
|
||||
requirements.
|
||||
|
||||
Your operators may be called by the system, even early in start-up before constructors have been executed. */
|
||||
void* operator new(std::size_t sz) throw (std::bad_alloc)
|
||||
{
|
||||
void *result = std::malloc (sz == 0 ? 1 : sz);
|
||||
if (result == NULL)
|
||||
throw std::bad_alloc();
|
||||
gNewCounter++;
|
||||
return result;
|
||||
}
|
||||
void operator delete(void* p) throw()
|
||||
{
|
||||
if (p == NULL)
|
||||
return;
|
||||
std::free (p);
|
||||
gDeleteCounter++;
|
||||
}
|
||||
|
||||
/* These are the 'nothrow' versions of the above operators.
|
||||
The system version will try to call a std::new_handler if they
|
||||
fail, but your overriding versions are not required to do this. */
|
||||
void* operator new(std::size_t sz, const std::nothrow_t&) throw()
|
||||
{
|
||||
try {
|
||||
void * result = ::operator new (sz); // calls our overridden operator new
|
||||
return result;
|
||||
} catch (std::bad_alloc &) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
void operator delete(void* p, const std::nothrow_t&) throw()
|
||||
{
|
||||
::operator delete (p);
|
||||
}
|
||||
|
||||
/* Bug 4067110 is that if your program has no weak symbols at all, the linker will not set the
|
||||
WEAK_DEFINES bit in the Mach-O header and as a result the new and delete operators above won't
|
||||
be seen by system libraries. This is mostly a problem for test programs and small examples,
|
||||
since almost all real C++ programs complicated enough to override new and delete will have at
|
||||
least one weak symbol. However, this is a small example, so: */
|
||||
void __attribute__((weak, visibility("default"))) workaroundFor4067110 () { }
|
||||
|
||||
/* This is a simple test program that causes the runtime library to call new and delete. */
|
||||
int main()
|
||||
{
|
||||
atexit (printCounters);
|
||||
try {
|
||||
std::locale example("does_not_exist");
|
||||
} catch (std::runtime_error &x) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
#endif // NV_CORE_MEMORY_H
|
||||
|
644
src/nvcore/Ptr.h
644
src/nvcore/Ptr.h
@ -1,322 +1,322 @@
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#ifndef NV_CORE_PTR_H
|
||||
#define NV_CORE_PTR_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Debug.h"
|
||||
|
||||
|
||||
|
||||
namespace nv
|
||||
{
|
||||
class WeakProxy;
|
||||
|
||||
/** Simple auto pointer template class.
|
||||
*
|
||||
* This is very similar to the standard auto_ptr class, but with some
|
||||
* additional limitations to make its use less error prone:
|
||||
* - Copy constructor and assignment operator are disabled.
|
||||
* - reset method is removed.
|
||||
*
|
||||
* The semantics of the standard auto_ptr are not clear and change depending
|
||||
* on the std implementation. For a discussion of the problems of auto_ptr read:
|
||||
* http://www.awprofessional.com/content/images/020163371X/autoptrupdate\auto_ptr_update.html
|
||||
*/
|
||||
template <class T>
|
||||
class AutoPtr
|
||||
{
|
||||
NV_FORBID_COPY(AutoPtr);
|
||||
NV_FORBID_HEAPALLOC();
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
AutoPtr(T * p = NULL) : m_ptr(p) { }
|
||||
|
||||
template <class Q>
|
||||
AutoPtr(Q * p) : m_ptr(static_cast<T *>(p)) { }
|
||||
|
||||
/// Dtor. Deletes owned pointer.
|
||||
~AutoPtr() {
|
||||
delete m_ptr;
|
||||
m_ptr = NULL;
|
||||
}
|
||||
|
||||
/// Delete owned pointer and assign new one.
|
||||
void operator=( T * p ) {
|
||||
if (p != m_ptr)
|
||||
{
|
||||
delete m_ptr;
|
||||
m_ptr = p;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Q>
|
||||
void operator=( Q * p ) {
|
||||
if (p != m_ptr)
|
||||
{
|
||||
delete m_ptr;
|
||||
m_ptr = static_cast<T *>(p);
|
||||
}
|
||||
}
|
||||
|
||||
/// Member access.
|
||||
T * operator -> () const {
|
||||
nvDebugCheck(m_ptr != NULL);
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/// Get reference.
|
||||
T & operator*() const {
|
||||
nvDebugCheck(m_ptr != NULL);
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
/// Get pointer.
|
||||
T * ptr() const { return m_ptr; }
|
||||
|
||||
/// Relinquish ownership of the underlying pointer and returns that pointer.
|
||||
T * release() {
|
||||
T * tmp = m_ptr;
|
||||
m_ptr = NULL;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// Const pointer equal comparation.
|
||||
friend bool operator == (const AutoPtr<T> & ap, const T * const p) {
|
||||
return (ap.ptr() == p);
|
||||
}
|
||||
|
||||
/// Const pointer nequal comparation.
|
||||
friend bool operator != (const AutoPtr<T> & ap, const T * const p) {
|
||||
return (ap.ptr() != p);
|
||||
}
|
||||
|
||||
/// Const pointer equal comparation.
|
||||
friend bool operator == (const T * const p, const AutoPtr<T> & ap) {
|
||||
return (ap.ptr() == p);
|
||||
}
|
||||
|
||||
/// Const pointer nequal comparation.
|
||||
friend bool operator != (const T * const p, const AutoPtr<T> & ap) {
|
||||
return (ap.ptr() != p);
|
||||
}
|
||||
|
||||
private:
|
||||
T * m_ptr;
|
||||
};
|
||||
|
||||
|
||||
/// Smart pointer template class.
|
||||
template <class BaseClass>
|
||||
class SmartPtr {
|
||||
public:
|
||||
|
||||
// BaseClass must implement addRef() and release().
|
||||
typedef SmartPtr<BaseClass> ThisType;
|
||||
|
||||
/// Default ctor.
|
||||
SmartPtr() : m_ptr(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/// Other type assignment.
|
||||
template <class OtherBase>
|
||||
SmartPtr( const SmartPtr<OtherBase> & tc )
|
||||
{
|
||||
m_ptr = static_cast<BaseClass *>( tc.ptr() );
|
||||
if (m_ptr) {
|
||||
m_ptr->addRef();
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy ctor.
|
||||
SmartPtr( const ThisType & bc )
|
||||
{
|
||||
m_ptr = bc.ptr();
|
||||
if (m_ptr) {
|
||||
m_ptr->addRef();
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy cast ctor. SmartPtr(NULL) is valid.
|
||||
explicit SmartPtr( BaseClass * bc )
|
||||
{
|
||||
m_ptr = bc;
|
||||
if (m_ptr) {
|
||||
m_ptr->addRef();
|
||||
}
|
||||
}
|
||||
|
||||
/// Dtor.
|
||||
~SmartPtr()
|
||||
{
|
||||
set(NULL);
|
||||
}
|
||||
|
||||
|
||||
/// -> operator.
|
||||
BaseClass * operator -> () const
|
||||
{
|
||||
nvCheck( m_ptr != NULL );
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/// * operator.
|
||||
BaseClass & operator*() const
|
||||
{
|
||||
nvCheck( m_ptr != NULL );
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
/// Get pointer.
|
||||
BaseClass * ptr() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/// Other type assignment.
|
||||
template <class OtherBase>
|
||||
void operator = ( const SmartPtr<OtherBase> & tc )
|
||||
{
|
||||
set( static_cast<BaseClass *>(tc.ptr()) );
|
||||
}
|
||||
|
||||
/// This type assignment.
|
||||
void operator = ( const ThisType & bc )
|
||||
{
|
||||
set( bc.ptr() );
|
||||
}
|
||||
|
||||
/// Pointer assignment.
|
||||
void operator = ( BaseClass * bc )
|
||||
{
|
||||
set( bc );
|
||||
}
|
||||
|
||||
|
||||
/// Other type equal comparation.
|
||||
template <class OtherBase>
|
||||
bool operator == ( const SmartPtr<OtherBase> & other ) const
|
||||
{
|
||||
return m_ptr == other.ptr();
|
||||
}
|
||||
|
||||
/// This type equal comparation.
|
||||
bool operator == ( const ThisType & bc ) const
|
||||
{
|
||||
return m_ptr == bc.ptr();
|
||||
}
|
||||
|
||||
/// Const pointer equal comparation.
|
||||
bool operator == ( const BaseClass * const bc ) const
|
||||
{
|
||||
return m_ptr == bc;
|
||||
}
|
||||
|
||||
/// Other type not equal comparation.
|
||||
template <class OtherBase>
|
||||
bool operator != ( const SmartPtr<OtherBase> & other ) const
|
||||
{
|
||||
return m_ptr != other.ptr();
|
||||
}
|
||||
|
||||
/// Other type not equal comparation.
|
||||
bool operator != ( const ThisType & bc ) const
|
||||
{
|
||||
return m_ptr != bc.ptr();
|
||||
}
|
||||
|
||||
/// Const pointer not equal comparation.
|
||||
bool operator != (const BaseClass * const bc) const
|
||||
{
|
||||
return m_ptr != bc;
|
||||
}
|
||||
|
||||
/// This type lower than comparation.
|
||||
bool operator < (const ThisType & p) const
|
||||
{
|
||||
return m_ptr < p.ptr();
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return isValidPtr(m_ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Set this pointer.
|
||||
void set( BaseClass * p )
|
||||
{
|
||||
if (p) p->addRef();
|
||||
if (m_ptr) m_ptr->release();
|
||||
m_ptr = p;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
BaseClass * m_ptr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Smart pointer template class.
|
||||
template <class T>
|
||||
class WeakPtr {
|
||||
public:
|
||||
|
||||
WeakPtr() {}
|
||||
|
||||
WeakPtr(T * p) { operator=(p); }
|
||||
WeakPtr(const SmartPtr<T> & p) { operator=(p.ptr()); }
|
||||
|
||||
// Default constructor and assignment from weak_ptr<T> are OK.
|
||||
|
||||
void operator=(T * p)
|
||||
{
|
||||
if (p) {
|
||||
m_proxy = p->getWeakProxy();
|
||||
nvDebugCheck(m_proxy != NULL);
|
||||
nvDebugCheck(m_proxy->ptr() == p);
|
||||
}
|
||||
else {
|
||||
m_proxy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void operator=(const SmartPtr<T> & ptr) { operator=(ptr.ptr()); }
|
||||
|
||||
bool operator==(const SmartPtr<T> & p) const { return ptr() == p.ptr(); }
|
||||
bool operator!=(const SmartPtr<T> & p) const { return ptr() != p.ptr(); }
|
||||
|
||||
bool operator==(const WeakPtr<T> & p) const { return ptr() == p.ptr(); }
|
||||
bool operator!=(const WeakPtr<T> & p) const { return ptr() != p.ptr(); }
|
||||
|
||||
bool operator==(T * p) const { return ptr() == p; }
|
||||
bool operator!=(T * p) const { return ptr() != p; }
|
||||
|
||||
T * operator->() const
|
||||
{
|
||||
T * p = ptr();
|
||||
nvDebugCheck(p != NULL);
|
||||
return p;
|
||||
}
|
||||
|
||||
T * ptr() const
|
||||
{
|
||||
if (m_proxy != NULL) {
|
||||
return static_cast<T *>(m_proxy->ptr());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
mutable SmartPtr<WeakProxy> m_proxy;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_PTR_H
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#ifndef NV_CORE_PTR_H
|
||||
#define NV_CORE_PTR_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Debug.h"
|
||||
|
||||
|
||||
|
||||
namespace nv
|
||||
{
|
||||
class WeakProxy;
|
||||
|
||||
/** Simple auto pointer template class.
|
||||
*
|
||||
* This is very similar to the standard auto_ptr class, but with some
|
||||
* additional limitations to make its use less error prone:
|
||||
* - Copy constructor and assignment operator are disabled.
|
||||
* - reset method is removed.
|
||||
*
|
||||
* The semantics of the standard auto_ptr are not clear and change depending
|
||||
* on the std implementation. For a discussion of the problems of auto_ptr read:
|
||||
* http://www.awprofessional.com/content/images/020163371X/autoptrupdate\auto_ptr_update.html
|
||||
*/
|
||||
template <class T>
|
||||
class AutoPtr
|
||||
{
|
||||
NV_FORBID_COPY(AutoPtr);
|
||||
NV_FORBID_HEAPALLOC();
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
AutoPtr(T * p = NULL) : m_ptr(p) { }
|
||||
|
||||
template <class Q>
|
||||
AutoPtr(Q * p) : m_ptr(static_cast<T *>(p)) { }
|
||||
|
||||
/// Dtor. Deletes owned pointer.
|
||||
~AutoPtr() {
|
||||
delete m_ptr;
|
||||
m_ptr = NULL;
|
||||
}
|
||||
|
||||
/// Delete owned pointer and assign new one.
|
||||
void operator=( T * p ) {
|
||||
if (p != m_ptr)
|
||||
{
|
||||
delete m_ptr;
|
||||
m_ptr = p;
|
||||
}
|
||||
}
|
||||
|
||||
template <class Q>
|
||||
void operator=( Q * p ) {
|
||||
if (p != m_ptr)
|
||||
{
|
||||
delete m_ptr;
|
||||
m_ptr = static_cast<T *>(p);
|
||||
}
|
||||
}
|
||||
|
||||
/// Member access.
|
||||
T * operator -> () const {
|
||||
nvDebugCheck(m_ptr != NULL);
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/// Get reference.
|
||||
T & operator*() const {
|
||||
nvDebugCheck(m_ptr != NULL);
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
/// Get pointer.
|
||||
T * ptr() const { return m_ptr; }
|
||||
|
||||
/// Relinquish ownership of the underlying pointer and returns that pointer.
|
||||
T * release() {
|
||||
T * tmp = m_ptr;
|
||||
m_ptr = NULL;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// Const pointer equal comparation.
|
||||
friend bool operator == (const AutoPtr<T> & ap, const T * const p) {
|
||||
return (ap.ptr() == p);
|
||||
}
|
||||
|
||||
/// Const pointer nequal comparation.
|
||||
friend bool operator != (const AutoPtr<T> & ap, const T * const p) {
|
||||
return (ap.ptr() != p);
|
||||
}
|
||||
|
||||
/// Const pointer equal comparation.
|
||||
friend bool operator == (const T * const p, const AutoPtr<T> & ap) {
|
||||
return (ap.ptr() == p);
|
||||
}
|
||||
|
||||
/// Const pointer nequal comparation.
|
||||
friend bool operator != (const T * const p, const AutoPtr<T> & ap) {
|
||||
return (ap.ptr() != p);
|
||||
}
|
||||
|
||||
private:
|
||||
T * m_ptr;
|
||||
};
|
||||
|
||||
|
||||
/// Smart pointer template class.
|
||||
template <class BaseClass>
|
||||
class SmartPtr {
|
||||
public:
|
||||
|
||||
// BaseClass must implement addRef() and release().
|
||||
typedef SmartPtr<BaseClass> ThisType;
|
||||
|
||||
/// Default ctor.
|
||||
SmartPtr() : m_ptr(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/// Other type assignment.
|
||||
template <class OtherBase>
|
||||
SmartPtr( const SmartPtr<OtherBase> & tc )
|
||||
{
|
||||
m_ptr = static_cast<BaseClass *>( tc.ptr() );
|
||||
if (m_ptr) {
|
||||
m_ptr->addRef();
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy ctor.
|
||||
SmartPtr( const ThisType & bc )
|
||||
{
|
||||
m_ptr = bc.ptr();
|
||||
if (m_ptr) {
|
||||
m_ptr->addRef();
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy cast ctor. SmartPtr(NULL) is valid.
|
||||
explicit SmartPtr( BaseClass * bc )
|
||||
{
|
||||
m_ptr = bc;
|
||||
if (m_ptr) {
|
||||
m_ptr->addRef();
|
||||
}
|
||||
}
|
||||
|
||||
/// Dtor.
|
||||
~SmartPtr()
|
||||
{
|
||||
set(NULL);
|
||||
}
|
||||
|
||||
|
||||
/// -> operator.
|
||||
BaseClass * operator -> () const
|
||||
{
|
||||
nvCheck( m_ptr != NULL );
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/// * operator.
|
||||
BaseClass & operator*() const
|
||||
{
|
||||
nvCheck( m_ptr != NULL );
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
/// Get pointer.
|
||||
BaseClass * ptr() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
/// Other type assignment.
|
||||
template <class OtherBase>
|
||||
void operator = ( const SmartPtr<OtherBase> & tc )
|
||||
{
|
||||
set( static_cast<BaseClass *>(tc.ptr()) );
|
||||
}
|
||||
|
||||
/// This type assignment.
|
||||
void operator = ( const ThisType & bc )
|
||||
{
|
||||
set( bc.ptr() );
|
||||
}
|
||||
|
||||
/// Pointer assignment.
|
||||
void operator = ( BaseClass * bc )
|
||||
{
|
||||
set( bc );
|
||||
}
|
||||
|
||||
|
||||
/// Other type equal comparation.
|
||||
template <class OtherBase>
|
||||
bool operator == ( const SmartPtr<OtherBase> & other ) const
|
||||
{
|
||||
return m_ptr == other.ptr();
|
||||
}
|
||||
|
||||
/// This type equal comparation.
|
||||
bool operator == ( const ThisType & bc ) const
|
||||
{
|
||||
return m_ptr == bc.ptr();
|
||||
}
|
||||
|
||||
/// Const pointer equal comparation.
|
||||
bool operator == ( const BaseClass * const bc ) const
|
||||
{
|
||||
return m_ptr == bc;
|
||||
}
|
||||
|
||||
/// Other type not equal comparation.
|
||||
template <class OtherBase>
|
||||
bool operator != ( const SmartPtr<OtherBase> & other ) const
|
||||
{
|
||||
return m_ptr != other.ptr();
|
||||
}
|
||||
|
||||
/// Other type not equal comparation.
|
||||
bool operator != ( const ThisType & bc ) const
|
||||
{
|
||||
return m_ptr != bc.ptr();
|
||||
}
|
||||
|
||||
/// Const pointer not equal comparation.
|
||||
bool operator != (const BaseClass * const bc) const
|
||||
{
|
||||
return m_ptr != bc;
|
||||
}
|
||||
|
||||
/// This type lower than comparation.
|
||||
bool operator < (const ThisType & p) const
|
||||
{
|
||||
return m_ptr < p.ptr();
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
return isValidPtr(m_ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Set this pointer.
|
||||
void set( BaseClass * p )
|
||||
{
|
||||
if (p) p->addRef();
|
||||
if (m_ptr) m_ptr->release();
|
||||
m_ptr = p;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
BaseClass * m_ptr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Smart pointer template class.
|
||||
template <class T>
|
||||
class WeakPtr {
|
||||
public:
|
||||
|
||||
WeakPtr() {}
|
||||
|
||||
WeakPtr(T * p) { operator=(p); }
|
||||
WeakPtr(const SmartPtr<T> & p) { operator=(p.ptr()); }
|
||||
|
||||
// Default constructor and assignment from weak_ptr<T> are OK.
|
||||
|
||||
void operator=(T * p)
|
||||
{
|
||||
if (p) {
|
||||
m_proxy = p->getWeakProxy();
|
||||
nvDebugCheck(m_proxy != NULL);
|
||||
nvDebugCheck(m_proxy->ptr() == p);
|
||||
}
|
||||
else {
|
||||
m_proxy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void operator=(const SmartPtr<T> & ptr) { operator=(ptr.ptr()); }
|
||||
|
||||
bool operator==(const SmartPtr<T> & p) const { return ptr() == p.ptr(); }
|
||||
bool operator!=(const SmartPtr<T> & p) const { return ptr() != p.ptr(); }
|
||||
|
||||
bool operator==(const WeakPtr<T> & p) const { return ptr() == p.ptr(); }
|
||||
bool operator!=(const WeakPtr<T> & p) const { return ptr() != p.ptr(); }
|
||||
|
||||
bool operator==(T * p) const { return ptr() == p; }
|
||||
bool operator!=(T * p) const { return ptr() != p; }
|
||||
|
||||
T * operator->() const
|
||||
{
|
||||
T * p = ptr();
|
||||
nvDebugCheck(p != NULL);
|
||||
return p;
|
||||
}
|
||||
|
||||
T * ptr() const
|
||||
{
|
||||
if (m_proxy != NULL) {
|
||||
return static_cast<T *>(m_proxy->ptr());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
mutable SmartPtr<WeakProxy> m_proxy;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_PTR_H
|
||||
|
@ -1,149 +1,149 @@
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#ifndef NV_CORE_REFCOUNTED_H
|
||||
#define NV_CORE_REFCOUNTED_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Debug.h"
|
||||
|
||||
#define NV_DECLARE_PTR(Class) \
|
||||
template <class T> class SmartPtr; \
|
||||
typedef SmartPtr<class Class> Class ## Ptr; \
|
||||
typedef SmartPtr<const class Class> Class ## ConstPtr
|
||||
|
||||
|
||||
namespace nv
|
||||
{
|
||||
/// Weak proxy.
|
||||
class WeakProxy
|
||||
{
|
||||
NV_FORBID_COPY(WeakProxy);
|
||||
public:
|
||||
/// Ctor.
|
||||
WeakProxy(void * ptr) : m_count(0), m_ptr(ptr) { }
|
||||
|
||||
/// Dtor.
|
||||
~WeakProxy()
|
||||
{
|
||||
nvCheck( m_count == 0 );
|
||||
}
|
||||
|
||||
/// Increase reference count.
|
||||
uint addRef() const
|
||||
{
|
||||
m_count++;
|
||||
return m_count;
|
||||
}
|
||||
|
||||
/// Decrease reference count and remove when 0.
|
||||
uint release() const
|
||||
{
|
||||
nvCheck( m_count > 0 );
|
||||
|
||||
m_count--;
|
||||
if( m_count == 0 ) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return m_count;
|
||||
}
|
||||
|
||||
/// WeakPtr's call this to determine if their pointer is valid or not.
|
||||
bool isAlive() const {
|
||||
return m_ptr != NULL;
|
||||
}
|
||||
|
||||
/// Only the actual object should call this.
|
||||
void notifyObjectDied() {
|
||||
m_ptr = NULL;
|
||||
}
|
||||
|
||||
/// Return proxy pointer.
|
||||
void * ptr() const {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable int m_count;
|
||||
void * m_ptr;
|
||||
};
|
||||
|
||||
|
||||
/// Reference counted base class to be used with SmartPtr and WeakPtr.
|
||||
class RefCounted
|
||||
{
|
||||
NV_FORBID_COPY(RefCounted);
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
RefCounted() : m_count(0), m_weak_proxy(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/// Virtual dtor.
|
||||
virtual ~RefCounted()
|
||||
{
|
||||
nvCheck( m_count == 0 );
|
||||
releaseWeakProxy();
|
||||
}
|
||||
|
||||
|
||||
/// Increase reference count.
|
||||
uint addRef() const
|
||||
{
|
||||
m_count++;
|
||||
return m_count;
|
||||
}
|
||||
|
||||
|
||||
/// Decrease reference count and remove when 0.
|
||||
uint release() const
|
||||
{
|
||||
nvCheck( m_count > 0 );
|
||||
|
||||
m_count--;
|
||||
if( m_count == 0 ) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return m_count;
|
||||
}
|
||||
|
||||
/// Get weak proxy.
|
||||
WeakProxy * getWeakProxy() const
|
||||
{
|
||||
if (m_weak_proxy == NULL) {
|
||||
m_weak_proxy = new WeakProxy((void *)this);
|
||||
m_weak_proxy->addRef();
|
||||
}
|
||||
return m_weak_proxy;
|
||||
}
|
||||
|
||||
/// Release the weak proxy.
|
||||
void releaseWeakProxy() const
|
||||
{
|
||||
if (m_weak_proxy != NULL) {
|
||||
m_weak_proxy->notifyObjectDied();
|
||||
m_weak_proxy->release();
|
||||
m_weak_proxy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get reference count.
|
||||
int refCount() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
mutable int m_count;
|
||||
mutable WeakProxy * m_weak_proxy;
|
||||
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
|
||||
#endif // NV_CORE_REFCOUNTED_H
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#ifndef NV_CORE_REFCOUNTED_H
|
||||
#define NV_CORE_REFCOUNTED_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Debug.h"
|
||||
|
||||
#define NV_DECLARE_PTR(Class) \
|
||||
template <class T> class SmartPtr; \
|
||||
typedef SmartPtr<class Class> Class ## Ptr; \
|
||||
typedef SmartPtr<const class Class> Class ## ConstPtr
|
||||
|
||||
|
||||
namespace nv
|
||||
{
|
||||
/// Weak proxy.
|
||||
class WeakProxy
|
||||
{
|
||||
NV_FORBID_COPY(WeakProxy);
|
||||
public:
|
||||
/// Ctor.
|
||||
WeakProxy(void * ptr) : m_count(0), m_ptr(ptr) { }
|
||||
|
||||
/// Dtor.
|
||||
~WeakProxy()
|
||||
{
|
||||
nvCheck( m_count == 0 );
|
||||
}
|
||||
|
||||
/// Increase reference count.
|
||||
uint addRef() const
|
||||
{
|
||||
m_count++;
|
||||
return m_count;
|
||||
}
|
||||
|
||||
/// Decrease reference count and remove when 0.
|
||||
uint release() const
|
||||
{
|
||||
nvCheck( m_count > 0 );
|
||||
|
||||
m_count--;
|
||||
if( m_count == 0 ) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return m_count;
|
||||
}
|
||||
|
||||
/// WeakPtr's call this to determine if their pointer is valid or not.
|
||||
bool isAlive() const {
|
||||
return m_ptr != NULL;
|
||||
}
|
||||
|
||||
/// Only the actual object should call this.
|
||||
void notifyObjectDied() {
|
||||
m_ptr = NULL;
|
||||
}
|
||||
|
||||
/// Return proxy pointer.
|
||||
void * ptr() const {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable int m_count;
|
||||
void * m_ptr;
|
||||
};
|
||||
|
||||
|
||||
/// Reference counted base class to be used with SmartPtr and WeakPtr.
|
||||
class RefCounted
|
||||
{
|
||||
NV_FORBID_COPY(RefCounted);
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
RefCounted() : m_count(0), m_weak_proxy(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/// Virtual dtor.
|
||||
virtual ~RefCounted()
|
||||
{
|
||||
nvCheck( m_count == 0 );
|
||||
releaseWeakProxy();
|
||||
}
|
||||
|
||||
|
||||
/// Increase reference count.
|
||||
uint addRef() const
|
||||
{
|
||||
m_count++;
|
||||
return m_count;
|
||||
}
|
||||
|
||||
|
||||
/// Decrease reference count and remove when 0.
|
||||
uint release() const
|
||||
{
|
||||
nvCheck( m_count > 0 );
|
||||
|
||||
m_count--;
|
||||
if( m_count == 0 ) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return m_count;
|
||||
}
|
||||
|
||||
/// Get weak proxy.
|
||||
WeakProxy * getWeakProxy() const
|
||||
{
|
||||
if (m_weak_proxy == NULL) {
|
||||
m_weak_proxy = new WeakProxy((void *)this);
|
||||
m_weak_proxy->addRef();
|
||||
}
|
||||
return m_weak_proxy;
|
||||
}
|
||||
|
||||
/// Release the weak proxy.
|
||||
void releaseWeakProxy() const
|
||||
{
|
||||
if (m_weak_proxy != NULL) {
|
||||
m_weak_proxy->notifyObjectDied();
|
||||
m_weak_proxy->release();
|
||||
m_weak_proxy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get reference count.
|
||||
int refCount() const
|
||||
{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
mutable int m_count;
|
||||
mutable WeakProxy * m_weak_proxy;
|
||||
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
|
||||
#endif // NV_CORE_REFCOUNTED_H
|
||||
|
@ -1,373 +1,369 @@
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_STDSTREAM_H
|
||||
#define NV_CORE_STDSTREAM_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Stream.h"
|
||||
|
||||
#include <stdio.h> // fopen
|
||||
#include <string.h> // memcpy
|
||||
#include <exception> // std::exception
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
// Portable version of fopen.
|
||||
inline FILE * fileOpen(const char * fileName, const char * mode)
|
||||
{
|
||||
nvCheck(fileName != NULL);
|
||||
#if NV_CC_MSVC && _MSC_VER >= 1400
|
||||
FILE * fp;
|
||||
if (fopen_s(&fp, fileName, mode) == 0) {
|
||||
return fp;
|
||||
}
|
||||
return NULL;
|
||||
#else
|
||||
return fopen(fileName, mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// Base stdio stream.
|
||||
class NVCORE_CLASS StdStream : public Stream
|
||||
{
|
||||
NV_FORBID_COPY(StdStream);
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
StdStream( FILE * fp, bool autoclose=true ) :
|
||||
m_fp(fp), m_autoclose(autoclose) { }
|
||||
|
||||
/// Dtor.
|
||||
virtual ~StdStream()
|
||||
{
|
||||
if( m_fp != NULL && m_autoclose ) {
|
||||
fclose( m_fp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
virtual void seek( uint pos )
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
nvDebugCheck(pos < size());
|
||||
fseek(m_fp, pos, SEEK_SET);
|
||||
}
|
||||
|
||||
virtual uint tell() const
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
return ftell(m_fp);
|
||||
}
|
||||
|
||||
virtual uint size() const
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
uint pos = ftell(m_fp);
|
||||
fseek(m_fp, 0, SEEK_END);
|
||||
uint end = ftell(m_fp);
|
||||
fseek(m_fp, pos, SEEK_SET);
|
||||
return end;
|
||||
}
|
||||
|
||||
virtual bool isError() const
|
||||
{
|
||||
return m_fp == NULL || ferror( m_fp ) != 0;
|
||||
}
|
||||
|
||||
virtual void clearError()
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
clearerr(m_fp);
|
||||
}
|
||||
|
||||
virtual bool isAtEnd() const
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
return feof( m_fp ) != 0;
|
||||
}
|
||||
|
||||
/// Always true.
|
||||
virtual bool isSeekable() const { return true; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
FILE * m_fp;
|
||||
bool m_autoclose;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Standard output stream.
|
||||
class NVCORE_CLASS StdOutputStream : public StdStream
|
||||
{
|
||||
NV_FORBID_COPY(StdOutputStream);
|
||||
public:
|
||||
|
||||
/// Construct stream by file name.
|
||||
StdOutputStream( const char * name ) :
|
||||
StdStream(fileOpen(name, "wb")) { }
|
||||
|
||||
/// Construct stream by file handle.
|
||||
StdOutputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose)
|
||||
{
|
||||
}
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
/// Write data.
|
||||
virtual uint serialize( void * data, uint len )
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
return (uint)fwrite(data, 1, len, m_fp);
|
||||
}
|
||||
|
||||
virtual bool isLoading() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool isSaving() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Standard input stream.
|
||||
class NVCORE_CLASS StdInputStream : public StdStream
|
||||
{
|
||||
NV_FORBID_COPY(StdInputStream);
|
||||
public:
|
||||
|
||||
/// Construct stream by file name.
|
||||
StdInputStream( const char * name ) :
|
||||
StdStream(fileOpen(name, "rb")) { }
|
||||
|
||||
/// Construct stream by file handle.
|
||||
StdInputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose)
|
||||
{
|
||||
}
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
/// Read data.
|
||||
virtual uint serialize( void * data, uint len )
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
return (uint)fread(data, 1, len, m_fp);
|
||||
}
|
||||
|
||||
virtual bool isLoading() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isSaving() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//@}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Memory input stream.
|
||||
class NVCORE_CLASS MemoryInputStream : public Stream
|
||||
{
|
||||
NV_FORBID_COPY(MemoryInputStream);
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
MemoryInputStream( const uint8 * mem, uint size ) :
|
||||
m_mem(mem), m_ptr(mem), m_size(size) { }
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
/// Read data.
|
||||
virtual uint serialize( void * data, uint len )
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
nvDebugCheck(!isError());
|
||||
|
||||
uint left = m_size - tell();
|
||||
if (len > left) len = left;
|
||||
|
||||
memcpy( data, m_ptr, len );
|
||||
m_ptr += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
virtual void seek( uint pos )
|
||||
{
|
||||
nvDebugCheck(!isError());
|
||||
m_ptr = m_mem + pos;
|
||||
nvDebugCheck(!isError());
|
||||
}
|
||||
|
||||
virtual uint tell() const
|
||||
{
|
||||
nvDebugCheck(m_ptr >= m_mem);
|
||||
return uint(m_ptr - m_mem);
|
||||
}
|
||||
|
||||
virtual uint size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
virtual bool isError() const
|
||||
{
|
||||
return m_mem == NULL || m_ptr > m_mem + m_size || m_ptr < m_mem;
|
||||
}
|
||||
|
||||
virtual void clearError()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
virtual bool isAtEnd() const
|
||||
{
|
||||
return m_ptr == m_mem + m_size;
|
||||
}
|
||||
|
||||
/// Always true.
|
||||
virtual bool isSeekable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isLoading() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isSaving() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
const uint8 * m_mem;
|
||||
const uint8 * m_ptr;
|
||||
uint m_size;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Protected input stream.
|
||||
class NVCORE_CLASS ProtectedStream : public Stream
|
||||
{
|
||||
NV_FORBID_COPY(ProtectedStream);
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
ProtectedStream( Stream & s ) : m_s(&s), m_autodelete(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// Ctor.
|
||||
ProtectedStream( Stream * s, bool autodelete = true ) :
|
||||
m_s(s), m_autodelete(autodelete)
|
||||
{
|
||||
nvDebugCheck(m_s != NULL);
|
||||
}
|
||||
|
||||
/// Dtor.
|
||||
virtual ~ProtectedStream()
|
||||
{
|
||||
if( m_autodelete ) {
|
||||
delete m_s;
|
||||
}
|
||||
}
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
/// Read data.
|
||||
virtual uint serialize( void * data, uint len )
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
len = m_s->serialize( data, len );
|
||||
|
||||
if( m_s->isError() ) {
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
virtual void seek( uint pos )
|
||||
{
|
||||
m_s->seek( pos );
|
||||
|
||||
if( m_s->isError() ) {
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
virtual uint tell() const
|
||||
{
|
||||
return m_s->tell();
|
||||
}
|
||||
|
||||
virtual uint size() const
|
||||
{
|
||||
return m_s->size();
|
||||
}
|
||||
|
||||
virtual bool isError() const
|
||||
{
|
||||
return m_s->isError();
|
||||
}
|
||||
|
||||
virtual void clearError()
|
||||
{
|
||||
m_s->clearError();
|
||||
}
|
||||
|
||||
virtual bool isAtEnd() const
|
||||
{
|
||||
return m_s->isAtEnd();
|
||||
}
|
||||
|
||||
virtual bool isSeekable() const
|
||||
{
|
||||
return m_s->isSeekable();
|
||||
}
|
||||
|
||||
virtual bool isLoading() const
|
||||
{
|
||||
return m_s->isLoading();
|
||||
}
|
||||
|
||||
virtual bool isSaving() const
|
||||
{
|
||||
return m_s->isSaving();
|
||||
}
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Stream * const m_s;
|
||||
bool const m_autodelete;
|
||||
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
|
||||
#endif // NV_CORE_STDSTREAM_H
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_STDSTREAM_H
|
||||
#define NV_CORE_STDSTREAM_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Stream.h"
|
||||
|
||||
#include <stdio.h> // fopen
|
||||
#include <string.h> // memcpy
|
||||
#include <exception> // std::exception
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
// Portable version of fopen.
|
||||
inline FILE * fileOpen(const char * fileName, const char * mode)
|
||||
{
|
||||
nvCheck(fileName != NULL);
|
||||
#if NV_CC_MSVC && _MSC_VER >= 1400
|
||||
FILE * fp;
|
||||
if (fopen_s(&fp, fileName, mode) == 0) {
|
||||
return fp;
|
||||
}
|
||||
return NULL;
|
||||
#else
|
||||
return fopen(fileName, mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// Base stdio stream.
|
||||
class NVCORE_CLASS StdStream : public Stream
|
||||
{
|
||||
NV_FORBID_COPY(StdStream);
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
StdStream( FILE * fp, bool autoclose=true ) : m_fp(fp), m_autoclose(autoclose) { }
|
||||
|
||||
/// Dtor.
|
||||
virtual ~StdStream()
|
||||
{
|
||||
if( m_fp != NULL && m_autoclose ) {
|
||||
_fclose_nolock( m_fp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
virtual void seek( uint pos )
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
nvDebugCheck(pos < size());
|
||||
_fseek_nolock(m_fp, pos, SEEK_SET);
|
||||
}
|
||||
|
||||
virtual uint tell() const
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
return _ftell_nolock(m_fp);
|
||||
}
|
||||
|
||||
virtual uint size() const
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
uint pos = ftell(m_fp);
|
||||
_fseek_nolock(m_fp, 0, SEEK_END);
|
||||
uint end = ftell(m_fp);
|
||||
_fseek_nolock(m_fp, pos, SEEK_SET);
|
||||
return end;
|
||||
}
|
||||
|
||||
virtual bool isError() const
|
||||
{
|
||||
return m_fp == NULL || ferror( m_fp ) != 0;
|
||||
}
|
||||
|
||||
virtual void clearError()
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
clearerr(m_fp);
|
||||
}
|
||||
|
||||
virtual bool isAtEnd() const
|
||||
{
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
return feof( m_fp ) != 0;
|
||||
}
|
||||
|
||||
/// Always true.
|
||||
virtual bool isSeekable() const { return true; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
FILE * m_fp;
|
||||
bool m_autoclose;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Standard output stream.
|
||||
class NVCORE_CLASS StdOutputStream : public StdStream
|
||||
{
|
||||
NV_FORBID_COPY(StdOutputStream);
|
||||
public:
|
||||
|
||||
/// Construct stream by file name.
|
||||
StdOutputStream( const char * name ) : StdStream(fileOpen(name, "wb")) { }
|
||||
|
||||
/// Construct stream by file handle.
|
||||
StdOutputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose)
|
||||
{
|
||||
}
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
/// Write data.
|
||||
virtual uint serialize( void * data, uint len )
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
return (uint)_fwrite_nolock(data, 1, len, m_fp);
|
||||
}
|
||||
|
||||
virtual bool isLoading() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool isSaving() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Standard input stream.
|
||||
class NVCORE_CLASS StdInputStream : public StdStream
|
||||
{
|
||||
NV_FORBID_COPY(StdInputStream);
|
||||
public:
|
||||
|
||||
/// Construct stream by file name.
|
||||
StdInputStream( const char * name ) : StdStream(fileOpen(name, "rb")) { }
|
||||
|
||||
/// Construct stream by file handle.
|
||||
StdInputStream( FILE * fp, bool autoclose=true ) : StdStream(fp, autoclose)
|
||||
{
|
||||
}
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
/// Read data.
|
||||
virtual uint serialize( void * data, uint len )
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
nvDebugCheck(m_fp != NULL);
|
||||
return (uint)_fread_nolock(data, 1, len, m_fp);
|
||||
}
|
||||
|
||||
virtual bool isLoading() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isSaving() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//@}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Memory input stream.
|
||||
class NVCORE_CLASS MemoryInputStream : public Stream
|
||||
{
|
||||
NV_FORBID_COPY(MemoryInputStream);
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
MemoryInputStream( const uint8 * mem, uint size ) : m_mem(mem), m_ptr(mem), m_size(size) { }
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
/// Read data.
|
||||
virtual uint serialize( void * data, uint len )
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
nvDebugCheck(!isError());
|
||||
|
||||
uint left = m_size - tell();
|
||||
if (len > left) len = left;
|
||||
|
||||
memcpy( data, m_ptr, len );
|
||||
m_ptr += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
virtual void seek( uint pos )
|
||||
{
|
||||
nvDebugCheck(!isError());
|
||||
m_ptr = m_mem + pos;
|
||||
nvDebugCheck(!isError());
|
||||
}
|
||||
|
||||
virtual uint tell() const
|
||||
{
|
||||
nvDebugCheck(m_ptr >= m_mem);
|
||||
return uint(m_ptr - m_mem);
|
||||
}
|
||||
|
||||
virtual uint size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
virtual bool isError() const
|
||||
{
|
||||
return m_mem == NULL || m_ptr > m_mem + m_size || m_ptr < m_mem;
|
||||
}
|
||||
|
||||
virtual void clearError()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
virtual bool isAtEnd() const
|
||||
{
|
||||
return m_ptr == m_mem + m_size;
|
||||
}
|
||||
|
||||
/// Always true.
|
||||
virtual bool isSeekable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isLoading() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool isSaving() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
const uint8 * m_mem;
|
||||
const uint8 * m_ptr;
|
||||
uint m_size;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Protected input stream.
|
||||
class NVCORE_CLASS ProtectedStream : public Stream
|
||||
{
|
||||
NV_FORBID_COPY(ProtectedStream);
|
||||
public:
|
||||
|
||||
/// Ctor.
|
||||
ProtectedStream( Stream & s ) : m_s(&s), m_autodelete(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// Ctor.
|
||||
ProtectedStream( Stream * s, bool autodelete = true ) :
|
||||
m_s(s), m_autodelete(autodelete)
|
||||
{
|
||||
nvDebugCheck(m_s != NULL);
|
||||
}
|
||||
|
||||
/// Dtor.
|
||||
virtual ~ProtectedStream()
|
||||
{
|
||||
if( m_autodelete ) {
|
||||
delete m_s;
|
||||
}
|
||||
}
|
||||
|
||||
/** @name Stream implementation. */
|
||||
//@{
|
||||
/// Read data.
|
||||
virtual uint serialize( void * data, uint len )
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
len = m_s->serialize( data, len );
|
||||
|
||||
if( m_s->isError() ) {
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
virtual void seek( uint pos )
|
||||
{
|
||||
m_s->seek( pos );
|
||||
|
||||
if( m_s->isError() ) {
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
virtual uint tell() const
|
||||
{
|
||||
return m_s->tell();
|
||||
}
|
||||
|
||||
virtual uint size() const
|
||||
{
|
||||
return m_s->size();
|
||||
}
|
||||
|
||||
virtual bool isError() const
|
||||
{
|
||||
return m_s->isError();
|
||||
}
|
||||
|
||||
virtual void clearError()
|
||||
{
|
||||
m_s->clearError();
|
||||
}
|
||||
|
||||
virtual bool isAtEnd() const
|
||||
{
|
||||
return m_s->isAtEnd();
|
||||
}
|
||||
|
||||
virtual bool isSeekable() const
|
||||
{
|
||||
return m_s->isSeekable();
|
||||
}
|
||||
|
||||
virtual bool isLoading() const
|
||||
{
|
||||
return m_s->isLoading();
|
||||
}
|
||||
|
||||
virtual bool isSaving() const
|
||||
{
|
||||
return m_s->isSaving();
|
||||
}
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
Stream * const m_s;
|
||||
bool const m_autodelete;
|
||||
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
|
||||
#endif // NV_CORE_STDSTREAM_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,376 +1,379 @@
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_STRING_H
|
||||
#define NV_CORE_STRING_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Memory.h"
|
||||
#include "Utils.h" // swap, hash
|
||||
|
||||
#include <string.h> // strlen, strcmp, etc.
|
||||
|
||||
#if NV_OS_WIN32
|
||||
#define NV_PATH_SEPARATOR '\\'
|
||||
#else
|
||||
#define NV_PATH_SEPARATOR '/'
|
||||
#endif
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
uint strHash(const char * str, uint h) NV_PURE;
|
||||
|
||||
/// String hash based on Bernstein's hash.
|
||||
inline uint strHash(const char * data, uint h = 5381)
|
||||
{
|
||||
uint i = 0;
|
||||
while(data[i] != 0) {
|
||||
h = (33 * h) ^ uint(data[i]);
|
||||
i++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
template <> struct Hash<const char *> {
|
||||
uint operator()(const char * str) const { return strHash(str); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
NVCORE_API int strCaseCmp(const char * s1, const char * s2) NV_PURE;
|
||||
NVCORE_API int strCmp(const char * s1, const char * s2) NV_PURE;
|
||||
|
||||
template <> struct Equal<const char *> {
|
||||
bool operator()(const char * a, const char * b) const { return strCmp(a, b) == 0; }
|
||||
};
|
||||
|
||||
|
||||
NVCORE_API void strCpy(char * dst, int size, const char * src);
|
||||
NVCORE_API void strCpy(char * dst, int size, const char * src, int len);
|
||||
NVCORE_API void strCat(char * dst, int size, const char * src);
|
||||
|
||||
NVCORE_API bool strMatch(const char * str, const char * pat) NV_PURE;
|
||||
|
||||
|
||||
/// String builder.
|
||||
class NVCORE_CLASS StringBuilder
|
||||
{
|
||||
public:
|
||||
|
||||
StringBuilder();
|
||||
explicit StringBuilder( int size_hint );
|
||||
StringBuilder( const char * str, int extra_size_hint = 0);
|
||||
StringBuilder( const StringBuilder & );
|
||||
|
||||
~StringBuilder();
|
||||
|
||||
StringBuilder & format( const char * format, ... ) __attribute__((format (printf, 2, 3)));
|
||||
StringBuilder & formatList( const char * format, va_list arg );
|
||||
|
||||
StringBuilder & append( const char * str );
|
||||
StringBuilder & appendFormat( const char * format, ... ) __attribute__((format (printf, 2, 3)));
|
||||
StringBuilder & appendFormatList( const char * format, va_list arg );
|
||||
|
||||
StringBuilder & number( int i, int base = 10 );
|
||||
StringBuilder & number( uint i, int base = 10 );
|
||||
|
||||
StringBuilder & reserve( uint size_hint );
|
||||
StringBuilder & copy( const char * str, int extra_size/*=0*/ );
|
||||
StringBuilder & copy( const StringBuilder & str );
|
||||
|
||||
StringBuilder & toLower();
|
||||
StringBuilder & toUpper();
|
||||
|
||||
void reset();
|
||||
bool isNull() const { return m_size == 0; }
|
||||
|
||||
// const char * accessors
|
||||
operator const char * () const { return m_str; }
|
||||
operator char * () { return m_str; }
|
||||
const char * str() const { return m_str; }
|
||||
char * str() { return m_str; }
|
||||
|
||||
char * release();
|
||||
|
||||
/// Implement value semantics.
|
||||
StringBuilder & operator=( const StringBuilder & s ) {
|
||||
return copy(s);
|
||||
}
|
||||
|
||||
/// Implement value semantics.
|
||||
StringBuilder & operator=( const char * s ) {
|
||||
return copy(s);
|
||||
}
|
||||
|
||||
/// Equal operator.
|
||||
bool operator==( const StringBuilder & s ) const {
|
||||
if (s.isNull()) return isNull();
|
||||
else if (isNull()) return false;
|
||||
else return strcmp(s.m_str, m_str) != 0;
|
||||
}
|
||||
|
||||
/// Return the exact length.
|
||||
uint length() const { return isNull() ? 0 : uint(strlen(m_str)); }
|
||||
|
||||
/// Return the size of the string container.
|
||||
uint capacity() const { return m_size; }
|
||||
|
||||
/// Return the hash of the string.
|
||||
uint hash() const { return isNull() ? 0 : strHash(m_str); }
|
||||
|
||||
/// Swap strings.
|
||||
friend void swap(StringBuilder & a, StringBuilder & b) {
|
||||
nv::swap(a.m_size, b.m_size);
|
||||
nv::swap(a.m_str, b.m_str);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/// Size of the string container.
|
||||
uint m_size;
|
||||
|
||||
/// String.
|
||||
char * m_str;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Path string. @@ This should be called PathBuilder.
|
||||
class NVCORE_CLASS Path : public StringBuilder
|
||||
{
|
||||
public:
|
||||
Path() : StringBuilder() {}
|
||||
explicit Path(int size_hint) : StringBuilder(size_hint) {}
|
||||
Path(const char * str, int extra_size_hint = 0) : StringBuilder(str, extra_size_hint) {}
|
||||
Path(const Path & path) : StringBuilder(path) {}
|
||||
|
||||
const char * fileName() const;
|
||||
const char * extension() const;
|
||||
|
||||
void translatePath(char pathSeparator = NV_PATH_SEPARATOR);
|
||||
|
||||
void stripFileName();
|
||||
void stripExtension();
|
||||
|
||||
// statics
|
||||
NVCORE_API static char separator();
|
||||
NVCORE_API static const char * fileName(const char *);
|
||||
NVCORE_API static const char * extension(const char *);
|
||||
};
|
||||
|
||||
|
||||
/// String class.
|
||||
class NVCORE_CLASS String
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructs a null string. @sa isNull()
|
||||
String()
|
||||
{
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
/// Constructs a shared copy of str.
|
||||
String(const String & str)
|
||||
{
|
||||
data = str.data;
|
||||
if (data != NULL) addRef();
|
||||
}
|
||||
|
||||
/// Constructs a shared string from a standard string.
|
||||
String(const char * str)
|
||||
{
|
||||
setString(str);
|
||||
}
|
||||
|
||||
/// Constructs a shared string from a standard string.
|
||||
String(const char * str, int length)
|
||||
{
|
||||
setString(str, length);
|
||||
}
|
||||
|
||||
/// Constructs a shared string from a StringBuilder.
|
||||
String(const StringBuilder & str)
|
||||
{
|
||||
setString(str);
|
||||
}
|
||||
|
||||
/// Dtor.
|
||||
~String()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
String clone() const;
|
||||
|
||||
/// Release the current string and allocate a new one.
|
||||
const String & operator=( const char * str )
|
||||
{
|
||||
release();
|
||||
setString( str );
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Release the current string and allocate a new one.
|
||||
const String & operator=( const StringBuilder & str )
|
||||
{
|
||||
release();
|
||||
setString( str );
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Implement value semantics.
|
||||
String & operator=( const String & str )
|
||||
{
|
||||
if (str.data != data)
|
||||
{
|
||||
release();
|
||||
data = str.data;
|
||||
addRef();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Equal operator.
|
||||
bool operator==( const String & str ) const
|
||||
{
|
||||
if( str.data == data ) {
|
||||
return true;
|
||||
}
|
||||
if ((data == NULL) != (str.data == NULL)) {
|
||||
return false;
|
||||
}
|
||||
return strcmp(data, str.data) == 0;
|
||||
}
|
||||
|
||||
/// Equal operator.
|
||||
bool operator==( const char * str ) const
|
||||
{
|
||||
nvCheck(str != NULL); // Use isNull!
|
||||
if (data == NULL) {
|
||||
return false;
|
||||
}
|
||||
return strcmp(data, str) == 0;
|
||||
}
|
||||
|
||||
/// Not equal operator.
|
||||
bool operator!=( const String & str ) const
|
||||
{
|
||||
if( str.data == data ) {
|
||||
return false;
|
||||
}
|
||||
if ((data == NULL) != (str.data == NULL)) {
|
||||
return true;
|
||||
}
|
||||
return strcmp(data, str.data) != 0;
|
||||
}
|
||||
|
||||
/// Not equal operator.
|
||||
bool operator!=( const char * str ) const
|
||||
{
|
||||
nvCheck(str != NULL); // Use isNull!
|
||||
if (data == NULL) {
|
||||
return false;
|
||||
}
|
||||
return strcmp(data, str) != 0;
|
||||
}
|
||||
|
||||
/// Returns true if this string is the null string.
|
||||
bool isNull() const { return data == NULL; }
|
||||
|
||||
/// Return the exact length.
|
||||
uint length() const { nvDebugCheck(data != NULL); return uint(strlen(data)); }
|
||||
|
||||
/// Return the hash of the string.
|
||||
uint hash() const { nvDebugCheck(data != NULL); return strHash(data); }
|
||||
|
||||
/// const char * cast operator.
|
||||
operator const char * () const { return data; }
|
||||
|
||||
/// Get string pointer.
|
||||
const char * str() const { return data; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Add reference count.
|
||||
void addRef()
|
||||
{
|
||||
if (data != NULL)
|
||||
{
|
||||
setRefCount(getRefCount() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Decrease reference count.
|
||||
void release()
|
||||
{
|
||||
if (data != NULL)
|
||||
{
|
||||
const uint16 count = getRefCount();
|
||||
setRefCount(count - 1);
|
||||
if (count - 1 == 0) {
|
||||
mem::free(data - 2);
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16 getRefCount() const
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
return *reinterpret_cast<const uint16 *>(data - 2);
|
||||
}
|
||||
|
||||
void setRefCount(uint16 count) {
|
||||
nvDebugCheck(data != NULL);
|
||||
nvCheck(count < 0xFFFF);
|
||||
*reinterpret_cast<uint16 *>(const_cast<char *>(data - 2)) = uint16(count);
|
||||
}
|
||||
|
||||
void setData(const char * str) {
|
||||
data = str + 2;
|
||||
}
|
||||
|
||||
void allocString(const char * str)
|
||||
{
|
||||
allocString(str, (int)strlen(str));
|
||||
}
|
||||
|
||||
void allocString(const char * str, int len)
|
||||
{
|
||||
const char * ptr = static_cast<const char *>(mem::malloc(2 + len + 1));
|
||||
|
||||
setData( ptr );
|
||||
setRefCount( 0 );
|
||||
|
||||
// Copy string.
|
||||
strCpy(const_cast<char *>(data), len+1, str, len);
|
||||
|
||||
// Add terminating character.
|
||||
const_cast<char *>(data)[len] = '\0';
|
||||
}
|
||||
|
||||
void setString(const char * str);
|
||||
void setString(const char * str, int length);
|
||||
void setString(const StringBuilder & str);
|
||||
|
||||
/// Swap strings.
|
||||
friend void swap(String & a, String & b) {
|
||||
swap(a.data, b.data);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const char * data;
|
||||
|
||||
};
|
||||
|
||||
template <> struct Hash<String> {
|
||||
uint operator()(const String & str) const { return str.hash(); }
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_STRING_H
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_STRING_H
|
||||
#define NV_CORE_STRING_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Memory.h"
|
||||
#include "Utils.h" // swap, hash
|
||||
|
||||
#include <string.h> // strlen, strcmp, etc.
|
||||
|
||||
#if NV_OS_WIN32
|
||||
#define NV_PATH_SEPARATOR '\\'
|
||||
#else
|
||||
#define NV_PATH_SEPARATOR '/'
|
||||
#endif
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
uint strHash(const char * str, uint h) NV_PURE;
|
||||
|
||||
/// String hash based on Bernstein's hash.
|
||||
inline uint strHash(const char * data, uint h = 5381)
|
||||
{
|
||||
uint i = 0;
|
||||
while(data[i] != 0) {
|
||||
h = (33 * h) ^ uint(data[i]);
|
||||
i++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
template <> struct Hash<const char *> {
|
||||
uint operator()(const char * str) const { return strHash(str); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
NVCORE_API int strCaseCmp(const char * s1, const char * s2) NV_PURE;
|
||||
NVCORE_API int strCmp(const char * s1, const char * s2) NV_PURE;
|
||||
|
||||
template <> struct Equal<const char *> {
|
||||
bool operator()(const char * a, const char * b) const { return strCmp(a, b) == 0; }
|
||||
};
|
||||
|
||||
|
||||
NVCORE_API void strCpy(char * dst, int size, const char * src);
|
||||
NVCORE_API void strCpy(char * dst, int size, const char * src, int len);
|
||||
NVCORE_API void strCat(char * dst, int size, const char * src);
|
||||
|
||||
NVCORE_API bool strMatch(const char * str, const char * pat) NV_PURE;
|
||||
|
||||
|
||||
/// String builder.
|
||||
class NVCORE_CLASS StringBuilder
|
||||
{
|
||||
public:
|
||||
|
||||
StringBuilder();
|
||||
explicit StringBuilder( int size_hint );
|
||||
StringBuilder( const char * str, int extra_size_hint = 0);
|
||||
StringBuilder( const StringBuilder & );
|
||||
|
||||
~StringBuilder();
|
||||
|
||||
StringBuilder & format( const char * format, ... ) __attribute__((format (printf, 2, 3)));
|
||||
StringBuilder & formatList( const char * format, va_list arg );
|
||||
|
||||
StringBuilder & append( const char * str );
|
||||
StringBuilder & appendFormat( const char * format, ... ) __attribute__((format (printf, 2, 3)));
|
||||
StringBuilder & appendFormatList( const char * format, va_list arg );
|
||||
|
||||
StringBuilder & number( int i, int base = 10 );
|
||||
StringBuilder & number( uint i, int base = 10 );
|
||||
|
||||
StringBuilder & reserve( uint size_hint );
|
||||
StringBuilder & copy( const char * str, int extra_size/*=0*/ );
|
||||
StringBuilder & copy( const StringBuilder & str );
|
||||
|
||||
StringBuilder & toLower();
|
||||
StringBuilder & toUpper();
|
||||
|
||||
bool endsWith(const char * str) const;
|
||||
bool beginsWith(const char * str) const;
|
||||
|
||||
void reset();
|
||||
bool isNull() const { return m_size == 0; }
|
||||
|
||||
// const char * accessors
|
||||
operator const char * () const { return m_str; }
|
||||
operator char * () { return m_str; }
|
||||
const char * str() const { return m_str; }
|
||||
char * str() { return m_str; }
|
||||
|
||||
char * release();
|
||||
|
||||
/// Implement value semantics.
|
||||
StringBuilder & operator=( const StringBuilder & s ) {
|
||||
return copy(s);
|
||||
}
|
||||
|
||||
/// Implement value semantics.
|
||||
StringBuilder & operator=( const char * s ) {
|
||||
return copy(s);
|
||||
}
|
||||
|
||||
/// Equal operator.
|
||||
bool operator==( const StringBuilder & s ) const {
|
||||
if (s.isNull()) return isNull();
|
||||
else if (isNull()) return false;
|
||||
else return strcmp(s.m_str, m_str) != 0;
|
||||
}
|
||||
|
||||
/// Return the exact length.
|
||||
uint length() const { return isNull() ? 0 : uint(strlen(m_str)); }
|
||||
|
||||
/// Return the size of the string container.
|
||||
uint capacity() const { return m_size; }
|
||||
|
||||
/// Return the hash of the string.
|
||||
uint hash() const { return isNull() ? 0 : strHash(m_str); }
|
||||
|
||||
/// Swap strings.
|
||||
friend void swap(StringBuilder & a, StringBuilder & b) {
|
||||
nv::swap(a.m_size, b.m_size);
|
||||
nv::swap(a.m_str, b.m_str);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/// Size of the string container.
|
||||
uint m_size;
|
||||
|
||||
/// String.
|
||||
char * m_str;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Path string. @@ This should be called PathBuilder.
|
||||
class NVCORE_CLASS Path : public StringBuilder
|
||||
{
|
||||
public:
|
||||
Path() : StringBuilder() {}
|
||||
explicit Path(int size_hint) : StringBuilder(size_hint) {}
|
||||
Path(const char * str, int extra_size_hint = 0) : StringBuilder(str, extra_size_hint) {}
|
||||
Path(const Path & path) : StringBuilder(path) {}
|
||||
|
||||
const char * fileName() const;
|
||||
const char * extension() const;
|
||||
|
||||
void translatePath(char pathSeparator = NV_PATH_SEPARATOR);
|
||||
|
||||
void stripFileName();
|
||||
void stripExtension();
|
||||
|
||||
// statics
|
||||
NVCORE_API static char separator();
|
||||
NVCORE_API static const char * fileName(const char *);
|
||||
NVCORE_API static const char * extension(const char *);
|
||||
};
|
||||
|
||||
|
||||
/// String class.
|
||||
class NVCORE_CLASS String
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructs a null string. @sa isNull()
|
||||
String()
|
||||
{
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
/// Constructs a shared copy of str.
|
||||
String(const String & str)
|
||||
{
|
||||
data = str.data;
|
||||
if (data != NULL) addRef();
|
||||
}
|
||||
|
||||
/// Constructs a shared string from a standard string.
|
||||
String(const char * str)
|
||||
{
|
||||
setString(str);
|
||||
}
|
||||
|
||||
/// Constructs a shared string from a standard string.
|
||||
String(const char * str, int length)
|
||||
{
|
||||
setString(str, length);
|
||||
}
|
||||
|
||||
/// Constructs a shared string from a StringBuilder.
|
||||
String(const StringBuilder & str)
|
||||
{
|
||||
setString(str);
|
||||
}
|
||||
|
||||
/// Dtor.
|
||||
~String()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
String clone() const;
|
||||
|
||||
/// Release the current string and allocate a new one.
|
||||
const String & operator=( const char * str )
|
||||
{
|
||||
release();
|
||||
setString( str );
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Release the current string and allocate a new one.
|
||||
const String & operator=( const StringBuilder & str )
|
||||
{
|
||||
release();
|
||||
setString( str );
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Implement value semantics.
|
||||
String & operator=( const String & str )
|
||||
{
|
||||
if (str.data != data)
|
||||
{
|
||||
release();
|
||||
data = str.data;
|
||||
addRef();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Equal operator.
|
||||
bool operator==( const String & str ) const
|
||||
{
|
||||
if( str.data == data ) {
|
||||
return true;
|
||||
}
|
||||
if ((data == NULL) != (str.data == NULL)) {
|
||||
return false;
|
||||
}
|
||||
return strcmp(data, str.data) == 0;
|
||||
}
|
||||
|
||||
/// Equal operator.
|
||||
bool operator==( const char * str ) const
|
||||
{
|
||||
nvCheck(str != NULL); // Use isNull!
|
||||
if (data == NULL) {
|
||||
return false;
|
||||
}
|
||||
return strcmp(data, str) == 0;
|
||||
}
|
||||
|
||||
/// Not equal operator.
|
||||
bool operator!=( const String & str ) const
|
||||
{
|
||||
if( str.data == data ) {
|
||||
return false;
|
||||
}
|
||||
if ((data == NULL) != (str.data == NULL)) {
|
||||
return true;
|
||||
}
|
||||
return strcmp(data, str.data) != 0;
|
||||
}
|
||||
|
||||
/// Not equal operator.
|
||||
bool operator!=( const char * str ) const
|
||||
{
|
||||
nvCheck(str != NULL); // Use isNull!
|
||||
if (data == NULL) {
|
||||
return false;
|
||||
}
|
||||
return strcmp(data, str) != 0;
|
||||
}
|
||||
|
||||
/// Returns true if this string is the null string.
|
||||
bool isNull() const { return data == NULL; }
|
||||
|
||||
/// Return the exact length.
|
||||
uint length() const { nvDebugCheck(data != NULL); return uint(strlen(data)); }
|
||||
|
||||
/// Return the hash of the string.
|
||||
uint hash() const { nvDebugCheck(data != NULL); return strHash(data); }
|
||||
|
||||
/// const char * cast operator.
|
||||
operator const char * () const { return data; }
|
||||
|
||||
/// Get string pointer.
|
||||
const char * str() const { return data; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Add reference count.
|
||||
void addRef()
|
||||
{
|
||||
if (data != NULL)
|
||||
{
|
||||
setRefCount(getRefCount() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Decrease reference count.
|
||||
void release()
|
||||
{
|
||||
if (data != NULL)
|
||||
{
|
||||
const uint16 count = getRefCount();
|
||||
setRefCount(count - 1);
|
||||
if (count - 1 == 0) {
|
||||
mem::free(data - 2);
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16 getRefCount() const
|
||||
{
|
||||
nvDebugCheck(data != NULL);
|
||||
return *reinterpret_cast<const uint16 *>(data - 2);
|
||||
}
|
||||
|
||||
void setRefCount(uint16 count) {
|
||||
nvDebugCheck(data != NULL);
|
||||
nvCheck(count < 0xFFFF);
|
||||
*reinterpret_cast<uint16 *>(const_cast<char *>(data - 2)) = uint16(count);
|
||||
}
|
||||
|
||||
void setData(const char * str) {
|
||||
data = str + 2;
|
||||
}
|
||||
|
||||
void allocString(const char * str)
|
||||
{
|
||||
allocString(str, (int)strlen(str));
|
||||
}
|
||||
|
||||
void allocString(const char * str, int len)
|
||||
{
|
||||
const char * ptr = static_cast<const char *>(mem::malloc(2 + len + 1));
|
||||
|
||||
setData( ptr );
|
||||
setRefCount( 0 );
|
||||
|
||||
// Copy string.
|
||||
strCpy(const_cast<char *>(data), len+1, str, len);
|
||||
|
||||
// Add terminating character.
|
||||
const_cast<char *>(data)[len] = '\0';
|
||||
}
|
||||
|
||||
void setString(const char * str);
|
||||
void setString(const char * str, int length);
|
||||
void setString(const StringBuilder & str);
|
||||
|
||||
/// Swap strings.
|
||||
friend void swap(String & a, String & b) {
|
||||
swap(a.data, b.data);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const char * data;
|
||||
|
||||
};
|
||||
|
||||
template <> struct Hash<String> {
|
||||
uint operator()(const String & str) const { return str.hash(); }
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_STRING_H
|
||||
|
@ -1,161 +1,161 @@
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_STREAM_H
|
||||
#define NV_CORE_STREAM_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Debug.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
/// Base stream class.
|
||||
class NVCORE_CLASS Stream {
|
||||
public:
|
||||
|
||||
enum ByteOrder {
|
||||
LittleEndian = false,
|
||||
BigEndian = true,
|
||||
};
|
||||
|
||||
/// Get the byte order of the system.
|
||||
static ByteOrder getSystemByteOrder() {
|
||||
#if NV_LITTLE_ENDIAN
|
||||
return LittleEndian;
|
||||
#else
|
||||
return BigEndian;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// Ctor.
|
||||
Stream() : m_byteOrder(LittleEndian) { }
|
||||
|
||||
/// Virtual destructor.
|
||||
virtual ~Stream() {}
|
||||
|
||||
/// Set byte order.
|
||||
void setByteOrder(ByteOrder bo) { m_byteOrder = bo; }
|
||||
|
||||
/// Get byte order.
|
||||
ByteOrder byteOrder() const { return m_byteOrder; }
|
||||
|
||||
|
||||
/// Serialize the given data.
|
||||
virtual uint serialize( void * data, uint len ) = 0;
|
||||
|
||||
/// Move to the given position in the archive.
|
||||
virtual void seek( uint pos ) = 0;
|
||||
|
||||
/// Return the current position in the archive.
|
||||
virtual uint tell() const = 0;
|
||||
|
||||
/// Return the current size of the archive.
|
||||
virtual uint size() const = 0;
|
||||
|
||||
/// Determine if there has been any error.
|
||||
virtual bool isError() const = 0;
|
||||
|
||||
/// Clear errors.
|
||||
virtual void clearError() = 0;
|
||||
|
||||
/// Return true if the stream is at the end.
|
||||
virtual bool isAtEnd() const = 0;
|
||||
|
||||
/// Return true if the stream is seekable.
|
||||
virtual bool isSeekable() const = 0;
|
||||
|
||||
/// Return true if this is an input stream.
|
||||
virtual bool isLoading() const = 0;
|
||||
|
||||
/// Return true if this is an output stream.
|
||||
virtual bool isSaving() const = 0;
|
||||
|
||||
|
||||
// friends
|
||||
friend Stream & operator<<( Stream & s, bool & c ) {
|
||||
#if NV_OS_DARWIN
|
||||
nvStaticCheck(sizeof(bool) == 4);
|
||||
uint8 b = c ? 1 : 0;
|
||||
s.serialize( &b, 1 );
|
||||
c = (b == 1);
|
||||
#else
|
||||
nvStaticCheck(sizeof(bool) == 1);
|
||||
s.serialize( &c, 1 );
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, char & c ) {
|
||||
nvStaticCheck(sizeof(char) == 1);
|
||||
s.serialize( &c, 1 );
|
||||
return s;
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, uint8 & c ) {
|
||||
nvStaticCheck(sizeof(uint8) == 1);
|
||||
s.serialize( &c, 1 );
|
||||
return s;
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, int8 & c ) {
|
||||
nvStaticCheck(sizeof(int8) == 1);
|
||||
s.serialize( &c, 1 );
|
||||
return s;
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, uint16 & c ) {
|
||||
nvStaticCheck(sizeof(uint16) == 2);
|
||||
return s.byteOrderSerialize( &c, 2 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, int16 & c ) {
|
||||
nvStaticCheck(sizeof(int16) == 2);
|
||||
return s.byteOrderSerialize( &c, 2 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, uint32 & c ) {
|
||||
nvStaticCheck(sizeof(uint32) == 4);
|
||||
return s.byteOrderSerialize( &c, 4 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, int32 & c ) {
|
||||
nvStaticCheck(sizeof(int32) == 4);
|
||||
return s.byteOrderSerialize( &c, 4 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, uint64 & c ) {
|
||||
nvStaticCheck(sizeof(uint64) == 8);
|
||||
return s.byteOrderSerialize( &c, 8 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, int64 & c ) {
|
||||
nvStaticCheck(sizeof(int64) == 8);
|
||||
return s.byteOrderSerialize( &c, 8 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, float & c ) {
|
||||
nvStaticCheck(sizeof(float) == 4);
|
||||
return s.byteOrderSerialize( &c, 4 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, double & c ) {
|
||||
nvStaticCheck(sizeof(double) == 8);
|
||||
return s.byteOrderSerialize( &c, 8 );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/// Serialize in the stream byte order.
|
||||
Stream & byteOrderSerialize( void * v, uint len ) {
|
||||
if( m_byteOrder == getSystemByteOrder() ) {
|
||||
serialize( v, len );
|
||||
}
|
||||
else {
|
||||
for( uint i = len; i > 0; i-- ) {
|
||||
serialize( (uint8 *)v + i - 1, 1 );
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
ByteOrder m_byteOrder;
|
||||
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_STREAM_H
|
||||
// This code is in the public domain -- Ignacio Casta<74>o <castano@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#ifndef NV_CORE_STREAM_H
|
||||
#define NV_CORE_STREAM_H
|
||||
|
||||
#include "nvcore.h"
|
||||
#include "Debug.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
/// Base stream class.
|
||||
class NVCORE_CLASS Stream {
|
||||
public:
|
||||
|
||||
enum ByteOrder {
|
||||
LittleEndian = false,
|
||||
BigEndian = true,
|
||||
};
|
||||
|
||||
/// Get the byte order of the system.
|
||||
static ByteOrder getSystemByteOrder() {
|
||||
#if NV_LITTLE_ENDIAN
|
||||
return LittleEndian;
|
||||
#else
|
||||
return BigEndian;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// Ctor.
|
||||
Stream() : m_byteOrder(LittleEndian) { }
|
||||
|
||||
/// Virtual destructor.
|
||||
virtual ~Stream() {}
|
||||
|
||||
/// Set byte order.
|
||||
void setByteOrder(ByteOrder bo) { m_byteOrder = bo; }
|
||||
|
||||
/// Get byte order.
|
||||
ByteOrder byteOrder() const { return m_byteOrder; }
|
||||
|
||||
|
||||
/// Serialize the given data.
|
||||
virtual uint serialize( void * data, uint len ) = 0;
|
||||
|
||||
/// Move to the given position in the archive.
|
||||
virtual void seek( uint pos ) = 0;
|
||||
|
||||
/// Return the current position in the archive.
|
||||
virtual uint tell() const = 0;
|
||||
|
||||
/// Return the current size of the archive.
|
||||
virtual uint size() const = 0;
|
||||
|
||||
/// Determine if there has been any error.
|
||||
virtual bool isError() const = 0;
|
||||
|
||||
/// Clear errors.
|
||||
virtual void clearError() = 0;
|
||||
|
||||
/// Return true if the stream is at the end.
|
||||
virtual bool isAtEnd() const = 0;
|
||||
|
||||
/// Return true if the stream is seekable.
|
||||
virtual bool isSeekable() const = 0;
|
||||
|
||||
/// Return true if this is an input stream.
|
||||
virtual bool isLoading() const = 0;
|
||||
|
||||
/// Return true if this is an output stream.
|
||||
virtual bool isSaving() const = 0;
|
||||
|
||||
|
||||
// friends
|
||||
friend Stream & operator<<( Stream & s, bool & c ) {
|
||||
#if NV_OS_DARWIN
|
||||
nvStaticCheck(sizeof(bool) == 4);
|
||||
uint8 b = c ? 1 : 0;
|
||||
s.serialize( &b, 1 );
|
||||
c = (b == 1);
|
||||
#else
|
||||
nvStaticCheck(sizeof(bool) == 1);
|
||||
s.serialize( &c, 1 );
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, char & c ) {
|
||||
nvStaticCheck(sizeof(char) == 1);
|
||||
s.serialize( &c, 1 );
|
||||
return s;
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, uint8 & c ) {
|
||||
nvStaticCheck(sizeof(uint8) == 1);
|
||||
s.serialize( &c, 1 );
|
||||
return s;
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, int8 & c ) {
|
||||
nvStaticCheck(sizeof(int8) == 1);
|
||||
s.serialize( &c, 1 );
|
||||
return s;
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, uint16 & c ) {
|
||||
nvStaticCheck(sizeof(uint16) == 2);
|
||||
return s.byteOrderSerialize( &c, 2 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, int16 & c ) {
|
||||
nvStaticCheck(sizeof(int16) == 2);
|
||||
return s.byteOrderSerialize( &c, 2 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, uint32 & c ) {
|
||||
nvStaticCheck(sizeof(uint32) == 4);
|
||||
return s.byteOrderSerialize( &c, 4 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, int32 & c ) {
|
||||
nvStaticCheck(sizeof(int32) == 4);
|
||||
return s.byteOrderSerialize( &c, 4 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, uint64 & c ) {
|
||||
nvStaticCheck(sizeof(uint64) == 8);
|
||||
return s.byteOrderSerialize( &c, 8 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, int64 & c ) {
|
||||
nvStaticCheck(sizeof(int64) == 8);
|
||||
return s.byteOrderSerialize( &c, 8 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, float & c ) {
|
||||
nvStaticCheck(sizeof(float) == 4);
|
||||
return s.byteOrderSerialize( &c, 4 );
|
||||
}
|
||||
friend Stream & operator<<( Stream & s, double & c ) {
|
||||
nvStaticCheck(sizeof(double) == 8);
|
||||
return s.byteOrderSerialize( &c, 8 );
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/// Serialize in the stream byte order.
|
||||
Stream & byteOrderSerialize( void * v, uint len ) {
|
||||
if( m_byteOrder == getSystemByteOrder() ) {
|
||||
serialize( v, len );
|
||||
}
|
||||
else {
|
||||
for( uint i = len; i > 0; i-- ) {
|
||||
serialize( (uint8 *)v + i - 1, 1 );
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
ByteOrder m_byteOrder;
|
||||
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_STREAM_H
|
||||
|
@ -10,20 +10,24 @@
|
||||
|
||||
#include <time.h> //clock
|
||||
|
||||
class NVCORE_CLASS Timer
|
||||
{
|
||||
public:
|
||||
Timer() {}
|
||||
namespace nv {
|
||||
|
||||
void start() { m_start = clock(); }
|
||||
void stop() { m_stop = clock(); }
|
||||
class NVCORE_CLASS Timer
|
||||
{
|
||||
public:
|
||||
Timer() {}
|
||||
|
||||
float elapsed() const { return float(m_stop - m_start) / CLOCKS_PER_SEC; }
|
||||
void start() { m_start = clock(); }
|
||||
void stop() { m_stop = clock(); }
|
||||
|
||||
private:
|
||||
clock_t m_start;
|
||||
clock_t m_stop;
|
||||
};
|
||||
float elapsed() const { return float(m_stop - m_start) / CLOCKS_PER_SEC; }
|
||||
|
||||
private:
|
||||
clock_t m_start;
|
||||
clock_t m_stop;
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#else
|
||||
|
||||
|
@ -141,9 +141,8 @@ void ColorBlock::swizzle(uint x, uint y, uint z, uint w)
|
||||
|
||||
|
||||
/// Returns true if the block has a single color.
|
||||
bool ColorBlock::isSingleColor() const
|
||||
bool ColorBlock::isSingleColor(Color32 mask/*= Color32(0xFF, 0xFF, 0xFF, 0x00)*/) const
|
||||
{
|
||||
Color32 mask(0xFF, 0xFF, 0xFF, 0x00);
|
||||
uint u = m_color[0].u & mask.u;
|
||||
|
||||
for (int i = 1; i < 16; i++)
|
||||
@ -184,7 +183,7 @@ bool ColorBlock::isSingleColorNoAlpha() const
|
||||
*/
|
||||
|
||||
/// Count number of unique colors in this color block.
|
||||
uint ColorBlock::countUniqueColors() const
|
||||
/*uint ColorBlock::countUniqueColors() const
|
||||
{
|
||||
uint count = 0;
|
||||
|
||||
@ -204,7 +203,7 @@ uint ColorBlock::countUniqueColors() const
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*/// Get average color of the block.
|
||||
Color32 ColorBlock::averageColor() const
|
||||
|
@ -25,9 +25,8 @@ namespace nv
|
||||
|
||||
void swizzle(uint x, uint y, uint z, uint w); // 0=r, 1=g, 2=b, 3=a, 4=0xFF, 5=0
|
||||
|
||||
bool isSingleColor() const;
|
||||
//bool isSingleColorNoAlpha() const;
|
||||
uint countUniqueColors() const;
|
||||
bool isSingleColor(Color32 mask = Color32(0xFF, 0xFF, 0xFF, 0x00)) const;
|
||||
//uint countUniqueColors() const;
|
||||
//Color32 averageColor() const;
|
||||
bool hasAlpha() const;
|
||||
|
||||
|
0
src/nvmath/Box.cpp
Executable file → Normal file
0
src/nvmath/Box.cpp
Executable file → Normal file
@ -221,10 +221,38 @@ void NormalCompressorDXT5::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alph
|
||||
|
||||
void NormalCompressorDXT5n::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alphaMode, const nvtt::CompressionOptions::Private & compressionOptions, void * output)
|
||||
{
|
||||
rgba.swizzle(4, 1, 5, 0); // 0xFF, G, 0, R
|
||||
|
||||
BlockDXT5 * block = new(output) BlockDXT5;
|
||||
|
||||
// Compress Y.
|
||||
if (compressionOptions.quality == Quality_Highest)
|
||||
{
|
||||
OptimalCompress::compressDXT1G(rgba, &block->color);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rgba.isSingleColor(Color32(0, 0xFF, 0, 0))) // Mask all but green channel.
|
||||
{
|
||||
OptimalCompress::compressDXT1G(rgba.color(0).g, &block->color);
|
||||
}
|
||||
else
|
||||
{
|
||||
ColorBlock tile = rgba;
|
||||
tile.swizzle(4, 1, 5, 3); // leave alpha in alpha channel.
|
||||
|
||||
nvsquish::WeightedClusterFit fit;
|
||||
fit.SetMetric(0, 1, 0);
|
||||
|
||||
int flags = 0;
|
||||
if (alphaMode == nvtt::AlphaMode_Transparency) flags |= nvsquish::kWeightColourByAlpha;
|
||||
|
||||
nvsquish::ColourSet colours((uint8 *)tile.colors(), flags);
|
||||
fit.SetColourSet(&colours, 0);
|
||||
fit.Compress(&block->color);
|
||||
}
|
||||
}
|
||||
|
||||
rgba.swizzle(4, 1, 5, 0); // 1, G, 0, R
|
||||
|
||||
// Compress X.
|
||||
if (compressionOptions.quality == Quality_Highest)
|
||||
{
|
||||
@ -234,31 +262,6 @@ void NormalCompressorDXT5n::compressBlock(ColorBlock & rgba, nvtt::AlphaMode alp
|
||||
{
|
||||
QuickCompress::compressDXT5A(rgba, &block->alpha);
|
||||
}
|
||||
|
||||
// Compress Y.
|
||||
if (compressionOptions.quality == Quality_Highest)
|
||||
{
|
||||
OptimalCompress::compressDXT1G(rgba, &block->color);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rgba.isSingleColor())
|
||||
{
|
||||
OptimalCompress::compressDXT1G(rgba.color(0), &block->color);
|
||||
}
|
||||
else
|
||||
{
|
||||
nvsquish::WeightedClusterFit fit;
|
||||
fit.SetMetric(0, 1, 0);
|
||||
|
||||
int flags = 0;
|
||||
if (alphaMode == nvtt::AlphaMode_Transparency) flags |= nvsquish::kWeightColourByAlpha;
|
||||
|
||||
nvsquish::ColourSet colours((uint8 *)rgba.colors(), flags);
|
||||
fit.SetColourSet(&colours, 0);
|
||||
fit.Compress(&block->color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -312,13 +312,19 @@ bool TexImage::setImage2D(nvtt::InputFormat format, int w, int h, int idx, const
|
||||
}
|
||||
|
||||
FloatImage * img = m->imageArray[idx];
|
||||
if (img->width() != w || img->height() != h)
|
||||
{
|
||||
return false;
|
||||
if (img != NULL) {
|
||||
if (img->width() != w || img->height() != h) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
detach();
|
||||
|
||||
if (img == NULL) {
|
||||
img = m->imageArray[idx] = new FloatImage();
|
||||
img->allocate(4, w, h);
|
||||
}
|
||||
|
||||
const int count = w * h;
|
||||
|
||||
float * restrict rdst = img->channel(0);
|
||||
@ -333,10 +339,10 @@ bool TexImage::setImage2D(nvtt::InputFormat format, int w, int h, int idx, const
|
||||
try {
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
rdst[i] = src[i].r;
|
||||
gdst[i] = src[i].g;
|
||||
bdst[i] = src[i].b;
|
||||
adst[i] = src[i].a;
|
||||
rdst[i] = float(src[i].r) / 255.0f;
|
||||
gdst[i] = float(src[i].g) / 255.0f;
|
||||
bdst[i] = float(src[i].b) / 255.0f;
|
||||
adst[i] = float(src[i].a) / 255.0f;
|
||||
}
|
||||
}
|
||||
catch(...) {
|
||||
|
@ -391,7 +391,6 @@ namespace nvtt
|
||||
/// A texture mipmap.
|
||||
struct TexImage
|
||||
{
|
||||
NVTT_API TexImage();
|
||||
NVTT_API TexImage(const TexImage & tex);
|
||||
NVTT_API ~TexImage();
|
||||
|
||||
@ -459,6 +458,7 @@ namespace nvtt
|
||||
NVTT_API bool copyChannel(const TexImage & srcImage, int srcChannel, int dstChannel);
|
||||
|
||||
private:
|
||||
TexImage();
|
||||
void detach();
|
||||
|
||||
friend struct Compressor;
|
||||
|
@ -558,7 +558,7 @@ int main(int argc, char *argv[])
|
||||
// fflush(stdout);
|
||||
// getchar();
|
||||
|
||||
Timer timer;
|
||||
nv::Timer timer;
|
||||
timer.start();
|
||||
|
||||
if (!context.process(inputOptions, compressionOptions, outputOptions))
|
||||
|
Reference in New Issue
Block a user