Initial commit
This commit is contained in:
+15
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// NTESPinyinConverter.h
|
||||
// NIM
|
||||
//
|
||||
// Created by amao on 10/15/13.
|
||||
// Copyright (c) 2013 Netease. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NTESPinyinConverter : NSObject
|
||||
+ (NTESPinyinConverter *)sharedInstance;
|
||||
|
||||
- (NSString *)toPinyin: (NSString *)source;
|
||||
@end
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// NTESPinyinConverter.m
|
||||
// NIM
|
||||
//
|
||||
// Created by amao on 10/15/13.
|
||||
// Copyright (c) 2013 Netease. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NTESPinyinConverter.h"
|
||||
|
||||
#define kHanziMin 0x4E00
|
||||
#define kHanziMax 0x9FA5
|
||||
|
||||
@interface NTESPinyinConverter ()
|
||||
{
|
||||
int *_codeIndex;
|
||||
char *_pinyin;
|
||||
BOOL _inited;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NTESPinyinConverter
|
||||
+ (NTESPinyinConverter *)sharedInstance
|
||||
{
|
||||
static NTESPinyinConverter *instance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[NTESPinyinConverter alloc] init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
_codeIndex = NULL;
|
||||
_pinyin = NULL;
|
||||
|
||||
NSString *filepath = [[NSBundle mainBundle] pathForResource:@"pinyin"
|
||||
ofType:@"bin"];
|
||||
if (filepath)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
FILE *fp = fopen([filepath UTF8String], "rb");
|
||||
if (fp)
|
||||
{
|
||||
int hanZiNumber = 0,pinyinSize = 0;
|
||||
size_t size = fread(&hanZiNumber, 4, 1, fp);
|
||||
if (size != 1)
|
||||
{
|
||||
assert(0);
|
||||
NSLog(@"Read HanziNumber Failed,%zu",size);
|
||||
break;
|
||||
}
|
||||
size = fread(&pinyinSize, 4, 1, fp);
|
||||
if (size != 1)
|
||||
{
|
||||
assert(0);
|
||||
NSLog(@"Read pinyinSize Failed,%zu",size);
|
||||
break;
|
||||
}
|
||||
|
||||
if (hanZiNumber != kHanziMax - kHanziMin + 1)
|
||||
{
|
||||
assert(0);
|
||||
NSLog(@"Read pinyinSize Failed,%zu",size);
|
||||
}
|
||||
|
||||
_codeIndex = (int*)calloc(hanZiNumber, sizeof(int));
|
||||
_pinyin = (char*)calloc(pinyinSize, sizeof(char));
|
||||
|
||||
size = fread(_codeIndex, 4, hanZiNumber, fp);
|
||||
if (size != hanZiNumber)
|
||||
{
|
||||
NSLog(@"Read CodeIndex Failed,%zu",size);
|
||||
break;
|
||||
}
|
||||
size = fread(_pinyin, 1, pinyinSize, fp);
|
||||
if (size != pinyinSize)
|
||||
{
|
||||
NSLog(@"Read Pinyin Failed,%zu",size);
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
_inited = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
NSLog(@"Open Pinyin File Failed %@",filepath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)pinyin: (unichar)p
|
||||
{
|
||||
if (p >= kHanziMin && p <= kHanziMax)
|
||||
{
|
||||
return [NSString stringWithUTF8String:_pinyin + _codeIndex[p - kHanziMin]] ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return [[NSString alloc]initWithCharacters:&p length:1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)toPinyin: (NSString *)source
|
||||
{
|
||||
if ([source length] == 0 || !_inited)
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
NSMutableString *pinyin = [[NSMutableString alloc] init];
|
||||
for (NSInteger i = 0; i < [source length]; i++)
|
||||
{
|
||||
unichar p = [source characterAtIndex:i];
|
||||
[pinyin appendString:[self pinyin:p]];
|
||||
}
|
||||
return pinyin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// NTESSpellingCenter.h
|
||||
// NIM
|
||||
// 用于拼音全称和简称生成查询读取的类
|
||||
// Created by amao on 13-1-21.
|
||||
// Copyright (c) 2013年 Netease. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface SpellingUnit : NSObject<NSCoding>
|
||||
@property (nonatomic,strong) NSString *fullSpelling;
|
||||
@property (nonatomic,strong) NSString *shortSpelling;
|
||||
@end
|
||||
|
||||
@interface NTESSpellingCenter : NSObject
|
||||
{
|
||||
NSMutableDictionary *_spellingCache; //全拼,简称cache
|
||||
NSString *_filepath;
|
||||
}
|
||||
+ (NTESSpellingCenter *)sharedCenter;
|
||||
- (void)saveSpellingCache; //写入缓存
|
||||
|
||||
- (SpellingUnit *)spellingForString: (NSString *)source; //全拼,简拼 (全是小写)
|
||||
- (NSString *)firstLetter: (NSString *)input; //首字母
|
||||
@end
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
//
|
||||
// NTESSpellingCenter.m
|
||||
// NIM
|
||||
//
|
||||
// Created by amao on 13-1-21.
|
||||
// Copyright (c) 2013年 Netease. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NTESSpellingCenter.h"
|
||||
#import "NTESPinyinConverter.h"
|
||||
|
||||
#define SPELLING_UNIT_FULLSPELLING @"f"
|
||||
#define SPELLING_UNIT_SHORTSPELLING @"s"
|
||||
#define SPELLING_CACHE @"sc"
|
||||
|
||||
@implementation SpellingUnit
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder
|
||||
{
|
||||
[aCoder encodeObject:_fullSpelling forKey:SPELLING_UNIT_FULLSPELLING];
|
||||
[aCoder encodeObject:_shortSpelling forKey:SPELLING_UNIT_SHORTSPELLING];
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)aDecoder
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
self.fullSpelling = [aDecoder decodeObjectForKey:SPELLING_UNIT_FULLSPELLING];
|
||||
self.shortSpelling= [aDecoder decodeObjectForKey:SPELLING_UNIT_SHORTSPELLING];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface NTESSpellingCenter ()
|
||||
- (SpellingUnit *)calcSpellingOfString: (NSString *)source;
|
||||
@end
|
||||
|
||||
|
||||
@implementation NTESSpellingCenter
|
||||
+ (NTESSpellingCenter *)sharedCenter
|
||||
{
|
||||
static NTESSpellingCenter *instance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
instance = [[NTESSpellingCenter alloc]init];
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *appDocumentPath= [[NSString alloc] initWithFormat:@"%@/",[paths objectAtIndex:0]];
|
||||
_filepath = [appDocumentPath stringByAppendingPathComponent:SPELLING_CACHE];
|
||||
|
||||
_spellingCache = nil;
|
||||
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:_filepath])
|
||||
{
|
||||
NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithFile:_filepath];
|
||||
if ([dict isKindOfClass:[NSDictionary class]])
|
||||
{
|
||||
_spellingCache = [[NSMutableDictionary alloc]initWithDictionary:dict];
|
||||
}
|
||||
|
||||
}
|
||||
if (!_spellingCache)
|
||||
{
|
||||
_spellingCache = [[NSMutableDictionary alloc]init];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)saveSpellingCache
|
||||
{
|
||||
static const NSInteger kMaxEntriesCount = 5000;
|
||||
@synchronized(self)
|
||||
{
|
||||
NSInteger count = [_spellingCache count];
|
||||
NSLog(@"Spelling Cache Entries %zd", count);
|
||||
if (count >= kMaxEntriesCount)
|
||||
{
|
||||
NSLog(@"Clear Spelling Cache %zd Entries",count);
|
||||
[_spellingCache removeAllObjects];
|
||||
}
|
||||
if (_spellingCache)
|
||||
{
|
||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_spellingCache];
|
||||
[data writeToFile:_filepath atomically:YES];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (SpellingUnit *)spellingForString:(NSString *)source
|
||||
{
|
||||
if ([source length] == 0)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
SpellingUnit *spellingUnit = nil;
|
||||
@synchronized(self)
|
||||
{
|
||||
SpellingUnit *unit = [_spellingCache objectForKey:source];
|
||||
if (!unit)
|
||||
{
|
||||
unit = [self calcSpellingOfString:source];
|
||||
if ([unit.fullSpelling length] && [unit.shortSpelling length])
|
||||
{
|
||||
[_spellingCache setObject:unit forKey:source];
|
||||
}
|
||||
}
|
||||
spellingUnit = unit;
|
||||
}
|
||||
return spellingUnit;
|
||||
}
|
||||
|
||||
- (NSString *)firstLetter:(NSString *)input
|
||||
{
|
||||
SpellingUnit *unit = [self spellingForString:input];
|
||||
NSString *spelling = unit.fullSpelling;
|
||||
return [spelling length] ? [spelling substringWithRange:NSMakeRange(0, 1)] : nil;
|
||||
}
|
||||
|
||||
|
||||
- (SpellingUnit *)calcSpellingOfString:(NSString *)source
|
||||
{
|
||||
NSMutableString *fullSpelling = [[NSMutableString alloc]init];
|
||||
NSMutableString *shortSpelling= [[NSMutableString alloc]init];
|
||||
for (NSInteger i = 0; i < [source length]; i++)
|
||||
{
|
||||
NSString *word = [source substringWithRange:NSMakeRange(i, 1)];
|
||||
NSString *pinyin = [[NTESPinyinConverter sharedInstance] toPinyin:word];
|
||||
|
||||
if ([pinyin length])
|
||||
{
|
||||
[fullSpelling appendString:pinyin];
|
||||
[shortSpelling appendString:[pinyin substringToIndex:1]];
|
||||
}
|
||||
}
|
||||
|
||||
SpellingUnit *unit = [[SpellingUnit alloc]init];
|
||||
unit.fullSpelling = [fullSpelling lowercaseString];
|
||||
unit.shortSpelling= [shortSpelling lowercaseString];
|
||||
return unit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user