Revision: 16681
Author: oleg.kulikoff
Date: Tue Jan 25 08:39:03 2011
Log: Issue 2293:SDP parsing worst time
http://code.google.com/p/mobicents/source/detail?r=16681

Added:
/trunk/servers/media/spi/src/test/java/org/mobicents/media/server/spi/format/AudioFormatTest.java /trunk/servers/media/spi/src/test/java/org/mobicents/media/server/spi/format/VideoFormatTest.java
Modified:
/trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/AudioFormat.java /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/EncodingName.java /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/Format.java /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/VideoFormat.java /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/utils/Text.java /trunk/servers/media/spi/src/test/java/org/mobicents/media/server/utils/TextTest.java

=======================================
--- /dev/null
+++ /trunk/servers/media/spi/src/test/java/org/mobicents/media/server/spi/format/AudioFormatTest.java Tue Jan 25 08:39:03 2011
@@ -0,0 +1,70 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.mobicents.media.server.spi.format;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author kulikov
+ */
+public class AudioFormatTest {
+
+    public AudioFormatTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getSampleRate method, of class AudioFormat.
+     */
+    @Test
+    public void testCloneExecutionTime() {
+        AudioFormat f = new AudioFormat("pcmu", 8000, 8, 1);
+
+        long s = System.currentTimeMillis();
+        for (int i = 0; i < 1000; i++) {
+            f.clone();
+        }
+        long duration = System.currentTimeMillis() - s;
+        System.out.println("Execution time: " + duration);
+        assertTrue("To slow", 3000000L > duration);
+    }
+
+    @Test
+    public void testImmutable() {
+        AudioFormat f = new AudioFormat("pcmu", 8000, 8, 1);
+        AudioFormat fc = f.clone();
+
+ //changing encoding name of the clone, original name must remains same
+        fc.setName(new EncodingName("pcma"));
+        assertEquals("pcmu", f.getName().toString());
+
+        //changing source and checking again
+        f.setName(new EncodingName("speex"));
+        assertEquals("pcma", fc.getName().toString());
+    }
+
+}
=======================================
--- /dev/null
+++ /trunk/servers/media/spi/src/test/java/org/mobicents/media/server/spi/format/VideoFormatTest.java Tue Jan 25 08:39:03 2011
@@ -0,0 +1,68 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.mobicents.media.server.spi.format;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author kulikov
+ */
+public class VideoFormatTest {
+
+    public VideoFormatTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void testCloneExecutionTime() {
+        VideoFormat f = new VideoFormat("h261", 15);
+
+        long s = System.currentTimeMillis();
+        for (int i = 0; i < 1000; i++) {
+            f.clone();
+        }
+
+        long duration = System.currentTimeMillis() - s;
+        System.out.println("Execution time: " + duration);
+        assertTrue("To slow", 3000000L > duration);
+    }
+
+    @Test
+    public void testImmutable() {
+        VideoFormat f = new VideoFormat("h261", 15);
+        VideoFormat fc = f.clone();
+
+ //changing encoding name of the clone, original name must remains same
+        fc.setName(new EncodingName("h263"));
+        assertEquals("h261", f.getName().toString());
+
+        //changing source and checking again
+        f.setName(new EncodingName("mp4v-es"));
+        assertEquals("h263", fc.getName().toString());
+    }
+
+}
=======================================
--- /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/AudioFormat.java Mon Jan 24 05:31:11 2011 +++ /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/AudioFormat.java Tue Jan 25 08:39:03 2011
@@ -23,11 +23,11 @@
  *
  * @author kulikov
  */
-public class AudioFormat extends Format {
+public class AudioFormat extends Format implements Cloneable {
     //sampling frequency
     private int sampleRate;
     //bits per sample
-    private int sampleSize;
+    private int sampleSize = -1;
     //number of channels
     private int channels = 1;

@@ -39,6 +39,47 @@
     public AudioFormat(EncodingName name) {
         super(name);
     }
+
+    /**
+     * Creates new format descriptor
+     *
+     * @param name the encoding
+     * @param sampleRate sample rate value in Hertz
+     * @param sampleSize sample size in bits
+     * @param channels number of channels
+     */
+ public AudioFormat(EncodingName name, int sampleRate, int sampleSize, int channels) {
+        super(name);
+        this.sampleRate = sampleRate;
+        this.sampleSize = sampleSize;
+        this.channels = channels;
+    }
+
+    /**
+     * Creates new format descriptor
+     *
+     * @param name the encoding
+     * @param sampleRate sample rate value in Hertz
+     * @param sampleSize sample size in bits
+     * @param channels number of channels
+     */
+ public AudioFormat(String name, int sampleRate, int sampleSize, int channels) {
+        super(new EncodingName(name));
+        this.sampleRate = sampleRate;
+        this.sampleSize = sampleSize;
+        this.channels = channels;
+    }
+
+    /**
+     * Creates new format descriptor
+     *
+     * @param name the encoding
+     * @param sampleRate sample rate value in Hertz
+     */
+    public AudioFormat(String name, int sampleRate) {
+        super(new EncodingName(name));
+        this.sampleRate = sampleRate;
+    }

     /**
      * Gets the sampling rate.
@@ -96,4 +137,8 @@
         this.channels = channels;
     }

-}
+    @Override
+    protected AudioFormat clone() {
+ return new AudioFormat(getName(), sampleRate, sampleSize, channels);
+    }
+}
=======================================
--- /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/EncodingName.java Mon Jan 24 05:31:11 2011 +++ /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/EncodingName.java Tue Jan 25 08:39:03 2011
@@ -29,7 +29,11 @@
     public EncodingName() {
         super();
     }
-
+
+    public EncodingName(Text text) {
+        super(text);
+    }
+
     public EncodingName(String s) {
         super(s);
     }
=======================================
--- /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/Format.java Mon Jan 24 05:31:11 2011 +++ /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/Format.java Tue Jan 25 08:39:03 2011
@@ -18,17 +18,19 @@

 package org.mobicents.media.server.spi.format;

+import org.mobicents.media.server.utils.Text;
+
 /**
  * Media format descriptor.
  *
  * @author kulikov
  */
-public class Format {
+public class Format implements Cloneable {
     //encoding name
     private EncodingName name;

     //any specific options
-    private String options;
+    private Text options;

     /**
      * Creates new descriptor.
@@ -63,7 +65,7 @@
      *
      * @return options as text.
      */
-    public String getOptions() {
+    public Text getOptions() {
         return options;
     }

@@ -72,7 +74,7 @@
      *
      * @param options new options.
      */
-    public void setOptions(String options) {
+    public void setOptions(Text options) {
         this.options = options;
     }

=======================================
--- /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/VideoFormat.java Mon Jan 24 05:31:11 2011 +++ /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/spi/format/VideoFormat.java Tue Jan 25 08:39:03 2011
@@ -21,7 +21,7 @@
  *
  * @author kulikov
  */
-public class VideoFormat extends Format {
+public class VideoFormat extends Format implements Cloneable {
     //number of frames per second
     private int frameRate;

@@ -33,6 +33,37 @@
     public VideoFormat(EncodingName name) {
         super(name);
     }
+
+    /**
+     * Creates new format descriptor.
+     *
+     * @param name format encoding name.
+     * @param  frameRate the number of frames per second.
+     */
+    public VideoFormat(EncodingName name, int frameRate) {
+        super(name);
+        this.frameRate = frameRate;
+    }
+
+    /**
+     * Creates new format descriptor.
+     *
+     * @param name format encoding name.
+     */
+    public VideoFormat(String name) {
+        super(new EncodingName(name));
+    }
+
+    /**
+     * Creates new format descriptor.
+     *
+     * @param name format encoding name.
+     * @param  frameRate the number of frames per second.
+     */
+    public VideoFormat(String name, int frameRate) {
+        super(new EncodingName(name));
+        this.frameRate = frameRate;
+    }

     /**
      * Gets the frame rate.
@@ -51,4 +82,10 @@
     public void setFrameRate(int frameRate) {
         this.frameRate = frameRate;
     }
-}
+
+    @Override
+    protected VideoFormat clone() {
+        return new VideoFormat(getName(), frameRate);
+    }
+
+}
=======================================
--- /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/utils/Text.java Mon Jan 24 05:31:11 2011 +++ /trunk/servers/media/spi/src/main/java/org/mobicents/media/server/utils/Text.java Tue Jan 25 08:39:03 2011
@@ -17,10 +17,12 @@
  */
 package org.mobicents.media.server.utils;

+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;

 /**
- * Case insensitive character string representation.
+ * Case insensitive text block representation.
  *
  * This class provides time deterministic and fast methods for creating
* and comparing short character strings like format names, attribute values, etc.
@@ -29,13 +31,16 @@
  */
 public class Text implements CharSequence {
     //reference on the local buffer
-    private byte[] chars;
+    protected byte[] chars;

     //the start position
-    private int pos;
+    protected int pos;

     //the length of the string
-    private int len;
+    protected int len;
+
+    /** points to the line separator */
+    private int linePointer;

     /**
      * Create an empty text object.
@@ -45,6 +50,17 @@
     public Text() {
     }

+    /**
+     * Creates new object with specified text.
+     *
+     * @param another the text object.
+     */
+    protected Text(Text another) {
+        this.chars = another.chars;
+        this.pos = another.pos;
+        this.len = another.len;
+    }
+
     /**
      * Creates new instance with specified text.
      *
@@ -94,7 +110,7 @@
      * @see java.lang.CharSequence#charAt(int)
      */
     public char charAt(int index) {
-        return (char) chars[index];
+        return (char) chars[pos + index];
     }

     /**
@@ -104,6 +120,78 @@
     public CharSequence subSequence(int start, int end) {
         return new Text(chars, start, end - start);
     }
+
+    /**
+     * Splits text into partitions.
+     *
+     * @param separator character used for partitioning
+     * @return array of text strings.
+     */
+    public Collection<Text> split(char separator) {
+        int pointer = pos;
+        int limit = pos + len;
+        int mark = pointer;
+
+        ArrayList<Text> tokens = new ArrayList();
+        while (pointer < limit) {
+            if (chars[pointer] == separator) {
+                tokens.add(new Text(chars, mark, pointer - mark));
+                mark = pointer + 1;
+            }
+            pointer++;
+        }
+
+        tokens.add(new Text(chars, mark, limit - mark));
+        return tokens;
+    }
+
+    /**
+     * Removes whitespaces from the head and tail of the string.
+     *
+     */
+    public void trim() {
+        //cut white spaces from the head
+        while (chars[pos] == ' ') {
+            pos++;
+            len--;
+        }
+
+        //cut from the end
+        while (chars[pos + len - 1] == ' ') {
+            len--;
+        }
+    }
+
+    /**
+     * Extracts next line from this text.
+     *
+     * @return
+     */
+    public Text nextLine() {
+        if (linePointer == 0) {
+            linePointer = pos;
+        } else {
+            linePointer++;
+        }
+
+        int mark = linePointer;
+        int limit = pos + len;
+
+        while (linePointer < limit && chars[linePointer] != '\n') {
+            linePointer++;
+        }
+
+        return new Text(chars, mark, linePointer - mark);
+    }
+
+    /**
+     * Shows is this text contains more lines.
+     *
+     * @return true if there are more lines
+     */
+    public boolean hasMoreLines() {
+        return linePointer < pos + len;
+    }

     @Override
     public boolean equals(Object other) {
@@ -116,7 +204,11 @@
         }

         Text t = (Text) other;
-        return compareChars(t.chars);
+        if (this.len != t.len) {
+            return false;
+        }
+
+        return compareChars(t.chars, t.pos);
     }

     @Override
@@ -126,16 +218,27 @@
         return hash;
     }

-    private boolean compareChars(byte[] chars) {
-        if (this.chars.length != chars.length) {
-            return false;
-        }
-        for (int i = 0; i < this.chars.length; i++) {
- if (differentChars((char) this.chars[i], (char) chars[i])) return false;
+    /**
+     * Compares specified character string with current string.
+     * The upper and lower case charactes are considered as equals.
+     *
+     * @param chars the string to be compared
+     * @return true if specified string equals to current
+     */
+    private boolean compareChars(byte[] chars, int pos) {
+        for (int i = 0; i < len; i++) {
+ if (differentChars((char) this.chars[i + this.pos], (char) chars[i + pos])) return false;
         }
         return true;
     }

+    /**
+     * Compares two chars.
+     *
+     * @param c1 the first char
+     * @param c2 the second char
+     * @return tru if first and second chars are different.
+     */
     private boolean differentChars(char c1, char c2) {
         if (65 <= c1 && c1 <= 97) {
             c1 +=32;
@@ -152,4 +255,39 @@
         return new String(chars, pos, len);
     }

-}
+    /**
+     * Converts string value to integer
+     * @return ineger value
+     */
+    public int toInteger() {
+        int res = 0;
+        for (int i = 0; i < len; i++) {
+            res += digit(pos + i) * pow(len - i - 1);
+        }
+        return res;
+    }
+
+    /**
+     * 10^a
+     *
+     * @param a the power
+     * @return the value of 10^a
+     */
+    private int pow(int a) {
+        int res = 1;
+        for (int i = 0; i < a; i++) {
+            res *= 10;
+        }
+        return res;
+    }
+
+    /**
+     * Converts character to digit.
+     *
+     * @param pos the position of the character
+     * @return the digit value
+     */
+    private int digit(int pos) {
+        return chars[pos] - 48;
+    }
+}
=======================================
--- /trunk/servers/media/spi/src/test/java/org/mobicents/media/server/utils/TextTest.java Mon Jan 24 05:31:11 2011 +++ /trunk/servers/media/spi/src/test/java/org/mobicents/media/server/utils/TextTest.java Tue Jan 25 08:39:03 2011
@@ -5,6 +5,8 @@

 package org.mobicents.media.server.utils;

+import java.util.Iterator;
+import java.util.Collection;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -73,6 +75,16 @@
             assertEquals(s.charAt(i), t.charAt(i));
         }
     }
+
+    @Test
+    public void testCharAtWithShifting() {
+        String s = "12345 One two three";
+        byte[] data = s.getBytes();
+        Text t = new Text();
+        t.strain(data, 6, data.length -6);
+
+        assertEquals('O', t.charAt(0));
+    }

     /**
      * Test of subSequence method, of class Text.
@@ -104,6 +116,20 @@
         Text t2 = new Text("test");
         assertTrue("Must be equals", t1.equals(t2));
     }
+
+    @Test
+    public void testEqualsDifferentBackground() {
+        Text t1 = new Text("test");
+
+        String s = "12345678test";
+
+        Text t2 = new Text();
+        t2.strain(s.getBytes(), 8, 4);
+
+        boolean res = t1.equals(t2);
+
+        assertTrue("Must be equals", res);
+    }

     @Test
     public void testEqualsWithDifferentCase() {
@@ -112,6 +138,83 @@
         assertTrue("Must be equals", t1.equals(t2));
     }

+    @Test
+    public void testSplit() {
+        Text t1 = new Text("test test1 test2");
+
+        Collection<Text> tokens = t1.split(' ');
+        assertEquals(3, tokens.size());
+
+        Iterator<Text> i = tokens.iterator();
+
+        Text t = i.next();
+        assertEquals("test", t.toString());
+
+        t = i.next();
+        assertEquals("test1", t.toString());
+
+        t = i.next();
+        assertEquals("test2", t.toString());
+    }
+
+    @Test
+    public void testSplitExecutionTime() {
+        Text t1 = new Text("test test1 test2");
+
+        long s = System.nanoTime();
+        for (int i = 0; i < 1000; i++) {
+            Collection<Text> tokens = t1.split(' ');
+        }
+
+        long f = System.nanoTime();
+        System.out.println("Split execution time=" + (f-s));
+        assertTrue("Too slow", 3000000 > (f-s));
+    }
+
+    @Test
+    public void testTrim() {
+        Text t1 = new Text(" test ");
+        t1.trim();
+        assertEquals("test", t1.toString());
+    }
+
+    @Test
+    public void testToInteger() {
+        Text t1 = new Text("1234");
+        assertEquals(1234, t1.toInteger());
+    }
+
+    @Test
+    public void testLineSplit() {
+        Text t1 = new Text("test\ntest1\ntest2");
+
+        Text t = t1.nextLine();
+        assertEquals("test", t.toString());
+
+        t = t1.nextLine();
+        assertEquals("test1", t.toString());
+
+        t = t1.nextLine();
+        assertEquals("test2", t.toString());
+    }
+
+    @Test
+    public void testMoreLines() {
+        Text t1 = new Text("test\ntest1\ntest2");
+
+        assertTrue(t1.hasMoreLines());
+        Text t = t1.nextLine();
+        assertEquals("test", t.toString());
+
+        t = t1.nextLine();
+        assertEquals("test1", t.toString());
+
+        t = t1.nextLine();
+        assertEquals("test2", t.toString());
+
+        assertFalse(t1.hasMoreLines());
+    }
+
     @Test
     public void perfTests() {
         byte[] data = "name1".getBytes();

Reply via email to