From 2e501c68a8641a2b3c430b55f13491a9c1c5d0f5 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 11 May 2010 12:20:11 +0200 Subject: Add support for custom allocators New example: examples/cxx/hybrid/allocator. --- NEWS | 8 + build/configuration.make | 4 + build/configure | 15 + build/dist | 8 + build/xsde/hybrid/xsd-cxx.make | 4 + build/xsde/parser/xsd-cxx.make | 4 + build/xsde/serializer/xsd-cxx.make | 4 + dist/build/config.make | 2 + dist/config/config.make | 18 + dist/config/config.nmake | 18 + dist/etc/evc-4.0/config.nmake | 18 + dist/etc/iphone/config-device.make | 18 + dist/etc/iphone/config-simulator.make | 18 + dist/etc/lynxos/config-4.2.make | 18 + dist/etc/lynxos/config-5.0.make | 18 + dist/etc/qnx/config-6.3-gcc-2.95.make | 18 + dist/etc/qnx/config-6.3-gcc-3.3.make | 18 + dist/etc/qnx/config-6.4.make | 18 + dist/etc/vc-8.0/config-max.nmake | 18 + dist/etc/vc-8.0/config-min.nmake | 18 + dist/etc/vc-9.0/config-max.nmake | 18 + dist/etc/vc-9.0/config-min.nmake | 18 + dist/etc/vxworks/config-5.5.1.make | 18 + dist/etc/vxworks/config-6.4-max.make | 18 + dist/etc/vxworks/config-6.4-min.make | 18 + dist/etc/vxworks/config-6.7-max.make | 18 + dist/etc/vxworks/config-6.7-min.make | 18 + dist/examples/cxx/hybrid/allocator/makefile | 81 ++++ dist/examples/cxx/hybrid/allocator/nmakefile | 77 ++++ dist/examples/cxx/hybrid/makefile | 16 +- dist/examples/cxx/hybrid/nmakefile | 17 +- dist/examples/cxx/parser/generated/makefile | 4 + dist/examples/cxx/parser/generated/nmakefile | 4 + dist/examples/cxx/parser/makefile | 11 + dist/examples/cxx/parser/nmakefile | 12 + dist/examples/cxx/serializer/makefile | 3 + dist/examples/cxx/serializer/nmakefile | 4 + dist/libxsde/xsde/makefile | 18 + dist/libxsde/xsde/nmakefile | 18 + documentation/cxx/hybrid/guide/index.xhtml | 121 ++++- documentation/cxx/parser/guide/index.xhtml | 114 ++++- documentation/cxx/serializer/guide/index.xhtml | 114 ++++- documentation/xsde.1 | 5 + documentation/xsde.xhtml | 5 + examples/cxx/hybrid/README | 11 +- examples/cxx/hybrid/allocator/README | 62 +++ examples/cxx/hybrid/allocator/arena.cxx | 167 +++++++ examples/cxx/hybrid/allocator/arena.hxx | 52 +++ examples/cxx/hybrid/allocator/driver.cxx | 325 ++++++++++++++ examples/cxx/hybrid/allocator/makefile | 108 +++++ examples/cxx/hybrid/allocator/people.xml | 28 ++ examples/cxx/hybrid/allocator/people.xsd | 37 ++ examples/cxx/hybrid/makefile | 22 +- libxsde/xsde/allocator.c | 32 ++ libxsde/xsde/allocator.h | 27 ++ libxsde/xsde/c/expat/xmlparse.c | 15 + libxsde/xsde/c/genx/genx.c | 18 + libxsde/xsde/cxx/allocator.cxx | 26 ++ libxsde/xsde/cxx/allocator.hxx | 49 ++ libxsde/xsde/cxx/allocator.ixx | 27 ++ libxsde/xsde/cxx/buffer.cxx | 20 +- libxsde/xsde/cxx/buffer.ixx | 13 +- libxsde/xsde/cxx/hashmap.cxx | 31 ++ libxsde/xsde/cxx/hashmap.hxx | 2 + libxsde/xsde/cxx/hybrid/base.hxx | 27 +- libxsde/xsde/cxx/hybrid/cdr/istream.cxx | 13 +- libxsde/xsde/cxx/hybrid/cdr/istream.txx | 25 ++ libxsde/xsde/cxx/hybrid/sequence.hxx | 14 +- libxsde/xsde/cxx/hybrid/sequence.ixx | 50 ++- libxsde/xsde/cxx/hybrid/sequence.txx | 12 +- libxsde/xsde/cxx/hybrid/xdr/istream.cxx | 23 +- libxsde/xsde/cxx/hybrid/xdr/istream.txx | 24 + libxsde/xsde/cxx/parser/expat/document.cxx | 16 + .../cxx/parser/non-validating/base64-binary.cxx | 35 +- .../xsde/cxx/parser/non-validating/hex-binary.cxx | 33 +- libxsde/xsde/cxx/parser/non-validating/id-stl.cxx | 1 - .../xsde/cxx/parser/non-validating/idrefs-stl.cxx | 34 +- libxsde/xsde/cxx/parser/non-validating/idrefs.cxx | 34 +- .../xsde/cxx/parser/non-validating/ncname-stl.cxx | 1 - .../cxx/parser/non-validating/nmtokens-stl.cxx | 34 +- .../xsde/cxx/parser/non-validating/nmtokens.cxx | 34 +- libxsde/xsde/cxx/parser/non-validating/qname.cxx | 33 +- .../cxx/parser/non-validating/xml-schema-pskel.hxx | 3 +- libxsde/xsde/cxx/parser/substitution-map.cxx | 25 ++ .../xsde/cxx/parser/validating/base64-binary.cxx | 33 +- libxsde/xsde/cxx/parser/validating/hex-binary.cxx | 33 +- libxsde/xsde/cxx/parser/validating/idrefs-stl.cxx | 34 +- libxsde/xsde/cxx/parser/validating/idrefs.cxx | 34 +- .../xsde/cxx/parser/validating/inheritance-map.cxx | 25 ++ .../xsde/cxx/parser/validating/nmtokens-stl.cxx | 34 +- libxsde/xsde/cxx/parser/validating/nmtokens.cxx | 34 +- libxsde/xsde/cxx/parser/validating/qname.cxx | 33 +- .../cxx/parser/validating/xml-schema-pskel.hxx | 3 +- libxsde/xsde/cxx/qname.cxx | 20 +- libxsde/xsde/cxx/qname.ixx | 17 + libxsde/xsde/cxx/sequence-base.cxx | 27 +- libxsde/xsde/cxx/sequence-base.ixx | 8 + libxsde/xsde/cxx/serializer/context.cxx | 16 + .../serializer/non-validating/base64-binary.cxx | 24 +- .../cxx/serializer/non-validating/hex-binary.cxx | 24 +- libxsde/xsde/cxx/serializer/non-validating/id.cxx | 22 +- .../xsde/cxx/serializer/non-validating/idref.cxx | 22 +- .../cxx/serializer/non-validating/idrefs-stl.cxx | 24 +- .../xsde/cxx/serializer/non-validating/idrefs.cxx | 25 +- .../cxx/serializer/non-validating/language.cxx | 22 +- .../xsde/cxx/serializer/non-validating/name.cxx | 22 +- .../xsde/cxx/serializer/non-validating/ncname.cxx | 22 +- .../xsde/cxx/serializer/non-validating/nmtoken.cxx | 22 +- .../cxx/serializer/non-validating/nmtokens-stl.cxx | 24 +- .../cxx/serializer/non-validating/nmtokens.cxx | 25 +- .../non-validating/normalized-string-stl.cxx | 1 - .../non-validating/normalized-string.cxx | 23 +- .../xsde/cxx/serializer/non-validating/qname.cxx | 24 +- .../xsde/cxx/serializer/non-validating/string.cxx | 22 +- .../xsde/cxx/serializer/non-validating/token.cxx | 22 +- libxsde/xsde/cxx/serializer/non-validating/uri.cxx | 22 +- libxsde/xsde/cxx/serializer/substitution-map.cxx | 49 +- .../cxx/serializer/validating/base64-binary.cxx | 24 +- .../xsde/cxx/serializer/validating/hex-binary.cxx | 24 +- libxsde/xsde/cxx/serializer/validating/id.cxx | 22 +- libxsde/xsde/cxx/serializer/validating/idref.cxx | 22 +- .../xsde/cxx/serializer/validating/idrefs-stl.cxx | 24 +- libxsde/xsde/cxx/serializer/validating/idrefs.cxx | 25 +- .../cxx/serializer/validating/inheritance-map.cxx | 25 ++ .../xsde/cxx/serializer/validating/language.cxx | 22 +- libxsde/xsde/cxx/serializer/validating/name.cxx | 22 +- libxsde/xsde/cxx/serializer/validating/ncname.cxx | 22 +- libxsde/xsde/cxx/serializer/validating/nmtoken.cxx | 22 +- .../cxx/serializer/validating/nmtokens-stl.cxx | 24 +- .../xsde/cxx/serializer/validating/nmtokens.cxx | 25 +- .../serializer/validating/normalized-string.cxx | 22 +- libxsde/xsde/cxx/serializer/validating/qname.cxx | 24 +- libxsde/xsde/cxx/serializer/validating/string.cxx | 22 +- libxsde/xsde/cxx/serializer/validating/token.cxx | 22 +- libxsde/xsde/cxx/serializer/validating/uri.cxx | 22 +- libxsde/xsde/cxx/stack.cxx | 11 +- libxsde/xsde/cxx/stack.ixx | 13 +- libxsde/xsde/cxx/strdupx.cxx | 13 + libxsde/xsde/cxx/strdupx.hxx | 5 +- libxsde/xsde/cxx/string-sequence.cxx | 19 +- libxsde/xsde/cxx/string-sequence.ixx | 39 +- libxsde/xsde/cxx/string.cxx | 8 + libxsde/xsde/cxx/string.ixx | 14 + libxsde/xsde/makefile | 24 + xsde/cxx/elements.cxx | 2 + xsde/cxx/elements.hxx | 5 + xsde/cxx/hybrid/cli.hxx | 2 + xsde/cxx/hybrid/default-value.cxx | 24 +- xsde/cxx/hybrid/elements.cxx | 1 + xsde/cxx/hybrid/elements.hxx | 353 ++++++++------- xsde/cxx/hybrid/extraction-source.cxx | 189 ++++++-- xsde/cxx/hybrid/generator.cxx | 27 ++ xsde/cxx/hybrid/parser-name-processor.cxx | 1 + xsde/cxx/hybrid/parser-source.cxx | 496 ++++++++++++++++----- xsde/cxx/hybrid/serializer-name-processor.cxx | 1 + xsde/cxx/hybrid/tree-forward.cxx | 18 + xsde/cxx/hybrid/tree-inline.cxx | 212 ++++++--- xsde/cxx/hybrid/tree-name-processor.cxx | 1 + xsde/cxx/hybrid/tree-source.cxx | 93 ++-- xsde/cxx/hybrid/tree-type-map.cxx | 1 + xsde/cxx/parser/cli.hxx | 2 + xsde/cxx/parser/elements.cxx | 1 + xsde/cxx/parser/generator.cxx | 25 ++ xsde/cxx/parser/name-processor.cxx | 1 + xsde/cxx/parser/parser-header.cxx | 21 +- xsde/cxx/parser/print-impl-common.hxx | 35 +- .../cxx/serializer/attribute-validation-source.cxx | 16 +- xsde/cxx/serializer/cli.hxx | 2 + xsde/cxx/serializer/element-validation-source.cxx | 16 +- xsde/cxx/serializer/elements.cxx | 1 + xsde/cxx/serializer/generator.cxx | 25 ++ xsde/cxx/serializer/name-processor.cxx | 1 + xsde/cxx/serializer/serializer-header.cxx | 20 +- xsde/cxx/serializer/serializer-source.cxx | 28 +- 174 files changed, 4897 insertions(+), 634 deletions(-) create mode 100644 dist/examples/cxx/hybrid/allocator/makefile create mode 100644 dist/examples/cxx/hybrid/allocator/nmakefile create mode 100644 examples/cxx/hybrid/allocator/README create mode 100644 examples/cxx/hybrid/allocator/arena.cxx create mode 100644 examples/cxx/hybrid/allocator/arena.hxx create mode 100644 examples/cxx/hybrid/allocator/driver.cxx create mode 100644 examples/cxx/hybrid/allocator/makefile create mode 100644 examples/cxx/hybrid/allocator/people.xml create mode 100644 examples/cxx/hybrid/allocator/people.xsd create mode 100644 libxsde/xsde/allocator.c create mode 100644 libxsde/xsde/allocator.h create mode 100644 libxsde/xsde/cxx/allocator.cxx create mode 100644 libxsde/xsde/cxx/allocator.hxx create mode 100644 libxsde/xsde/cxx/allocator.ixx diff --git a/NEWS b/NEWS index 96dcb95..1c4718b 100644 --- a/NEWS +++ b/NEWS @@ -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 diff --git a/build/dist b/build/dist index cbb9678..bcc7c60 100755 --- a/build/dist +++ b/build/dist @@ -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 @@ 3.564-bit Integer Type 3.6Parser and Serializer Reuse 3.7Support for Polymorphism + 3.8Custom Allocators @@ -1562,6 +1563,118 @@ $ xsde cxx-hybrid --generate-parser --generate-serializer \

For information on how to use object models with polymorphic types, refer to Section 4.10, "Polymorphic Object Models".

+

3.8 Custom Allocators

+ +

By default the XSD/e runtime and generated code use + the standard operators new and delete + 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 + --custom-allocator 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 malloc(), realloc(), and + free() functions.

+ +
+extern "C" void*
+xsde_alloc (size_t);
+
+extern "C" void*
+xsde_realloc (void*, size_t);
+
+extern "C" void
+xsde_free (void*);
+  
+ +

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 + xml_schema namespace defines the following two + helper functions and, if C++ exceptions are enabled, automatic + pointer class:

+ +
+namespace xml_schema
+{
+  void*
+  alloc (size_t);
+
+  void
+  free (void*);
+
+  struct alloc_guard
+  {
+    alloc_guard (void*);
+    ~alloc_guard ();
+
+    void*
+    get () const;
+
+    void
+    release ();
+
+  private:
+    ...
+  };
+}
+  
+ +

If C++ exceptions are disabled, these functions are equivalent + to xsde_alloc() and xsde_free(). + If exceptions are enabled, xml_schema::alloc() + throws std::bad_alloc on memory allocation failure.

+ +

The following code fragment shows how to create and destroy a + dynamically-allocated object with custom allocators when C++ + exceptions are disabled:

+ +
+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);
+}
+  
+ +

The equivalent code fragment for configurations with C++ exceptions + enabled is shown below:

+ +
+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);
+}
+  
+ +

For a complete example that shows how to use custom allocators, see + the allocator example which can be found in the + examples/cxx/hybrid/ directory of the XSD/e distribution.

@@ -1882,7 +1995,9 @@ private:

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 Section 3.8, "Custom Allocators"), + the object model expects you to allocate such an object with operator new and will eventually delete it with operator delete. You can also request generation of detach functions with the --generate-detach 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.

4.3 Enumerations

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 @@ 5.564-bit Integer Type 5.6Parser Reuse 5.7Support for Polymorphism - 5.8A Minimal Example + 5.8Custom Allocators + 5.9A Minimal Example @@ -2842,7 +2843,116 @@ main () on root elements requires a number of special actions as shown in the polyroot example.

-

5.8 A Minimal Example

+

5.8 Custom Allocators

+ +

By default the XSD/e runtime and generated code use + the standard operators new and delete + 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 + --custom-allocator 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 malloc(), realloc(), and + free() functions.

+ +
+extern "C" void*
+xsde_alloc (size_t);
+
+extern "C" void*
+xsde_realloc (void*, size_t);
+
+extern "C" void
+xsde_free (void*);
+  
+ +

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 + xml_schema namespace defines the following two + helper functions and, if C++ exceptions are enabled, automatic + pointer class:

+ +
+namespace xml_schema
+{
+  void*
+  alloc (size_t);
+
+  void
+  free (void*);
+
+  struct alloc_guard
+  {
+    alloc_guard (void*);
+    ~alloc_guard ();
+
+    void*
+    get () const;
+
+    void
+    release ();
+
+  private:
+    ...
+  };
+}
+  
+ +

If C++ exceptions are disabled, these functions are equivalent + to xsde_alloc() and xsde_free(). + If exceptions are enabled, xml_schema::alloc() + throws std::bad_alloc on memory allocation failure.

+ +

The following code fragment shows how to create and destroy a + dynamically-allocated object with custom allocators when C++ + exceptions are disabled:

+ +
+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);
+}
+  
+ +

The equivalent code fragment for configurations with C++ exceptions + enabled is shown below:

+ +
+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);
+}
+  
+ +

5.9 A Minimal Example

The following example is a re-implementation of the person records example presented in 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 @@ 6.564-bit Integer Type 6.6Serializer Reuse 6.7Support for Polymorphism - 6.8A Minimal Example + 6.8Custom Allocators + 6.9A Minimal Example @@ -3664,7 +3665,116 @@ main () on root elements requires a number of special actions as shown in the polyroot example.

-

6.8 A Minimal Example

+

6.8 Custom Allocators

+ +

By default the XSD/e runtime and generated code use + the standard operators new and delete + 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 + --custom-allocator 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 malloc(), realloc(), and + free() functions.

+ +
+extern "C" void*
+xsde_alloc (size_t);
+
+extern "C" void*
+xsde_realloc (void*, size_t);
+
+extern "C" void
+xsde_free (void*);
+  
+ +

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 + xml_schema namespace defines the following two + helper functions and, if C++ exceptions are enabled, automatic + pointer class:

+ +
+namespace xml_schema
+{
+  void*
+  alloc (size_t);
+
+  void
+  free (void*);
+
+  struct alloc_guard
+  {
+    alloc_guard (void*);
+    ~alloc_guard ();
+
+    void*
+    get () const;
+
+    void
+    release ();
+
+  private:
+    ...
+  };
+}
+  
+ +

If C++ exceptions are disabled, these functions are equivalent + to xsde_alloc() and xsde_free(). + If exceptions are enabled, xml_schema::alloc() + throws std::bad_alloc on memory allocation failure.

+ +

The following code fragment shows how to create and destroy a + dynamically-allocated object with custom allocators when C++ + exceptions are disabled:

+ +
+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);
+}
+  
+ +

The equivalent code fragment for configurations with C++ exceptions + enabled is shown below:

+ +
+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);
+}
+  
+ +

6.9 A Minimal Example

The following example is a re-implementation of the person records example presented in 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 long and unsigned long. +

--custom-allocator
+
Generate code that performs memory management using custom allocator + functions provided by your application instead of the standard + operator new/delete.
+
--generate-inline
Generate simple functions inline. This option triggers creation of the inline file.
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 +// copyright : not copyrighted - public domain + +#include +#include // 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 (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 ( + reinterpret_cast (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 (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 (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 +// copyright : not copyrighted - public domain + +#ifndef ARENA_HXX +#define ARENA_HXX + +#include // 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 +// copyright : not copyrighted - public domain + +#include + +#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 +# 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 @@ + + + + + + + + John + Doe + male + 32 + + + + Jane + Doe + female + 28 + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 +// 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 + +#include + +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 +// 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 // 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 +#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 #include +#include + #include "genx.h" +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#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 +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include +#include + +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 +// 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 // size_t +#include // placement new + +#include + +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 + +#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 +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +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 (operator new (capacity)); +#ifndef XSDE_CUSTOM_ALLOCATOR + char* data = static_cast (operator new (capacity)); +#else + char* data = static_cast (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 (operator new (capacity)); +#ifndef XSDE_CUSTOM_ALLOCATOR + char* data = static_cast (operator new (capacity)); +#else + char* data = static_cast (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 // memcmp +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#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 (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#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 (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 ( operator new (sizeof (bucket) + 2 * (sizeof (element) + esize_))); +#else + p = static_cast ( + 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 ( operator new (sizeof (bucket) + c * (sizeof (element) + esize_))); +#else + bucket* n = static_cast ( + 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 // strcmp #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#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 +#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 (alloc (sizeof (T))); + alloc_guard pg (p); + new (p) T; + pg.release (); +#endif typename var_sequence::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 #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#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:: pop_back () { - delete static_cast (data_)[size_ - 1]; + T* x = static_cast (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 var_sequence:: 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 (data_) + (size_ - 1)) erase_ (i.i_, sizeof (T*), 0); @@ -582,7 +598,15 @@ namespace xsde inline void var_sequence:: 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 (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 (data_)[i]; + { + T* x = static_cast (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 (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 (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 (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 +#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 (alloc (sizeof (T))); + alloc_guard pg (p); + new (p) T; + pg.release (); +#endif typename var_sequence::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 #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #ifdef XSDE_ENCODING_ISO8859_1 # include #endif @@ -1291,7 +1295,11 @@ namespace xsde buf = data_buf_; else { +#ifndef XSDE_CUSTOM_ALLOCATOR buf = new char[iso_n]; +#else + buf = static_cast (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 (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 (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 ( + 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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 ( + 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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 ( + 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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 ( + 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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 (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 // exit #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include #include @@ -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 ( + 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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 ( + 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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 ( + 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 // exit #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include #include @@ -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 ( + 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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 ( + 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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include 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 ( + 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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include #include @@ -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 (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 // strlen, memcpy -#include // size_t - +#include #include 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 // strcmp +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#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 +#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 #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #ifdef XSDE_ENCODING_ISO8859_1 # include #endif @@ -738,7 +742,11 @@ namespace xsde buf = data_buf_; else { +#ifndef XSDE_CUSTOM_ALLOCATOR buf = new char[utf_n]; +#else + buf = static_cast (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 (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 (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde base64_binary_simpl:: ~base64_binary_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + buffer* v = const_cast (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 (value_); + buffer* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde hex_binary_simpl:: ~hex_binary_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + buffer* v = const_cast (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 (value_); + buffer* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde id_simpl:: ~id_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde idref_simpl:: ~idref_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde idrefs_simpl:: ~idrefs_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + string_sequence* v = const_cast (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 (value_); + string_sequence* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde idrefs_simpl:: ~idrefs_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + string_sequence* v = const_cast (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 (value_); + string_sequence* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde language_simpl:: ~language_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde name_simpl:: ~name_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde ncname_simpl:: ~ncname_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde nmtoken_simpl:: ~nmtoken_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde nmtokens_simpl:: ~nmtokens_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + string_sequence* v = const_cast (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 (value_); + string_sequence* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde nmtokens_simpl:: ~nmtokens_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + string_sequence* v = const_cast (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 (value_); + string_sequence* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde normalized_string_simpl:: ~normalized_string_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde qname_simpl:: ~qname_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + qname* v = const_cast (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 (value_); + qname* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde string_simpl:: ~string_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde token_simpl:: ~token_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,15 @@ namespace xsde uri_simpl:: ~uri_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 // exit #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include #include @@ -29,7 +33,14 @@ namespace xsde { for (const_iterator i (begin ()), e (end ()); i != e; ++i) { - delete *static_cast (const_cast (*i)); + hashmap* p = *static_cast (const_cast (*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 (const_cast (p)); else { +#ifndef XSDE_CUSTOM_ALLOCATOR m = new hashmap (XSDE_SERIALIZER_SMAP_BUCKET_BUCKETS, sizeof (value)); +#else + m = static_cast (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 ( + 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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde base64_binary_simpl:: ~base64_binary_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + buffer* v = const_cast (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 (value_); + buffer* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde hex_binary_simpl:: ~hex_binary_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + buffer* v = const_cast (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 (value_); + buffer* v = const_cast (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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -21,8 +25,15 @@ namespace xsde id_simpl:: ~id_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -21,8 +25,15 @@ namespace xsde idref_simpl:: ~idref_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde idrefs_simpl:: ~idrefs_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + string_sequence* v = const_cast (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 (value_); + string_sequence* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde idrefs_simpl:: ~idrefs_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + string_sequence* v = const_cast (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 (value_); + string_sequence* v = const_cast (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 // exit #endif +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + #include #include @@ -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 ( + 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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde language_simpl:: ~language_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -19,8 +23,15 @@ namespace xsde name_simpl:: ~name_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -21,8 +25,15 @@ namespace xsde ncname_simpl:: ~ncname_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -19,8 +23,15 @@ namespace xsde nmtoken_simpl:: ~nmtoken_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde nmtokens_simpl:: ~nmtokens_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + string_sequence* v = const_cast (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 (value_); + string_sequence* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -16,8 +20,16 @@ namespace xsde nmtokens_simpl:: ~nmtokens_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + string_sequence* v = const_cast (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 (value_); + string_sequence* v = const_cast (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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde normalized_string_simpl:: ~normalized_string_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -20,8 +24,16 @@ namespace xsde qname_simpl:: ~qname_simpl () { - if (free_) - delete const_cast (value_); + if (free_ && value_) + { + qname* v = const_cast (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 (value_); + qname* v = const_cast (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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde string_simpl:: ~string_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde token_simpl:: ~token_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#endif + namespace xsde { namespace cxx @@ -17,8 +21,15 @@ namespace xsde uri_simpl:: ~uri_simpl () { - if (free_) - delete[] const_cast (value_); + if (free_ && value_) + { + char* v = const_cast (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 (value_); + char* v = const_cast (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 (operator new (c * el_size_)); +#else + char* d = static_cast (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 +#else +# include // 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 #include +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#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 (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 (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 // memcpy, strlen, strcmp +#include // strcmp +#include #include namespace xsde @@ -15,7 +16,11 @@ namespace xsde clear () { for (size_t i = 0; i < size_; ++i) +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] static_cast (data_)[i]; +#else + cxx::free (static_cast (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 (data_)[size_++] = s; + static_cast (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 (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 +#endif + namespace xsde { namespace cxx @@ -90,14 +94,22 @@ namespace xsde inline void string_sequence:: pop_back () { +#ifndef XSDE_CUSTOM_ALLOCATOR delete[] static_cast (data_)[size_ - 1]; +#else + cxx::free (static_cast (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 (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 (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 (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 +#include + +#ifdef XSDE_CUSTOM_ALLOCATOR +# include +#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 const& ir, Boolean trace_include_regex_, Boolean inline_, + Boolean custom_allocator, Containers::Vector 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 const& include_regex, Boolean trace_include_regex_, Boolean inline_, + Boolean custom_allocator, Containers::Vector 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, 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 (), ops.value (), ops.value (), + ops.value (), ops.value ()), options (ops), exceptions (!ops.value ()), 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 () = h.value (); r->value () = h.value (); r->value () = h.value (); + r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); @@ -918,6 +925,7 @@ namespace CXX r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); + r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); r->value () = h.value (); @@ -1634,6 +1642,25 @@ namespace CXX << endl; } + if (ops.value ()) + { + 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 (), ops.value (), ops.value (), + ops.value (), ops.value ()), impl_suffix_ (ops.value ()), aggr_suffix_ (ops.value ()), 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 (), ops.value (), ops.value (), + ops.value (), ops.value ()), impl_suffix_ (ops.value ()), aggr_suffix_ (ops.value ()), 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 " << endl + << endl; + if (ctx.stl) ctx.os << "#include " << 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 ("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 (), ops.value (), ops.value (), + ops.value (), ops.value ()), stl (!ops.value ()), detach (ops.value ()), 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 ("value-member") << ";"; + { + String p (L"this->" + u.context ().get ("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 (), ops.value (), ops.value (), + ops.value (), ops.value ()) { } 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 (), ops.value (), ops.value (), + ops.value (), ops.value ()), 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 ()) + { + 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 (), ops.value (), ops.value (), + ops.value (), ops.value ()), skel_suffix_ (ops.value ()), impl_suffix_ (ops.value ()), 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 " << endl - << "#include " << endl; + if (ctx.custom_alloc) + ctx.os << "#include " << endl; + + ctx.os << "#include " << endl; if (ctx.char_encoding == L"iso8859-1") ctx.os << "#include " << 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 () && 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 () && 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 (), ops.value (), ops.value (), + ops.value (), ops.value ()), 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 ()) + { + 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 (), ops.value (), ops.value (), + ops.value (), ops.value ()), skel_suffix_ (ops.value ()), impl_suffix_ (ops.value ()), 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 " << endl - << endl; + if (ctx.custom_alloc) + ctx.os << "#include " << 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 -- cgit v1.1