diff options
174 files changed, 4897 insertions, 634 deletions
@@ -11,6 +11,14 @@ Version 3.2.0 XSD/e runtime library accordingly and pass the --char-encoding option to the XSD/e compiler when translating your schemas. + * Support for custom allocators. This feature allows you to configure + the XSD/e runtime and generated code to perform memory management + using custom allocator functions provided by your application instead + of the standard operator new/delete. For more information, see Section + 3.8, "Custom Allocators" in the C++/Hybrid Mapping Getting Started + Guide (equivalent documentation is provided for other mappings) as + well as the 'allocator' example in the examples/cxx/hybrid/ directory. + * When built with Xerces-C++ 3-series, enable handling of multiple imports for the same namespace. Before, all subsequent imports for a namespace were ignored which caused error in some schemas. diff --git a/build/configuration.make b/build/configuration.make index 49624e5..0de6d47 100644 --- a/build/configuration.make +++ b/build/configuration.make @@ -20,6 +20,8 @@ xsde_snprintf := xsde_parser_validation := xsde_serializer_validation := xsde_reuse_style := +xsde_custom_allocator := +xsde_default_allocator := xsde_xdr := xsde_cdr := xsde_polymorphic := @@ -46,6 +48,8 @@ $(out_root)/%: xsde_snprintf := $(xsde_snprintf) $(out_root)/%: xsde_parser_validation := $(xsde_parser_validation) $(out_root)/%: xsde_serializer_validation := $(xsde_serializer_validation) $(out_root)/%: xsde_reuse_style := $(xsde_reuse_style) +$(out_root)/%: xsde_custom_allocator := $(xsde_custom_allocator) +$(out_root)/%: xsde_default_allocator := $(xsde_default_allocator) $(out_root)/%: xsde_xdr := $(xsde_xdr) $(out_root)/%: xsde_cdr := $(xsde_cdr) $(out_root)/%: xsde_polymorphic := $(xsde_polymorphic) diff --git a/build/configure b/build/configure index 8295e76..7e37c13 100755 --- a/build/configure +++ b/build/configure @@ -108,6 +108,19 @@ $echo reuse_style=`read_option "mixin tiein none" "tiein"` $echo +$echo "Would you like to enable support for custom memory allocator?" +$echo + +allocator=`read_y_n n` + +$echo +$echo "Would you like to include the default implementation of the" +$echo "memory allocator functions into the XSD/e runtime library?" +$echo + +allocator_default=`read_y_n n` + +$echo $echo "Would you like to build support for serialization in XDR format?" $echo "This requires the XDR API that is part of Sun RPC (rpc/xdr.h)." $echo @@ -185,6 +198,8 @@ echo "xsde_snprintf := $snprintf" >> echo "xsde_parser_validation := $parser_validation" >>$1 echo "xsde_serializer_validation := $serializer_validation" >>$1 echo "xsde_reuse_style := $reuse_style" >>$1 +echo "xsde_custom_allocator := $allocator" >>$1 +echo "xsde_default_allocator := $allocator_default" >>$1 echo "xsde_xdr := $xdr" >>$1 echo "xsde_cdr := $cdr" >>$1 echo "xsde_polymorphic := $polymorphic" >>$1 @@ -263,6 +263,10 @@ gen 'ifeq ($(XSDE_POLYMORPHIC),y)' gen 'EXTRA_XSDFLAGS += --runtime-polymorphic' gen 'endif' gen +gen 'ifeq ($(XSDE_CUSTOM_ALLOCATOR),y)' +gen 'EXTRA_XSDFLAGS += --custom-allocator' +gen 'endif' +gen gen "$driver: $obj" '$(root)/libxsde/xsde/libxsde.a' gen @@ -414,6 +418,10 @@ gen '!if "$(XSDE_POLYMORPHIC)" == "y"' gen 'EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --runtime-polymorphic' gen '!endif' gen +gen '!if "$(XSDE_CUSTOM_ALLOCATOR)" == "y"' +gen 'EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --custom-allocator' +gen '!endif' +gen gen "$driver: $obj" '$(root)\\libxsde\\xsde\\xsde.lib' gen diff --git a/build/xsde/hybrid/xsd-cxx.make b/build/xsde/hybrid/xsd-cxx.make index 540fa1f..57420f0 100644 --- a/build/xsde/hybrid/xsd-cxx.make +++ b/build/xsde/hybrid/xsd-cxx.make @@ -94,6 +94,10 @@ ifeq ($(xsde_reuse_style),none) $(error Hybrid mapping requires support for base parser/serializer reuse) endif +ifeq ($(xsde_custom_allocator),y) +ops += $(xsde_options) --custom-allocator +endif + $(xsd_hybrid_pattern): xsde_options := $(ops) .PRECIOUS: $(xsd_hybrid_pattern) diff --git a/build/xsde/parser/xsd-cxx.make b/build/xsde/parser/xsd-cxx.make index f9c87e9..3a246ff 100644 --- a/build/xsde/parser/xsd-cxx.make +++ b/build/xsde/parser/xsd-cxx.make @@ -68,6 +68,10 @@ ifeq ($(xsde_reuse_style),none) ops += $(xsde_options) --reuse-style-none endif +ifeq ($(xsde_custom_allocator),y) +ops += $(xsde_options) --custom-allocator +endif + $(xsd_parser_pattern): xsde_options := $(ops) diff --git a/build/xsde/serializer/xsd-cxx.make b/build/xsde/serializer/xsd-cxx.make index a042ef9..86101c6 100644 --- a/build/xsde/serializer/xsd-cxx.make +++ b/build/xsde/serializer/xsd-cxx.make @@ -68,6 +68,10 @@ ifeq ($(xsde_reuse_style),none) ops += $(xsde_options) --reuse-style-none endif +ifeq ($(xsde_custom_allocator),y) +ops += $(xsde_options) --custom-allocator +endif + $(xsd_serializer_pattern): xsde_options := $(ops) diff --git a/dist/build/config.make b/dist/build/config.make index b05df1a..e9e7826 100644 --- a/dist/build/config.make +++ b/dist/build/config.make @@ -23,6 +23,8 @@ XSDE_SNPRINTF := $(strip $(XSDE_SNPRINTF)) XSDE_PARSER_VALIDATION := $(strip $(XSDE_PARSER_VALIDATION)) XSDE_SERIALIZER_VALIDATION := $(strip $(XSDE_SERIALIZER_VALIDATION)) XSDE_REUSE_STYLE := $(strip $(XSDE_REUSE_STYLE)) +XSDE_CUSTOM_ALLOCATOR := $(strip $(XSDE_CUSTOM_ALLOCATOR)) +XSDE_DEFAULT_ALLOCATOR := $(strip $(XSDE_DEFAULT_ALLOCATOR)) XSDE_CDR := $(strip $(XSDE_CDR)) XSDE_XDR := $(strip $(XSDE_XDR)) XSDE_POLYMORPHIC := $(strip $(XSDE_POLYMORPHIC)) diff --git a/dist/config/config.make b/dist/config/config.make index fccb68f..95dc46f 100644 --- a/dist/config/config.make +++ b/dist/config/config.make @@ -117,6 +117,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/config/config.nmake b/dist/config/config.nmake index 0e4008f..3e23c25 100644 --- a/dist/config/config.nmake +++ b/dist/config/config.nmake @@ -116,6 +116,24 @@ XSDE_SERIALIZER_VALIDATION = y XSDE_REUSE_STYLE = tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR = n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR = n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/evc-4.0/config.nmake b/dist/etc/evc-4.0/config.nmake index 136f281..825c909 100644 --- a/dist/etc/evc-4.0/config.nmake +++ b/dist/etc/evc-4.0/config.nmake @@ -119,6 +119,24 @@ XSDE_SERIALIZER_VALIDATION = y XSDE_REUSE_STYLE = tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR = n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR = n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/iphone/config-device.make b/dist/etc/iphone/config-device.make index c6e8634..8d11943 100644 --- a/dist/etc/iphone/config-device.make +++ b/dist/etc/iphone/config-device.make @@ -124,6 +124,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/iphone/config-simulator.make b/dist/etc/iphone/config-simulator.make index afff0a6..48f0652 100644 --- a/dist/etc/iphone/config-simulator.make +++ b/dist/etc/iphone/config-simulator.make @@ -124,6 +124,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/lynxos/config-4.2.make b/dist/etc/lynxos/config-4.2.make index 5be4262..d1b1b68 100644 --- a/dist/etc/lynxos/config-4.2.make +++ b/dist/etc/lynxos/config-4.2.make @@ -123,6 +123,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/lynxos/config-5.0.make b/dist/etc/lynxos/config-5.0.make index 25a15b2..b61ade3 100644 --- a/dist/etc/lynxos/config-5.0.make +++ b/dist/etc/lynxos/config-5.0.make @@ -123,6 +123,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/qnx/config-6.3-gcc-2.95.make b/dist/etc/qnx/config-6.3-gcc-2.95.make index 3211450..1228db2 100644 --- a/dist/etc/qnx/config-6.3-gcc-2.95.make +++ b/dist/etc/qnx/config-6.3-gcc-2.95.make @@ -122,6 +122,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/qnx/config-6.3-gcc-3.3.make b/dist/etc/qnx/config-6.3-gcc-3.3.make index e0a84db..fe39d31 100644 --- a/dist/etc/qnx/config-6.3-gcc-3.3.make +++ b/dist/etc/qnx/config-6.3-gcc-3.3.make @@ -122,6 +122,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/qnx/config-6.4.make b/dist/etc/qnx/config-6.4.make index 71f40db..33d3658 100644 --- a/dist/etc/qnx/config-6.4.make +++ b/dist/etc/qnx/config-6.4.make @@ -122,6 +122,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/vc-8.0/config-max.nmake b/dist/etc/vc-8.0/config-max.nmake index 59d1a1c..07a7c0a 100644 --- a/dist/etc/vc-8.0/config-max.nmake +++ b/dist/etc/vc-8.0/config-max.nmake @@ -120,6 +120,24 @@ XSDE_SERIALIZER_VALIDATION = y XSDE_REUSE_STYLE = tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR = n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR = n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/vc-8.0/config-min.nmake b/dist/etc/vc-8.0/config-min.nmake index bdb9863..1177d58 100644 --- a/dist/etc/vc-8.0/config-min.nmake +++ b/dist/etc/vc-8.0/config-min.nmake @@ -120,6 +120,24 @@ XSDE_SERIALIZER_VALIDATION = y XSDE_REUSE_STYLE = tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR = n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR = n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/vc-9.0/config-max.nmake b/dist/etc/vc-9.0/config-max.nmake index 3a11fe7..6d39a73 100644 --- a/dist/etc/vc-9.0/config-max.nmake +++ b/dist/etc/vc-9.0/config-max.nmake @@ -120,6 +120,24 @@ XSDE_SERIALIZER_VALIDATION = y XSDE_REUSE_STYLE = tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR = n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR = n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/vc-9.0/config-min.nmake b/dist/etc/vc-9.0/config-min.nmake index 9df85b5..337369f 100644 --- a/dist/etc/vc-9.0/config-min.nmake +++ b/dist/etc/vc-9.0/config-min.nmake @@ -120,6 +120,24 @@ XSDE_SERIALIZER_VALIDATION = y XSDE_REUSE_STYLE = tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR = n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR = n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/vxworks/config-5.5.1.make b/dist/etc/vxworks/config-5.5.1.make index 89bf164..df7549e 100644 --- a/dist/etc/vxworks/config-5.5.1.make +++ b/dist/etc/vxworks/config-5.5.1.make @@ -123,6 +123,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/vxworks/config-6.4-max.make b/dist/etc/vxworks/config-6.4-max.make index b1b08fd..835ba84 100644 --- a/dist/etc/vxworks/config-6.4-max.make +++ b/dist/etc/vxworks/config-6.4-max.make @@ -135,6 +135,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/vxworks/config-6.4-min.make b/dist/etc/vxworks/config-6.4-min.make index 3435c70..2ac5ef3 100644 --- a/dist/etc/vxworks/config-6.4-min.make +++ b/dist/etc/vxworks/config-6.4-min.make @@ -122,6 +122,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/vxworks/config-6.7-max.make b/dist/etc/vxworks/config-6.7-max.make index 43731df..30e7347 100644 --- a/dist/etc/vxworks/config-6.7-max.make +++ b/dist/etc/vxworks/config-6.7-max.make @@ -135,6 +135,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/etc/vxworks/config-6.7-min.make b/dist/etc/vxworks/config-6.7-min.make index cf8d622..b624c8c 100644 --- a/dist/etc/vxworks/config-6.7-min.make +++ b/dist/etc/vxworks/config-6.7-min.make @@ -122,6 +122,24 @@ XSDE_SERIALIZER_VALIDATION := y XSDE_REUSE_STYLE := tiein +# Set to 'y' if you would like the XSD/e runtime and the generated code +# to perform memory management using custom allocator functions provided +# by your application instead of the standard operator new/delete. Also +# don't forget to use the --custom-allocator option when compiling your +# schemas. See the documentation and examples for more information on +# custom allocators. +# +XSDE_CUSTOM_ALLOCATOR := n + + +# Set to 'y' if you would like to include the default implementation of the +# custom allocator into the XSD/e runtime library. This option is primarily +# useful for testing and only makes sense if XSDE_CUSTOM_ALLOCATOR is set +# to 'y'. +# +XSDE_DEFAULT_ALLOCATOR := n + + # Set to 'y' if you want support for serialization of the C++/Hybrid # object model to the CDR (Common Data Representation) binary format. # This functionality requires the ACE library. diff --git a/dist/examples/cxx/hybrid/allocator/makefile b/dist/examples/cxx/hybrid/allocator/makefile new file mode 100644 index 0000000..d0e2318 --- /dev/null +++ b/dist/examples/cxx/hybrid/allocator/makefile @@ -0,0 +1,81 @@ +root := ../../../.. + +include $(root)/build/cxx/rules.make + +# Build. +# +EXTRA_CPPFLAGS := -I$(root)/libxsde + +EXTRA_XSDFLAGS := --no-stl --no-exceptions --custom-allocator + +ifeq ($(XSDE_ENCODING),iso8859-1) +EXTRA_XSDFLAGS += --char-encoding iso8859-1 +endif + +ifeq ($(XSDE_IOSTREAM),n) +EXTRA_XSDFLAGS += --no-iostream +endif + +ifeq ($(XSDE_LONGLONG),n) +EXTRA_XSDFLAGS += --no-long-long +endif + +ifeq ($(XSDE_PARSER_VALIDATION),n) +EXTRA_XSDFLAGS += --suppress-parser-val +endif + +ifeq ($(XSDE_SERIALIZER_VALIDATION),n) +EXTRA_XSDFLAGS += --suppress-serializer-val +endif + +ifeq ($(XSDE_REUSE_STYLE),mixin) +EXTRA_XSDFLAGS += --reuse-style-mixin +endif + +ifeq ($(XSDE_POLYMORPHIC),y) +EXTRA_XSDFLAGS += --runtime-polymorphic +endif + +driver: driver.o arena.o people.o people-pskel.o people-pimpl.o \ +people-sskel.o people-simpl.o $(root)/libxsde/xsde/libxsde.a + +driver.o: driver.cxx arena.cxx arena.hxx people.hxx people-pimpl.hxx \ +people-simpl.hxx +arena.o: arena.cxx arena.hxx +people.o: people.cxx +people-pskel.o: people-pskel.cxx +people-pimpl.o: people-pimpl.cxx +people-simpl.o: people-simpl.cxx +people-simpl.o: people-simpl.cxx + +.PRECIOUS: %.hxx %.cxx %-pskel.hxx %-pskel.cxx %-pimpl.hxx %-pimpl.cxx \ +%-sskel.hxx %-sskel.cxx %-simpl.hxx %-simpl.cxx + +%.hxx %.cxx %-pskel.hxx %-pskel.cxx %-pimpl.hxx %-pimpl.cxx \ +%-sskel.hxx %-sskel.cxx %-simpl.hxx %-simpl.cxx: %.xsd + $(root)/bin/xsde cxx-hybrid $(XSDFLAGS) $(EXTRA_XSDFLAGS) \ +--generate-parser --generate-serializer --generate-aggregate $< + + +# Generate. +# +.PHONY: gen +gen: people.hxx + + +# Test. +# +.PHONY: test +test: driver people.xml + ./driver people.xml + +# Clean. +# +.PHONY: clean cleanobj +cleanobj: + rm -f people-pimpl.o people-pskel.o people-simpl.o people-sskel.o \ +people.o driver.o arena.o driver + +clean: cleanobj + rm -f people-pimpl.?xx people-pskel.?xx people-simpl.?xx \ +people-sskel.?xx people.?xx diff --git a/dist/examples/cxx/hybrid/allocator/nmakefile b/dist/examples/cxx/hybrid/allocator/nmakefile new file mode 100644 index 0000000..908dd7e --- /dev/null +++ b/dist/examples/cxx/hybrid/allocator/nmakefile @@ -0,0 +1,77 @@ +root = ..\..\..\.. + +!include $(root)\build\cxx\rules.nmake + +# Build. +# +EXTRA_CPPFLAGS = /I$(root)\libxsde + +EXTRA_XSDFLAGS = --no-stl --no-exceptions --custom-allocator + +!if "$(XSDE_ENCODING)" == "iso8859-1" +EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --char-encoding iso8859-1 +!endif + +!if "$(XSDE_IOSTREAM)" == "n" +EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --no-iostream +!endif + +!if "$(XSDE_LONGLONG)" == "n" +EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --no-long-long +!endif + +!if "$(XSDE_PARSER_VALIDATION)" == "n" +EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --suppress-parser-val +!endif + +!if "$(XSDE_SERIALIZER_VALIDATION)" == "n" +EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --suppress-serializer-val +!endif + +!if "$(XSDE_REUSE_STYLE)" == "mixin" +EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --reuse-style-mixin +!endif + +!if "$(XSDE_POLYMORPHIC)" == "y" +EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --runtime-polymorphic +!endif + +driver.exe: driver.obj arena.obj people.obj people-pskel.obj people-pimpl.obj \ +people-sskel.obj people-simpl.obj $(root)\libxsde\xsde\xsde.lib + +driver.obj: driver.cxx arena.cxx arena.hxx people.hxx people-pimpl.hxx \ +people-simpl.hxx +arena.obj: arena.cxx arena.hxx +people.obj: people.cxx +people-pskel.obj: people-pskel.cxx +people-pimpl.obj: people-pimpl.cxx +people-sskel.obj: people-sskel.cxx +people-simpl.obj: people-simpl.cxx + +people.cxx people.hxx \ +people-pskel.cxx people-pskel.hxx people-pimpl.cxx people-pimpl.hxx \ +people-sskel.cxx people-sskel.hxx people-simpl.cxx people-simpl.hxx \ +: people.xsd + $(root)\bin\xsde.exe cxx-hybrid $(XSDFLAGS) $(EXTRA_XSDFLAGS) \ +--generate-parser --generate-serializer --generate-aggregate people.xsd + + +# Generate. +# +gen: people.hxx + + +# Test. +# +test: driver.exe people.xml + .\driver.exe people.xml + +# Clean. +# +cleanobj: + -del people-pimpl.obj people-pskel.obj people-simpl.obj \ +people-sskel.obj people.obj driver.obj arena.obj driver.exe + +clean: cleanobj + -del people-pimpl.?xx people-pskel.?xx people-simpl.?xx \ +people-sskel.?xx people.?xx diff --git a/dist/examples/cxx/hybrid/makefile b/dist/examples/cxx/hybrid/makefile index 3a9ddaa..859451b 100644 --- a/dist/examples/cxx/hybrid/makefile +++ b/dist/examples/cxx/hybrid/makefile @@ -2,7 +2,11 @@ root := ../../.. include $(root)/build/config.make -dirs := binary compositors custom +dirs := + +ifeq ($(XSDE_CUSTOM_ALLOCATOR),n) + +dirs += binary compositors custom ifeq ($(XSDE_IOSTREAM),y) ifeq ($(XSDE_EXCEPTIONS),y) @@ -26,6 +30,16 @@ dirs += minimal endif endif +else # XSDE_CUSTOM_ALLOCATOR + +ifeq ($(XSDE_STL),n) +ifeq ($(XSDE_EXCEPTIONS),n) +dirs += allocator +endif +endif + +endif + .PHONY: all $(dirs) diff --git a/dist/examples/cxx/hybrid/nmakefile b/dist/examples/cxx/hybrid/nmakefile index 8bd74e6..45c57ca 100644 --- a/dist/examples/cxx/hybrid/nmakefile +++ b/dist/examples/cxx/hybrid/nmakefile @@ -2,7 +2,11 @@ root = ..\..\.. !include $(root)\build\config.nmake -dirs = binary compositors custom +dirs = + +!if "$(XSDE_CUSTOM_ALLOCATOR)" == "n" + +dirs = $(dirs) binary compositors custom !if "$(XSDE_IOSTREAM)" == "y" !if "$(XSDE_EXCEPTIONS)" == "y" @@ -26,6 +30,17 @@ dirs = $(dirs) minimal !endif !endif +!else # XSDE_CUSTOM_ALLOCATOR + +!if "$(XSDE_STL)" == "n" +!if "$(XSDE_EXCEPTIONS)" == "n" +dirs = $(dirs) allocator +!endif +!endif + +!endif + + all: @for %i in ( $(dirs) ) do \ @cmd /c "echo entering %i && cd %i && $(MAKE) /nologo /f nmakefile" || exit 1 diff --git a/dist/examples/cxx/parser/generated/makefile b/dist/examples/cxx/parser/generated/makefile index 6f77af4..5335819 100644 --- a/dist/examples/cxx/parser/generated/makefile +++ b/dist/examples/cxx/parser/generated/makefile @@ -46,6 +46,10 @@ ifeq ($(XSDE_POLYMORPHIC),y) EXTRA_XSDFLAGS += --runtime-polymorphic endif +ifeq ($(XSDE_CUSTOM_ALLOCATOR),y) +EXTRA_XSDFLAGS += --custom-allocator +endif + library-pdriver: library-pdriver.o library-pskel.o library-pimpl.o $(root)/libxsde/xsde/libxsde.a library-pdriver.o: library-pdriver.cxx library-pimpl.hxx library-pskel.hxx diff --git a/dist/examples/cxx/parser/generated/nmakefile b/dist/examples/cxx/parser/generated/nmakefile index c801757..e505207 100644 --- a/dist/examples/cxx/parser/generated/nmakefile +++ b/dist/examples/cxx/parser/generated/nmakefile @@ -46,6 +46,10 @@ EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --reuse-style-mixin EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --runtime-polymorphic !endif +!if "$(XSDE_CUSTOM_ALLOCATOR)" == "y" +EXTRA_XSDFLAGS = $(EXTRA_XSDFLAGS) --custom-allocator +!endif + library-pdriver.exe: library-pdriver.obj library-pskel.obj library-pimpl.obj $(root)\libxsde\xsde\xsde.lib library-pdriver.obj: library-pdriver.cxx library-pimpl.hxx library-pskel.hxx diff --git a/dist/examples/cxx/parser/makefile b/dist/examples/cxx/parser/makefile index c286089..e0d9974 100644 --- a/dist/examples/cxx/parser/makefile +++ b/dist/examples/cxx/parser/makefile @@ -4,6 +4,8 @@ include $(root)/build/config.make dirs := +ifeq ($(XSDE_CUSTOM_ALLOCATOR),n) + ifneq ($(XSDE_REUSE_STYLE),none) dirs += generated endif @@ -39,6 +41,15 @@ endif endif endif +else # XSDE_CUSTOM_ALLOCATOR + +ifeq ($(XSDE_DEFAULT_ALLOCATOR),y) +ifneq ($(XSDE_REUSE_STYLE),none) +dirs += generated +endif +endif + +endif .PHONY: all $(dirs) diff --git a/dist/examples/cxx/parser/nmakefile b/dist/examples/cxx/parser/nmakefile index 8e88704..a23503d 100644 --- a/dist/examples/cxx/parser/nmakefile +++ b/dist/examples/cxx/parser/nmakefile @@ -4,6 +4,8 @@ root = ..\..\.. dirs = +!if "$(XSDE_CUSTOM_ALLOCATOR)" == "n" + !if "$(XSDE_REUSE_STYLE)" != "none" dirs = $(dirs) generated !endif @@ -39,6 +41,16 @@ dirs = $(dirs) minimal !endif !endif +!else # XSDE_CUSTOM_ALLOCATOR + +!if "$(XSDE_DEFAULT_ALLOCATOR)" == "y" +!if "$(XSDE_REUSE_STYLE)" != "none" +dirs = $(dirs) generated +!endif +!endif + +!endif + all: @for %i in ( $(dirs) ) do \ @cmd /c "echo entering %i && cd %i && $(MAKE) /nologo /f nmakefile" || exit 1 diff --git a/dist/examples/cxx/serializer/makefile b/dist/examples/cxx/serializer/makefile index 7677036..4164240 100644 --- a/dist/examples/cxx/serializer/makefile +++ b/dist/examples/cxx/serializer/makefile @@ -4,6 +4,8 @@ include $(root)/build/config.make dirs := +ifeq ($(XSDE_CUSTOM_ALLOCATOR),n) + ifeq ($(XSDE_STL),y) ifeq ($(XSDE_IOSTREAM),y) ifeq ($(XSDE_EXCEPTIONS),y) @@ -35,6 +37,7 @@ endif endif endif +endif # XSDE_CUSTOM_ALLOCATOR .PHONY: all $(dirs) diff --git a/dist/examples/cxx/serializer/nmakefile b/dist/examples/cxx/serializer/nmakefile index cd87db8..ee2224d 100644 --- a/dist/examples/cxx/serializer/nmakefile +++ b/dist/examples/cxx/serializer/nmakefile @@ -4,6 +4,8 @@ root = ..\..\.. dirs = +!if "$(XSDE_CUSTOM_ALLOCATOR)" == "n" + !if "$(XSDE_STL)" == "y" !if "$(XSDE_IOSTREAM)" == "y" !if "$(XSDE_EXCEPTIONS)" == "y" @@ -35,6 +37,8 @@ dirs = $(dirs) minimal !endif !endif +!endif # XSDE_CUSTOM_ALLOCATOR + all: @for %i in ( $(dirs) ) do \ @cmd /c "echo entering %i && cd %i && $(MAKE) /nologo /f nmakefile" || exit 1 diff --git a/dist/libxsde/xsde/makefile b/dist/libxsde/xsde/makefile index 9d3d1a1..34e026b 100644 --- a/dist/libxsde/xsde/makefile +++ b/dist/libxsde/xsde/makefile @@ -9,8 +9,20 @@ EXTRA_CPPFLAGS := -I.. src := c/expat/xmlparse.c c/expat/xmlrole.c c/expat/xmltok.c src += c/genx/genx.c c/genx/char-props.c +ifeq ($(XSDE_CUSTOM_ALLOCATOR),y) +ifeq ($(XSDE_DEFAULT_ALLOCATOR),y) +src += allocator.c +endif +endif + src += cxx/string.cxx cxx/string-search.cxx cxx/ro-string.cxx cxx/stack.cxx +ifeq ($(XSDE_CUSTOM_ALLOCATOR),y) +ifeq ($(XSDE_EXCEPTIONS),y) +src += cxx/allocator.cxx +endif +endif + ifeq ($(XSDE_ENCODING),iso8859-1) src += cxx/iso8859-1.cxx endif @@ -565,6 +577,12 @@ ifeq ($(XSDE_REUSE_STYLE),none) else @echo $(h)undef XSDE_REUSE_STYLE_NONE >>$@ endif +ifeq ($(XSDE_CUSTOM_ALLOCATOR),y) + @echo $(h)define XSDE_CUSTOM_ALLOCATOR >>$@ +endif +ifeq ($(XSDE_DEFAULT_ALLOCATOR),y) + @echo $(h)define XSDE_DEFAULT_ALLOCATOR >>$@ +endif ifeq ($(XSDE_POLYMORPHIC),y) @echo $(h)define XSDE_POLYMORPHIC >>$@ @echo $(h)define XSDE_PARSER_SMAP_BUCKETS $(XSDE_PARSER_SMAP_BUCKETS)UL >>$@ diff --git a/dist/libxsde/xsde/nmakefile b/dist/libxsde/xsde/nmakefile index b1fd08b..25625a3 100644 --- a/dist/libxsde/xsde/nmakefile +++ b/dist/libxsde/xsde/nmakefile @@ -11,12 +11,24 @@ EXTRA_CPPFLAGS = /I.. src = c\expat\xmlparse.c c\expat\xmlrole.c c\expat\xmltok.c src = $(src) c\genx\genx.c c\genx\char-props.c +!if "$(XSDE_CUSTOM_ALLOCATOR)" == "y" +!if "$(XSDE_DEFAULT_ALLOCATOR)" == "y" +src = $(src) allocator.c +!endif +!endif + src = $(src) \ cxx\string.cxx \ cxx\string-search.cxx \ cxx\ro-string.cxx \ cxx\stack.cxx +!if "$(XSDE_CUSTOM_ALLOCATOR)" == "y" +!if "$(XSDE_EXCEPTIONS)" == "y" +src = $(src) cxx/allocator.cxx +!endif +!endif + !if "$(XSDE_ENCODING)" == "iso8859-1" src = $(src) cxx\iso8859-1.cxx !endif @@ -565,6 +577,12 @@ config.h: !else @echo #undef XSDE_REUSE_STYLE_NONE >>$@ !endif +!if "$(XSDE_CUSTOM_ALLOCATOR)" == "y" + @echo #define XSDE_CUSTOM_ALLOCATOR >>$@ +!endif +!if "$(XSDE_DEFAULT_ALLOCATOR)" == "y" + @echo #define XSDE_DEFAULT_ALLOCATOR >>$@ +!endif !if "$(XSDE_POLYMORPHIC)" == "y" @echo #define XSDE_POLYMORPHIC >>$@ @echo #define XSDE_PARSER_SMAP_BUCKETS $(XSDE_PARSER_SMAP_BUCKETS)UL >>$@ diff --git a/documentation/cxx/hybrid/guide/index.xhtml b/documentation/cxx/hybrid/guide/index.xhtml index 3d414ce..460e3b2 100644 --- a/documentation/cxx/hybrid/guide/index.xhtml +++ b/documentation/cxx/hybrid/guide/index.xhtml @@ -232,6 +232,7 @@ <tr><th>3.5</th><td><a href="#3.5">64-bit Integer Type</a></td></tr> <tr><th>3.6</th><td><a href="#3.6">Parser and Serializer Reuse</a></td></tr> <tr><th>3.7</th><td><a href="#3.7">Support for Polymorphism</a></td></tr> + <tr><th>3.8</th><td><a href="#3.8">Custom Allocators</a></td></tr> </table> </td> </tr> @@ -1562,6 +1563,118 @@ $ xsde cxx-hybrid --generate-parser --generate-serializer \ <p>For information on how to use object models with polymorphic types, refer to <a href="#4.10">Section 4.10, "Polymorphic Object Models"</a>.</p> + <h2><a name="3.8">3.8 Custom Allocators</a></h2> + + <p>By default the XSD/e runtime and generated code use + the standard operators <code>new</code> and <code>delete</code> + to manage dynamic memory. However, it is possible to instead + use custom allocator functions provided by your application. + To achieve this, configure the XSD/e runtime library to use + custom allocator functions as well as pass the + <code>--custom-allocator</code> option to the XSD/e compiler + when translating your schemas. The signatures of the custom + allocator functions that should be provided by your application + are listed below. Their semantics should be equivalent to the + standard C <code>malloc()</code>, <code>realloc()</code>, and + <code>free()</code> functions.</p> + + <pre class="c++"> +extern "C" void* +xsde_alloc (size_t); + +extern "C" void* +xsde_realloc (void*, size_t); + +extern "C" void +xsde_free (void*); + </pre> + + <p>Note also that when custom allocators are enabled, any + dynamically-allocated object of which the XSD/e runtime + or generated code assume ownership should be allocated + using the custom allocation function. Similarly, if your + application assumes ownership of any dynamically-allocated + object returned by the XSD/e runtime or the generated code, + then such an object should be disposed of using the custom + deallocation function. To help with these tasks the generated + <code>xml_schema</code> namespace defines the following two + helper functions and, if C++ exceptions are enabled, automatic + pointer class:</p> + + <pre class="c++"> +namespace xml_schema +{ + void* + alloc (size_t); + + void + free (void*); + + struct alloc_guard + { + alloc_guard (void*); + ~alloc_guard (); + + void* + get () const; + + void + release (); + + private: + ... + }; +} + </pre> + + <p>If C++ exceptions are disabled, these functions are equivalent + to <code>xsde_alloc()</code> and <code>xsde_free()</code>. + If exceptions are enabled, <code>xml_schema::alloc()</code> + throws <code>std::bad_alloc</code> on memory allocation failure.</p> + + <p>The following code fragment shows how to create and destroy a + dynamically-allocated object with custom allocators when C++ + exceptions are disabled:</p> + + <pre class="c++"> +void* v = xml_schema::alloc (sizeof (type)); + +if (v == 0) +{ + // Handle out of memory condition. +} + +type* x = new (v) type (1, 2); + +... + +if (x) +{ + x->~type (); + xml_schema::free (x); +} + </pre> + + <p>The equivalent code fragment for configurations with C++ exceptions + enabled is shown below:</p> + + <pre class="c++"> +xml_schema::alloc_guard g (xml_schema::alloc (sizeof (type))); +type* x = new (g.get ()) type (1, 2); +g.release (); + +... + +if (x) +{ + x->~type (); + xml_schema::free (x); +} + </pre> + + <p>For a complete example that shows how to use custom allocators, see + the <code>allocator</code> example which can be found in the + <code>examples/cxx/hybrid/</code> directory of the XSD/e distribution.</p> <!-- Chapater 4 --> @@ -1882,7 +1995,9 @@ private: <p>When you set a value of an element or attribute of a variable-length type, the object model assumes ownership of - the pointed to object. It expects you to allocate the object with + the pointed to object. Unless you are using custom allocators + (see <a href="#3.8">Section 3.8, "Custom Allocators"</a>), + the object model expects you to allocate such an object with operator <code>new</code> and will eventually delete it with operator <code>delete</code>. You can also request generation of detach functions with the <code>--generate-detach</code> compiler @@ -1963,8 +2078,8 @@ people* con = new people; // Populate per and con. staff s; -s->permanent (per) // Assumes ownership or per. -s->contract (con) // Assumes ownership or con. +s->permanent (per) // Assumes ownership of per. +s->contract (con) // Assumes ownership of con. </pre> <h2><a name="4.3">4.3 Enumerations</a></h2> diff --git a/documentation/cxx/parser/guide/index.xhtml b/documentation/cxx/parser/guide/index.xhtml index 6a019c5..6805a9b 100644 --- a/documentation/cxx/parser/guide/index.xhtml +++ b/documentation/cxx/parser/guide/index.xhtml @@ -286,7 +286,8 @@ <tr><th>5.5</th><td><a href="#5.5">64-bit Integer Type</a></td></tr> <tr><th>5.6</th><td><a href="#5.6">Parser Reuse</a></td></tr> <tr><th>5.7</th><td><a href="#5.7">Support for Polymorphism</a></td></tr> - <tr><th>5.8</th><td><a href="#5.8">A Minimal Example</a></td></tr> + <tr><th>5.8</th><td><a href="#5.8">Custom Allocators</a></td></tr> + <tr><th>5.9</th><td><a href="#5.9">A Minimal Example</a></td></tr> </table> </td> </tr> @@ -2842,7 +2843,116 @@ main () on root elements requires a number of special actions as shown in the <code>polyroot</code> example.</p> - <h2><a name="5.8">5.8 A Minimal Example</a></h2> + <h2><a name="5.8">5.8 Custom Allocators</a></h2> + + <p>By default the XSD/e runtime and generated code use + the standard operators <code>new</code> and <code>delete</code> + to manage dynamic memory. However, it is possible to instead + use custom allocator functions provided by your application. + To achieve this, configure the XSD/e runtime library to use + custom allocator functions as well as pass the + <code>--custom-allocator</code> option to the XSD/e compiler + when translating your schemas. The signatures of the custom + allocator functions that should be provided by your application + are listed below. Their semantics should be equivalent to the + standard C <code>malloc()</code>, <code>realloc()</code>, and + <code>free()</code> functions.</p> + + <pre class="c++"> +extern "C" void* +xsde_alloc (size_t); + +extern "C" void* +xsde_realloc (void*, size_t); + +extern "C" void +xsde_free (void*); + </pre> + + <p>Note also that when custom allocators are enabled, any + dynamically-allocated object of which the XSD/e runtime + or generated code assume ownership should be allocated + using the custom allocation function. Similarly, if your + application assumes ownership of any dynamically-allocated + object returned by the XSD/e runtime or the generated code, + then such an object should be disposed of using the custom + deallocation function. To help with these tasks the generated + <code>xml_schema</code> namespace defines the following two + helper functions and, if C++ exceptions are enabled, automatic + pointer class:</p> + + <pre class="c++"> +namespace xml_schema +{ + void* + alloc (size_t); + + void + free (void*); + + struct alloc_guard + { + alloc_guard (void*); + ~alloc_guard (); + + void* + get () const; + + void + release (); + + private: + ... + }; +} + </pre> + + <p>If C++ exceptions are disabled, these functions are equivalent + to <code>xsde_alloc()</code> and <code>xsde_free()</code>. + If exceptions are enabled, <code>xml_schema::alloc()</code> + throws <code>std::bad_alloc</code> on memory allocation failure.</p> + + <p>The following code fragment shows how to create and destroy a + dynamically-allocated object with custom allocators when C++ + exceptions are disabled:</p> + + <pre class="c++"> +void* v = xml_schema::alloc (sizeof (type)); + +if (v == 0) +{ + // Handle out of memory condition. +} + +type* x = new (v) type (1, 2); + +... + +if (x) +{ + x->~type (); + xml_schema::free (x); +} + </pre> + + <p>The equivalent code fragment for configurations with C++ exceptions + enabled is shown below:</p> + + <pre class="c++"> +xml_schema::alloc_guard g (xml_schema::alloc (sizeof (type))); +type* x = new (g.get ()) type (1, 2); +g.release (); + +... + +if (x) +{ + x->~type (); + xml_schema::free (x); +} + </pre> + + <h2><a name="5.9">5.9 A Minimal Example</a></h2> <p>The following example is a re-implementation of the person records example presented in <a href="#3">Chapter 3, diff --git a/documentation/cxx/serializer/guide/index.xhtml b/documentation/cxx/serializer/guide/index.xhtml index 34ef798..e1fecb4 100644 --- a/documentation/cxx/serializer/guide/index.xhtml +++ b/documentation/cxx/serializer/guide/index.xhtml @@ -298,7 +298,8 @@ <tr><th>6.5</th><td><a href="#6.5">64-bit Integer Type</a></td></tr> <tr><th>6.6</th><td><a href="#6.6">Serializer Reuse</a></td></tr> <tr><th>6.7</th><td><a href="#6.7">Support for Polymorphism</a></td></tr> - <tr><th>6.8</th><td><a href="#6.8">A Minimal Example</a></td></tr> + <tr><th>6.8</th><td><a href="#6.8">Custom Allocators</a></td></tr> + <tr><th>6.9</th><td><a href="#6.9">A Minimal Example</a></td></tr> </table> </td> </tr> @@ -3664,7 +3665,116 @@ main () on root elements requires a number of special actions as shown in the <code>polyroot</code> example.</p> - <h2><a name="6.8">6.8 A Minimal Example</a></h2> + <h2><a name="6.8">6.8 Custom Allocators</a></h2> + + <p>By default the XSD/e runtime and generated code use + the standard operators <code>new</code> and <code>delete</code> + to manage dynamic memory. However, it is possible to instead + use custom allocator functions provided by your application. + To achieve this, configure the XSD/e runtime library to use + custom allocator functions as well as pass the + <code>--custom-allocator</code> option to the XSD/e compiler + when translating your schemas. The signatures of the custom + allocator functions that should be provided by your application + are listed below. Their semantics should be equivalent to the + standard C <code>malloc()</code>, <code>realloc()</code>, and + <code>free()</code> functions.</p> + + <pre class="c++"> +extern "C" void* +xsde_alloc (size_t); + +extern "C" void* +xsde_realloc (void*, size_t); + +extern "C" void +xsde_free (void*); + </pre> + + <p>Note also that when custom allocators are enabled, any + dynamically-allocated object of which the XSD/e runtime + or generated code assume ownership should be allocated + using the custom allocation function. Similarly, if your + application assumes ownership of any dynamically-allocated + object returned by the XSD/e runtime or the generated code, + then such an object should be disposed of using the custom + deallocation function. To help with these tasks the generated + <code>xml_schema</code> namespace defines the following two + helper functions and, if C++ exceptions are enabled, automatic + pointer class:</p> + + <pre class="c++"> +namespace xml_schema +{ + void* + alloc (size_t); + + void + free (void*); + + struct alloc_guard + { + alloc_guard (void*); + ~alloc_guard (); + + void* + get () const; + + void + release (); + + private: + ... + }; +} + </pre> + + <p>If C++ exceptions are disabled, these functions are equivalent + to <code>xsde_alloc()</code> and <code>xsde_free()</code>. + If exceptions are enabled, <code>xml_schema::alloc()</code> + throws <code>std::bad_alloc</code> on memory allocation failure.</p> + + <p>The following code fragment shows how to create and destroy a + dynamically-allocated object with custom allocators when C++ + exceptions are disabled:</p> + + <pre class="c++"> +void* v = xml_schema::alloc (sizeof (type)); + +if (v == 0) +{ + // Handle out of memory condition. +} + +type* x = new (v) type (1, 2); + +... + +if (x) +{ + x->~type (); + xml_schema::free (x); +} + </pre> + + <p>The equivalent code fragment for configurations with C++ exceptions + enabled is shown below:</p> + + <pre class="c++"> +xml_schema::alloc_guard g (xml_schema::alloc (sizeof (type))); +type* x = new (g.get ()) type (1, 2); +g.release (); + +... + +if (x) +{ + x->~type (); + xml_schema::free (x); +} + </pre> + + <h2><a name="6.9">6.9 A Minimal Example</a></h2> <p>The following example is a re-implementation of the person records example presented in <a href="#4">Chapter 4, diff --git a/documentation/xsde.1 b/documentation/xsde.1 index e578afa..a4b55dc 100644 --- a/documentation/xsde.1 +++ b/documentation/xsde.1 @@ -213,6 +213,11 @@ and .B unsigned .BR long . +.IP "\fB\--custom-allocator\fR" +Generate code that performs memory management using custom allocator +functions provided by your application instead of the standard operator +new/delete. + .IP "\fB\--generate-inline\fR" Generate simple functions inline. This option triggers creation of the inline file. diff --git a/documentation/xsde.xhtml b/documentation/xsde.xhtml index d758905..859719e 100644 --- a/documentation/xsde.xhtml +++ b/documentation/xsde.xhtml @@ -195,6 +195,11 @@ built-in XML Schema types are then mapped to <code><b>long</b></code> and <code><b>unsigned long</b></code>.</dd> + <dt><code><b>--custom-allocator</b></code></dt> + <dd>Generate code that performs memory management using custom allocator + functions provided by your application instead of the standard + operator new/delete.</dd> + <dt><code><b>--generate-inline</b></code></dt> <dd>Generate simple functions inline. This option triggers creation of the inline file.</dd> diff --git a/examples/cxx/hybrid/README b/examples/cxx/hybrid/README index 7d9312d..dabc11f 100644 --- a/examples/cxx/hybrid/README +++ b/examples/cxx/hybrid/README @@ -1,7 +1,7 @@ -This directory contains a number of examples that show how to -use the Embedded C++/Hybrid mapping. The following list gives -an overview of each example. See the README files in example -directories for more information on each example. +This directory contains a number of examples that show how to use the +Embedded C++/Hybrid mapping. The following list gives an overview of +each example. See the README files in example directories for more +information on each example. hello A simple "Hello, world!" example that shows how to parse XML @@ -44,6 +44,9 @@ polyroot Shows how to handle XML vocabularies with polymorphic document root elements. +allocator + Shows how to use a custom memory allocator implementation. + custom/ A collection of examples that show how to customize the C++/Hybrid object model by using custom C++ classes instead of or in addition diff --git a/examples/cxx/hybrid/allocator/README b/examples/cxx/hybrid/allocator/README new file mode 100644 index 0000000..f2ea51c --- /dev/null +++ b/examples/cxx/hybrid/allocator/README @@ -0,0 +1,62 @@ +This example shows how to use a custom memory allocator implementation +with the Embedded C++/Hybrid mapping. It is based on the 'minimal' example +(so the support for STL, iostream, and C++ exceptions is disabled) and the +only changes made are to the memory management. + +The example consists of the following files: + +people.xsd + XML Schema which describes a collection of person records. + +people.xml + Sample XML instance document. + +people.hxx +people.cxx + +people-pskel.hxx +people-pskel.cxx +people-pimpl.hxx +people-pimpl.cxx + +people-pskel.hxx +people-pskel.cxx +people-pimpl.hxx +people-pimpl.cxx + Object model (the first pair of files), parser skeletons (the second + pair), parser implementations (the third pair), serializer skeletons + (the fourth pair), and serializer implementations (the fifth pair). + These files are generated by the XSD/e compiler from people.xsd. The + --generate-parser, --generate-serializer, --generate-aggregate, + --no-stl, --no-iostream, and --no-exceptions options were used to + request the generation of the parsing and serialization code as well + as to disable the use of STL, iostream, and C++ exceptions. Furthermore, + the --custom-allocator option was specific to make the generated code + use custom memory management functions instead of the standard new and + delete operators. + +arena.hxx +arena.cxx + An implementation of a simple pooled memory allocator. + +driver.cxx + Driver for the example. Besides the implementation of the main() + function, this file also provides the implementations of the custom + memory management function, xsde_alloc, xsde_realloc, and xsde_free, + that are used by the XSD/e runtime and the generated code. + + The driver first sets up the memory pool using a stack-allocated memory + region. It then calls the parser that constructs the object model from + the input XML file. After that the driver prints the content of the + object model to STDERR. Finally, the driver modifies the object model + and calls the serializer to serialize it back to XML. The implementation + also prints the memory usage statistics after parsing and after + serialization. + +To run the example on the sample XML instance document simply execute: + +$ ./driver people.xml + +The example reads from STDIN if input file is not specified: + +$ ./driver <people.xml diff --git a/examples/cxx/hybrid/allocator/arena.cxx b/examples/cxx/hybrid/allocator/arena.cxx new file mode 100644 index 0000000..facb852 --- /dev/null +++ b/examples/cxx/hybrid/allocator/arena.cxx @@ -0,0 +1,167 @@ +// file : examples/cxx/hybrid/allocator/arena.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : not copyrighted - public domain + +#include <stdio.h> +#include <string.h> // memcpy + +#include "arena.hxx" + +arena:: +arena (void* memory, size_t size) + : alloc_count_ (0), + realloc_count_ (0), + free_count_ (0), + cur_allocated_ (0), + max_allocated_ (0) +{ + head_ = static_cast<block*> (memory); + head_->cap = size - sizeof (block); + head_->next = 0; + head_->used = false; +} + +void* arena:: +allocate (size_t size) +{ + block* b = head_; + + while (b != 0) + { + if (!b->used) + { + if (b->cap >= size) + { + // See if it makes sense to fragment this block. + // + if (b->cap - size >= sizeof (block) * 2) + { + block* b1 = reinterpret_cast<block*> ( + reinterpret_cast<char*> (b) + sizeof (block) + size); + + b1->cap = b->cap - size - sizeof (block); + b1->next = b->next; + b1->used = false; + + b->next = b1; + b->cap = size; + } + + b->used = true; + b->size = size; + + alloc_count_++; + cur_allocated_ += size; + + if (cur_allocated_ > max_allocated_) + max_allocated_ = cur_allocated_; + + return b + 1; + } + + // This block is not big enough. See if we can merge it + // with the next block. + // + if (b->next != 0 && !b->next->used) + { + block* b1 = b->next; + b->cap += b1->cap + sizeof (block); + b->next = b1->next; + + // Try the merged block again. + // + continue; + } + } + + // This block is either in use or not big enough. Continue + // searching. + // + b = b->next; + } + + return 0; +} + +void* arena:: +reallocate (void* p, size_t size) +{ + // If the passed pointer is NULL, reallocate is equivalent to + // allocate. + // + if (!p) + return allocate (size); + + block* b = static_cast<block*> (p) - 1; + + // If the passed size is NULL, reallocate is equivalent to free. + // + if (size == 0) + { + free (p); + return 0; + } + + // If this block is not large enough to satisfy the request, try to + // merge it with the next block(s). + // + while (b->cap < size && b->next != 0 && !b->next->used) + { + block* b1 = b->next; + b->cap += b1->cap + sizeof (block); + b->next = b1->next; + } + + // If this block is now large enough then we can reuse the same + // memory region. + // + if (b->cap >= size) + { + realloc_count_++; + cur_allocated_ += size - b->size; + + if (cur_allocated_ > max_allocated_) + max_allocated_ = cur_allocated_; + + b->size = size; + return p; + } + + // Otherwise allocate a new block and copy the data over. + // + void* r = allocate (size); + + if (r) + { + memcpy (r, p, b->size); + free (p); + } + + return r; +} + +void arena:: +free (void* p) +{ + if (p) + { + block* b = static_cast<block*> (p) - 1; + + cur_allocated_ -= b->size; + free_count_++; + + b->used = false; + } +} + +void arena:: +print_statistics () +{ + printf ("\n"); + printf ("allocations: %lu\n", alloc_count_); + printf ("reallocations: %lu\n", realloc_count_); + printf ("deallocations: %lu\n", free_count_); + printf ("currently in use: %lu bytes\n", cur_allocated_); + printf ("maximum in use: %lu bytes\n", max_allocated_); + printf ("\n"); +} diff --git a/examples/cxx/hybrid/allocator/arena.hxx b/examples/cxx/hybrid/allocator/arena.hxx new file mode 100644 index 0000000..0463a38 --- /dev/null +++ b/examples/cxx/hybrid/allocator/arena.hxx @@ -0,0 +1,52 @@ +// file : examples/cxx/hybrid/allocator/arena.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : not copyrighted - public domain + +#ifndef ARENA_HXX +#define ARENA_HXX + +#include <stddef.h> // size_t + +// Sample pooled memory arena. The primary goal here is to provide a +// simple, if naive, implementation. As a result, it probably shouldn't +// be used in production. +// +class arena +{ +public: + arena (void* memory, size_t size); + + void* + allocate (size_t); + + void* + reallocate (void*, size_t); + + void + free (void*); + + void + print_statistics (); + +private: + struct block + { + size_t cap; // block capacity + size_t size; // allocated size + block* next; // next block + size_t used; // used flag + }; + + block* head_; // Linked list of blocks. + + // Statistics. + // + size_t alloc_count_; + size_t realloc_count_; + size_t free_count_; + + size_t cur_allocated_; + size_t max_allocated_; +}; + +#endif // ARENA_HXX diff --git a/examples/cxx/hybrid/allocator/driver.cxx b/examples/cxx/hybrid/allocator/driver.cxx new file mode 100644 index 0000000..933784e --- /dev/null +++ b/examples/cxx/hybrid/allocator/driver.cxx @@ -0,0 +1,325 @@ +// file : examples/cxx/hybrid/allocator/driver.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : not copyrighted - public domain + +#include <stdio.h> + +#include "arena.hxx" + +#include "people.hxx" +#include "people-pimpl.hxx" +#include "people-simpl.hxx" + +// eVC++ 4.0 does not like using xml_schema::strdupx; Note also that +// xml_schema::strdupx will use the custom allocator to allocate the +// memory. +// +inline char* +strdupx (const char* s) +{ + return xml_schema::strdupx (s); +} + +// Implementation of the XSD/e custom allocator functions. +// +arena* xsde_arena; + +extern "C" void* +xsde_alloc (size_t n) +{ + return xsde_arena->allocate (n); +} + +extern "C" void* +xsde_realloc (void* p, size_t n) +{ + return xsde_arena->reallocate (p, n); +} + +extern "C" void +xsde_free (void* p) +{ + return xsde_arena->free (p); +} + +// +// +struct writer: xml_schema::writer +{ + virtual bool + write (const char* s, size_t n) + { + return fwrite (s, n, 1, stdout) == 1; + } + + virtual bool + flush () + { + return fflush (stdout) == 0; + } +}; + +int +main (int argc, char* argv[]) +{ + const char* input; + + if (argc < 2) + { + input = "STDIN"; + fprintf (stderr, "XML file not specified, reading from STDIN\n"); + } + else + input = argv[1]; + + // Set up the memory pool. + // + char pool[65536 * 2]; + arena ar (pool, sizeof (pool)); + xsde_arena = &ar; + + // Open the file or use STDIN. + // + FILE* f = argc > 1 ? fopen (argv[1], "rb") : stdin; + + if (f == 0) + { + fprintf (stderr, "%s: unable to open\n", input); + return 1; + } + + // Parse. + // + using xml_schema::parser_error; + + parser_error pe; + bool io_error = false; + people* ppl = 0; + + do + { + people_paggr people_p; + xml_schema::document_pimpl doc_p (people_p.root_parser (), + people_p.root_name ()); + + if (pe = doc_p._error ()) + break; + + people_p.pre (); + + if (pe = people_p._error ()) + break; + + char buf[4096]; + + do + { + size_t s = fread (buf, 1, sizeof (buf), f); + + if (s != sizeof (buf) && ferror (f)) + { + io_error = true; + break; + } + + doc_p.parse (buf, s, feof (f) != 0); + pe = doc_p._error (); + + } while (!pe && !feof (f)); + + if (io_error || pe) + break; + + ppl = people_p.post (); + + pe = people_p._error (); + + } while (false); + + if (argc > 1) + fclose (f); + + // Handle parsing errors. + // + if (io_error) + { + fprintf (stderr, "%s: read failure\n", input); + return 1; + } + + if (pe) + { + switch (pe.type ()) + { + case parser_error::sys: + { + fprintf (stderr, "%s: %s\n", input, pe.sys_text ()); + break; + } + case parser_error::xml: + { + fprintf (stderr, "%s:%lu:%lu: %s\n", + input, pe.line (), pe.column (), pe.xml_text ()); + break; + } +#ifdef XSDE_PARSER_VALIDATION + case parser_error::schema: + { + fprintf (stderr, "%s:%lu:%lu: %s\n", + input, pe.line (), pe.column (), pe.schema_text ()); + break; + } +#endif + case parser_error::app: + { + fprintf (stderr, "%s:%lu:%lu: application error %d\n", + input, pe.line (), pe.column (), pe.app_code ()); + break; + } + default: + break; + } + + return 1; + } + + // Print memory usage statistics. + // + xsde_arena->print_statistics (); + + // Print what we've got. + // + people::person_sequence& ps = ppl->person (); + + for (people::person_const_iterator i = ps.begin (); i != ps.end (); ++i) + { + printf ("first: %s\n" "last: %s\n" "gender: %s\n" "age: %hu\n\n", + i->first_name (), + i->last_name (), + i->gender ().string (), + i->age ()); + } + + // Remove people that are younger than 30. + // + for (people::person_iterator j = ps.begin (); j != ps.end ();) + { + if (j->age () < 30) + j = ps.erase (j); + else + ++j; + } + + // Insert a new person. Note that we need to allocate the + // object using the XSD/e allocator. + // + { + void* mem = xsde_alloc (sizeof (person)); + + if (!mem) + { + fprintf (stderr, "no memory\n"); + return 1; + } + + person* p = new (mem) person; + + p->first_name (strdupx ("Joe")); // No out of memory check. + p->last_name (strdupx ("Dirt")); // No out of memory check. + p->age (36); + p->gender (gender::male); + + ps.insert (ps.begin (), p); // No out of memory check. + } + + // Serialize. + // + using xml_schema::serializer_error; + + serializer_error se; + writer w; + + do + { + people_saggr people_s; + xml_schema::document_simpl doc_s (people_s.root_serializer (), + people_s.root_name ()); + + doc_s.add_no_namespace_schema ("people.xsd"); + + se = doc_s._error (); + if (se) + break; + + people_s.pre (*ppl); + + se = people_s._error (); + if (se) + break; + + doc_s.serialize (w, xml_schema::document_simpl::pretty_print); + + se = doc_s._error (); + if (se) + break; + + people_s.post (); + + se = people_s._error (); + + } while (false); + + + // Delete the people object model. Here we can explicitly call the + // destructor and then free the memory using the custom allocator + // function. Alternatively, if the arena is used to hold only one + // object model, then we can simply destroy the arena since all + // the dynamic memory allocated by the object model is inside + // this arena. + // + // + ppl->~people (); + xsde_free (ppl); + + // Print memory usage statistics. + // + xsde_arena->print_statistics (); + xsde_arena = 0; + + // Handle serializer errors. + // + if (se) + { + switch (se.type ()) + { + case serializer_error::sys: + { + fprintf (stderr, "error: %s\n", se.sys_text ()); + break; + } + case serializer_error::xml: + { + fprintf (stderr, "error: %s\n", se.xml_text ()); + break; + } +#ifdef XSDE_SERIALIZER_VALIDATION + case serializer_error::schema: + { + fprintf (stderr, "error: %s\n", se.schema_text ()); + break; + } +#endif + case serializer_error::app: + { + fprintf (stderr, "application error: %d\n", se.app_code ()); + break; + } + default: + break; + } + + return 1; + } + + return 0; +} diff --git a/examples/cxx/hybrid/allocator/makefile b/examples/cxx/hybrid/allocator/makefile new file mode 100644 index 0000000..d6a1cd6 --- /dev/null +++ b/examples/cxx/hybrid/allocator/makefile @@ -0,0 +1,108 @@ +# file : examples/cxx/hybrid/allocator/makefile +# author : Boris Kolpackov <boris@codesynthesis.com> +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make + +xsd := people.xsd +cxx := driver.cxx arena.cxx + +obj := $(addprefix $(out_base)/,\ +$(cxx:.cxx=.o) \ +$(xsd:.xsd=.o) \ +$(xsd:.xsd=-pskel.o) \ +$(xsd:.xsd=-pimpl.o) \ +$(xsd:.xsd=-sskel.o) \ +$(xsd:.xsd=-simpl.o)) + +dep := $(obj:.o=.o.d) + +xsde.l := $(out_root)/libxsde/xsde/xsde.l +xsde.l.cpp-options := $(out_root)/libxsde/xsde/xsde.l.cpp-options + +driver := $(out_base)/driver +dist := $(out_base)/.dist +dist-win := $(out_base)/.dist-win +clean := $(out_base)/.clean + +# Build. +# +$(driver): $(obj) $(xsde.l) + +$(obj) $(dep): $(xsde.l.cpp-options) + +genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.cxx) \ + $(xsd:.xsd=-pskel.hxx) $(xsd:.xsd=-pskel.cxx) \ + $(xsd:.xsd=-pimpl.hxx) $(xsd:.xsd=-pimpl.cxx) \ + $(xsd:.xsd=-sskel.hxx) $(xsd:.xsd=-sskel.cxx) \ + $(xsd:.xsd=-simpl.hxx) $(xsd:.xsd=-simpl.cxx) + +gen := $(addprefix $(out_base)/,$(genf)) + +$(gen): $(out_root)/xsde/xsde +$(gen): xsde := $(out_root)/xsde/xsde +$(gen): xsde_options += --generate-parser --generate-serializer \ +--generate-aggregate + +$(call include-dep,$(dep)) + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + + +# Dist. +# +dist-common := $(out_base)/.dist-common +$(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base)) + +$(dist-common): + $(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx) + $(call install-data,$(src_base)/arena.cxx,$(dist_prefix)/$(path)/arena.cxx) + $(call install-data,$(src_base)/arena.hxx,$(dist_prefix)/$(path)/arena.hxx) + $(call install-data,$(src_base)/people.xsd,$(dist_prefix)/$(path)/people.xsd) + $(call install-data,$(src_base)/people.xml,$(dist_prefix)/$(path)/people.xml) + +$(dist): $(dist-common) + $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README) + +$(dist-win): $(dist-common) + $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt) + $(call message,,unix2dos $(dist_prefix)/$(path)/README.txt) + + +# Clean. +# +$(clean): $(driver).o.clean \ + $(addsuffix .cxx.clean,$(obj)) \ + $(addsuffix .cxx.clean,$(dep)) \ + $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean)) + + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(gen): | $(out_base)/.gitignore +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(bld_root)/install.make) +$(call include,$(scf_root)/xsde/hybrid/xsd-cxx.make) + + +# Dependencies. +# +$(call import,$(src_root)/xsde/makefile) +$(call import,$(src_root)/libxsde/xsde/makefile) diff --git a/examples/cxx/hybrid/allocator/people.xml b/examples/cxx/hybrid/allocator/people.xml new file mode 100644 index 0000000..ad4135a --- /dev/null +++ b/examples/cxx/hybrid/allocator/people.xml @@ -0,0 +1,28 @@ +<?xml version="1.0"?> + +<!-- + +file : examples/cxx/hybrid/allocator/people.xml +author : Boris Kolpackov <boris@codesynthesis.com> +copyright : not copyrighted - public domain + +--> + +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="people.xsd"> + + <person> + <first-name>John</first-name> + <last-name>Doe</last-name> + <gender>male</gender> + <age>32</age> + </person> + + <person> + <first-name>Jane</first-name> + <last-name>Doe</last-name> + <gender>female</gender> + <age>28</age> + </person> + +</people> diff --git a/examples/cxx/hybrid/allocator/people.xsd b/examples/cxx/hybrid/allocator/people.xsd new file mode 100644 index 0000000..131be7b --- /dev/null +++ b/examples/cxx/hybrid/allocator/people.xsd @@ -0,0 +1,37 @@ +<?xml version="1.0"?> + +<!-- + +file : examples/cxx/hybrid/allocator/people.xsd +author : Boris Kolpackov <boris@codesynthesis.com> +copyright : not copyrighted - public domain + +--> + +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + + <xsd:simpleType name="gender"> + <xsd:restriction base="xsd:string"> + <xsd:enumeration value="male"/> + <xsd:enumeration value="female"/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:complexType name="person"> + <xsd:sequence> + <xsd:element name="first-name" type="xsd:string"/> + <xsd:element name="last-name" type="xsd:string"/> + <xsd:element name="gender" type="gender"/> + <xsd:element name="age" type="xsd:unsignedShort"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="people"> + <xsd:sequence> + <xsd:element name="person" type="person" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="people" type="people"/> + +</xsd:schema> diff --git a/examples/cxx/hybrid/makefile b/examples/cxx/hybrid/makefile index c82a2ec..8bdb2de 100644 --- a/examples/cxx/hybrid/makefile +++ b/examples/cxx/hybrid/makefile @@ -5,8 +5,20 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make -all_examples := binary compositors custom hello multiroot polymorphism \ -polyroot streaming library wildcard filter minimal +all_examples := \ +allocator \ +binary \ +compositors \ +custom \ +hello \ +multiroot \ +polymorphism \ +polyroot \ +streaming \ +library \ +wildcard \ +filter \ +minimal build_examples := binary compositors custom @@ -29,9 +41,15 @@ endif ifeq ($(xsde_stl),n) ifeq ($(xsde_exceptions),n) build_examples += minimal + +ifeq ($(xsde_custom_allocator),y) +build_examples += allocator +endif + endif endif + default := $(out_base)/ dist := $(out_base)/.dist dist-win := $(out_base)/.dist-win diff --git a/libxsde/xsde/allocator.c b/libxsde/xsde/allocator.c new file mode 100644 index 0000000..7874295 --- /dev/null +++ b/libxsde/xsde/allocator.c @@ -0,0 +1,32 @@ +// file : xsde/allocator.c +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +// This is the default implementation of the custom allocator functions. +// It is primarily useful for testing when XSD/e is configured with custom +// allocators. You can also replace this implementation with your own if +// you would like to test with that. +// + +#include <stdlib.h> + +#include <xsde/allocator.h> + +void* +xsde_alloc (size_t n) +{ + return malloc (n); +} + +void* +xsde_realloc (void* p, size_t n) +{ + return realloc (p, n); +} + +void +xsde_free (void* p) +{ + free (p); +} diff --git a/libxsde/xsde/allocator.h b/libxsde/xsde/allocator.h new file mode 100644 index 0000000..771f893 --- /dev/null +++ b/libxsde/xsde/allocator.h @@ -0,0 +1,27 @@ +// file : xsde/allocator.h +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSDE_ALLOCATOR_HXX +#define XSDE_ALLOCATOR_HXX + +#include <stddef.h> // size_t + +#ifdef __cplusplus +extern "C" +{ +#endif + +// Custom allocator functions. Your implementation should always return +// 0 on failure, regardless of whether exceptions are enabled or not. +// +void* xsde_alloc (size_t); +void* xsde_realloc (void*, size_t); +void xsde_free (void*); + +#ifdef __cplusplus +} +#endif + +#endif // XSDE_ALLOCATOR_HXX diff --git a/libxsde/xsde/c/expat/xmlparse.c b/libxsde/xsde/c/expat/xmlparse.c index 6eac810..19fa39a 100644 --- a/libxsde/xsde/c/expat/xmlparse.c +++ b/libxsde/xsde/c/expat/xmlparse.c @@ -12,6 +12,10 @@ #include "expat.h" +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/allocator.h> +#endif + #ifdef XML_UNICODE #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX #define XmlConvert XmlUtf16Convert @@ -702,6 +706,16 @@ parserCreate(const XML_Char *encodingName, } else { XML_Memory_Handling_Suite *mtemp; + +#ifdef XSDE_CUSTOM_ALLOCATOR + parser = (XML_Parser)xsde_alloc(sizeof(struct XML_ParserStruct)); + if (parser != NULL) { + mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); + mtemp->malloc_fcn = xsde_alloc; + mtemp->realloc_fcn = xsde_realloc; + mtemp->free_fcn = xsde_free; + } +#else parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); if (parser != NULL) { mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); @@ -709,6 +723,7 @@ parserCreate(const XML_Char *encodingName, mtemp->realloc_fcn = realloc; mtemp->free_fcn = free; } +#endif } if (!parser) diff --git a/libxsde/xsde/c/genx/genx.c b/libxsde/xsde/c/genx/genx.c index 0c0ed17..6596f81 100644 --- a/libxsde/xsde/c/genx/genx.c +++ b/libxsde/xsde/c/genx/genx.c @@ -10,8 +10,14 @@ #include <stdlib.h> #include <string.h> +#include <xsde/config.h> + #include "genx.h" +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/allocator.h> +#endif + #define Boolean int #define True 1 #define False 0 @@ -156,7 +162,11 @@ static void * allocate(genxWriter w, int bytes) if (w->alloc) return (void *) (*w->alloc)(w->userData, bytes); else +#ifdef XSDE_CUSTOM_ALLOCATOR + return (void *) xsde_alloc(bytes); +#else return (void *) malloc(bytes); +#endif } static void deallocate(genxWriter w, void * data) @@ -164,7 +174,11 @@ static void deallocate(genxWriter w, void * data) if (w->dealloc) (*w->dealloc)(w->userData, data); else if (w->alloc == NULL) +#ifdef XSDE_CUSTOM_ALLOCATOR + xsde_free(data); +#else free(data); +#endif } static utf8 copy(genxWriter w, constUtf8 from) @@ -527,7 +541,11 @@ genxWriter genxNew(void * (* alloc)(void * userData, int bytes), if (alloc) w = (genxWriter) (*alloc)(userData, sizeof(struct genxWriter_rec)); else +#ifdef XSDE_CUSTOM_ALLOCATOR + w = (genxWriter) xsde_alloc(sizeof(struct genxWriter_rec)); +#else w = (genxWriter) malloc(sizeof(struct genxWriter_rec)); +#endif if (w == NULL) return NULL; diff --git a/libxsde/xsde/cxx/allocator.cxx b/libxsde/xsde/cxx/allocator.cxx new file mode 100644 index 0000000..0e7fb79 --- /dev/null +++ b/libxsde/xsde/cxx/allocator.cxx @@ -0,0 +1,26 @@ +// file : xsde/cxx/allocator.cxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xsde/cxx/config.hxx> +#include <xsde/cxx/allocator.hxx> + +namespace xsde +{ + namespace cxx + { +#ifdef XSDE_EXCEPTIONS + void* + alloc (size_t n) + { + void* p = xsde_alloc (n); + + if (p == 0) + throw std::bad_alloc (); + + return p; + } +#endif + } +} diff --git a/libxsde/xsde/cxx/allocator.hxx b/libxsde/xsde/cxx/allocator.hxx new file mode 100644 index 0000000..248ee55 --- /dev/null +++ b/libxsde/xsde/cxx/allocator.hxx @@ -0,0 +1,49 @@ +// file : xsde/cxx/allocator.hxx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSDE_CXX_ALLOCATOR_HXX +#define XSDE_CXX_ALLOCATOR_HXX + +#include <stddef.h> // size_t +#include <new> // placement new + +#include <xsde/cxx/config.hxx> + +namespace xsde +{ + namespace cxx + { + // Allocate a memory block using custom allocator. If exceptions + // are enabled this function throws std::bad_alloc on failure. + // Otherwise it returns 0. + // + void* + alloc (size_t); + + void + free (void*); + +#ifdef XSDE_EXCEPTIONS + struct alloc_guard + { + alloc_guard (void* p) : p_ (p) {} + ~alloc_guard () { if (p_) cxx::free (p_); } + + void* + get () const { return p_; } + + void + release () { p_ = 0; } + + private: + void* p_; + }; +#endif + } +} + +#include <xsde/cxx/allocator.ixx> + +#endif // XSDE_CXX_ALLOCATOR_HXX diff --git a/libxsde/xsde/cxx/allocator.ixx b/libxsde/xsde/cxx/allocator.ixx new file mode 100644 index 0000000..9f3d50b --- /dev/null +++ b/libxsde/xsde/cxx/allocator.ixx @@ -0,0 +1,27 @@ +// file : xsde/cxx/allocator.ixx +// author : Boris Kolpackov <boris@codesynthesis.com> +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include <xsde/allocator.h> + +namespace xsde +{ + namespace cxx + { +#ifndef XSDE_EXCEPTIONS + inline void* + alloc (size_t n) + { + return xsde_alloc (n); + } +#endif + + inline void + free (void* p) + { + if (p) + xsde_free (p); + } + } +} diff --git a/libxsde/xsde/cxx/buffer.cxx b/libxsde/xsde/cxx/buffer.cxx index fbaa809..d9102ae 100644 --- a/libxsde/xsde/cxx/buffer.cxx +++ b/libxsde/xsde/cxx/buffer.cxx @@ -88,13 +88,21 @@ namespace xsde } else { - char* data = reinterpret_cast<char*> (operator new (capacity)); +#ifndef XSDE_CUSTOM_ALLOCATOR + char* data = static_cast<char*> (operator new (capacity)); +#else + char* data = static_cast<char*> (alloc (capacity)); +#endif if (copy && size_ > 0) memcpy (data, data_, size_); if (data_) +#ifndef XSDE_CUSTOM_ALLOCATOR operator delete (data_); +#else + cxx::free (data_); +#endif data_ = data; capacity_ = capacity; @@ -118,7 +126,11 @@ namespace xsde } else { - char* data = reinterpret_cast<char*> (operator new (capacity)); +#ifndef XSDE_CUSTOM_ALLOCATOR + char* data = static_cast<char*> (operator new (capacity)); +#else + char* data = static_cast<char*> (alloc (capacity)); +#endif if (data != 0) { @@ -126,7 +138,11 @@ namespace xsde memcpy (data, data_, size_); if (data_) +#ifndef XSDE_CUSTOM_ALLOCATOR operator delete (data_); +#else + cxx::free (data_); +#endif data_ = data; capacity_ = capacity; diff --git a/libxsde/xsde/cxx/buffer.ixx b/libxsde/xsde/cxx/buffer.ixx index 51e3f07..2229396 100644 --- a/libxsde/xsde/cxx/buffer.ixx +++ b/libxsde/xsde/cxx/buffer.ixx @@ -5,6 +5,10 @@ #include <string.h> // memcmp +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -15,7 +19,11 @@ namespace xsde ~buffer () { if (data_) +#ifndef XSDE_CUSTOM_ALLOCATOR operator delete (data_); +#else + cxx::free (data_); +#endif } inline buffer:: @@ -41,7 +49,11 @@ namespace xsde } if (data_) +#ifndef XSDE_CUSTOM_ALLOCATOR operator delete (data_); +#else + cxx::free (data_); +#endif data_ = reinterpret_cast<char*> (data); size_ = size; @@ -210,4 +222,3 @@ namespace xsde } } } - diff --git a/libxsde/xsde/cxx/hashmap.cxx b/libxsde/xsde/cxx/hashmap.cxx index b633cbd..f87ebbf 100644 --- a/libxsde/xsde/cxx/hashmap.cxx +++ b/libxsde/xsde/cxx/hashmap.cxx @@ -7,6 +7,10 @@ #include <xsde/cxx/hashmap.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -76,10 +80,18 @@ namespace xsde for (size_t i = 0; i < bcount_; ++i) { if (buckets_[i]) +#ifndef XSDE_CUSTOM_ALLOCATOR operator delete (buckets_[i]); +#else + cxx::free (buckets_[i]); +#endif } +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] buckets_; +#else + cxx::free (buckets_); // POD. +#endif #ifndef XSDE_EXCEPTIONS } @@ -95,7 +107,11 @@ namespace xsde error_ = error_none; #endif +#ifndef XSDE_CUSTOM_ALLOCATOR buckets_ = new bucket*[bcount_]; +#else + buckets_ = static_cast<bucket**> (alloc (bcount_ * sizeof (bucket*))); +#endif #ifndef XSDE_EXCEPTIONS if (buckets_ == 0) @@ -118,8 +134,13 @@ namespace xsde // No elements in this bucket yet. Start with capacity for 2 // elements. // +#ifndef XSDE_CUSTOM_ALLOCATOR p = static_cast<bucket*> ( operator new (sizeof (bucket) + 2 * (sizeof (element) + esize_))); +#else + p = static_cast<bucket*> ( + alloc (sizeof (bucket) + 2 * (sizeof (element) + esize_))); +#endif #ifndef XSDE_EXCEPTIONS if (p == 0) @@ -137,8 +158,14 @@ namespace xsde // No more space in this bucket. Create a bigger bucket. // size_t c = p->size_ * 2; + +#ifndef XSDE_CUSTOM_ALLOCATOR bucket* n = static_cast<bucket*> ( operator new (sizeof (bucket) + c * (sizeof (element) + esize_))); +#else + bucket* n = static_cast<bucket*> ( + alloc (sizeof (bucket) + c * (sizeof (element) + esize_))); +#endif #ifndef XSDE_EXCEPTIONS if (n == 0) @@ -155,7 +182,11 @@ namespace xsde memcpy (dst, src, p->size_ * (sizeof (element) + esize_)); +#ifndef XSDE_CUSTOM_ALLOCATOR operator delete (p); +#else + cxx::free (p); +#endif p = n; } diff --git a/libxsde/xsde/cxx/hashmap.hxx b/libxsde/xsde/cxx/hashmap.hxx index 9b85fa4..c2562e1 100644 --- a/libxsde/xsde/cxx/hashmap.hxx +++ b/libxsde/xsde/cxx/hashmap.hxx @@ -117,6 +117,8 @@ namespace xsde hash (size_t hash, const char*, size_t n); protected: + // Keep these types POD. + // struct bucket { size_t size_; diff --git a/libxsde/xsde/cxx/hybrid/base.hxx b/libxsde/xsde/cxx/hybrid/base.hxx index 1a238a1..89431a2 100644 --- a/libxsde/xsde/cxx/hybrid/base.hxx +++ b/libxsde/xsde/cxx/hybrid/base.hxx @@ -12,6 +12,10 @@ # include <string.h> // strcmp #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -566,17 +570,34 @@ namespace xsde struct string_base { string_base () : x_ (0) {} - ~string_base () {delete[] x_;} + ~string_base () + { +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] x_; +#else + cxx::free (x_); +#endif + } const char* base_value () const {return x_;} char* base_value () {return x_;} - void base_value (char* x) {delete[] x_; x_ = x;} + + void base_value (char* x) + { +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] x_; +#else + cxx::free (x_); +#endif + x_ = x; + } + char* base_value_detach () {char* r = x_; x_ = 0; return r;} operator const char* () const {return x_;} operator char* () {return x_;} - string_base& operator= (char* x) {delete[] x_; x_ = x; return *this;} + string_base& operator= (char* x) {base_value (x); return *this;} protected: char* x_; diff --git a/libxsde/xsde/cxx/hybrid/cdr/istream.cxx b/libxsde/xsde/cxx/hybrid/cdr/istream.cxx index 684df2d..06e26e6 100644 --- a/libxsde/xsde/cxx/hybrid/cdr/istream.cxx +++ b/libxsde/xsde/cxx/hybrid/cdr/istream.cxx @@ -17,7 +17,14 @@ namespace xsde struct str_guard { str_guard (char* s) : s_ (s) {} - ~str_guard () {delete[] s_;} + ~str_guard () + { +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] s_; +#else + cxx::free (s_); +#endif + } private: char* s_; @@ -70,7 +77,11 @@ namespace xsde return false; x = v; +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] v; +#else + cxx::free (v); +#endif return true; } #else diff --git a/libxsde/xsde/cxx/hybrid/cdr/istream.txx b/libxsde/xsde/cxx/hybrid/cdr/istream.txx index 58cd98b..f1d8d6c 100644 --- a/libxsde/xsde/cxx/hybrid/cdr/istream.txx +++ b/libxsde/xsde/cxx/hybrid/cdr/istream.txx @@ -3,6 +3,10 @@ // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -73,7 +77,14 @@ namespace xsde while (n--) { +#ifndef XSDE_CUSTOM_ALLOCATOR T* p = new T; +#else + T* p = static_cast<T*> (alloc (sizeof (T))); + alloc_guard pg (p); + new (p) T; + pg.release (); +#endif typename var_sequence<T>::guard g (p); s >> *p; g.release (); @@ -159,14 +170,28 @@ namespace xsde while (n--) { +#ifndef XSDE_CUSTOM_ALLOCATOR T* p = new T; if (p == 0) return false; +#else + void* v = alloc (sizeof (T)); + + if (v == 0) + return false; + + T* p = new (v) T; // c-tor cannot fail +#endif if (!(s >> *p)) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete p; +#else + p->~T (); + cxx::free (p); +#endif return false; } diff --git a/libxsde/xsde/cxx/hybrid/sequence.hxx b/libxsde/xsde/cxx/hybrid/sequence.hxx index 451c76d..fa5c697 100644 --- a/libxsde/xsde/cxx/hybrid/sequence.hxx +++ b/libxsde/xsde/cxx/hybrid/sequence.hxx @@ -22,6 +22,10 @@ # include <xsde/cxx/string-sequence.hxx> #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -831,7 +835,15 @@ namespace xsde public: struct guard { - ~guard () { delete p_; } + ~guard () + { +#ifndef XSDE_CUSTOM_ALLOCATOR + delete p_; +#else + cxx::free (p_); +#endif + } + guard (T* p) : p_ (p) {} void diff --git a/libxsde/xsde/cxx/hybrid/sequence.ixx b/libxsde/xsde/cxx/hybrid/sequence.ixx index 6029b76..1ec2a4c 100644 --- a/libxsde/xsde/cxx/hybrid/sequence.ixx +++ b/libxsde/xsde/cxx/hybrid/sequence.ixx @@ -551,7 +551,15 @@ namespace xsde inline void var_sequence<T>:: pop_back () { - delete static_cast<T**> (data_)[size_ - 1]; + T* x = static_cast<T**> (data_)[size_ - 1]; + +#ifndef XSDE_CUSTOM_ALLOCATOR + delete x; +#else + if (x) + x->~T (); + cxx::free (x); +#endif --size_; } @@ -559,7 +567,15 @@ namespace xsde inline var_iterator<T> var_sequence<T>:: erase (iterator i) { - delete *i.i_; + T* x = *i.i_; + +#ifndef XSDE_CUSTOM_ALLOCATOR + delete x; +#else + if (x) + x->~T (); + cxx::free (x); +#endif if (i.i_ != static_cast<T**> (data_) + (size_ - 1)) erase_ (i.i_, sizeof (T*), 0); @@ -582,7 +598,15 @@ namespace xsde inline void var_sequence<T>:: attach (iterator i, T* x) { - delete *i.i_; + T* t = *i.i_; + +#ifndef XSDE_CUSTOM_ALLOCATOR + delete t; +#else + if (t) + t->~T (); + cxx::free (t); +#endif *i.i_ = x; } @@ -632,7 +656,15 @@ namespace xsde if (r == error_none) static_cast<T**> (data_)[size_++] = x; else + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete x; +#else + if (x) + x->~T (); + cxx::free (x); +#endif + } return r; } @@ -650,7 +682,13 @@ namespace xsde } else { +#ifndef XSDE_CUSTOM_ALLOCATOR delete x; +#else + if (x) + x->~T (); + cxx::free (x); +#endif return error_no_memory; } } @@ -669,7 +707,13 @@ namespace xsde } else { +#ifndef XSDE_CUSTOM_ALLOCATOR delete x; +#else + if (x) + x->~T (); + cxx::free (x); +#endif return error_no_memory; } } diff --git a/libxsde/xsde/cxx/hybrid/sequence.txx b/libxsde/xsde/cxx/hybrid/sequence.txx index 4fd3a85..b79e9d5 100644 --- a/libxsde/xsde/cxx/hybrid/sequence.txx +++ b/libxsde/xsde/cxx/hybrid/sequence.txx @@ -152,7 +152,17 @@ namespace xsde clear () { for (size_t i = 0; i < size_; ++i) - delete static_cast<T**> (data_)[i]; + { + T* x = static_cast<T**> (data_)[i]; + +#ifndef XSDE_CUSTOM_ALLOCATOR + delete x; +#else + if (x) + x->~T (); + cxx::free (x); +#endif + } size_ = 0; } diff --git a/libxsde/xsde/cxx/hybrid/xdr/istream.cxx b/libxsde/xsde/cxx/hybrid/xdr/istream.cxx index 2f870d0..e31fb7f 100644 --- a/libxsde/xsde/cxx/hybrid/xdr/istream.cxx +++ b/libxsde/xsde/cxx/hybrid/xdr/istream.cxx @@ -23,7 +23,7 @@ namespace xsde throw xdr_exception (); x.clear (); - + if (n != 0) { x.resize (n); @@ -42,11 +42,19 @@ namespace xsde if (!xdr_u_int (&xdr_, &n)) throw xdr_exception (); +#ifndef XSDE_CUSTOM_ALLOCATOR x = new char[n + 1]; +#else + x = static_cast<char*> (alloc (n + 1)); +#endif if (!xdr_opaque (&xdr_, x, n)) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] x; +#else + cxx::free (x); +#endif throw xdr_exception (); } @@ -80,14 +88,14 @@ namespace xsde return false; x.clear (); - + if (n != 0) { x.resize (n); char* p = const_cast<char*> (x.c_str ()); return xdr_opaque (&xdr_, p, n); } - + return true; } #else @@ -99,14 +107,21 @@ namespace xsde if (!xdr_u_int (&xdr_, &n)) return false; +#ifndef XSDE_CUSTOM_ALLOCATOR x = new char[n + 1]; - +#else + x = static_cast<char*> (alloc (n + 1)); +#endif if (x == 0) return false; if (!xdr_opaque (&xdr_, x, n)) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] x; +#else + cxx::free (x); +#endif return false; } diff --git a/libxsde/xsde/cxx/hybrid/xdr/istream.txx b/libxsde/xsde/cxx/hybrid/xdr/istream.txx index 8f1d646..876befd 100644 --- a/libxsde/xsde/cxx/hybrid/xdr/istream.txx +++ b/libxsde/xsde/cxx/hybrid/xdr/istream.txx @@ -3,6 +3,10 @@ // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -73,7 +77,14 @@ namespace xsde while (n--) { +#ifndef XSDE_CUSTOM_ALLOCATOR T* p = new T; +#else + T* p = static_cast<T*> (alloc (sizeof (T))); + alloc_guard pg (p); + new (p) T; + pg.release (); +#endif typename var_sequence<T>::guard g (p); s >> *p; g.release (); @@ -159,14 +170,27 @@ namespace xsde while (n--) { +#ifndef XSDE_CUSTOM_ALLOCATOR T* p = new T; if (p == 0) return false; +#else + void* v = alloc (sizeof (T)); + + if (v == 0) + return false; + T* p = new (v) T; // c-tor cannot fail +#endif if (!(s >> *p)) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete p; +#else + p->~T (); + cxx::free (p); +#endif return false; } diff --git a/libxsde/xsde/cxx/parser/expat/document.cxx b/libxsde/xsde/cxx/parser/expat/document.cxx index 61cc1d0..84cf7f8 100644 --- a/libxsde/xsde/cxx/parser/expat/document.cxx +++ b/libxsde/xsde/cxx/parser/expat/document.cxx @@ -17,6 +17,10 @@ # include <fstream> #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #ifdef XSDE_ENCODING_ISO8859_1 # include <xsde/cxx/iso8859-1.hxx> #endif @@ -1291,7 +1295,11 @@ namespace xsde buf = data_buf_; else { +#ifndef XSDE_CUSTOM_ALLOCATOR buf = new char[iso_n]; +#else + buf = static_cast<char*> (alloc (iso_n)); +#endif #ifndef XSDE_EXCEPTIONS if (buf == 0) @@ -1324,7 +1332,11 @@ namespace xsde buf = data_buf_; else { +#ifndef XSDE_CUSTOM_ALLOCATOR buf = new char[iso_n]; +#else + buf = static_cast<char*> (alloc (iso_n)); +#endif #ifndef XSDE_EXCEPTIONS if (buf == 0) @@ -1354,7 +1366,11 @@ namespace xsde buf = name_buf_; else { +#ifndef XSDE_CUSTOM_ALLOCATOR buf = new char[iso_n]; +#else + buf = static_cast<char*> (alloc (iso_n)); +#endif #ifndef XSDE_EXCEPTIONS if (buf == 0) diff --git a/libxsde/xsde/cxx/parser/non-validating/base64-binary.cxx b/libxsde/xsde/cxx/parser/non-validating/base64-binary.cxx index f84d2a4..fb90768 100644 --- a/libxsde/xsde/cxx/parser/non-validating/base64-binary.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/base64-binary.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/non-validating/base64-binary.hxx> static unsigned char @@ -34,11 +38,18 @@ namespace xsde { namespace non_validating { - base64_binary_pimpl:: + base64_binary_pimpl:: ~base64_binary_pimpl () { - if (!base_) + if (!base_ && buf_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete buf_; +#else + buf_->~buffer (); + cxx::free (buf_); +#endif + } } void base64_binary_pimpl:: @@ -46,9 +57,14 @@ namespace xsde { base64_binary_pskel::_reset (); - if (!base_) + if (!base_ && buf_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete buf_; +#else + buf_->~buffer (); + cxx::free (buf_); +#endif buf_ = 0; } } @@ -70,7 +86,20 @@ namespace xsde { if (buf_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR buf_ = new buffer (); +#else + buf_ = static_cast<buffer*> (alloc (sizeof (buffer))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (buf_); + new (buf_) buffer (); + ag.release (); +#else + if (buf_) + new (buf_) buffer (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (buf_ == 0) diff --git a/libxsde/xsde/cxx/parser/non-validating/hex-binary.cxx b/libxsde/xsde/cxx/parser/non-validating/hex-binary.cxx index 530315e..83c578b 100644 --- a/libxsde/xsde/cxx/parser/non-validating/hex-binary.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/hex-binary.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/non-validating/hex-binary.hxx> static unsigned char @@ -33,8 +37,15 @@ namespace xsde hex_binary_pimpl:: ~hex_binary_pimpl () { - if (!base_) + if (!base_ && buf_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete buf_; +#else + buf_->~buffer (); + cxx::free (buf_); +#endif + } } void hex_binary_pimpl:: @@ -42,9 +53,14 @@ namespace xsde { hex_binary_pskel::_reset (); - if (!base_) + if (!base_ && buf_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete buf_; +#else + buf_->~buffer (); + cxx::free (buf_); +#endif buf_ = 0; } } @@ -66,7 +82,20 @@ namespace xsde { if (buf_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR buf_ = new buffer (); +#else + buf_ = static_cast<buffer*> (alloc (sizeof (buffer))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (buf_); + new (buf_) buffer (); + ag.release (); +#else + if (buf_) + new (buf_) buffer (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (buf_ == 0) diff --git a/libxsde/xsde/cxx/parser/non-validating/id-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/id-stl.cxx index 6c49ecf..2e5ebd7 100644 --- a/libxsde/xsde/cxx/parser/non-validating/id-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/id-stl.cxx @@ -47,4 +47,3 @@ namespace xsde } } } - diff --git a/libxsde/xsde/cxx/parser/non-validating/idrefs-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/idrefs-stl.cxx index 7c2b30d..6ae0245 100644 --- a/libxsde/xsde/cxx/parser/non-validating/idrefs-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/idrefs-stl.cxx @@ -7,6 +7,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/non-validating/idrefs-stl.hxx> namespace xsde @@ -20,8 +24,15 @@ namespace xsde idrefs_pimpl:: ~idrefs_pimpl () { - if (!base_) + if (!base_ && seq_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif + } } void idrefs_pimpl:: @@ -29,9 +40,14 @@ namespace xsde { idrefs_pskel::_reset (); - if (!base_) + if (!base_ && seq_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif seq_ = 0; } @@ -55,7 +71,21 @@ namespace xsde { if (seq_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR seq_ = new string_sequence (); +#else + seq_ = static_cast<string_sequence*> ( + alloc (sizeof (string_sequence))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (seq_); + new (seq_) string_sequence (); + ag.release (); +#else + if (seq_) + new () string_sequence (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (seq_ == 0) diff --git a/libxsde/xsde/cxx/parser/non-validating/idrefs.cxx b/libxsde/xsde/cxx/parser/non-validating/idrefs.cxx index d9e2794..b559c81 100644 --- a/libxsde/xsde/cxx/parser/non-validating/idrefs.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/idrefs.cxx @@ -7,6 +7,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/non-validating/idrefs.hxx> namespace xsde @@ -20,8 +24,15 @@ namespace xsde idrefs_pimpl:: ~idrefs_pimpl () { - if (!base_) + if (!base_ && seq_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif + } } void idrefs_pimpl:: @@ -29,9 +40,14 @@ namespace xsde { idrefs_pskel::_reset (); - if (!base_) + if (!base_ && seq_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif seq_ = 0; } @@ -55,7 +71,21 @@ namespace xsde { if (seq_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR seq_ = new string_sequence (); +#else + seq_ = static_cast<string_sequence*> ( + alloc (sizeof (string_sequence))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (seq_); + new (seq_) string_sequence (); + ag.release (); +#else + if (seq_) + new () string_sequence (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (seq_ == 0) diff --git a/libxsde/xsde/cxx/parser/non-validating/ncname-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/ncname-stl.cxx index f0b5202..0ab155e 100644 --- a/libxsde/xsde/cxx/parser/non-validating/ncname-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/ncname-stl.cxx @@ -47,4 +47,3 @@ namespace xsde } } } - diff --git a/libxsde/xsde/cxx/parser/non-validating/nmtokens-stl.cxx b/libxsde/xsde/cxx/parser/non-validating/nmtokens-stl.cxx index 07d1945..93aefce 100644 --- a/libxsde/xsde/cxx/parser/non-validating/nmtokens-stl.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/nmtokens-stl.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/non-validating/nmtokens-stl.hxx> namespace xsde @@ -18,8 +22,15 @@ namespace xsde nmtokens_pimpl:: ~nmtokens_pimpl () { - if (!base_) + if (!base_ && seq_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif + } } void nmtokens_pimpl:: @@ -27,9 +38,14 @@ namespace xsde { nmtokens_pskel::_reset (); - if (!base_) + if (!base_ && seq_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif seq_ = 0; } @@ -53,7 +69,21 @@ namespace xsde { if (seq_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR seq_ = new string_sequence (); +#else + seq_ = static_cast<string_sequence*> ( + alloc (sizeof (string_sequence))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (seq_); + new (seq_) string_sequence (); + ag.release (); +#else + if (seq_) + new () string_sequence (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (seq_ == 0) diff --git a/libxsde/xsde/cxx/parser/non-validating/nmtokens.cxx b/libxsde/xsde/cxx/parser/non-validating/nmtokens.cxx index 15a6254..c798b88 100644 --- a/libxsde/xsde/cxx/parser/non-validating/nmtokens.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/nmtokens.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/non-validating/nmtokens.hxx> namespace xsde @@ -18,8 +22,15 @@ namespace xsde nmtokens_pimpl:: ~nmtokens_pimpl () { - if (!base_) + if (!base_ && seq_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif + } } void nmtokens_pimpl:: @@ -27,9 +38,14 @@ namespace xsde { nmtokens_pskel::_reset (); - if (!base_) + if (!base_ && seq_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif seq_ = 0; } @@ -53,7 +69,21 @@ namespace xsde { if (seq_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR seq_ = new string_sequence (); +#else + seq_ = static_cast<string_sequence*> ( + alloc (sizeof (string_sequence))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (seq_); + new (seq_) string_sequence (); + ag.release (); +#else + if (seq_) + new () string_sequence (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (seq_ == 0) diff --git a/libxsde/xsde/cxx/parser/non-validating/qname.cxx b/libxsde/xsde/cxx/parser/non-validating/qname.cxx index 9be5872..7d9f71d 100644 --- a/libxsde/xsde/cxx/parser/non-validating/qname.cxx +++ b/libxsde/xsde/cxx/parser/non-validating/qname.cxx @@ -6,6 +6,10 @@ #include <xsde/cxx/config.hxx> #include <xsde/cxx/string.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/non-validating/qname.hxx> namespace xsde @@ -19,8 +23,15 @@ namespace xsde qname_pimpl:: ~qname_pimpl () { - if (!base_) + if (!base_ && qn_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete qn_; +#else + qn_->~qname (); + cxx::free (qn_); +#endif + } } void qname_pimpl:: @@ -28,9 +39,14 @@ namespace xsde { qname_pskel::_reset (); - if (!base_) + if (!base_ && qn_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete qn_; +#else + qn_->~qname (); + cxx::free (qn_); +#endif qn_ = 0; } } @@ -52,7 +68,20 @@ namespace xsde { if (qn_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR qn_ = new qname (); +#else + qn_ = static_cast<qname*> (alloc (sizeof (qname))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (qn_); + new (qn_) qname (); + ag.release (); +#else + if (qn_) + new (qn_) qname (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (qn_ == 0) diff --git a/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.hxx b/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.hxx index 5f28434..59469c6 100644 --- a/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.hxx +++ b/libxsde/xsde/cxx/parser/non-validating/xml-schema-pskel.hxx @@ -548,7 +548,8 @@ namespace xsde // String-based types. If STL is disabled you are getting a C - // string that you have to delete with delete[]. + // string that you have to delete with delete[] (or custom + // deallocator if enabled). // struct string_pskel: simple_content { diff --git a/libxsde/xsde/cxx/parser/substitution-map.cxx b/libxsde/xsde/cxx/parser/substitution-map.cxx index a10770a..5cbe4a1 100644 --- a/libxsde/xsde/cxx/parser/substitution-map.cxx +++ b/libxsde/xsde/cxx/parser/substitution-map.cxx @@ -12,6 +12,10 @@ # include <stdlib.h> // exit #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/substitution-map.hxx> #include <xsde/cxx/parser/substitution-map-load.hxx> @@ -174,7 +178,21 @@ namespace xsde { if (count == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR map = new substitution_map (XSDE_PARSER_SMAP_BUCKETS); +#else + map = static_cast<substitution_map*> ( + alloc (sizeof (substitution_map))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard mg (map); + new (map) substitution_map (XSDE_PARSER_SMAP_BUCKETS); + mg.release (); +#else + if (map) + new (map) substitution_map (XSDE_PARSER_SMAP_BUCKETS); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (map == 0 || map->_error () != substitution_map::error_none) @@ -197,7 +215,14 @@ namespace xsde ~substitution_map_init () { if (--count == 0) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete map; +#else + map->~substitution_map (); + cxx::free (map); +#endif + } } // substitution_map_entry diff --git a/libxsde/xsde/cxx/parser/validating/base64-binary.cxx b/libxsde/xsde/cxx/parser/validating/base64-binary.cxx index 3aac6f3..f36df5a 100644 --- a/libxsde/xsde/cxx/parser/validating/base64-binary.cxx +++ b/libxsde/xsde/cxx/parser/validating/base64-binary.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/validating/base64-binary.hxx> static unsigned char @@ -37,8 +41,15 @@ namespace xsde base64_binary_pimpl:: ~base64_binary_pimpl () { - if (!base_) + if (!base_ && buf_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete buf_; +#else + buf_->~buffer (); + cxx::free (buf_); +#endif + } } void base64_binary_pimpl:: @@ -46,9 +57,14 @@ namespace xsde { base64_binary_pskel::_reset (); - if (!base_) + if (!base_ && buf_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete buf_; +#else + buf_->~buffer (); + cxx::free (buf_); +#endif buf_ = 0; } } @@ -70,7 +86,20 @@ namespace xsde { if (buf_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR buf_ = new buffer (); +#else + buf_ = static_cast<buffer*> (alloc (sizeof (buffer))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (buf_); + new (buf_) buffer (); + ag.release (); +#else + if (buf_) + new (buf_) buffer (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (buf_ == 0) diff --git a/libxsde/xsde/cxx/parser/validating/hex-binary.cxx b/libxsde/xsde/cxx/parser/validating/hex-binary.cxx index 24035fa..f7e6139 100644 --- a/libxsde/xsde/cxx/parser/validating/hex-binary.cxx +++ b/libxsde/xsde/cxx/parser/validating/hex-binary.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/validating/hex-binary.hxx> static unsigned char @@ -33,8 +37,15 @@ namespace xsde hex_binary_pimpl:: ~hex_binary_pimpl () { - if (!base_) + if (!base_ && buf_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete buf_; +#else + buf_->~buffer (); + cxx::free (buf_); +#endif + } } void hex_binary_pimpl:: @@ -42,9 +53,14 @@ namespace xsde { hex_binary_pskel::_reset (); - if (!base_) + if (!base_ && buf_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete buf_; +#else + buf_->~buffer (); + cxx::free (buf_); +#endif buf_ = 0; } } @@ -66,7 +82,20 @@ namespace xsde { if (buf_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR buf_ = new buffer (); +#else + buf_ = static_cast<buffer*> (alloc (sizeof (buffer))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (buf_); + new (buf_) buffer (); + ag.release (); +#else + if (buf_) + new (buf_) buffer (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (buf_ == 0) diff --git a/libxsde/xsde/cxx/parser/validating/idrefs-stl.cxx b/libxsde/xsde/cxx/parser/validating/idrefs-stl.cxx index 85129ed..3fc3175 100644 --- a/libxsde/xsde/cxx/parser/validating/idrefs-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/idrefs-stl.cxx @@ -7,6 +7,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/validating/idrefs-stl.hxx> namespace xsde @@ -20,8 +24,15 @@ namespace xsde idrefs_pimpl:: ~idrefs_pimpl () { - if (!base_) + if (!base_ && seq_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif + } } void idrefs_pimpl:: @@ -29,9 +40,14 @@ namespace xsde { idrefs_pskel::_reset (); - if (!base_) + if (!base_ && seq_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif seq_ = 0; } @@ -55,7 +71,21 @@ namespace xsde { if (seq_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR seq_ = new string_sequence (); +#else + seq_ = static_cast<string_sequence*> ( + alloc (sizeof (string_sequence))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (seq_); + new (seq_) string_sequence (); + ag.release (); +#else + if (seq_) + new () string_sequence (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (seq_ == 0) diff --git a/libxsde/xsde/cxx/parser/validating/idrefs.cxx b/libxsde/xsde/cxx/parser/validating/idrefs.cxx index 2bf35d2..851d28c 100644 --- a/libxsde/xsde/cxx/parser/validating/idrefs.cxx +++ b/libxsde/xsde/cxx/parser/validating/idrefs.cxx @@ -7,6 +7,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/validating/idrefs.hxx> namespace xsde @@ -20,8 +24,15 @@ namespace xsde idrefs_pimpl:: ~idrefs_pimpl () { - if (!base_) + if (!base_ && seq_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif + } } void idrefs_pimpl:: @@ -29,9 +40,14 @@ namespace xsde { idrefs_pskel::_reset (); - if (!base_) + if (!base_ && seq_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif seq_ = 0; } @@ -55,7 +71,21 @@ namespace xsde { if (seq_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR seq_ = new string_sequence (); +#else + seq_ = static_cast<string_sequence*> ( + alloc (sizeof (string_sequence))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (seq_); + new (seq_) string_sequence (); + ag.release (); +#else + if (seq_) + new () string_sequence (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (seq_ == 0) diff --git a/libxsde/xsde/cxx/parser/validating/inheritance-map.cxx b/libxsde/xsde/cxx/parser/validating/inheritance-map.cxx index c3b9e41..f23e841 100644 --- a/libxsde/xsde/cxx/parser/validating/inheritance-map.cxx +++ b/libxsde/xsde/cxx/parser/validating/inheritance-map.cxx @@ -12,6 +12,10 @@ # include <stdlib.h> // exit #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/validating/inheritance-map.hxx> #include <xsde/cxx/parser/validating/inheritance-map-load.hxx> @@ -50,7 +54,21 @@ namespace xsde { if (count == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR map = new inheritance_map (XSDE_PARSER_IMAP_BUCKETS); +#else + map = static_cast<inheritance_map*> ( + alloc (sizeof (inheritance_map))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard mg (map); + new (map) inheritance_map (XSDE_PARSER_IMAP_BUCKETS); + mg.release (); +#else + if (map) + new (map) inheritance_map (XSDE_PARSER_IMAP_BUCKETS); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (map == 0 || map->_error () != inheritance_map::error_none) @@ -73,7 +91,14 @@ namespace xsde ~inheritance_map_init () { if (--count == 0) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete map; +#else + map->~inheritance_map (); + cxx::free (map); +#endif + } } // inheritance_map_entry diff --git a/libxsde/xsde/cxx/parser/validating/nmtokens-stl.cxx b/libxsde/xsde/cxx/parser/validating/nmtokens-stl.cxx index 8410d89..6258e26 100644 --- a/libxsde/xsde/cxx/parser/validating/nmtokens-stl.cxx +++ b/libxsde/xsde/cxx/parser/validating/nmtokens-stl.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/validating/nmtokens-stl.hxx> namespace xsde @@ -18,8 +22,15 @@ namespace xsde nmtokens_pimpl:: ~nmtokens_pimpl () { - if (!base_) + if (!base_ && seq_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif + } } void nmtokens_pimpl:: @@ -27,9 +38,14 @@ namespace xsde { nmtokens_pskel::_reset (); - if (!base_) + if (!base_ && seq_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif seq_ = 0; } @@ -53,7 +69,21 @@ namespace xsde { if (seq_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR seq_ = new string_sequence (); +#else + seq_ = static_cast<string_sequence*> ( + alloc (sizeof (string_sequence))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (seq_); + new (seq_) string_sequence (); + ag.release (); +#else + if (seq_) + new () string_sequence (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (seq_ == 0) diff --git a/libxsde/xsde/cxx/parser/validating/nmtokens.cxx b/libxsde/xsde/cxx/parser/validating/nmtokens.cxx index 7573f28..5d06ef1 100644 --- a/libxsde/xsde/cxx/parser/validating/nmtokens.cxx +++ b/libxsde/xsde/cxx/parser/validating/nmtokens.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/parser/validating/nmtokens.hxx> namespace xsde @@ -18,8 +22,15 @@ namespace xsde nmtokens_pimpl:: ~nmtokens_pimpl () { - if (!base_) + if (!base_ && seq_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif + } } void nmtokens_pimpl:: @@ -27,9 +38,14 @@ namespace xsde { nmtokens_pskel::_reset (); - if (!base_) + if (!base_ && seq_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete seq_; +#else + seq_->~string_sequence (); + cxx::free (seq_); +#endif seq_ = 0; } @@ -53,7 +69,21 @@ namespace xsde { if (seq_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR seq_ = new string_sequence (); +#else + seq_ = static_cast<string_sequence*> ( + alloc (sizeof (string_sequence))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (seq_); + new (seq_) string_sequence (); + ag.release (); +#else + if (seq_) + new () string_sequence (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (seq_ == 0) diff --git a/libxsde/xsde/cxx/parser/validating/qname.cxx b/libxsde/xsde/cxx/parser/validating/qname.cxx index b98c8e9..5709824 100644 --- a/libxsde/xsde/cxx/parser/validating/qname.cxx +++ b/libxsde/xsde/cxx/parser/validating/qname.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/config.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/xml/ncname.hxx> #include <xsde/cxx/parser/validating/qname.hxx> @@ -20,8 +24,15 @@ namespace xsde qname_pimpl:: ~qname_pimpl () { - if (!base_) + if (!base_ && qn_) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete qn_; +#else + qn_->~qname (); + cxx::free (qn_); +#endif + } } void qname_pimpl:: @@ -29,9 +40,14 @@ namespace xsde { qname_pskel::_reset (); - if (!base_) + if (!base_ && qn_) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete qn_; +#else + qn_->~qname (); + cxx::free (qn_); +#endif qn_ = 0; } } @@ -53,7 +69,20 @@ namespace xsde { if (qn_ == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR qn_ = new qname (); +#else + qn_ = static_cast<qname*> (alloc (sizeof (qname))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard ag (qn_); + new (qn_) qname (); + ag.release (); +#else + if (qn_) + new (qn_) qname (); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (qn_ == 0) diff --git a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx index a978c6d..4b6b126 100644 --- a/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx +++ b/libxsde/xsde/cxx/parser/validating/xml-schema-pskel.hxx @@ -655,7 +655,8 @@ namespace xsde // // String-based types. If STL is disabled you are getting a C - // string that you have to delete with delete[]. + // string that you have to delete with delete[] (or custom + // deallocator if enabled). // struct string_facets diff --git a/libxsde/xsde/cxx/qname.cxx b/libxsde/xsde/cxx/qname.cxx index bd5e1c2..be196be 100644 --- a/libxsde/xsde/cxx/qname.cxx +++ b/libxsde/xsde/cxx/qname.cxx @@ -3,9 +3,7 @@ // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <string.h> // strlen, memcpy -#include <stddef.h> // size_t - +#include <xsde/cxx/strdupx.hxx> #include <xsde/cxx/qname.hxx> namespace xsde @@ -19,18 +17,20 @@ namespace xsde #endif prefix_copy (const char* prefix) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] prefix_; +#else + cxx::free (prefix_); +#endif if (prefix) { - size_t size = strlen (prefix) + 1; - prefix_ = new char[size]; + prefix_ = strdupx (prefix); #ifndef XSDE_EXCEPTIONS if (prefix_ == 0) return error_no_memory; #endif - memcpy (prefix_, prefix, size); } else prefix_ = 0; @@ -47,18 +47,20 @@ namespace xsde #endif name_copy (const char* name) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] name_; +#else + cxx::free (name_); +#endif if (name) { - size_t size = strlen (name) + 1; - name_ = new char[size]; + name_ = strdupx (name); #ifndef XSDE_EXCEPTIONS if (name_ == 0) return error_no_memory; #endif - memcpy (name_, name, size); } else name_ = 0; diff --git a/libxsde/xsde/cxx/qname.ixx b/libxsde/xsde/cxx/qname.ixx index c46802d..f449ef3 100644 --- a/libxsde/xsde/cxx/qname.ixx +++ b/libxsde/xsde/cxx/qname.ixx @@ -5,6 +5,10 @@ #include <string.h> // strcmp +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -14,8 +18,13 @@ namespace xsde inline qname:: ~qname () { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] prefix_; delete[] name_; +#else + cxx::free (prefix_); + cxx::free (name_); +#endif } inline qname:: @@ -66,7 +75,11 @@ namespace xsde inline void qname:: prefix (char* prefix) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] prefix_; +#else + cxx::free (prefix_); +#endif prefix_ = prefix; } @@ -95,7 +108,11 @@ namespace xsde inline void qname:: name (char* name) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] name_; +#else + cxx::free (name_); +#endif name_ = name; } diff --git a/libxsde/xsde/cxx/sequence-base.cxx b/libxsde/xsde/cxx/sequence-base.cxx index d2099a3..06d4012 100644 --- a/libxsde/xsde/cxx/sequence-base.cxx +++ b/libxsde/xsde/cxx/sequence-base.cxx @@ -29,7 +29,15 @@ namespace xsde struct guard { guard (void* p) : p_ (p) {} - ~guard () {if (p_) operator delete (p_);} + ~guard () + { + if (p_) +#ifndef XSDE_CUSTOM_ALLOCATOR + operator delete (p_); +#else + cxx::free (p_); +#endif + } void release () { p_ = 0; } @@ -42,7 +50,12 @@ namespace xsde grow_ (size_t n, size_t es, move_func mv) { size_t c = n == 0 ? (capacity_ != 0 ? capacity_ * 2 : 8) : n; + +#ifndef XSDE_CUSTOM_ALLOCATOR void* d = operator new (c * es); +#else + void* d = alloc (c * es); +#endif if (size_) { @@ -57,7 +70,11 @@ namespace xsde } if (data_) +#ifndef XSDE_CUSTOM_ALLOCATOR operator delete (data_); +#else + cxx::free (data_); +#endif data_ = d; capacity_ = c; @@ -89,7 +106,11 @@ namespace xsde grow_ (size_t n, size_t es, move_func mv) { size_t c = n == 0 ? (capacity_ != 0 ? capacity_ * 2 : 8) : n; +#ifndef XSDE_CUSTOM_ALLOCATOR void* d = operator new (c * es); +#else + void* d = alloc (c * es); +#endif if (d == 0) return error_no_memory; @@ -103,7 +124,11 @@ namespace xsde } if (data_) +#ifndef XSDE_CUSTOM_ALLOCATOR operator delete (data_); +#else + cxx::free (data_); +#endif data_ = d; capacity_ = c; diff --git a/libxsde/xsde/cxx/sequence-base.ixx b/libxsde/xsde/cxx/sequence-base.ixx index e4e446b..164feb4 100644 --- a/libxsde/xsde/cxx/sequence-base.ixx +++ b/libxsde/xsde/cxx/sequence-base.ixx @@ -3,6 +3,10 @@ // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -17,7 +21,11 @@ namespace xsde ~sequence_base () { if (data_) +#ifndef XSDE_CUSTOM_ALLOCATOR operator delete (data_); +#else + cxx::free (data_); +#endif } inline bool sequence_base:: diff --git a/libxsde/xsde/cxx/serializer/context.cxx b/libxsde/xsde/cxx/serializer/context.cxx index faa1ed4..0a53c74 100644 --- a/libxsde/xsde/cxx/serializer/context.cxx +++ b/libxsde/xsde/cxx/serializer/context.cxx @@ -13,6 +13,10 @@ # include <xsde/cxx/serializer/exceptions.hxx> #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #ifdef XSDE_ENCODING_ISO8859_1 # include <xsde/cxx/iso8859-1.hxx> #endif @@ -738,7 +742,11 @@ namespace xsde buf = data_buf_; else { +#ifndef XSDE_CUSTOM_ALLOCATOR buf = new char[utf_n]; +#else + buf = static_cast<char*> (alloc (utf_n)); +#endif #ifndef XSDE_EXCEPTIONS if (buf == 0) @@ -763,7 +771,11 @@ namespace xsde buf = data_buf_; else { +#ifndef XSDE_CUSTOM_ALLOCATOR buf = new char[utf_n]; +#else + buf = static_cast<char*> (alloc (utf_n)); +#endif #ifndef XSDE_EXCEPTIONS if (buf == 0) @@ -788,7 +800,11 @@ namespace xsde buf = fix; else { +#ifndef XSDE_CUSTOM_ALLOCATOR buf = new char[utf_n]; +#else + buf = static_cast<char*> (alloc (utf_n)); +#endif #ifndef XSDE_EXCEPTIONS if (buf == 0) diff --git a/libxsde/xsde/cxx/serializer/non-validating/base64-binary.cxx b/libxsde/xsde/cxx/serializer/non-validating/base64-binary.cxx index 89afb12..180823e 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/base64-binary.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/base64-binary.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/base64-binary.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde base64_binary_simpl:: ~base64_binary_simpl () { - if (free_) - delete const_cast<buffer*> (value_); + if (free_ && value_) + { + buffer* v = const_cast<buffer*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~buffer (); + cxx::free (v); +#endif + } } void base64_binary_simpl:: @@ -156,7 +168,13 @@ namespace xsde if (free_) { - delete const_cast<buffer*> (value_); + buffer* v = const_cast<buffer*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~buffer (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/hex-binary.cxx b/libxsde/xsde/cxx/serializer/non-validating/hex-binary.cxx index 9c5a49c..36d3e32 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/hex-binary.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/hex-binary.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/hex-binary.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde hex_binary_simpl:: ~hex_binary_simpl () { - if (free_) - delete const_cast<buffer*> (value_); + if (free_ && value_) + { + buffer* v = const_cast<buffer*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~buffer (); + cxx::free (v); +#endif + } } void hex_binary_simpl:: @@ -60,7 +72,13 @@ namespace xsde if (free_) { - delete const_cast<buffer*> (value_); + buffer* v = const_cast<buffer*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~buffer (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/id.cxx b/libxsde/xsde/cxx/serializer/non-validating/id.cxx index db50bef..ac7ede2 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/id.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/id.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/id.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde id_simpl:: ~id_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void id_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/idref.cxx b/libxsde/xsde/cxx/serializer/non-validating/idref.cxx index c4022e7..e52650f 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/idref.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/idref.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/idref.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde idref_simpl:: ~idref_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void idref_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/idrefs-stl.cxx b/libxsde/xsde/cxx/serializer/non-validating/idrefs-stl.cxx index ab48695..b95719a 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/idrefs-stl.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/idrefs-stl.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/idrefs-stl.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde idrefs_simpl:: ~idrefs_simpl () { - if (free_) - delete const_cast<string_sequence*> (value_); + if (free_ && value_) + { + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif + } } void idrefs_simpl:: @@ -91,7 +103,13 @@ namespace xsde if (free_) { - delete const_cast<string_sequence*> (value_); + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/idrefs.cxx b/libxsde/xsde/cxx/serializer/non-validating/idrefs.cxx index 11261a6..f812526 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/idrefs.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/idrefs.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/idrefs.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde idrefs_simpl:: ~idrefs_simpl () { - if (free_) - delete const_cast<string_sequence*> (value_); + if (free_ && value_) + { + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif + } } void idrefs_simpl:: @@ -91,7 +103,13 @@ namespace xsde if (free_) { - delete const_cast<string_sequence*> (value_); + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif value_ = 0; } } @@ -106,4 +124,3 @@ namespace xsde } } } - diff --git a/libxsde/xsde/cxx/serializer/non-validating/language.cxx b/libxsde/xsde/cxx/serializer/non-validating/language.cxx index 72ccd8b..801aa3a 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/language.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/language.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/language.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde language_simpl:: ~language_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void language_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/name.cxx b/libxsde/xsde/cxx/serializer/non-validating/name.cxx index 851dcf9..6e8e0b1 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/name.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/name.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/name.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde name_simpl:: ~name_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void name_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/ncname.cxx b/libxsde/xsde/cxx/serializer/non-validating/ncname.cxx index 3c86986..eee9d60 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/ncname.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/ncname.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/ncname.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde ncname_simpl:: ~ncname_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void ncname_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/nmtoken.cxx b/libxsde/xsde/cxx/serializer/non-validating/nmtoken.cxx index a384c04..8f153ff 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/nmtoken.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/nmtoken.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/nmtoken.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde nmtoken_simpl:: ~nmtoken_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void nmtoken_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/nmtokens-stl.cxx b/libxsde/xsde/cxx/serializer/non-validating/nmtokens-stl.cxx index 6636b33..7cea1f1 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/nmtokens-stl.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/nmtokens-stl.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/nmtokens-stl.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde nmtokens_simpl:: ~nmtokens_simpl () { - if (free_) - delete const_cast<string_sequence*> (value_); + if (free_ && value_) + { + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif + } } void nmtokens_simpl:: @@ -91,7 +103,13 @@ namespace xsde if (free_) { - delete const_cast<string_sequence*> (value_); + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/nmtokens.cxx b/libxsde/xsde/cxx/serializer/non-validating/nmtokens.cxx index ad40fc4..57afd8d 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/nmtokens.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/nmtokens.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/nmtokens.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde nmtokens_simpl:: ~nmtokens_simpl () { - if (free_) - delete const_cast<string_sequence*> (value_); + if (free_ && value_) + { + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif + } } void nmtokens_simpl:: @@ -91,7 +103,13 @@ namespace xsde if (free_) { - delete const_cast<string_sequence*> (value_); + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif value_ = 0; } } @@ -106,4 +124,3 @@ namespace xsde } } } - diff --git a/libxsde/xsde/cxx/serializer/non-validating/normalized-string-stl.cxx b/libxsde/xsde/cxx/serializer/non-validating/normalized-string-stl.cxx index 5810de3..b5209c3 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/normalized-string-stl.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/normalized-string-stl.cxx @@ -33,4 +33,3 @@ namespace xsde } } } - diff --git a/libxsde/xsde/cxx/serializer/non-validating/normalized-string.cxx b/libxsde/xsde/cxx/serializer/non-validating/normalized-string.cxx index b1bbf29..202ac76 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/normalized-string.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/normalized-string.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/normalized-string.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde normalized_string_simpl:: ~normalized_string_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void normalized_string_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } @@ -41,4 +57,3 @@ namespace xsde } } } - diff --git a/libxsde/xsde/cxx/serializer/non-validating/qname.cxx b/libxsde/xsde/cxx/serializer/non-validating/qname.cxx index 19c7daa..ec267ef 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/qname.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/qname.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/qname.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde qname_simpl:: ~qname_simpl () { - if (free_) - delete const_cast<qname*> (value_); + if (free_ && value_) + { + qname* v = const_cast<qname*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~qname (); + cxx::free (v); +#endif + } } void qname_simpl:: @@ -52,7 +64,13 @@ namespace xsde if (free_) { - delete const_cast<qname*> (value_); + qname* v = const_cast<qname*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~qname (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/string.cxx b/libxsde/xsde/cxx/serializer/non-validating/string.cxx index 7b1e546..1c6c50f 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/string.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/string.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/string.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde string_simpl:: ~string_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void string_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/token.cxx b/libxsde/xsde/cxx/serializer/non-validating/token.cxx index 5ff0739..2af141c 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/token.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/token.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/token.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde token_simpl:: ~token_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void token_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/non-validating/uri.cxx b/libxsde/xsde/cxx/serializer/non-validating/uri.cxx index 43bafbd..5640302 100644 --- a/libxsde/xsde/cxx/serializer/non-validating/uri.cxx +++ b/libxsde/xsde/cxx/serializer/non-validating/uri.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/non-validating/uri.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde uri_simpl:: ~uri_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void uri_simpl:: @@ -33,7 +44,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/substitution-map.cxx b/libxsde/xsde/cxx/serializer/substitution-map.cxx index 0dfc97f..28f01b5 100644 --- a/libxsde/xsde/cxx/serializer/substitution-map.cxx +++ b/libxsde/xsde/cxx/serializer/substitution-map.cxx @@ -12,6 +12,10 @@ # include <stdlib.h> // exit #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/serializer/substitution-map.hxx> #include <xsde/cxx/serializer/substitution-map-load.hxx> @@ -29,7 +33,14 @@ namespace xsde { for (const_iterator i (begin ()), e (end ()); i != e; ++i) { - delete *static_cast<hashmap**> (const_cast<void*> (*i)); + hashmap* p = *static_cast<hashmap**> (const_cast<void*> (*i)); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete p; +#else + if (p) + p->~hashmap (); + cxx::free (p); +#endif } } @@ -45,8 +56,23 @@ namespace xsde m = *static_cast<hashmap**> (const_cast<void*> (p)); else { +#ifndef XSDE_CUSTOM_ALLOCATOR m = new hashmap (XSDE_SERIALIZER_SMAP_BUCKET_BUCKETS, sizeof (value)); +#else + m = static_cast<hashmap*> (alloc (sizeof (hashmap))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard mg (m); + new (m) hashmap (XSDE_SERIALIZER_SMAP_BUCKET_BUCKETS, + sizeof (value)); + mg.release (); +#else + if (m) + new (m) hashmap (XSDE_SERIALIZER_SMAP_BUCKET_BUCKETS, + sizeof (value)); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (m == 0 || m->_error () != hashmap::error_none) @@ -166,7 +192,21 @@ namespace xsde { if (count == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR map = new substitution_map (XSDE_SERIALIZER_SMAP_BUCKETS); +#else + map = static_cast<substitution_map*> ( + alloc (sizeof (substitution_map))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard mg (map); + new (map) substitution_map (XSDE_SERIALIZER_SMAP_BUCKETS); + mg.release (); +#else + if (map) + new (map) substitution_map (XSDE_SERIALIZER_SMAP_BUCKETS); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (map == 0 || map->_error () != substitution_map::error_none) @@ -189,7 +229,14 @@ namespace xsde ~substitution_map_init () { if (--count == 0) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete map; +#else + map->~substitution_map (); + cxx::free (map); +#endif + } } // substitution_map_entry diff --git a/libxsde/xsde/cxx/serializer/validating/base64-binary.cxx b/libxsde/xsde/cxx/serializer/validating/base64-binary.cxx index e192be7..04b3ef0 100644 --- a/libxsde/xsde/cxx/serializer/validating/base64-binary.cxx +++ b/libxsde/xsde/cxx/serializer/validating/base64-binary.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/validating/base64-binary.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde base64_binary_simpl:: ~base64_binary_simpl () { - if (free_) - delete const_cast<buffer*> (value_); + if (free_ && value_) + { + buffer* v = const_cast<buffer*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~buffer (); + cxx::free (v); +#endif + } } void base64_binary_simpl:: @@ -156,7 +168,13 @@ namespace xsde if (free_) { - delete const_cast<buffer*> (value_); + buffer* v = const_cast<buffer*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~buffer (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/hex-binary.cxx b/libxsde/xsde/cxx/serializer/validating/hex-binary.cxx index 5c3a8d5..712bbcb 100644 --- a/libxsde/xsde/cxx/serializer/validating/hex-binary.cxx +++ b/libxsde/xsde/cxx/serializer/validating/hex-binary.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/validating/hex-binary.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde hex_binary_simpl:: ~hex_binary_simpl () { - if (free_) - delete const_cast<buffer*> (value_); + if (free_ && value_) + { + buffer* v = const_cast<buffer*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~buffer (); + cxx::free (v); +#endif + } } void hex_binary_simpl:: @@ -60,7 +72,13 @@ namespace xsde if (free_) { - delete const_cast<buffer*> (value_); + buffer* v = const_cast<buffer*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~buffer (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/id.cxx b/libxsde/xsde/cxx/serializer/validating/id.cxx index 55e91ef..b9baf40 100644 --- a/libxsde/xsde/cxx/serializer/validating/id.cxx +++ b/libxsde/xsde/cxx/serializer/validating/id.cxx @@ -10,6 +10,10 @@ #include <xsde/cxx/serializer/validating/id.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -21,8 +25,15 @@ namespace xsde id_simpl:: ~id_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void id_simpl:: @@ -49,7 +60,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/idref.cxx b/libxsde/xsde/cxx/serializer/validating/idref.cxx index 93e4228..f4f3014 100644 --- a/libxsde/xsde/cxx/serializer/validating/idref.cxx +++ b/libxsde/xsde/cxx/serializer/validating/idref.cxx @@ -10,6 +10,10 @@ #include <xsde/cxx/serializer/validating/idref.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -21,8 +25,15 @@ namespace xsde idref_simpl:: ~idref_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void idref_simpl:: @@ -49,7 +60,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/idrefs-stl.cxx b/libxsde/xsde/cxx/serializer/validating/idrefs-stl.cxx index df51d23..04f225a 100644 --- a/libxsde/xsde/cxx/serializer/validating/idrefs-stl.cxx +++ b/libxsde/xsde/cxx/serializer/validating/idrefs-stl.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/validating/idrefs-stl.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde idrefs_simpl:: ~idrefs_simpl () { - if (free_) - delete const_cast<string_sequence*> (value_); + if (free_ && value_) + { + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif + } } void idrefs_simpl:: @@ -92,7 +104,13 @@ namespace xsde if (free_) { - delete const_cast<string_sequence*> (value_); + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/idrefs.cxx b/libxsde/xsde/cxx/serializer/validating/idrefs.cxx index da2ac9b..4b5d7d2 100644 --- a/libxsde/xsde/cxx/serializer/validating/idrefs.cxx +++ b/libxsde/xsde/cxx/serializer/validating/idrefs.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/validating/idrefs.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde idrefs_simpl:: ~idrefs_simpl () { - if (free_) - delete const_cast<string_sequence*> (value_); + if (free_ && value_) + { + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif + } } void idrefs_simpl:: @@ -92,7 +104,13 @@ namespace xsde if (free_) { - delete const_cast<string_sequence*> (value_); + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif value_ = 0; } } @@ -107,4 +125,3 @@ namespace xsde } } } - diff --git a/libxsde/xsde/cxx/serializer/validating/inheritance-map.cxx b/libxsde/xsde/cxx/serializer/validating/inheritance-map.cxx index 35e2dc5..b320ee7 100644 --- a/libxsde/xsde/cxx/serializer/validating/inheritance-map.cxx +++ b/libxsde/xsde/cxx/serializer/validating/inheritance-map.cxx @@ -12,6 +12,10 @@ # include <stdlib.h> // exit #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + #include <xsde/cxx/serializer/validating/inheritance-map.hxx> #include <xsde/cxx/serializer/validating/inheritance-map-load.hxx> @@ -50,7 +54,21 @@ namespace xsde { if (count == 0) { +#ifndef XSDE_CUSTOM_ALLOCATOR map = new inheritance_map (XSDE_SERIALIZER_IMAP_BUCKETS); +#else + map = static_cast<inheritance_map*> ( + alloc (sizeof (inheritance_map))); + +#ifdef XSDE_EXCEPTIONS + alloc_guard mg (map); + new (map) inheritance_map (XSDE_SERIALIZER_IMAP_BUCKETS); + mg.release (); +#else + if (map) + new (map) inheritance_map (XSDE_SERIALIZER_IMAP_BUCKETS); +#endif +#endif #ifndef XSDE_EXCEPTIONS if (map == 0 || map->_error () != inheritance_map::error_none) @@ -73,7 +91,14 @@ namespace xsde ~inheritance_map_init () { if (--count == 0) + { +#ifndef XSDE_CUSTOM_ALLOCATOR delete map; +#else + map->~inheritance_map (); + cxx::free (map); +#endif + } } // inheritance_map_entry diff --git a/libxsde/xsde/cxx/serializer/validating/language.cxx b/libxsde/xsde/cxx/serializer/validating/language.cxx index 662c512..08be3bf 100644 --- a/libxsde/xsde/cxx/serializer/validating/language.cxx +++ b/libxsde/xsde/cxx/serializer/validating/language.cxx @@ -6,6 +6,10 @@ #include <xsde/cxx/serializer/validating/language.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde language_simpl:: ~language_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void language_simpl:: @@ -78,7 +89,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/name.cxx b/libxsde/xsde/cxx/serializer/validating/name.cxx index c1fec6e..4c974c0 100644 --- a/libxsde/xsde/cxx/serializer/validating/name.cxx +++ b/libxsde/xsde/cxx/serializer/validating/name.cxx @@ -8,6 +8,10 @@ #include <xsde/cxx/serializer/validating/name.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -19,8 +23,15 @@ namespace xsde name_simpl:: ~name_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void name_simpl:: @@ -67,7 +78,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/ncname.cxx b/libxsde/xsde/cxx/serializer/validating/ncname.cxx index ee6079b..86b9ecb 100644 --- a/libxsde/xsde/cxx/serializer/validating/ncname.cxx +++ b/libxsde/xsde/cxx/serializer/validating/ncname.cxx @@ -10,6 +10,10 @@ #include <xsde/cxx/serializer/validating/ncname.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -21,8 +25,15 @@ namespace xsde ncname_simpl:: ~ncname_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void ncname_simpl:: @@ -49,7 +60,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/nmtoken.cxx b/libxsde/xsde/cxx/serializer/validating/nmtoken.cxx index a230b57..c2f4a12 100644 --- a/libxsde/xsde/cxx/serializer/validating/nmtoken.cxx +++ b/libxsde/xsde/cxx/serializer/validating/nmtoken.cxx @@ -8,6 +8,10 @@ #include <xsde/cxx/serializer/validating/nmtoken.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -19,8 +23,15 @@ namespace xsde nmtoken_simpl:: ~nmtoken_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void nmtoken_simpl:: @@ -58,7 +69,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/nmtokens-stl.cxx b/libxsde/xsde/cxx/serializer/validating/nmtokens-stl.cxx index 9633fbe..b72ae0a 100644 --- a/libxsde/xsde/cxx/serializer/validating/nmtokens-stl.cxx +++ b/libxsde/xsde/cxx/serializer/validating/nmtokens-stl.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/validating/nmtokens-stl.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde nmtokens_simpl:: ~nmtokens_simpl () { - if (free_) - delete const_cast<string_sequence*> (value_); + if (free_ && value_) + { + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif + } } void nmtokens_simpl:: @@ -92,7 +104,13 @@ namespace xsde if (free_) { - delete const_cast<string_sequence*> (value_); + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/nmtokens.cxx b/libxsde/xsde/cxx/serializer/validating/nmtokens.cxx index 9c93ef5..bfc52be 100644 --- a/libxsde/xsde/cxx/serializer/validating/nmtokens.cxx +++ b/libxsde/xsde/cxx/serializer/validating/nmtokens.cxx @@ -5,6 +5,10 @@ #include <xsde/cxx/serializer/validating/nmtokens.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde nmtokens_simpl:: ~nmtokens_simpl () { - if (free_) - delete const_cast<string_sequence*> (value_); + if (free_ && value_) + { + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif + } } void nmtokens_simpl:: @@ -92,7 +104,13 @@ namespace xsde if (free_) { - delete const_cast<string_sequence*> (value_); + string_sequence* v = const_cast<string_sequence*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~string_sequence (); + cxx::free (v); +#endif value_ = 0; } } @@ -107,4 +125,3 @@ namespace xsde } } } - diff --git a/libxsde/xsde/cxx/serializer/validating/normalized-string.cxx b/libxsde/xsde/cxx/serializer/validating/normalized-string.cxx index 89bb32c..8d807a4 100644 --- a/libxsde/xsde/cxx/serializer/validating/normalized-string.cxx +++ b/libxsde/xsde/cxx/serializer/validating/normalized-string.cxx @@ -6,6 +6,10 @@ #include <xsde/cxx/serializer/validating/normalized-string.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde normalized_string_simpl:: ~normalized_string_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void normalized_string_simpl:: @@ -51,7 +62,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/qname.cxx b/libxsde/xsde/cxx/serializer/validating/qname.cxx index a51685e..cca29d6 100644 --- a/libxsde/xsde/cxx/serializer/validating/qname.cxx +++ b/libxsde/xsde/cxx/serializer/validating/qname.cxx @@ -9,6 +9,10 @@ #include <xsde/cxx/serializer/validating/qname.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -20,8 +24,16 @@ namespace xsde qname_simpl:: ~qname_simpl () { - if (free_) - delete const_cast<qname*> (value_); + if (free_ && value_) + { + qname* v = const_cast<qname*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~qname (); + cxx::free (v); +#endif + } } void qname_simpl:: @@ -69,7 +81,13 @@ namespace xsde if (free_) { - delete const_cast<qname*> (value_); + qname* v = const_cast<qname*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete v; +#else + v->~qname (); + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/string.cxx b/libxsde/xsde/cxx/serializer/validating/string.cxx index a8d287e..a8f6dfa 100644 --- a/libxsde/xsde/cxx/serializer/validating/string.cxx +++ b/libxsde/xsde/cxx/serializer/validating/string.cxx @@ -6,6 +6,10 @@ #include <xsde/cxx/serializer/validating/string.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde string_simpl:: ~string_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void string_simpl:: @@ -38,7 +49,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/token.cxx b/libxsde/xsde/cxx/serializer/validating/token.cxx index 30e98f8..d38ef33 100644 --- a/libxsde/xsde/cxx/serializer/validating/token.cxx +++ b/libxsde/xsde/cxx/serializer/validating/token.cxx @@ -6,6 +6,10 @@ #include <xsde/cxx/serializer/validating/token.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde token_simpl:: ~token_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void token_simpl:: @@ -63,7 +74,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/serializer/validating/uri.cxx b/libxsde/xsde/cxx/serializer/validating/uri.cxx index a1b7a86..3cfdc26 100644 --- a/libxsde/xsde/cxx/serializer/validating/uri.cxx +++ b/libxsde/xsde/cxx/serializer/validating/uri.cxx @@ -6,6 +6,10 @@ #include <xsde/cxx/serializer/validating/uri.hxx> #include <xsde/cxx/serializer/validating/string-common.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde uri_simpl:: ~uri_simpl () { - if (free_) - delete[] const_cast<char*> (value_); + if (free_ && value_) + { + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif + } } void uri_simpl:: @@ -42,7 +53,12 @@ namespace xsde if (free_) { - delete[] const_cast<char*> (value_); + char* v = const_cast<char*> (value_); +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] v; +#else + cxx::free (v); +#endif value_ = 0; } } diff --git a/libxsde/xsde/cxx/stack.cxx b/libxsde/xsde/cxx/stack.cxx index 936a732..9ed2270 100644 --- a/libxsde/xsde/cxx/stack.cxx +++ b/libxsde/xsde/cxx/stack.cxx @@ -19,7 +19,12 @@ namespace xsde grow () { size_t c = capacity_ ? capacity_ * 2 : 8; - char* d = new char[c * el_size_]; + +#ifndef XSDE_CUSTOM_ALLOCATOR + char* d = static_cast<char*> (operator new (c * el_size_)); +#else + char* d = static_cast<char*> (alloc (c * el_size_)); +#endif #ifndef XSDE_EXCEPTIONS if (d == 0) @@ -29,7 +34,11 @@ namespace xsde if (size_ > 1) memcpy (d, data_, (size_ - 1) * el_size_); +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] data_; +#else + cxx::free (data_); +#endif data_ = d; capacity_ = c; diff --git a/libxsde/xsde/cxx/stack.ixx b/libxsde/xsde/cxx/stack.ixx index 05c60ac..8b69407 100644 --- a/libxsde/xsde/cxx/stack.ixx +++ b/libxsde/xsde/cxx/stack.ixx @@ -3,6 +3,12 @@ // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#else +# include <new> // operator new/delete +#endif + namespace xsde { namespace cxx @@ -10,7 +16,12 @@ namespace xsde inline stack:: ~stack () { - delete[] data_; + if (data_) +#ifndef XSDE_CUSTOM_ALLOCATOR + operator delete (data_); +#else + cxx::free (data_); +#endif } inline stack:: diff --git a/libxsde/xsde/cxx/strdupx.cxx b/libxsde/xsde/cxx/strdupx.cxx index 840bf3f..c9b68c4 100644 --- a/libxsde/xsde/cxx/strdupx.cxx +++ b/libxsde/xsde/cxx/strdupx.cxx @@ -8,6 +8,10 @@ #include <xsde/cxx/config.hxx> #include <xsde/cxx/strdupx.hxx> +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -16,7 +20,12 @@ namespace xsde strdupx (const char* s) { size_t n = strlen (s); + +#ifndef XSDE_CUSTOM_ALLOCATOR char* r = new char[n + 1]; +#else + char* r = static_cast<char*> (alloc (n + 1)); +#endif #ifndef XSDE_EXCEPTIONS if (r) @@ -29,7 +38,11 @@ namespace xsde char* strndupx (const char* s, size_t n) { +#ifndef XSDE_CUSTOM_ALLOCATOR char* r = new char[n + 1]; +#else + char* r = static_cast<char*> (alloc (n + 1)); +#endif #ifndef XSDE_EXCEPTIONS if (r) diff --git a/libxsde/xsde/cxx/strdupx.hxx b/libxsde/xsde/cxx/strdupx.hxx index 190d519..eef6922 100644 --- a/libxsde/xsde/cxx/strdupx.hxx +++ b/libxsde/xsde/cxx/strdupx.hxx @@ -13,8 +13,9 @@ namespace xsde namespace cxx { // C++ versions of strdup and strndup. They allocate the string - // using new char[]. In the no-exceptions case return 0 if - // allocation fails. + // using new char[] (or custom allocator, if enabled). When + // exceptions are disabled these functions return 0 if allocation + // fails. // char* strdupx (const char*); diff --git a/libxsde/xsde/cxx/string-sequence.cxx b/libxsde/xsde/cxx/string-sequence.cxx index d10ec34..5387e79 100644 --- a/libxsde/xsde/cxx/string-sequence.cxx +++ b/libxsde/xsde/cxx/string-sequence.cxx @@ -3,8 +3,9 @@ // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <string.h> // memcpy, strlen, strcmp +#include <string.h> // strcmp +#include <xsde/cxx/strdupx.hxx> #include <xsde/cxx/string-sequence.hxx> namespace xsde @@ -15,7 +16,11 @@ namespace xsde clear () { for (size_t i = 0; i < size_; ++i) +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] static_cast<char**> (data_)[i]; +#else + cxx::free (static_cast<char**> (data_)[i]); +#endif size_ = 0; } @@ -27,11 +32,7 @@ namespace xsde if (capacity_ < size_ + 1) grow_ (0, sizeof (char*), 0); - size_t n = strlen (cs) + 1; - char* s = new char[n]; - memcpy (s, cs, n); - - static_cast<char**> (data_)[size_++] = s; + static_cast<char**> (data_)[size_++] = strdupx (cs); } #else string_sequence::error string_sequence:: @@ -44,14 +45,10 @@ namespace xsde if (r == error_none) { - size_t n = strlen (cs) + 1; - char* s = new char[n]; + char* s = strdupx (cs); if (s != 0) - { - memcpy (s, cs, n); static_cast<char**> (data_)[size_++] = s; - } else r = error_no_memory; } diff --git a/libxsde/xsde/cxx/string-sequence.ixx b/libxsde/xsde/cxx/string-sequence.ixx index 4c7f42d..b902bd7 100644 --- a/libxsde/xsde/cxx/string-sequence.ixx +++ b/libxsde/xsde/cxx/string-sequence.ixx @@ -3,6 +3,10 @@ // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -90,14 +94,22 @@ namespace xsde inline void string_sequence:: pop_back () { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] static_cast<char**> (data_)[size_ - 1]; +#else + cxx::free (static_cast<char**> (data_)[size_ - 1]); +#endif --size_; } inline string_sequence::iterator string_sequence:: erase (iterator i) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] *i; +#else + cxx::free (*i); +#endif if (i != static_cast<char**> (data_) + (size_ - 1)) erase_ (i, sizeof (char*), 0); @@ -112,7 +124,15 @@ namespace xsde { struct guard { - ~guard () { delete[] p_; } + ~guard () + { +#ifndef XSDE_CUSTOM_ALLOCATOR + delete[] p_; +#else + cxx::free (p_); +#endif + } + guard (char* p) : p_ (p) {} void @@ -164,7 +184,11 @@ namespace xsde if (r == error_none) static_cast<char**> (data_)[size_++] = x; else +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] x; +#else + cxx::free (x); +#endif return r; } @@ -181,7 +205,11 @@ namespace xsde } else { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] x; +#else + cxx::free (x); +#endif return error_no_memory; } } @@ -199,7 +227,11 @@ namespace xsde } else { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] x; +#else + cxx::free (x); +#endif return error_no_memory; } } @@ -225,7 +257,12 @@ namespace xsde inline void string_sequence:: attach (iterator p, char* x) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] *p; +#else + cxx::free (*p); +#endif + *p = x; } diff --git a/libxsde/xsde/cxx/string.cxx b/libxsde/xsde/cxx/string.cxx index 5284220..02c8d04 100644 --- a/libxsde/xsde/cxx/string.cxx +++ b/libxsde/xsde/cxx/string.cxx @@ -56,7 +56,11 @@ namespace xsde else new_cap += (new_cap & 1) ? 1 : 0; // Make even. +#ifndef XSDE_CUSTOM_ALLOCATOR char* p = new char[new_cap]; +#else + char* p = static_cast<char*> (alloc (new_cap)); +#endif if (p == 0) return error_no_memory; @@ -64,7 +68,11 @@ namespace xsde if (copy && size_ != 0) memcpy (p, data_, size_ + 1); +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] data_; +#else + cxx::free (data_); +#endif data_ = p; capacity_ = new_cap; diff --git a/libxsde/xsde/cxx/string.ixx b/libxsde/xsde/cxx/string.ixx index ce479bb..f8f8378 100644 --- a/libxsde/xsde/cxx/string.ixx +++ b/libxsde/xsde/cxx/string.ixx @@ -5,6 +5,12 @@ #include <string.h> +#include <xsde/cxx/config.hxx> + +#ifdef XSDE_CUSTOM_ALLOCATOR +# include <xsde/cxx/allocator.hxx> +#endif + namespace xsde { namespace cxx @@ -12,7 +18,11 @@ namespace xsde inline string:: ~string () { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] data_; +#else + cxx::free (data_); +#endif } inline string:: @@ -40,7 +50,11 @@ namespace xsde inline void string:: attach (char* s, size_t n) { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] data_; +#else + cxx::free (data_); +#endif data_ = s; size_ = n; diff --git a/libxsde/xsde/makefile b/libxsde/xsde/makefile index f313347..2ec1c41 100644 --- a/libxsde/xsde/makefile +++ b/libxsde/xsde/makefile @@ -8,12 +8,24 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make c_tun := c/expat/xmlparse.c c/expat/xmlrole.c c/expat/xmltok.c c_tun += c/genx/genx.c c/genx/char-props.c +ifeq ($(xsde_custom_allocator),y) +ifeq ($(xsde_default_allocator),y) +c_tun += allocator.c +endif +endif + cxx_tun := \ cxx/string.cxx \ cxx/string-search.cxx \ cxx/ro-string.cxx \ cxx/stack.cxx +ifeq ($(xsde_custom_allocator),y) +ifeq ($(xsde_exceptions),y) +cxx_tun += cxx/allocator.cxx +endif +endif + ifeq ($(xsde_encoding),iso8859-1) cxx_tun += cxx/iso8859-1.cxx endif @@ -592,6 +604,16 @@ ifeq ($(xsde_reuse_style),none) else @echo '#undef XSDE_REUSE_STYLE_NONE' >>$@ endif +ifeq ($(xsde_custom_allocator),y) + @echo '#define XSDE_CUSTOM_ALLOCATOR' >>$@ +else + @echo '#undef XSDE_CUSTOM_ALLOCATOR' >>$@ +endif +ifeq ($(xsde_default_allocator),y) + @echo '#define XSDE_DEFAULT_ALLOCATOR' >>$@ +else + @echo '#undef XSDE_DEFAULT_ALLOCATOR' >>$@ +endif ifeq ($(xsde_polymorphic),y) @echo '#define XSDE_POLYMORPHIC' >>$@ @echo '#define XSDE_PARSER_SMAP_BUCKETS $(xsde_parser_smap_buckets)UL' >>$@ @@ -618,6 +640,8 @@ $(out_base)/: $(xsde.l) # Dist. # $(dist): + $(call install-data,$(src_base)/allocator.h,$(dist_prefix)/libxsde/xsde/allocator.h) + $(call install-data,$(src_base)/allocator.c,$(dist_prefix)/libxsde/xsde/allocator.c) $(call install-dir,$(src_base)/c,$(dist_prefix)/libxsde/xsde/c,\( -name '*.h' -o -name '*.c' -o -name COPYING \)) $(call install-dir,$(src_base)/cxx,$(dist_prefix)/libxsde/xsde/cxx,-name '*.?xx') diff --git a/xsde/cxx/elements.cxx b/xsde/cxx/elements.cxx index 49d7f34..3da9392 100644 --- a/xsde/cxx/elements.cxx +++ b/xsde/cxx/elements.cxx @@ -125,6 +125,7 @@ namespace CXX Containers::Vector<NarrowString> const& ir, Boolean trace_include_regex_, Boolean inline_, + Boolean custom_allocator, Containers::Vector<NarrowString> const& reserved_name) : os (o), schema_root (root), @@ -139,6 +140,7 @@ namespace CXX type_exp (type_exp_), inst_exp (inst_exp_), inl (inl_), + custom_alloc (custom_allocator), ns_mapping_cache (ns_mapping_cache_), schema_path_ (path), xs_ns_ (0), diff --git a/xsde/cxx/elements.hxx b/xsde/cxx/elements.hxx index a708cca..098bd84 100644 --- a/xsde/cxx/elements.hxx +++ b/xsde/cxx/elements.hxx @@ -159,6 +159,7 @@ namespace CXX Containers::Vector<NarrowString> const& include_regex, Boolean trace_include_regex_, Boolean inline_, + Boolean custom_allocator, Containers::Vector<NarrowString> const& reserved_name); protected: @@ -176,6 +177,7 @@ namespace CXX type_exp (c.type_exp), inst_exp (c.inst_exp), inl (c.inl), + custom_alloc (c.custom_alloc), ns_mapping_cache (c.ns_mapping_cache), xs_ns_ (c.xs_ns_), cxx_id_expr (c.cxx_id_expr), @@ -204,6 +206,7 @@ namespace CXX type_exp (c.type_exp), inst_exp (c.inst_exp), inl (c.inl), + custom_alloc (c.custom_alloc), ns_mapping_cache (c.ns_mapping_cache), xs_ns_ (c.xs_ns_), cxx_id_expr (c.cxx_id_expr), @@ -338,6 +341,8 @@ namespace CXX String& inst_exp; String& inl; + Boolean custom_alloc; + public: MappingCache& ns_mapping_cache; diff --git a/xsde/cxx/hybrid/cli.hxx b/xsde/cxx/hybrid/cli.hxx index 3834767..5de1692 100644 --- a/xsde/cxx/hybrid/cli.hxx +++ b/xsde/cxx/hybrid/cli.hxx @@ -44,6 +44,7 @@ namespace CXX extern Key generate_xml_schema; extern Key extern_xml_schema; extern Key suppress_reset; + extern Key custom_allocator; extern Key generate_polymorphic; extern Key runtime_polymorphic; extern Key polymorphic_type; @@ -134,6 +135,7 @@ namespace CXX generate_xml_schema, Boolean, extern_xml_schema, NarrowString, suppress_reset, Boolean, + custom_allocator, Boolean, generate_polymorphic, Boolean, runtime_polymorphic, Boolean, polymorphic_type, Cult::Containers::Vector<NarrowString>, diff --git a/xsde/cxx/hybrid/default-value.cxx b/xsde/cxx/hybrid/default-value.cxx index a255c92..58a5507 100644 --- a/xsde/cxx/hybrid/default-value.cxx +++ b/xsde/cxx/hybrid/default-value.cxx @@ -499,7 +499,29 @@ namespace CXX member_ = "tmp."; else { - os << "tmp = new " << fq_name (t) << ";"; + String tn (fq_name (t)); + + if (!custom_alloc) + os << "tmp = new " << tn << ";"; + else + { + os << "tmp = static_cast< " << tn << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << tn << ")));"; + + if (exceptions) + os << "::xsde::cxx::alloc_guard tmpg (tmp);"; + else + os << endl + << "if (tmp)" << endl; + + os << "new (tmp) " << fq_name (t) << ";"; + + if (exceptions) + os << "tmpg.release ();"; + else + os << endl; + + } if (!exceptions) { diff --git a/xsde/cxx/hybrid/elements.cxx b/xsde/cxx/hybrid/elements.cxx index 3607c37..fe5c97e 100644 --- a/xsde/cxx/hybrid/elements.cxx +++ b/xsde/cxx/hybrid/elements.cxx @@ -32,6 +32,7 @@ namespace CXX ops.value<CLI::include_regex> (), ops.value<CLI::include_regex_trace> (), ops.value<CLI::generate_inline> (), + ops.value<CLI::custom_allocator> (), ops.value<CLI::reserved_name> ()), options (ops), exceptions (!ops.value<CLI::no_exceptions> ()), diff --git a/xsde/cxx/hybrid/elements.hxx b/xsde/cxx/hybrid/elements.hxx index 01030d5..60211e8 100644 --- a/xsde/cxx/hybrid/elements.hxx +++ b/xsde/cxx/hybrid/elements.hxx @@ -1611,76 +1611,63 @@ namespace CXX String xs_ns_; }; - struct TypeOps: Traversal::Type, - Traversal::AnyType, - Traversal::AnySimpleType, - - Traversal::Fundamental::Byte, - Traversal::Fundamental::UnsignedByte, - Traversal::Fundamental::Short, - Traversal::Fundamental::UnsignedShort, - Traversal::Fundamental::Int, - Traversal::Fundamental::UnsignedInt, - Traversal::Fundamental::Long, - Traversal::Fundamental::UnsignedLong, - Traversal::Fundamental::Integer, - Traversal::Fundamental::NonPositiveInteger, - Traversal::Fundamental::NonNegativeInteger, - Traversal::Fundamental::PositiveInteger, - Traversal::Fundamental::NegativeInteger, - - Traversal::Fundamental::Boolean, - - Traversal::Fundamental::Float, - Traversal::Fundamental::Double, - Traversal::Fundamental::Decimal, - - Traversal::Fundamental::String, - Traversal::Fundamental::NormalizedString, - Traversal::Fundamental::Token, - Traversal::Fundamental::Name, - Traversal::Fundamental::NameToken, - Traversal::Fundamental::NameTokens, - Traversal::Fundamental::NCName, - Traversal::Fundamental::Language, - - Traversal::Fundamental::QName, - - Traversal::Fundamental::Id, - Traversal::Fundamental::IdRef, - Traversal::Fundamental::IdRefs, - - Traversal::Fundamental::AnyURI, - - Traversal::Fundamental::Base64Binary, - Traversal::Fundamental::HexBinary, - - Traversal::Fundamental::Date, - Traversal::Fundamental::DateTime, - Traversal::Fundamental::Duration, - Traversal::Fundamental::Day, - Traversal::Fundamental::Month, - Traversal::Fundamental::MonthDay, - Traversal::Fundamental::Year, - Traversal::Fundamental::YearMonth, - Traversal::Fundamental::Time, - - Traversal::Fundamental::Entity, - Traversal::Fundamental::Entities, - - Context + struct TypeOpsBase: Traversal::Type, + Traversal::AnyType, + Traversal::AnySimpleType, + + Traversal::Fundamental::Byte, + Traversal::Fundamental::UnsignedByte, + Traversal::Fundamental::Short, + Traversal::Fundamental::UnsignedShort, + Traversal::Fundamental::Int, + Traversal::Fundamental::UnsignedInt, + Traversal::Fundamental::Long, + Traversal::Fundamental::UnsignedLong, + Traversal::Fundamental::Integer, + Traversal::Fundamental::NonPositiveInteger, + Traversal::Fundamental::NonNegativeInteger, + Traversal::Fundamental::PositiveInteger, + Traversal::Fundamental::NegativeInteger, + + Traversal::Fundamental::Boolean, + + Traversal::Fundamental::Float, + Traversal::Fundamental::Double, + Traversal::Fundamental::Decimal, + + Traversal::Fundamental::String, + Traversal::Fundamental::NormalizedString, + Traversal::Fundamental::Token, + Traversal::Fundamental::Name, + Traversal::Fundamental::NameToken, + Traversal::Fundamental::NameTokens, + Traversal::Fundamental::NCName, + Traversal::Fundamental::Language, + + Traversal::Fundamental::QName, + + Traversal::Fundamental::Id, + Traversal::Fundamental::IdRef, + Traversal::Fundamental::IdRefs, + + Traversal::Fundamental::AnyURI, + + Traversal::Fundamental::Base64Binary, + Traversal::Fundamental::HexBinary, + + Traversal::Fundamental::Date, + Traversal::Fundamental::DateTime, + Traversal::Fundamental::Duration, + Traversal::Fundamental::Day, + Traversal::Fundamental::Month, + Traversal::Fundamental::MonthDay, + Traversal::Fundamental::Year, + Traversal::Fundamental::YearMonth, + Traversal::Fundamental::Time, + + Traversal::Fundamental::Entity, + Traversal::Fundamental::Entities { - enum Use - { - deref, - delete_ - }; - - TypeOps (Context& c, Use use) - : Context (c), use_ (use) - { - } - virtual Void traverse (SemanticGraph::Type& t) { @@ -1704,135 +1691,135 @@ namespace CXX // Boolean. // virtual Void - traverse (SemanticGraph::Fundamental::Boolean&) + traverse (SemanticGraph::Fundamental::Boolean& t) { - fund_type (); + fund_type (t); } // Integral types. // virtual Void - traverse (SemanticGraph::Fundamental::Byte&) + traverse (SemanticGraph::Fundamental::Byte& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::UnsignedByte&) + traverse (SemanticGraph::Fundamental::UnsignedByte& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::Short&) + traverse (SemanticGraph::Fundamental::Short& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::UnsignedShort&) + traverse (SemanticGraph::Fundamental::UnsignedShort& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::Int&) + traverse (SemanticGraph::Fundamental::Int& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::UnsignedInt&) + traverse (SemanticGraph::Fundamental::UnsignedInt& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::Long&) + traverse (SemanticGraph::Fundamental::Long& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::UnsignedLong&) + traverse (SemanticGraph::Fundamental::UnsignedLong& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::Integer&) + traverse (SemanticGraph::Fundamental::Integer& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::NonPositiveInteger&) + traverse (SemanticGraph::Fundamental::NonPositiveInteger& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::NonNegativeInteger&) + traverse (SemanticGraph::Fundamental::NonNegativeInteger& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::PositiveInteger&) + traverse (SemanticGraph::Fundamental::PositiveInteger& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::NegativeInteger&) + traverse (SemanticGraph::Fundamental::NegativeInteger& t) { - fund_type (); + fund_type (t); } // Floats. // virtual Void - traverse (SemanticGraph::Fundamental::Float&) + traverse (SemanticGraph::Fundamental::Float& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::Double&) + traverse (SemanticGraph::Fundamental::Double& t) { - fund_type (); + fund_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::Decimal&) + traverse (SemanticGraph::Fundamental::Decimal& t) { - fund_type (); + fund_type (t); } // Strings. // virtual Void - traverse (SemanticGraph::Fundamental::String&) + traverse (SemanticGraph::Fundamental::String& t) { - string_type (); + string_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::NormalizedString&) + traverse (SemanticGraph::Fundamental::NormalizedString& t) { - string_type (); + string_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::Token&) + traverse (SemanticGraph::Fundamental::Token& t) { - string_type (); + string_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::NameToken&) + traverse (SemanticGraph::Fundamental::NameToken& t) { - string_type (); + string_type (t); } virtual Void @@ -1842,21 +1829,21 @@ namespace CXX } virtual Void - traverse (SemanticGraph::Fundamental::Name&) + traverse (SemanticGraph::Fundamental::Name& t) { - string_type (); + string_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::NCName&) + traverse (SemanticGraph::Fundamental::NCName& t) { - string_type (); + string_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::Language&) + traverse (SemanticGraph::Fundamental::Language& t) { - string_type (); + string_type (t); } // Qualified name. @@ -1870,15 +1857,15 @@ namespace CXX // ID/IDREF. // virtual Void - traverse (SemanticGraph::Fundamental::Id&) + traverse (SemanticGraph::Fundamental::Id& t) { - string_type (); + string_type (t); } virtual Void - traverse (SemanticGraph::Fundamental::IdRef&) + traverse (SemanticGraph::Fundamental::IdRef& t) { - string_type (); + string_type (t); } virtual Void @@ -1890,9 +1877,9 @@ namespace CXX // URI. // virtual Void - traverse (SemanticGraph::Fundamental::AnyURI&) + traverse (SemanticGraph::Fundamental::AnyURI& t) { - string_type (); + string_type (t); } // Binary. @@ -1968,9 +1955,9 @@ namespace CXX // Entity. // virtual Void - traverse (SemanticGraph::Fundamental::Entity&) + traverse (SemanticGraph::Fundamental::Entity& t) { - string_type (); + string_type (t); } virtual Void @@ -1979,66 +1966,96 @@ namespace CXX type (t); } - private: - Void + protected: + virtual Void + type (SemanticGraph::Type&) = 0; + + virtual Void + fund_type (SemanticGraph::Type&) = 0; + + virtual Void + string_type (SemanticGraph::Type&) = 0; + }; + + struct TypeDeref: TypeOpsBase, Context + { + TypeDeref (Context& c) + : Context (c) + { + } + + protected: + virtual Void type (SemanticGraph::Type& t) { - switch (use_) - { - case deref: - { - if (!fixed_length (t)) - os << "*"; + if (!fixed_length (t)) + os << "*"; + } - break; - } - case delete_: - { - os << "delete"; - break; - } - } + virtual Void + fund_type (SemanticGraph::Type&) + { + } + + virtual Void + string_type (SemanticGraph::Type&) + { + } + }; + + struct TypeDelete: TypeOpsBase, Context + { + TypeDelete (Context& c) + : Context (c) + { } Void - fund_type () + dispatch (SemanticGraph::Node& type, String const& var) { - switch (use_) + var_ = var; + Traversal::NodeBase::dispatch (type); + } + + protected: + virtual Void + type (SemanticGraph::Type& t) + { + if (!custom_alloc) + os << "delete " << var_ << ";"; + else { - case deref: - { - break; - } - case delete_: - { - os << "delete"; - break; - } + os << "if (" << var_ << ")" + << "{" + << "typedef " << fq_name (t) << " _dtor;" + << var_ << "->~_dtor ();" + << "::xsde::cxx::free (" << var_ << ");" + << "}"; } } - Void - string_type () + virtual Void + fund_type (SemanticGraph::Type& t) { - switch (use_) + type (t); + } + + virtual Void + string_type (SemanticGraph::Type& t) + { + if (stl) + type (t); + else { - case deref: - { - break; - } - case delete_: - { - if (stl) - os << "delete"; - else - os << "delete[]"; - break; - } + if (!custom_alloc) + os << "delete[] " << var_ << ";"; + else + os << "::xsde::cxx::free (" << var_ << ");"; } } private: - Use use_; + String var_; }; // diff --git a/xsde/cxx/hybrid/extraction-source.cxx b/xsde/cxx/hybrid/extraction-source.cxx index 3b98100..1e2a602 100644 --- a/xsde/cxx/hybrid/extraction-source.cxx +++ b/xsde/cxx/hybrid/extraction-source.cxx @@ -239,15 +239,30 @@ namespace CXX { String fq (fq_name (t)); - if (exceptions) - os << "x." << name << " (new " << fq << ");"; + if (!custom_alloc) + os << fq << "* i = new " << fq << ";"; else - os << fq << "* i = new " << fq << ";" - << endl + os << fq << "* i = static_cast< " << fq << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << fq << ")));"; + + if (!exceptions) + os << endl << "if (i == 0)" << endl << "return false;" - << endl - << "x." << name << " (i);"; + << endl; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard ig (i);"; + + os << "new (i) " << fq << ";"; + + if (exceptions) + os << "ig.release ();"; + } + + os << "x." << name << " (i);"; } if (exceptions) @@ -354,15 +369,30 @@ namespace CXX { String fq (fq_name (t)); - if (exceptions) - os << "x." << name << " (new " << fq << ");"; + if (!custom_alloc) + os << fq << "* i = new " << fq << ";"; else - os << fq << "* i = new " << fq << ";" - << endl + os << fq << "* i = static_cast< " << fq << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << fq << ")));"; + + if (!exceptions) + os << endl << "if (i == 0)" << endl << "return false;" - << endl - << "x." << name << " (i);"; + << endl; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard ig (i);"; + + os << "new (i) " << fq << ";"; + + if (exceptions) + os << "ig.release ();"; + } + + os << "x." << name << " (i);"; } if (exceptions) @@ -423,15 +453,30 @@ namespace CXX { String fq (scope (a) + L"::" + etype (a)); - if (exceptions) - os << "x." << name << " (new " << fq << ");"; + if (!custom_alloc) + os << fq << "* i = new " << fq << ";"; else - os << fq << "* i = new " << fq << ";" - << endl + os << fq << "* i = static_cast< " << fq << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << fq << ")));"; + + if (!exceptions) + os << endl << "if (i == 0)" << endl << "return false;" - << endl - << "x." << name << " (i);"; + << endl; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard ig (i);"; + + os << "new (i) " << fq << ";"; + + if (exceptions) + os << "ig.release ();"; + } + + os << "x." << name << " (i);"; } if (exceptions) @@ -529,15 +574,30 @@ namespace CXX { String fq (fq_name (t)); - if (exceptions) - os << "x." << name << " (new " << fq << ");"; + if (!custom_alloc) + os << fq << "* i = new " << fq << ";"; else - os << fq << "* i = new " << fq << ";" - << endl + os << fq << "* i = static_cast< " << fq << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << fq << ")));"; + + if (!exceptions) + os << endl << "if (i == 0)" << endl << "return false;" - << endl - << "x." << name << " (i);"; + << endl; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard ig (i);"; + + os << "new (i) " << fq << ";"; + + if (exceptions) + os << "ig.release ();"; + } + + os << "x." << name << " (i);"; } if (exceptions) @@ -604,15 +664,30 @@ namespace CXX { String fq (scope (c) + L"::" + etype (c)); - if (exceptions) - os << "x." << name << " (new " << fq << ");"; + if (!custom_alloc) + os << fq << "* i = new " << fq << ";"; else - os << fq << "* i = new " << fq << ";" - << endl + os << fq << "* i = static_cast< " << fq << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << fq << ")));"; + + if (!exceptions) + os << endl << "if (i == 0)" << endl << "return false;" - << endl - << "x." << name << " (i);"; + << endl; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard ig (i);"; + + os << "new (i) " << fq << ";"; + + if (exceptions) + os << "ig.release ();"; + } + + os << "x." << name << " (i);"; } if (exceptions) @@ -681,15 +756,30 @@ namespace CXX { String fq (scope (c) + L"::" + etype (c)); - if (exceptions) - os << "x." << name << " (new " << fq << ");"; + if (!custom_alloc) + os << fq << "* i = new " << fq << ";"; else - os << fq << "* i = new " << fq << ";" - << endl + os << fq << "* i = static_cast< " << fq << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << fq << ")));"; + + if (!exceptions) + os << endl << "if (i == 0)" << endl << "return false;" - << endl - << "x." << name << " (i);"; + << endl; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard ig (i);"; + + os << "new (i) " << fq << ";"; + + if (exceptions) + os << "ig.release ();"; + } + + os << "x." << name << " (i);"; } if (exceptions) @@ -784,15 +874,30 @@ namespace CXX { String fq (scope (s) + L"::" + etype (s)); - if (exceptions) - os << "x." << name << " (new " << fq << ");"; + if (!custom_alloc) + os << fq << "* i = new " << fq << ";"; else - os << fq << "* i = new " << fq << ";" - << endl + os << fq << "* i = static_cast< " << fq << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << fq << ")));"; + + if (!exceptions) + os << endl << "if (i == 0)" << endl << "return false;" - << endl - << "x." << name << " (i);"; + << endl; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard ig (i);"; + + os << "new (i) " << fq << ";"; + + if (exceptions) + os << "ig.release ();"; + } + + os << "x." << name << " (i);"; } if (exceptions) diff --git a/xsde/cxx/hybrid/generator.cxx b/xsde/cxx/hybrid/generator.cxx index 34cfa2d..0ccbb91 100644 --- a/xsde/cxx/hybrid/generator.cxx +++ b/xsde/cxx/hybrid/generator.cxx @@ -132,6 +132,7 @@ namespace CXX extern Key generate_xml_schema = "generate-xml-schema"; extern Key extern_xml_schema = "extern-xml-schema"; extern Key suppress_reset = "suppress-reset"; + extern Key custom_allocator = "custom-allocator"; extern Key generate_polymorphic = "generate-polymorphic"; extern Key runtime_polymorphic = "runtime-polymorphic"; extern Key polymorphic_type = "polymorphic-type"; @@ -309,6 +310,11 @@ namespace CXX << " reset code." << endl; + e << "--custom-allocator" << endl + << " Generate code that uses custom allocator functions\n" + << " instead of operator new/delete." + << endl; + e << "--generate-polymorphic" << endl << " Generate polymorphism-aware code. Specify this\n" << " option if you use substitution groups or xsi:type." @@ -836,6 +842,7 @@ namespace CXX r->value<P::generate_xml_schema> () = h.value<H::generate_xml_schema> (); r->value<P::extern_xml_schema> () = h.value<H::extern_xml_schema> (); r->value<P::suppress_reset> () = h.value<H::suppress_reset> (); + r->value<P::custom_allocator> () = h.value<H::custom_allocator> (); r->value<P::generate_polymorphic> () = h.value<H::generate_polymorphic> (); r->value<P::runtime_polymorphic> () = h.value<H::runtime_polymorphic> (); r->value<P::output_dir> () = h.value<H::output_dir> (); @@ -918,6 +925,7 @@ namespace CXX r->value<S::generate_xml_schema> () = h.value<H::generate_xml_schema> (); r->value<S::extern_xml_schema> () = h.value<H::extern_xml_schema> (); r->value<S::suppress_reset> () = h.value<H::suppress_reset> (); + r->value<S::custom_allocator> () = h.value<H::custom_allocator> (); r->value<S::generate_polymorphic> () = h.value<H::generate_polymorphic> (); r->value<S::runtime_polymorphic> () = h.value<H::runtime_polymorphic> (); r->value<S::output_dir> () = h.value<H::output_dir> (); @@ -1634,6 +1642,25 @@ namespace CXX << endl; } + if (ops.value<CLI::custom_allocator> ()) + { + hxx << "#ifndef XSDE_CUSTOM_ALLOCATOR" << endl + << "#error the generated code uses custom allocator while " << + "the XSD/e runtime does not (reconfigure the runtime or " << + "remove --custom-allocator)" << endl + << "#endif" << endl + << endl; + } + else + { + hxx << "#ifdef XSDE_CUSTOM_ALLOCATOR" << endl + << "#error the XSD/e runtime uses custom allocator while " << + "the generated code does not (reconfigure the runtime or " << + "add --custom-allocator)" << endl + << "#endif" << endl + << endl; + } + // // diff --git a/xsde/cxx/hybrid/parser-name-processor.cxx b/xsde/cxx/hybrid/parser-name-processor.cxx index 15b0459..3dce6fe 100644 --- a/xsde/cxx/hybrid/parser-name-processor.cxx +++ b/xsde/cxx/hybrid/parser-name-processor.cxx @@ -47,6 +47,7 @@ namespace CXX ops.value<CLI::include_regex> (), ops.value<CLI::include_regex_trace> (), ops.value<CLI::generate_inline> (), + ops.value<CLI::custom_allocator> (), ops.value<CLI::reserved_name> ()), impl_suffix_ (ops.value<CLI::pimpl_type_suffix> ()), aggr_suffix_ (ops.value<CLI::paggr_type_suffix> ()), diff --git a/xsde/cxx/hybrid/parser-source.cxx b/xsde/cxx/hybrid/parser-source.cxx index 525f364..94f05df 100644 --- a/xsde/cxx/hybrid/parser-source.cxx +++ b/xsde/cxx/hybrid/parser-source.cxx @@ -165,14 +165,25 @@ namespace CXX if (!fl) { + String p (L"this->" + state + L".x_"); + // d-tor // os << name << "::" << endl << "~" << name << " ()" << "{" - << "if (!this->" << epstate_base (e) << ")" << endl - << "delete this->" << state << ".x_;" - << "}"; + << "if (!this->" << epstate_base (e) << " && " << p << ")"; + + if (!custom_alloc) + os << endl + << "delete " << p << ";"; + else + os << "{" + << p << "->~" << ename (e) << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << "}"; // reset // @@ -188,10 +199,16 @@ namespace CXX os << epskel (e) << "::_reset ();" << endl; - os << "if (!this->" << epstate_base (e) << ")" - << "{" - << "delete this->" << state << ".x_;" - << "this->" << state << ".x_ = 0;" + os << "if (!this->" << epstate_base (e) << " && " << p << ")" + << "{"; + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << p << "->~" << ename (e) << " ();" + << "::xsde::cxx::free (" << p << ");"; + + os << p << " = 0;" << "}" << "}"; } @@ -269,12 +286,32 @@ namespace CXX } else { - if (exceptions) - os << "this->" << pre_impl_name (e) << " (new " << type << ");"; + if (!custom_alloc) + os << type << "* x = new " << type << ";"; else - os << type << "* x = new " << type << ";" - << "if (x)" << endl - << "this->" << pre_impl_name (e) << " (x);" + os << type << "* x = static_cast< " << type << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (!exceptions) + os << endl + << "if (x)" + << "{"; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard xg (x);"; + + os << "new (x) " << type << ";"; + + if (exceptions) + os << "xg.release ();"; + } + + os << "this->" << pre_impl_name (e) << " (x);"; + + if (!exceptions) + os << "}" << "else" << endl << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; } @@ -455,6 +492,8 @@ namespace CXX String const& member (epstate_member (l)); String item (unclash (epskel (l), "item")); + String p (L"this->" + member); + os << "// " << name << endl << "//" << endl << endl; @@ -465,7 +504,7 @@ namespace CXX << name << " (bool b)" << "{" << "this->" << base << " = b;" - << "this->" << member << " = 0;" + << p << " = 0;" << "}"; // d-tor @@ -473,31 +512,48 @@ namespace CXX os << name << "::" << endl << "~" << name << " ()" << "{" - << "if (!this->" << base << ")" << endl - << "delete this->" << member << ";" - << "}"; + << "if (!this->" << base << " && " << p << ")"; + + if (!custom_alloc) + os << endl + << "delete " << p << ";"; + else + os << "{" + << p << "->~" << ename (l) << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << "}"; // reset // if (reset) + { os << "void " << name << "::" << endl << "_reset ()" << "{" << epskel (l) << "::_reset ();" << endl - << "if (!this->" << base << ")" - << "{" - << "delete this->" << member << ";" - << "this->" << member << " = 0;" + << "if (!this->" << base << " && " << p << ")" + << "{"; + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << p << "->~" << ename (l) << " ();" + << "::xsde::cxx::free (" << p << ");"; + + os << p << " = 0;" << "}" << "}"; + } // pre_impl // os << "void " << name << "::" << endl << pre_impl_name (l) << " (" << type << "* x)" << "{" - << "this->" << member << " = x;" + << p << " = x;" << "}"; // pre @@ -506,12 +562,32 @@ namespace CXX << "pre ()" << "{"; - if (exceptions) - os << "this->" << pre_impl_name (l) << " (new " << type << ");"; + if (!custom_alloc) + os << type << "* x = new " << type << ";"; else - os << type << "* x = new " << type << ";" - << "if (x)" << endl - << "this->" << pre_impl_name (l) << " (x);" + os << type << "* x = static_cast< " << type << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (!exceptions) + os << endl + << "if (x)" + << "{"; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard xg (x);"; + + os << "new (x) " << type << ";"; + + if (exceptions) + os << "xg.release ();"; + } + + os << "this->" << pre_impl_name (l) << " (x);"; + + if (!exceptions) + os << "}" << "else" << endl << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; @@ -526,9 +602,9 @@ namespace CXX << "{"; if (exceptions) - os << "this->" << member << "->push_back (i);"; + os << p << "->push_back (i);"; else - os << "if (this->" << member << "->push_back (i))" << endl + os << "if (" << p << "->push_back (i))" << endl << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; os << "}"; @@ -540,8 +616,8 @@ namespace CXX os << ret << " " << name << "::" << endl << post_name (l) << " ()" << "{" - << type << "* r = this->" << member << ";" - << "this->" << member << " = 0;" + << type << "* r = " << p << ";" + << p << " = 0;" << "return r;" << "}"; } @@ -606,6 +682,7 @@ namespace CXX else { String const& base (epstate_base (u)); + String p (L"this->" + state + L".x_"); // c-tor // @@ -613,7 +690,7 @@ namespace CXX << name << " (bool b)" << "{" << "this->" << base << " = b;" - << "this->" << state << ".x_ = 0;" + << p << " = 0;" << "}"; // d-tor @@ -621,31 +698,48 @@ namespace CXX os << name << "::" << endl << "~" << name << " ()" << "{" - << "if (!this->" << base << ")" << endl - << "delete this->" << state << ".x_;" - << "}"; + << "if (!this->" << base << " && " << p << ")"; + + if (!custom_alloc) + os << endl + << "delete " << p << ";"; + else + os << "{" + << p << "->~" << ename (u) << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << "}"; // reset // if (reset) + { os << "void " << name << "::" << endl << "_reset ()" << "{" << epskel (u) << "::_reset ();" << endl - << "if (!this->" << base << ")" - << "{" - << "delete this->" << state << ".x_;" - << "this->" << state << ".x_ = 0;" + << "if (!this->" << base << " && " << p << ")" + << "{"; + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << p << "->~" << ename (u) << " ();" + << "::xsde::cxx::free (" << p << ");"; + + os << p << " = 0;" << "}" << "}"; + } // pre_impl // os << "void " << name << "::" << endl << pre_impl_name (u) << " (" << type << "* x)" << "{" - << "this->" << state << ".x_ = x;"; + << p << " = x;"; if (exceptions) os << "this->" << state << ".str_.assign (\"\", 0);"; @@ -664,12 +758,32 @@ namespace CXX << "pre ()" << "{"; - if (exceptions) - os << "this->" << pre_impl_name (u) << " (new " << type << ");"; + if (!custom_alloc) + os << type << "* x = new " << type << ";"; else - os << type << "* x = new " << type << ";" - << "if (x)" << endl - << "this->" << pre_impl_name (u) << " (x);" + os << type << "* x = static_cast< " << type << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (!exceptions) + os << endl + << "if (x)" + << "{"; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard xg (x);"; + + os << "new (x) " << type << ";"; + + if (exceptions) + os << "xg.release ();"; + } + + os << "this->" << pre_impl_name (u) << " (x);"; + + if (!exceptions) + os << "}" << "else" << endl << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; @@ -697,8 +811,8 @@ namespace CXX os << ret << " " << name << "::" << endl << post_name (u) << " ()" << "{" - << type << "* r = this->" << state << ".x_;" - << "this->" << state << ".x_ = 0;" + << type << "* r = " << p << ";" + << p << " = 0;" << "r->" << value << " (this->" << state << ".str_.detach ());" << "return r;" << "}"; @@ -946,17 +1060,35 @@ namespace CXX else { String const& name (ename (a)); - String const& type (etype (a)); String const& scope (fq_scope (a)); + String type (scope + L"::" + etype (a)); - if (exceptions) - os << access << name << " (new " << - scope << "::" << type << ");"; + if (!custom_alloc) + os << type << "* x = new " << type << ";"; else - os << scope << "::" << type << "* x = new " << - scope << "::" << type << ";" - << "if (x)" << endl - << access << name << " (x);" + os << type << "* x = static_cast< " << type << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (!exceptions) + os << endl + << "if (x)" + << "{"; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard xg (x);"; + + os << "new (x) " << type << ";"; + + if (exceptions) + os << "xg.release ();"; + } + + os << access << name << " (x);"; + + if (!exceptions) + os << "}" << "else" << endl << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; } @@ -981,18 +1113,17 @@ namespace CXX if (c.max () != 1) { String const& name (ename (c)); - String const& type (etype (c)); String const& access_s (access_seq (c, false)); String const& ptr (epstate_member (c)); + String type (type_scope + L"::" + etype (c)); if (fixed_length (c)) { if (exceptions) - os << access_s << name << " ().push_back (" << - type_scope << "::" << type << " ());"; + os << access_s << name << " ().push_back (" << type << " ());"; else os << "if (" << access_s << name << " ().push_back (" << - type_scope << "::" << type << " ()))" + type << " ()))" << "{" << "this->_sys_error (::xsde::cxx::sys_error::no_memory);" << "return;" @@ -1003,8 +1134,27 @@ namespace CXX } else { - os << access << ptr << " = new " << type_scope << "::" << - type << ";"; + if (!custom_alloc) + os << access << ptr << " = new " << type << ";"; + else + { + os << access << ptr << " = static_cast< " << type << + "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (exceptions) + os << "::xsde::cxx::alloc_guard ag (" << access << ptr << ");"; + else + os << endl + << "if (" << access << ptr << ")" << endl; + + os << "new (" << access << ptr << ") " << type << ";"; + + if (exceptions) + os << "ag.release ();"; + else + os << endl; + } if (exceptions) os << access_s << name << " ().push_back (" << @@ -1029,16 +1179,34 @@ namespace CXX os << access << epresent (c) << " (true);"; else { - String const& type (etype (c)); + String type (type_scope + L"::" + etype (c)); - if (exceptions) - os << access << name << " (new " << type_scope << "::" << - type << ");"; + if (!custom_alloc) + os << type << "* x = new " << type << ";"; else - os << type_scope << "::" << type << "* x = new " << - type_scope << "::" << type << ";" - << "if (x)" << endl - << access << name << " (x);" + os << type << "* x = static_cast< " << type << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (!exceptions) + os << endl + << "if (x)" + << "{"; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard xg (x);"; + + os << "new (x) " << type << ";"; + + if (exceptions) + os << "xg.release ();"; + } + + os << access << name << " (x);"; + + if (!exceptions) + os << "}" << "else" << "{" << "this->_sys_error (::xsde::cxx::sys_error::no_memory);" @@ -1103,17 +1271,35 @@ namespace CXX os << "case " << eptag (p) << ":" << "{"; - String const& type (etype (p)); String const& scope (fq_scope (p)); + String type (scope + L"::" + etype (p)); - if (exceptions) - os << access_seq (p) << ename (p) << - " (new " << scope << "::" << type << ");"; + if (!custom_alloc) + os << type << "* x = new " << type << ";"; else - os << scope << "::" << type << "* x = new " << - scope << "::" << type << ";" - << "if (x)" << endl - << access_seq (p) << ename (p) << " (x);" + os << type << "* x = static_cast< " << type << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (!exceptions) + os << endl + << "if (x)" + << "{"; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard xg (x);"; + + os << "new (x) " << type << ";"; + + if (exceptions) + os << "xg.release ();"; + } + + os << access_seq (p) << ename (p) << " (x);"; + + if (!exceptions) + os << "}" << "else" << endl << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; @@ -1144,9 +1330,9 @@ namespace CXX String const& access (access_seq (s)); String const& access_s (access_seq (s, false)); String const& name (ename (s)); - String const& type (etype (s)); String const& scope (fq_scope (s)); String const& ptr (epstate_member (s)); + String type (scope + L"::" + etype (s)); os << "void " << sc << "::" << endl << epnext (s) << " ()" @@ -1155,11 +1341,10 @@ namespace CXX if (fixed_length (s)) { if (exceptions) - os << access_s << name << " ().push_back (" << - scope << "::" << type << " ());"; + os << access_s << name << " ().push_back (" << type << " ());"; else os << "if (" << access_s << name << " ().push_back (" << - scope << "::" << type << " ()))" + type << " ()))" << "{" << "this->_sys_error (::xsde::cxx::sys_error::no_memory);" << "return;" @@ -1170,8 +1355,27 @@ namespace CXX } else { - os << access << ptr << " = new " << scope << "::" << - type << ";"; + if (!custom_alloc) + os << access << ptr << " = new " << type << ";"; + else + { + os << access << ptr << " = static_cast< " << type << + "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (exceptions) + os << "::xsde::cxx::alloc_guard ag (" << access << ptr << ");"; + else + os << endl + << "if (" << access << ptr << ")" << endl; + + os << "new (" << access << ptr << ") " << type << ";"; + + if (exceptions) + os << "ag.release ();"; + else + os << endl; + } if (exceptions) os << access_s << name << " ().push_back (" << @@ -1200,17 +1404,35 @@ namespace CXX else { String const& name (ename (s)); - String const& type (etype (s)); String const& scope (fq_scope (s)); + String type (scope + L"::" + etype (s)); - if (exceptions) - os << access << name << " (new " << - scope << "::" << type << ");"; + if (!custom_alloc) + os << type << "* x = new " << type << ";"; else - os << scope << "::" << type << "* x = new " << - scope << "::" << type << ";" - << "if (x)" << endl - << access << name << " (x);" + os << type << "* x = static_cast< " << type << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (!exceptions) + os << endl + << "if (x)" + << "{"; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard xg (x);"; + + os << "new (x) " << type << ";"; + + if (exceptions) + os << "xg.release ();"; + } + + os << access << name << " (x);"; + + if (!exceptions) + os << "}" << "else" << endl << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; } @@ -1450,17 +1672,38 @@ namespace CXX if (!rec) { - os << "if (!this->" << epstate_base (c) << ")" << endl - << "delete this->" << state << "." << member << ";"; + String p (L"this->" + state + L"." + member); + + os << "if (!this->" << epstate_base (c) << " && " << p << ")"; + + if (!custom_alloc) + os << endl + << "delete " << p << ";"; + else + os << "{" + << p << "->~" << ename (c) << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; } else { + String p (top_member); + os << "for (; !this->" << state << ".empty (); " << "this->" << state << ".pop ())" << "{" - << "if (!this->" << epstate_base (c) << ")" << endl - << "delete " << top_member << ";" - << "}"; + << "if (!this->" << epstate_base (c) << " && " << p << ")"; + + if (!custom_alloc) + os << endl + << "delete " << p << ";"; + else + os << "{" + << p << "->~" << ename (c) << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << "}"; } os << "}"; @@ -1481,22 +1724,41 @@ namespace CXX if (!rec) { - os << "if (!this->" << epstate_base (c) << ")" - << "{" - << "delete this->" << state << "." << member << ";" - << "this->" << state << "." << member << " = 0;" + String p (L"this->" + state + L"." + member); + + os << "if (!this->" << epstate_base (c) << " && " << p << ")" + << "{"; + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << p << "->~" << ename (c) << " ();" + << "::xsde::cxx::free (" << p << ");"; + + os << p << " = 0;" << "}"; } else { // Same code as in d-tor. // + String p (top_member); + os << "for (; !this->" << state << ".empty (); " << "this->" << state << ".pop ())" << "{" - << "if (!this->" << epstate_base (c) << ")" << endl - << "delete " << top_member << ";" - << "}"; + << "if (!this->" << epstate_base (c) << " && " << p << ")"; + + if (!custom_alloc) + os << endl + << "delete " << p << ";"; + else + os << "{" + << p << "->~" << ename (c) << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << "}"; } os << "}"; @@ -1633,12 +1895,32 @@ namespace CXX } else { - if (exceptions) - os << "this->" << pre_impl_name (c) << " (new " << type << ");"; + if (!custom_alloc) + os << type << "* x = new " << type << ";"; else - os << type << "* x = new " << type << ";" - << "if (x)" << endl - << "this->" << pre_impl_name (c) << " (x);" + os << type << "* x = static_cast< " << type << "* > (" << endl + << "::xsde::cxx::alloc (sizeof (" << type << ")));"; + + if (!exceptions) + os << endl + << "if (x)" + << "{"; + + if (custom_alloc) + { + if (exceptions) + os << "::xsde::cxx::alloc_guard xg (x);"; + + os << "new (x) " << type << ";"; + + if (exceptions) + os << "xg.release ();"; + } + + os << "this->" << pre_impl_name (c) << " (x);"; + + if (!exceptions) + os << "}" << "else" << endl << "this->_sys_error (::xsde::cxx::sys_error::no_memory);"; } diff --git a/xsde/cxx/hybrid/serializer-name-processor.cxx b/xsde/cxx/hybrid/serializer-name-processor.cxx index 17522cf..41f8885 100644 --- a/xsde/cxx/hybrid/serializer-name-processor.cxx +++ b/xsde/cxx/hybrid/serializer-name-processor.cxx @@ -46,6 +46,7 @@ namespace CXX ops.value<CLI::include_regex> (), ops.value<CLI::include_regex_trace> (), ops.value<CLI::generate_inline> (), + ops.value<CLI::custom_allocator> (), ops.value<CLI::reserved_name> ()), impl_suffix_ (ops.value<CLI::simpl_type_suffix> ()), aggr_suffix_ (ops.value<CLI::saggr_type_suffix> ()), diff --git a/xsde/cxx/hybrid/tree-forward.cxx b/xsde/cxx/hybrid/tree-forward.cxx index 24d7b21..dbfdd7e 100644 --- a/xsde/cxx/hybrid/tree-forward.cxx +++ b/xsde/cxx/hybrid/tree-forward.cxx @@ -628,6 +628,20 @@ namespace CXX pre (ns); names (ns); + // Custom allocator. + // + if (custom_alloc) + { + os << endl + << "// Custom allocator." << endl + << "//" << endl + << "using ::xsde::cxx::alloc;" + << "using ::xsde::cxx::free;"; + + if (exceptions) + os << "using ::xsde::cxx::alloc_guard;"; + } + // strdupx // if (!stl) @@ -718,6 +732,10 @@ namespace CXX } else { + if (ctx.custom_alloc) + ctx.os << "#include <xsde/cxx/allocator.hxx>" << endl + << endl; + if (ctx.stl) ctx.os << "#include <string>" << endl; else diff --git a/xsde/cxx/hybrid/tree-inline.cxx b/xsde/cxx/hybrid/tree-inline.cxx index 1da9261..fa55403 100644 --- a/xsde/cxx/hybrid/tree-inline.cxx +++ b/xsde/cxx/hybrid/tree-inline.cxx @@ -260,6 +260,8 @@ namespace CXX } else { + String p (L"this->" + member); + // const char* // name () const // @@ -267,7 +269,7 @@ namespace CXX << "const char* " << name << "::" << endl << value << " () const" << "{" - << "return this->" << member << ";" + << "return " << p << ";" << "}"; // char* @@ -277,7 +279,7 @@ namespace CXX << "char* " << name << "::" << endl << value << " ()" << "{" - << "return this->" << member << ";" + << "return " << p << ";" << "}"; // void @@ -286,9 +288,14 @@ namespace CXX os << inl << "void " << name << "::" << endl << value << " (char* x)" - << "{" - << "delete[] this->" << member << ";" - << "this->" << member << " = x;" + << "{"; + + if (!custom_alloc) + os << "delete[] " << p << ";"; + else + os << "::xsde::cxx::free (" << p << ");"; + + os << p << " = x;" << "}"; // char* @@ -300,8 +307,8 @@ namespace CXX << "char* " << name << "::" << endl << uc.get<String> ("value-detach") << " ()" << "{" - << "char* r = this->" << member << ";" - << "this->" << member << " = 0;" + << "char* r = " << p << ";" + << p << " = 0;" << "return r;" << "}"; } @@ -348,8 +355,8 @@ namespace CXX ro_ret_ (c, TypeName::ro_ret), ret_ (c, TypeName::ret), arg_ (c, TypeName::arg), - deref_ (c, TypeOps::deref), - delete_ (c, TypeOps::delete_), + deref_ (c), + delete_ (c), compare_value_ (c) { } @@ -425,9 +432,8 @@ namespace CXX else { os << "{"; - delete_.dispatch (t); - os << " this->" << member << ";" - << "this->" << member << " = 0;" + delete_.dispatch (t, L"this->" + member); + os << "this->" << member << " = 0;" << "}"; } } @@ -439,9 +445,8 @@ namespace CXX { os << "if (!x)" << "{"; - delete_.dispatch (t); - os << " this->" << member << ";" - << "this->" << member << " = 0;" + delete_.dispatch (t, L"this->" + member); + os << "this->" << member << " = 0;" << "}"; } } @@ -530,10 +535,7 @@ namespace CXX << "{"; if (!fl) - { - delete_.dispatch (t); - os << " this->" << member << ";"; - } + delete_.dispatch (t, L"this->" + member); os << "this->" << member << " = x;"; @@ -566,8 +568,8 @@ namespace CXX TypeName ro_ret_; TypeName ret_; TypeName arg_; - TypeOps deref_; - TypeOps delete_; + TypeDeref deref_; + TypeDelete delete_; CompareValue compare_value_; }; @@ -578,8 +580,8 @@ namespace CXX ro_ret_ (c, TypeName::ro_ret), ret_ (c, TypeName::ret), arg_ (c, TypeName::arg), - deref_ (c, TypeOps::deref), - delete_ (c, TypeOps::delete_) + deref_ (c), + delete_ (c) { } @@ -653,9 +655,8 @@ namespace CXX { os << "if (!x)" << "{"; - delete_.dispatch (t); - os << " this->" << member << ";" - << "this->" << member << " = 0;" + delete_.dispatch (t, L"this->" + member); + os << "this->" << member << " = 0;" << "}"; } @@ -699,10 +700,7 @@ namespace CXX << "{"; if (!fl) - { - delete_.dispatch (t); - os << " this->" << member << ";"; - } + delete_.dispatch (t, L"this->" + member); os << "this->" << member << " = x;"; @@ -734,8 +732,8 @@ namespace CXX TypeName ro_ret_; TypeName ret_; TypeName arg_; - TypeOps deref_; - TypeOps delete_; + TypeDeref deref_; + TypeDelete delete_; }; struct ElementInChoiceFunc: Traversal::Element, Context @@ -746,8 +744,8 @@ namespace CXX ret_ (c, TypeName::ret), arg_ (c, TypeName::arg), var_ (c, TypeName::var), - deref_ (c, TypeOps::deref), - delete_ (c, TypeOps::delete_) + deref_ (c), + delete_ (c) { } @@ -849,9 +847,8 @@ namespace CXX { os << "else if (!x)" << "{"; - delete_.dispatch (t); - os << " this->" << umember << "." << member << ";" - << "this->" << umember << "." << member << " = 0;" + delete_.dispatch (t, L"this->" + umember + L"." + member); + os << "this->" << umember << "." << member << " = 0;" << "}"; } @@ -935,10 +932,10 @@ namespace CXX } else { - os << "else" << endl; - delete_.dispatch (t); - os << " this->" << umember << "." << member << ";" - << endl + os << "else" + << "{"; + delete_.dispatch (t, L"this->" + umember + L"." + member); + os << "}" << "this->" << umember << "." << member << " = x;"; } @@ -968,8 +965,8 @@ namespace CXX TypeName ret_; TypeName arg_; TypeName var_; - TypeOps deref_; - TypeOps delete_; + TypeDeref deref_; + TypeDelete delete_; }; struct AllFunc: Traversal::All, Context @@ -1013,7 +1010,7 @@ namespace CXX // void - // preset (bool); + // present (bool); // os << inl << "void " << scope << "::" << endl @@ -1024,10 +1021,21 @@ namespace CXX os << "this->" << epresent_member (a) << " = x;"; else { + String p (L"this->" + member); + os << "if (!x)" - << "{" - << "delete this->" << member << ";" - << "this->" << member << " = 0;" + << "{"; + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << type << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << p << " = 0;" << "}"; } @@ -1083,7 +1091,18 @@ namespace CXX << "{"; if (!fl) - os << "delete this->" << member << ";"; + { + String p (L"this->" + member); + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << type << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + } os << "this->" << member << " = x;"; @@ -1206,10 +1225,21 @@ namespace CXX os << "this->" << epresent_member (c) << " = x;"; else { + String p (L"this->" + member); + os << "if (!x)" - << "{" - << "delete this->" << member << ";" - << "this->" << member << " = 0;" + << "{"; + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << type << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << p << " = 0;" << "}"; } @@ -1265,7 +1295,18 @@ namespace CXX << "{"; if (!fl) - os << "delete this->" << member << ";"; + { + String p (L"this->" + member); + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << type << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + } os << "this->" << member << " = x;"; @@ -1374,10 +1415,21 @@ namespace CXX os << "this->" << epresent_member (s) << " = x;"; else { + String p (L"this->" + member); + os << "if (!x)" - << "{" - << "delete this->" << member << ";" - << "this->" << member << " = 0;" + << "{"; + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << type << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << p << " = 0;" << "}"; } @@ -1433,7 +1485,18 @@ namespace CXX << "{"; if (!fl) - os << "delete this->" << member << ";"; + { + String p (L"this->" + member); + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << type << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + } os << "this->" << member << " = x;"; @@ -1562,10 +1625,21 @@ namespace CXX } else { + String p (L"this->" + umember + L"." + member); + os << "else if (!x)" - << "{" - << "delete this->" << umember << "." << member << ";" - << "this->" << umember << "." << member << " = 0;" + << "{"; + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << type << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << p << " = 0;" << "}"; } @@ -1638,10 +1712,22 @@ namespace CXX } else { - os << "else" << endl - << "delete this->" << umember << "." << member << ";" - << endl - << "this->" << umember << "." << member << " = x;"; + String p (L"this->" + umember + L"." + member); + + os << "else"; + + if (!custom_alloc) + os << endl + << "delete " << p << ";" + << endl; + else + os << " if (" << p << ")" + << "{" + << p << "->~" << type << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + + os << p << " = x;"; } os << "}"; diff --git a/xsde/cxx/hybrid/tree-name-processor.cxx b/xsde/cxx/hybrid/tree-name-processor.cxx index 95aab7b..8fa6aa6 100644 --- a/xsde/cxx/hybrid/tree-name-processor.cxx +++ b/xsde/cxx/hybrid/tree-name-processor.cxx @@ -49,6 +49,7 @@ namespace CXX ops.value<CLI::include_regex> (), ops.value<CLI::include_regex_trace> (), ops.value<CLI::generate_inline> (), + ops.value<CLI::custom_allocator> (), ops.value<CLI::reserved_name> ()), stl (!ops.value<CLI::no_stl> ()), detach (ops.value<CLI::generate_detach> ()), diff --git a/xsde/cxx/hybrid/tree-source.cxx b/xsde/cxx/hybrid/tree-source.cxx index ba2562d..5887d32 100644 --- a/xsde/cxx/hybrid/tree-source.cxx +++ b/xsde/cxx/hybrid/tree-source.cxx @@ -252,8 +252,14 @@ namespace CXX << "{"; if (!stl) - os << "delete[] this->" << - u.context ().get<String> ("value-member") << ";"; + { + String p (L"this->" + u.context ().get<String> ("value-member")); + + if (!custom_alloc) + os << "delete[] " << p << ";"; + else + os << "::xsde::cxx::free (" << p << ");"; + } os << "}"; @@ -382,7 +388,7 @@ namespace CXX : Context (c), action_ (action), var_ (c, TypeName::var), - delete_ (c, TypeOps::delete_) + delete_ (c) { } @@ -487,10 +493,7 @@ namespace CXX << "~_dtor ();"; } else - { - delete_.dispatch (t); - os << " this->" << umember << "." << member << ";"; - } + delete_.dispatch (t, L"this->" + umember + L"." + member); } break; @@ -626,15 +629,26 @@ namespace CXX } else { + String const& type (etype (c)); + if (fixed_length (c)) { - String const& type (etype (c)); - os << "reinterpret_cast< " << type << "& > (this->" << umember << "." << member << ").~" << type << " ();"; } else - os << "delete this->" << umember << "." << member << ";"; + { + String p (L"this->" + umember + L"." + member); + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << type << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + } } break; @@ -691,7 +705,7 @@ namespace CXX private: Action action_; TypeName var_; - TypeOps delete_; + TypeDelete delete_; }; // @@ -927,7 +941,7 @@ namespace CXX struct AttributeDtor: Traversal::Attribute, Context { AttributeDtor (Context& c) - : Context (c), delete_ (c, TypeOps::delete_) + : Context (c), delete_ (c) { } @@ -939,22 +953,19 @@ namespace CXX SemanticGraph::Type& t (a.type ()); if (!fixed_length (t)) - { - delete_.dispatch (t); - os << " this->" << emember (a) << ";"; - } + delete_.dispatch (t, L"this->" + emember (a)); } } private: - TypeOps delete_; + TypeDelete delete_; }; struct ElementDtor: Traversal::Element, Context { ElementDtor (Context& c) - : Context (c), delete_ (c, TypeOps::delete_) + : Context (c), delete_ (c) { } @@ -966,15 +977,12 @@ namespace CXX SemanticGraph::Type& t (e.type ()); if (!fixed_length (t)) - { - delete_.dispatch (t); - os << " this->" << emember (e) << ";"; - } + delete_.dispatch (t, L"this->" + emember (e)); } } private: - TypeOps delete_; + TypeDelete delete_; }; struct AllDtor: Traversal::All, Context @@ -993,7 +1001,18 @@ namespace CXX if (a.min () == 0) { if (!fixed_length (a)) - os << "delete this->" << emember (a) << ";"; + { + String p (L"this->" + emember (a)); + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << etype (a) << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + } } else All::contains (a); @@ -1015,7 +1034,18 @@ namespace CXX if (c.min () == 0) { if (!fixed_length (c)) - os << "delete this->" << emember (c) << ";"; + { + String p (L"this->" + emember (c)); + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << etype (c) << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + } } else { @@ -1041,7 +1071,18 @@ namespace CXX if (s.min () == 0) { if (!fixed_length (s)) - os << "delete this->" << emember (s) << ";"; + { + String p (L"this->" + emember (s)); + + if (!custom_alloc) + os << "delete " << p << ";"; + else + os << "if (" << p << ")" + << "{" + << p << "->~" << etype (s) << " ();" + << "::xsde::cxx::free (" << p << ");" + << "}"; + } } else Sequence::contains (s); diff --git a/xsde/cxx/hybrid/tree-type-map.cxx b/xsde/cxx/hybrid/tree-type-map.cxx index 12b83de..cf36ce2 100644 --- a/xsde/cxx/hybrid/tree-type-map.cxx +++ b/xsde/cxx/hybrid/tree-type-map.cxx @@ -40,6 +40,7 @@ namespace CXX ops.value<CLI::include_regex> (), ops.value<CLI::include_regex_trace> (), ops.value<CLI::generate_inline> (), + ops.value<CLI::custom_allocator> (), ops.value<CLI::reserved_name> ()) { } diff --git a/xsde/cxx/parser/cli.hxx b/xsde/cxx/parser/cli.hxx index a50c3ff..d4d42c7 100644 --- a/xsde/cxx/parser/cli.hxx +++ b/xsde/cxx/parser/cli.hxx @@ -36,6 +36,7 @@ namespace CXX extern Key generate_polymorphic; extern Key runtime_polymorphic; extern Key suppress_reset; + extern Key custom_allocator; extern Key generate_noop_impl; extern Key generate_print_impl; extern Key generate_test_driver; @@ -99,6 +100,7 @@ namespace CXX generate_polymorphic, Boolean, runtime_polymorphic, Boolean, suppress_reset, Boolean, + custom_allocator, Boolean, generate_noop_impl, Boolean, generate_print_impl, Boolean, generate_test_driver, Boolean, diff --git a/xsde/cxx/parser/elements.cxx b/xsde/cxx/parser/elements.cxx index 0b98370..7cf1fec 100644 --- a/xsde/cxx/parser/elements.cxx +++ b/xsde/cxx/parser/elements.cxx @@ -32,6 +32,7 @@ namespace CXX ops.value<CLI::include_regex> (), ops.value<CLI::include_regex_trace> (), ops.value<CLI::generate_inline> (), + ops.value<CLI::custom_allocator> (), ops.value<CLI::reserved_name> ()), options (ops), xml_parser (xml_parser_), diff --git a/xsde/cxx/parser/generator.cxx b/xsde/cxx/parser/generator.cxx index c8a9f68..74ba2ea 100644 --- a/xsde/cxx/parser/generator.cxx +++ b/xsde/cxx/parser/generator.cxx @@ -125,6 +125,7 @@ namespace CXX extern Key generate_polymorphic = "generate-polymorphic"; extern Key runtime_polymorphic = "runtime-polymorphic"; extern Key suppress_reset = "suppress-reset"; + extern Key custom_allocator = "custom-allocator"; extern Key generate_noop_impl = "generate-noop-impl"; extern Key generate_print_impl = "generate-print-impl"; extern Key generate_test_driver = "generate-test-driver"; @@ -246,6 +247,11 @@ namespace CXX << " Suppress the generation of parser reset code." << endl; + e << "--custom-allocator" << endl + << " Generate code that uses custom allocator functions\n" + << " instead of operator new/delete." + << endl; + e << "--generate-noop-impl" << endl << " Generate a sample parser implementation that\n" << " does nothing (no operation)." @@ -1396,6 +1402,25 @@ namespace CXX << endl; } + if (ops.value<CLI::custom_allocator> ()) + { + hxx << "#ifndef XSDE_CUSTOM_ALLOCATOR" << endl + << "#error the generated code uses custom allocator while " << + "the XSD/e runtime does not (reconfigure the runtime or " << + "remove --custom-allocator)" << endl + << "#endif" << endl + << endl; + } + else + { + hxx << "#ifdef XSDE_CUSTOM_ALLOCATOR" << endl + << "#error the XSD/e runtime uses custom allocator while " << + "the generated code does not (reconfigure the runtime or " << + "add --custom-allocator)" << endl + << "#endif" << endl + << endl; + } + // // diff --git a/xsde/cxx/parser/name-processor.cxx b/xsde/cxx/parser/name-processor.cxx index 2cd1020..42b2863 100644 --- a/xsde/cxx/parser/name-processor.cxx +++ b/xsde/cxx/parser/name-processor.cxx @@ -45,6 +45,7 @@ namespace CXX ops.value<CLI::include_regex> (), ops.value<CLI::include_regex_trace> (), ops.value<CLI::generate_inline> (), + ops.value<CLI::custom_allocator> (), ops.value<CLI::reserved_name> ()), skel_suffix_ (ops.value<CLI::skel_type_suffix> ()), impl_suffix_ (ops.value<CLI::impl_type_suffix> ()), diff --git a/xsde/cxx/parser/parser-header.cxx b/xsde/cxx/parser/parser-header.cxx index 5062337..e3b4aeb 100644 --- a/xsde/cxx/parser/parser-header.cxx +++ b/xsde/cxx/parser/parser-header.cxx @@ -1589,6 +1589,21 @@ namespace CXX String const c (char_type); + // Custom allocator. + // + if (custom_alloc) + { + os << "// Custom allocator." << endl + << "//" << endl + << "using ::xsde::cxx::alloc;" + << "using ::xsde::cxx::free;"; + + if (exceptions) + os << "using ::xsde::cxx::alloc_guard;"; + + os << endl; + } + os << "// Built-in XML Schema types mapping." << endl << "//" << endl << "using ::xsde::cxx::string_sequence;" @@ -1739,8 +1754,10 @@ namespace CXX } else { - ctx.os << "#include <xsde/config.h>" << endl - << "#include <xsde/cxx/ro-string.hxx>" << endl; + if (ctx.custom_alloc) + ctx.os << "#include <xsde/cxx/allocator.hxx>" << endl; + + ctx.os << "#include <xsde/cxx/ro-string.hxx>" << endl; if (ctx.char_encoding == L"iso8859-1") ctx.os << "#include <xsde/cxx/iso8859-1.hxx>" << endl; diff --git a/xsde/cxx/parser/print-impl-common.hxx b/xsde/cxx/parser/print-impl-common.hxx index b997f74..13325bd 100644 --- a/xsde/cxx/parser/print-impl-common.hxx +++ b/xsde/cxx/parser/print-impl-common.hxx @@ -998,8 +998,13 @@ namespace CXX if (options.value<CLI::no_stl> () && default_type (t, xs_ns_name () + L"::qname*")) { - os << endl - << "delete " << arg_ << ";"; + os << endl; + + if (!custom_alloc) + os << "delete " << arg_ << ";"; + else + os << arg_ << "->~qname ();" + << xs_ns_name () << "::free (" << arg_ << ");"; } } @@ -1029,8 +1034,12 @@ namespace CXX { if (options.value<CLI::no_stl> () && default_type (t, "char*")) { - os << endl - << "delete[] " << arg_ << ";"; + os << endl; + + if (!custom_alloc) + os << "delete[] " << arg_ << ";"; + else + os << xs_ns_name () << "::free (" << arg_ << ");"; } } @@ -1039,8 +1048,13 @@ namespace CXX { if (default_type (t, xs_ns_name () + L"::string_sequence*")) { - os << endl - << "delete " << arg_ << ";"; + os << endl; + + if (!custom_alloc) + os << "delete " << arg_ << ";"; + else + os << arg_ << "->~string_sequence ();" + << xs_ns_name () << "::free (" << arg_ << ");"; } } @@ -1049,8 +1063,13 @@ namespace CXX { if (default_type (t, xs_ns_name () + L"::buffer*")) { - os << endl - << "delete " << arg_ << ";"; + os << endl; + + if (!custom_alloc) + os << "delete " << arg_ << ";"; + else + os << arg_ << "->~buffer ();" + << xs_ns_name () << "::free (" << arg_ << ");"; } } diff --git a/xsde/cxx/serializer/attribute-validation-source.cxx b/xsde/cxx/serializer/attribute-validation-source.cxx index 79ae256..7dea3c3 100644 --- a/xsde/cxx/serializer/attribute-validation-source.cxx +++ b/xsde/cxx/serializer/attribute-validation-source.cxx @@ -329,6 +329,7 @@ namespace CXX << "this->_start_attribute (ns, name);" << endl; else + { os << "bool r;" << "if (ns == 0 || *ns == '\\0')" << endl << "r = this->_start_attribute (name);" @@ -336,13 +337,20 @@ namespace CXX << "r = this->_start_attribute (ns, name);" << endl << "if (free)" - << "{" - << "delete[] ns;" - << "delete[] name;" - << "}" + << "{"; + + if (!custom_alloc) + os << "delete[] ns;" + << "delete[] name;"; + else + os << "::xsde::cxx::free (ns);" + << "::xsde::cxx::free (name);"; + + os << "}" << "if (!r)" << endl << "return;" << endl; + } os << "this->" << eserialize (a) << " ();" << endl diff --git a/xsde/cxx/serializer/cli.hxx b/xsde/cxx/serializer/cli.hxx index d65ca1a..ca6f779 100644 --- a/xsde/cxx/serializer/cli.hxx +++ b/xsde/cxx/serializer/cli.hxx @@ -36,6 +36,7 @@ namespace CXX extern Key generate_polymorphic; extern Key runtime_polymorphic; extern Key suppress_reset; + extern Key custom_allocator; extern Key generate_empty_impl; extern Key generate_test_driver; extern Key force_overwrite; @@ -98,6 +99,7 @@ namespace CXX generate_polymorphic, Boolean, runtime_polymorphic, Boolean, suppress_reset, Boolean, + custom_allocator, Boolean, generate_empty_impl, Boolean, generate_test_driver, Boolean, force_overwrite, Boolean, diff --git a/xsde/cxx/serializer/element-validation-source.cxx b/xsde/cxx/serializer/element-validation-source.cxx index b39fed7..ea5fec2 100644 --- a/xsde/cxx/serializer/element-validation-source.cxx +++ b/xsde/cxx/serializer/element-validation-source.cxx @@ -736,6 +736,7 @@ namespace CXX << "this->_start_element (ns, name);" << endl; else + { os << "bool r;" << "if (ns == 0 || *ns == '\\0')" << endl << "r = this->_start_element (name);" @@ -743,13 +744,20 @@ namespace CXX << "r = this->_start_element (ns, name);" << endl << "if (free)" - << "{" - << "delete[] ns;" - << "delete[] name;" - << "}" + << "{"; + + if (!custom_alloc) + os << "delete[] ns;" + << "delete[] name;"; + else + os << "::xsde::cxx::free (ns);" + << "::xsde::cxx::free (name);"; + + os << "}" << "if (!r)" << endl << "return;" << endl; + } os << "this->" << eserialize (a) << " ();" << endl diff --git a/xsde/cxx/serializer/elements.cxx b/xsde/cxx/serializer/elements.cxx index 12a715c..5395953 100644 --- a/xsde/cxx/serializer/elements.cxx +++ b/xsde/cxx/serializer/elements.cxx @@ -32,6 +32,7 @@ namespace CXX ops.value<CLI::include_regex> (), ops.value<CLI::include_regex_trace> (), ops.value<CLI::generate_inline> (), + ops.value<CLI::custom_allocator> (), ops.value<CLI::reserved_name> ()), options (ops), xml_serializer (xml_serializer_), diff --git a/xsde/cxx/serializer/generator.cxx b/xsde/cxx/serializer/generator.cxx index 92e5197..5c94c98 100644 --- a/xsde/cxx/serializer/generator.cxx +++ b/xsde/cxx/serializer/generator.cxx @@ -123,6 +123,7 @@ namespace CXX extern Key generate_polymorphic = "generate-polymorphic"; extern Key runtime_polymorphic = "runtime-polymorphic"; extern Key suppress_reset = "suppress-reset"; + extern Key custom_allocator = "custom-allocator"; extern Key generate_empty_impl = "generate-empty-impl"; extern Key generate_test_driver = "generate-test-driver"; extern Key force_overwrite = "force-overwrite"; @@ -243,6 +244,11 @@ namespace CXX << " Suppress the generation of serializer reset code." << endl; + e << "--custom-allocator" << endl + << " Generate code that uses custom allocator functions\n" + << " instead of operator new/delete." + << endl; + e << "--generate-empty-impl" << endl << " Generate a sample serializer implementation with\n" << " empty function bodies." @@ -1382,6 +1388,25 @@ namespace CXX << endl; } + if (ops.value<CLI::custom_allocator> ()) + { + hxx << "#ifndef XSDE_CUSTOM_ALLOCATOR" << endl + << "#error the generated code uses custom allocator while " << + "the XSD/e runtime does not (reconfigure the runtime or " << + "remove --custom-allocator)" << endl + << "#endif" << endl + << endl; + } + else + { + hxx << "#ifdef XSDE_CUSTOM_ALLOCATOR" << endl + << "#error the XSD/e runtime uses custom allocator while " << + "the generated code does not (reconfigure the runtime or " << + "add --custom-allocator)" << endl + << "#endif" << endl + << endl; + } + // // diff --git a/xsde/cxx/serializer/name-processor.cxx b/xsde/cxx/serializer/name-processor.cxx index ec4c442..f7f63a2 100644 --- a/xsde/cxx/serializer/name-processor.cxx +++ b/xsde/cxx/serializer/name-processor.cxx @@ -45,6 +45,7 @@ namespace CXX ops.value<CLI::include_regex> (), ops.value<CLI::include_regex_trace> (), ops.value<CLI::generate_inline> (), + ops.value<CLI::custom_allocator> (), ops.value<CLI::reserved_name> ()), skel_suffix_ (ops.value<CLI::skel_type_suffix> ()), impl_suffix_ (ops.value<CLI::impl_type_suffix> ()), diff --git a/xsde/cxx/serializer/serializer-header.cxx b/xsde/cxx/serializer/serializer-header.cxx index dd20289..3a10942 100644 --- a/xsde/cxx/serializer/serializer-header.cxx +++ b/xsde/cxx/serializer/serializer-header.cxx @@ -1756,6 +1756,21 @@ namespace CXX String const c (char_type); + // Custom allocator. + // + if (custom_alloc) + { + os << "// Custom allocator." << endl + << "//" << endl + << "using ::xsde::cxx::alloc;" + << "using ::xsde::cxx::free;"; + + if (exceptions) + os << "using ::xsde::cxx::alloc_guard;"; + + os << endl; + } + os << "// Built-in XML Schema types mapping." << endl << "//" << endl << "using ::xsde::cxx::string_sequence;" @@ -1898,8 +1913,9 @@ namespace CXX } else { - ctx.os << "#include <xsde/config.h>" << endl - << endl; + if (ctx.custom_alloc) + ctx.os << "#include <xsde/cxx/allocator.hxx>" << endl + << endl; // std::string or xsde::cxx::string is used in wildcard API. // diff --git a/xsde/cxx/serializer/serializer-source.cxx b/xsde/cxx/serializer/serializer-source.cxx index a5765a0..1dbe496 100644 --- a/xsde/cxx/serializer/serializer-source.cxx +++ b/xsde/cxx/serializer/serializer-source.cxx @@ -1386,10 +1386,16 @@ namespace CXX << "r = this->_start_element (ns, name);" << endl << "if (free)" - << "{" - << "delete[] ns;" - << "delete[] name;" - << "}" + << "{"; + + if (!custom_alloc) + os << "delete[] ns;" + << "delete[] name;"; + else + os << "::xsde::cxx::free (ns);" + << "::xsde::cxx::free (name);"; + + os << "}" << "if (!r)" << endl << "return;" << endl @@ -1640,10 +1646,16 @@ namespace CXX << "r = this->_start_attribute (ns, name);" << endl << "if (free)" - << "{" - << "delete[] ns;" - << "delete[] name;" - << "}" + << "{"; + + if (!custom_alloc) + os << "delete[] ns;" + << "delete[] name;"; + else + os << "::xsde::cxx::free (ns);" + << "::xsde::cxx::free (name);"; + + os << "}" << "if (!r)" << endl << "return;" << endl |