// File: Eba-M[P]E3DC-Control/cJSON.c
// Function: cJSON_Compare
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
{
    if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)))
    {
        return false;
    }

    /* check if type is valid */
    switch (a->type & 0xFF)
    {
        case cJSON_False:
        case cJSON_True:
        case cJSON_NULL:
        case cJSON_Number:
        case cJSON_String:
        case cJSON_Raw:
        case cJSON_Array:
        case cJSON_Object:
            break;

        default:
            return false;
    }

    /* identical objects are equal */
    if (a == b)
    {
        return true;
    }

    switch (a->type & 0xFF)
    {
        /* in these cases and equal type is enough */
        case cJSON_False:
        case cJSON_True:
        case cJSON_NULL:
            return true;

        case cJSON_Number:
            if (compare_double(a->valuedouble, b->valuedouble))
            {
                return true;
            }
            return false;

        case cJSON_String:
        case cJSON_Raw:
            if ((a->valuestring == NULL) || (b->valuestring == NULL))
            {
                return false;
            }
            if (strcmp(a->valuestring, b->valuestring) == 0)
            {
                return true;
            }

            return false;

        case cJSON_Array:
        {
            cJSON *a_element = a->child;
            cJSON *b_element = b->child;

            for (; (a_element != NULL) && (b_element != NULL);)
            {
                if (!cJSON_Compare(a_element, b_element, case_sensitive))
                {
                    return false;
                }

                a_element = a_element->next;
                b_element = b_element->next;
            }

            /* one of the arrays is longer than the other */
            if (a_element != b_element) {
                return false;
            }

            return true;
        }

        case cJSON_Object:
        {
            cJSON *a_element = NULL;
            cJSON *b_element = NULL;
            cJSON_ArrayForEach(a_element, a)
            {
                /* TODO This has O(n^2) runtime, which is horrible! */
                b_element = get_object_item(b, a_element->string, case_sensitive);
                if (b_element == NULL)
                {
                    return false;
                }

                if (!cJSON_Compare(a_element, b_element, case_sensitive))
                {
                    return false;
                }
            }

            /* doing this twice, once on a and b to prevent true comparison if a subset of b
             * TODO: Do this the proper way, this is just a fix for now */
            cJSON_ArrayForEach(b_element, b)
            {
                a_element = get_object_item(a, b_element->string, case_sensitive);
                if (a_element == NULL)
                {
                    return false;
                }

                if (!cJSON_Compare(b_element, a_element, case_sensitive))
                {
                    return false;
                }
            }

            return true;
        }

        default:
            return false;
    }
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x58(%rsp)
movq %rsi, 0x50(%rsp)
movl %edx, 0x4c(%rsp)
cmpq $0x0, 0x58(%rsp)
je 0x5c281
cmpq $0x0, 0x50(%rsp)
je 0x5c281
movq 0x58(%rsp), %rax
movl 0x18(%rax), %eax
andl $0xff, %eax
movq 0x50(%rsp), %rcx
movl 0x18(%rcx), %ecx
andl $0xff, %ecx
cmpl %ecx, %eax
je 0x5c28e
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
movq 0x58(%rsp), %rax
movzbl 0x18(%rax), %eax
movl %eax, 0x24(%rsp)
decl %eax
subl $0x2, %eax
jb 0x5c2e8
jmp 0x5c2a4
movl 0x24(%rsp), %eax
subl $0x4, %eax
je 0x5c2e8
jmp 0x5c2af
movl 0x24(%rsp), %eax
subl $0x8, %eax
je 0x5c2e8
jmp 0x5c2ba
movl 0x24(%rsp), %eax
subl $0x10, %eax
je 0x5c2e8
jmp 0x5c2c5
movl 0x24(%rsp), %eax
subl $0x20, %eax
je 0x5c2e8
jmp 0x5c2d0
movl 0x24(%rsp), %eax
subl $0x40, %eax
je 0x5c2e8
jmp 0x5c2db
movl 0x24(%rsp), %eax
subl $0x80, %eax
jne 0x5c2ea
jmp 0x5c2e8
jmp 0x5c2f7
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
movq 0x58(%rsp), %rax
cmpq 0x50(%rsp), %rax
jne 0x5c310
movl $0x1, 0x64(%rsp)
jmp 0x5c60f
movq 0x58(%rsp), %rax
movzbl 0x18(%rax), %eax
movl %eax, 0x20(%rsp)
decl %eax
subl $0x2, %eax
jb 0x5c375
jmp 0x5c326
movl 0x20(%rsp), %eax
subl $0x4, %eax
je 0x5c375
jmp 0x5c331
movl 0x20(%rsp), %eax
subl $0x8, %eax
je 0x5c382
jmp 0x5c33c
movl 0x20(%rsp), %eax
subl $0x10, %eax
je 0x5c3ba
jmp 0x5c347
movl 0x20(%rsp), %eax
subl $0x20, %eax
je 0x5c415
jmp 0x5c356
movl 0x20(%rsp), %eax
subl $0x40, %eax
je 0x5c4bd
jmp 0x5c365
movl 0x20(%rsp), %eax
subl $0x80, %eax
je 0x5c3ba
jmp 0x5c607
movl $0x1, 0x64(%rsp)
jmp 0x5c60f
movq 0x58(%rsp), %rax
movsd 0x30(%rax), %xmm0
movq 0x50(%rsp), %rax
movsd 0x30(%rax), %xmm1
callq 0x5c620
cmpl $0x0, %eax
je 0x5c3ad
movl $0x1, 0x64(%rsp)
jmp 0x5c60f
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
movq 0x58(%rsp), %rax
cmpq $0x0, 0x20(%rax)
je 0x5c3d2
movq 0x50(%rsp), %rax
cmpq $0x0, 0x20(%rax)
jne 0x5c3df
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
movq 0x58(%rsp), %rax
movq 0x20(%rax), %rdi
movq 0x50(%rsp), %rax
movq 0x20(%rax), %rsi
callq 0x23c0
cmpl $0x0, %eax
jne 0x5c408
movl $0x1, 0x64(%rsp)
jmp 0x5c60f
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
movq 0x58(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x50(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x38(%rsp)
xorl %eax, %eax
cmpq $0x0, 0x40(%rsp)
movb %al, 0x1f(%rsp)
je 0x5c44c
cmpq $0x0, 0x38(%rsp)
setne %al
movb %al, 0x1f(%rsp)
movb 0x1f(%rsp), %al
testb $0x1, %al
jne 0x5c456
jmp 0x5c497
movq 0x40(%rsp), %rdi
movq 0x38(%rsp), %rsi
movl 0x4c(%rsp), %edx
callq 0x5c240
cmpl $0x0, %eax
jne 0x5c47b
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
movq 0x40(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x38(%rsp)
jmp 0x5c431
movq 0x40(%rsp), %rax
cmpq 0x38(%rsp), %rax
je 0x5c4b0
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
movl $0x1, 0x64(%rsp)
jmp 0x5c60f
movq $0x0, 0x30(%rsp)
movq $0x0, 0x28(%rsp)
cmpq $0x0, 0x58(%rsp)
je 0x5c4e7
movq 0x58(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
jmp 0x5c4f0
xorl %eax, %eax
movq %rax, 0x10(%rsp)
jmp 0x5c4f0
movq 0x10(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
je 0x5c569
movq 0x50(%rsp), %rdi
movq 0x30(%rsp), %rax
movq 0x38(%rax), %rsi
movl 0x4c(%rsp), %edx
callq 0x5a1c0
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
jne 0x5c533
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
movl 0x4c(%rsp), %edx
callq 0x5c240
cmpl $0x0, %eax
jne 0x5c558
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
jmp 0x5c55a
movq 0x30(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x30(%rsp)
jmp 0x5c4fa
cmpq $0x0, 0x50(%rsp)
je 0x5c581
movq 0x50(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x8(%rsp)
jmp 0x5c58a
xorl %eax, %eax
movq %rax, 0x8(%rsp)
jmp 0x5c58a
movq 0x8(%rsp), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
je 0x5c5fd
movq 0x58(%rsp), %rdi
movq 0x28(%rsp), %rax
movq 0x38(%rax), %rsi
movl 0x4c(%rsp), %edx
callq 0x5a1c0
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
jne 0x5c5ca
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rsi
movl 0x4c(%rsp), %edx
callq 0x5c240
cmpl $0x0, %eax
jne 0x5c5ec
movl $0x0, 0x64(%rsp)
jmp 0x5c60f
jmp 0x5c5ee
movq 0x28(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x28(%rsp)
jmp 0x5c594
movl $0x1, 0x64(%rsp)
jmp 0x5c60f
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
addq $0x68, %rsp
retq
nopl (%rax,%rax)