| // 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); |
| } |
| } |