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 * @version $Id: WindowSizeOptionHandler.java 1697293 2015-08-24 01:01:00Z sebb $
023 * @since 2.0
024 ***/
025public class WindowSizeOptionHandler extends TelnetOptionHandler
026{
027    /***
028     * Horizontal Size
029     ***/
030    private int m_nWidth = 80;
031
032    /***
033     * Vertical Size
034     ***/
035    private int m_nHeight = 24;
036
037    /***
038     * Window size option
039     ***/
040    protected static final int WINDOW_SIZE = 31;
041
042    /***
043     * Constructor for the WindowSizeOptionHandler. Allows defining desired
044     * initial setting for local/remote activation of this option and
045     * behaviour in case a local/remote activation request for this
046     * option is received.
047     * <p>
048     * @param nWidth - Window width.
049     * @param nHeight - Window Height
050     * @param initlocal - if set to true, a WILL is sent upon connection.
051     * @param initremote - if set to true, a DO is sent upon connection.
052     * @param acceptlocal - if set to true, any DO request is accepted.
053     * @param acceptremote - if set to true, any WILL request is accepted.
054     ***/
055    public WindowSizeOptionHandler(
056        int nWidth,
057        int nHeight,
058        boolean initlocal,
059        boolean initremote,
060        boolean acceptlocal,
061        boolean acceptremote
062    ) {
063        super (
064            TelnetOption.WINDOW_SIZE,
065            initlocal,
066            initremote,
067            acceptlocal,
068            acceptremote
069        );
070
071        m_nWidth = nWidth;
072        m_nHeight = nHeight;
073    }
074
075    /***
076     * Constructor for the WindowSizeOptionHandler. Initial and accept
077     * behaviour flags are set to false
078     * <p>
079     * @param nWidth - Window width.
080     * @param nHeight - Window Height
081     ***/
082    public WindowSizeOptionHandler(
083        int nWidth,
084        int nHeight
085    ) {
086        super (
087            TelnetOption.WINDOW_SIZE,
088            false,
089            false,
090            false,
091            false
092        );
093
094        m_nWidth = nWidth;
095        m_nHeight = nHeight;
096    }
097
098    /***
099     * Implements the abstract method of TelnetOptionHandler.
100     * This will send the client Height and Width to the server.
101     * <p>
102     * @return array to send to remote system
103     ***/
104    @Override
105    public int[] startSubnegotiationLocal()
106    {
107        int nCompoundWindowSize = m_nWidth * 0x10000 + m_nHeight;
108        int nResponseSize = 5;
109        int nIndex;
110        int nShift;
111        int nTurnedOnBits;
112
113        if ((m_nWidth % 0x100) == 0xFF) {
114            nResponseSize += 1;
115        }
116
117        if ((m_nWidth / 0x100) == 0xFF) {
118            nResponseSize += 1;
119        }
120
121        if ((m_nHeight % 0x100) == 0xFF) {
122            nResponseSize += 1;
123        }
124
125        if ((m_nHeight / 0x100) == 0xFF) {
126            nResponseSize += 1;
127        }
128
129        //
130        // allocate response array
131        //
132        int response[] = new int[nResponseSize];
133
134        //
135        // Build response array.
136        // ---------------------
137        // 1. put option name.
138        // 2. loop through Window size and fill the values,
139        // 3.    duplicate 'ff' if needed.
140        //
141
142        response[0] = WINDOW_SIZE;                          // 1 //
143
144        for (                                               // 2 //
145            nIndex=1, nShift = 24;
146            nIndex < nResponseSize;
147            nIndex++, nShift -=8
148        ) {
149            nTurnedOnBits = 0xFF;
150            nTurnedOnBits <<= nShift;
151            response[nIndex] = (nCompoundWindowSize & nTurnedOnBits) >>> nShift;
152
153            if (response[nIndex] == 0xff) {                 // 3 //
154                nIndex++;
155                response[nIndex] = 0xff;
156            }
157        }
158
159        return response;
160    }
161
162}