| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'dart:convert'; | |
| import 'dart:ffi'; | |
| import 'dart:io'; | |
| import 'package:ffi/ffi.dart'; | |
| import 'package:path/path.dart' as p; | |
| import 'cjson_generated_bindings.dart' as cj; | |
| final cjson = cj.CJson(DynamicLibrary.open(_getPath())); | |
| /// Using the generated C_JSON bindings. | |
| void main() { | |
| // Load json from [example.json] file. | |
| final jsonString = File('./example.json').readAsStringSync(); | |
| // Parse this json string using our cJSON library. | |
| final cjsonParsedJson = cjson.cJSON_Parse(jsonString.toNativeUtf8().cast()); | |
| if (cjsonParsedJson == nullptr) { | |
| print('Error parsing cjson.'); | |
| exit(1); | |
| } | |
| // The json is now stored in some C data structure which we need | |
| // to iterate and convert to a dart object (map/list). | |
| // Converting cjson object to a dart object. | |
| final dynamic dartJson = convertCJsonToDartObj(cjsonParsedJson.cast()); | |
| // Delete the cjsonParsedJson object. | |
| cjson.cJSON_Delete(cjsonParsedJson); | |
| // Check if the converted json is correct | |
| // by comparing the result with json converted by `dart:convert`. | |
| if (dartJson.toString() == json.decode(jsonString).toString()) { | |
| print('Parsed Json: $dartJson'); | |
| print('Json converted successfully'); | |
| } else { | |
| print("Converted json doesn't match\n"); | |
| print('Actual:\n$dartJson\n'); | |
| print('Expected:\n${json.decode(jsonString)}'); | |
| } | |
| } | |
| String _getPath() { | |
| final cjsonExamplePath = Directory.current.absolute.path; | |
| var path = p.join(cjsonExamplePath, '../../third_party/cjson_library/'); | |
| if (Platform.isMacOS) { | |
| path = p.join(path, 'libcjson.dylib'); | |
| } else if (Platform.isWindows) { | |
| path = p.join(path, 'Debug', 'cjson.dll'); | |
| } else { | |
| path = p.join(path, 'libcjson.so'); | |
| } | |
| return path; | |
| } | |
| dynamic convertCJsonToDartObj(Pointer<cj.cJSON> parsedcjson) { | |
| dynamic obj; | |
| if (cjson.cJSON_IsObject(parsedcjson.cast()) == 1) { | |
| obj = <String, dynamic>{}; | |
| Pointer<cj.cJSON>? ptr; | |
| ptr = parsedcjson.ref.child; | |
| while (ptr != nullptr) { | |
| final dynamic o = convertCJsonToDartObj(ptr!); | |
| _addToObj(obj, o, ptr.ref.string.cast()); | |
| ptr = ptr.ref.next; | |
| } | |
| } else if (cjson.cJSON_IsArray(parsedcjson.cast()) == 1) { | |
| obj = <dynamic>[]; | |
| Pointer<cj.cJSON>? ptr; | |
| ptr = parsedcjson.ref.child; | |
| while (ptr != nullptr) { | |
| final dynamic o = convertCJsonToDartObj(ptr!); | |
| _addToObj(obj, o); | |
| ptr = ptr.ref.next; | |
| } | |
| } else if (cjson.cJSON_IsString(parsedcjson.cast()) == 1) { | |
| obj = parsedcjson.ref.valuestring.cast<Utf8>().toDartString(); | |
| } else if (cjson.cJSON_IsNumber(parsedcjson.cast()) == 1) { | |
| obj = parsedcjson.ref.valueint == parsedcjson.ref.valuedouble | |
| ? parsedcjson.ref.valueint | |
| : parsedcjson.ref.valuedouble; | |
| } | |
| return obj; | |
| } | |
| void _addToObj(dynamic obj, dynamic o, [Pointer<Utf8>? name]) { | |
| if (obj is Map<String, dynamic>) { | |
| obj[name!.toDartString()] = o; | |
| } else if (obj is List<dynamic>) { | |
| obj.add(o); | |
| } | |
| } |