blob: 2774c314a69876d18e6ef2c40706e9e56040d629 [file] [log] [blame]
// 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 '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.toString() + '\n');
print('Expected:\n' + json.decode(jsonString).toString());
}
}
String _getPath() {
var path = '../../third_party/cjson_library/libcjson.so';
if (Platform.isMacOS) {
path = '../../third_party/cjson_library/libstructs.dylib';
}
if (Platform.isWindows) {
path = r'..\..\third_party\cjson_library\Debug\structs.dll';
}
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);
}
}