// Push the item onto the stack\r
//\r
CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));\r
+ if (Data->Type == EFI_IFR_TYPE_BUFFER) {\r
+ (*StackPtr)->Buffer = AllocateCopyPool(Data->BufferLen, Data->Buffer);\r
+ ASSERT ((*StackPtr)->Buffer != NULL);\r
+ }\r
+ \r
*StackPtr = *StackPtr + 1;\r
\r
return EFI_SUCCESS;\r
CHAR16 *String;\r
CHAR16 *PrintFormat;\r
CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];\r
+ UINT8 *TmpBuf;\r
UINTN BufferSize;\r
\r
Status = PopExpression (&Value);\r
case EFI_IFR_TYPE_BOOLEAN:\r
String = (Value.Value.b) ? L"True" : L"False";\r
break;\r
-\r
+ \r
+ case EFI_IFR_TYPE_BUFFER:\r
+ //\r
+ // + 3 is base on the unicode format, the length may be odd number, \r
+ // so need 1 byte to align, also need 2 bytes for L'\0'.\r
+ //\r
+ TmpBuf = AllocateZeroPool (Value.BufferLen + 3);\r
+ if (Format == EFI_IFR_STRING_ASCII) {\r
+ CopyMem (TmpBuf, Value.Buffer, Value.BufferLen);\r
+ PrintFormat = L"%a"; \r
+ } else {\r
+ // Format == EFI_IFR_STRING_UNICODE\r
+ CopyMem (TmpBuf, Value.Buffer, Value.BufferLen * sizeof (CHAR16));\r
+ PrintFormat = L"%s"; \r
+ }\r
+ UnicodeSPrint (Buffer, MAXIMUM_VALUE_CHARACTERS, PrintFormat, Value.Buffer); \r
+ String = Buffer; \r
+ FreePool (TmpBuf);\r
+ FreePool (Value.Buffer);\r
+ break;\r
+ \r
default:\r
return EFI_UNSUPPORTED;\r
}\r
return Status;\r
}\r
\r
- if (Value.Type >= EFI_IFR_TYPE_OTHER) {\r
+ if (Value.Type >= EFI_IFR_TYPE_OTHER && Value.Type != EFI_IFR_TYPE_BUFFER) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
Result->Value.u64 = StrDecimalToUint64 (String);\r
}\r
FreePool (String);\r
+ } else if (Value.Type == EFI_IFR_TYPE_BUFFER) {\r
+ if (Value.BufferLen > 8) {\r
+ FreePool (Value.Buffer);\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ Result->Value.u64 = *(UINT64*) Value.Buffer;\r
+ FreePool (Value.Buffer);\r
} else {\r
CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
}\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_HII_VALUE Value;\r
+ EFI_HII_VALUE Value[2];\r
CHAR16 *String[2];\r
UINTN Index;\r
CHAR16 *StringPtr;\r
String[1] = NULL;\r
StringPtr = NULL;\r
Status = EFI_SUCCESS;\r
+ ZeroMem (Value, sizeof (Value));\r
\r
for (Index = 0; Index < 2; Index++) {\r
- Status = PopExpression (&Value);\r
+ Status = PopExpression (&Value[Index]);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+ if (Value[Index].Type != EFI_IFR_TYPE_STRING && Value[Index].Type != EFI_IFR_TYPE_BUFFER) {\r
Status = EFI_UNSUPPORTED;\r
goto Done;\r
}\r
\r
- String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String[Index] == NULL) {\r
- Status = EFI_NOT_FOUND;\r
- goto Done;\r
+ if (Value[Index].Type == EFI_IFR_TYPE_STRING) {\r
+ String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);\r
+ if (String[Index] == NULL) {\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
}\r
}\r
\r
- Size = StrSize (String[0]);\r
- StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
- ASSERT (StringPtr != NULL);\r
- StrCpy (StringPtr, String[1]);\r
- StrCat (StringPtr, String[0]);\r
+ if (Value[0].Type == EFI_IFR_TYPE_STRING) {\r
+ Size = StrSize (String[0]);\r
+ StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
+ ASSERT (StringPtr != NULL);\r
+ StrCpy (StringPtr, String[1]);\r
+ StrCat (StringPtr, String[0]);\r
\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
+ Result->Type = EFI_IFR_TYPE_STRING;\r
+ Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
+ } else {\r
+ Result->Type = EFI_IFR_TYPE_BUFFER;\r
+ Result->BufferLen = (UINT16) (Value[0].BufferLen + Value[1].BufferLen);\r
+\r
+ Result->Buffer = AllocateZeroPool (Result->BufferLen);\r
+ ASSERT (Result->Buffer != NULL);\r
\r
+ CopyMem (Result->Buffer, Value[0].Buffer, Value[0].BufferLen);\r
+ CopyMem (&Result->Buffer[Value[0].BufferLen], Value[1].Buffer, Value[1].BufferLen);\r
+ }\r
Done:\r
+ if (Value[0].Buffer != NULL) {\r
+ FreePool (Value[0].Buffer);\r
+ }\r
+ if (Value[1].Buffer != NULL) {\r
+ FreePool (Value[1].Buffer);\r
+ }\r
if (String[0] != NULL) {\r
FreePool (String[0]);\r
}\r
UINTN Base;\r
UINTN Length;\r
CHAR16 *SubString;\r
+ UINT8 *Buffer;\r
+ UINT16 BufferLen;\r
\r
Status = PopExpression (&Value);\r
if (EFI_ERROR (Status)) {\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- if (Value.Type != EFI_IFR_TYPE_STRING) {\r
+ if (Value.Type != EFI_IFR_TYPE_STRING && Value.Type != EFI_IFR_TYPE_BUFFER) {\r
return EFI_UNSUPPORTED;\r
}\r
- String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
- if (String == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
+ if (Value.Type == EFI_IFR_TYPE_STRING) {\r
+ String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
+ if (String == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
- if (Length == 0 || Base >= StrLen (String)) {\r
- SubString = gEmptyString;\r
- } else {\r
- SubString = String + Base;\r
- if ((Base + Length) < StrLen (String)) {\r
- SubString[Length] = L'\0';\r
+ if (Length == 0 || Base >= StrLen (String)) {\r
+ SubString = gEmptyString;\r
+ } else {\r
+ SubString = String + Base;\r
+ if ((Base + Length) < StrLen (String)) {\r
+ SubString[Length] = L'\0';\r
+ }\r
}\r
- }\r
\r
- Result->Type = EFI_IFR_TYPE_STRING;\r
- Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
+ Result->Type = EFI_IFR_TYPE_STRING;\r
+ Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
\r
- FreePool (String);\r
+ FreePool (String);\r
+ } else {\r
+ Buffer = Value.Buffer;\r
+ BufferLen = Value.BufferLen;\r
+ \r
+ Result->Type = EFI_IFR_TYPE_BUFFER;\r
+ if (Length == 0 || Base >= BufferLen) {\r
+ Result->BufferLen = 0;\r
+ Result->Buffer = NULL;\r
+ } else {\r
+ Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length); \r
+ Result->Buffer = AllocateZeroPool (Result->BufferLen);\r
+ ASSERT (Result->Buffer != NULL);\r
+ CopyMem (Result->Buffer, &Value.Buffer[Base], Result->BufferLen);\r
+ }\r
\r
+ FreePool (Value.Buffer);\r
+ }\r
+ \r
return Status;\r
}\r
\r
INT64 Temp64;\r
CHAR16 *Str1;\r
CHAR16 *Str2;\r
+ UINTN Len;\r
\r
if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
- return EFI_INVALID_PARAMETER;\r
+ if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
}\r
\r
if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
return Result;\r
}\r
\r
+ if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) {\r
+ if (Value1->Type != Value2->Type) {\r
+ //\r
+ // Both Operator should be type of Buffer.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen;\r
+ Result = CompareMem (Value1->Buffer, Value2->Buffer, Len);\r
+ if ((Result == 0) && (Value1->BufferLen != Value2->BufferLen))\r
+ {\r
+ //\r
+ // In this case, means base on samll number buffer, the data is same\r
+ // So which value has more data, which value is bigger.\r
+ //\r
+ Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1;\r
+ }\r
+ return Result;\r
+ } \r
+\r
//\r
// Take remain types(integer, boolean, date/time) as integer\r
//\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- if (Value->Type != EFI_IFR_TYPE_STRING) {\r
+ if (Value->Type != EFI_IFR_TYPE_STRING && Value->Type != EFI_IFR_TYPE_BUFFER) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
\r
- StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
- if (StrPtr == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
+ if (Value->Type == EFI_IFR_TYPE_STRING) {\r
+ StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
+ if (StrPtr == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
\r
- Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
- Value->Value.u64 = StrLen (StrPtr);\r
- FreePool (StrPtr);\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ Value->Value.u64 = StrLen (StrPtr);\r
+ FreePool (StrPtr);\r
+ } else {\r
+ Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
+ Value->Value.u64 = Value->BufferLen;\r
+ FreePool (Value->Buffer);\r
+ }\r
break;\r
\r
case EFI_IFR_NOT_OP:\r
}\r
FreePool (StrPtr);\r
Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ } else if (Value->Type == EFI_IFR_TYPE_BUFFER) {\r
+ //\r
+ // When converting from a buffer, if the buffer is all zeroes, \r
+ // then push False. Otherwise push True. \r
+ //\r
+ for (Index =0; Index < Value->BufferLen; Index ++) {\r
+ if (Value->Buffer[Index] != 0) { \r
+ break;\r
+ }\r
+ }\r
+\r
+ if (Index >= Value->BufferLen) {\r
+ Value->Value.b = FALSE;\r
+ } else {\r
+ Value->Value.b = TRUE;\r
+ }\r
+ Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
+ FreePool (Value->Buffer);\r
}\r
break;\r
\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
- if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) {\r
+ if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && \r
+ Data2.Type != EFI_IFR_TYPE_STRING && \r
+ Data2.Type != EFI_IFR_TYPE_BUFFER) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
}\r
}\r
\r
Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle);\r
+ if (Data1.Type == EFI_IFR_TYPE_BUFFER) {\r
+ FreePool (Data1.Buffer);\r
+ FreePool (Data2.Buffer);\r
+ }\r
+ \r
if (Result == EFI_INVALID_PARAMETER) {\r
Status = EFI_INVALID_PARAMETER;\r
goto Done;\r
if (Question->ValueExpression != NULL) {\r
Status = EvaluateExpression (FormSet, Form, Question->ValueExpression);\r
if (!EFI_ERROR (Status)) {\r
- CopyMem (&Question->HiiValue, &Question->ValueExpression->Result, sizeof (EFI_HII_VALUE));\r
+ if (Question->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {\r
+ ASSERT (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER && Question->HiiValue.Buffer != NULL);\r
+ if (Question->StorageWidth > Question->ValueExpression->Result.BufferLen) {\r
+ CopyMem (Question->HiiValue.Buffer, Question->ValueExpression->Result.Buffer, Question->ValueExpression->Result.BufferLen);\r
+ Question->HiiValue.BufferLen = Question->ValueExpression->Result.BufferLen;\r
+ } else {\r
+ CopyMem (Question->HiiValue.Buffer, Question->ValueExpression->Result.Buffer, Question->StorageWidth);\r
+ Question->HiiValue.BufferLen = Question->StorageWidth;\r
+ }\r
+ FreePool (Question->ValueExpression->Result.Buffer);\r
+ }\r
+ Question->HiiValue.Type = Question->ValueExpression->Result.Type;\r
+ CopyMem (&Question->HiiValue.Value, &Question->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE)); \r
}\r
return Status;\r
}\r
//\r
if (Question->ReadExpression != NULL && Form->FormType == STANDARD_MAP_FORM_TYPE) {\r
Status = EvaluateExpression (FormSet, Form, Question->ReadExpression);\r
- if (!EFI_ERROR (Status) && (Question->ReadExpression->Result.Type < EFI_IFR_TYPE_OTHER)) {\r
+ if (!EFI_ERROR (Status) && \r
+ ((Question->ReadExpression->Result.Type < EFI_IFR_TYPE_OTHER) || (Question->ReadExpression->Result.Type == EFI_IFR_TYPE_BUFFER))) {\r
//\r
// Only update question value to the valid result.\r
//\r
- CopyMem (&Question->HiiValue, &Question->ReadExpression->Result, sizeof (EFI_HII_VALUE));\r
+ if (Question->ReadExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {\r
+ ASSERT (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER && Question->HiiValue.Buffer != NULL);\r
+ if (Question->StorageWidth > Question->ReadExpression->Result.BufferLen) {\r
+ CopyMem (Question->HiiValue.Buffer, Question->ReadExpression->Result.Buffer, Question->ReadExpression->Result.BufferLen);\r
+ Question->HiiValue.BufferLen = Question->ReadExpression->Result.BufferLen;\r
+ } else {\r
+ CopyMem (Question->HiiValue.Buffer, Question->ReadExpression->Result.Buffer, Question->StorageWidth);\r
+ Question->HiiValue.BufferLen = Question->StorageWidth;\r
+ }\r
+ FreePool (Question->ReadExpression->Result.Buffer);\r
+ }\r
+ Question->HiiValue.Type = Question->ReadExpression->Result.Type;\r
+ CopyMem (&Question->HiiValue.Value, &Question->ReadExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE)); \r
return EFI_SUCCESS;\r
}\r
}\r
return Status;\r
}\r
\r
- CopyMem (HiiValue, &Default->ValueExpression->Result, sizeof (EFI_HII_VALUE));\r
+ if (Default->ValueExpression->Result.Type == EFI_IFR_TYPE_BUFFER) {\r
+ ASSERT (HiiValue->Type == EFI_IFR_TYPE_BUFFER && Question->BufferValue != NULL);\r
+ if (Question->StorageWidth > Default->ValueExpression->Result.BufferLen) {\r
+ CopyMem (Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Default->ValueExpression->Result.BufferLen);\r
+ Question->HiiValue.BufferLen = Default->ValueExpression->Result.BufferLen;\r
+ } else {\r
+ CopyMem (Question->HiiValue.Buffer, Default->ValueExpression->Result.Buffer, Question->StorageWidth);\r
+ Question->HiiValue.BufferLen = Question->StorageWidth;\r
+ }\r
+ FreePool (Default->ValueExpression->Result.Buffer);\r
+ }\r
+ HiiValue->Type = Default->ValueExpression->Result.Type;\r
+ CopyMem (&HiiValue->Value, &Default->ValueExpression->Result.Value, sizeof (EFI_IFR_TYPE_VALUE)); \r
} else {\r
//\r
// Default value is embedded in EFI_IFR_DEFAULT\r