001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.net.telnet;
019
020/***
021 * Implements the telnet window size option RFC 1073.
022 * @since 2.0
023 ***/
024public class WindowSizeOptionHandler extends TelnetOptionHandler
025{
026    /***
027     * Horizontal Size
028     ***/
029    private int m_nWidth = 80;
030
031    /***
032     * Vertical Size
033     ***/
034    private int m_nHeight = 24;
035
036    /***
037     * Window size option
038     ***/
039    protected static final int WINDOW_SIZE = 31;
040
041    /***
042     * Constructor for the WindowSizeOptionHandler. Allows defining desired
043     * initial setting for local/remote activation of this option and
044     * behavior in case a local/remote activation request for this
045     * option is received.
046     * <p>
047     * @param nWidth - Window width.
048     * @param nHeight - Window Height
049     * @param initlocal - if set to true, a WILL is sent upon connection.
050     * @param initremote - if set to true, a DO is sent upon connection.
051     * @param acceptlocal - if set to true, any DO request is accepted.
052     * @param acceptremote - if set to true, any WILL request is accepted.
053     ***/
054    public WindowSizeOptionHandler(
055        int nWidth,
056        int nHeight,
057        boolean initlocal,
058        boolean initremote,
059        boolean acceptlocal,
060        boolean acceptremote
061    ) {
062        super (
063            TelnetOption.WINDOW_SIZE,
064            initlocal,
065            initremote,
066            acceptlocal,
067            acceptremote
068        );
069
070        m_nWidth = nWidth;
071        m_nHeight = nHeight;
072    }
073
074    /***
075     * Constructor for the WindowSizeOptionHandler. Initial and accept
076     * behavior flags are set to false
077     * <p>
078     * @param nWidth - Window width.
079     * @param nHeight - Window Height
080     ***/
081    public WindowSizeOptionHandler(
082        int nWidth,
083        int nHeight
084    ) {
085        super (
086            TelnetOption.WINDOW_SIZE,
087            false,
088            false,
089            false,
090            false
091        );
092
093        m_nWidth = nWidth;
094        m_nHeight = nHeight;
095    }
096
097    /***
098     * Implements the abstract method of TelnetOptionHandler.
099     * This will send the client Height and Width to the server.
100     * <p>
101     * @return array to send to remote system
102     ***/
103    @Override
104    public int[] startSubnegotiationLocal()
105    {
106        int nCompoundWindowSize = m_nWidth * 0x10000 + m_nHeight;
107        int nResponseSize = 5;
108        int nIndex;
109        int nShift;
110        int nTurnedOnBits;
111
112        if ((m_nWidth % 0x100) == 0xFF) {
113            nResponseSize += 1;
114        }
115
116        if ((m_nWidth / 0x100) == 0xFF) {
117            nResponseSize += 1;
118        }
119
120        if ((m_nHeight % 0x100) == 0xFF) {
121            nResponseSize += 1;
122        }
123
124        if ((m_nHeight / 0x100) == 0xFF) {
125            nResponseSize += 1;
126        }
127
128        //
129        // allocate response array
130        //
131        int response[] = new int[nResponseSize];
132
133        //
134        // Build response array.
135        // ---------------------
136        // 1. put option name.
137        // 2. loop through Window size and fill the values,
138        // 3.    duplicate 'ff' if needed.
139        //
140
141        response[0] = WINDOW_SIZE;                          // 1 //
142
143        for (                                               // 2 //
144            nIndex=1, nShift = 24;
145            nIndex < nResponseSize;
146            nIndex++, nShift -=8
147        ) {
148            nTurnedOnBits = 0xFF;
149            nTurnedOnBits <<= nShift;
150            response[nIndex] = (nCompoundWindowSize & nTurnedOnBits) >>> nShift;
151
152            if (response[nIndex] == 0xff) {                 // 3 //
153                nIndex++;
154                response[nIndex] = 0xff;
155            }
156        }
157
158        return response;
159    }
160
161}