mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-30 12:43:41 +01:00
338 lines
9.0 KiB
C
338 lines
9.0 KiB
C
|
/** @file
|
||
|
|
||
|
OcSerializeLib
|
||
|
|
||
|
Copyright (c) 2018, vit9696
|
||
|
|
||
|
All rights reserved.
|
||
|
|
||
|
This program and the accompanying materials
|
||
|
are licensed and made available under the terms and conditions of the BSD License
|
||
|
which accompanies this distribution. The full text of the license may be found at
|
||
|
http://opensource.org/licenses/bsd-license.php
|
||
|
|
||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||
|
|
||
|
**/
|
||
|
|
||
|
#ifndef OC_SERIALIZE_LIB_H
|
||
|
#define OC_SERIALIZE_LIB_H
|
||
|
|
||
|
#include <Library/OcXmlLib.h>
|
||
|
#include <Library/OcTemplateLib.h>
|
||
|
|
||
|
typedef struct OC_SCHEMA_ OC_SCHEMA;
|
||
|
typedef union OC_SCHEMA_INFO_ OC_SCHEMA_INFO;
|
||
|
|
||
|
//
|
||
|
// Generic applier interface that knows how to provide Info with data from Node.
|
||
|
//
|
||
|
typedef
|
||
|
VOID
|
||
|
(*OC_APPLY) (
|
||
|
OUT VOID *Serialized,
|
||
|
IN XML_NODE *Node,
|
||
|
IN OC_SCHEMA_INFO *Info,
|
||
|
IN CONST CHAR8 *Context OPTIONAL
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// OC_SCHEMA_INFO for nested dictionaries
|
||
|
//
|
||
|
typedef struct {
|
||
|
//
|
||
|
// Nested schema list.
|
||
|
//
|
||
|
OC_SCHEMA *Schema;
|
||
|
//
|
||
|
// Nested schema list size.
|
||
|
//
|
||
|
UINT32 SchemaSize;
|
||
|
} OC_SCHEMA_DICT;
|
||
|
|
||
|
//
|
||
|
// OC_SCHEMA_INFO for static values
|
||
|
//
|
||
|
|
||
|
typedef enum OC_SCHEMA_VALUE_TYPE_ {
|
||
|
OC_SCHEMA_VALUE_BOOLEAN,
|
||
|
OC_SCHEMA_VALUE_INTEGER,
|
||
|
OC_SCHEMA_VALUE_DATA,
|
||
|
OC_SCHEMA_VALUE_STRING,
|
||
|
OC_SCHEMA_VALUE_MDATA
|
||
|
} OC_SCHEMA_VALUE_TYPE;
|
||
|
|
||
|
typedef struct {
|
||
|
//
|
||
|
// Value pointer.
|
||
|
//
|
||
|
UINTN Field;
|
||
|
//
|
||
|
// Value size.
|
||
|
//
|
||
|
UINT32 FieldSize;
|
||
|
//
|
||
|
// Source type.
|
||
|
//
|
||
|
OC_SCHEMA_VALUE_TYPE Type;
|
||
|
} OC_SCHEMA_VALUE;
|
||
|
|
||
|
//
|
||
|
// OC_SCHEMA_INFO for blob values
|
||
|
//
|
||
|
|
||
|
typedef enum OC_SCHEMA_BLOB_TYPE_ {
|
||
|
OC_SCHEMA_BLOB_DATA,
|
||
|
OC_SCHEMA_BLOB_STRING,
|
||
|
OC_SCHEMA_BLOB_MDATA
|
||
|
} OC_SCHEMA_BLOB_TYPE;
|
||
|
|
||
|
typedef struct {
|
||
|
//
|
||
|
// Blob pointer.
|
||
|
//
|
||
|
UINTN Field;
|
||
|
//
|
||
|
// Source type.
|
||
|
//
|
||
|
OC_SCHEMA_BLOB_TYPE Type;
|
||
|
} OC_SCHEMA_BLOB;
|
||
|
|
||
|
//
|
||
|
// OC_SCHEMA_INFO for array/map lists
|
||
|
//
|
||
|
typedef struct {
|
||
|
//
|
||
|
// List pointer.
|
||
|
//
|
||
|
UINTN Field;
|
||
|
//
|
||
|
// List entry schema.
|
||
|
//
|
||
|
OC_SCHEMA *Schema;
|
||
|
} OC_SCHEMA_LIST;
|
||
|
|
||
|
//
|
||
|
// All standard variants of schema info
|
||
|
//
|
||
|
union OC_SCHEMA_INFO_ {
|
||
|
OC_SCHEMA_DICT Dict;
|
||
|
OC_SCHEMA_VALUE Value;
|
||
|
OC_SCHEMA_BLOB Blob;
|
||
|
OC_SCHEMA_LIST List;
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// Schema context, allowing node recursion.
|
||
|
//
|
||
|
struct OC_SCHEMA_ {
|
||
|
//
|
||
|
// Key name to match against in the dictionary.
|
||
|
//
|
||
|
CONST CHAR8 *Name;
|
||
|
//
|
||
|
// Node type required to match to be able to call Apply.
|
||
|
// PLIST_NODE_TYPE_ANY could be specified if Apply does the validation.
|
||
|
//
|
||
|
PLIST_NODE_TYPE Type;
|
||
|
//
|
||
|
// Apply handler that will merge Node data into object.
|
||
|
//
|
||
|
OC_APPLY Apply;
|
||
|
//
|
||
|
// Information about Node to object bridge.
|
||
|
//
|
||
|
OC_SCHEMA_INFO Info;
|
||
|
};
|
||
|
|
||
|
//
|
||
|
// Find schema in a sorted list
|
||
|
//
|
||
|
OC_SCHEMA *
|
||
|
LookupConfigSchema (
|
||
|
IN OC_SCHEMA *SortedList,
|
||
|
IN UINT32 Size,
|
||
|
IN CONST CHAR8 *Name
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Apply interface to parse serialized dictionaries
|
||
|
//
|
||
|
VOID
|
||
|
ParseSerializedDict (
|
||
|
OUT VOID *Serialized,
|
||
|
IN XML_NODE *Node,
|
||
|
IN OC_SCHEMA_INFO *Info,
|
||
|
IN CONST CHAR8 *Context OPTIONAL
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Apply interface to parse serialized OC_SCHEMA_VALUE_TYPE.
|
||
|
//
|
||
|
VOID
|
||
|
ParseSerializedValue (
|
||
|
OUT VOID *Serialized,
|
||
|
IN XML_NODE *Node,
|
||
|
IN OC_SCHEMA_INFO *Info,
|
||
|
IN CONST CHAR8 *Context OPTIONAL
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Apply interface to parse serialized OC_SCHEMA_BLOB_TYPE.
|
||
|
//
|
||
|
VOID
|
||
|
ParseSerializedBlob (
|
||
|
OUT VOID *Serialized,
|
||
|
IN XML_NODE *Node,
|
||
|
IN OC_SCHEMA_INFO *Info,
|
||
|
IN CONST CHAR8 *Context OPTIONAL
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Apply interface to parse serialized array
|
||
|
//
|
||
|
VOID
|
||
|
ParseSerializedArray (
|
||
|
OUT VOID *Serialized,
|
||
|
IN XML_NODE *Node,
|
||
|
IN OC_SCHEMA_INFO *Info,
|
||
|
IN CONST CHAR8 *Context OPTIONAL
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Apply interface to parse serialized map with arbitrary values,
|
||
|
// and OC_STRING strings.
|
||
|
//
|
||
|
VOID
|
||
|
ParseSerializedMap (
|
||
|
OUT VOID *Serialized,
|
||
|
IN XML_NODE *Node,
|
||
|
IN OC_SCHEMA_INFO *Info,
|
||
|
IN CONST CHAR8 *Context OPTIONAL
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Main interface for parsing serialized data.
|
||
|
// PlistBuffer will be modified during the execution.
|
||
|
//
|
||
|
BOOLEAN
|
||
|
ParseSerialized (
|
||
|
OUT VOID *Serialized,
|
||
|
IN OC_SCHEMA_INFO *RootSchema,
|
||
|
IN VOID *PlistBuffer,
|
||
|
IN UINT32 PlistSize
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Retrieve typed field pointer from offset
|
||
|
//
|
||
|
#define OC_SCHEMA_FIELD(Base, Type, Offset) \
|
||
|
((Type *)(((UINT8 *) (Base)) + (Offset)))
|
||
|
|
||
|
//
|
||
|
// Smart declaration base macros, see usage below.
|
||
|
//
|
||
|
#define OC_SCHEMA_VALUE(Name, Offset, Type, SourceType) \
|
||
|
{(Name), PLIST_NODE_TYPE_ANY, ParseSerializedValue, \
|
||
|
{.Value = {Offset, sizeof (Type), SourceType}}}
|
||
|
|
||
|
#define OC_SCHEMA_BLOB(Name, Offset, SourceType) \
|
||
|
{(Name), PLIST_NODE_TYPE_ANY, ParseSerializedBlob, \
|
||
|
{.Blob = {Offset, SourceType}}}
|
||
|
|
||
|
//
|
||
|
// Smart declaration macros for builtin appliers,
|
||
|
// which point straight to types.
|
||
|
//
|
||
|
// Name represents dictionary name if any (otherwise NULL).
|
||
|
// Type represents value or value type for size calculation.
|
||
|
// Schema represents element schema.
|
||
|
//
|
||
|
// M prefix stands for Meta, which means meta data type casting is used.
|
||
|
// F suffix stands for Fixed, which means fixed file size is assumed.
|
||
|
//
|
||
|
#define OC_SCHEMA_DICT(Name, Schema) \
|
||
|
{(Name), PLIST_NODE_TYPE_DICT, ParseSerializedDict, \
|
||
|
{.Dict = {(Schema), ARRAY_SIZE (Schema)}}}
|
||
|
|
||
|
#define OC_SCHEMA_BOOLEAN(Name) \
|
||
|
OC_SCHEMA_VALUE (Name, 0, BOOLEAN, OC_SCHEMA_VALUE_BOOLEAN)
|
||
|
|
||
|
#define OC_SCHEMA_INTEGER(Name, Type) \
|
||
|
OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_INTEGER)
|
||
|
|
||
|
#define OC_SCHEMA_STRING(Name) \
|
||
|
OC_SCHEMA_BLOB (Name, 0, OC_SCHEMA_BLOB_STRING)
|
||
|
|
||
|
#define OC_SCHEMA_STRINGF(Name, Type) \
|
||
|
OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_STRING)
|
||
|
|
||
|
#define OC_SCHEMA_DATA(Name) \
|
||
|
OC_SCHEMA_BLOB (Name, 0, OC_SCHEMA_BLOB_DATA)
|
||
|
|
||
|
#define OC_SCHEMA_DATAF(Name, Type) \
|
||
|
OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_DATA)
|
||
|
|
||
|
#define OC_SCHEMA_MDATA(Name) \
|
||
|
OC_SCHEMA_BLOB (Name, 0, OC_SCHEMA_BLOB_MDATA)
|
||
|
|
||
|
#define OC_SCHEMA_MDATAF(Name, Type) \
|
||
|
OC_SCHEMA_VALUE (Name, 0, Type, OC_SCHEMA_VALUE_MDATA)
|
||
|
|
||
|
#define OC_SCHEMA_ARRAY(Name, ChildSchema) \
|
||
|
{(Name), PLIST_NODE_TYPE_ARRAY, ParseSerializedArray, \
|
||
|
{.List = {0, ChildSchema}}}
|
||
|
|
||
|
#define OC_SCHEMA_MAP(Name, ChildSchema) \
|
||
|
{(Name), PLIST_NODE_TYPE_DICT, ParseSerializedMap, \
|
||
|
{.List = {0, ChildSchema}}}
|
||
|
|
||
|
//
|
||
|
// Smart declaration macros for builtin appliers,
|
||
|
// which point to structures, containing these types.
|
||
|
//
|
||
|
// Name represents dictionary name if any (otherwise NULL).
|
||
|
// Type represents container structure type for this value.
|
||
|
// Field represents item in the container type.
|
||
|
// Schema represents element schema.
|
||
|
//
|
||
|
#define OC_SCHEMA_BOOLEAN_IN(Name, Type, Field) \
|
||
|
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
|
||
|
OC_SCHEMA_VALUE_BOOLEAN)
|
||
|
|
||
|
#define OC_SCHEMA_INTEGER_IN(Name, Type, Field) \
|
||
|
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
|
||
|
OC_SCHEMA_VALUE_INTEGER)
|
||
|
|
||
|
#define OC_SCHEMA_STRING_IN(Name, Type, Field) \
|
||
|
OC_SCHEMA_BLOB (Name, OFFSET_OF (Type, Field), OC_SCHEMA_BLOB_STRING)
|
||
|
|
||
|
#define OC_SCHEMA_STRINGF_IN(Name, Type, Field) \
|
||
|
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
|
||
|
OC_SCHEMA_VALUE_STRING)
|
||
|
|
||
|
#define OC_SCHEMA_DATA_IN(Name, Type, Field) \
|
||
|
OC_SCHEMA_BLOB (Name, OFFSET_OF (Type, Field), OC_SCHEMA_BLOB_DATA)
|
||
|
|
||
|
#define OC_SCHEMA_DATAF_IN(Name, Type, Field) \
|
||
|
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
|
||
|
OC_SCHEMA_VALUE_DATA)
|
||
|
|
||
|
#define OC_SCHEMA_MDATA_IN(Name, Type, Field) \
|
||
|
OC_SCHEMA_BLOB (Name, OFFSET_OF (Type, Field), OC_SCHEMA_BLOB_MDATA)
|
||
|
|
||
|
#define OC_SCHEMA_MDATAF_IN(Name, Type, Field) \
|
||
|
OC_SCHEMA_VALUE (Name, OFFSET_OF (Type, Field), (((Type *)0)->Field), \
|
||
|
OC_SCHEMA_VALUE_MDATA)
|
||
|
|
||
|
#define OC_SCHEMA_ARRAY_IN(Name, Type, Field, ChildSchema) \
|
||
|
{(Name), PLIST_NODE_TYPE_ARRAY, ParseSerializedArray, \
|
||
|
{.List = {OFFSET_OF (Type, Field), ChildSchema}}}
|
||
|
|
||
|
#define OC_SCHEMA_MAP_IN(Name, Type, Field, ChildSchema) \
|
||
|
{(Name), PLIST_NODE_TYPE_DICT, ParseSerializedMap, \
|
||
|
{.List = {OFFSET_OF (Type, Field), ChildSchema}}}
|
||
|
|
||
|
#endif // OC_SERIALIZE_LIB_H
|