diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index daa4f0d62..f1c961d58 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionName="1.0" >
diff --git a/android/src/net/sf/openrocket/android/thrustcurve/ThrustCurveAPI.java b/android/src/net/sf/openrocket/android/thrustcurve/ThrustCurveAPI.java
index 6b74c2856..0d1a3de42 100644
--- a/android/src/net/sf/openrocket/android/thrustcurve/ThrustCurveAPI.java
+++ b/android/src/net/sf/openrocket/android/thrustcurve/ThrustCurveAPI.java
@@ -18,14 +18,14 @@ import net.sf.openrocket.motor.ThrustCurveMotorPlaceholder;
public abstract class ThrustCurveAPI {
- private static String url_base = "http://www.thrustcurve.org/servlets/";
+ //private static String url_base = "http://www.thrustcurve.org/servlets/";
public static SearchResponse doSearch( SearchRequest request ) throws MalformedURLException, IOException {
String requestString = request.toString();
AndroidLogWrapper.d(ThrustCurveAPI.class, "doSearch: " + requestString);
- URL url = new URL(url_base + "search");
+ URL url = new URL("http", "www.thurustcurve.org", "servlets/search");
OutputStream stream;
@@ -58,7 +58,7 @@ public abstract class ThrustCurveAPI {
String requestString = dr.toString();
AndroidLogWrapper.d(ThrustCurveAPI.class, "downloadData: " + requestString);
- URL url = new URL(url_base + "download");
+ URL url = new URL("http", "www.thurustcurve.org", "servlets/download");
OutputStream stream;
diff --git a/core/src/net/sf/openrocket/file/GeneralRocketLoader.java b/core/src/net/sf/openrocket/file/GeneralRocketLoader.java
index 775d9eddf..16f9c9acd 100644
--- a/core/src/net/sf/openrocket/file/GeneralRocketLoader.java
+++ b/core/src/net/sf/openrocket/file/GeneralRocketLoader.java
@@ -12,6 +12,7 @@ import java.util.zip.ZipInputStream;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.file.openrocket.importt.OpenRocketLoader;
import net.sf.openrocket.file.rocksim.importt.RocksimLoader;
+import net.sf.openrocket.util.TextUtil;
/**
@@ -26,9 +27,9 @@ public class GeneralRocketLoader extends AbstractRocketLoader {
private static final int READ_BYTES = 300;
private static final byte[] GZIP_SIGNATURE = { 31, -117 }; // 0x1f, 0x8b
- private static final byte[] ZIP_SIGNATURE = "PK".getBytes(Charset.forName("US-ASCII"));
- private static final byte[] OPENROCKET_SIGNATURE = " handlerStack = new ArrayDeque();
- private final Deque elementData = new ArrayDeque();
- private final Deque> elementAttributes = new ArrayDeque>();
+ private final SimpleStack handlerStack = new SimpleStack();
+ private final SimpleStack elementData = new SimpleStack();
+ private final SimpleStack> elementAttributes = new SimpleStack>();
// Ignore all elements as long as ignore > 0
diff --git a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java
index b27fbbb0d..9000a5400 100644
--- a/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java
+++ b/core/src/net/sf/openrocket/rocketcomponent/RocketComponent.java
@@ -1,8 +1,6 @@
package net.sf.openrocket.rocketcomponent;
-import java.util.ArrayDeque;
import java.util.Collection;
-import java.util.Deque;
import java.util.EventListener;
import java.util.Iterator;
import java.util.List;
@@ -21,6 +19,7 @@ import net.sf.openrocket.util.Invalidator;
import net.sf.openrocket.util.LineStyle;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.SafetyMutex;
+import net.sf.openrocket.util.SimpleStack;
import net.sf.openrocket.util.UniqueID;
@@ -1853,7 +1852,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
*/
private static class RocketComponentIterator implements Iterator {
// Stack holds iterators which still have some components left.
- private final Deque> iteratorStack = new ArrayDeque>();
+ private final SimpleStack> iteratorStack = new SimpleStack>();
private final Rocket root;
private final int treeModID;
diff --git a/core/src/net/sf/openrocket/util/ArrayUtils.java b/core/src/net/sf/openrocket/util/ArrayUtils.java
new file mode 100644
index 000000000..4202c53ce
--- /dev/null
+++ b/core/src/net/sf/openrocket/util/ArrayUtils.java
@@ -0,0 +1,46 @@
+package net.sf.openrocket.util;
+
+import java.lang.reflect.Array;
+
+public class ArrayUtils {
+
+ /**
+ * Implementation of java.util.Arrays.copyOfRange
+ *
+ * Since Froyo does not include this function it must be implemented here.
+ *
+ * @param original
+ * @param start
+ * @param end
+ * @return
+ */
+ public static T[] copyOfRange( T[] original, int start, int end ) {
+
+ if ( original == null ) {
+ throw new NullPointerException();
+ }
+
+ if ( start < 0 || start > original.length ) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ if ( start > end ) {
+ throw new IllegalArgumentException();
+ }
+
+ T[] result = (T[]) Array.newInstance( original.getClass().getComponentType(), end-start );
+
+ int index = 0;
+ int stop = original.length < end ? original.length : end;
+ for ( int i = start; i < stop; i ++ ) {
+ if ( i < original.length ) {
+ result[index] = original[i];
+ }
+ index++;
+ }
+
+ return result;
+
+ }
+
+}
diff --git a/core/src/net/sf/openrocket/util/SimpleStack.java b/core/src/net/sf/openrocket/util/SimpleStack.java
new file mode 100644
index 000000000..6bdd96718
--- /dev/null
+++ b/core/src/net/sf/openrocket/util/SimpleStack.java
@@ -0,0 +1,29 @@
+package net.sf.openrocket.util;
+
+import java.util.NoSuchElementException;
+/**
+ * SimpleStack implementation backed by an ArrayList.
+ *
+ */
+public class SimpleStack extends ArrayList {
+
+ public void push( T value ) {
+ this.add(value);
+ }
+
+ public T peek() {
+ if ( size() <= 0 ) {
+ return null;
+ }
+ return this.get( size() -1 );
+ }
+
+ public T pop() {
+ if ( size() <= 0 ) {
+ throw new NoSuchElementException();
+ }
+ T value = this.remove( size() -1 );
+ return value;
+ }
+
+}
diff --git a/core/src/net/sf/openrocket/util/TextUtil.java b/core/src/net/sf/openrocket/util/TextUtil.java
index 32dffd849..0189545e0 100644
--- a/core/src/net/sf/openrocket/util/TextUtil.java
+++ b/core/src/net/sf/openrocket/util/TextUtil.java
@@ -1,12 +1,32 @@
package net.sf.openrocket.util;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
public class TextUtil {
+
+
private static final char[] HEX = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
-
+
+ /**
+ * Return the byte array for the string in the given charset.
+ *
+ * This function is implemented because Froyo (Android API 8) does not support
+ * String.getBytes(Charset)
+ *
+ * @param string
+ * @param charSet
+ * @return
+ */
+ public static byte[] convertStringToBytes( String string, Charset charSet ) {
+ ByteBuffer encoded = charSet.encode(string);
+ return encoded.array();
+ }
+
/**
* Return the bytes formatted as a hexadecimal string. The length of the
diff --git a/core/test/net/sf/openrocket/util/ArrayUtilsTest.java b/core/test/net/sf/openrocket/util/ArrayUtilsTest.java
new file mode 100644
index 000000000..aefc21856
--- /dev/null
+++ b/core/test/net/sf/openrocket/util/ArrayUtilsTest.java
@@ -0,0 +1,84 @@
+package net.sf.openrocket.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+public class ArrayUtilsTest {
+
+ @Test(expected=NullPointerException.class)
+ public void testCopyOfRange_NullArg() {
+ ArrayUtils.copyOfRange( (Byte[]) null, 0 , 14);
+ }
+
+ @Test(expected=ArrayIndexOutOfBoundsException.class)
+ public void testCopyOfRange_StartTooBig() {
+ Integer[] original = new Integer[5];
+ ArrayUtils.copyOfRange( original, 8 , 14);
+ }
+
+ @Test(expected=ArrayIndexOutOfBoundsException.class)
+ public void testCopyOfRange_StartTooSmall() {
+ Integer[] original = new Integer[5];
+ ArrayUtils.copyOfRange( original, -1 , 14);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testCopyOfRange_IllegalRange() {
+ Integer[] original = new Integer[5];
+ ArrayUtils.copyOfRange( original, 5, 0 );
+ }
+
+ @Test
+ public void testCopyOfRange() {
+ Integer[] original = new Integer[5];
+ for ( int i =0; i < 5; i++ ) {
+ original[i] = i;
+ }
+ Integer[] copy = ArrayUtils.copyOfRange( original, 0, 0 );
+ assertEquals( 0, copy.length );
+
+ copy = ArrayUtils.copyOfRange( original, 2, 2 );
+ assertEquals( 0, copy.length );
+
+ copy = ArrayUtils.copyOfRange( original, 0, 2 );
+ assertEquals( 2, copy.length );
+ for( int i =0; i< 2; i++ ) {
+ assertEquals( original[i], copy[i] );
+ }
+
+ copy = ArrayUtils.copyOfRange( original, 2, 5 );
+ assertEquals( 3, copy.length );
+ for( int i =0; i< 3; i++ ) {
+ assertEquals( original[i+2], copy[i] );
+ }
+
+ copy = ArrayUtils.copyOfRange( original, 2, 15 );
+ assertEquals( 13, copy.length );
+ for( int i =0; i< 3; i++ ) {
+ assertEquals( original[i+2], copy[i] );
+ }
+ for ( int i=3; i< 13; i++ ) {
+ assertNull(copy[i]);
+ }
+
+ }
+
+ @Test
+ public void testCopyOfRange_ZeroSize() {
+ Integer[] original = new Integer[0];
+
+ Integer[] copy = ArrayUtils.copyOfRange( original, 0, 0 );
+ assertEquals( 0, copy.length );
+
+ copy = ArrayUtils.copyOfRange( original, 0, 2 );
+ assertEquals( 2, copy.length );
+ for( int i =0; i< 2; i++ ) {
+ assertEquals( null, copy[i] );
+ }
+
+ }
+
+
+}
diff --git a/core/test/net/sf/openrocket/util/SimpleStackTest.java b/core/test/net/sf/openrocket/util/SimpleStackTest.java
new file mode 100644
index 000000000..16cd312be
--- /dev/null
+++ b/core/test/net/sf/openrocket/util/SimpleStackTest.java
@@ -0,0 +1,43 @@
+package net.sf.openrocket.util;
+
+import java.util.NoSuchElementException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+public class SimpleStackTest {
+
+ @Test(expected=NoSuchElementException.class)
+ public void testEmptyStack() {
+ SimpleStack s = new SimpleStack();
+
+ assertNull(s.peek());
+
+ s.pop();
+ }
+
+ @Test
+ public void testPushAndPop() {
+
+ SimpleStack s = new SimpleStack();
+
+ for( int i = 0; i< 10; i++ ) {
+ s.push(i);
+ assertEquals(i+1, s.size());
+ }
+
+ for( int i=9; i>= 0; i-- ) {
+ assertEquals( i, s.peek().intValue() );
+ Integer val = s.pop();
+ assertEquals( i, val.intValue() );
+ assertEquals( i, s.size() );
+ }
+
+ assertNull( s.peek() );
+ assertEquals( 0, s.size() );
+
+ }
+
+}
diff --git a/core/test/net/sf/openrocket/util/TextUtilTest.java b/core/test/net/sf/openrocket/util/TextUtilTest.java
index 8ac8319d0..4c040fbbe 100644
--- a/core/test/net/sf/openrocket/util/TextUtilTest.java
+++ b/core/test/net/sf/openrocket/util/TextUtilTest.java
@@ -2,13 +2,36 @@ package net.sf.openrocket.util;
import static java.lang.Math.PI;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+import java.nio.charset.Charset;
import java.util.Random;
import org.junit.Test;
public class TextUtilTest {
+ @Test
+ public void testConvertStringToBytes() {
+
+ Charset us_ascii = Charset.forName("US-ASCII");
+
+ byte[] ZIP_SIGNATURE_CORRECT = "PK".getBytes(us_ascii);
+ byte[] ZIP_SIGNATURE_TEST = TextUtil.convertStringToBytes( "PK", us_ascii);
+
+ assertArrayEquals( ZIP_SIGNATURE_CORRECT, ZIP_SIGNATURE_TEST );
+
+ byte[] OPENROCKET_SIGNATURE_CORRECT = "