1/*
2 * dom.c --
3 *
4 * Dom-like interface to support building DOM documents.
5 *
6 * Copyright (c) 1999, 2000 Ajuba Solutions
7 *
8 * RCS: $Id: dom.c,v 1.3 2001/09/20 18:28:48 jenglish Exp $
9 *
10 */
11
12#include "tdp.h"
13#include "tclDomProInt.h"
14
15/*
16 * DOMImplemenation Methods
17 */
18Tdp_DocumentType Tdp_CreateDocumentType(Tcl_Interp *interp,
19    Tdp_Document parentDocument, char *name, char *publicId, char *systemId)
20{
21    TclDomInterpData *interpDataPtr;
22    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
23	    PACKAGE_NAME, NULL);
24    return ((Tdp_DocumentType) TclDomCreateDocType(interp, interpDataPtr,
25	    (TclDomDocument *) parentDocument, name, publicId, systemId));
26}
27
28/*
29 * Document Methods
30 */
31
32Tdp_Document Tdp_CreateDocument(Tcl_Interp *interp)
33{
34    TclDomInterpData *interpDataPtr;
35    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
36	    PACKAGE_NAME, NULL);
37    return ((Tdp_Document) TclDomEmptyDocument(interp, interpDataPtr));
38}
39
40TdpDomError Tdp_CreateElement(Tcl_Interp *interp, Tdp_Document parentDocument,
41	char *tagname, Tdp_Element *elementPtr)
42{
43    TclDomInterpData *interpDataPtr;
44    TclDomDocument *documentPtr;
45    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
46	    PACKAGE_NAME, NULL);
47    documentPtr = (TclDomDocument *) parentDocument;
48    /* XXX should check for valid tag in TclDomCreateElement */
49    *elementPtr = (Tdp_Element) TclDomCreateElement(interp, interpDataPtr,
50	    documentPtr, tagname);
51    return TDP_OK;
52}
53
54Tdp_TextNode Tdp_CreateTextNode(Tcl_Interp *interp,
55    Tdp_Document parentDocument, char *data)
56{
57    TclDomInterpData *interpDataPtr;
58    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
59	    PACKAGE_NAME, NULL);
60    return ((Tdp_TextNode) TclDomCreateTextNode(interp, interpDataPtr,
61	    (TclDomDocument *) parentDocument, data));
62}
63
64Tdp_CommentNode Tdp_CreateCommentNode(Tcl_Interp *interp,
65    Tdp_Document parentDocument, char *data)
66{
67    TclDomInterpData *interpDataPtr;
68    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
69	    PACKAGE_NAME, NULL);
70    return ((Tdp_CommentNode) TclDomCreateCommentNode(interp, interpDataPtr,
71	    (TclDomDocument *) parentDocument, data));
72}
73
74Tdp_PINode Tdp_CreateProcessingInstructionNode(Tcl_Interp *interp,
75    Tdp_Document parentDocument, char *target, char *data)
76{
77    TclDomInterpData *interpDataPtr;
78    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
79	    PACKAGE_NAME, NULL);
80    return ((Tdp_PINode) TclDomCreateProcessingInstructionNode(interp,
81	    interpDataPtr, (TclDomDocument *) parentDocument, target, data));
82}
83
84Tdp_Element Tdp_GetDocumentElement(Tdp_Document document)
85{
86    TclDomDocument *documentPtr = (TclDomDocument *) document;
87	return (Tdp_Element) documentPtr->selfPtr;
88}
89
90/*
91 * Node Methods
92 */
93
94Tdp_Node Tdp_GetParentNode(Tdp_Node node)
95{
96    TclDomNode *nodePtr = (TclDomNode *) node;
97    if (nodePtr->nodeType != ELEMENT_NODE) {
98	    return NULL;
99    }
100    return (Tdp_Node) nodePtr->parentNodePtr;
101}
102
103Tdp_Node Tdp_GetLastChild(Tdp_Node node)
104{
105    TclDomNode *nodePtr = (TclDomNode *) node;
106    if (nodePtr->nodeType != ELEMENT_NODE) {
107	    return NULL;
108    }
109    return (Tdp_Node) nodePtr->lastChildPtr;
110}
111
112TdpNodeType Tdp_GetNodeType(Tdp_Node node)
113{
114    return (((TclDomNode *) node)->nodeType);
115}
116
117char * Tdp_GetNodeValue(Tdp_Node node)
118{
119    if (((TclDomNode *) node)->nodeValue) {
120	return ((TclDomNode *) node)->nodeValue;
121    } else {
122	return "";
123    }
124}
125
126TdpDomError Tdp_SetNodeValue(Tdp_Node node, char *data)
127{
128    return TclDomSetNodeValue((TclDomNode *) node, data);
129}
130
131TdpDomError Tdp_AppendChild(Tcl_Interp *interp, Tdp_Node parent,
132        Tdp_Node newChild)
133{
134    int result;
135    TclDomInterpData *interpDataPtr;
136    TclDomNode *parentPtr;
137    TclDomNode *newChildPtr;
138    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
139	    PACKAGE_NAME, NULL);
140    parentPtr = (TclDomNode *) parent;
141    newChildPtr = (TclDomNode *) newChild;
142    result = TclDomAppendChild(interp, interpDataPtr, parentPtr,
143	newChildPtr);
144    if (result == TCL_OK) {
145	    return TDP_OK;
146    } else {
147	    return TDP_HIERARCHY_REQUEST_ERR;
148    }
149}
150
151/*
152 * Element Methods
153 */
154
155TdpDomError Tdp_SetAttribute(Tcl_Interp *interp, Tdp_Element element,
156    char *name, char *value)
157{
158    TclDomInterpData *interpDataPtr;
159    TdpDomError domError;
160    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
161	    PACKAGE_NAME, NULL);
162
163    domError = TclDomSetAttribute(interp, interpDataPtr, (TclDomNode *)
164	element, name, value);
165    return domError;
166}
167
168/*
169 * TclDomPro Extension Methods
170 */
171
172Tcl_Obj* Tdp_GetDocumentObj(Tcl_Interp *interp, Tdp_Document document)
173{
174    Tcl_Obj *docObjPtr;
175    TclDomInterpData *interpDataPtr;
176    TclDomDocument *documentPtr;
177    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
178	    PACKAGE_NAME, NULL);
179    documentPtr = (TclDomDocument *) document;
180    docObjPtr = TclDomGetNodeObj(interpDataPtr, documentPtr->selfPtr);
181    return docObjPtr;
182}
183
184void Tdp_SetStartLocation(Tdp_Node node,
185    unsigned int line,
186    unsigned int column,
187    unsigned int width,
188    unsigned int endLine,
189    unsigned int endColumn)
190{
191    TclDomNode *nodePtr = (TclDomNode *) node;
192    nodePtr->startLine = line;
193    nodePtr->startColumn = column;
194    nodePtr->startWidth = width;
195    nodePtr->startLineClose = endLine;
196    nodePtr->startColumnClose = endColumn;
197}
198
199void Tdp_SetEndLocation(Tdp_Node node,
200    unsigned int line,
201    unsigned int column,
202    unsigned int width,
203    unsigned int endLine,
204    unsigned int endColumn)
205{
206    TclDomNode *nodePtr = (TclDomNode *) node;
207    nodePtr->endLine = line;
208    nodePtr->endColumn = column;
209    nodePtr->endWidth = width;
210    nodePtr->endLineClose = endLine;
211    nodePtr->endColumnClose = endColumn;
212}
213
214void Tdp_GetStartLocation(Tdp_Node node, unsigned int* linePtr,
215    unsigned int* columnPtr, unsigned int* widthPtr)
216{
217    TclDomNode *nodePtr = (TclDomNode *) node;
218    *linePtr = nodePtr->startLine;
219    *columnPtr = nodePtr->startColumn;
220    *widthPtr = nodePtr->startWidth;
221}
222
223void Tdp_GetEndLocation(Tdp_Node node, unsigned int* linePtr,
224    unsigned int* columnPtr, unsigned int* widthPtr)
225{
226    TclDomNode *nodePtr = (TclDomNode *) node;
227    *linePtr = nodePtr->endLine;
228    *columnPtr = nodePtr->endColumn;
229    *widthPtr = nodePtr->endWidth;
230}
231
232void Tdp_SetDocumentType(Tcl_Interp *interp, Tdp_Document document,
233	Tdp_DocumentType docType)
234{
235    TclDomInterpData *interpDataPtr;
236    TclDomDocument *documentPtr;
237    TclDomDocTypeNode *docTypePtr;
238    int result;
239
240    interpDataPtr = (TclDomInterpData *) Tcl_GetAssocData(interp,
241	    PACKAGE_NAME, NULL);
242    documentPtr = (TclDomDocument *) document;
243    docTypePtr = (TclDomDocTypeNode *) docType;
244
245    result = TclDomAppendChild(interp, interpDataPtr,
246	    (TclDomNode *) documentPtr, (TclDomNode *) docTypePtr);
247}
248