diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2012-03-15 21:14:40 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-03-21 17:14:17 -0500 |
commit | b519667966e373477febd4b3f1c84ffa1aa5e6a7 (patch) | |
tree | a98a9a31a6ff2ad1bffae3ffad13c683c989994e /src | |
parent | 9302381c9c1ba1660323c703855b35b1afceb114 (diff) | |
download | talos-hostboot-b519667966e373477febd4b3f1c84ffa1aa5e6a7.tar.gz talos-hostboot-b519667966e373477febd4b3f1c84ffa1aa5e6a7.zip |
Support string attributes
- Updated targeting test makefile to enable access to targ trace
- Added testcases to verify string attribute behavior
- Added string attribute types for testing
- Added string attributes to target types for testing
- Updated attribute compiler to output string attribute typedefs + sizes
- Updated attribute compiler to emit more friendly attribute alias
- Updated attribute compiler to process and emit string attributes
Change-Id: I4fe1bbd402319e7f40d90f6448cd342f714c1058
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/767
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/usr/targeting/test/makefile | 3 | ||||
-rw-r--r-- | src/usr/targeting/test/targetingtest.H | 246 | ||||
-rw-r--r-- | src/usr/targeting/xmltohb/attribute_types.xml | 59 | ||||
-rw-r--r-- | src/usr/targeting/xmltohb/target_types.xml | 4 | ||||
-rwxr-xr-x | src/usr/targeting/xmltohb/xmltohb.pl | 137 |
5 files changed, 435 insertions, 14 deletions
diff --git a/src/usr/targeting/test/makefile b/src/usr/targeting/test/makefile index e4398bf7c..4e51e8849 100644 --- a/src/usr/targeting/test/makefile +++ b/src/usr/targeting/test/makefile @@ -27,6 +27,9 @@ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer +# Allow testcase to access component trace macros +EXTRAINCDIR += ../ + MODULE = testtargeting TESTS = *.H diff --git a/src/usr/targeting/test/targetingtest.H b/src/usr/targeting/test/targetingtest.H index e1a535660..bc5e0008c 100644 --- a/src/usr/targeting/test/targetingtest.H +++ b/src/usr/targeting/test/targetingtest.H @@ -58,7 +58,7 @@ #include <targeting/predicates/predicatepostfixexpr.H> #include <targeting/targreasoncodes.H> #include <errl/errludtarget.H> - +#include "trace.H" #include <kernel/console.H> //@fixme /** @@ -1511,6 +1511,250 @@ class TargetingTestSuite: public CxxTest::TestSuite TS_TRACE(EXIT_MRK "testErrlTargetFFDC"); } + + /** + * @test Tests string attributes + */ + void testStringAttributes(void) + { + TS_TRACE(ENTER_MRK "testStringAttributes" ); + + using namespace TARGETING; + + do { + + TargetService& l_targetService = targetService(); + + // Get the top level target for the string attribute tests + Target* l_pTopLevel = NULL; + (void) l_targetService.getTopLevelTarget(l_pTopLevel); + if (l_pTopLevel == NULL) + { + TS_FAIL("ERROR: Can not find top level target; bypassing " + "remaining string attribute tests"); + break; + } + + // TC1: Test NULL string attribute + // TC1.1: String storage size must match the stated size + ATTR_TEST_NULL_STRING_type l_nullStringReference = {0}; + ATTR_TEST_NULL_STRING_type l_nullString = {0}; + if(sizeof(l_nullString) != ATTR_TEST_NULL_STRING_max_chars+1) + { + TS_FAIL("ERROR: l_nullString size (%d) " + "does not match stated size (%d)", + sizeof(l_nullString), + ATTR_TEST_NULL_STRING_max_chars+1); + } + + // TC1.2: String size must be non-zero + if(sizeof(l_nullString) == 0) + { + TS_FAIL("ERROR: l_nullString size is zero"); + } + + // TC1.3: Must be able to read the string + if(!l_pTopLevel->tryGetAttr<ATTR_TEST_NULL_STRING>(l_nullString)) + { + TS_FAIL("ERROR: Can not read l_nullString attribute"); + } + + // TC1.4: All bytes of the string must match the reference version + if(memcmp(l_nullStringReference, + l_nullString, + sizeof(l_nullStringReference))) + { + TS_FAIL("ERROR: l_nullString bytes do not match the reference" + "version"); + TARG_BIN("Expected (l_nullStringReference)", + l_nullStringReference,sizeof(l_nullStringReference)); + TARG_BIN("Actual (l_nullString)", + l_nullString,sizeof(l_nullString)); + } + + // TC1.5: String must equal the empty string by string comparison + if(strcmp(l_nullString,"") != 0) + { + TS_FAIL("ERROR: l_nullString does not strcmp to the empty string"); + TARG_BIN("Actual (l_nullString)", + l_nullString,sizeof(l_nullString)); + } + + // TC2: Test string attribute with only 1 character + // TC2.1: String storage size must match the stated size + ATTR_TEST_MIN_STRING_type l_minStringReference = {0}; + l_minStringReference[0] = 'Z'; + ATTR_TEST_MIN_STRING_type l_minString = {0}; + if(sizeof(l_minString) != ATTR_TEST_MIN_STRING_max_chars+1) + { + TS_FAIL("ERROR: l_minString size (%d) " + "does not match stated size (%d)", + sizeof(l_minString), + ATTR_TEST_MIN_STRING_max_chars+1); + } + + // TC2.2: String size must be non-zero + if(sizeof(l_minString) == 0) + { + TS_FAIL("ERROR: l_minString size is zero"); + } + + // TC2.3: Must be able to read the string + if(!l_pTopLevel->tryGetAttr<ATTR_TEST_MIN_STRING>(l_minString)) + { + TS_FAIL("ERROR: Can not read l_minString attribute"); + } + + // TC2.4: All bytes in string must match the reference string + if(memcmp(l_minStringReference, + l_minString, + sizeof(l_minStringReference))) + { + TS_FAIL("ERROR l_minString bytes do not match the reference " + "version"); + TARG_BIN("Expected (l_minStringReference)", + l_minStringReference,sizeof(l_minStringReference)); + TARG_BIN("Actual (l_minString)", + l_minString,sizeof(l_minString)); + } + + // TC2.5: String must equal "Z" by comparison + if(strcmp(l_minString,l_minStringReference) != 0) + { + TS_FAIL("ERROR l_minString does not strcmp to the reference " + "string"); + TARG_BIN("Actual (l_minString)", + l_minString,sizeof(l_minString)); + } + + // TC3: Test string with maximum number of characters (including NULL) + // TC3.1: String storage size must match the stated size + ATTR_TEST_MAX_STRING_type l_maxStringReference = {0}; + l_maxStringReference[0] = 'a'; + l_maxStringReference[1] = 'b'; + l_maxStringReference[2] = 'c'; + ATTR_TEST_MAX_STRING_type l_maxString = {0}; + if(sizeof(l_maxString) != ATTR_TEST_MAX_STRING_max_chars+1) + { + TS_FAIL("ERROR: l_maxString size (%d) " + "does not match stated size (%d)", + sizeof(l_maxString), + ATTR_TEST_MAX_STRING_max_chars+1); + } + + // TC3.2: String storage size must be non-zero + if(sizeof(l_maxString) == 0) + { + TS_FAIL("ERROR: l_maxString storage size is zero"); + } + + // TC3.3: Must be able to read the string + if(!l_pTopLevel->tryGetAttr<ATTR_TEST_MAX_STRING>(l_maxString)) + { + TS_FAIL("ERROR: Could not read l_maxString"); + } + + // TC3.4: All bytes in string must match the reference + if(memcmp(l_maxStringReference, + l_maxString, + sizeof(l_maxStringReference))) + { + TS_FAIL("ERROR: l_maxString bytes do not match the reference " + "version"); + TARG_BIN("Expected (l_maxStringReference)", + l_maxStringReference,sizeof(l_maxStringReference)); + TARG_BIN("Actual (l_maxString)", + l_maxString,sizeof(l_maxString)); + } + + // TC3.5: String must equal "abc" by comparison + if(strcmp(l_maxString,l_maxStringReference) != 0) + { + TS_FAIL("ERROR: l_maxString does not strcmp to the reference " + "string"); + TARG_BIN("Actual (l_maxString)", + l_maxString,sizeof(l_maxString)); + } + + // TC4: Test string with no supplied default value + // TC4.1: String storage size must match stated size + ATTR_TEST_NO_DEFAULT_STRING_type l_noDefaultStringReference = {0}; + ATTR_TEST_NO_DEFAULT_STRING_type l_noDefaultString = {0}; + if(sizeof(l_noDefaultString) != ATTR_TEST_NO_DEFAULT_STRING_max_chars+1) + { + TS_FAIL("ERROR: l_noDefaultString size (%d) " + "does not match stated size (%d)", + sizeof(l_noDefaultString), + ATTR_TEST_NO_DEFAULT_STRING_max_chars+1); + } + + // TC4.2: String storage size must be non-zero + if(sizeof(l_noDefaultString) == 0) + { + TS_FAIL("ERROR: l_noDefaultString storage size is zero"); + } + + // TC4.3: Must be able to read the string + if(!l_pTopLevel->tryGetAttr<ATTR_TEST_NO_DEFAULT_STRING>( + l_noDefaultString)) + { + TS_FAIL("ERROR: Could not read l_noDefaultString"); + } + + // TC4.4: All bytes in string must match the reference + if(memcmp(l_noDefaultStringReference, + l_noDefaultString, + sizeof(l_noDefaultStringReference))) + { + TS_FAIL("ERROR: l_noDefaultString bytes do not match the " + "reference"); + TARG_BIN("Expected (l_noDefaultStringReference)", + l_noDefaultStringReference, + sizeof(l_noDefaultStringReference)); + TARG_BIN("Actual (l_noDefaultString)", + l_noDefaultString,sizeof(l_noDefaultString)); + } + + // TC4.5: String must equal empty string by comparison + if(strcmp(l_noDefaultString,l_noDefaultStringReference) != 0) + { + TS_FAIL("ERROR: l_noDefaultString does not strcmp to the reference " + "string"); + TARG_BIN("Actual (l_noDefaultString)", + l_noDefaultString,sizeof(l_noDefaultString)); + } + + // TC5: Write string and read back + // TC5.1: Must be able to write the string + ATTR_TEST_NO_DEFAULT_STRING_type l_writeString = {0}; + strcpy(l_writeString,"aabbcc"); + if(!l_pTopLevel->trySetAttr<ATTR_TEST_NO_DEFAULT_STRING>(l_writeString)) + { + TS_FAIL("ERROR: Could not write l_writeString"); + } + + ATTR_TEST_NO_DEFAULT_STRING_type l_readString = {0}; + if(!l_pTopLevel->tryGetAttr<ATTR_TEST_NO_DEFAULT_STRING>(l_readString)) + { + TS_FAIL("ERROR: Could not read l_readString"); + } + + if(strcmp(l_writeString,l_readString) != 0) + { + TS_FAIL("ERROR: String does not match what was written"); + TARG_BIN("Expected (l_writeString)", + l_writeString, + sizeof(l_writeString)); + TARG_BIN("Actual (l_readString)", + l_readString, + sizeof(l_readString)); + } + + } while(0); + + TS_TRACE(EXIT_MRK "testStringAttributes" ); + } + }; #endif // End __TESTTARGETING_H diff --git a/src/usr/targeting/xmltohb/attribute_types.xml b/src/usr/targeting/xmltohb/attribute_types.xml index 3b0cb4cb1..9f42d262b 100644 --- a/src/usr/targeting/xmltohb/attribute_types.xml +++ b/src/usr/targeting/xmltohb/attribute_types.xml @@ -3202,4 +3202,63 @@ </hwpfToHbAttrMap> </attribute> +<!-- Begin attributes (4) to test string support --> + +<attribute> + <id>TEST_NULL_STRING</id> + <description>Test attribute; string with empty default value</description> + <simpleType> + <string> + <default></default> + <sizeInclNull>10</sizeInclNull> + </string> + </simpleType> + <persistency>volatile</persistency> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>TEST_MIN_STRING</id> + <description>Test attribute; smallest string possible given size</description> + <simpleType> + <string> + <default>a</default> + <sizeInclNull>10</sizeInclNull> + </string> + </simpleType> + <persistency>volatile</persistency> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>TEST_MAX_STRING</id> + <description>Test attribute; largest string possible given size</description> + <simpleType> + <string> + <default>abc</default> + <sizeInclNull>4</sizeInclNull> + </string> + </simpleType> + <persistency>volatile</persistency> + <readable/> + <writeable/> +</attribute> + +<attribute> + <id>TEST_NO_DEFAULT_STRING</id> + <description>Test attribute; string with no default supplied</description> + <simpleType> + <string> + <sizeInclNull>10</sizeInclNull> + </string> + </simpleType> + <persistency>volatile</persistency> + <readable/> + <writeable/> +</attribute> + +<!-- End attributes (4) to test string support --> + </attributes> diff --git a/src/usr/targeting/xmltohb/target_types.xml b/src/usr/targeting/xmltohb/target_types.xml index 206221a5e..b9fb47a6c 100644 --- a/src/usr/targeting/xmltohb/target_types.xml +++ b/src/usr/targeting/xmltohb/target_types.xml @@ -67,6 +67,10 @@ <attribute><id>HB_MUTEX_TEST_LOCK</id></attribute> <attribute><id>DUMMY_RW</id></attribute> <attribute><id>XSCOM_BASE_ADDRESS</id></attribute> + <attribute><id>TEST_NULL_STRING</id></attribute> + <attribute><id>TEST_MIN_STRING</id><default>Z</default></attribute> + <attribute><id>TEST_MAX_STRING</id></attribute> + <attribute><id>TEST_NO_DEFAULT_STRING</id></attribute> <attribute> <id>PHYS_PATH</id> <default>physical:sys-0</default> diff --git a/src/usr/targeting/xmltohb/xmltohb.pl b/src/usr/targeting/xmltohb/xmltohb.pl index 48d5c260d..c67532047 100755 --- a/src/usr/targeting/xmltohb/xmltohb.pl +++ b/src/usr/targeting/xmltohb/xmltohb.pl @@ -1212,6 +1212,15 @@ sub writeTraitFileTraits { $dimensions .= "[$bound]"; } } + elsif(exists $simpleType->{string}) + { + # Create the string dimension + if(exists $simpleType->{string}->{sizeInclNull}) + { + $dimensions .= + "[$simpleType->{string}->{sizeInclNull}]"; + } + } last; } } @@ -1247,8 +1256,27 @@ sub writeTraitFileTraits { print $outFile " typedef ", $type, " Type$dimensions;\n"; print $outFile "};\n\n"; + $typedefs .= "// Type aliases and/or sizes for ATTR_" + . "$attribute->{id} attribute\n"; + $typedefs .= "typedef " . $type . " $attribute->{id}" . "_ATTR" . $dimensions . ";\n"; + + # Append a more friendly type alias for attribute + $typedefs .= "typedef " . $type . + " ATTR_" . "$attribute->{id}" . "_type" . $dimensions . ";\n"; + + # If a string, append max # of characters for the string + if( (exists $attribute->{simpleType}) + && (exists $attribute->{simpleType}->{string})) + { + my $size = $attribute->{simpleType}->{string}->{sizeInclNull} - 1; + $typedefs .= "const size_t ATTR_" + . "$attribute->{id}" . "_max_chars = " + . "$size" + . ";\n"; + } + $typedefs .= "\n"; }; print $outFile "/**\n"; @@ -1326,6 +1354,36 @@ sub packQuad{ } ################################################################################ +# Pack string into buffer +################################################################################ + +sub packString{ + my($value,$attribute) = @_; + + # Proper attribute tags already verified, no need to do checking again + my $sizeInclNull = $attribute->{simpleType}->{string}->{sizeInclNull}; + + # print "String content (before fixup) is [$value]\n"; + + # For sanity, remove all white space from front and end of string + $value =~ s/^\s+//g; + $value =~ s/\s+$//g; + + my $length = length($value); + + # print "String content (after fixup) is [$value]\n"; + # print "String length is $length\n"; + # print "String container size is $sizeInclNull\n"; + + if(($length + 1) > $sizeInclNull) + { + fatal("ERROR: Supplied string exceeds allows length"); + } + + return pack("Z$sizeInclNull",$value); +} + +################################################################################ # Get space required to store an enum, based on the max value ################################################################################ @@ -1461,6 +1519,16 @@ sub defaultZero { } ################################################################################ +# Return string default (empty string) +################################################################################ + +sub defaultString { + my($attributes,$typeInstance) = @_; + + return ""; +} + +################################################################################ # Return default value for an attribute whose type is 'enumeration' ################################################################################ @@ -1506,6 +1574,37 @@ sub enforceHbMutex { } ################################################################################ +# Enforce string restrictions +################################################################################ + +sub enforceString { + my($attribute,$value) = @_; + + if(!exists $attribute->{simpleType}) + { + fatal("ERROR: Tried to enforce string policies on a non-simple type"); + } + + if(!exists $attribute->{simpleType}->{string}) + { + fatal("ERROR: Did not find expected string element"); + } + + if(!exists $attribute->{simpleType}->{string}->{sizeInclNull}) + { + fatal("ERROR: Did not find expected string sizeInclNull element"); + } + + my $size = $attribute->{simpleType}->{string}->{sizeInclNull}; + if($size <= 1) + { + fatal("ERROR: String size must be > 1 (string of size one is " + . "only big enough to hold the empty string, which is not " + . "useful)"); + } +} + +################################################################################ # Get hash ref to supported simple types and their properties ################################################################################ @@ -1515,16 +1614,17 @@ sub simpleTypeProperties { # Intentionally didn't wrap these to 80 columns to keep them lined up and # more readable/editable - $typesHoH{"int8_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int8_t" , bytes => 1, bits => 8 , default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "C" }; - $typesHoH{"int16_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int16_t" , bytes => 2, bits => 16, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "n" }; - $typesHoH{"int32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int32_t" , bytes => 4, bits => 32, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "N" }; - $typesHoH{"int64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int64_t" , bytes => 8, bits => 64, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt =>\&packQuad}; - $typesHoH{"uint8_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint8_t" , bytes => 1, bits => 8 , default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "C" }; - $typesHoH{"uint16_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint16_t" , bytes => 2, bits => 16, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "n" }; - $typesHoH{"uint32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint32_t" , bytes => 4, bits => 32, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt => "N" }; - $typesHoH{"uint64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint64_t" , bytes => 8, bits => 64, default => \&defaultZero, alignment => 1, specialPolicies =>\&null, packfmt =>\&packQuad}; - $typesHoH{"enumeration"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "XMLTOHB_USE_PARENT_ATTR_ID" , bytes => 0, bits => 0 , default => \&defaultEnum, alignment => 1, specialPolicies =>\&null, packfmt => "packEnumeration"}; - $typesHoH{"hbmutex"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "mutex_t*" , bytes => 8, bits => 64, default => \&defaultZero, alignment => 8, specialPolicies =>\&enforceHbMutex, packfmt =>\&packQuad}; + $typesHoH{"string"} = { supportsArray => 0, canBeHex => 0, complexTypeSupport => 0, typeName => "char" , bytes => 1, bits => 8 , default => \&defaultString, alignment => 1, specialPolicies =>\&enforceString, packfmt =>\&packString}; + $typesHoH{"int8_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int8_t" , bytes => 1, bits => 8 , default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt => "C" }; + $typesHoH{"int16_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int16_t" , bytes => 2, bits => 16, default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt => "n" }; + $typesHoH{"int32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int32_t" , bytes => 4, bits => 32, default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt => "N" }; + $typesHoH{"int64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "int64_t" , bytes => 8, bits => 64, default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt =>\&packQuad}; + $typesHoH{"uint8_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint8_t" , bytes => 1, bits => 8 , default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt => "C" }; + $typesHoH{"uint16_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint16_t" , bytes => 2, bits => 16, default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt => "n" }; + $typesHoH{"uint32_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint32_t" , bytes => 4, bits => 32, default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt => "N" }; + $typesHoH{"uint64_t"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 1, typeName => "uint64_t" , bytes => 8, bits => 64, default => \&defaultZero , alignment => 1, specialPolicies =>\&null, packfmt =>\&packQuad}; + $typesHoH{"enumeration"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "XMLTOHB_USE_PARENT_ATTR_ID" , bytes => 0, bits => 0 , default => \&defaultEnum , alignment => 1, specialPolicies =>\&null, packfmt => "packEnumeration"}; + $typesHoH{"hbmutex"} = { supportsArray => 1, canBeHex => 1, complexTypeSupport => 0, typeName => "mutex_t*" , bytes => 8, bits => 64, default => \&defaultZero , alignment => 8, specialPolicies =>\&enforceHbMutex, packfmt =>\&packQuad}; return \%typesHoH; } @@ -1551,7 +1651,13 @@ sub getAttributeDefault { # might add value to the hash if(exists $attribute->{simpleType}->{$type} ) { - if(exists $attribute->{simpleType}->{$type}->{default}) + # If attribute exists, or is not a HASH val (which can + # occur if the default element is omitted), then just + # grab the supplied value, otherwise use the default for + # the type + if( (exists $attribute->{simpleType}->{$type}->{default}) + && (ref ($attribute->{simpleType}->{$type}->{default}) + ne "HASH") ) { $default = $attribute->{simpleType}->{$type}->{default}; @@ -2002,8 +2108,9 @@ sub packEntityPath { } ################################################################################ -# Pack an attribute into a binary data stream +# Pack a single, simple attribute into a binary data stream ################################################################################ + sub packSingleSimpleTypeAttribute { my($binaryDataRef,$attributesRef,$attributeRef,$typeName,$value) = @_; @@ -2032,7 +2139,7 @@ sub packSingleSimpleTypeAttribute { if(ref ($simpleTypeProperties->{$typeName}{packfmt}) eq "CODE") { $$binaryDataRef .= $simpleTypeProperties->{$typeName}{packfmt}-> - ($value); + ($value,$$attributeRef); } else { @@ -2042,6 +2149,10 @@ sub packSingleSimpleTypeAttribute { } } +################################################################################ +# Pack generic attribute into a binary data stream +################################################################################ + sub packAttribute { my($attributes,$attribute,$value) = @_; |