File tree Expand file tree Collapse file tree 4 files changed +71
-0
lines changed
Expand file tree Collapse file tree 4 files changed +71
-0
lines changed Original file line number Diff line number Diff line change @@ -11,6 +11,7 @@ _xmlCtxtSetErrorHandler
1111_xmlCtxtValidateDtd
1212_xmlDocGetRootElement
1313_xmlDocSetRootElement
14+ _xmlDOMWrapCloneNode
1415_xmlFreeDoc
1516_xmlFreeDtd
1617_xmlFreeNode
Original file line number Diff line number Diff line change @@ -79,6 +79,31 @@ function allocUTF8Buffer(str: string | null) {
7979 return [ buf , len ] ;
8080}
8181
82+ class PointerRef < T extends Pointer > {
83+ ptr : Pointer ;
84+
85+ constructor ( ptr : Pointer ) {
86+ this . ptr = ptr ;
87+ }
88+
89+ dereference ( ) : T {
90+ return libxml2 . getValue ( this . ptr , '*' ) as T ;
91+ }
92+ }
93+
94+ // TODO: find out actual pointer size
95+ const POINTER_SIZE = 8 ;
96+
97+ export function withPointerRef < T extends Pointer , R > ( process : ( pointerRef : PointerRef < T > ) => R ) : R {
98+ const buf = libxml2 . _malloc ( POINTER_SIZE ) ;
99+
100+ try {
101+ return process ( new PointerRef < T > ( buf ) ) ;
102+ } finally {
103+ libxml2 . _free ( buf ) ;
104+ }
105+ }
106+
82107function withStrings < R > ( process : ( ...buf : number [ ] ) => R , ...strings : ( string | null ) [ ] ) : R {
83108 const args = strings . map ( ( str ) => {
84109 const [ buf ] = allocUTF8Buffer ( str ) ;
@@ -725,6 +750,7 @@ export const xmlXPathFreeContext = libxml2._xmlXPathFreeContext;
725750export const xmlXPathFreeObject = libxml2 . _xmlXPathFreeObject ;
726751export const xmlXPathNewContext = libxml2 . _xmlXPathNewContext ;
727752export const xmlXPathSetContextNode = libxml2 . _xmlXPathSetContextNode ;
753+ export const xmlDOMWrapCloneNode = libxml2 . _xmlDOMWrapCloneNode ;
728754
729755/**
730756 * Create an output buffer using I/O callbacks (same pattern as xmlSaveToIO)
Original file line number Diff line number Diff line change @@ -2,6 +2,7 @@ type Pointer = number;
22type CString = Pointer ;
33type XmlAttrPtr = Pointer ;
44type XmlCharEncodingHandlerPtr = Pointer ;
5+ type XMLDomWrapCtxtPtr = Pointer ;
56type XmlParserCtxtPtr = Pointer ;
67type XmlParserInputBufferPtr = Pointer ;
78type XmlDocPtr = Pointer ;
@@ -62,6 +63,16 @@ export class LibXml2 {
6263 _xmlCtxtValidateDtd ( ctxt : XmlParserCtxtPtr , doc : XmlDocPtr , dtd : XmlDtdPtr ) : number ;
6364 _xmlFreeNode ( node : XmlNodePtr ) : void ;
6465 _xmlFreeParserCtxt ( ctxt : XmlParserCtxtPtr ) : void ;
66+ _xmlDOMWrapCloneNode (
67+ ctxt : XMLDomWrapCtxtPtr ,
68+ sourceDoc : XmlDocPtr ,
69+ node : XmlNodePtr ,
70+ resNode : Pointer ,
71+ destDoc : XmlDocPtr ,
72+ destParent : XmlDocPtr ,
73+ deep : number ,
74+ options : number ,
75+ ) : number ;
6576 _xmlDocGetRootElement ( doc : XmlDocPtr ) : XmlNodePtr ;
6677 _xmlDocSetRootElement ( doc : XmlDocPtr , root : XmlNodePtr ) : XmlNodePtr ;
6778 _xmlFreeDoc ( Doc : XmlDocPtr ) : void ;
Original file line number Diff line number Diff line change @@ -8,9 +8,11 @@ import {
88 XmlNsStruct ,
99 XmlOutputBufferHandler ,
1010 XmlXPathObjectStruct ,
11+ withPointerRef ,
1112 xmlAddChild ,
1213 xmlAddNextSibling ,
1314 xmlAddPrevSibling ,
15+ xmlDOMWrapCloneNode ,
1416 xmlFreeNode ,
1517 xmlGetNsList ,
1618 xmlHasNsProp ,
@@ -798,6 +800,37 @@ export class XmlElement extends XmlTreeNode {
798800 ) ;
799801 }
800802
803+ /**
804+ * Insert a clone of the given source node to the end of the children list.
805+ */
806+ addClone ( srcNode : XmlElement , deep : boolean = true ) : XmlElement {
807+ return withPointerRef ( ( resNodePtr ) => {
808+ const result = xmlDOMWrapCloneNode (
809+ 0 ,
810+ srcNode . doc . _ptr ,
811+ srcNode . _nodePtr ,
812+ resNodePtr . ptr ,
813+ this . doc . _ptr ,
814+ this . _nodePtr ,
815+ deep ? 1 : 0 ,
816+ 0 ,
817+ ) ;
818+
819+ switch ( result ) {
820+ case 0 :
821+ {
822+ const resNode = resNodePtr . dereference ( ) ;
823+ xmlAddChild ( this . _nodePtr , resNode ) ;
824+ return new XmlElement ( resNode ) ;
825+ }
826+ case 1 :
827+ throw new Error ( 'Unsupported node type given to addClone' ) ;
828+ default :
829+ throw new Error ( 'Internal error in addClone' ) ;
830+ }
831+ } ) ;
832+ }
833+
801834 /**
802835 * Save the XmlElement to a buffer and invoke the callbacks to process.
803836 *
You can’t perform that action at this time.
0 commit comments