Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / iapi / types / BinaryDecimal.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/types/BinaryDecimal.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/types/BinaryDecimal.java
new file mode 100644 (file)
index 0000000..bdb8c53
--- /dev/null
@@ -0,0 +1,714 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.iapi.types.BinaryDecimal\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.types;\r
+\r
+import java.io.IOException;\r
+import java.io.ObjectInput;\r
+import java.io.ObjectOutput;\r
+import java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+import java.sql.Types;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.io.ArrayInputStream;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+/**\r
+ * SQL DECIMAL using raw data. Provides the basis for the\r
+ * CDCDecimal implementation.\r
+ * <P>\r
+ * The on-disk format must match the SQLDecimal format so that\r
+ * databases are portable across J2ME and J2SE environments.\r
+ * <P>\r
+ * The format of the byte array is defined by the return of the\r
+ * java.math.BigInteger.toByteArray:, extracted here.\r
+ * \r
+ * Returns a byte array containing the two's-complement representation of this BigInteger.\r
+ * The byte array will be in big-endian byte-order: the most significant byte is in the zeroth element.\r
+ *\r
+ * This is the format for DECIMAL even if BigINteger is not available, e.g. OSGi ee.minimum.\r
+ */\r
+\r
+abstract class BinaryDecimal extends NumberDataType\r
+       implements VariableSizeDataValue\r
+{\r
+       /**\r
+        * An unscaled value of 1 in two's complement\r
+        */\r
+       private static final byte[] ONE_2C = {(byte) 0x01};\r
+       \r
+       /**\r
+        * The unscaled value as a binary two's complement array.\r
+       */\r
+       protected byte[]                data2c;\r
+\r
+       /**\r
+        * The SQL scale, zero or positive, of the value\r
+        */\r
+       protected int                   sqlScale;\r
+       \r
+       \r
+       BinaryDecimal() {\r
+       }\r
+       \r
+       /*\r
+       ** Methods about the DECIMAL type itself.\r
+       */\r
+\r
+       /**\r
+        * DECIMAL implementation.\r
+        * Use DECIMAL to indicate to self that another\r
+        * passed in value is an instance of this type.\r
+        */\r
+       public final int typeToBigDecimal()\r
+       {\r
+               return java.sql.Types.DECIMAL;\r
+       }\r
+\r
+       /** @see DataValueDescriptor#typePrecedence */\r
+       public final int typePrecedence()\r
+       {\r
+               return TypeId.DECIMAL_PRECEDENCE;\r
+       }\r
+       \r
+       /* Return DECIMAL as the type name.\r
+        * @see org.apache.derby.iapi.types.DataValueDescriptor#getTypeName()\r
+        */\r
+       public final String getTypeName() {\r
+               return TypeId.DECIMAL_NAME;\r
+       }\r
+\r
+       /**\r
+        * Return my format identifier.\r
+        * \r
+        * @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId\r
+        */\r
+       public final int getTypeFormatId() {\r
+               return StoredFormatIds.SQL_DECIMAL_ID;\r
+       }       \r
+       \r
+       /*\r
+       ** NULL handling.\r
+       */\r
+\r
+       /**\r
+        * see if the decimal value is null.\r
+        */\r
+       public boolean isNull()\r
+       {\r
+               return data2c == null;\r
+       }       \r
+\r
+       public void restoreToNull()\r
+       {\r
+               data2c = null;\r
+       }\r
+\r
+       /* Check the leftmost bit, if set the value is negative.\r
+        * NULL values return false.\r
+        * @see org.apache.derby.iapi.types.NumberDataType#isNegative()\r
+        */\r
+       protected boolean isNegative() {\r
+               return !isNull() && ((data2c[0] & 0x80) != 0);\r
+       }\r
+       \r
+       \r
+       /*\r
+       ** Methods to convert values into this DECIMAL\r
+       */\r
+       \r
+       /**\r
+        * Set the value from a long.\r
+        */\r
+       public void setValue(long theValue)\r
+       {\r
+               byte[] rd = data2c;\r
+               if (rd == null || rd.length < 8)\r
+                       rd = new byte[8];\r
+               \r
+               rd[0] = (byte)(theValue >>> 56);\r
+               rd[1] = (byte)(theValue >>> 48);\r
+               rd[2] = (byte)(theValue >>> 40);\r
+               rd[3] = (byte)(theValue >>> 32);\r
+               rd[4] = (byte)(theValue >>> 24);\r
+               rd[5] = (byte)(theValue >>> 16);\r
+               rd[6] = (byte)(theValue >>> 8);\r
+               rd[7] = (byte) theValue;\r
+               \r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       data2c = rd;\r
+                       sqlScale = 0;\r
+                       try {\r
+                       if (theValue != getLong())\r
+                               SanityManager.THROWASSERT("BinaryDecimal invalid long conversion before reduce in "\r
+                                               + theValue + " out " + getLong());\r
+                       }\r
+                       catch (StandardException se)\r
+                       {\r
+                               SanityManager.THROWASSERT(se);\r
+                       }\r
+               }\r
+               \r
+               data2c = BinaryDecimal.reduceBytes2c(rd, 0, 8);\r
+               sqlScale = 0;\r
+               \r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       try {\r
+                       if (theValue != getLong())\r
+                               SanityManager.THROWASSERT("BinaryDecimal invalid long conversion after reduce in "\r
+                                               + theValue + " out " + getLong());\r
+                       }\r
+                       catch (StandardException se)\r
+                       {\r
+                               SanityManager.THROWASSERT(se);\r
+                       }\r
+               }       \r
+       }\r
+\r
+       /**\r
+        * Set the value from an int, just copy 'byte-by-byte'\r
+        * from the int to a four byte array. Then reduce.\r
+        * @see NumberDataValue#setValue\r
+        */\r
+       public final void setValue(int theValue)\r
+       {\r
+               byte[] rd = data2c;\r
+               if (rd == null || rd.length < 4)\r
+                       rd = new byte[4];\r
+               \r
+               rd[0] = (byte)(theValue >>> 24);\r
+               rd[1] = (byte)(theValue >>> 16);\r
+               rd[2] = (byte)(theValue >>> 8);\r
+               rd[3] = (byte) theValue;\r
+                       \r
+               data2c = BinaryDecimal.reduceBytes2c(rd, 0, 4);\r
+               sqlScale = 0;\r
+       }\r
+       \r
+       /**\r
+        * Set the value from a boolean\r
+        */\r
+       public void setValue(boolean theValue)\r
+       {\r
+               int intValue = theValue ? 1 : 0;\r
+               setValue(intValue);\r
+       }\r
+       \r
+       /**\r
+        * Convert from a double, normalize and then convert as a String.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public final void setValue(double theValue) throws StandardException\r
+       {\r
+               setCoreValue(NumberDataType.normalizeDOUBLE(theValue));\r
+       }\r
+\r
+       /**\r
+        * Convert from a float, normalize and then convert as a String.\r
+        *\r
+        */\r
+       public final void setValue(float theValue)\r
+               throws StandardException\r
+       {\r
+               setCoreValue((double)NumberDataType.normalizeREAL(theValue));\r
+       }\r
+       \r
+       private void setCoreValue(double theValue) throws StandardException {\r
+               setValue(Double.toString(theValue));\r
+       }\r
+       \r
+       /**\r
+       Called when setting a DECIMAL value internally or from\r
+       through a procedure or function.\r
+       Handles long in addition to BigDecimal to handle\r
+       identity being stored as a long but returned as a DECIMAL.\r
+       */\r
+       public void setValue(Number theValue) throws StandardException\r
+       {\r
+               if (SanityManager.ASSERT)\r
+               {\r
+                       if (theValue != null &&\r
+                               !(theValue instanceof java.lang.Long))\r
+                               SanityManager.THROWASSERT("BinaryDecimal.setValue(Number) passed a " + theValue.getClass());\r
+               }\r
+       \r
+               if (theValue == null)\r
+                       setToNull();\r
+               else\r
+                       setValue(theValue.longValue());\r
+       }\r
+       \r
+       /**\r
+        * Set this DECIMAL value from another DataValueDescriptor\r
+        */\r
+       protected void setFrom(DataValueDescriptor dvd) throws StandardException\r
+       {\r
+       \r
+               switch (dvd.typeToBigDecimal())\r
+               {\r
+                       case Types.CHAR:\r
+                       case Types.DECIMAL: // TODO : direct copy\r
+                               \r
+                               setValue(dvd.getString());\r
+                               break;\r
+                       case Types.BIGINT:\r
+                               setValue(dvd.getLong());\r
+                           break;\r
+                       default:\r
+                               super.setFrom(dvd);\r
+               }\r
+       }\r
+       /*\r
+       ** Methods to get a value from this DECIMAL\r
+       */\r
+\r
+       /**\r
+        * Return a int from this value.\r
+        * \r
+        * @exception StandardException\r
+        *                this value is out of range for an int\r
+        */\r
+       public final int getInt() throws StandardException\r
+       {\r
+               if (isNull())\r
+                       return 0;\r
+\r
+               try {\r
+                       long lv = getLong();\r
+\r
+                       if ((lv >= Integer.MIN_VALUE) && (lv <= Integer.MAX_VALUE))\r
+                               return (int) lv;\r
+\r
+               } catch (StandardException se) {\r
+                       // out of range error but with incorrect messgae (BIGINT)\r
+                       // fall through to correct message\r
+               }\r
+\r
+               throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "INTEGER");\r
+       }\r
+\r
+       /**\r
+        * Return a byte from this value.\r
+        * \r
+        * @exception StandardException\r
+        *                this value is out of range for a short\r
+        */\r
+       public final byte getByte() throws StandardException {\r
+               if (isNull())\r
+                       return (byte) 0;\r
+\r
+               try {\r
+                       long lv = getLong();\r
+\r
+                       if ((lv >= Byte.MIN_VALUE) && (lv <= Byte.MAX_VALUE))\r
+                               return (byte) lv;\r
+\r
+               } catch (StandardException se) {\r
+                       // out of range error but with incorrect messgae (BIGINT)\r
+                       // fall through to correct message\r
+               }\r
+\r
+               throw StandardException.newException(\r
+                               SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "TINYINT");\r
+       }\r
+\r
+       /**\r
+        * Return a short from this value.\r
+        * @exception StandardException this value is out of range for a short\r
+        */\r
+       public final short getShort() throws StandardException  \r
+       {\r
+               if (isNull())\r
+                       return (short)0;\r
+\r
+               try {\r
+                       long lv = getLong();\r
+\r
+                       if ((lv >= Short.MIN_VALUE) && (lv <= Short.MAX_VALUE))\r
+                               return (short) lv;\r
+\r
+               } catch (StandardException se) {\r
+                       // out of range error but with incorrect messgae (BIGINT)\r
+                       // fall through to correct message\r
+               }\r
+\r
+               throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "SMALLINT");\r
+       }\r
+       \r
+       \r
+       /*\r
+       ** DECIMAL arithmetic methods.\r
+       */\r
+       \r
+       /**\r
+        * This method implements the + operator for DECIMAL.\r
+        *\r
+        * @param addend1       One of the addends\r
+        * @param addend2       The other addend\r
+        * @param result        The result of a previous call to this method, null\r
+        *                                      if not called yet\r
+        *\r
+        * @return      A SQLDecimal containing the result of the addition\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       public final NumberDataValue plus(NumberDataValue addend1,\r
+                                                       NumberDataValue addend2,\r
+                                                       NumberDataValue result)\r
+                               throws StandardException\r
+       {\r
+               if (result == null)\r
+               {\r
+                       result = (NumberDataValue) getNewNull();\r
+               }\r
+\r
+               if (addend1.isNull() || addend2.isNull())\r
+               {\r
+                       result.setToNull();\r
+                       return result;\r
+               }\r
+\r
+               return plusNN(addend1, addend2, result);\r
+       }\r
+       \r
+       /* (non-Javadoc)\r
+        * @see org.apache.derby.iapi.types.NumberDataValue#times(org.apache.derby.iapi.types.NumberDataValue, org.apache.derby.iapi.types.NumberDataValue, org.apache.derby.iapi.types.NumberDataValue)\r
+        */\r
+       public final NumberDataValue times(NumberDataValue left, NumberDataValue right, NumberDataValue result)\r
+       throws StandardException\r
+       {\r
+               if (result == null)\r
+               {\r
+                       result = (NumberDataValue) getNewNull();\r
+               }\r
+\r
+               if (left.isNull() || right.isNull())\r
+               {\r
+                       result.setToNull();\r
+                       return result;\r
+               }               \r
+               return timesNN(left, right, result);\r
+       }\r
+       public NumberDataValue divide(NumberDataValue dividend,\r
+                        NumberDataValue divisor,\r
+                        NumberDataValue result)\r
+throws StandardException\r
+{\r
+return divide(dividend, divisor, result, -1);\r
+}\r
+\r
+       /**\r
+        * This method implements the / operator for BigDecimal/BigDecimal\r
+        *\r
+        * @param dividend      The numerator\r
+        * @param divisor       The denominator\r
+        * @param result        The result of a previous call to this method, null\r
+        *                                      if not called yet\r
+        * @param scale         The result scale, if < 0, calculate the scale according\r
+        *                                      to the actual values' sizes\r
+        *\r
+        * @return      A SQLDecimal containing the result of the division\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       public final NumberDataValue divide(NumberDataValue dividend,\r
+                                                        NumberDataValue divisor,\r
+                                                        NumberDataValue result,\r
+                                                        int scale)\r
+                               throws StandardException\r
+       {\r
+               if (result == null)\r
+               {\r
+                       result = (NumberDataValue) getNewNull();\r
+               }\r
+\r
+               if (dividend.isNull() || divisor.isNull())\r
+               {\r
+                       result.setToNull();\r
+                       return result;\r
+               }\r
+               \r
+               return divideNN(dividend, divisor, result, scale);\r
+       }       \r
+       public final NumberDataValue minus(NumberDataValue left, NumberDataValue right, NumberDataValue result)\r
+       throws StandardException\r
+       {\r
+               if (result == null)\r
+               {\r
+                       result = (NumberDataValue) getNewNull();\r
+               }\r
+\r
+               if (left.isNull() || right.isNull())\r
+               {\r
+                       result.setToNull();\r
+                       return result;\r
+               }\r
+               \r
+               return minusNN(left, right, result);\r
+       }\r
+       \r
+       /**\r
+        * Implement subtraction using addition and negation of the right value.\r
+        */\r
+       public NumberDataValue minusNN(NumberDataValue left, NumberDataValue right, NumberDataValue result)\r
+               throws StandardException\r
+       {\r
+               // Requires plusNN() correctly handles that its right argument and\r
+               // result can be references to the same object.\r
+               return plusNN(left, right.minus(result), result);\r
+       }\r
+               \r
+       /*\r
+       ** Abstract methods for handling non-null arithmetic.\r
+       ** Eventually move these methods into NumberDataType\r
+       ** and directly compile to them when arguments cannot\r
+       ** be null. A performance optimization.\r
+       */\r
+       \r
+       \r
+       /**\r
+        * Multiple two non-nullable values using DECIMAL arithmetic.\r
+        */\r
+       public abstract NumberDataValue timesNN(NumberDataValue left,\r
+                       NumberDataValue right, NumberDataValue result)\r
+                       throws StandardException;\r
+\r
+       /**\r
+        * Add two non-nullable values using DECIMAL arithmetic.\r
+        * For subclasses of BinaryDecimal, any implementation\r
+        * must handle the result and addend2 (right) being references\r
+        * to the same object.\r
+        */\r
+       public abstract NumberDataValue plusNN(NumberDataValue addend1,\r
+                       NumberDataValue addend2, NumberDataValue result)\r
+                       throws StandardException;\r
+\r
+       /**\r
+        * Divide two non-nullable values using DECIMAL arithmetic.\r
+        */\r
+       public abstract NumberDataValue divideNN(NumberDataValue dividend,\r
+                       NumberDataValue divisor, NumberDataValue result, int scale)\r
+                       throws StandardException;\r
+       \r
+       /*\r
+       ** Methods that act directly on twos complement byte arrays.\r
+       */\r
+\r
+       /**\r
+        * Compress the passed in byte array so that leading\r
+        * 0x00 and 0xff are removed when possible.\r
+        * E.g.\r
+        * 0x00000453 ->>> 0x0453\r
+        * 0xfffffff2 ->>> 0xf2\r
+        * 0xff192312 ->>> 0xff192312 (unchanged)\r
+        * 0xffff8039 ->>> 0x8039\r
+        * data2c is set to the compressed value.\r
+        * @param dataLength Valid length of data in data2c.\r
+        */\r
+       private static byte[] reduceBytes2c(byte[] rd, int offset, int dataLength)\r
+       {\r
+               // look for leading zeros, if the value\r
+               // is dataLength bytes long then look\r
+               // at up to the first (dataLength - 1) bytes\r
+               // to see if leading 0x00 can be removed.\r
+\r
+               int leading;\r
+               for (leading = 0; leading < (dataLength - 1); leading++)\r
+               {\r
+                       if (rd[offset + leading] != (byte) 0)\r
+                               break;\r
+                       \r
+                       // if the hi bit of the next byte is set\r
+                       // then we cannot strip this 0x00 otherwise\r
+                       // the number will turn negative.\r
+                       if ((rd[offset + leading + 1] & 0x80) != 0)\r
+                               break;\r
+               }\r
+\r
+               if (leading == 0)\r
+               {\r
+                       // now a similar trick with 0xff, but a slight\r
+                       // complication.\r
+                       for (; leading < (dataLength - 1); leading++)\r
+                       {\r
+                               // Need to check the highest byte of the\r
+                               // would-be remaining significant byte is\r
+                               // set to indicate this is still a negative number\r
+                               \r
+                               if ((rd[offset + leading] == (byte) 0xff) && ((rd[offset + leading+1] & (byte) 0x80) != 0))\r
+                                       continue;\r
+                               break;\r
+                       }\r
+               }\r
+               \r
+               if ((leading != 0) || (rd.length != dataLength))\r
+               {\r
+                       byte[] reduced = new byte[dataLength - leading];\r
+                       System.arraycopy(rd, offset + leading, reduced, 0, reduced.length);\r
+                       return reduced;\r
+               }\r
+               \r
+               return rd;\r
+       }\r
+\r
+       /**\r
+        * Return the SQL scale of this value, number of digits after the\r
+        * decimal point, or zero for a whole number.\r
+        */\r
+       public int getDecimalValueScale()\r
+       {\r
+               if (isNull())\r
+                       return 0;\r
+               \r
+               return sqlScale;\r
+       }       \r
+       \r
+       /*\r
+       ** I/O handling\r
+       */\r
+\r
+       /** \r
+        * Distill the Decimal to a byte array and\r
+        * Write out: <UL>\r
+        *      <LI> scale (unsigned byte) </LI>\r
+        *      <LI> length of byte array </LI>\r
+        *      <LI> the byte array </LI> </UL>\r
+        *\r
+        */\r
+       public void writeExternal(ObjectOutput out) throws IOException \r
+       {\r
+               // never called when value is null\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(! isNull());\r
+\r
+               out.writeByte(sqlScale);\r
+               out.writeByte(data2c.length);\r
+               out.write(data2c);\r
+       }\r
+       \r
+       /** \r
+        * Note the use of data2c: we reuse the array if the\r
+        * incoming array is the same length or smaller than\r
+        * the array length.  \r
+        * \r
+        * @see java.io.Externalizable#readExternal \r
+        */\r
+       public void readExternal(ObjectInput in) throws IOException \r
+       {\r
+               sqlScale = in.readUnsignedByte();\r
+               int size = in.readUnsignedByte();\r
+\r
+               /*\r
+               ** Allocate a new array if the data to read\r
+               ** is larger than the existing array, or if\r
+               ** we don't have an array yet.\r
+\r
+        Need to use readFully below and NOT just read because read does not\r
+        guarantee getting size bytes back, whereas readFully does (unless EOF).\r
+        */\r
+               if ((data2c == null) || size != data2c.length)\r
+               {\r
+                       data2c = new byte[size];\r
+               }\r
+               in.readFully(data2c);\r
+\r
+       }\r
+       public void readExternalFromArray(ArrayInputStream in) throws IOException \r
+       {\r
+               sqlScale = in.readUnsignedByte();\r
+               int size = in.readUnsignedByte();\r
+\r
+               /*\r
+               ** Allocate a new array if the data to read\r
+               ** is larger than the existing array, or if\r
+               ** we don't have an array yet.\r
+\r
+        Need to use readFully below and NOT just read because read does not\r
+        guarantee getting size bytes back, whereas readFully does (unless EOF).\r
+        */\r
+               if ((data2c == null) || size != data2c.length)\r
+               {\r
+                       data2c = new byte[size];\r
+               }\r
+               in.readFully(data2c);\r
+       }\r
+\r
+\r
+\r
+       public final int getLength()\r
+       {\r
+               return getDecimalValuePrecision();\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.apache.derby.iapi.types.DataValueDescriptor#getClone()\r
+        */\r
+       public DataValueDescriptor getClone() {\r
+               BinaryDecimal dvd = (BinaryDecimal) getNewNull();\r
+               \r
+               if (this.data2c != null)\r
+               {\r
+                       dvd.data2c = new byte[data2c.length];\r
+                       System.arraycopy(data2c, 0, dvd.data2c, 0, data2c.length);\r
+                       dvd.sqlScale = sqlScale;\r
+               }\r
+               \r
+               return dvd;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.apache.derby.iapi.types.DataValueDescriptor#setValueFromResultSet(java.sql.ResultSet, int, boolean)\r
+        */\r
+       public void setValueFromResultSet(ResultSet resultSet, int colNumber, boolean isNullable) throws StandardException, SQLException {\r
+               // TODO Auto-generated method stub\r
+               throw StandardException.newException(SQLState.NOT_IMPLEMENTED);\r
+               \r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see org.apache.derby.iapi.types.DataValueDescriptor#estimateMemoryUsage()\r
+        */\r
+       public int estimateMemoryUsage() {\r
+               // TODO Auto-generated method stub\r
+               return 0;\r
+       }\r
+       \r
+       public int hashCode()\r
+       {\r
+               if (isNull())\r
+                       return 0;\r
+\r
+               try {\r
+                       return (int) getLong();\r
+               } catch (StandardException se)\r
+               {\r
+                       return 0;\r
+               }\r
+       }\r
+}\r