-
Notifications
You must be signed in to change notification settings - Fork 300
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: use dynamics to cover string and number (#600)
* fix: use dynamics to cover string and number * fix: change values in JS too
- Loading branch information
Showing
5 changed files
with
120 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#import <folly/dynamic.h> | ||
#import <Foundation/Foundation.h> | ||
#import <objc/runtime.h> | ||
|
||
// copied from RCTFollyConvert | ||
static id RNCPickerConvertFollyDynamicToId(const folly::dynamic &dyn) | ||
{ | ||
// I could imagine an implementation which avoids copies by wrapping the | ||
// dynamic in a derived class of NSDictionary. We can do that if profiling | ||
// implies it will help. | ||
|
||
switch (dyn.type()) { | ||
case folly::dynamic::NULLT: | ||
return nil; | ||
case folly::dynamic::BOOL: | ||
return dyn.getBool() ? @YES : @NO; | ||
case folly::dynamic::INT64: | ||
return @(dyn.getInt()); | ||
case folly::dynamic::DOUBLE: | ||
return @(dyn.getDouble()); | ||
case folly::dynamic::STRING: | ||
return [[NSString alloc] initWithBytes:dyn.c_str() length:dyn.size() encoding:NSUTF8StringEncoding]; | ||
case folly::dynamic::ARRAY: { | ||
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dyn.size()]; | ||
for (const auto &elem : dyn) { | ||
id value = RNCPickerConvertFollyDynamicToId(elem); | ||
if (value) { | ||
[array addObject:value]; | ||
} | ||
} | ||
return array; | ||
} | ||
case folly::dynamic::OBJECT: { | ||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:dyn.size()]; | ||
for (const auto &elem : dyn.items()) { | ||
id key = RNCPickerConvertFollyDynamicToId(elem.first); | ||
id value = RNCPickerConvertFollyDynamicToId(elem.second); | ||
if (key && value) { | ||
dict[key] = value; | ||
} | ||
} | ||
return dict; | ||
} | ||
} | ||
} | ||
|
||
static folly::dynamic RNCPickerRNCPickerConvertIdToFollyDynamic(id json) | ||
{ | ||
if (json == nil || json == (id)kCFNull) { | ||
return nullptr; | ||
} else if ([json isKindOfClass:[NSNumber class]]) { | ||
const char *objCType = [json objCType]; | ||
switch (objCType[0]) { | ||
// This is a c++ bool or C99 _Bool. On some platforms, BOOL is a bool. | ||
case _C_BOOL: | ||
return (bool)[json boolValue]; | ||
case _C_CHR: | ||
// On some platforms, objc BOOL is a signed char, but it | ||
// might also be a small number. Use the same hack JSC uses | ||
// to distinguish them: | ||
// https://phabricator.intern.facebook.com/diffusion/FBS/browse/master/fbobjc/xplat/third-party/jsc/safari-600-1-4-17/JavaScriptCore/API/JSValue.mm;b8ee03916489f8b12143cd5c0bca546da5014fc9$901 | ||
if ([json isKindOfClass:[@YES class]]) { | ||
return (bool)[json boolValue]; | ||
} else { | ||
return [json longLongValue]; | ||
} | ||
case _C_UCHR: | ||
case _C_SHT: | ||
case _C_USHT: | ||
case _C_INT: | ||
case _C_UINT: | ||
case _C_LNG: | ||
case _C_ULNG: | ||
case _C_LNG_LNG: | ||
case _C_ULNG_LNG: | ||
return [json longLongValue]; | ||
|
||
case _C_FLT: | ||
case _C_DBL: | ||
return [json doubleValue]; | ||
|
||
// default: | ||
// fall through | ||
} | ||
} else if ([json isKindOfClass:[NSString class]]) { | ||
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding]; | ||
return std::string(reinterpret_cast<const char *>(data.bytes), data.length); | ||
} else if ([json isKindOfClass:[NSArray class]]) { | ||
folly::dynamic array = folly::dynamic::array; | ||
for (id element in json) { | ||
array.push_back(RNCPickerRNCPickerConvertIdToFollyDynamic(element)); | ||
} | ||
return array; | ||
} else if ([json isKindOfClass:[NSDictionary class]]) { | ||
__block folly::dynamic object = folly::dynamic::object(); | ||
|
||
[json enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, __unused BOOL *stop) { | ||
object.insert(RNCPickerRNCPickerConvertIdToFollyDynamic(key), RNCPickerRNCPickerConvertIdToFollyDynamic(value)); | ||
}]; | ||
|
||
return object; | ||
} | ||
|
||
return nil; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters