View Javadoc
1   package com.ericsson.research.transport.ws.spi;
2   
3   /*
4    * ##_BEGIN_LICENSE_##
5    * Transport Abstraction Package (trap)
6    * ----------
7    * Copyright (C) 2014 Ericsson AB
8    * ----------
9    * Redistribution and use in source and binary forms, with or without modification,
10   * are permitted provided that the following conditions are met:
11   * 
12   * 1. Redistributions of source code must retain the above copyright notice, this
13   *    list of conditions and the following disclaimer.
14   * 
15   * 2. Redistributions in binary form must reproduce the above copyright notice,
16   *    this list of conditions and the following disclaimer in the documentation
17   *    and/or other materials provided with the distribution.
18   * 
19   * 3. Neither the name of the Ericsson AB nor the names of its contributors
20   *    may be used to endorse or promote products derived from this software without
21   *    specific prior written permission.
22   * 
23   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26   * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32   * OF THE POSSIBILITY OF SUCH DAMAGE.
33   * ##_END_LICENSE_##
34   */
35  
36  import com.ericsson.research.transport.ws.WSException;
37  
38  public class WSHixieFrame extends WSAbstractFrame
39  {
40      
41      private static final byte[] CLOSE_PAYLOAD = new byte[] { (byte) 0xFF, 0 };
42      
43      protected WSHixieFrame()
44      {
45      }
46      
47      public WSHixieFrame(byte type, byte[] payload)
48      {
49          super(type);
50          switch (type)
51          {
52              case BINARY_FRAME:
53                  int j = 1;
54                  for (int i = 28; i >= 0; i = i - 7)
55                  {
56                      byte b = (byte) ((payload.length >>> i) & 0x7F);
57                      if (b > 0 || j > 1 || i == 0)
58                      {
59                          if (i > 0)
60                              b |= 0x80;
61                          if (j == 1)
62                              this.payload = new byte[payload.length + 2 + (i / 7)];
63                          this.payload[j++] = b;
64                      }
65                  }
66                  this.payload[0] = (byte) 0x80;
67                  System.arraycopy(payload, 0, this.payload, j, payload.length);
68                  break;
69              case TEXT_FRAME:
70                  this.payload = new byte[payload.length + 2];
71                  this.payload[0] = 0;
72                  System.arraycopy(payload, 0, this.payload, 1, payload.length);
73                  this.payload[payload.length + 1] = (byte) 0xFF;
74                  break;
75              case CLOSE_FRAME:
76                  this.payload = CLOSE_PAYLOAD;
77                  break;
78                  
79                  default:
80                      throw new IllegalStateException("Invalid payload type");
81          }
82      }
83      
84      public int deserialize(byte[] data, int length) throws WSException
85      {
86          if (this.l1 == -1)
87              throw new IllegalStateException("Already deserialized");
88          for (;;)
89          {
90              if (length <= this.pos)
91                  return 0;
92              switch (this.pos)
93              {
94                  case 0:
95                      if ((data[0] & 0x80) == 0)
96                          this.type = TEXT_FRAME;
97                      else if ((data[0] & 0x7F) == 0)
98                          this.type = BINARY_FRAME;
99                      else
100                         this.type = CLOSE_FRAME;
101                     this.pos++;
102                     break;
103                 case 1:
104                     if (this.type == CLOSE_FRAME)
105                     {
106                         this.l1 = -1;
107                         return 2;
108                     }
109                 default:
110                     switch (this.type)
111                     {
112                         case BINARY_FRAME:
113                             if (this.len == -1)
114                             {
115                                 if ((data[this.pos] & 0x80) == 0)
116                                 {
117                                     this.len = data[1] & 0x7F;
118                                     for (int i = 2; i <= this.pos; i++)
119                                         this.len = (this.len << 7) | (data[i] & 0x7F);
120                                     this.l1 = (byte) (this.pos + 1);
121                                     this.pos += this.len;
122                                     continue;
123                                 }
124                             }
125                             else
126                             {
127                                 this.payload = new byte[this.len];
128                                 if (this.len > 0)
129                                     System.arraycopy(data, this.l1, this.payload, 0, this.len);
130                                 this.l1 = -1;
131                                 return this.pos + 1;
132                             }
133                             break;
134                         case TEXT_FRAME:
135                             if (data[this.pos] == (byte) 0xFF)
136                             {
137                                 this.payload = new byte[this.pos - 1];
138                                 if (this.pos > 1)
139                                     System.arraycopy(data, 1, this.payload, 0, this.pos - 1);
140                                 this.l1 = -1;
141                                 return this.pos + 1;
142                             }
143                             break;
144                     }
145                     this.pos++;
146             }
147         }
148     }
149     
150 }