/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-2014 The eXist Project
* http://exist-db.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
package org.exist.dom.persistent;
import org.exist.numbering.NodeId;
import org.exist.storage.Signatures;
import org.exist.util.ByteConversion;
import org.exist.util.pool.NodePool;
import org.exist.xquery.XPathException;
import org.exist.xquery.value.StringValue;
import org.w3c.dom.Comment;
import org.w3c.dom.Node;
import javax.xml.XMLConstants;
import static java.nio.charset.StandardCharsets.UTF_8;
public class CommentImpl extends AbstractCharacterData implements Comment {
public CommentImpl() {
super(Node.COMMENT_NODE);
}
public CommentImpl(final String data) {
super(Node.COMMENT_NODE, data);
}
public CommentImpl(final char[] data, final int start, final int howmany) {
super(Node.COMMENT_NODE, data, start, howmany);
}
@Override
public String getLocalName() {
return "";
}
@Override
public String getNamespaceURI() {
return XMLConstants.NULL_NS_URI;
}
@Override
public String toString() {
return "<!-- " + cdata.toString() + " -->";
}
/**
* Serializes a (persistent DOM) Comment to a byte array
*
* data = signature nodeIdUnitsLength nodeId cdata
*
* signature = [byte] 0x60
*
* nodeIdUnitsLength = [short] (2 bytes) The number of units of the comment's NodeId
* nodeId = {@see org.exist.numbering.DLNBase#serialize(byte[], int)}
*
* cdata = jUtf8
*
* jUtf8 = {@see java.io.DataOutputStream#writeUTF(java.lang.String)}
*/
@Override
public byte[] serialize() {
String s;
try {
s = StringValue.expand(cdata);
} catch(final XPathException e) {
LOG.warn(e);
s = cdata.toString();
}
final byte[] cd = s.getBytes(UTF_8);
final int nodeIdLen = nodeId.size();
final byte[] data = new byte[StoredNode.LENGTH_SIGNATURE_LENGTH + NodeId.LENGTH_NODE_ID_UNITS +
+nodeIdLen + cd.length];
int pos = 0;
data[pos] = (byte) (Signatures.Comm << 0x5);
pos += StoredNode.LENGTH_SIGNATURE_LENGTH;
ByteConversion.shortToByte((short) nodeId.units(), data, pos);
pos += NodeId.LENGTH_NODE_ID_UNITS;
nodeId.serialize(data, pos);
pos += nodeIdLen;
System.arraycopy(cd, 0, data, pos, cd.length);
return data;
}
public static StoredNode deserialize(final byte[] data, final int start, final int len,
final DocumentImpl doc, final boolean pooled) {
int pos = start;
pos += LENGTH_SIGNATURE_LENGTH;
final int dlnLen = ByteConversion.byteToShort(data, pos);
pos += NodeId.LENGTH_NODE_ID_UNITS;
final NodeId dln = doc.getBrokerPool().getNodeFactory().createFromData(dlnLen, data, pos);
int nodeIdLen = dln.size();
pos += nodeIdLen;
final String cdata = new String(data, pos, len - (pos - start), UTF_8);
//OK : we have the necessary material to build the comment
final CommentImpl comment;
if(pooled) {
comment = (CommentImpl) NodePool.getInstance().borrowNode(Node.COMMENT_NODE);
} else {
comment = new CommentImpl();
}
comment.setNodeId(dln);
comment.appendData(cdata);
return comment;
}
}