c14n (empty) → 0.1.0.0
raw patch · 5 files changed
+471/−0 lines, 5 filesdep +basedep +bytestring
Dependencies added: base, bytestring
Files
- LICENSE +21/−0
- c14n.cabal +48/−0
- cbits/libxml.c +5/−0
- src/Text/XML/C14N.hs +146/−0
- src/Text/XML/C14N/LibXML.hsc +251/−0
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2020 Michael B. Gale++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ c14n.cabal view
@@ -0,0 +1,48 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.33.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 27cf335f30aa9127c857b841734dd2c389fc6f511adb198dfcf2052f5d9150fb++name: c14n+version: 0.1.0.0+synopsis: Bindings to the c14n implementation in libxml.+description: Please see the README on GitHub at <https://github.com/mbg/c14n#readme>+category: XML+homepage: https://github.com/mbg/c14n#readme+bug-reports: https://github.com/mbg/c14n/issues+author: Michael B. Gale+maintainer: m.gale@warwick.ac.uk+copyright: Copyright (c) Michael B. Gale+license: MIT+license-file: LICENSE+build-type: Simple++source-repository head+ type: git+ location: https://github.com/mbg/c14n++library+ exposed-modules:+ Text.XML.C14N+ Text.XML.C14N.LibXML+ other-modules:+ Paths_c14n+ hs-source-dirs:+ src+ ghc-options: -W+ c-sources:+ cbits/libxml.c+ extra-libraries:+ xml2+ build-depends:+ base >=4.8 && <5+ , bytestring+ if os(darwin)+ include-dirs:+ /usr/local/opt/libxml2/include/libxml2+ extra-lib-dirs:+ /usr/local/opt/libxml2/lib+ default-language: Haskell2010
+ cbits/libxml.c view
@@ -0,0 +1,5 @@+#include <libxml/globals.h>++void freeXml(void* p) {+ xmlFree(p);+}
+ src/Text/XML/C14N.hs view
@@ -0,0 +1,146 @@+--------------------------------------------------------------------------------+-- Haskell bindings for c14n implementation in libxml --+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE --+-- file in the root directory of this source tree. --+--------------------------------------------------------------------------------++-- | Provides a mid-level interface to libxml's implementation of c14n, i.e. +-- XML canonicalisation. +module Text.XML.C14N ( + -- * Canonicalisation+ c14n_1_0,+ c14n_exclusive_1_0,+ c14n_1_1,+ c14n,++ -- * Parsing+ xml_opt_recover, + xml_opt_noent,+ xml_opt_dtdload,+ xml_opt_dtdattr,+ xml_opt_dtdvalid,+ xml_opt_noerror,+ xml_opt_nowarning,+ xml_opt_pedantic,+ xml_opt_noblanks,+ xml_opt_sax1,+ xml_opt_xinclude,+ xml_opt_nonet,+ xml_opt_nodict,+ xml_opt_nsclean,+ xml_opt_nocdata,+ xml_opt_noxincnode,+ xml_opt_compact,+ xml_opt_old10,+ xml_opt_nobasefix,+ xml_opt_huge,+ xml_opt_oldsax,+ xml_opt_ignore_env,+ xml_opt_big_lines,+ parseXml+) where ++--------------------------------------------------------------------------------++import Control.Exception++import Data.Bits+import qualified Data.ByteString as BS+import qualified Data.ByteString.Unsafe as BS++import Text.XML.C14N.LibXML ++import Foreign.Ptr+import Foreign.ForeignPtr+import Foreign.Marshal+import Foreign.Storable+import Foreign.C.Error+import Foreign.C.Types++--------------------------------------------------------------------------------++-- | 'parseXml' @parseOpts text@ parses @text@ into an XML document using +-- libxml according to options given by @parseOpts@.+parseXml :: [CInt] -> BS.ByteString -> IO (ForeignPtr LibXMLDoc) +parseXml opts bin = newForeignPtr xmlFreeDoc =<< + (BS.unsafeUseAsCStringLen bin $ \(ptr, len) -> + throwErrnoIfNull "xmlReadMemory" $ xmlReadMemory + ptr (fromIntegral len) nullPtr nullPtr (foldl (.|.) 0 opts))++-- | 'withXmlXPathNodeList' @docPtr xPathLocation continuation@ evaluates the+-- XPath location path given by @xPathLocation@ in the document context +-- pointed at by @docPtr@ and calls @continuation@ with the result.+withXmlXPathNodeList :: Ptr LibXMLDoc + -> BS.ByteString + -> (Ptr LibXMLNodeSet -> IO a) + -> IO a+withXmlXPathNodeList docPtr expr cont = + -- initialise a new XPath context, run the continuation with the context+ -- as argument, and then free up the context again afterwards+ bracket (xmlXPathNewContext docPtr) xmlXPathFreeContext $ \ctx -> + -- get a C string pointer for the XPath location path+ BS.unsafeUseAsCString expr $ \strPtr ->+ -- evaluate the XPath location path and free up the resulting object+ -- after the continuation is finished; see + -- http://xmlsoft.org/html/libxml-xpath.html#xmlXPathEval+ bracket+ ( throwErrnoIfNull "xmlXPathEval" $ + xmlXPathEval (castPtr strPtr) ctx+ )+ xmlXPathFreeObject + -- the XPath object structure contains the node set pointer+ -- at offset 8; see + -- http://xmlsoft.org/html/libxml-xpath.html#xmlXPathObject+ $ \a -> peekByteOff a 8 >>= cont++-- | 'c14n' @parseOpts mode nsPrefixes keepComments xPathLocation input@ +-- canonicalises the document given by @input@, which is parsed using options+-- specified by @parseOpts@. The @mode@ argument deteremines the +-- canonicalisation mode to use. @nsPrefixes@ gives a (potentially empty)+-- list of namespace prefixes which is used when @mode@ is +-- 'c14n_exclusive_1_0'. If @keepComments@ is 'True', all comments are kept+-- in the output. @xPathLocation@ is used to select a set of nodes that should+-- be included in the canonicalised result.+c14n :: [CInt]+ -> CInt + -> [BS.ByteString] + -> Bool + -> Maybe BS.ByteString + -> BS.ByteString + -> IO BS.ByteString+c14n opts mode nsPrefixes keepComments xpath bin = + -- parse the input xml+ parseXml opts bin >>= \docPtr ->+ -- wrap the pointer we got in a foreign pointer+ withForeignPtr docPtr $ \ptr -> + -- convert the namespace prefixes into C strings+ withMany BS.unsafeUseAsCString nsPrefixes $ \inclPtr ->+ -- turn the Haskell list of C strings into a C array,+ -- terminated by NULL+ withArray0 nullPtr inclPtr $ \arrayPtr -> + -- get a pointer to the node set + maybeWith (withXmlXPathNodeList ptr) xpath $ \nsPtr ->+ -- allocate some memory for a pointer to the results+ alloca $ \outPtr -> do+ -- convert the option determining whether to keep comments from a + -- Haskell boolean to a CInt+ let commentsOpt = fromIntegral (fromEnum keepComments)+ -- cast from CChar pointers to whatever LibXMLChar is (e.g. Word8)+ let prefixesPtr :: Ptr (Ptr LibXMLChar)+ prefixesPtr = castPtr arrayPtr++ -- run the canonicalisation function on the document;+ -- this function returns the number of bytes that were written+ -- to outPtr or a negative value if this fails+ numBytes <- throwErrnoIf (<0) "xmlC14NDocDumpMemory" $+ xmlC14NDocDumpMemory ptr nsPtr mode prefixesPtr commentsOpt outPtr ++ -- dereference the results pointer + ptrPtr <- peek outPtr++ -- construct a ByteString from the C string and return it+ BS.unsafePackCStringFinalizer + ptrPtr (fromIntegral numBytes) (freeXml ptrPtr)++--------------------------------------------------------------------------------
+ src/Text/XML/C14N/LibXML.hsc view
@@ -0,0 +1,251 @@+--------------------------------------------------------------------------------+-- Haskell bindings for c14n implementation in libxml --+--------------------------------------------------------------------------------+-- This source code is licensed under the MIT license found in the LICENSE --+-- file in the root directory of this source tree. --+--------------------------------------------------------------------------------++-- | Bindings to libxml types and functions required for the c14n +-- implementation. See http://xmlsoft.org/html/libxml-c14n.html+module Text.XML.C14N.LibXML (+ -- * libxml2 types+ LibXMLDoc,+ LibXMLNodeSet,+ LibXMLChar,+ LibXMLXPathCtx,+ LibXMLXPathObj,++ -- * Memory-related functions+ freeXml,++ -- * Parsing+ -- See http://xmlsoft.org/html/libxml-parser.html+ xml_opt_recover, + xml_opt_noent,+ xml_opt_dtdload,+ xml_opt_dtdattr,+ xml_opt_dtdvalid,+ xml_opt_noerror,+ xml_opt_nowarning,+ xml_opt_pedantic,+ xml_opt_noblanks,+ xml_opt_sax1,+ xml_opt_xinclude,+ xml_opt_nonet,+ xml_opt_nodict,+ xml_opt_nsclean,+ xml_opt_nocdata,+ xml_opt_noxincnode,+ xml_opt_compact,+ xml_opt_old10,+ xml_opt_nobasefix,+ xml_opt_huge,+ xml_opt_oldsax,+ xml_opt_ignore_env,+ xml_opt_big_lines,+ xmlReadMemory,+ xmlFreeDoc,++ -- * XML canonicalisation+ -- See http://xmlsoft.org/html/libxml-c14n.html+ c14n_1_0,+ c14n_exclusive_1_0,+ c14n_1_1,+ xmlC14NDocDumpMemory,++ -- * XPath+ -- See http://xmlsoft.org/html/libxml-xpath.html+ xmlXPathNewContext,+ xmlXPathFreeContext,+ xmlXPathEval,+ xmlXPathFreeObject+) where ++--------------------------------------------------------------------------------++#include <libxml/parser.h>+#include <libxml/c14n.h>++import Data.Word++import Foreign.Ptr+import Foreign.C.String+import Foreign.C.Types++--------------------------------------------------------------------------------++-- | Original C14N 1.0 specification.+c14n_1_0 :: CInt +c14n_1_0 = #{const XML_C14N_1_0}++-- | Exclusive C14N 1.0 specification.+c14n_exclusive_1_0 :: CInt +c14n_exclusive_1_0 = #{const XML_C14N_EXCLUSIVE_1_0}++-- | C14N 1.1 specification.+c14n_1_1 :: CInt +c14n_1_1 = #{const XML_C14N_1_1}++--------------------------------------------------------------------------------++-- | Recover on errors.+xml_opt_recover :: CInt +xml_opt_recover = #{const XML_PARSE_RECOVER}++-- | Substitute entities.+xml_opt_noent :: CInt+xml_opt_noent = #{const XML_PARSE_NOENT}++-- | Load the external subset.+xml_opt_dtdload :: CInt +xml_opt_dtdload = #{const XML_PARSE_DTDLOAD}++-- | Default DTD attributes.+xml_opt_dtdattr :: CInt +xml_opt_dtdattr = #{const XML_PARSE_DTDATTR}++-- | Validate with the DTD.+xml_opt_dtdvalid :: CInt +xml_opt_dtdvalid = #{const XML_PARSE_DTDVALID}++-- | Suppress error reports.+xml_opt_noerror :: CInt +xml_opt_noerror = #{const XML_PARSE_NOERROR}++-- | Suppress warning reports.+xml_opt_nowarning :: CInt +xml_opt_nowarning = #{const XML_PARSE_NOWARNING}++-- | Pedantic error reporting.+xml_opt_pedantic :: CInt +xml_opt_pedantic = #{const XML_PARSE_PEDANTIC}++-- | Remove blank nodes.+xml_opt_noblanks :: CInt +xml_opt_noblanks = #{const XML_PARSE_NOBLANKS}++-- | Use the SAX1 interface internally.+xml_opt_sax1 :: CInt +xml_opt_sax1 = #{const XML_PARSE_SAX1}++-- | Implement XInclude substitution.+xml_opt_xinclude :: CInt +xml_opt_xinclude = #{const XML_PARSE_XINCLUDE}++-- | Forbid network access.+xml_opt_nonet :: CInt+xml_opt_nonet = #{const XML_PARSE_NONET}++-- | Do not reuse the context dictionary.+xml_opt_nodict :: CInt+xml_opt_nodict = #{const XML_PARSE_NODICT}++-- | Remove redundant namespaces declarations.+xml_opt_nsclean :: CInt+xml_opt_nsclean = #{const XML_PARSE_NSCLEAN}++-- | Merge CDATA as text nodes.+xml_opt_nocdata :: CInt+xml_opt_nocdata = #{const XML_PARSE_NOCDATA}++-- | Do not generate XINCLUDE START/END nodes.+xml_opt_noxincnode :: CInt+xml_opt_noxincnode = #{const XML_PARSE_NOXINCNODE}++-- | Compact small text nodes; no modification of the tree allowed afterwards+-- (will probably crash if you try to modify the tree)+xml_opt_compact :: CInt+xml_opt_compact = #{const XML_PARSE_COMPACT}++-- | Parse using XML-1.0 before update 5.+xml_opt_old10 :: CInt+xml_opt_old10 = #{const XML_PARSE_OLD10}++-- | Do not fixup XINCLUDE xml:base uris.+xml_opt_nobasefix :: CInt+xml_opt_nobasefix = #{const XML_PARSE_NOBASEFIX}++-- | Relax any hardcoded limit from the parser.+xml_opt_huge :: CInt+xml_opt_huge = #{const XML_PARSE_HUGE}++-- | Parse using SAX2 interface before 2.7.0.+xml_opt_oldsax :: CInt+xml_opt_oldsax = #{const XML_PARSE_OLDSAX}++-- | Ignore internal document encoding hint.+xml_opt_ignore_env :: CInt+xml_opt_ignore_env = #{const XML_PARSE_IGNORE_ENC}++-- | Store big lines numbers in text PSVI field.+xml_opt_big_lines :: CInt+xml_opt_big_lines = #{const XML_PARSE_BIG_LINES}++--------------------------------------------------------------------------------++-- | XML documents+data LibXMLDoc ++-- | XML node sets+data LibXMLNodeSet++-- | XML strings+type LibXMLChar = #type xmlChar++-- | XML XPath contexts+data LibXMLXPathCtx++-- | XML XPath objects+data LibXMLXPathObj++-- | Free an XML object.+foreign import ccall unsafe "freeXml"+ freeXml :: Ptr a -> IO ()++-- | Free an XML document.+foreign import ccall unsafe "libxml/tree.h &xmlFreeDoc"+ xmlFreeDoc :: FunPtr ((Ptr LibXMLDoc) -> IO ())++-- | Parses an XML document from a textual representation held in memory.+foreign import ccall unsafe "libxml/parser.h xmlReadMemory"+ xmlReadMemory :: CString + -> CInt + -> CString + -> CString + -> CInt + -> IO (Ptr LibXMLDoc)++-- | Writes the canonicalised representation of an XML document to memory.+foreign import ccall unsafe "libxml/c14n.h xmlC14NDocDumpMemory"+ xmlC14NDocDumpMemory :: Ptr LibXMLDoc -- ^ The XML document to canonicalise.+ -> Ptr LibXMLNodeSet -- ^ The nodes set to be included+ -- in the canonicalised output.+ -> CInt -- ^ The canonicalisation mode.+ -> Ptr (Ptr LibXMLChar) -- ^ A list of inclusive + -- namespace prefixes+ -> CInt -- ^ A boolean value indicating whether comments+ -- should be included in the result or not.+ -> Ptr (Ptr LibXMLChar) -- ^ A memory address to which+ -- the output should be written.+ -> IO CInt++-- | Creates a new XPath context for the given document.+foreign import ccall unsafe "libxml/xpath.h xmlXPathNewContext"+ xmlXPathNewContext :: Ptr LibXMLDoc -> IO (Ptr LibXMLXPathCtx)++-- | Frees up an 'LibXMLXPathCtx' context.+foreign import ccall unsafe "libxml/xpath.h xmlXPathFreeContext"+ xmlXPathFreeContext :: Ptr LibXMLXPathCtx -> IO ()++-- | 'xmlXPathEval' @pathPtr ctxPtr@ evaluates the XPath location path+-- pointed at by @pathPtr@ in the XPath context pointed at by @ctxPtr@. +foreign import ccall unsafe "libxml/xpath.h xmlXPathEval"+ xmlXPathEval :: Ptr LibXMLChar + -> Ptr LibXMLXPathCtx + -> IO (Ptr LibXMLXPathObj)++-- | Free up an 'LibXMLXPathObj' object.+foreign import ccall unsafe "libxml/xpath.h xmlXPathFreeObject"+ xmlXPathFreeObject :: Ptr LibXMLXPathObj -> IO ()++--------------------------------------------------------------------------------