View Javadoc

1   /*
2    * jSDP: A Java implementation of SDP protocol Copyright (C) 2007 Claudio Di
3    * Vita
4    */
5   package net.sourceforge.jsdp;
6   
7   import java.util.regex.Matcher;
8   import java.util.regex.Pattern;
9   
10  /**
11   * A <tt>Bandwith</tt> represents an <b>b=<i>&lt;field value&gt;</i></b>
12   * field contained in a SDP message.
13   * <p>
14   * A bandwith field specifies the proposed bandwidth to be used by the session
15   * or media, and is optional. Multiple bandwidth specifiers of different types
16   * may be associated with the same {@link SessionDescription}. Each has the
17   * form <b>b<i>=&lt;modifier&gt;</i>:<i>&lt;value&gt;</i></b>. There are
18   * four bandwith modifers (or types):
19   * </p>
20   * <ul>
21   * <li>AS: Application Specific maximum. The bandwidth is interpreted to be
22   * application-specific, and will be treated as application's concept of maximum
23   * bandwidth</li>
24   * <br/>
25   * <li>CT: Conference Total. An implicit maximum bandwidth is associated with
26   * each TTL on the Mbone or within a particular multicast administrative scope
27   * region (the Mbone bandwidth vs. TTL limits are given in the MBone FAQ). If
28   * the bandwidth of a session or media in a session is different from the
29   * bandwidth implicit from the scope, a <b>b=CT:<i>&lt;bandwith&gt;</i></b>
30   * line should be supplied for the session giving the proposed upper limit to
31   * the bandwidth used.<br/>The primary purpose of this is to give an
32   * approximate idea as to whether two or more conferences can co-exist
33   * simultaneously</li>
34   * <br/>
35   * <li>RS: RCTP bandwith for data senders</li>
36   * <br/>
37   * <li>RR: RCTP bandwith for other participants in the RTP session</li>
38   * </ul>
39   * 
40   * @since 0.1.0
41   * 
42   * @version 1.0
43   * 
44   * @author <a href="mailto:cdivita@users.sourceforge.net">Claudio Di Vita</a>
45   */
46  public class Bandwith implements Field {
47  
48      /** The class Stream Unique Identifier, SUID */
49      private static final long serialVersionUID = 8829981734747249624L;
50  
51      /** The AS modifier */
52      public static final String AS = "AS";
53  
54      /** The CT modifier */
55      public static final String CT = "CT";
56  
57      /** The RS modifier */
58      public static final String RS = "RS";
59  
60      /** The RR modifier */
61      public static final String RR = "RR";
62  
63      /** The pattern used to parse the field */
64      private static final Pattern fieldPattern = Pattern.compile("(.+):((\\d+))");
65  
66      /** The bandwith modifier */
67      protected String modifier;
68  
69      /** The bandwith value, in kbits/second */
70      protected int value;
71  
72      /**
73       * Creates a new <tt>Bandwith</tt>.
74       */
75      protected Bandwith() {
76  
77          super();
78      }
79  
80      /**
81       * Creates a new <tt>Bandwith</tt>.
82       * 
83       * @param modifier the bandwith modifier
84       * @param value the bandwith value in kbits/second
85       * 
86       * @throws SDPException if the modifier is unknown, or the value is negative
87       */
88      public Bandwith(final String modifier, final int value) throws SDPException {
89  
90          this();
91  
92          setModifier(modifier);
93          setValue(value);
94      }
95  
96      /**
97       * Parse an input string and constructs the equivalent bandwith field.
98       * 
99       * @param field the string to parse
100      * 
101      * @return a new <tt>Bandwith</tt> instance
102      * 
103      * @throws SDPParseException if an error occurs while parsing
104      */
105     public static Bandwith parse(final String field) throws SDPParseException {
106 
107         if (!field.startsWith("b=")) {
108             throw new SDPParseException("The string \"" + field + "\" isn't a bandwith field");
109         }
110 
111         Bandwith b = null;
112 
113         /* Create the matcher */
114         Matcher matcher = fieldPattern.matcher(field.substring(2));
115 
116         /* Test */
117         if (matcher.matches()) {
118             try {
119                 b = new Bandwith(matcher.group(1), Integer.parseInt(matcher.group(2)));
120             }
121             catch (SDPException parseException) {
122                 throw new SDPParseException("The string \"" + field + "\" isn't a valid bandwith field", parseException);
123             }
124         }
125         else {
126             throw new SDPParseException("The string \"" + field + "\" isn't a valid bandwith field");
127         }
128 
129         return b;
130     }
131 
132     /**
133      * Returns a clone of this field.
134      * 
135      * @return a clone of this field
136      */
137     public Object clone() {
138 
139         Bandwith field = new Bandwith();
140         field.modifier = new String(modifier);
141         field.value = this.value;
142 
143         return field;
144     }
145 
146     /**
147      * Returns the bandwith modifier.
148      * 
149      * @return The bandwith modifier.
150      *         <p>
151      *         The allowed modifiers are defined by <a
152      *         href="http://www.ietf.org/rfc/rfc2327.txt">RFC 2327</a> and <a
153      *         href="http://www.ietf.org/rfc/rfc3556.txt">RFC 3556</a>:
154      *         </p>
155      *         <ul>
156      *         <li>AS: Application Specific</li>
157      *         <li>CT: Conference Total</li>
158      *         <li>RS: RCTP bandwith for data senders</li>
159      *         <li>RR: RCTP bandwith for data receivers</li>
160      *         </ul>
161      */
162     public String getModifier() {
163 
164         return modifier;
165     }
166 
167     /**
168      * Returns the type character for the field.
169      * 
170      * @return the field type character: <b>b</b>
171      */
172     public char getType() {
173 
174         return Field.BANDWITH_FIELD;
175     }
176 
177     /**
178      * Returns the bandwith value.
179      * 
180      * @return the bandwith value in kbits/second
181      */
182     public int getValue() {
183 
184         return value;
185     }
186 
187     /**
188      * Sets the bandwith modifier.
189      * 
190      * @param modifier the modifier to set
191      * 
192      * @throws SDPException if the modifier is unknown
193      */
194     public void setModifier(final String modifier) throws SDPException {
195 
196         if (modifier.equals(AS) || modifier.equals(CT) || modifier.equals(RR) || modifier.equals(RS)) {
197             this.modifier = modifier;
198         }
199         else {
200             throw new SDPException("Unknown modifier: " + modifier);
201         }
202     }
203 
204     /**
205      * Sets the bandwith value.
206      * 
207      * @param value the value to set
208      * 
209      * @throws SDPException if value is negative
210      */
211     public void setValue(final int value) throws SDPException {
212 
213         if (value < 0) {
214             throw new SDPException("Invalid bandwith value: " + value);
215         }
216 
217         this.value = value;
218     }
219 
220     /**
221      * Returns a string representation of the field. The representation has the
222      * form: <b>b=<i>&lt;modifier&gt;</i>:<i>&lt;value&gt;</i></b>
223      * 
224      * @return the string representation of the field
225      */
226     public String toString() {
227 
228         return getType() + "=" + modifier + ":" + value;
229     }
230 }