/*
 * Copyright (C) 2005 NTT DATA Corporation
 * 
 */
package org.postgresforest.tool.util;

import java.util.regex.Pattern;

/**
 * 文字列置換ユーティリティクラス
 *
 */
public class StringReplaceUtil {
	protected final static String PARAM_STR = "?";
	protected Pattern m_pattern;
	protected String[] m_divStr;
	protected String[] m_valueList;
	
	/**
	 * 
	 */
	public StringReplaceUtil(String souceStr) {
		m_pattern = Pattern.compile("\\" + PARAM_STR);
		reset(souceStr);
		
	}

	public void reset(String souceStr){
		m_divStr = m_pattern.split(souceStr);
		m_valueList = new String[m_divStr.length - 1];

	}

	public void set(int index, String value){
		m_valueList[index -1] = value;

	}

	public void set(int index, byte[] value){

		set(index,escapeString(toPGString(value)));
	}
	
	public String get(){
		StringBuffer replaceStr = new StringBuffer();
		for (int i = 0; i < m_valueList.length; i++) {
			replaceStr.append(m_divStr[i]);
			if(m_valueList[i] == null){
				replaceStr.append(PARAM_STR);
			}else{
				replaceStr.append(m_valueList[i]);
			}
		}
		replaceStr.append(m_divStr[m_valueList.length]);
		
		
		return replaceStr.toString();
	}


	/*
	 * Converts a java byte[] into a PG bytea string (i.e. the text
	 * representation of the bytea data type)
	 */
	private static String toPGString(byte[] p_buf) 
	{
		if (p_buf == null)
			return null;
		StringBuffer l_strbuf = new StringBuffer(2 * p_buf.length);
		for (int i = 0; i < p_buf.length; i++)
		{
			int l_int = (int)p_buf[i];
			if (l_int < 0)
			{
				l_int = 256 + l_int;
			}
			//we escape the same non-printable characters as the backend
			//we must escape all 8bit characters otherwise when convering
			//from java unicode to the db character set we may end up with
			//question marks if the character set is SQL_ASCII
			if (l_int < 040 || l_int > 0176)
			{
				//escape charcter with the form \000, but need two \\ because of
				//the parser
				l_strbuf.append("\\");
				l_strbuf.append((char)(((l_int >> 6) & 0x3) + 48));
				l_strbuf.append((char)(((l_int >> 3) & 0x7) + 48));
				l_strbuf.append((char)((l_int & 0x07) + 48));
			}
			else if (p_buf[i] == (byte)'\\')
			{
				//escape the backslash character as \\, but need four \\\\ because
				//of the parser
				l_strbuf.append("\\\\");
			}
			else
			{
				//other characters are left alone
				l_strbuf.append((char)p_buf[i]);
			}
		}
		return l_strbuf.toString();
	}

    private String escapeString(String p_input ) {
    	StringBuffer p_output = new StringBuffer();
        for (int i = 0 ; i < p_input.length() ; ++i)
        {
            char c = p_input.charAt(i);
			switch (c)
			{
			    case '\\':
			    case '\'':
					p_output.append('\\');
					p_output.append(c);
					break;
				default:
					p_output.append(c);
			}
        }
        return p_output.toString();
    }


	/* (非 Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return get();
	}

}
