//
// XMLCIM.java
//
// The contents of this file are subject to the SNIA Public License Version 1.0
// (the "License"); you may not use this file except in compliance with the
// License. You may obtain a copy of the License at
//
//	http://www.snia.org/resources/openSource.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is XMLCIM.java
// 
// The Initial Developer of the Original Code is David Simons.
//
// Contributor(s):
//
//
// This source uses the Solaris WBEM APIs version 2.2. 
// Synchronization will be maintained with the Solaris WBEM APIS,
// which are being standardized through the Java Community Process.
//
//
// $Id: XMLCIM.java,v 1.1 2003/07/17 18:32:55 kumpf Exp $
//
// $Log: XMLCIM.java,v $
// Revision 1.1  2003/07/17 18:32:55  kumpf
// HP-BAPU: PEP-64 CIM Client and CIM Listener Java Interface
//
// Revision 1.1.1.1  2001/10/31 18:17:32  karl
// import of SNIA 0_7
//
// Revision 1.6  2001/03/21 15:49:13  davidsi
// - Work around for 16bit wide apostrophes.
//
// Revision 1.5  2000/11/18 12:59:16  davidsi
// - Strip non escaped <CR> and <LF> characters from the escaped string -
//   some CIMOMs appear to embed these as noise.
//
// Revision 1.4  2000/11/11 15:50:28  davidsi
// - From mihajlov. Extended escaping/unescaping to account for apostrophes
//   and quotes.
//
// Revision 1.3  2000/08/16 05:59:59  shawn
// merge P_TOMCAT31 branch
//
// Revision 1.2.8.1  2000/08/10 00:03:36  shawn
// head merge
//
// Revision 1.2  2000/05/11 10:11:23  davidsi
// - Fixed tabs.
//
// Revision 1.1  2000/05/06 17:17:01  davidsi
// - Moved from cim/client directory
//
// Revision 1.3  2000/04/09 13:14:46  davidsi
// - Fixed case on ClassName (was CLASSNAME).
//
// Revision 1.2  2000/02/13 15:09:08  davidsi
// - Added text to cover re-use of Solaris WBEM APIs.
//
// Revision 1.1.1.1  2000/02/06 16:41:04  davidsi
// Initial version.
//
//
//
package org.snia.wbemcmd.xml;

public class XMLCIM {
    public static XMLCIM xmlCIMEscape=new XMLCIM();
	
    private int bufSize=0;
    private char[] newValue;
    
    //
    //
    public synchronized  String XMLEscape(String in) {
	int i;
	char[] values;
	int out=0;
	boolean noconv=true;
	
	if (in==null)
	    return(null);
	
	values=in.toCharArray();
	if (values.length*5+1>bufSize) {
	    bufSize=5*values.length+1;
	    newValue=new char[bufSize];
	}
	for(i=0;i<values.length;i++) {
	    char ch=values[i];
	    
	    if ((ch>='a' && ch<='z') 
		|| (ch>='A' && ch<='Z') 
		|| (ch>='0' && ch<='9') ) {
		newValue[out++]=ch;
	    } else if (ch=='\n') {
		newValue[out++]='\\';
		newValue[out++]='n';
		noconv=false;
	    } else if (ch=='\t') {
		newValue[out++]='\\';
		newValue[out++]='t';
		noconv=false;
	    } else if (ch=='>') {
		newValue[out++]='&';
		newValue[out++]='g';
		newValue[out++]='t';
		newValue[out++]=';';
		noconv=false;
	    } else if (ch=='<') {
		newValue[out++]='&';
		newValue[out++]='l';
		newValue[out++]='t';
		newValue[out++]=';';
		noconv=false;
	    } else if (ch=='&') {
		newValue[out++]='&';
		newValue[out++]='a';
		newValue[out++]='m';
		newValue[out++]='p';
		newValue[out++]=';';
		noconv=false;
	    } else if (ch=='\"') {
		newValue[out++]='&';
		newValue[out++]='q';
		newValue[out++]='u';
		newValue[out++]='o';
		newValue[out++]='t';
		newValue[out++]=';';
		noconv=false;
	    } else if (ch=='\'' || ch==8216 || ch==8217) {
		newValue[out++]='&';
		newValue[out++]='a';
		newValue[out++]='p';
		newValue[out++]='o';
		newValue[out++]='s';
		newValue[out++]=';';
		noconv=false;
            } else
		newValue[out++]=values[i];
	}
	//
	// If no conversion, then don't build the new string
	//
	if (noconv)
	    return(in);
	
	newValue[out++]='\0';
	return(new String(newValue, 0, out-1));
    }
    public synchronized String xmlCIMUnescape(String text) {
	int i;
	char[] values;
	int out=0;
	boolean changed=false;	// true when unescaping changed something
				// - assume that most cases don't require a 
				// change
    
	if (text==null)
	    return(text);
	
	
	values=text.toCharArray();
	if (values.length*5+1>bufSize) {
	    bufSize=5*values.length+1;
	    newValue=new char[bufSize];
	}
	for(i=0;i<values.length;i++) {
	    char ch=values[i];
	    if (ch=='\n') {
		changed=true;
		continue;
	    }
	    if (ch==10) {
		changed=true;
		continue;
	     }
	    if (ch=='\\' && i+1<values.length) {
		int v=i+1;
		if (values[v]=='n')
		    { changed=true;newValue[out++]='\n';}
		else if (values[v]=='t')
		    { changed=true; newValue[out++]='\t';}
		else {
		    newValue[out++]='\\';
		    newValue[out++]=values[v];
		}
		i++;
		continue;
	    } else if (ch=='&') {
		int v=i+1;
		int w=i+2;
		int y=i+3;
		int z=i+4;
		if (i+3<values.length) {
		    if (values[v]=='g' && values[w]=='t' && values[y]==';')
			{ changed=true;newValue[out++]='>'; i +=3; continue; }
		    if (values[v]=='l' && values[w]=='t' && values[y]==';')
			{ changed=true;newValue[out++]='<';i +=3; continue; }
		} else if (i+4<values.length) {
		    int x=i+4;
		    if (values[v]=='a' && values[w]=='m' && values[y]=='p' && values[x]==';')
			{ changed=true;newValue[out++]='&'; i+=4; continue; }
		} else if (i+5<values.length) {
		    int x=i+5;
		    if (values[v]=='q' && values[w]=='u' && values[y]=='o' && values[z] == 't' && values[x]==';')
			{ changed=true;newValue[out++]='\"'; i+=5; continue; }
		    if (values[v]=='a' && values[w]=='p' && values[y]=='o' && values[z] == 's' && values[x]==';')
			{ changed=true;newValue[out++]='\''; i+=5; continue; }
		}
	    }
	    newValue[out++]=ch;
	}
	if (!changed)
	    return(text);
	newValue[out++]='\0';
	return(new String(newValue, 0, out-1));
    }
}
