Skip to content

Commit

Permalink
Don't call length from substring
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed Nov 2, 2017
1 parent 24f8667 commit e80ac45
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 24 deletions.
Expand Up @@ -158,21 +158,21 @@ public int computeHash()
@Override
public TextValue substring( int start, int length )
{
int s = Math.min( start, length() );
int e = Math.min( s + length, length() );
byte[] values = bytes;
if ( s >= e )
if ( start < 0 || length < 0 )
{
return StringValue.EMTPY;
throw new IndexOutOfBoundsException( "Cannot handle negative start index nor negative length" );
}

int end = start + length;
byte[] values = bytes;
int count = 0, byteStart = -1, byteEnd = -1, i = offset, len = offset + byteLength;
while ( i < len )
{
if ( count == s )
if ( count == start )
{
byteStart = i;
}
if ( count == e )
if ( count == end )
{
byteEnd = i;
break;
Expand All @@ -196,9 +196,10 @@ public TextValue substring( int start, int length )
{
byteEnd = len;
}

assert byteStart >= 0;
assert byteEnd >= byteStart;
if ( byteStart < 0 )
{
return StringValue.EMTPY;
}
return new UTF8StringValue( values, byteStart, byteEnd - byteStart );
}

Expand Down
Expand Up @@ -48,7 +48,7 @@ public final class Values
public static final Value MAX_STRING = Values.booleanValue( false );
public static final BooleanValue TRUE = Values.booleanValue( true );
public static final BooleanValue FALSE = Values.booleanValue( false );
public static final TextValue EMPTY_STRING = Values.stringValue( "" );
public static final TextValue EMPTY_STRING = StringValue.EMTPY;
public static final DoubleValue E = Values.doubleValue( Math.E );
public static final DoubleValue PI = Values.doubleValue( Math.PI );
public static final ArrayValue EMPTY_SHORT_ARRAY = Values.shortArray( new short[0] );
Expand Down
Expand Up @@ -19,18 +19,22 @@
*/
package org.neo4j.values.storable;

import org.junit.Rule;
import org.junit.Test;

import java.nio.charset.StandardCharsets;
import org.junit.rules.ExpectedException;

import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.neo4j.values.storable.Values.stringValue;
import static org.neo4j.values.storable.Values.utf8Value;

public class UTF8StringValueTest
{
@Rule
public ExpectedException exception = ExpectedException.none();

private String[] strings = {"", "1337", " ", "普通话/普通話", "\uD83D\uDE21", " a b c ", "䤹᳽", "熨", "ۼ",
"ⲹ楡톜ഷۢ⼈늉₭샺ጚ砧攡跿家䯶鲏⬖돛犽ۼ",
" 㺂࿝鋦毠",//first character is a thin space,
Expand All @@ -43,7 +47,7 @@ public void shouldHandleDifferentTypesOfStrings()
for ( String string : strings )
{
TextValue stringValue = stringValue( string );
byte[] bytes = string.getBytes( StandardCharsets.UTF_8 );
byte[] bytes = string.getBytes( UTF_8 );
TextValue utf8 = utf8Value( bytes );
assertSame( stringValue, utf8 );
}
Expand All @@ -55,7 +59,7 @@ public void shouldTrimDifferentTypesOfStrings()
for ( String string : strings )
{
TextValue stringValue = stringValue( string );
byte[] bytes = string.getBytes( StandardCharsets.UTF_8 );
byte[] bytes = string.getBytes( UTF_8 );
TextValue utf8 = utf8Value( bytes );
assertSame( stringValue.trim(), utf8.trim() );
}
Expand All @@ -67,7 +71,7 @@ public void shouldLTrimDifferentTypesOfStrings()
for ( String string : strings )
{
TextValue stringValue = stringValue( string );
byte[] bytes = string.getBytes( StandardCharsets.UTF_8 );
byte[] bytes = string.getBytes( UTF_8 );
TextValue utf8 = utf8Value( bytes );
assertSame( stringValue.ltrim(), utf8.ltrim() );
}
Expand All @@ -78,7 +82,7 @@ public void trimShouldBeSameAsLtrimAndRtrim()
{
for ( String string : strings )
{
TextValue utf8 = utf8Value( string.getBytes( StandardCharsets.UTF_8 ) );
TextValue utf8 = utf8Value( string.getBytes( UTF_8 ) );
assertSame( utf8.trim(), utf8.ltrim().rtrim() );
}
}
Expand All @@ -87,7 +91,7 @@ public void trimShouldBeSameAsLtrimAndRtrim()
public void shouldSubstring()
{
String string = "ü";
TextValue utf8 = utf8Value( string.getBytes( StandardCharsets.UTF_8 ) );
TextValue utf8 = utf8Value( string.getBytes( UTF_8 ) );
assertThat( utf8.substring( 0, 1 ).stringValue(), equalTo( "ü" ) );
}

Expand All @@ -97,7 +101,7 @@ public void shouldRTrimDifferentTypesOfStrings()
for ( String string : strings )
{
TextValue stringValue = stringValue( string );
byte[] bytes = string.getBytes( StandardCharsets.UTF_8 );
byte[] bytes = string.getBytes( UTF_8 );
TextValue utf8 = utf8Value( bytes );
assertSame( stringValue.rtrim(), utf8.rtrim() );
}
Expand All @@ -111,10 +115,10 @@ public void shouldCompareTo()
for ( String string2 : strings )
{

int x = stringValue( string1 ).compareTo( utf8Value( string2.getBytes( StandardCharsets.UTF_8 ) ) );
int y = utf8Value( string1.getBytes( StandardCharsets.UTF_8 ) ).compareTo( stringValue( string2 ) );
int z = utf8Value( string1.getBytes( StandardCharsets.UTF_8 ) )
.compareTo( utf8Value( string2.getBytes( StandardCharsets.UTF_8 ) ) );
int x = stringValue( string1 ).compareTo( utf8Value( string2.getBytes( UTF_8 ) ) );
int y = utf8Value( string1.getBytes( UTF_8 ) ).compareTo( stringValue( string2 ) );
int z = utf8Value( string1.getBytes( UTF_8 ) )
.compareTo( utf8Value( string2.getBytes( UTF_8 ) ) );

assertThat( x, equalTo( y ) );
assertThat( x, equalTo( z ) );
Expand All @@ -126,7 +130,7 @@ public void shouldCompareTo()
public void shouldHandleOffset()
{
// Given
byte[] bytes = "abcdefg".getBytes( StandardCharsets.UTF_8 );
byte[] bytes = "abcdefg".getBytes( UTF_8 );

// When
TextValue textValue = utf8Value( bytes, 3, 2 );
Expand All @@ -144,4 +148,56 @@ private void assertSame( TextValue lhs, TextValue rhs )
assertThat( format( "%s.hashCode != %s.hashCode", rhs, lhs ), lhs.hashCode(), equalTo( rhs.hashCode() ) );
assertThat( lhs, equalTo( rhs ) );
}

@Test
public void shouldHandleTooLargeStartPointInSubstring()
{
// Given
UTF8StringValue value = utf8Value( "hello".getBytes( UTF_8 ) );

// When
TextValue substring = value.substring( 8, 5 );

// Then
assertThat( substring, equalTo( StringValue.EMTPY ) );
}

@Test
public void shouldHandleTooLargeLengthInSubstring()
{
// Given
UTF8StringValue value = utf8Value( "hello".getBytes( UTF_8 ) );

// When
TextValue substring = value.substring( 3, 76 );

// Then
assertThat( substring.stringValue(), equalTo( "lo" ) );
}

@Test
public void shouldThrowOnNegativeStart()
{
// Given
UTF8StringValue value = utf8Value( "hello".getBytes( UTF_8 ) );

// Expect
exception.expect( IndexOutOfBoundsException.class );

// When
value.substring( -4, 3 );
}

@Test
public void shouldThrowOnNegativeLength()
{
// Given
UTF8StringValue value = utf8Value( "hello".getBytes( UTF_8 ) );

// Expect
exception.expect( IndexOutOfBoundsException.class );

// When
value.substring( 4, -3 );
}
}

0 comments on commit e80ac45

Please sign in to comment.