// Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// ignore_for_file: camel_case_types, non_constant_identifier_names

// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

/// Holds bindings to cJSON.
class CJson {
  /// Holds the symbol lookup function.
  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
      _lookup;

  /// The symbols are looked up in [dynamicLibrary].
  CJson(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;

  /// The symbols are looked up with [lookup].
  CJson.fromLookup(
      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
          lookup)
      : _lookup = lookup;

  ffi.Pointer<ffi.Char> cJSON_Version() {
    return _cJSON_Version();
  }

  late final _cJSON_VersionPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
          'cJSON_Version');
  late final _cJSON_Version =
      _cJSON_VersionPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();

  void cJSON_InitHooks(
    ffi.Pointer<cJSON_Hooks> hooks,
  ) {
    return _cJSON_InitHooks(
      hooks,
    );
  }

  late final _cJSON_InitHooksPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<cJSON_Hooks>)>>(
          'cJSON_InitHooks');
  late final _cJSON_InitHooks =
      _cJSON_InitHooksPtr.asFunction<void Function(ffi.Pointer<cJSON_Hooks>)>();

  ffi.Pointer<cJSON> cJSON_Parse(
    ffi.Pointer<ffi.Char> value,
  ) {
    return _cJSON_Parse(
      value,
    );
  }

  late final _cJSON_ParsePtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>>('cJSON_Parse');
  late final _cJSON_Parse = _cJSON_ParsePtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_ParseWithOpts(
    ffi.Pointer<ffi.Char> value,
    ffi.Pointer<ffi.Pointer<ffi.Char>> return_parse_end,
    int require_null_terminated,
  ) {
    return _cJSON_ParseWithOpts(
      value,
      return_parse_end,
      require_null_terminated,
    );
  }

  late final _cJSON_ParseWithOptsPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<ffi.Char>,
              ffi.Pointer<ffi.Pointer<ffi.Char>>,
              cJSON_bool)>>('cJSON_ParseWithOpts');
  late final _cJSON_ParseWithOpts = _cJSON_ParseWithOptsPtr.asFunction<
      ffi.Pointer<cJSON> Function(
          ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Pointer<ffi.Char>>, int)>();

  ffi.Pointer<ffi.Char> cJSON_Print(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_Print(
      item,
    );
  }

  late final _cJSON_PrintPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>>('cJSON_Print');
  late final _cJSON_Print = _cJSON_PrintPtr
      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();

  ffi.Pointer<ffi.Char> cJSON_PrintUnformatted(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_PrintUnformatted(
      item,
    );
  }

  late final _cJSON_PrintUnformattedPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Char> Function(
              ffi.Pointer<cJSON>)>>('cJSON_PrintUnformatted');
  late final _cJSON_PrintUnformatted = _cJSON_PrintUnformattedPtr
      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();

  ffi.Pointer<ffi.Char> cJSON_PrintBuffered(
    ffi.Pointer<cJSON> item,
    int prebuffer,
    int fmt,
  ) {
    return _cJSON_PrintBuffered(
      item,
      prebuffer,
      fmt,
    );
  }

  late final _cJSON_PrintBufferedPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Char> Function(
              ffi.Pointer<cJSON>, ffi.Int, cJSON_bool)>>('cJSON_PrintBuffered');
  late final _cJSON_PrintBuffered = _cJSON_PrintBufferedPtr.asFunction<
      ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>, int, int)>();

  int cJSON_PrintPreallocated(
    ffi.Pointer<cJSON> item,
    ffi.Pointer<ffi.Char> buffer,
    int length,
    int format,
  ) {
    return _cJSON_PrintPreallocated(
      item,
      buffer,
      length,
      format,
    );
  }

  late final _cJSON_PrintPreallocatedPtr = _lookup<
      ffi.NativeFunction<
          cJSON_bool Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              ffi.Int, cJSON_bool)>>('cJSON_PrintPreallocated');
  late final _cJSON_PrintPreallocated = _cJSON_PrintPreallocatedPtr.asFunction<
      int Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, int, int)>();

  void cJSON_Delete(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_Delete(
      item,
    );
  }

  late final _cJSON_DeletePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<cJSON>)>>(
          'cJSON_Delete');
  late final _cJSON_Delete =
      _cJSON_DeletePtr.asFunction<void Function(ffi.Pointer<cJSON>)>();

  int cJSON_GetArraySize(
    ffi.Pointer<cJSON> array,
  ) {
    return _cJSON_GetArraySize(
      array,
    );
  }

  late final _cJSON_GetArraySizePtr =
      _lookup<ffi.NativeFunction<ffi.Int Function(ffi.Pointer<cJSON>)>>(
          'cJSON_GetArraySize');
  late final _cJSON_GetArraySize =
      _cJSON_GetArraySizePtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  ffi.Pointer<cJSON> cJSON_GetArrayItem(
    ffi.Pointer<cJSON> array,
    int index,
  ) {
    return _cJSON_GetArrayItem(
      array,
      index,
    );
  }

  late final _cJSON_GetArrayItemPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<cJSON>, ffi.Int)>>('cJSON_GetArrayItem');
  late final _cJSON_GetArrayItem = _cJSON_GetArrayItemPtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, int)>();

  ffi.Pointer<cJSON> cJSON_GetObjectItem(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_GetObjectItem(
      object,
      string,
    );
  }

  late final _cJSON_GetObjectItemPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_GetObjectItem');
  late final _cJSON_GetObjectItem = _cJSON_GetObjectItemPtr.asFunction<
      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_GetObjectItemCaseSensitive(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_GetObjectItemCaseSensitive(
      object,
      string,
    );
  }

  late final _cJSON_GetObjectItemCaseSensitivePtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_GetObjectItemCaseSensitive');
  late final _cJSON_GetObjectItemCaseSensitive =
      _cJSON_GetObjectItemCaseSensitivePtr.asFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  int cJSON_HasObjectItem(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_HasObjectItem(
      object,
      string,
    );
  }

  late final _cJSON_HasObjectItemPtr = _lookup<
      ffi.NativeFunction<
          cJSON_bool Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_HasObjectItem');
  late final _cJSON_HasObjectItem = _cJSON_HasObjectItemPtr
      .asFunction<int Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<ffi.Char> cJSON_GetErrorPtr() {
    return _cJSON_GetErrorPtr();
  }

  late final _cJSON_GetErrorPtrPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
          'cJSON_GetErrorPtr');
  late final _cJSON_GetErrorPtr =
      _cJSON_GetErrorPtrPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();

  ffi.Pointer<ffi.Char> cJSON_GetStringValue(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_GetStringValue(
      item,
    );
  }

  late final _cJSON_GetStringValuePtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<ffi.Char> Function(
              ffi.Pointer<cJSON>)>>('cJSON_GetStringValue');
  late final _cJSON_GetStringValue = _cJSON_GetStringValuePtr
      .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsInvalid(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsInvalid(
      item,
    );
  }

  late final _cJSON_IsInvalidPtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsInvalid');
  late final _cJSON_IsInvalid =
      _cJSON_IsInvalidPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsFalse(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsFalse(
      item,
    );
  }

  late final _cJSON_IsFalsePtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsFalse');
  late final _cJSON_IsFalse =
      _cJSON_IsFalsePtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsTrue(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsTrue(
      item,
    );
  }

  late final _cJSON_IsTruePtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsTrue');
  late final _cJSON_IsTrue =
      _cJSON_IsTruePtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsBool(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsBool(
      item,
    );
  }

  late final _cJSON_IsBoolPtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsBool');
  late final _cJSON_IsBool =
      _cJSON_IsBoolPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsNull(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsNull(
      item,
    );
  }

  late final _cJSON_IsNullPtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsNull');
  late final _cJSON_IsNull =
      _cJSON_IsNullPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsNumber(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsNumber(
      item,
    );
  }

  late final _cJSON_IsNumberPtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsNumber');
  late final _cJSON_IsNumber =
      _cJSON_IsNumberPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsString(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsString(
      item,
    );
  }

  late final _cJSON_IsStringPtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsString');
  late final _cJSON_IsString =
      _cJSON_IsStringPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsArray(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsArray(
      item,
    );
  }

  late final _cJSON_IsArrayPtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsArray');
  late final _cJSON_IsArray =
      _cJSON_IsArrayPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsObject(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsObject(
      item,
    );
  }

  late final _cJSON_IsObjectPtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsObject');
  late final _cJSON_IsObject =
      _cJSON_IsObjectPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  int cJSON_IsRaw(
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_IsRaw(
      item,
    );
  }

  late final _cJSON_IsRawPtr =
      _lookup<ffi.NativeFunction<cJSON_bool Function(ffi.Pointer<cJSON>)>>(
          'cJSON_IsRaw');
  late final _cJSON_IsRaw =
      _cJSON_IsRawPtr.asFunction<int Function(ffi.Pointer<cJSON>)>();

  ffi.Pointer<cJSON> cJSON_CreateNull() {
    return _cJSON_CreateNull();
  }

  late final _cJSON_CreateNullPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
          'cJSON_CreateNull');
  late final _cJSON_CreateNull =
      _cJSON_CreateNullPtr.asFunction<ffi.Pointer<cJSON> Function()>();

  ffi.Pointer<cJSON> cJSON_CreateTrue() {
    return _cJSON_CreateTrue();
  }

  late final _cJSON_CreateTruePtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
          'cJSON_CreateTrue');
  late final _cJSON_CreateTrue =
      _cJSON_CreateTruePtr.asFunction<ffi.Pointer<cJSON> Function()>();

  ffi.Pointer<cJSON> cJSON_CreateFalse() {
    return _cJSON_CreateFalse();
  }

  late final _cJSON_CreateFalsePtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
          'cJSON_CreateFalse');
  late final _cJSON_CreateFalse =
      _cJSON_CreateFalsePtr.asFunction<ffi.Pointer<cJSON> Function()>();

  ffi.Pointer<cJSON> cJSON_CreateBool(
    int boolean,
  ) {
    return _cJSON_CreateBool(
      boolean,
    );
  }

  late final _cJSON_CreateBoolPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function(cJSON_bool)>>(
          'cJSON_CreateBool');
  late final _cJSON_CreateBool =
      _cJSON_CreateBoolPtr.asFunction<ffi.Pointer<cJSON> Function(int)>();

  ffi.Pointer<cJSON> cJSON_CreateNumber(
    double num,
  ) {
    return _cJSON_CreateNumber(
      num,
    );
  }

  late final _cJSON_CreateNumberPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function(ffi.Double)>>(
          'cJSON_CreateNumber');
  late final _cJSON_CreateNumber =
      _cJSON_CreateNumberPtr.asFunction<ffi.Pointer<cJSON> Function(double)>();

  ffi.Pointer<cJSON> cJSON_CreateString(
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_CreateString(
      string,
    );
  }

  late final _cJSON_CreateStringPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<ffi.Char>)>>('cJSON_CreateString');
  late final _cJSON_CreateString = _cJSON_CreateStringPtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_CreateRaw(
    ffi.Pointer<ffi.Char> raw,
  ) {
    return _cJSON_CreateRaw(
      raw,
    );
  }

  late final _cJSON_CreateRawPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<ffi.Char>)>>('cJSON_CreateRaw');
  late final _cJSON_CreateRaw = _cJSON_CreateRawPtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_CreateArray() {
    return _cJSON_CreateArray();
  }

  late final _cJSON_CreateArrayPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
          'cJSON_CreateArray');
  late final _cJSON_CreateArray =
      _cJSON_CreateArrayPtr.asFunction<ffi.Pointer<cJSON> Function()>();

  ffi.Pointer<cJSON> cJSON_CreateObject() {
    return _cJSON_CreateObject();
  }

  late final _cJSON_CreateObjectPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<cJSON> Function()>>(
          'cJSON_CreateObject');
  late final _cJSON_CreateObject =
      _cJSON_CreateObjectPtr.asFunction<ffi.Pointer<cJSON> Function()>();

  ffi.Pointer<cJSON> cJSON_CreateStringReference(
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_CreateStringReference(
      string,
    );
  }

  late final _cJSON_CreateStringReferencePtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<ffi.Char>)>>('cJSON_CreateStringReference');
  late final _cJSON_CreateStringReference = _cJSON_CreateStringReferencePtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_CreateObjectReference(
    ffi.Pointer<cJSON> child,
  ) {
    return _cJSON_CreateObjectReference(
      child,
    );
  }

  late final _cJSON_CreateObjectReferencePtr = _lookup<
          ffi.NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>>(
      'cJSON_CreateObjectReference');
  late final _cJSON_CreateObjectReference = _cJSON_CreateObjectReferencePtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>();

  ffi.Pointer<cJSON> cJSON_CreateArrayReference(
    ffi.Pointer<cJSON> child,
  ) {
    return _cJSON_CreateArrayReference(
      child,
    );
  }

  late final _cJSON_CreateArrayReferencePtr = _lookup<
          ffi.NativeFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>>(
      'cJSON_CreateArrayReference');
  late final _cJSON_CreateArrayReference = _cJSON_CreateArrayReferencePtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>)>();

  ffi.Pointer<cJSON> cJSON_CreateIntArray(
    ffi.Pointer<ffi.Int> numbers,
    int count,
  ) {
    return _cJSON_CreateIntArray(
      numbers,
      count,
    );
  }

  late final _cJSON_CreateIntArrayPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<ffi.Int>, ffi.Int)>>('cJSON_CreateIntArray');
  late final _cJSON_CreateIntArray = _cJSON_CreateIntArrayPtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Int>, int)>();

  ffi.Pointer<cJSON> cJSON_CreateFloatArray(
    ffi.Pointer<ffi.Float> numbers,
    int count,
  ) {
    return _cJSON_CreateFloatArray(
      numbers,
      count,
    );
  }

  late final _cJSON_CreateFloatArrayPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<ffi.Float>, ffi.Int)>>('cJSON_CreateFloatArray');
  late final _cJSON_CreateFloatArray = _cJSON_CreateFloatArrayPtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Float>, int)>();

  ffi.Pointer<cJSON> cJSON_CreateDoubleArray(
    ffi.Pointer<ffi.Double> numbers,
    int count,
  ) {
    return _cJSON_CreateDoubleArray(
      numbers,
      count,
    );
  }

  late final _cJSON_CreateDoubleArrayPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<ffi.Double>, ffi.Int)>>('cJSON_CreateDoubleArray');
  late final _cJSON_CreateDoubleArray = _cJSON_CreateDoubleArrayPtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Double>, int)>();

  ffi.Pointer<cJSON> cJSON_CreateStringArray(
    ffi.Pointer<ffi.Pointer<ffi.Char>> strings,
    int count,
  ) {
    return _cJSON_CreateStringArray(
      strings,
      count,
    );
  }

  late final _cJSON_CreateStringArrayPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Pointer<ffi.Char>>,
              ffi.Int)>>('cJSON_CreateStringArray');
  late final _cJSON_CreateStringArray = _cJSON_CreateStringArrayPtr.asFunction<
      ffi.Pointer<cJSON> Function(ffi.Pointer<ffi.Pointer<ffi.Char>>, int)>();

  void cJSON_AddItemToArray(
    ffi.Pointer<cJSON> array,
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_AddItemToArray(
      array,
      item,
    );
  }

  late final _cJSON_AddItemToArrayPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(
              ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>>('cJSON_AddItemToArray');
  late final _cJSON_AddItemToArray = _cJSON_AddItemToArrayPtr
      .asFunction<void Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();

  void cJSON_AddItemToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_AddItemToObject(
      object,
      string,
      item,
    );
  }

  late final _cJSON_AddItemToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              ffi.Pointer<cJSON>)>>('cJSON_AddItemToObject');
  late final _cJSON_AddItemToObject = _cJSON_AddItemToObjectPtr.asFunction<
      void Function(
          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();

  void cJSON_AddItemToObjectCS(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_AddItemToObjectCS(
      object,
      string,
      item,
    );
  }

  late final _cJSON_AddItemToObjectCSPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              ffi.Pointer<cJSON>)>>('cJSON_AddItemToObjectCS');
  late final _cJSON_AddItemToObjectCS = _cJSON_AddItemToObjectCSPtr.asFunction<
      void Function(
          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();

  void cJSON_AddItemReferenceToArray(
    ffi.Pointer<cJSON> array,
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_AddItemReferenceToArray(
      array,
      item,
    );
  }

  late final _cJSON_AddItemReferenceToArrayPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<cJSON>,
              ffi.Pointer<cJSON>)>>('cJSON_AddItemReferenceToArray');
  late final _cJSON_AddItemReferenceToArray = _cJSON_AddItemReferenceToArrayPtr
      .asFunction<void Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();

  void cJSON_AddItemReferenceToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_AddItemReferenceToObject(
      object,
      string,
      item,
    );
  }

  late final _cJSON_AddItemReferenceToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              ffi.Pointer<cJSON>)>>('cJSON_AddItemReferenceToObject');
  late final _cJSON_AddItemReferenceToObject =
      _cJSON_AddItemReferenceToObjectPtr.asFunction<
          void Function(
              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();

  ffi.Pointer<cJSON> cJSON_DetachItemViaPointer(
    ffi.Pointer<cJSON> parent,
    ffi.Pointer<cJSON> item,
  ) {
    return _cJSON_DetachItemViaPointer(
      parent,
      item,
    );
  }

  late final _cJSON_DetachItemViaPointerPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
              ffi.Pointer<cJSON>)>>('cJSON_DetachItemViaPointer');
  late final _cJSON_DetachItemViaPointer =
      _cJSON_DetachItemViaPointerPtr.asFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();

  ffi.Pointer<cJSON> cJSON_DetachItemFromArray(
    ffi.Pointer<cJSON> array,
    int which,
  ) {
    return _cJSON_DetachItemFromArray(
      array,
      which,
    );
  }

  late final _cJSON_DetachItemFromArrayPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<cJSON>, ffi.Int)>>('cJSON_DetachItemFromArray');
  late final _cJSON_DetachItemFromArray = _cJSON_DetachItemFromArrayPtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, int)>();

  void cJSON_DeleteItemFromArray(
    ffi.Pointer<cJSON> array,
    int which,
  ) {
    return _cJSON_DeleteItemFromArray(
      array,
      which,
    );
  }

  late final _cJSON_DeleteItemFromArrayPtr = _lookup<
          ffi.NativeFunction<ffi.Void Function(ffi.Pointer<cJSON>, ffi.Int)>>(
      'cJSON_DeleteItemFromArray');
  late final _cJSON_DeleteItemFromArray = _cJSON_DeleteItemFromArrayPtr
      .asFunction<void Function(ffi.Pointer<cJSON>, int)>();

  ffi.Pointer<cJSON> cJSON_DetachItemFromObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_DetachItemFromObject(
      object,
      string,
    );
  }

  late final _cJSON_DetachItemFromObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_DetachItemFromObject');
  late final _cJSON_DetachItemFromObject =
      _cJSON_DetachItemFromObjectPtr.asFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_DetachItemFromObjectCaseSensitive(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_DetachItemFromObjectCaseSensitive(
      object,
      string,
    );
  }

  late final _cJSON_DetachItemFromObjectCaseSensitivePtr = _lookup<
          ffi.NativeFunction<
              ffi.Pointer<cJSON> Function(
                  ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>>(
      'cJSON_DetachItemFromObjectCaseSensitive');
  late final _cJSON_DetachItemFromObjectCaseSensitive =
      _cJSON_DetachItemFromObjectCaseSensitivePtr.asFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  void cJSON_DeleteItemFromObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_DeleteItemFromObject(
      object,
      string,
    );
  }

  late final _cJSON_DeleteItemFromObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_DeleteItemFromObject');
  late final _cJSON_DeleteItemFromObject = _cJSON_DeleteItemFromObjectPtr
      .asFunction<void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  void cJSON_DeleteItemFromObjectCaseSensitive(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_DeleteItemFromObjectCaseSensitive(
      object,
      string,
    );
  }

  late final _cJSON_DeleteItemFromObjectCaseSensitivePtr = _lookup<
          ffi.NativeFunction<
              ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>>(
      'cJSON_DeleteItemFromObjectCaseSensitive');
  late final _cJSON_DeleteItemFromObjectCaseSensitive =
      _cJSON_DeleteItemFromObjectCaseSensitivePtr.asFunction<
          void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  void cJSON_InsertItemInArray(
    ffi.Pointer<cJSON> array,
    int which,
    ffi.Pointer<cJSON> newitem,
  ) {
    return _cJSON_InsertItemInArray(
      array,
      which,
      newitem,
    );
  }

  late final _cJSON_InsertItemInArrayPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Int,
              ffi.Pointer<cJSON>)>>('cJSON_InsertItemInArray');
  late final _cJSON_InsertItemInArray = _cJSON_InsertItemInArrayPtr
      .asFunction<void Function(ffi.Pointer<cJSON>, int, ffi.Pointer<cJSON>)>();

  int cJSON_ReplaceItemViaPointer(
    ffi.Pointer<cJSON> parent,
    ffi.Pointer<cJSON> item,
    ffi.Pointer<cJSON> replacement,
  ) {
    return _cJSON_ReplaceItemViaPointer(
      parent,
      item,
      replacement,
    );
  }

  late final _cJSON_ReplaceItemViaPointerPtr = _lookup<
      ffi.NativeFunction<
          cJSON_bool Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>,
              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemViaPointer');
  late final _cJSON_ReplaceItemViaPointer =
      _cJSON_ReplaceItemViaPointerPtr.asFunction<
          int Function(
              ffi.Pointer<cJSON>, ffi.Pointer<cJSON>, ffi.Pointer<cJSON>)>();

  void cJSON_ReplaceItemInArray(
    ffi.Pointer<cJSON> array,
    int which,
    ffi.Pointer<cJSON> newitem,
  ) {
    return _cJSON_ReplaceItemInArray(
      array,
      which,
      newitem,
    );
  }

  late final _cJSON_ReplaceItemInArrayPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Int,
              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemInArray');
  late final _cJSON_ReplaceItemInArray = _cJSON_ReplaceItemInArrayPtr
      .asFunction<void Function(ffi.Pointer<cJSON>, int, ffi.Pointer<cJSON>)>();

  void cJSON_ReplaceItemInObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
    ffi.Pointer<cJSON> newitem,
  ) {
    return _cJSON_ReplaceItemInObject(
      object,
      string,
      newitem,
    );
  }

  late final _cJSON_ReplaceItemInObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemInObject');
  late final _cJSON_ReplaceItemInObject =
      _cJSON_ReplaceItemInObjectPtr.asFunction<
          void Function(
              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();

  void cJSON_ReplaceItemInObjectCaseSensitive(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> string,
    ffi.Pointer<cJSON> newitem,
  ) {
    return _cJSON_ReplaceItemInObjectCaseSensitive(
      object,
      string,
      newitem,
    );
  }

  late final _cJSON_ReplaceItemInObjectCaseSensitivePtr = _lookup<
      ffi.NativeFunction<
          ffi.Void Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              ffi.Pointer<cJSON>)>>('cJSON_ReplaceItemInObjectCaseSensitive');
  late final _cJSON_ReplaceItemInObjectCaseSensitive =
      _cJSON_ReplaceItemInObjectCaseSensitivePtr.asFunction<
          void Function(
              ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<cJSON>)>();

  ffi.Pointer<cJSON> cJSON_Duplicate(
    ffi.Pointer<cJSON> item,
    int recurse,
  ) {
    return _cJSON_Duplicate(
      item,
      recurse,
    );
  }

  late final _cJSON_DuplicatePtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(
              ffi.Pointer<cJSON>, cJSON_bool)>>('cJSON_Duplicate');
  late final _cJSON_Duplicate = _cJSON_DuplicatePtr
      .asFunction<ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, int)>();

  int cJSON_Compare(
    ffi.Pointer<cJSON> a,
    ffi.Pointer<cJSON> b,
    int case_sensitive,
  ) {
    return _cJSON_Compare(
      a,
      b,
      case_sensitive,
    );
  }

  late final _cJSON_ComparePtr = _lookup<
      ffi.NativeFunction<
          cJSON_bool Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>,
              cJSON_bool)>>('cJSON_Compare');
  late final _cJSON_Compare = _cJSON_ComparePtr
      .asFunction<int Function(ffi.Pointer<cJSON>, ffi.Pointer<cJSON>, int)>();

  void cJSON_Minify(
    ffi.Pointer<ffi.Char> json,
  ) {
    return _cJSON_Minify(
      json,
    );
  }

  late final _cJSON_MinifyPtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Char>)>>(
          'cJSON_Minify');
  late final _cJSON_Minify =
      _cJSON_MinifyPtr.asFunction<void Function(ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_AddNullToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> name,
  ) {
    return _cJSON_AddNullToObject(
      object,
      name,
    );
  }

  late final _cJSON_AddNullToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_AddNullToObject');
  late final _cJSON_AddNullToObject = _cJSON_AddNullToObjectPtr.asFunction<
      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_AddTrueToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> name,
  ) {
    return _cJSON_AddTrueToObject(
      object,
      name,
    );
  }

  late final _cJSON_AddTrueToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_AddTrueToObject');
  late final _cJSON_AddTrueToObject = _cJSON_AddTrueToObjectPtr.asFunction<
      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_AddFalseToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> name,
  ) {
    return _cJSON_AddFalseToObject(
      object,
      name,
    );
  }

  late final _cJSON_AddFalseToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_AddFalseToObject');
  late final _cJSON_AddFalseToObject = _cJSON_AddFalseToObjectPtr.asFunction<
      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_AddBoolToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> name,
    int boolean,
  ) {
    return _cJSON_AddBoolToObject(
      object,
      name,
      boolean,
    );
  }

  late final _cJSON_AddBoolToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              cJSON_bool)>>('cJSON_AddBoolToObject');
  late final _cJSON_AddBoolToObject = _cJSON_AddBoolToObjectPtr.asFunction<
      ffi.Pointer<cJSON> Function(
          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, int)>();

  ffi.Pointer<cJSON> cJSON_AddNumberToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> name,
    double number,
  ) {
    return _cJSON_AddNumberToObject(
      object,
      name,
      number,
    );
  }

  late final _cJSON_AddNumberToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              ffi.Double)>>('cJSON_AddNumberToObject');
  late final _cJSON_AddNumberToObject = _cJSON_AddNumberToObjectPtr.asFunction<
      ffi.Pointer<cJSON> Function(
          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, double)>();

  ffi.Pointer<cJSON> cJSON_AddStringToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> name,
    ffi.Pointer<ffi.Char> string,
  ) {
    return _cJSON_AddStringToObject(
      object,
      name,
      string,
    );
  }

  late final _cJSON_AddStringToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              ffi.Pointer<ffi.Char>)>>('cJSON_AddStringToObject');
  late final _cJSON_AddStringToObject = _cJSON_AddStringToObjectPtr.asFunction<
      ffi.Pointer<cJSON> Function(
          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_AddRawToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> name,
    ffi.Pointer<ffi.Char> raw,
  ) {
    return _cJSON_AddRawToObject(
      object,
      name,
      raw,
    );
  }

  late final _cJSON_AddRawToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>,
              ffi.Pointer<ffi.Char>)>>('cJSON_AddRawToObject');
  late final _cJSON_AddRawToObject = _cJSON_AddRawToObjectPtr.asFunction<
      ffi.Pointer<cJSON> Function(
          ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_AddObjectToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> name,
  ) {
    return _cJSON_AddObjectToObject(
      object,
      name,
    );
  }

  late final _cJSON_AddObjectToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_AddObjectToObject');
  late final _cJSON_AddObjectToObject = _cJSON_AddObjectToObjectPtr.asFunction<
      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  ffi.Pointer<cJSON> cJSON_AddArrayToObject(
    ffi.Pointer<cJSON> object,
    ffi.Pointer<ffi.Char> name,
  ) {
    return _cJSON_AddArrayToObject(
      object,
      name,
    );
  }

  late final _cJSON_AddArrayToObjectPtr = _lookup<
      ffi.NativeFunction<
          ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>,
              ffi.Pointer<ffi.Char>)>>('cJSON_AddArrayToObject');
  late final _cJSON_AddArrayToObject = _cJSON_AddArrayToObjectPtr.asFunction<
      ffi.Pointer<cJSON> Function(ffi.Pointer<cJSON>, ffi.Pointer<ffi.Char>)>();

  double cJSON_SetNumberHelper(
    ffi.Pointer<cJSON> object,
    double number,
  ) {
    return _cJSON_SetNumberHelper(
      object,
      number,
    );
  }

  late final _cJSON_SetNumberHelperPtr = _lookup<
      ffi.NativeFunction<
          ffi.Double Function(
              ffi.Pointer<cJSON>, ffi.Double)>>('cJSON_SetNumberHelper');
  late final _cJSON_SetNumberHelper = _cJSON_SetNumberHelperPtr
      .asFunction<double Function(ffi.Pointer<cJSON>, double)>();

  ffi.Pointer<ffi.Void> cJSON_malloc(
    int size,
  ) {
    return _cJSON_malloc(
      size,
    );
  }

  late final _cJSON_mallocPtr =
      _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size)>>(
          'cJSON_malloc');
  late final _cJSON_malloc =
      _cJSON_mallocPtr.asFunction<ffi.Pointer<ffi.Void> Function(int)>();

  void cJSON_free(
    ffi.Pointer<ffi.Void> object,
  ) {
    return _cJSON_free(
      object,
    );
  }

  late final _cJSON_freePtr =
      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
          'cJSON_free');
  late final _cJSON_free =
      _cJSON_freePtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
}

class cJSON extends ffi.Struct {
  external ffi.Pointer<cJSON> next;

  external ffi.Pointer<cJSON> prev;

  external ffi.Pointer<cJSON> child;

  @ffi.Int()
  external int type;

  external ffi.Pointer<ffi.Char> valuestring;

  @ffi.Int()
  external int valueint;

  @ffi.Double()
  external double valuedouble;

  external ffi.Pointer<ffi.Char> string;
}

class cJSON_Hooks extends ffi.Struct {
  external ffi
          .Pointer<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function(ffi.Size)>>
      malloc_fn;

  external ffi
          .Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>
      free_fn;
}

typedef cJSON_bool = ffi.Int;

const int CJSON_VERSION_MAJOR = 1;

const int CJSON_VERSION_MINOR = 7;

const int CJSON_VERSION_PATCH = 12;

const int cJSON_Invalid = 0;

const int cJSON_False = 1;

const int cJSON_True = 2;

const int cJSON_NULL = 4;

const int cJSON_Number = 8;

const int cJSON_String = 16;

const int cJSON_Array = 32;

const int cJSON_Object = 64;

const int cJSON_Raw = 128;

const int cJSON_IsReference = 256;

const int cJSON_StringIsConst = 512;

const int CJSON_NESTING_LIMIT = 1000;

const double CJSON_DOUBLE_PRECISION = 1e-16;
