static size_t read_characteristic_write_request_parameters()

in HAP/HAPIPAccessoryProtocol.c [1058:1467]


static size_t read_characteristic_write_request_parameters(
        struct util_json_reader* r,
        char* buffer,
        size_t length,
        HAPIPWriteRequestParameters* parameters,
        HAPError* err) {
    size_t i, j, k, n;
    int frac;
    uint64_t aid, iid;
    unsigned int ev, remote;
    float fval;
    int64_t llval;
    uint64_t ullval;
    char number[64];
    unsigned int response;

    HAPAssert(r != NULL);
    HAPAssert(buffer != NULL);
    HAPAssert(parameters != NULL);
    HAPAssert(err != NULL);

    *err = kHAPError_None;
    k = util_json_reader_read(r, buffer, length);
    if (r->state != util_JSON_READER_STATE_BEGINNING_STRING) {
        *err = kHAPError_InvalidData;
        goto exit;
    }
    HAPAssert(k <= length);
    i = k;
    k += util_json_reader_read(r, &buffer[k], length - k);
    if (r->state != util_JSON_READER_STATE_COMPLETED_STRING) {
        *err = kHAPError_InvalidData;
        goto exit;
    }
    HAPAssert(k <= length);
    j = k;
    k += util_json_reader_read(r, &buffer[k], length - k);
    if (r->state != util_JSON_READER_STATE_AFTER_NAME_SEPARATOR) {
        *err = kHAPError_InvalidData;
        goto exit;
    }
    HAPAssert(i <= j);
    HAPAssert(j <= k);
    HAPAssert(k <= length);
    if (j - i == 5) {
        if (HAPRawBufferAreEqual(&buffer[i], "\"aid\"", 5)) {
            k += util_json_reader_read(r, &buffer[k], length - k);
            if (r->state != util_JSON_READER_STATE_BEGINNING_NUMBER) {
                *err = kHAPError_InvalidData;
                goto exit;
            }
            HAPAssert(k <= length);
            i = k;
            k += util_json_reader_read(r, &buffer[k], length - k);
            if (r->state != util_JSON_READER_STATE_COMPLETED_NUMBER) {
                *err = kHAPError_InvalidData;
                goto exit;
            }
            HAPAssert(i <= k);
            HAPAssert(k <= length);
            n = try_read_uint64(&buffer[i], k - i, &aid);
            if (n == k - i) {
                parameters->aid.isDefined = true;
                parameters->aid.value = aid;
            } else {
                *err = kHAPError_InvalidData;
                goto exit;
            }
        } else if (HAPRawBufferAreEqual(&buffer[i], "\"iid\"", 5)) {
            k += util_json_reader_read(r, &buffer[k], length - k);
            if (r->state != util_JSON_READER_STATE_BEGINNING_NUMBER) {
                *err = kHAPError_InvalidData;
                goto exit;
            }
            HAPAssert(k <= length);
            i = k;
            k += util_json_reader_read(r, &buffer[k], length - k);
            if (r->state != util_JSON_READER_STATE_COMPLETED_NUMBER) {
                *err = kHAPError_InvalidData;
                goto exit;
            }
            HAPAssert(i <= k);
            HAPAssert(k <= length);
            n = try_read_uint64(&buffer[i], k - i, &iid);
            if (n == k - i) {
                parameters->iid.isDefined = true;
                parameters->iid.value = iid;
            } else {
                *err = kHAPError_InvalidData;
                goto exit;
            }
        } else {
            size_t skippedBytes;
            *err = HAPJSONUtilsSkipValue(r, &buffer[k], length - k, &skippedBytes);
            if (*err) {
                HAPAssert((*err == kHAPError_InvalidData) || (*err == kHAPError_OutOfResources));
                goto exit;
            }
            k += skippedBytes;
        }
    } else if ((j - i == 7) && HAPRawBufferAreEqual(&buffer[i], "\"value\"", 7)) {
        k += util_json_reader_read(r, &buffer[k], length - k);
        switch (r->state) {
            case util_JSON_READER_STATE_BEGINNING_NUMBER: {
                HAPAssert(k <= length);
                i = k;
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_NUMBER) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                HAPAssert(i <= k);
                HAPAssert(k <= length);
                n = 0;
                HAPAssert(n <= sizeof number);
                frac = 0;
                while ((i < k) && (n < sizeof number)) {
                    if (!frac && (buffer[i] == '.')) {
                        frac = 1;
                    }
                    number[n] = buffer[i];
                    n++;
                    i++;
                }
                if (n < sizeof number) {
                    HAPAssert(i == k);
                    number[n] = '\0';
                    if (frac) {
                        *err = HAPFloatFromString(number, &fval);
                        if (*err) {
                            HAPAssert(*err == kHAPError_InvalidData);
                            goto exit;
                        }
                        parameters->value.floatValue = fval;
                        parameters->type = kHAPIPWriteValueType_Float;
                    } else {
                        *err = HAPInt64FromString(number, &llval);
                        if (!*err) {
                            if (llval < 0) {
                                if (llval >= INT32_MIN) {
                                    parameters->value.intValue = (int32_t) llval;
                                    parameters->type = kHAPIPWriteValueType_Int;
                                } else {
                                    *err = kHAPError_InvalidData;
                                    goto exit;
                                }
                            } else {
                                parameters->value.unsignedIntValue = (uint64_t) llval;
                                parameters->type = kHAPIPWriteValueType_UInt;
                            }
                        } else {
                            HAPAssert(*err == kHAPError_InvalidData);
                            *err = HAPUInt64FromString(number, &ullval);
                            if (*err) {
                                HAPAssert(*err == kHAPError_InvalidData);
                                goto exit;
                            }
                            parameters->value.unsignedIntValue = ullval;
                            parameters->type = kHAPIPWriteValueType_UInt;
                        }
                    }
                } else {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
            } break;
            case util_JSON_READER_STATE_BEGINNING_STRING: {
                HAPAssert(k <= length);
                i = k;
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_STRING) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                HAPAssert(i <= k);
                HAPAssert(k <= length);
                HAPAssert(k - i >= 2);
                parameters->value.stringValue.bytes = &buffer[i + 1];
                parameters->value.stringValue.numBytes = k - i - 2;
                if (!HAPUTF8IsValidData(
                            HAPNonnull(parameters->value.stringValue.bytes), parameters->value.stringValue.numBytes)) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                *err = HAPJSONUtilsUnescapeStringData(
                        HAPNonnull(parameters->value.stringValue.bytes), &parameters->value.stringValue.numBytes);
                if (*err) {
                    HAPAssert(*err == kHAPError_InvalidData);
                    goto exit;
                }
                parameters->type = kHAPIPWriteValueType_String;
            } break;
            case util_JSON_READER_STATE_BEGINNING_FALSE: {
                HAPAssert(k <= length);
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_FALSE) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                parameters->value.unsignedIntValue = 0;
                parameters->type = kHAPIPWriteValueType_UInt;
            } break;
            case util_JSON_READER_STATE_BEGINNING_TRUE: {
                HAPAssert(k <= length);
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_TRUE) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                parameters->value.unsignedIntValue = 1;
                parameters->type = kHAPIPWriteValueType_UInt;
            } break;
            default: {
                *err = kHAPError_InvalidData;
            }
                goto exit;
        }
    } else if ((j - i == 4) && HAPRawBufferAreEqual(&buffer[i], "\"ev\"", 4)) {
        k += util_json_reader_read(r, &buffer[k], length - k);
        switch (r->state) {
            case util_JSON_READER_STATE_BEGINNING_NUMBER:
                HAPAssert(k <= length);
                i = k;
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_NUMBER) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                HAPAssert(i <= k);
                HAPAssert(k <= length);
                n = try_read_uint(&buffer[i], k - i, &ev);
                if (n == k - i) {
                    if (ev == 0) {
                        parameters->ev = kHAPIPEventNotificationState_Disabled;
                    } else if (ev == 1) {
                        parameters->ev = kHAPIPEventNotificationState_Enabled;
                    } else {
                        *err = kHAPError_InvalidData;
                        goto exit;
                    }
                } else {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                break;
            case util_JSON_READER_STATE_BEGINNING_FALSE:
                HAPAssert(k <= length);
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_FALSE) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                parameters->ev = kHAPIPEventNotificationState_Disabled;
                break;
            case util_JSON_READER_STATE_BEGINNING_TRUE:
                HAPAssert(k <= length);
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_TRUE) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                parameters->ev = kHAPIPEventNotificationState_Enabled;
                break;
            default:
                *err = kHAPError_InvalidData;
                goto exit;
        }
    } else if ((j - i == 10) && HAPRawBufferAreEqual(&buffer[i], "\"authData\"", 10)) {
        k += util_json_reader_read(r, &buffer[k], length - k);
        if (r->state != util_JSON_READER_STATE_BEGINNING_STRING) {
            *err = kHAPError_InvalidData;
            goto exit;
        }
        HAPAssert(k <= length);
        i = k;
        k += util_json_reader_read(r, &buffer[k], length - k);
        if (r->state != util_JSON_READER_STATE_COMPLETED_STRING) {
            *err = kHAPError_InvalidData;
            goto exit;
        }
        HAPAssert(i <= k);
        HAPAssert(k <= length);
        HAPAssert(k - i >= 2);
        parameters->authorizationData.bytes = &buffer[i + 1];
        parameters->authorizationData.numBytes = k - i - 2;
        if (!HAPUTF8IsValidData(
                    HAPNonnull(parameters->authorizationData.bytes), parameters->authorizationData.numBytes)) {
            *err = kHAPError_InvalidData;
            goto exit;
        }
        *err = HAPJSONUtilsUnescapeStringData(
                HAPNonnull(parameters->authorizationData.bytes), &parameters->authorizationData.numBytes);
        if (*err) {
            HAPAssert(*err == kHAPError_InvalidData);
            goto exit;
        }
    } else if ((j - i == 8) && HAPRawBufferAreEqual(&buffer[i], "\"remote\"", 8)) {
        k += util_json_reader_read(r, &buffer[k], length - k);
        switch (r->state) {
            case util_JSON_READER_STATE_BEGINNING_NUMBER:
                HAPAssert(k <= length);
                i = k;
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_NUMBER) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                HAPAssert(i <= k);
                HAPAssert(k <= length);
                n = try_read_uint(&buffer[i], k - i, &remote);
                if (n == k - i) {
                    if (remote == 0) {
                        parameters->remote = false;
                    } else if (remote == 1) {
                        parameters->remote = true;
                    } else {
                        *err = kHAPError_InvalidData;
                        goto exit;
                    }
                } else {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                break;
            case util_JSON_READER_STATE_BEGINNING_FALSE:
                HAPAssert(k <= length);
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_FALSE) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                parameters->remote = false;
                break;
            case util_JSON_READER_STATE_BEGINNING_TRUE:
                HAPAssert(k <= length);
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_TRUE) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                parameters->remote = true;
                break;
            default:
                *err = kHAPError_InvalidData;
                goto exit;
        }
    } else if ((j - i == 3) && HAPRawBufferAreEqual(&buffer[i], "\"r\"", 3)) {
        k += util_json_reader_read(r, &buffer[k], length - k);
        switch (r->state) {
            case util_JSON_READER_STATE_BEGINNING_NUMBER:
                HAPAssert(k <= length);
                i = k;
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_NUMBER) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                HAPAssert(i <= k);
                HAPAssert(k <= length);
                n = try_read_uint(&buffer[i], k - i, &response);
                if (n == k - i) {
                    if (response == 0) {
                        parameters->response = false;
                    } else if (response == 1) {
                        parameters->response = true;
                    } else {
                        *err = kHAPError_InvalidData;
                        goto exit;
                    }
                } else {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                break;
            case util_JSON_READER_STATE_BEGINNING_FALSE:
                HAPAssert(k <= length);
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_FALSE) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                parameters->response = false;
                break;
            case util_JSON_READER_STATE_BEGINNING_TRUE:
                HAPAssert(k <= length);
                k += util_json_reader_read(r, &buffer[k], length - k);
                if (r->state != util_JSON_READER_STATE_COMPLETED_TRUE) {
                    *err = kHAPError_InvalidData;
                    goto exit;
                }
                parameters->response = true;
                break;
            default:
                *err = kHAPError_InvalidData;
                goto exit;
        }
    } else {
        size_t skippedBytes;
        *err = HAPJSONUtilsSkipValue(r, &buffer[k], length - k, &skippedBytes);
        if (*err) {
            HAPAssert((*err == kHAPError_InvalidData) || (*err == kHAPError_OutOfResources));
            goto exit;
        }
        k += skippedBytes;
    }
exit:
    HAPAssert((r->state != util_JSON_READER_STATE_ERROR) || *err);
    HAPAssert(k <= length);
    return k;
}