//
//  NSString+substringWithRange2.m
//  サロゲートペア文字に対応したsubstringWithRange:
//
//  Created by AIG-Soft(iMac) on 2015/08/31.
//  Copyright (c) 2015年 AIG-Soft. All rights reserved.
//

#import "NSString+substringWithRange2.h"
#import "libs.h"

//#define	printSelf()		nslog(@"%@:%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd))

@implementation NSString (substringWithRange2)

/// サロゲートペアを考慮したlength
-(NSUInteger)length2
{
	printSelf();
	NSUInteger len=0;
	for (NSUInteger i=0;i<[self length];i++) {
		ULong c16=[self characterAtIndex:i];
		nslog(@"UTF16=$%x",(int)c16);
		if (isSurrogate(c16)) {
			nslog(@"サロゲートペア文字である");
			i++;
		}
		len++;
	}
	nslog(@"長さ=%tu",len);
	return (len);
}


/// サロゲートペアを考慮したsubstringWithRange:
-(NSString *)substringWithRange2:(NSRange)range
{
	printSelf();
	nslog(@"range={%tu,%tu}",range.location,range.length);
	
	NSUInteger length=range.length;
	if (length==0) {
		nslog(@"長さ0の時は常に空文字列");
		return @"";
	}
	// length>=1
	
	// サロゲートペアを位置を算出
	NSInteger i=[self getLocationWithSurrogate:self location:range.location];
	
	NSUInteger len=0;
	NSRange range2={i,0}; // 新しい切り出し範囲
	for (;i<[self length];i++) {
		ULong c16=[self characterAtIndex:i];
		len++;
		nslog(@"UTF16=$%x",(int)c16);
		if (isSurrogate(c16)) {
			nslog(@"サロゲートペア文字である");
			len++;
			i++;
		}
		if (--length==0) break;
	}
	nslog(@"len=%tu",len);
	range2.length=len;
	NSString *s=[self substringWithRange:range2];
	nslog(@"s=%@",s);
	return s;
}

/// サロゲートペアを考慮したsubstringFromIndex:
// fromは0:先頭〜
-(NSString *)substringFromIndex2:(NSUInteger)from
{
	printSelf();
	nslog(@"from=%tu",from);
	NSRange range={from,[self length]}; // 長さは以降全てで構わない;substringWithRange2が吸収してくれるので(substringWithRange:ではそういう指定はできない)
	return [self substringWithRange2:range];
}

/// サロゲートペアを考慮したsubstringToIndex:
// toで指定した位置の直前まで=先頭何文字
//  故に、to=0なら常に@"",=1なら先頭1文字(文字位置0)
-(NSString *)substringToIndex2:(NSUInteger)to
{
	printSelf();
	if (to==0) {
		nslog(@"toが0の時は常に空文字列");
		return @"";
	}
	nslog(@"to=%tu",to);
	NSRange range=NSMakeRange(0,to);
	return [self substringWithRange2:range];
}

/// サロゲートペアを考慮してlocation文字目の位置を得る
/// @param [in] location 文字位置;0:先頭~
-(NSUInteger)getLocationWithSurrogate:(NSString *)str location:(NSUInteger)location
{
	printSelf();
	NSUInteger i=0;
	if (location>0) {
		for (;i<[str length];i++) {
			ULong c16=[str characterAtIndex:i];
			nslog(@"UTF16=$%x",(int)c16);
			if (isSurrogate(c16)) {
				nslog(@"サロゲートペア文字である");
				i++;
			}
			if (--location==0) {
				// location>=1であるが、
				// サロゲートペアでないときはi=0,ペアの時は=1となっている(forの次の++がまだかかってないから)
				i++;
				break;
			}
		}
		// locationがlengthを超えるときは=lengthが入る
	} // location=0:先頭の時は常に0=先頭
	nslog(@"開始位置=%tu",i);
	return (i);
}

@end
