RSExport RSErrorRef RSErrorCreate(RSAllocatorRef allocator, RSStringRef domain, RSIndex code, RSDictionaryRef userInfo) { RSErrorRef err = (RSErrorRef)__RSRuntimeCreateInstance(allocator, RSErrorGetTypeID(), sizeof(struct __RSError) - sizeof(RSRuntimeBase)); err->_code = code; if (domain) err->_domain = RSRetain(domain); else HALTWithError(RSInvalidArgumentException, "the domain is nil."); if (userInfo) err->_userInfo = RSRetain(userInfo); return err; }
static RSTypeRef __RSErrorRSCoreFoundationCallBack(RSErrorRef err, RSStringRef key) { if (!RSEqual(key, RSErrorDescriptionKey) && !RSEqual(key, RSErrorLocalizedFailureReasonKey)) return nil; RSStringRef errStr = nil; struct __RSErrorPrivateFormatTable cFormat = __RSErrorDomainRSCoreFoundationGetCStringWithCode(RSErrorGetCode(err)); if (cFormat.argsCnt) { RSStringRef format = RSStringCreateWithCString(RSAllocatorSystemDefault, cFormat.format, RSStringEncodingUTF8); RSArrayRef objects = RSDictionaryGetValue(__RSErrorGetUserInfo(err), RSErrorTargetKey); RSTypeRef object[3] = {nil}; RSIndex minCnt = 0; if (objects) { minCnt = min(cFormat.argsCnt, RSArrayGetCount(objects)); switch (minCnt) { case 1: object[0] = RSArrayObjectAtIndex(objects, 0); errStr = RSStringCreateWithFormat(RSAllocatorSystemDefault, format, object[0]); break; case 2: object[0] = RSArrayObjectAtIndex(objects, 0); object[1] = RSArrayObjectAtIndex(objects, 1); errStr = RSStringCreateWithFormat(RSAllocatorSystemDefault, format, object[0], object[1]); break; case 3: object[0] = RSArrayObjectAtIndex(objects, 0); object[1] = RSArrayObjectAtIndex(objects, 1); object[2] = RSArrayObjectAtIndex(objects, 2); errStr = RSStringCreateWithFormat(RSAllocatorSystemDefault, format, object[0], object[1], object[2]); break; default: HALTWithError(RSInvalidArgumentException, "the formate is too long to support"); break; } } for (RSIndex idx = 0; idx < minCnt; idx++) { RSRelease(object[idx]); } RSRelease(format); } else { errStr = RSStringCreateWithCString(RSAllocatorSystemDefault, cFormat.format, RSStringEncodingUTF8); } return errStr; }
RSExport RSBitU32 RSAbsoluteTimeGetDayOfWeek(RSAbsoluteTime at, RSTimeZoneRef tz) { int64_t absolute; RSAbsoluteTime fixedat; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX if (tz) { if (RSTimeZoneGetTypeID() != RSGetTypeID(tz)) HALTWithError(RSInvalidArgumentException, "timezone is not kind of RSTimeZone"); } fixedat = at + (nil != tz ? RSTimeZoneGetSecondsFromGMT(tz, at) : 0.0); #else fixedat = at; #endif absolute = (int64_t)floor(fixedat / 86400.0); return (absolute < 0) ? ((absolute + 1) % 7 + 7) : (absolute % 7 + 1); /* Monday = 1, etc. */ }
RSExport RSBitU32 RSAbsoluteTimeGetDayOfYear(RSAbsoluteTime at, RSTimeZoneRef tz) { RSAbsoluteTime fixedat; int64_t absolute, year; int8_t month, day; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX if (tz) { if (RSTimeZoneGetTypeID() != RSGetTypeID(tz)) HALTWithError(RSInvalidArgumentException, "timezone is not kind of RSTimeZone"); } fixedat = at + (nil != tz ? RSTimeZoneGetSecondsFromGMT(tz, at) : 0.0); #else fixedat = at; #endif absolute = (int64_t)floor(fixedat / 86400.0); __RSYMDFromAbsolute(absolute, &year, &month, &day); return __RSDaysBeforeMonth(month, year, isleap(year)) + day; }
static RSBitU64 __RSAllocatorUpdateUnit(RSBit8 operand) { RSBitU64 result = 0; RSSpinLockLock(&___RSAllocatorAllocateUnitNumberLock); switch (operand) { case 0: result = ___RSAllocatorAllocateUnitNumber; break; case 1: ___RSAllocatorAllocateUnitNumber++; #if __RSRuntimeDebugPreference if (___RSDebugLogPreference._RSRuntimeInstanceAllocFreeWatcher) { __RSCLog(RSLogLevelDebug, "runtime unit - %llu\n", ___RSAllocatorAllocateUnitNumber); } #endif result = YES; break; case -1: ___RSAllocatorAllocateUnitNumber--; #if __RSRuntimeDebugPreference if (___RSDebugLogPreference._RSRuntimeInstanceAllocFreeWatcher) { __RSCLog(RSLogLevelDebug, "runtime unit - %llu\n", ___RSAllocatorAllocateUnitNumber); } #endif result = YES; default: break; } if (___RSAllocatorAllocateUnitNumber == ~0) { HALTWithError(RSGenericException, "What the hell was that?! You malloc to much memory blocks!"); } RSSpinLockUnlock(&___RSAllocatorAllocateUnitNumberLock); return result; }
RSExport RSBitU32 RSAbsoluteTimeGetWeekOfYear(RSAbsoluteTime at, RSTimeZoneRef tz) { int64_t absolute, year; int8_t month, day; RSAbsoluteTime fixedat; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX if (tz) { if (RSTimeZoneGetTypeID() != RSGetTypeID(tz)) HALTWithError(RSInvalidArgumentException, "timezone is not kind of RSTimeZone"); } fixedat = at + (nil != tz ? RSTimeZoneGetSecondsFromGMT(tz, at) : 0.0); #else fixedat = at; #endif absolute = (int64_t)floor(fixedat / 86400.0); __RSYMDFromAbsolute(absolute, &year, &month, &day); double absolute0101 = __RSAbsoluteFromYMD(year, 1, 1); int64_t dow0101 = __RSDoubleModToInt(absolute0101, 7) + 1; /* First three and last three days of a year can end up in a week of a different year */ if (1 == month && day < 4) { if ((day < 4 && 5 == dow0101) || (day < 3 && 6 == dow0101) || (day < 2 && 7 == dow0101)) { return 53; } } if (12 == month && 28 < day) { double absolute20101 = __RSAbsoluteFromYMD(year + 1, 1, 1); int64_t dow20101 = __RSDoubleModToInt(absolute20101, 7) + 1; if ((28 < day && 4 == dow20101) || (29 < day && 3 == dow20101) || (30 < day && 2 == dow20101)) { return 1; } } /* Days into year, plus a week-shifting correction, divided by 7. First week is 1. */ return (__RSDaysBeforeMonth(month, year, isleap(year)) + day + (dow0101 - 11) % 7 + 2) / 7 + 1; }
RSInline void __RSTimeZoneAvailable(RSTimeZoneRef timeZone) { if (timeZone == nil || timeZone->_zoneName == nil) HALTWithError(RSInvalidArgumentException, "the time zone object is nil"); __RSGenericValidInstance(timeZone, _RSTimeZoneTypeID); return; }
RSExport RSDateRef RSDateCreateWithString(RSAllocatorRef allocator, RSStringRef value) { const int dateLength = 20; RSDateRef _v = nil; //%04d-%02d-%02dT%02d:%02d:%02dZ //4 +1 +2 +1 +2 +1 +2 +1 +2 +1 +2 +1 //%04d - %02d - %02d T %02d : %02d : %02d Z //5,3,3,3,3,3 = 20 if (dateLength == RSStringGetLength(value)) { UniChar ptr[6] = {0}; ptr[0] = RSStringGetCharacterAtIndex(value, 5 - 1); //- ptr[1] = RSStringGetCharacterAtIndex(value, 8 - 1); //- ptr[2] = RSStringGetCharacterAtIndex(value, 11 - 1);//T ptr[3] = RSStringGetCharacterAtIndex(value, 14 - 1);//: ptr[4] = RSStringGetCharacterAtIndex(value, 17 - 1);//: ptr[5] = RSStringGetCharacterAtIndex(value, 20 - 1);//Z if ((ptr[0] == ptr[1]) && (ptr[1] == '-') && (ptr[2] == 'T') && (ptr[3] == ptr[4]) && (ptr[4] == ':') && (ptr[5] == 'Z')) { #if 0 UTF8Char year[5] = {0}; UTF8Char month[3] = {0}; UTF8Char day[3] = {0}; UTF8Char hour[3] = {0}; UTF8Char minute[3] = {0}; UTF8Char second[3] = {0}; RSStringGetUTF8Characters(value, RSMakeRange(0, 4), year); RSStringGetUTF8Characters(value, RSMakeRange(5, 2), month); RSStringGetUTF8Characters(value, RSMakeRange(8, 2), day); RSStringGetUTF8Characters(value, RSMakeRange(11, 2), hour); RSStringGetUTF8Characters(value, RSMakeRange(14, 2), minute); RSStringGetUTF8Characters(value, RSMakeRange(17, 2), second); RSGregorianDate gd = {0}; gd.year = atoi((const char*)year); gd.month= atoi((const char*)month); gd.day = atoi((const char*)day); gd.hour = atoi((const char*)hour); gd.minute = atoi((const char*)minute); gd.second = atoi((const char*)second); #else RSGregorianDate gd = {0}; UniChar payload[4] = {0}; RSIndex tmp = 0; RSStringGetCharacters(value, RSMakeRange(0, 4), payload); if (!__unichar2i(payload, 4, &tmp)) return nil; gd.year = (RSBitU32)tmp; memset(payload, 0, sizeof(payload)); RSStringGetCharacters(value, RSMakeRange(5, 2), payload); if (!__unichar2i(payload, 2, &tmp)) return nil; gd.month = (RSBitU8)tmp; if (__dateCheckRange(gd.month, 1, 12) == NO) return nil; RSStringGetCharacters(value, RSMakeRange(8, 2), payload); if (!__unichar2i(payload, 2, &tmp)) return nil; gd.day = (RSBitU8)tmp; int maxm = 0; switch (gd.month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: maxm = 31; break; case 2: maxm = 28; break; default: maxm = 30; break; } if ((gd.year % 400 == 0) || ((gd.year % 100 != 0) && (gd.year % 4 == 0))) { maxm++; } if (maxm > 32) HALTWithError(RSInvalidArgumentException, "maxm > 32"); if (__dateCheckRange(gd.day, 1, maxm) == NO) return nil; RSStringGetCharacters(value, RSMakeRange(11, 2), payload); if (!__unichar2i(payload, 2, &tmp)) return nil; gd.hour = (RSBitU8)tmp; if (__dateCheckRange(gd.day, 0, 59) == NO) return nil; RSStringGetCharacters(value, RSMakeRange(14, 2), payload); if (!__unichar2i(payload, 2, &tmp)) return nil; gd.minute = (RSBitU8)tmp; if (__dateCheckRange(gd.day, 0, 59) == NO) return nil; RSStringGetCharacters(value, RSMakeRange(17, 2), payload); if (!__unichar2i(payload, 2, &tmp)) return nil; gd.second = (RSBitU8)tmp; if (__dateCheckRange(gd.day, 0, 59) == NO) return nil; #endif _v = RSDateCreate(allocator, RSGregorianDateGetAbsoluteTime(gd, RSTimeZoneCopySystem())); } } return _v; }
static void __RSDateAvailable(RSDateRef date) { if (date == nil) HALTWithError(RSInvalidArgumentException, "date is nil"); if (RSGetTypeID(date) != RSDateGetTypeID()) HALTWithError(RSInvalidArgumentException, "date is not kind of RSDate"); return; }
static BOOL __RSCalendarAvailable(RSCalendarRef calendar) { if (calendar == nil) return NO; if (RSGetTypeID(calendar) != RSCalendarGetTypeID()) HALTWithError(RSInvalidArgumentException, "calendar not available"); return YES; }