fbshipit-source-id: d0f4b1833968aae403b114119f4e8cda184361c9
This commit is contained in:
20
iOS/SonarKit/FBCxxUtils/FBCxxFollyDynamicConvert.h
Normal file
20
iOS/SonarKit/FBCxxUtils/FBCxxFollyDynamicConvert.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2004-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the LICENSE
|
||||
* file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace cxxutils {
|
||||
|
||||
folly::dynamic convertIdToFollyDynamic(id json);
|
||||
id convertFollyDynamicToId(const folly::dynamic &dyn);
|
||||
|
||||
} }
|
||||
@@ -1,97 +1,17 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
#import "FBCxxFollyDynamicConvert.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace cxxutils {
|
||||
|
||||
/*
|
||||
* Copyright (c) 2018-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the LICENSE
|
||||
* file in the root directory of this source tree.
|
||||
*
|
||||
* The implementation is taken from RCTFollyConvert(https://fburl.com/vzw8ql2q)
|
||||
*/
|
||||
#include "SKUtils.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
using namespace facebook::sonar;
|
||||
|
||||
@implementation SKUtils
|
||||
|
||||
+ (folly::dynamic)convertIdToFollyDynamic:(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 {
|
||||
const auto value = [json longLongValue];
|
||||
if (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 (isnan(value) || isinf(value)) {
|
||||
return nullptr;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
case _C_FLT:
|
||||
case _C_DBL: {
|
||||
const auto value = [json doubleValue];
|
||||
if (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<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([self convertIdToFollyDynamic: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([self convertIdToFollyDynamic:key],
|
||||
[self convertIdToFollyDynamic:value]);
|
||||
}];
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id)convertFollyDynamicToId:(const folly::dynamic &)dyn {
|
||||
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.
|
||||
@@ -107,22 +27,84 @@ using namespace facebook::sonar;
|
||||
return @(dyn.getDouble());
|
||||
case folly::dynamic::STRING:
|
||||
return [[NSString alloc] initWithBytes:dyn.c_str() length:dyn.size()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
encoding:NSUTF8StringEncoding];
|
||||
case folly::dynamic::ARRAY: {
|
||||
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dyn.size()];
|
||||
for (auto &elem : dyn) {
|
||||
[array addObject:[self convertFollyDynamicToId: elem]];
|
||||
[array addObject:convertFollyDynamicToId(elem)];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
case folly::dynamic::OBJECT: {
|
||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:dyn.size()];
|
||||
for (auto &elem : dyn.items()) {
|
||||
dict[[self convertFollyDynamicToId:elem.first]] = [self convertFollyDynamicToId:elem.second];
|
||||
dict[convertFollyDynamicToId(elem.first)] = convertFollyDynamicToId(elem.second);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
folly::dynamic convertIdToFollyDynamic(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(convertIdToFollyDynamic(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(convertIdToFollyDynamic(key),
|
||||
convertIdToFollyDynamic(value));
|
||||
}];
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
} }
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the LICENSE
|
||||
* file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <folly/dynamic.h>
|
||||
|
||||
namespace facebook { namespace sonar {
|
||||
#define _C_ID '@'
|
||||
#define _C_CLASS '#'
|
||||
#define _C_SEL ':'
|
||||
#define _C_CHR 'c'
|
||||
#define _C_UCHR 'C'
|
||||
#define _C_SHT 's'
|
||||
#define _C_USHT 'S'
|
||||
#define _C_INT 'i'
|
||||
#define _C_UINT 'I'
|
||||
#define _C_LNG 'l'
|
||||
#define _C_ULNG 'L'
|
||||
#define _C_LNG_LNG 'q'
|
||||
#define _C_ULNG_LNG 'Q'
|
||||
#define _C_FLT 'f'
|
||||
#define _C_DBL 'd'
|
||||
#define _C_BFLD 'b'
|
||||
#define _C_BOOL 'B'
|
||||
#define _C_VOID 'v'
|
||||
#define _C_UNDEF '?'
|
||||
#define _C_PTR '^'
|
||||
#define _C_CHARPTR '*'
|
||||
#define _C_ATOM '%'
|
||||
#define _C_ARY_B '['
|
||||
#define _C_ARY_E ']'
|
||||
#define _C_UNION_B '('
|
||||
#define _C_UNION_E ')'
|
||||
#define _C_STRUCT_B '{'
|
||||
#define _C_STRUCT_E '}'
|
||||
#define _C_VECTOR '!'
|
||||
#define _C_CONST 'r'
|
||||
}
|
||||
}
|
||||
|
||||
@interface SKUtils: NSObject
|
||||
+ (folly::dynamic)convertIdToFollyDynamic:(id)json;
|
||||
+ (id)convertFollyDynamicToId:(const folly::dynamic &)dyn;
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user