Class object_getClass(const id object) { Class cls = 0; do { if (object->isTaggedPointer()) { if (is_data(object)) { cls = CHData::getClass(nullptr); break; } if (is_string(object)) { cls = CHString::getClass(nullptr); break; } if (is_number(object)) { cls = CHNumber::getClass(nullptr); break; } } cls = object->getClass(); } while (0); return cls; }
void object_setIvar(id obj, const Ivar ivar, id value) { if (obj && ivar && !obj->isTaggedPointer()) { const char *encodeType = ivar_getTypeEncoding(ivar); int offset = ivar_getOffset(ivar); switch (encodeType[0]) { case 'C': case 'c': { auto v = (char *)obj + offset; *v = *(CHNumber *)value; } case 'i': case 'I': { auto v = (int *)((char *)obj + offset); *v = *(CHNumber *)value; } case 'l': case 'L': { auto v = (long *)((char *)obj + offset); *v = *(CHNumber *)value; } case 'q': case 'Q': { auto *v = (long long *)((char *)obj + offset); *v = *(CHNumber *)value; } case 'f': { auto v = (float *)((char *)obj + offset); *v = *(CHNumber *)value; } case 'd': { auto v = (double *)((char *)obj + offset); *v = *(CHNumber *)value; } case 'B': { auto v = (bool *)((char *)obj + offset); *v = *(CHNumber *)value; } case '^': { switch (encodeType[1]) { case '#': { id *idx = (id *)((char *)obj + offset); *idx = value; } case 'C': case 'c': { auto v = (char **)obj + offset; *v = (char *)value; } case 'i': case 'I': { auto v = (int **)((char *)obj + offset); *v = (int *)value; } case 'l': case 'L': { auto v = (long **)((char *)obj + offset); *v = (long *)value; } case 'q': case 'Q': { auto *v = (long long **)((char *)obj + offset); *v = (long long *)value; } case 'f': { auto v = (float **)((char *)obj + offset); *v = (float *)value; } case 'd': { auto v = (double **)((char *)obj + offset); *v = (double *)value; } case 'B': { auto v = (bool **)((char *)obj + offset); *v = (bool *)value; } case 'v': { auto v = (void **)((char *)obj + offset); *v = (void *)value; } default: break; } } case ':': { // do nothing... } default: break; } } }
id object_getIvar(id obj, Ivar ivar) { if (obj && ivar && !obj->isTaggedPointer()) { int offset = ivar_getOffset(ivar); const char *encodeType = ivar_getTypeEncoding(ivar); switch (encodeType[0]) { case 'C': case 'c': { auto v = (char *)obj + offset; return number(*v); } case 'i': case 'I': { auto v = (int *)((char *)obj + offset); return number(*v); } case 'l': case 'L': { auto v = (long *)((char *)obj + offset); return number(*v); } case 'q': case 'Q': { auto *v = (long long *)((char *)obj + offset); return number(*v); } case 'f': { auto v = (float *)((char *)obj + offset); return number(*v); } case 'd': { auto v = (double *)((char *)obj + offset); return number(*v); } case 'B': { auto v = (bool *)((char *)obj + offset); return number(*v); } case '^': { switch (encodeType[1]) { case '#': { id *idx = (id *)((char *)obj + offset); return *idx; } case 'C': case 'c': { auto v = (char **)obj + offset; return (id)*v; } case 'i': case 'I': { auto v = (int **)((char *)obj + offset); return number(*v); } case 'l': case 'L': { auto v = (long **)((char *)obj + offset); return (id)*v; } case 'q': case 'Q': { auto *v = (long long **)((char *)obj + offset); return (id)*v; } case 'f': { auto v = (float **)((char *)obj + offset); return (id)*v; } case 'd': { auto v = (double **)((char *)obj + offset); return (id)*v; } case 'B': { auto v = (bool **)((char *)obj + offset); return (id)*v; } case 'v': { auto v = (void **)((char *)obj + offset); return (id)*v; } default: break; } } case ':': { auto v = (SEL *)((char *)obj + offset); CHString *str = CHString::stringWithUTF8String(*v); return (id)str; } default: break; } } return nullptr; }