From 86c661e8c78409145914a13b5242c9a79a0c19a5 Mon Sep 17 00:00:00 2001 From: Traximus Date: Mon, 28 Jan 2013 14:21:17 +0800 Subject: [PATCH 1/2] fix some little bugs 1. fix a problem on ACWebDAVItem's createDateStr and modifyDateStr, it will not return nil now(reference from DAVKit) 2.fix a bug on transfering the parameter overwrite on ACWebDAVCopyRequest; It didn't transfer overwrite successfully before. 3. fix the delegate call of ACWebDAVCopyRequest and ACWebDAVMoveRequest --- src/.DS_Store | Bin 6148 -> 12292 bytes src/ACWebDAV/.DS_Store | Bin 6148 -> 12292 bytes src/ACWebDAV/ACWebDAVClient.m | 71 +- src/ACWebDAV/Classes/ACWebDAVFile.m | 17 + src/ACWebDAV/Classes/ACWebDAVItem.m | 70 +- src/ACWebDAV/ISO8601/ISO8601DateFormatter.h | 79 ++ src/ACWebDAV/ISO8601/ISO8601DateFormatter.m | 880 ++++++++++++++++++++ src/ACWebDAV/ISO8601/LICENSE.txt | 9 + src/ACWebDAV/RFC1123/NSDateRFC1123.h | 30 + src/ACWebDAV/RFC1123/NSDateRFC1123.m | 82 ++ src/ACWebDAV/Requests/ACWebDAVCopyRequest.m | 13 +- src/ACWebDAV/Requests/ACWebDAVMoveRequest.m | 13 +- 12 files changed, 1223 insertions(+), 41 deletions(-) create mode 100755 src/ACWebDAV/ISO8601/ISO8601DateFormatter.h create mode 100755 src/ACWebDAV/ISO8601/ISO8601DateFormatter.m create mode 100755 src/ACWebDAV/ISO8601/LICENSE.txt create mode 100755 src/ACWebDAV/RFC1123/NSDateRFC1123.h create mode 100755 src/ACWebDAV/RFC1123/NSDateRFC1123.m diff --git a/src/.DS_Store b/src/.DS_Store index 907d3413bdab61ad8b9ebc35faa0eb6d6fa4a7bd..1362d255d58c6a821ecf2408d3b2c38480ce4994 100644 GIT binary patch delta 638 zcmZoMXi1P@U|?W$DortDU;r^WfEYvza8E20o2aMAD6lbLH}hr%jz7$c**Q2SHn1=X zOy*%xknzmPPfp6oPXeh0VmBbx_zwmQ3_t~UgIO6I8JvOQAq)X%YR@361+v+|Dm{QI zG1M{!A*-GIjOCj&s$q;bkQ7Wl$@&#do+%Dlej}S?JvZ34V1`nLbcRHRB8FgwN`^d! zWK?6Bo*-!hGNEn^We8>PWN<-M%bbO#mIG`o>|5 zex5u>=n+RsadJ*letyozLPy5M>>M0|%s^d0AixbITtNnGEd0(qnP0{eWE=w%#AuLh L44dP5<}d>QW^5SI diff --git a/src/ACWebDAV/.DS_Store b/src/ACWebDAV/.DS_Store index 8f906be3ba0701d74062883e15cd19725a1c6d29..bd0176755c773ced978e60d2dc120f14b35111a4 100644 GIT binary patch literal 12292 zcmeHL&2G~`5S~p7b@&mvAeEcNi9=M`ElFC5Lr4pv5(v~(6p8W^*A+1`aj6q}2!Q|x zUV!(22jPr(0N$f~v%9SlyG2DR0+ktScQ(88W%GUOU1v;0s?iI5qG=*>P}rBwqB_8M zoJ-CMw&w!80-h+KCAv=cX@=UlXz36IL;+Di6c7bOfqy{(JhR!HL!SF)RBBN`6!>xaf`D8AEV56VK7O)->#W8CF%_`3B& z;|-jYfs?W`E1RJxJv(r&4kuMNUTRT56v!*Ux%(O9?2EKUo1^*ra-3`gaS~vhx71CP zE4$jz;=U|qkz$JQ9Uba&{-42r{Z0IfalBf|;ER|)#1&z-h!V`2W)R;QfueSIQ4<}2 z2zJsf%kfLF6-Q~;^S-IV#N?^dQx5Fh`dZWplbuG=>xAjUW;@wwM&V}A+J2#K&FxN{be=Ixk1kV_ z?$SI}$s_+SP-U(QbDFB}SIcg-GH0poukz8Uj*-bwb!Y`^|B`xq2VgH`c0u6> + +/*This class converts dates to and from ISO 8601 strings. A good introduction to ISO 8601: + * + *Parsing can be done strictly, or not. When you parse loosely, leading whitespace is ignored, as is anything after the date. + *The loose parser will return an NSDate for this string: @" \t\r\n\f\t 2006-03-02!!!" + *Leading non-whitespace will not be ignored; the string will be rejected, and nil returned. See the README that came with this addition. + * + *The strict parser will only accept a string if the date is the entire string. The above string would be rejected immediately, solely on these grounds. + *Also, the loose parser provides some extensions that the strict parser doesn't. + *For example, the standard says for "-DDD" (an ordinal date in the implied year) that the logical representation (meaning, hierarchically) would be "--DDD", but because that extra hyphen is "superfluous", it was omitted. + *The loose parser will accept the extra hyphen; the strict parser will not. + *A full list of these extensions is in the README file. + */ + +/*The format to either expect or produce. + *Calendar format is YYYY-MM-DD. + *Ordinal format is YYYY-DDD, where DDD ranges from 1 to 366; for example, 2009-32 is 2009-02-01. + *Week format is YYYY-Www-D, where ww ranges from 1 to 53 (the 'W' is literal) and D ranges from 1 to 7; for example, 2009-W05-07. + */ +enum { + ISO8601DateFormatCalendar, + ISO8601DateFormatOrdinal, + ISO8601DateFormatWeek, +}; +typedef NSUInteger ISO8601DateFormat; + +//The default separator for time values. Currently, this is ':'. +extern unichar ISO8601DefaultTimeSeparatorCharacter; + +@interface ISO8601DateFormatter: NSFormatter +{ + NSString *lastUsedFormatString; + NSDateFormatter *unparsingFormatter; + + NSCalendar *parsingCalendar, *unparsingCalendar; + + NSTimeZone *defaultTimeZone; + ISO8601DateFormat format; + unichar timeSeparator; + BOOL includeTime; + BOOL parsesStrictly; +} + +//Call this if you get a memory warning. ++ (void) purgeGlobalCaches; + +@property(nonatomic, retain) NSTimeZone *defaultTimeZone; + +#pragma mark Parsing + +//As a formatter, this object converts strings to dates. + +@property BOOL parsesStrictly; + +- (NSDateComponents *) dateComponentsFromString:(NSString *)string; +- (NSDateComponents *) dateComponentsFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone; +- (NSDateComponents *) dateComponentsFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone range:(out NSRange *)outRange; + +- (NSDate *) dateFromString:(NSString *)string; +- (NSDate *) dateFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone; +- (NSDate *) dateFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone range:(out NSRange *)outRange; + +#pragma mark Unparsing + +@property ISO8601DateFormat format; +@property BOOL includeTime; +@property unichar timeSeparator; + +- (NSString *) stringFromDate:(NSDate *)date; +- (NSString *) stringFromDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone; + +@end diff --git a/src/ACWebDAV/ISO8601/ISO8601DateFormatter.m b/src/ACWebDAV/ISO8601/ISO8601DateFormatter.m new file mode 100755 index 0000000..35a6b14 --- /dev/null +++ b/src/ACWebDAV/ISO8601/ISO8601DateFormatter.m @@ -0,0 +1,880 @@ +/*ISO8601DateFormatter.m + * + *Created by Peter Hosey on 2009-04-11. + *Copyright 2009 Peter Hosey. All rights reserved. + */ + +#import +#import "ISO8601DateFormatter.h" + +#ifndef DEFAULT_TIME_SEPARATOR +# define DEFAULT_TIME_SEPARATOR ':' +#endif +unichar ISO8601DefaultTimeSeparatorCharacter = DEFAULT_TIME_SEPARATOR; + +//Unicode date formats. +#define ISO_CALENDAR_DATE_FORMAT @"yyyy-MM-dd" +//#define ISO_WEEK_DATE_FORMAT @"YYYY-'W'ww-ee" //Doesn't actually work because NSDateComponents counts the weekday starting at 1. +#define ISO_ORDINAL_DATE_FORMAT @"yyyy-DDD" +#define ISO_TIME_FORMAT @"HH:mm:ss" +#define ISO_TIME_WITH_TIMEZONE_FORMAT ISO_TIME_FORMAT @"Z" +//printf formats. +#define ISO_TIMEZONE_UTC_FORMAT @"Z" +#define ISO_TIMEZONE_OFFSET_FORMAT @"%+.2d%.2d" + +@interface ISO8601DateFormatter(UnparsingPrivate) + +- (NSString *) replaceColonsInString:(NSString *)timeFormat withTimeSeparator:(unichar)timeSep; + +- (NSString *) stringFromDate:(NSDate *)date formatString:(NSString *)dateFormat timeZone:(NSTimeZone *)timeZone; +- (NSString *) weekDateStringForDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone; + +@end + +static NSMutableDictionary *timeZonesByOffset; + +@implementation ISO8601DateFormatter + ++ (void) initialize { + if (!timeZonesByOffset) { + timeZonesByOffset = [[NSMutableDictionary alloc] init]; + } +} + ++ (void) purgeGlobalCaches { + timeZonesByOffset = nil; +} + +- (NSCalendar *) makeCalendarWithDesiredConfiguration { + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; + calendar.firstWeekday = 2; //Monday + calendar.timeZone = [NSTimeZone defaultTimeZone]; + return calendar; +} + +- (id) init { + if ((self = [super init])) { + parsingCalendar = [self makeCalendarWithDesiredConfiguration]; + unparsingCalendar = [self makeCalendarWithDesiredConfiguration]; + + format = ISO8601DateFormatCalendar; + timeSeparator = ISO8601DefaultTimeSeparatorCharacter; + includeTime = NO; + parsesStrictly = NO; + } + return self; +} + +@synthesize defaultTimeZone; + +- (void) setDefaultTimeZone:(NSTimeZone *)tz +{ + if (defaultTimeZone != tz) + { + defaultTimeZone = tz; + + unparsingCalendar.timeZone = defaultTimeZone; + } +} + +//The following properties are only here because GCC doesn't like @synthesize in category implementations. + +#pragma mark Parsing + +@synthesize parsesStrictly; + +static NSUInteger read_segment(const unsigned char *str, const unsigned char **next, NSUInteger *out_num_digits); +static NSUInteger read_segment_4digits(const unsigned char *str, const unsigned char **next, NSUInteger *out_num_digits); +static NSUInteger read_segment_2digits(const unsigned char *str, const unsigned char **next); +static double read_double(const unsigned char *str, const unsigned char **next); +static BOOL is_leap_year(NSUInteger year); + +/*Valid ISO 8601 date formats: + * + *YYYYMMDD + *YYYY-MM-DD + *YYYY-MM + *YYYY + *YY //century + * //Implied century: YY is 00-99 + * YYMMDD + * YY-MM-DD + * -YYMM + * -YY-MM + * -YY + * //Implied year + * --MMDD + * --MM-DD + * --MM + * //Implied year and month + * ---DD + * //Ordinal dates: DDD is the number of the day in the year (1-366) + *YYYYDDD + *YYYY-DDD + * YYDDD + * YY-DDD + * -DDD + * //Week-based dates: ww is the number of the week, and d is the number (1-7) of the day in the week + *yyyyWwwd + *yyyy-Www-d + *yyyyWww + *yyyy-Www + *yyWwwd + *yy-Www-d + *yyWww + *yy-Www + * //Year of the implied decade + *-yWwwd + *-y-Www-d + *-yWww + *-y-Www + * //Week and day of implied year + * -Wwwd + * -Www-d + * //Week only of implied year + * -Www + * //Day only of implied week + * -W-d + */ + +- (NSDateComponents *) dateComponentsFromString:(NSString *)string { + return [self dateComponentsFromString:string timeZone:NULL]; +} +- (NSDateComponents *) dateComponentsFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone { + return [self dateComponentsFromString:string timeZone:outTimeZone range:NULL]; +} +- (NSDateComponents *) dateComponentsFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone range:(out NSRange *)outRange { + NSDate *now = [NSDate date]; + + NSDateComponents *components = [[NSDateComponents alloc] init]; + NSDateComponents *nowComponents = [parsingCalendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:now]; + + NSUInteger + //Date + year, + month_or_week = 0U, + day = 0U, + //Time + hour = 0U; + NSTimeInterval + minute = 0.0, + second = 0.0; + //Time zone + NSInteger tz_hour = 0; + NSInteger tz_minute = 0; + + enum { + monthAndDate, + week, + dateOnly + } dateSpecification = monthAndDate; + + BOOL strict = self.parsesStrictly; + unichar timeSep = self.timeSeparator; + + if (strict) timeSep = ISO8601DefaultTimeSeparatorCharacter; + NSAssert(timeSep != '\0', @"Time separator must not be NUL."); + + BOOL isValidDate = ([string length] > 0U); + NSTimeZone *timeZone = nil; + + const unsigned char *ch = (const unsigned char *)[string UTF8String]; + + NSRange range = { 0U, 0U }; + const unsigned char *start_of_date = NULL; + if (strict && isspace(*ch)) { + range.location = NSNotFound; + isValidDate = NO; + } else { + //Skip leading whitespace. + NSUInteger i = 0U; + for(NSUInteger len = strlen((const char *)ch); i < len; ++i) { + if (!isspace(ch[i])) + break; + } + + range.location = i; + ch += i; + start_of_date = ch; + + NSUInteger segment; + NSUInteger num_leading_hyphens = 0U, num_digits = 0U; + + if (*ch == 'T') { + //There is no date here, only a time. Set the date to now; then we'll parse the time. + isValidDate = isdigit(*++ch); + + year = nowComponents.year; + month_or_week = nowComponents.month; + day = nowComponents.day; + } else { + while(*ch == '-') { + ++num_leading_hyphens; + ++ch; + } + + segment = read_segment(ch, &ch, &num_digits); + switch(num_digits) { + case 0: + if (*ch == 'W') { + if ((ch[1] == '-') && isdigit(ch[2]) && ((num_leading_hyphens == 1U) || ((num_leading_hyphens == 2U) && !strict))) { + year = nowComponents.year; + month_or_week = 1U; + ch += 2; + goto parseDayAfterWeek; + } else if (num_leading_hyphens == 1U) { + year = nowComponents.year; + goto parseWeekAndDay; + } else + isValidDate = NO; + } else + isValidDate = NO; + break; + + case 8: //YYYY MM DD + if (num_leading_hyphens > 0U) + isValidDate = NO; + else { + day = segment % 100U; + segment /= 100U; + month_or_week = segment % 100U; + year = segment / 100U; + } + break; + + case 6: //YYMMDD (implicit century) + if (num_leading_hyphens > 0U) + isValidDate = NO; + else { + day = segment % 100U; + segment /= 100U; + month_or_week = segment % 100U; + year = nowComponents.year; + year -= (year % 100U); + year += segment / 100U; + } + break; + + case 4: + switch(num_leading_hyphens) { + case 0: //YYYY + year = segment; + + if (*ch == '-') ++ch; + + if (!isdigit(*ch)) { + if (*ch == 'W') + goto parseWeekAndDay; + else + month_or_week = day = 1U; + } else { + segment = read_segment(ch, &ch, &num_digits); + switch(num_digits) { + case 4: //MMDD + day = segment % 100U; + month_or_week = segment / 100U; + break; + + case 2: //MM + month_or_week = segment; + + if (*ch == '-') ++ch; + if (!isdigit(*ch)) + day = 1U; + else + day = read_segment(ch, &ch, NULL); + break; + + case 3: //DDD + day = segment % 1000U; + dateSpecification = dateOnly; + if (strict && (day > (365U + is_leap_year(year)))) + isValidDate = NO; + break; + + default: + isValidDate = NO; + } + } + break; + + case 1: //YYMM + month_or_week = segment % 100U; + year = segment / 100U; + + if (*ch == '-') ++ch; + if (!isdigit(*ch)) + day = 1U; + else + day = read_segment(ch, &ch, NULL); + + break; + + case 2: //MMDD + day = segment % 100U; + month_or_week = segment / 100U; + year = nowComponents.year; + + break; + + default: + isValidDate = NO; + } //switch(num_leading_hyphens) (4 digits) + break; + + case 1: + if (strict) { + //Two digits only - never just one. + if (num_leading_hyphens == 1U) { + if (*ch == '-') ++ch; + if (*++ch == 'W') { + year = nowComponents.year; + year -= (year % 10U); + year += segment; + goto parseWeekAndDay; + } else + isValidDate = NO; + } else + isValidDate = NO; + break; + } + case 2: + switch(num_leading_hyphens) { + case 0: + if (*ch == '-') { + //Implicit century + year = nowComponents.year; + year -= (year % 100U); + year += segment; + + if (*++ch == 'W') + goto parseWeekAndDay; + else if (!isdigit(*ch)) { + goto centuryOnly; + } else { + //Get month and/or date. + segment = read_segment_4digits(ch, &ch, &num_digits); + NSLog(@"(%@) parsing month; segment is %lu and ch is %s", string, (unsigned long)segment, ch); + switch(num_digits) { + case 4: //YY-MMDD + day = segment % 100U; + month_or_week = segment / 100U; + break; + + case 1: //YY-M; YY-M-DD (extension) + if (strict) { + isValidDate = NO; + break; + } + case 2: //YY-MM; YY-MM-DD + month_or_week = segment; + if (*ch == '-') { + if (isdigit(*++ch)) + day = read_segment_2digits(ch, &ch); + else + day = 1U; + } else + day = 1U; + break; + + case 3: //Ordinal date. + day = segment; + dateSpecification = dateOnly; + break; + } + } + } else if (*ch == 'W') { + year = nowComponents.year; + year -= (year % 100U); + year += segment; + + parseWeekAndDay: //*ch should be 'W' here. + if (!isdigit(*++ch)) { + //Not really a week-based date; just a year followed by '-W'. + if (strict) + isValidDate = NO; + else + month_or_week = day = 1U; + } else { + month_or_week = read_segment_2digits(ch, &ch); + if (*ch == '-') ++ch; + parseDayAfterWeek: + day = isdigit(*ch) ? read_segment_2digits(ch, &ch) : 1U; + dateSpecification = week; + } + } else { + //Century only. Assume current year. + centuryOnly: + year = segment * 100U + nowComponents.year % 100U; + month_or_week = day = 1U; + } + break; + + case 1:; //-YY; -YY-MM (implicit century) + NSLog(@"(%@) found %lu digits and one hyphen, so this is either -YY or -YY-MM; segment (year) is %lu", string, (unsigned long)num_digits, (unsigned long)segment); + NSUInteger current_year = nowComponents.year; + NSUInteger current_century = (current_year % 100U); + year = segment + (current_year - current_century); + if (num_digits == 1U) //implied decade + year += current_century - (current_year % 10U); + + if (*ch == '-') { + ++ch; + month_or_week = read_segment_2digits(ch, &ch); + NSLog(@"(%@) month is %lu", string, (unsigned long)month_or_week); + } + + day = 1U; + break; + + case 2: //--MM; --MM-DD + year = nowComponents.year; + month_or_week = segment; + if (*ch == '-') { + ++ch; + day = read_segment_2digits(ch, &ch); + } + break; + + case 3: //---DD + year = nowComponents.year; + month_or_week = nowComponents.month; + day = segment; + break; + + default: + isValidDate = NO; + } //switch(num_leading_hyphens) (2 digits) + break; + + case 7: //YYYY DDD (ordinal date) + if (num_leading_hyphens > 0U) + isValidDate = NO; + else { + day = segment % 1000U; + year = segment / 1000U; + dateSpecification = dateOnly; + if (strict && (day > (365U + is_leap_year(year)))) + isValidDate = NO; + } + break; + + case 3: //--DDD (ordinal date, implicit year) + //Technically, the standard only allows one hyphen. But it says that two hyphens is the logical implementation, and one was dropped for brevity. So I have chosen to allow the missing hyphen. + if ((num_leading_hyphens < 1U) || ((num_leading_hyphens > 2U) && !strict)) + isValidDate = NO; + else { + day = segment; + year = nowComponents.year; + dateSpecification = dateOnly; + if (strict && (day > (365U + is_leap_year(year)))) + isValidDate = NO; + } + break; + + default: + isValidDate = NO; + } + } + + if (isValidDate) { + if (isspace(*ch) || (*ch == 'T')) ++ch; + + if (isdigit(*ch)) { + hour = read_segment_2digits(ch, &ch); + if (*ch == timeSep) { + ++ch; + if ((timeSep == ',') || (timeSep == '.')) { + //We can't do fractional minutes when '.' is the segment separator. + //Only allow whole minutes and whole seconds. + minute = read_segment_2digits(ch, &ch); + if (*ch == timeSep) { + ++ch; + second = read_segment_2digits(ch, &ch); + } + } else { + //Allow a fractional minute. + //If we don't get a fraction, look for a seconds segment. + //Otherwise, the fraction of a minute is the seconds. + minute = read_double(ch, &ch); + second = modf(minute, &minute); + if (second > DBL_EPSILON) + second *= 60.0; //Convert fraction (e.g. .5) into seconds (e.g. 30). + else if (*ch == timeSep) { + ++ch; + second = read_double(ch, &ch); + } + } + } + + if (!strict) { + if (isspace(*ch)) ++ch; + } + + switch(*ch) { + case 'Z': + timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; + break; + + case '+': + case '-':; + BOOL negative = (*ch == '-'); + if (isdigit(*++ch)) { + //Read hour offset. + segment = *ch - '0'; + if (isdigit(*++ch)) { + segment *= 10U; + segment += *(ch++) - '0'; + } + tz_hour = (NSInteger)segment; + if (negative) tz_hour = -tz_hour; + + //Optional separator. + if (*ch == timeSep) ++ch; + + if (isdigit(*ch)) { + //Read minute offset. + segment = *ch - '0'; + if (isdigit(*++ch)) { + segment *= 10U; + segment += *ch - '0'; + } + tz_minute = segment; + if (negative) tz_minute = -tz_minute; + } + + NSTimeInterval timeZoneOffset = (tz_hour * 3600) + (tz_minute * 60); + NSNumber *offsetNum = [NSNumber numberWithDouble:timeZoneOffset]; + timeZone = [timeZonesByOffset objectForKey:offsetNum]; + if (!timeZone) { + timeZone = [NSTimeZone timeZoneForSecondsFromGMT:timeZoneOffset]; + if (timeZone) + [timeZonesByOffset setObject:timeZone forKey:offsetNum]; + } + } + } + } + } + + if (isValidDate) { + components.year = year; + components.day = day; + components.hour = hour; + components.minute = (NSInteger)minute; + components.second = (NSInteger)second; + + switch(dateSpecification) { + case monthAndDate: + components.month = month_or_week; + break; + + case week:; + //Adapted from . + //This works by converting the week date into an ordinal date, then letting the next case handle it. + NSUInteger prevYear = year - 1U; + NSUInteger YY = prevYear % 100U; + NSUInteger C = prevYear - YY; + NSUInteger G = YY + YY / 4U; + NSUInteger isLeapYear = (((C / 100U) % 4U) * 5U); + NSUInteger Jan1Weekday = (isLeapYear + G) % 7U; + enum { monday, tuesday, wednesday, thursday/*, friday, saturday, sunday*/ }; + components.day = ((8U - Jan1Weekday) + (7U * (Jan1Weekday > thursday))) + (day - 1U) + (7U * (month_or_week - 2)); + + case dateOnly: //An "ordinal date". + break; + } + } + } //if (!(strict && isdigit(ch[0]))) + + if (outRange) { + if (isValidDate) + range.length = ch - start_of_date; + else + range.location = NSNotFound; + + *outRange = range; + } + if (outTimeZone) { + *outTimeZone = timeZone; + } + + return components; +} + +- (NSDate *) dateFromString:(NSString *)string { + return [self dateFromString:string timeZone:NULL]; +} +- (NSDate *) dateFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone { + return [self dateFromString:string timeZone:outTimeZone range:NULL]; +} +- (NSDate *) dateFromString:(NSString *)string timeZone:(out NSTimeZone **)outTimeZone range:(out NSRange *)outRange { + NSTimeZone *timeZone = nil; + NSDateComponents *components = [self dateComponentsFromString:string timeZone:&timeZone range:outRange]; + if (outTimeZone) + *outTimeZone = timeZone; + parsingCalendar.timeZone = timeZone; + + return [parsingCalendar dateFromComponents:components]; +} + +- (BOOL)getObjectValue:(id *)outValue forString:(NSString *)string errorDescription:(NSString **)error { + NSDate *date = [self dateFromString:string]; + if (outValue) + *outValue = date; + return (date != nil); +} + +#pragma mark Unparsing + +@synthesize format; +@synthesize includeTime; +@synthesize timeSeparator; + +- (NSString *) replaceColonsInString:(NSString *)timeFormat withTimeSeparator:(unichar)timeSep { + if (timeSep != ':') { + NSMutableString *timeFormatMutable = [timeFormat mutableCopy]; + [timeFormatMutable replaceOccurrencesOfString:@":" + withString:[NSString stringWithCharacters:&timeSep length:1U] + options:NSBackwardsSearch | NSLiteralSearch + range:(NSRange){ 0UL, [timeFormat length] }]; + timeFormat = timeFormatMutable; + } + return timeFormat; +} + +- (NSString *) stringFromDate:(NSDate *)date { + NSTimeZone *timeZone = self.defaultTimeZone; + if (!timeZone) timeZone = [NSTimeZone defaultTimeZone]; + return [self stringFromDate:date timeZone:timeZone]; +} + +- (NSString *) stringFromDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone { + switch (self.format) { + case ISO8601DateFormatCalendar: + return [self stringFromDate:date formatString:ISO_CALENDAR_DATE_FORMAT timeZone:timeZone]; + case ISO8601DateFormatWeek: + return [self weekDateStringForDate:date timeZone:timeZone]; + case ISO8601DateFormatOrdinal: + return [self stringFromDate:date formatString:ISO_ORDINAL_DATE_FORMAT timeZone:timeZone]; + default: + [NSException raise:NSInternalInconsistencyException format:@"self.format was %d, not calendar (%d), week (%d), or ordinal (%d)", self.format, ISO8601DateFormatCalendar, ISO8601DateFormatWeek, ISO8601DateFormatOrdinal]; + return nil; + } +} + +- (NSString *) stringFromDate:(NSDate *)date formatString:(NSString *)dateFormat timeZone:(NSTimeZone *)timeZone { + if (includeTime) + dateFormat = [dateFormat stringByAppendingFormat:@"'T' %@", [self replaceColonsInString:ISO_TIME_FORMAT withTimeSeparator:self.timeSeparator]]; + + unparsingCalendar.timeZone = timeZone; + + if (dateFormat != lastUsedFormatString) { + unparsingFormatter = nil; + lastUsedFormatString = dateFormat; + } + + if (!unparsingFormatter) { + unparsingFormatter = [[NSDateFormatter alloc] init]; + unparsingFormatter.formatterBehavior = NSDateFormatterBehavior10_4; + unparsingFormatter.dateFormat = dateFormat; + unparsingFormatter.calendar = unparsingCalendar; + } + + NSString *str = [unparsingFormatter stringForObjectValue:date]; + + if (includeTime) { + NSInteger offset = [timeZone secondsFromGMT]; + offset /= 60; //bring down to minutes + if (offset == 0) + str = [str stringByAppendingString:ISO_TIMEZONE_UTC_FORMAT]; + else + str = [str stringByAppendingFormat:ISO_TIMEZONE_OFFSET_FORMAT, offset / 60, offset % 60]; + } + + //Undo the change we made earlier + unparsingCalendar.timeZone = self.defaultTimeZone; + + return str; +} + +- (NSString *) stringForObjectValue:(id)value { + NSParameterAssert([value isKindOfClass:[NSDate class]]); + + return [self stringFromDate:(NSDate *)value]; +} + +/*Adapted from: + * Algorithm for Converting Gregorian Dates to ISO 8601 Week Date + * Rick McCarty, 1999 + * http://personal.ecu.edu/mccartyr/ISOwdALG.txt + */ +- (NSString *) weekDateStringForDate:(NSDate *)date timeZone:(NSTimeZone *)timeZone { + unparsingCalendar.timeZone = timeZone; + NSDateComponents *components = [unparsingCalendar components:NSYearCalendarUnit | NSWeekdayCalendarUnit | NSDayCalendarUnit fromDate:date]; + + //Determine the ordinal date. + NSDateComponents *startOfYearComponents = [unparsingCalendar components:NSYearCalendarUnit fromDate:date]; + startOfYearComponents.month = 1; + startOfYearComponents.day = 1; + NSDateComponents *ordinalComponents = [unparsingCalendar components:NSDayCalendarUnit fromDate:[unparsingCalendar dateFromComponents:startOfYearComponents] toDate:date options:0]; + ordinalComponents.day += 1; + + enum { + monday, tuesday, wednesday, thursday, friday, saturday, sunday + }; + enum { + january = 1, february, march, + april, may, june, + july, august, september, + october, november, december + }; + + NSInteger year = components.year; + NSInteger week = 0; + //The old unparser added 6 to [calendarDate dayOfWeek], which was zero-based; components.weekday is one-based, so we now add only 5. + NSInteger dayOfWeek = (components.weekday + 5) % 7; + NSInteger dayOfYear = ordinalComponents.day; + + NSInteger prevYear = year - 1; + + BOOL yearIsLeapYear = is_leap_year(year); + BOOL prevYearIsLeapYear = is_leap_year(prevYear); + + NSInteger YY = prevYear % 100; + NSInteger C = prevYear - YY; + NSInteger G = YY + YY / 4; + NSInteger Jan1Weekday = (((((C / 100) % 4) * 5) + G) % 7); + + NSInteger weekday = ((dayOfYear + Jan1Weekday) - 1) % 7; + + if((dayOfYear <= (7 - Jan1Weekday)) && (Jan1Weekday > thursday)) { + week = 52 + ((Jan1Weekday == friday) || ((Jan1Weekday == saturday) && prevYearIsLeapYear)); + --year; + } else { + NSInteger lengthOfYear = 365 + yearIsLeapYear; + if((lengthOfYear - dayOfYear) < (thursday - weekday)) { + ++year; + week = 1; + } else { + NSInteger J = dayOfYear + (sunday - weekday) + Jan1Weekday; + week = J / 7 - (Jan1Weekday > thursday); + } + } + + NSString *timeString; + if(includeTime) { + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + unichar timeSep = self.timeSeparator; + if (!timeSep) timeSep = ISO8601DefaultTimeSeparatorCharacter; + formatter.dateFormat = [self replaceColonsInString:ISO_TIME_WITH_TIMEZONE_FORMAT withTimeSeparator:timeSep]; + + timeString = [formatter stringForObjectValue:date]; + } else + timeString = @""; + + return [NSString stringWithFormat:@"%lu-W%02lu-%02lu%@", (unsigned long)year, (unsigned long)week, ((unsigned long)dayOfWeek) + 1U, timeString]; +} + +@end + +static NSUInteger read_segment(const unsigned char *str, const unsigned char **next, NSUInteger *out_num_digits) { + NSUInteger num_digits = 0U; + NSUInteger value = 0U; + + while(isdigit(*str)) { + value *= 10U; + value += *str - '0'; + ++num_digits; + ++str; + } + + if (next) *next = str; + if (out_num_digits) *out_num_digits = num_digits; + + return value; +} +static NSUInteger read_segment_4digits(const unsigned char *str, const unsigned char **next, NSUInteger *out_num_digits) { + NSUInteger num_digits = 0U; + NSUInteger value = 0U; + + if (isdigit(*str)) { + value += *(str++) - '0'; + ++num_digits; + } + + if (isdigit(*str)) { + value *= 10U; + value += *(str++) - '0'; + ++num_digits; + } + + if (isdigit(*str)) { + value *= 10U; + value += *(str++) - '0'; + ++num_digits; + } + + if (isdigit(*str)) { + value *= 10U; + value += *(str++) - '0'; + ++num_digits; + } + + if (next) *next = str; + if (out_num_digits) *out_num_digits = num_digits; + + return value; +} +static NSUInteger read_segment_2digits(const unsigned char *str, const unsigned char **next) { + NSUInteger value = 0U; + + if (isdigit(*str)) + value += *str - '0'; + + if (isdigit(*++str)) { + value *= 10U; + value += *(str++) - '0'; + } + + if (next) *next = str; + + return value; +} + +//strtod doesn't support ',' as a separator. This does. +static double read_double(const unsigned char *str, const unsigned char **next) { + double value = 0.0; + + if (str) { + NSUInteger int_value = 0; + + while(isdigit(*str)) { + int_value *= 10U; + int_value += (*(str++) - '0'); + } + value = int_value; + + if (((*str == ',') || (*str == '.'))) { + ++str; + + register double multiplier, multiplier_multiplier; + multiplier = multiplier_multiplier = 0.1; + + while(isdigit(*str)) { + value += (*(str++) - '0') * multiplier; + multiplier *= multiplier_multiplier; + } + } + } + + if (next) *next = str; + + return value; +} + +static BOOL is_leap_year(NSUInteger year) { + return \ + ((year % 4U) == 0U) + && (((year % 100U) != 0U) + || ((year % 400U) == 0U)); +} diff --git a/src/ACWebDAV/ISO8601/LICENSE.txt b/src/ACWebDAV/ISO8601/LICENSE.txt new file mode 100755 index 0000000..65e9e22 --- /dev/null +++ b/src/ACWebDAV/ISO8601/LICENSE.txt @@ -0,0 +1,9 @@ +Copyright © 2006 Peter Hosey + All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of Peter Hosey nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/ACWebDAV/RFC1123/NSDateRFC1123.h b/src/ACWebDAV/RFC1123/NSDateRFC1123.h new file mode 100755 index 0000000..7638830 --- /dev/null +++ b/src/ACWebDAV/RFC1123/NSDateRFC1123.h @@ -0,0 +1,30 @@ +// +// NSDateRFC1123.h +// Filmfest +// +// Created by Marcus Rohrmoser on 19.08.09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import + +/** Category on NSDate to add rfc1123 dates. Donated from the Filmfest App for free use as in free beer. + http://blog.mro.name/2009/08/nsdateformatter-http-header/ and + http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 + */ +@interface NSDate (NSDateRFC1123) + +/** + Convert a RFC1123 'Full-Date' string (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1) into NSDate. + @param value_ something like either @"Fri, 14 Aug 2009 14:45:31 GMT" or @"Sunday, 06-Nov-94 08:49:37 GMT" or @"Sun Nov 6 08:49:37 1994" + @return nil if not parseable. + */ ++(NSDate*)dateFromRFC1123:(NSString*)value_; + +/** + Convert NSDate into a RFC1123 'Full-Date' string (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1). + @return something like @"Fri, 14 Aug 2009 14:45:31 GMT" + */ +-(NSString*)rfc1123String; + +@end \ No newline at end of file diff --git a/src/ACWebDAV/RFC1123/NSDateRFC1123.m b/src/ACWebDAV/RFC1123/NSDateRFC1123.m new file mode 100755 index 0000000..d74e007 --- /dev/null +++ b/src/ACWebDAV/RFC1123/NSDateRFC1123.m @@ -0,0 +1,82 @@ +// +// NSDateRFC1123.m +// Filmfest +// +// Created by Marcus Rohrmoser on 19.08.09. +// Copyright 2009 __MyCompanyName__. All rights reserved. +// + +#import "NSDateRFC1123.h" + +@implementation NSDate (NSDateRFC1123) + ++(NSDate*)dateFromRFC1123:(NSString*)value_ +{ + if(value_ == nil) + return nil; + static NSDateFormatter *rfc1123 = nil; + if(rfc1123 == nil) + { + rfc1123 = [[NSDateFormatter alloc] init]; + rfc1123.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; + rfc1123.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; + rfc1123.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss z"; + } + NSDate *ret = [rfc1123 dateFromString:value_]; + if(ret != nil) + return ret; + + static NSDateFormatter *rfc850 = nil; + if(rfc850 == nil) + { + rfc850 = [[NSDateFormatter alloc] init]; + rfc850.locale = rfc1123.locale; + rfc850.timeZone = rfc1123.timeZone; + rfc850.dateFormat = @"EEEE',' dd'-'MMM'-'yy HH':'mm':'ss z"; + } + ret = [rfc850 dateFromString:value_]; + if(ret != nil) + return ret; + + static NSDateFormatter *asctime = nil; + if(asctime == nil) + { + asctime = [[NSDateFormatter alloc] init]; + asctime.locale = rfc1123.locale; + asctime.timeZone = rfc1123.timeZone; + asctime.dateFormat = @"EEE MMM d HH':'mm':'ss yyyy"; + } + return [asctime dateFromString:value_]; +} + + +-(NSString*)rfc1123String +{ + static NSDateFormatter *df = nil; + if(df == nil) + { + df = [[NSDateFormatter alloc] init]; + df.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; + df.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; + df.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'"; + } + return [df stringFromDate:self]; +} + + +#if 0 +// Fri, 14 Aug 2009 14:45:31 GMT +NSLogD(@"Last-Modified: %@", [vc.response.allHeaderFields objectForKey:@"Last-Modified"]); +// df.calendar = @"gregorian"; +NSLogD(@"Now: %@", [NSDate date]); +for(NSString* fmt in [NSArray arrayWithObjects:@"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j", @"k", @"l", @"m", @"n", @"o", @"p", @"q", @"r", @"s", @"t", @"u", @"v", @"w", @"x", @"y", @"z", nil]) +{ + rfc1123.dateFormat = [NSString stringWithFormat:@"%@%@%@", fmt, fmt, fmt]; + rfc1123.dateFormat = fmt; + NSLogD(@"Now (%@): %@", rfc1123.dateFormat, [rfc1123 stringFromDate:[NSDate date]]); + rfc1123.dateFormat = [rfc1123.dateFormat uppercaseString]; + NSLogD(@"Now (%@): %@", rfc1123.dateFormat, [rfc1123 stringFromDate:[NSDate date]]); +} +#endif + +@end \ No newline at end of file diff --git a/src/ACWebDAV/Requests/ACWebDAVCopyRequest.m b/src/ACWebDAV/Requests/ACWebDAVCopyRequest.m index 3f0dd75..901d7da 100644 --- a/src/ACWebDAV/Requests/ACWebDAVCopyRequest.m +++ b/src/ACWebDAV/Requests/ACWebDAVCopyRequest.m @@ -25,12 +25,12 @@ +(ACWebDAVCopyRequest*)requestWithLocation:(ACWebDAVLocation*)_location { } +(ACWebDAVCopyRequest*)requestToCopyItem:(ACWebDAVItem*)item toURL:(NSURL*)_destination delegate:(id) _delegate { - return [self requestToCopyItem:item toLocation:[ACWebDAVLocation locationWithURL:_destination] delegate:_delegate]; + return [self requestToCopyItem:item toLocation:[ACWebDAVLocation locationWithURL:_destination] overWrite:NO delegate:_delegate]; } -+(ACWebDAVCopyRequest*)requestToCopyItem:(ACWebDAVItem*)item toLocation:(ACWebDAVLocation*)_destination delegate:(id) _delegate { ++(ACWebDAVCopyRequest*)requestToCopyItem:(ACWebDAVItem*)item toLocation:(ACWebDAVLocation*)_destination overWrite:(BOOL)overwrite delegate:(id) _delegate { ACWebDAVCopyRequest* request = [self requestWithLocation:item.location]; - request.overwrite = NO; + request.overwrite = overwrite; request.destination = _destination; request.delegate = _delegate; return request; @@ -62,14 +62,14 @@ -(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChalleng - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response { if([response statusCode] == 201) { - if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(ACWebDAVCopyRequest:didCopyItem:)]) { + if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(request:didCopyItem:)]) { ACWebDAVLocation* newLocation = [ACWebDAVLocation locationWithURL:[response URL] username:self.location.username password:self.location.password]; ACWebDAVItem* item = [[ACWebDAVItem alloc] initWithLocation:newLocation]; [self.delegate request:self didCopyItem:item]; [item release]; } } else { - if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(ACWebDAVCopyRequest:didFailWithErrorCode:)]) { + if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(request:didFailWithErrorCode:)]) { [self.delegate request:self didFailWithErrorCode:[response statusCode]]; } } @@ -82,7 +82,8 @@ -(void)connectionDidFinishLoading:(NSURLConnection *)connection { -(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; - if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(ACWebDAVCopyRequest:didFailWithError:)]) { + if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(request:didFailWithError:)]) + { [self.delegate request:self didFailWithError:error]; } [connection release]; diff --git a/src/ACWebDAV/Requests/ACWebDAVMoveRequest.m b/src/ACWebDAV/Requests/ACWebDAVMoveRequest.m index 5bddb59..bbe75dd 100644 --- a/src/ACWebDAV/Requests/ACWebDAVMoveRequest.m +++ b/src/ACWebDAV/Requests/ACWebDAVMoveRequest.m @@ -25,12 +25,12 @@ +(ACWebDAVMoveRequest*)requestWithLocation:(ACWebDAVLocation*)_location { } +(ACWebDAVMoveRequest*)requestToMoveItem:(ACWebDAVItem*)item toURL:(NSURL*)_destination delegate:(id) _delegate { - return [self requestToMoveItem:item toLocation:[ACWebDAVLocation locationWithURL:_destination] delegate:_delegate]; + return [self requestToMoveItem:item toLocation:[ACWebDAVLocation locationWithURL:_destination] overWrite:NO delegate:_delegate]; } -+(ACWebDAVMoveRequest*)requestToMoveItem:(ACWebDAVItem*)item toLocation:(ACWebDAVLocation*)_destination delegate:(id) _delegate { ++(ACWebDAVMoveRequest*)requestToMoveItem:(ACWebDAVItem*)item toLocation:(ACWebDAVLocation*)_destination overWrite:(BOOL)overwrite delegate:(id) _delegate { ACWebDAVMoveRequest* request = [self requestWithLocation:item.location]; - request.overwrite = NO; + request.overwrite = overwrite; request.destination = _destination; request.delegate = _delegate; return request; @@ -62,14 +62,14 @@ -(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChalleng - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response { if([response statusCode] == 201) { - if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(ACWebDAVMoveRequest:didMoveItem:)]) { + if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(request:didMoveItem:)]) { ACWebDAVLocation* newLocation = [ACWebDAVLocation locationWithURL:[response URL] username:self.location.username password:self.location.password]; ACWebDAVItem* item = [[ACWebDAVItem alloc] initWithLocation:newLocation]; [self.delegate request:self didMoveItem:item]; [item release]; } } else { - if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(ACWebDAVMoveRequest:didFailWithErrorCode:)]) { + if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(request:didFailWithErrorCode:)]) { [self.delegate request:self didFailWithErrorCode:[response statusCode]]; } } @@ -82,7 +82,8 @@ -(void)connectionDidFinishLoading:(NSURLConnection *)connection { -(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; - if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(ACWebDAVMoveRequest:didFailWithError:)]) { + if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(request: didFailWithError:)]) + { [self.delegate request:self didFailWithError:error]; } [connection release]; From b25387d25beeb741fd714bc27a22a77ab1e2dfd6 Mon Sep 17 00:00:00 2001 From: Traximus Date: Mon, 28 Jan 2013 14:40:53 +0800 Subject: [PATCH 2/2] fix some little bugs 1.ACWebDAVDownloadRequest.h&.m add a new var to hold the reference of currentConnection, used to cancel a request if needed; also add a new method(cancel) to cancel this request 2.ACWebDAVDeleteRequest.m - connection: didReceiveResponse: response.statusCode=201 OR response.statusCode=204 all shows deleted successfully. 3.ACWebDAVClient.h - add new optional delegate methods - (BOOL)needToCancelDownload; - (void)resetCancelDownload:(BOOL)cancel; - (BOOL)needToCancelUpload; - (void)resetCancelUpload:(BOOL)cancel; used to check if need to cancel a request --- .gitignore | 1 + src/.DS_Store | Bin 12292 -> 12292 bytes src/ACWebDAV/.DS_Store | Bin 12292 -> 12292 bytes src/ACWebDAV/ACWebDAVClient.h | 6 +++++- src/ACWebDAV/Requests/ACWebDAVDeleteRequest.m | 2 +- .../Requests/ACWebDAVDownloadRequest.h | 2 ++ .../Requests/ACWebDAVDownloadRequest.m | 20 ++++++++++++++++-- 7 files changed, 27 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index bc41820..7d91e7a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Mac OS X *.DS_Store +.DS_Store # Xcode *.pbxuser diff --git a/src/.DS_Store b/src/.DS_Store index 1362d255d58c6a821ecf2408d3b2c38480ce4994..6c8193af50f70244fc89a684106b302d3b3a28a2 100644 GIT binary patch delta 57 zcmZokXi3$B N#?6AVpM{th7yvNi5*7de delta 70 zcmZokXi3b<06AI~dH?_b diff --git a/src/ACWebDAV/.DS_Store b/src/ACWebDAV/.DS_Store index bd0176755c773ced978e60d2dc120f14b35111a4..72a255a3ef1525f4832b02bffdf1668e5386336d 100644 GIT binary patch delta 186 zcmZokXi1ph&nUPtU^hRb;AS3y$4oMwIr+&+Ir&Kp3=9Gc49p*Zw8nohU|`sMS4fzV z1t`Ki`HQgfMGrPn$mdO`Hq)E`l&Ad54b`d`SfXOjj delta 83 zcmZokXi1ph&&ag(Mqs diff --git a/src/ACWebDAV/ACWebDAVClient.h b/src/ACWebDAV/ACWebDAVClient.h index 205c3d7..2556f0c 100644 --- a/src/ACWebDAV/ACWebDAVClient.h +++ b/src/ACWebDAV/ACWebDAVClient.h @@ -71,11 +71,15 @@ @protocol ACWebDAVClientDelegate @optional +- (BOOL)needToCancelDownload; +- (void)resetCancelDownload:(BOOL)cancel; +- (BOOL)needToCancelUpload; +- (void)resetCancelUpload:(BOOL)cancel; - (void)client:(ACWebDAVClient*)client failedWithError:(NSError*)error; - (void)client:(ACWebDAVClient*)client failedWithErrorCode:(int)errorCode; -- (void)client:(ACWebDAVClient*)client loadedMetadata:(ACWebDAVItem*)item; +- (void)client:(ACWebDAVClient*)client loadedMetadata:(NSArray *)items; - (void)client:(ACWebDAVClient*)client loadMetadataFailedWithError:(NSError*)error; - (void)client:(ACWebDAVClient*)client loadMetadataFailedWithErrorCode:(int)errorCode; diff --git a/src/ACWebDAV/Requests/ACWebDAVDeleteRequest.m b/src/ACWebDAV/Requests/ACWebDAVDeleteRequest.m index 903432f..390433b 100644 --- a/src/ACWebDAV/Requests/ACWebDAVDeleteRequest.m +++ b/src/ACWebDAV/Requests/ACWebDAVDeleteRequest.m @@ -54,7 +54,7 @@ -(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChalleng } - (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response { - if([response statusCode] == 201) { + if([response statusCode] == 201||[response statusCode]==204) { if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(request:didDeleteItem:)]) { ACWebDAVLocation* newLocation = [ACWebDAVLocation locationWithURL:[response URL] username:self.location.username password:self.location.password]; ACWebDAVItem* item = [[ACWebDAVItem alloc] initWithLocation:newLocation]; diff --git a/src/ACWebDAV/Requests/ACWebDAVDownloadRequest.h b/src/ACWebDAV/Requests/ACWebDAVDownloadRequest.h index b045f7c..b46c047 100644 --- a/src/ACWebDAV/Requests/ACWebDAVDownloadRequest.h +++ b/src/ACWebDAV/Requests/ACWebDAVDownloadRequest.h @@ -36,8 +36,10 @@ @property (nonatomic, retain) id delegate; @property (nonatomic, retain) ACWebDAVLocation* location; @property (nonatomic, retain) NSDictionary* userInfo; +@property (nonatomic, retain) NSURLConnection* currentConnection;//new -(void)start; +-(void)cancel; +(ACWebDAVDownloadRequest*)requestToDownloadItem:(ACWebDAVItem*)item delegate:(id) delegate; @end diff --git a/src/ACWebDAV/Requests/ACWebDAVDownloadRequest.m b/src/ACWebDAV/Requests/ACWebDAVDownloadRequest.m index 78910a6..edb3c7c 100644 --- a/src/ACWebDAV/Requests/ACWebDAVDownloadRequest.m +++ b/src/ACWebDAV/Requests/ACWebDAVDownloadRequest.m @@ -11,7 +11,7 @@ @implementation ACWebDAVDownloadRequest -@synthesize delegate, location, userInfo; +@synthesize delegate, location, userInfo,currentConnection; -(id)initWithLocation:(ACWebDAVLocation*)_location { if(self = [self init]) { @@ -34,9 +34,23 @@ -(void)start { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:self.location.url]; NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; + if (self.currentConnection!=nil) + { + self.currentConnection = nil; + } + self.currentConnection = conn; [conn start]; } +//new +-(void)cancel +{ + [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; + [self.currentConnection cancel]; + [self.currentConnection release]; + NSLog(@"canceled"); +} + -(NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectResponse { return request; } @@ -72,7 +86,8 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLRe } } --(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)d { +-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)d +{ [data appendData:d]; if(self.delegate != nil && [(NSObject*)self.delegate respondsToSelector:@selector(request:didUpdateDownloadProgress:)]) { [self.delegate request:self didUpdateDownloadProgress:(float)data.length/contentLength]; @@ -96,6 +111,7 @@ -(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error } -(void)dealloc { + [currentConnection release];//new [userInfo release]; [location release]; [(NSObject*)delegate release];