From 68cf267b1d6590af3cb6f4a08da33ec8ef6c3e5d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 18 May 2016 15:49:33 +0900 Subject: [PATCH] Do not convert NSDictionary to JSON --- atom/browser/mac/dict_util.mm | 100 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 13 deletions(-) diff --git a/atom/browser/mac/dict_util.mm b/atom/browser/mac/dict_util.mm index 1889095..f880cda 100644 --- a/atom/browser/mac/dict_util.mm +++ b/atom/browser/mac/dict_util.mm @@ -4,13 +4,55 @@ #include "atom/browser/mac/dict_util.h" -#include "base/mac/scoped_nsobject.h" -#include "base/json/json_reader.h" #include "base/json/json_writer.h" +#include "base/strings/sys_string_conversions.h" #include "base/values.h" namespace atom { +namespace { + +scoped_ptr NSArrayToListValue(NSArray* arr) { + if (!arr) + return nullptr; + + scoped_ptr result(new base::ListValue); + for (id value in arr) { + if ([value isKindOfClass:[NSString class]]) { + result->AppendString(base::SysNSStringToUTF8(value)); + } else if ([value isKindOfClass:[NSNumber class]]) { + const char* objc_type = [value objCType]; + if (strcmp(objc_type, @encode(BOOL)) == 0 || + strcmp(objc_type, @encode(char)) == 0) + result->AppendBoolean([value boolValue]); + else if (strcmp(objc_type, @encode(double)) == 0 || + strcmp(objc_type, @encode(float)) == 0) + result->AppendDouble([value doubleValue]); + else + result->AppendInteger([value intValue]); + } else if ([value isKindOfClass:[NSArray class]]) { + scoped_ptr sub_arr = NSArrayToListValue(value); + if (sub_arr) + result->Append(std::move(sub_arr)); + else + result->Append(base::Value::CreateNullValue()); + } else if ([value isKindOfClass:[NSDictionary class]]) { + scoped_ptr sub_dict = + NSDictionaryToDictionaryValue(value); + if (sub_dict) + result->Append(std::move(sub_dict)); + else + result->Append(base::Value::CreateNullValue()); + } else { + result->Append(base::Value::CreateNullValue()); + } + } + + return result; +} + +} // namespace + NSDictionary* DictionaryValueToNSDictionary(const base::DictionaryValue& value) { std::string json; if (!base::JSONWriter::Write(value, &json)) @@ -26,20 +68,52 @@ NSDictionary* DictionaryValueToNSDictionary(const base::DictionaryValue& value) scoped_ptr NSDictionaryToDictionaryValue( NSDictionary* dict) { - if (!dict || ![NSJSONSerialization isValidJSONObject:dict]) + if (!dict) return nullptr; - NSData* data = [NSJSONSerialization dataWithJSONObject:dict - options:0 - error:nil]; - if (!data) - return nullptr; + scoped_ptr result(new base::DictionaryValue); + for (id key in dict) { + std::string str_key; + if ([key isKindOfClass:[NSString class]]) + str_key = base::SysNSStringToUTF8(key); + else + str_key = base::SysNSStringToUTF8([NSString stringWithFormat:@"%p", key]); + + id value = [dict objectForKey:key]; + if ([value isKindOfClass:[NSString class]]) { + result->SetStringWithoutPathExpansion( + str_key, base::SysNSStringToUTF8(value)); + } else if ([value isKindOfClass:[NSNumber class]]) { + const char* objc_type = [value objCType]; + if (strcmp(objc_type, @encode(BOOL)) == 0 || + strcmp(objc_type, @encode(char)) == 0) + result->SetBooleanWithoutPathExpansion(str_key, [value boolValue]); + else if (strcmp(objc_type, @encode(double)) == 0 || + strcmp(objc_type, @encode(float)) == 0) + result->SetDoubleWithoutPathExpansion(str_key, [value doubleValue]); + else + result->SetIntegerWithoutPathExpansion(str_key, [value intValue]); + } else if ([value isKindOfClass:[NSArray class]]) { + scoped_ptr sub_arr = NSArrayToListValue(value); + if (sub_arr) + result->SetWithoutPathExpansion(str_key, std::move(sub_arr)); + else + result->SetWithoutPathExpansion(str_key, + base::Value::CreateNullValue()); + } else if ([value isKindOfClass:[NSDictionary class]]) { + scoped_ptr sub_dict = + NSDictionaryToDictionaryValue(value); + if (sub_dict) + result->SetWithoutPathExpansion(str_key, std::move(sub_dict)); + else + result->SetWithoutPathExpansion(str_key, + base::Value::CreateNullValue()); + } else { + result->SetWithoutPathExpansion(str_key, base::Value::CreateNullValue()); + } + } - base::scoped_nsobject json = - [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - scoped_ptr value = - base::JSONReader::Read([json UTF8String]); - return base::DictionaryValue::From(std::move(value)); + return result; } } // namespace atom -- 2.7.4