diff --git a/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.h b/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.h deleted file mode 120000 index 741727187..000000000 --- a/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../fbobjc/Libraries/FBCxxUtils/FBCxxUtils/FBCxxFollyDynamicConvert.h \ No newline at end of file diff --git a/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.h b/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.h new file mode 100644 index 000000000..dbd834633 --- /dev/null +++ b/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.h @@ -0,0 +1,14 @@ +// Copyright 2004-present Facebook. All Rights Reserved. +#pragma once + +#import + +#include + +namespace facebook { +namespace cxxutils { + +folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf = false); +id convertFollyDynamicToId(const folly::dynamic &dyn); + +} } diff --git a/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.mm b/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.mm deleted file mode 120000 index 9dfc382f8..000000000 --- a/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.mm +++ /dev/null @@ -1 +0,0 @@ -../../../../../fbobjc/Libraries/FBCxxUtils/FBCxxUtils/FBCxxFollyDynamicConvert.mm \ No newline at end of file diff --git a/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.mm b/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.mm new file mode 100644 index 000000000..77f50c474 --- /dev/null +++ b/iOS/FlipperKit/FBCxxUtils/FBCxxFollyDynamicConvert.mm @@ -0,0 +1,128 @@ +// Copyright 2004-present Facebook. All Rights Reserved. + +#import "FBCxxFollyDynamicConvert.h" + +#import + +namespace facebook { +namespace cxxutils { + +/* + * The implementation is taken from RCTFollyConvert(https://fburl.com/vzw8ql2q) + */ + +id convertFollyDynamicToId(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 (id)kCFNull; + 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 (auto &elem : dyn) { + id obj = convertFollyDynamicToId(elem); + if (obj) { + [array addObject:obj]; + } + } + return array; + } + case folly::dynamic::OBJECT: { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:dyn.size()]; + for (auto &elem : dyn.items()) { + id obj = convertFollyDynamicToId(elem.second); + if (obj) { + dict[convertFollyDynamicToId(elem.first)] = obj; + } + } + return dict; + } + } +} + +folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf) +{ + 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 { + const auto value = [json longLongValue]; + if (nullifyNanAndInf && (isnan(value) || isinf(value))) { + return nullptr; + } + return value; + } + 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: { + const auto value = [json longLongValue]; + if (nullifyNanAndInf && (isnan(value) || isinf(value))) { + return nullptr; + } + return value; + } + + case _C_FLT: + case _C_DBL: { + const auto value = [json doubleValue]; + if (nullifyNanAndInf && (isnan(value) || isinf(value))) { + return nullptr; + } + return value; + } + + // default: + // fall through + } + } else if ([json isKindOfClass:[NSString class]]) { + NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding]; + return std::string(reinterpret_cast(data.bytes), data.length); + } else if ([json isKindOfClass:[NSArray class]]) { + folly::dynamic array = folly::dynamic::array; + for (id element in json) { + array.push_back(convertIdToFollyDynamic(element, nullifyNanAndInf)); + } + 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(convertIdToFollyDynamic(key, nullifyNanAndInf), convertIdToFollyDynamic(value, nullifyNanAndInf)); + }]; + + return object; + } + + return nil; +} +} +} diff --git a/iOS/SonarKit/FBCxxUtils/FBCxxFollyDynamicConvert.h b/iOS/SonarKit/FBCxxUtils/FBCxxFollyDynamicConvert.h deleted file mode 100644 index dbd834633..000000000 --- a/iOS/SonarKit/FBCxxUtils/FBCxxFollyDynamicConvert.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. -#pragma once - -#import - -#include - -namespace facebook { -namespace cxxutils { - -folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf = false); -id convertFollyDynamicToId(const folly::dynamic &dyn); - -} } diff --git a/iOS/SonarKit/FBCxxUtils/FBCxxFollyDynamicConvert.mm b/iOS/SonarKit/FBCxxUtils/FBCxxFollyDynamicConvert.mm deleted file mode 100644 index 77f50c474..000000000 --- a/iOS/SonarKit/FBCxxUtils/FBCxxFollyDynamicConvert.mm +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2004-present Facebook. All Rights Reserved. - -#import "FBCxxFollyDynamicConvert.h" - -#import - -namespace facebook { -namespace cxxutils { - -/* - * The implementation is taken from RCTFollyConvert(https://fburl.com/vzw8ql2q) - */ - -id convertFollyDynamicToId(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 (id)kCFNull; - 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 (auto &elem : dyn) { - id obj = convertFollyDynamicToId(elem); - if (obj) { - [array addObject:obj]; - } - } - return array; - } - case folly::dynamic::OBJECT: { - NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:dyn.size()]; - for (auto &elem : dyn.items()) { - id obj = convertFollyDynamicToId(elem.second); - if (obj) { - dict[convertFollyDynamicToId(elem.first)] = obj; - } - } - return dict; - } - } -} - -folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf) -{ - 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 { - const auto value = [json longLongValue]; - if (nullifyNanAndInf && (isnan(value) || isinf(value))) { - return nullptr; - } - return value; - } - 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: { - const auto value = [json longLongValue]; - if (nullifyNanAndInf && (isnan(value) || isinf(value))) { - return nullptr; - } - return value; - } - - case _C_FLT: - case _C_DBL: { - const auto value = [json doubleValue]; - if (nullifyNanAndInf && (isnan(value) || isinf(value))) { - return nullptr; - } - return value; - } - - // default: - // fall through - } - } else if ([json isKindOfClass:[NSString class]]) { - NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding]; - return std::string(reinterpret_cast(data.bytes), data.length); - } else if ([json isKindOfClass:[NSArray class]]) { - folly::dynamic array = folly::dynamic::array; - for (id element in json) { - array.push_back(convertIdToFollyDynamic(element, nullifyNanAndInf)); - } - 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(convertIdToFollyDynamic(key, nullifyNanAndInf), convertIdToFollyDynamic(value, nullifyNanAndInf)); - }]; - - return object; - } - - return nil; -} -} -}