mirror of
https://github.com/s00500/ESPUI.git
synced 2025-11-28 04:13:16 +00:00
Reworked control marshaling code to be aware of and enforce size limits by starting to fragment sooner.
This commit is contained in:
@@ -19,7 +19,6 @@ Control::Control(ControlType type, const char* label, std::function<void(Control
|
||||
{
|
||||
id = ++idCounter;
|
||||
ControlChangeID = 1;
|
||||
EstimateMarshaledSize();
|
||||
}
|
||||
|
||||
Control::Control(const Control& Control)
|
||||
@@ -32,8 +31,7 @@ Control::Control(const Control& Control)
|
||||
visible(Control.visible),
|
||||
parentControl(Control.parentControl),
|
||||
next(Control.next),
|
||||
ControlChangeID(Control.ControlChangeID),
|
||||
EstimatedMarshaledSize(Control.EstimatedMarshaledSize)
|
||||
ControlChangeID(Control.ControlChangeID)
|
||||
{ }
|
||||
|
||||
void Control::SendCallback(int type)
|
||||
@@ -50,20 +48,70 @@ void Control::DeleteControl()
|
||||
callback = nullptr;
|
||||
}
|
||||
|
||||
void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t StartingOffset)
|
||||
bool Control::MarshalControl(JsonObject & _item,
|
||||
bool refresh,
|
||||
uint32_t StartingOffset,
|
||||
uint32_t AvailMarshaledLength,
|
||||
uint32_t &EstimatedMarshaledLength)
|
||||
{
|
||||
JsonObject & item = _item;
|
||||
uint32_t length = value.length();
|
||||
uint32_t maxLength = uint32_t(double(ESPUI.jsonInitialDocumentSize) * 0.75);
|
||||
if((length > maxLength) || StartingOffset)
|
||||
{
|
||||
/*
|
||||
Serial.println(String("MarshalControl:Start Fragment Processing"));
|
||||
Serial.println(String("MarshalControl:id: ") + String(id));
|
||||
Serial.println(String("MarshalControl:length: ") + String(length));
|
||||
Serial.println(String("MarshalControl:StartingOffset: ") + String(StartingOffset));
|
||||
Serial.println(String("MarshalControl:maxLength: ") + String(maxLength));
|
||||
// this code assumes MaxMarshaledLength > JsonMarshalingRatio
|
||||
// Serial.println(String("MarshalControl: StartingOffset: ") + String(StartingOffset));
|
||||
// Serial.println(String("MarshalControl: AvailMarshaledLength: ") + String(AvailMarshaledLength));
|
||||
// Serial.println(String("MarshalControl: Control ID: ") + String(id));
|
||||
|
||||
bool ControlIsFragmented = false;
|
||||
// create a new item in the response document
|
||||
JsonObject & item = _item;
|
||||
|
||||
// how much space do we expect to use?
|
||||
uint32_t ValueMarshaledLength = (value.length() - StartingOffset) * JsonMarshalingRatio;
|
||||
uint32_t LabelMarshaledLength = strlen(label) * JsonMarshalingRatio;
|
||||
uint32_t MinimumMarshaledLength = LabelMarshaledLength + JsonMarshaledOverhead;
|
||||
uint32_t MaximumMarshaledLength = ValueMarshaledLength + MinimumMarshaledLength;
|
||||
uint32_t SpaceForMarshaledValue = AvailMarshaledLength - MinimumMarshaledLength;
|
||||
// Serial.println(String("MarshalControl: value.length(): ") + String(value.length()));
|
||||
// Serial.println(String("MarshalControl: ValueMarshaledLength: ") + String(ValueMarshaledLength));
|
||||
// Serial.println(String("MarshalControl: LabelMarshaledLength: ") + String(LabelMarshaledLength));
|
||||
// Serial.println(String("MarshalControl: MaximumMarshaledLength: ") + String(MaximumMarshaledLength));
|
||||
// Serial.println(String("MarshalControl: MinimumMarshaledLength: ") + String(MinimumMarshaledLength));
|
||||
// Serial.println(String("MarshalControl: SpaceForMarshaledValue: ") + String(SpaceForMarshaledValue));
|
||||
|
||||
// will the item fit in the remaining space? Fragment if not
|
||||
if (AvailMarshaledLength < MinimumMarshaledLength)
|
||||
{
|
||||
// Serial.println(String("MarshalControl: Cannot Marshal control. Not enough space for basic headers."));
|
||||
EstimatedMarshaledLength = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t MaxValueLength = (SpaceForMarshaledValue / JsonMarshalingRatio);
|
||||
// Serial.println(String("MarshalControl: MaxValueLength: ") + String(MaxValueLength));
|
||||
|
||||
uint32_t ValueLenToSend = min((value.length() - StartingOffset), MaxValueLength);
|
||||
// Serial.println(String("MarshalControl: ValueLenToSend: ") + String(ValueLenToSend));
|
||||
|
||||
uint32_t AdjustedMarshaledLength = (ValueLenToSend * JsonMarshalingRatio) + MinimumMarshaledLength;
|
||||
// Serial.println(String("MarshalControl: AdjustedMarshaledLength: ") + String(AdjustedMarshaledLength));
|
||||
|
||||
bool NeedToFragment = (ValueLenToSend < value.length());
|
||||
// Serial.println(String("MarshalControl: NeedToFragment: ") + String(NeedToFragment));
|
||||
|
||||
if ((AdjustedMarshaledLength > AvailMarshaledLength) && (0 != ValueLenToSend))
|
||||
{
|
||||
// Serial.println(String("MarshalControl: Cannot Marshal control. Not enough space for marshaled control."));
|
||||
EstimatedMarshaledLength = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
EstimatedMarshaledLength = AdjustedMarshaledLength;
|
||||
|
||||
// are we fragmenting?
|
||||
if(NeedToFragment || StartingOffset)
|
||||
{
|
||||
// Serial.println(String("MarshalControl:Start Fragment Processing"));
|
||||
// Serial.println(String("MarshalControl:id: ") + String(id));
|
||||
// Serial.println(String("MarshalControl:StartingOffset: ") + String(StartingOffset));
|
||||
/*
|
||||
if(0 == StartingOffset)
|
||||
{
|
||||
Serial.println(String("MarshalControl: New control to fragement. ID: ") + String(id));
|
||||
@@ -72,17 +120,18 @@ void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t Starting
|
||||
{
|
||||
Serial.println(String("MarshalControl: Next fragement. ID: ") + String(id));
|
||||
}
|
||||
*/
|
||||
|
||||
*/
|
||||
// indicate that no additional controls should be sent
|
||||
ControlIsFragmented = true;
|
||||
|
||||
// fill in the fragment header
|
||||
_item[F("type")] = uint32_t(ControlType::Fragment);
|
||||
_item[F("id")] = id;
|
||||
|
||||
length = min((length - StartingOffset), maxLength);
|
||||
// Serial.println(String("MarshalControl:Final length: ") + String(length));
|
||||
|
||||
_item[F("offset")] = StartingOffset;
|
||||
_item[F("length")] = length;
|
||||
_item[F("length")] = ValueLenToSend;
|
||||
_item[F("total")] = value.length();
|
||||
item = _item.createNestedObject(F("control"));
|
||||
}
|
||||
@@ -99,7 +148,7 @@ void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t Starting
|
||||
}
|
||||
|
||||
item[F("label")] = label;
|
||||
item[F ("value")] = (ControlType::Password == type) ? F ("--------") : value.substring(StartingOffset, length + StartingOffset);
|
||||
item[F ("value")] = (ControlType::Password == type) ? F ("--------") : value.substring(StartingOffset, StartingOffset + ValueLenToSend);
|
||||
item[F("visible")] = visible;
|
||||
item[F("color")] = (int)color;
|
||||
item[F("enabled")] = enabled;
|
||||
@@ -132,6 +181,9 @@ void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t Starting
|
||||
item[F("selected")] = "";
|
||||
}
|
||||
}
|
||||
|
||||
// Serial.println(String("MarshalControl:Done"));
|
||||
return ControlIsFragmented;
|
||||
}
|
||||
|
||||
void Control::MarshalErrorMessage(JsonObject & item)
|
||||
@@ -282,10 +334,3 @@ void Control::onWsEvent(String & cmd, String& data)
|
||||
}
|
||||
} while (false);
|
||||
}
|
||||
|
||||
void Control::EstimateMarshaledSize()
|
||||
{
|
||||
EstimatedMarshaledSize = MarshalingOverhead + (JsonMarshalingRatio * (strlen(label) + value.length()));
|
||||
|
||||
} // EstimateSerializedSize
|
||||
|
||||
|
||||
Reference in New Issue
Block a user