size_t HAPIPAccessoryProtocolGetNumCharacteristicReadResponseBytes()

in HAP/HAPIPAccessoryProtocol.c [284:542]


size_t HAPIPAccessoryProtocolGetNumCharacteristicReadResponseBytes(
        HAPAccessoryServerRef* server,
        HAPIPReadContextRef* readContexts,
        size_t numReadContexts,
        HAPIPReadRequestParameters* parameters) {
    HAPPrecondition(server);
    HAPPrecondition(readContexts);
    HAPPrecondition(parameters);

    size_t r, i, n;
    int success;

    r = 22;
    i = 0;
    HAPAssert(i <= numReadContexts);
    while ((i < numReadContexts) && (((HAPIPReadContext*) &readContexts[i])->status == 0)) {
        i++;
    }
    HAPIPReadContext* readContext = (HAPIPReadContext*) &readContexts[i];
    HAPAssert((i == numReadContexts) || ((i < numReadContexts) && (readContext->status != 0)));
    success = i == numReadContexts;
    for (i = 0; i < numReadContexts; i++) {
        readContext = (HAPIPReadContext*) &readContexts[i];

        const HAPBaseCharacteristic* chr_ = GetCharacteristic(server, readContext->aid, readContext->iid);
        HAPAssert(chr_ || (readContext->status != 0));
        r += (i == 0 ? 15 : 16) + HAPUInt64GetNumDescriptionBytes(readContext->aid) +
             HAPUInt64GetNumDescriptionBytes(readContext->iid);
        if (parameters->type && chr_) {
            r += 10 + HAPUUIDGetNumDescriptionBytes(chr_->characteristicType);
        }
        if (parameters->meta && chr_) {
            switch (chr_->format) {
                case kHAPCharacteristicFormat_Bool: {
                    r += 16;
                } break;
                case kHAPCharacteristicFormat_UInt8: {
                    r += 17;
                } break;
                case kHAPCharacteristicFormat_UInt16: {
                    r += 18;
                } break;
                case kHAPCharacteristicFormat_UInt32: {
                    r += 18;
                } break;
                case kHAPCharacteristicFormat_UInt64: {
                    r += 18;
                } break;
                case kHAPCharacteristicFormat_Int: {
                    r += 15;
                } break;
                case kHAPCharacteristicFormat_Float: {
                    r += 17;
                } break;
                case kHAPCharacteristicFormat_String: {
                    r += 18;
                } break;
                case kHAPCharacteristicFormat_TLV8: {
                    r += 16;
                } break;
                case kHAPCharacteristicFormat_Data: {
                    r += 16;
                } break;
            }
        }
        if (readContext->status == 0) {
            HAPAssert(chr_);
            r += success ? 9 : 20;
            if (HAPUUIDAreEqual(chr_->characteristicType, &kHAPCharacteristicType_ProgrammableSwitchEvent)) {
                r += 4;
            } else {
                switch (chr_->format) {
                    case kHAPCharacteristicFormat_Bool: {
                        r += 1;
                    } break;
                    case kHAPCharacteristicFormat_UInt8:
                    case kHAPCharacteristicFormat_UInt16:
                    case kHAPCharacteristicFormat_UInt32:
                    case kHAPCharacteristicFormat_UInt64: {
                        r += HAPUInt64GetNumDescriptionBytes(readContext->value.unsignedIntValue);
                    } break;
                    case kHAPCharacteristicFormat_Int: {
                        r += HAPInt32GetNumDescriptionBytes(readContext->value.intValue);
                    } break;
                    case kHAPCharacteristicFormat_Float: {
                        r += HAPJSONUtilsGetFloatNumDescriptionBytes(readContext->value.floatValue);
                    } break;
                    case kHAPCharacteristicFormat_String:
                    case kHAPCharacteristicFormat_TLV8:
                    case kHAPCharacteristicFormat_Data: {
                        r += 2 + HAPJSONUtilsGetNumEscapedStringDataBytes(
                                         HAPNonnull(readContext->value.stringValue.bytes),
                                         readContext->value.stringValue.numBytes);
                    } break;
                }
            }
        } else {
            r += 10 + HAPInt32GetNumDescriptionBytes(readContext->status);
        }
        if (parameters->perms && chr_) {
            n = HAPCharacteristicGetNumEnabledProperties(chr_);
            r += 11 + (unsigned int) (n == 0 ? 0 : n * 4 + n - 1);
        }
        if (parameters->ev && chr_) {
            r += 6 + (readContext->ev ? 4 : 5);
        }
        if (parameters->meta && chr_) {
            HAPCharacteristicUnits unit = kHAPCharacteristicUnits_None;
            switch (chr_->format) {
                case kHAPCharacteristicFormat_Bool: {
                } break;
                case kHAPCharacteristicFormat_UInt8: {
                    unit = ((const HAPUInt8Characteristic*) chr_)->units;
                } break;
                case kHAPCharacteristicFormat_UInt16: {
                    unit = ((const HAPUInt16Characteristic*) chr_)->units;
                } break;
                case kHAPCharacteristicFormat_UInt32: {
                    unit = ((const HAPUInt32Characteristic*) chr_)->units;
                } break;
                case kHAPCharacteristicFormat_UInt64: {
                    unit = ((const HAPUInt64Characteristic*) chr_)->units;
                } break;
                case kHAPCharacteristicFormat_Int: {
                    unit = ((const HAPIntCharacteristic*) chr_)->units;
                } break;
                case kHAPCharacteristicFormat_Float: {
                    unit = ((const HAPFloatCharacteristic*) chr_)->units;
                } break;
                case kHAPCharacteristicFormat_String:
                case kHAPCharacteristicFormat_TLV8:
                case kHAPCharacteristicFormat_Data: {
                } break;
            }
            switch (unit) {
                case kHAPCharacteristicUnits_None: {
                    r += 0;
                } break;
                case kHAPCharacteristicUnits_Celsius: {
                    r += 17;
                } break;
                case kHAPCharacteristicUnits_ArcDegrees: {
                    r += 20;
                } break;
                case kHAPCharacteristicUnits_Percentage: {
                    r += 20;
                } break;
                case kHAPCharacteristicUnits_Lux: {
                    r += 13;
                } break;
                case kHAPCharacteristicUnits_Seconds: {
                    r += 17;
                } break;
            }
            switch (chr_->format) {
                case kHAPCharacteristicFormat_Bool: {
                } break;
                case kHAPCharacteristicFormat_UInt8: {
                    const HAPUInt8Characteristic* chr = (const HAPUInt8Characteristic*) chr_;
                    uint8_t minimumValue = chr->constraints.minimumValue;
                    uint8_t maximumValue = chr->constraints.maximumValue;
                    uint8_t stepValue = chr->constraints.stepValue;
                    HAPAssert(minimumValue <= maximumValue);

                    if (minimumValue || maximumValue != UINT8_MAX) {
                        r += 35 + HAPUInt64GetNumDescriptionBytes(minimumValue) +
                             HAPUInt64GetNumDescriptionBytes(maximumValue) + HAPUInt64GetNumDescriptionBytes(stepValue);
                    }
                } break;
                case kHAPCharacteristicFormat_UInt16: {
                    const HAPUInt16Characteristic* chr = (const HAPUInt16Characteristic*) chr_;
                    uint16_t minimumValue = chr->constraints.minimumValue;
                    uint16_t maximumValue = chr->constraints.maximumValue;
                    uint16_t stepValue = chr->constraints.stepValue;
                    HAPAssert(minimumValue <= maximumValue);

                    if (minimumValue || maximumValue != UINT16_MAX) {
                        r += 35 + HAPUInt64GetNumDescriptionBytes(minimumValue) +
                             HAPUInt64GetNumDescriptionBytes(maximumValue) + HAPUInt64GetNumDescriptionBytes(stepValue);
                    }
                } break;
                case kHAPCharacteristicFormat_UInt32: {
                    const HAPUInt32Characteristic* chr = (const HAPUInt32Characteristic*) chr_;
                    uint32_t minimumValue = chr->constraints.minimumValue;
                    uint32_t maximumValue = chr->constraints.maximumValue;
                    uint32_t stepValue = chr->constraints.stepValue;
                    HAPAssert(minimumValue <= maximumValue);

                    if (minimumValue || maximumValue != UINT32_MAX) {
                        r += 35 + HAPUInt64GetNumDescriptionBytes(minimumValue) +
                             HAPUInt64GetNumDescriptionBytes(maximumValue) + HAPUInt64GetNumDescriptionBytes(stepValue);
                    }
                } break;
                case kHAPCharacteristicFormat_UInt64: {
                    const HAPUInt64Characteristic* chr = (const HAPUInt64Characteristic*) chr_;
                    uint64_t minimumValue = chr->constraints.minimumValue;
                    uint64_t maximumValue = chr->constraints.maximumValue;
                    uint64_t stepValue = chr->constraints.stepValue;
                    HAPAssert(minimumValue <= maximumValue);

                    if (minimumValue || maximumValue != UINT64_MAX) {
                        r += 35 + HAPUInt64GetNumDescriptionBytes(minimumValue) +
                             HAPUInt64GetNumDescriptionBytes(maximumValue) + HAPUInt64GetNumDescriptionBytes(stepValue);
                    }
                } break;
                case kHAPCharacteristicFormat_Int: {
                    const HAPIntCharacteristic* chr = (const HAPIntCharacteristic*) chr_;
                    int32_t minimumValue = chr->constraints.minimumValue;
                    int32_t maximumValue = chr->constraints.maximumValue;
                    int32_t stepValue = chr->constraints.stepValue;
                    HAPAssert(minimumValue <= maximumValue);
                    HAPAssert(stepValue >= 0);

                    if (minimumValue != INT32_MIN || maximumValue != INT32_MAX) {
                        r += 35 + HAPInt32GetNumDescriptionBytes(minimumValue) +
                             HAPInt32GetNumDescriptionBytes(maximumValue) + HAPInt32GetNumDescriptionBytes(stepValue);
                    }
                } break;
                case kHAPCharacteristicFormat_Float: {
                    const HAPFloatCharacteristic* chr = (const HAPFloatCharacteristic*) chr_;
                    float minimumValue = chr->constraints.minimumValue;
                    float maximumValue = chr->constraints.maximumValue;
                    float stepValue = chr->constraints.stepValue;
                    HAPAssert(HAPFloatIsFinite(minimumValue) || HAPFloatIsInfinite(minimumValue));
                    HAPAssert(HAPFloatIsFinite(maximumValue) || HAPFloatIsInfinite(maximumValue));
                    HAPAssert(minimumValue <= maximumValue);
                    HAPAssert(stepValue >= 0);

                    if (!(HAPFloatIsInfinite(minimumValue) && minimumValue < 0) ||
                        !(HAPFloatIsInfinite(maximumValue) && maximumValue > 0)) {
                        r += 35 + HAPJSONUtilsGetFloatNumDescriptionBytes(minimumValue) +
                             HAPJSONUtilsGetFloatNumDescriptionBytes(maximumValue) +
                             HAPJSONUtilsGetFloatNumDescriptionBytes(stepValue);
                    }
                } break;
                case kHAPCharacteristicFormat_String: {
                    const HAPStringCharacteristic* chr = (const HAPStringCharacteristic*) chr_;
                    uint16_t maxLength = chr->constraints.maxLength;

                    if (maxLength != 64) {
                        r += 10 + HAPUInt64GetNumDescriptionBytes(maxLength);
                    }
                } break;
                case kHAPCharacteristicFormat_TLV8: {
                } break;
                case kHAPCharacteristicFormat_Data: {
                    const HAPDataCharacteristic* chr = (const HAPDataCharacteristic*) chr_;
                    uint32_t maxLength = chr->constraints.maxLength;

                    if (maxLength != 2097152) {
                        r += 14 + HAPUInt64GetNumDescriptionBytes(maxLength);
                    }
                } break;
            }
        }
    }
    HAPAssert(i == numReadContexts);
    return r;
}