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 width = 80;
030
031    /**
032     * Vertical Size
033     */
034    private int height = 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        final int nWidth,
056        final int nHeight,
057        final boolean initlocal,
058        final boolean initremote,
059        final boolean acceptlocal,
060        final boolean acceptremote
061    ) {
062        super (
063            TelnetOption.WINDOW_SIZE,
064            initlocal,
065            initremote,
066            acceptlocal,
067            acceptremote
068        );
069
070        width = nWidth;
071        height = 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        final int nWidth,
083        final int nHeight
084    ) {
085        super (
086            TelnetOption.WINDOW_SIZE,
087            false,
088            false,
089            false,
090            false
091        );
092
093        width = nWidth;
094        height = 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        final int nCompoundWindowSize = width * 0x10000 + height;
107        int nResponseSize = 5;
108        int nIndex;
109        int nShift;
110        int nTurnedOnBits;
111
112        if (width % 0x100 == 0xFF) {
113            nResponseSize += 1;
114        }
115
116        if (width / 0x100 == 0xFF) {
117            nResponseSize += 1;
118        }
119
120        if (height % 0x100 == 0xFF) {
121            nResponseSize += 1;
122        }
123
124        if (height / 0x100 == 0xFF) {
125            nResponseSize += 1;
126        }
127
128        //
129        // allocate response array
130        //
131        final 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}