Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

BlobEscapedFilter.java

00001 /**
00002  * C-JDBC: Clustered JDBC.
00003  * Copyright (C) 2002-2005 French National Institute For Research In Computer
00004  * Science And Control (INRIA).
00005  * Contact: c-jdbc@objectweb.org
00006  *
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or any later
00010  * version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00015  * for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00020  *
00021  * Initial developer(s): Silvan Eugen Lincan
00022  * Contributor(s): ______________________.
00023  */
00024 
00025 package org.objectweb.cjdbc.common.sql.filters;
00026 
00027 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags;
00028 
00029 /**
00030  * This class defines a BlobEscapedFilter. It acts just the same as the
00031  * <code>NoneBlobFilter</code> except that the content is escaped to prevent
00032  * strange characters for disturbing the data. This has been adapted mainly for
00033  * PostgreSQL bytea data, but it should be usable for any other database.
00034  * 
00035  * @author <a href="mailto:s.lincan@moodmedia.ro">Silvan Eugen Lincan </a>
00036  * @version 1.0
00037  */
00038 public class BlobEscapedFilter extends AbstractBlobFilter
00039 {
00040 
00041   /**
00042    * @see org.objectweb.cjdbc.common.sql.filters.AbstractBlobFilter#encode(byte[])
00043    */
00044   public String encode(byte[] data)
00045   {
00046     return BlobEscapedFilter.toPGString(data);
00047   }
00048 
00049   /**
00050    * @see org.objectweb.cjdbc.common.sql.filters.AbstractBlobFilter#encode(java.lang.String)
00051    */
00052   public String encode(String data)
00053   {
00054     return data;
00055   }
00056 
00057   /**
00058    * @see org.objectweb.cjdbc.common.sql.filters.AbstractBlobFilter#decode(byte[])
00059    */
00060   public byte[] decode(byte[] data)
00061   {
00062     return data;
00063   }
00064 
00065   /**
00066    * @see org.objectweb.cjdbc.common.sql.filters.AbstractBlobFilter#decode(java.lang.String)
00067    */
00068   public byte[] decode(String data)
00069   {
00070     return data.getBytes();
00071   }
00072 
00073   /**
00074    * @see org.objectweb.cjdbc.common.sql.filters.AbstractBlobFilter#getXml()
00075    */
00076   public String getXml()
00077   {
00078     return DatabasesXmlTags.VAL_escaped;
00079   }
00080 
00081   /**
00082    * Converts a java byte[] into a PG bytea string (i.e. the text representation
00083    * of the bytea data type). Escape characters between 32 and 126.
00084    * 
00085    * @param postgresBuf The byte array to be converted
00086    * @return the string representation
00087    */
00088   public static String toPGString(byte[] postgresBuf)
00089   {
00090     if (postgresBuf == null)
00091     {
00092       return null;
00093     }
00094     StringBuffer stringBuffer = new StringBuffer(2 * postgresBuf.length);
00095     for (int i = 0; i < postgresBuf.length; i++)
00096     {
00097       int l_int = (int) postgresBuf[i];
00098       if (l_int < 0)
00099       {
00100         l_int = 256 + l_int;
00101       }
00102       /*
00103        * Escape the same non-printable characters as the backend. Must escape
00104        * all 8bit characters otherwise when convering from java unicode to the
00105        * db character set we may end up with question marks if the character set
00106        * is SQL_ASCII.
00107        */
00108       if (l_int < 040 || l_int > 0176)
00109       {
00110         /* escape charcter '\0000', but need two \\ because of the parser. */
00111         stringBuffer.append("\\");
00112         stringBuffer.append((char) (((l_int >> 6) & 0x3) + 48));
00113         stringBuffer.append((char) (((l_int >> 3) & 0x7) + 48));
00114         stringBuffer.append((char) ((l_int & 0x07) + 48));
00115       }
00116       else if (postgresBuf[i] == (byte) '\\')
00117       {
00118         /*
00119          * escape the backslash character as \\, but need four \\\\ because of
00120          * the parser.
00121          */
00122         stringBuffer.append("\\\\");
00123       }
00124       else
00125       {
00126         /* other characters are left alone */
00127         stringBuffer.append((char) postgresBuf[i]);
00128       }
00129     }
00130     String x = stringBuffer.toString();
00131     /* Add 10% for escaping. */
00132     StringBuffer sbuf = new StringBuffer(2 + x.length() * 11 / 10);
00133     for (int i = 0; i < x.length(); ++i)
00134     {
00135       char c = x.charAt(i);
00136       if ((c == '\'') || (c == '\\'))
00137         sbuf.append("\\");
00138       sbuf.append(c);
00139     }
00140 
00141     return sbuf.toString();
00142   }
00143 
00144   /**
00145    * Converts a PG bytea raw value (i.e. the raw binary representation of the
00146    * bytea data type) into a java byte[].
00147    * 
00148    * @param s The byte array to be converted.
00149    * @return an java byte[]
00150    */
00151   public static byte[] toBytes(byte[] s)
00152   {
00153     if (s == null)
00154     {
00155       return null;
00156     }
00157     int slength = s.length;
00158     byte[] buf = new byte[slength];
00159     int bufpos = 0;
00160     int thebyte;
00161     byte nextbyte;
00162     byte secondbyte;
00163     for (int i = 0; i < slength; i++)
00164     {
00165       nextbyte = s[i];
00166       if (nextbyte == (byte) '\\')
00167       {
00168         secondbyte = s[++i];
00169         if (secondbyte == (byte) '\\')
00170         {
00171           /* escaped \ */
00172           buf[bufpos++] = (byte) '\\';
00173         }
00174         else
00175         {
00176           thebyte = (secondbyte - 48) * 64 + (s[++i] - 48) * 8 + (s[++i] - 48);
00177           if (thebyte > 127)
00178             thebyte -= 256;
00179           buf[bufpos++] = (byte) thebyte;
00180         }
00181       }
00182       else
00183       {
00184         buf[bufpos++] = nextbyte;
00185       }
00186     }
00187     byte[] resultReturn = new byte[bufpos];
00188     System.arraycopy(buf, 0, resultReturn, 0, bufpos);
00189     return resultReturn;
00190   }
00191 }

Generated on Mon Apr 11 22:01:29 2005 for C-JDBC by  doxygen 1.3.9.1