int maxLen)
throws StandardException
{
int startInt;
int lengthInt;
BitDataValue varbitResult;
if (result == null)
{
result = new SQLVarbit();
}
varbitResult = (BitDataValue) result;
/* The result is null if the receiver (this) is null or if the length is negative.
* Oracle docs don't say what happens if the start position or the length is a usernull.
* We will return null, which is the only sensible thing to do.
* (If the user did not specify a length then length is not a user null.)
*/
if (this.isNull() || start.isNull() || (length != null && length.isNull()))
{
varbitResult.setToNull();
return varbitResult;
}
startInt = start.getInt();
// If length is not specified, make it till end of the string
if (length != null)
{
lengthInt = length.getInt();
}
else lengthInt = getLength() - startInt + 1;
/* DB2 Compatibility: Added these checks to match DB2. We currently enforce these
* limits in both modes. We could do these checks in DB2 mode only, if needed, so
* leaving earlier code for out of range in for now, though will not be exercised
*/
if ((startInt <= 0 || lengthInt < 0 || startInt > getLength() ||
lengthInt > getLength() - startInt + 1))
throw StandardException.newException(SQLState.LANG_SUBSTR_START_OR_LEN_OUT_OF_RANGE);
// Return null if length is non-positive
if (lengthInt < 0)
{
varbitResult.setToNull();
return varbitResult;
}
/* If startInt < 0 then we count from the right of the string */
if (startInt < 0)
{
startInt += getLength();
if (startInt < 0)
{
lengthInt += startInt;
startInt = 0;
}
if (lengthInt + startInt > 0)
{
lengthInt += startInt;
}
else
{
lengthInt = 0;
}
}
else if (startInt > 0)
{
/* java substr() is 0 based */
startInt--;
}
/* Oracle docs don't say what happens if the window is to the
* left of the string. Return "" if the window
* is to the left or right or if the length is 0.
*/
if (lengthInt == 0 ||
lengthInt <= 0 - startInt ||
startInt > getLength())
{
varbitResult.setValue(new byte[0]);
return varbitResult;
}
if (lengthInt >= getLength() - startInt)
{
byte[] substring = new byte[dataValue.length - startInt];
System.arraycopy(dataValue, startInt, substring, 0, substring.length);
varbitResult.setValue(substring);
}
else
{
byte[] substring = new byte[lengthInt];
System.arraycopy(dataValue, startInt, substring, 0, substring.length);
varbitResult.setValue(substring);
}
return varbitResult;
}