Skip to content

Instantly share code, notes, and snippets.

@novi
Created October 28, 2010 08:39
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save novi/650925 to your computer and use it in GitHub Desktop.
Save novi/650925 to your computer and use it in GitHub Desktop.
Create your own CFType Class
// Created by Yusuke Ito, @novi_
#include <CoreFoundation/CoreFoundation.h>
#define UseCFHeader 0
#if UseCFHeader
#include "CFRuntime.h"
#else
enum {
_kCFRuntimeNotATypeID = 0
};
typedef struct __CFRuntimeBase {
uintptr_t _cfisa;
uint8_t _cfinfo[4];
#if __LP64__
uint32_t _rc;
#endif
} CFRuntimeBase;
typedef struct __CFRuntimeClass { // Version 0 struct
CFIndex version;
const char *className;
void (*init)(CFTypeRef cf);
CFTypeRef (*copy)(CFAllocatorRef allocator, CFTypeRef cf);
#if MAC_OS_X_VERSION_10_2 <= MAC_OS_X_VERSION_MAX_ALLOWED
void (*finalize)(CFTypeRef cf);
#else
void (*dealloc)(CFTypeRef cf);
#endif
Boolean (*equal)(CFTypeRef cf1, CFTypeRef cf2);
CFHashCode (*hash)(CFTypeRef cf);
CFStringRef (*copyFormattingDesc)(CFTypeRef cf, CFDictionaryRef formatOptions); // str with retain
CFStringRef (*copyDebugDesc)(CFTypeRef cf); // str with retain
#if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
#define CF_RECLAIM_AVAILABLE 1
void (*reclaim)(CFTypeRef cf);
#endif
} CFRuntimeClass;
CF_EXPORT CFTypeID _CFRuntimeRegisterClass(const CFRuntimeClass * const cls);
CF_EXPORT CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CFIndex extraBytes, unsigned char *category);
#endif
static void __MyValueDealloc(CFTypeRef cf);
static CFStringRef __MyValueCopyDescription(CFTypeRef cf);
static CFTypeID __kMyValueTypeID = _kCFRuntimeNotATypeID;
struct __MyValue {
CFRuntimeBase _base;
int value;
};
typedef struct __MyValue* MyValueRef;
static const CFRuntimeClass __MyValueClass = {
0,
"MyValue",
NULL, // init
NULL, // copy
__MyValueDealloc, // dealloc
NULL, // equal
NULL, // hash
NULL, //
__MyValueCopyDescription, // description
};
CFTypeID MyValueGetTypeID(void)
{
if (_kCFRuntimeNotATypeID == __kMyValueTypeID) {
__kMyValueTypeID = _CFRuntimeRegisterClass(&__MyValueClass);
}
return __kMyValueTypeID;
}
MyValueRef MyValueCreateWithValue(CFAllocatorRef allocator, int val)
{
uint32_t size = sizeof(struct __MyValue) - sizeof(CFRuntimeBase);
MyValueRef memory = (void*)_CFRuntimeCreateInstance(allocator, MyValueGetTypeID(), size, NULL);
if (NULL == memory) {
return NULL;
}
((struct __MyValue*)memory)->value = val;
return memory;
}
static void __MyValueDealloc(CFTypeRef cf)
{
//MyValueRef val = (void*)cf;
printf("__MyValueDealloc\n");
}
static CFStringRef __MyValueCopyDescription(CFTypeRef cf)
{
MyValueRef val = (void*)cf;
return CFStringCreateWithFormat(CFGetAllocator(cf), NULL, CFSTR("<MyValue %p [%p]>{value = %d}"), cf, CFGetAllocator(cf), val->value);
}
int MyValueGetValue(MyValueRef obj)
{
//__CFGenericValidateType(obj, MyValueGetTypeID());
return obj->value;
}
int main (int argc, const char * argv[])
{
MyValueRef myval = MyValueCreateWithValue(NULL, 47);
CFStringRef str = CFStringCreateWithCString(NULL, "hoge", kCFStringEncodingASCII);
printf("string: typeid=%ld, retaincount=%ld, type=%s, value=%s\n",
CFGetTypeID(str),
CFGetRetainCount(str),
CFStringGetCStringPtr(CFCopyTypeIDDescription(CFGetTypeID(str)), kCFStringEncodingASCII),
CFStringGetCStringPtr(str, kCFStringEncodingASCII));
CFShow(str);
CFRetain(myval);
printf("myval: typeid=%ld, retaincount=%ld, type=%s, value=%d\n",
CFGetTypeID(myval),
CFGetRetainCount(myval),
CFStringGetCStringPtr(CFCopyTypeIDDescription(CFGetTypeID(myval)), kCFStringEncodingASCII),
MyValueGetValue(myval));
CFShow(myval);
CFRelease(myval);
CFRelease(myval);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment