You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by rw...@apache.org on 2004/09/27 13:21:21 UTC

cvs commit: jakarta-commons/net/src/java/org/apache/commons/net/ntp NTPUDPClient.java NtpUtils.java NtpV3Impl.java NtpV3Packet.java TimeInfo.java TimeStamp.java

rwinston    2004/09/27 04:21:21

  Modified:    net/src/java/org/apache/commons/net/ftp FTPClient.java
  Added:       net/src/java/org/apache/commons/net/ntp NTPUDPClient.java
                        NtpUtils.java NtpV3Impl.java NtpV3Packet.java
                        TimeInfo.java TimeStamp.java
  Log:
  PR:31435
  Inital commit of SNTP/NTP codebase into Commons-Net
  
  Revision  Changes    Path
  1.42      +29 -11    jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPClient.java
  
  Index: FTPClient.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPClient.java,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- FTPClient.java	24 Sep 2004 12:07:07 -0000	1.41
  +++ FTPClient.java	27 Sep 2004 11:21:21 -0000	1.42
  @@ -258,6 +258,7 @@
       private boolean __remoteVerificationEnabled;
       private long __restartOffset;
       private FTPFileEntryParserFactory __parserFactory;
  +    private int __bufferSize;
   
       // __systemName is a cached value that should not be referenced directly
       // except when assigned in getSystemName and __initDefaults.
  @@ -297,6 +298,7 @@
           __restartOffset      = 0;
           __systemName         = null;
           __entryParser        = null;
  +        __bufferSize 		 = Util.DEFAULT_COPY_BUFFER_SIZE;
       }
   
       private String __parsePathname(String reply)
  @@ -367,16 +369,15 @@
           if ((socket = _openDataConnection_(command, remote)) == null)
               return false;
   
  -        // TODO: Buffer size may have to be adjustable in future to tune
  -        // performance.
           output = new BufferedOutputStream(socket.getOutputStream(),
  -                                          Util.DEFAULT_COPY_BUFFER_SIZE);
  +                                          getBufferSize()
  +                                          );
           if (__fileType == ASCII_FILE_TYPE)
               output = new ToNetASCIIOutputStream(output);
           // Treat everything else as binary for now
           try
           {
  -            Util.copyStream(local, output, Util.DEFAULT_COPY_BUFFER_SIZE,
  +            Util.copyStream(local, output, getBufferSize(),
                               CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
                               false);
           }
  @@ -414,7 +415,7 @@
             // own if they want to wrap the SocketOutputStream we return
             // for file types other than ASCII.
             output = new BufferedOutputStream(output,
  -                                            Util.DEFAULT_COPY_BUFFER_SIZE);
  +                                            getBufferSize());
             output = new ToNetASCIIOutputStream(output);
   
           }
  @@ -1265,16 +1266,14 @@
           if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
               return false;
   
  -        // TODO: Buffer size may have to be adjustable in future to tune
  -        // performance.
           input = new BufferedInputStream(socket.getInputStream(),
  -                                        Util.DEFAULT_COPY_BUFFER_SIZE);
  +                                        getBufferSize());
           if (__fileType == ASCII_FILE_TYPE)
             input = new FromNetASCIIInputStream(input);
           // Treat everything else as binary for now
           try
           {
  -            Util.copyStream(input, local, Util.DEFAULT_COPY_BUFFER_SIZE,
  +            Util.copyStream(input, local, getBufferSize(),
                               CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
                               false);
           }
  @@ -1334,7 +1333,7 @@
             // own if they want to wrap the SocketInputStream we return
             // for file types other than ASCII.
             input = new BufferedInputStream(input,
  -                                          Util.DEFAULT_COPY_BUFFER_SIZE);
  +                                          getBufferSize());
             input = new FromNetASCIIInputStream(input);
           }
           return new org.apache.commons.net.io.SocketInputStream(socket, input);
  @@ -2599,7 +2598,26 @@
   
           completePendingCommand();
           return list;
  -    }}
  +    }
  +    
  +    /**
  +     * Set the internal buffer size.
  +     *  
  +     * @param bufSize The size of the buffer
  +     */
  +    public void setBufferSize(int bufSize) {
  +    	__bufferSize = bufSize;
  +    }
  +    
  +    /**
  +     * Retrieve the current internal buffer size.
  +     * @return The current buffer size.
  +     */
  +    public int getBufferSize() {
  +    	return __bufferSize;
  +    }
  +    
  +}
   
   /* Emacs configuration
    * Local variables:        **
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ntp/NTPUDPClient.java
  
  Index: NTPUDPClient.java
  ===================================================================
  package org.apache.commons.net.ntp;
  /*
   * Copyright 2001-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  import java.io.IOException;
  import java.net.DatagramPacket;
  import java.net.InetAddress;
  import org.apache.commons.net.DatagramSocketClient;
  
  /***
   * The NTPUDPClient class is a UDP implementation of a client for the
   * Network Time Protocol (NTP) described in RFC 1305 as well as the
   * Simple Network Time Protocol (SNTP) in RFC-2030. To use the class,
   * merely open a local datagram socket with <a href="#open"> open </a>
   * and call <a href="#getTime"> getTime </a> to retrieve the time. Then call
   * <a href="org.apache.commons.net.DatagramSocketClient.html#close"> close </a>
   * to close the connection properly.
   * Successive calls to <a href="#getTime"> getTime </a> are permitted
   * without re-establishing a connection.  That is because UDP is a
   * connectionless protocol and the Network Time Protocol is stateless.
   *
   * @author Jason Mathews, MITRE Corp
   * @version $Revision: 1.1 $ $Date: 2004/09/27 11:21:21 $
   ***/
  
  public final class NTPUDPClient extends DatagramSocketClient
  {
      /*** The default NTP port.  It is set to 123 according to RFC 1305. ***/
      public static final int DEFAULT_PORT = 123;
  
      private int _version = NtpV3Packet.VERSION_3;
  
      /***
       * Retrieves the time information from the specified server and port and
       * returns it. The time is the number of miliiseconds since
       * 00:00 (midnight) 1 January 1900 UTC, as specified by RFC 1305.
       * This method reads the raw NTP packet and constructs a <i>TimeInfo</i>
       * object that allows access to all the fields of the NTP message header.
       * <p>
       * @param host The address of the server.
       * @param port The port of the service.
       * @return The time value retrieved from the server.
       * @exception IOException If an error occurs while retrieving the time.
       ***/
      public TimeInfo getTime(InetAddress host, int port) throws IOException
      {
          // if not connected then open to next available UDP port
          if (!isOpen())
          {
              open();
          }
  
          NtpV3Packet message = new NtpV3Impl();
          message.setMode(NtpV3Packet.MODE_CLIENT);
          message.setVersion(_version);
          DatagramPacket sendPacket = message.getDatagramPacket();
          sendPacket.setAddress(host);
  
          NtpV3Packet recMessage = new NtpV3Impl();
          DatagramPacket receivePacket = recMessage.getDatagramPacket();
  
          /*
           * Must minimize the time between getting the current time,
           * timestamping the packet, and sending it out which
           * introduces an error in the delay time.
           * No extraneous logging and initializations here !!!
           */
          TimeStamp now = TimeStamp.getCurrentTime();
  
          // Note that if you do not set the transmit time field then originating time
          // in server response is all 0's which is "Thu Feb 07 01:28:16 EST 2036".
          message.setTransmitTime(now);
  
          _socket_.send(sendPacket);
          _socket_.receive(receivePacket);
  
          long returnTime = System.currentTimeMillis();
          // create TimeInfo message container but don't pre-compute the details yet
          TimeInfo info = new TimeInfo(recMessage, returnTime, false);
  
          return info;
      }
  
      /***
       * Retrieves the time information from the specified server on the
       * default NTP port and returns it. The time is the number of miliiseconds
       * since 00:00 (midnight) 1 January 1900 UTC, as specified by RFC 1305.
       * This method reads the raw NTP packet and constructs a <i>TimeInfo</i>
       * object that allows access to all the fields of the NTP message header.
       * <p>
       * @param host The address of the server.
       * @return The time value retrieved from the server.
       * @exception IOException If an error occurs while retrieving the time.
       ***/
      public TimeInfo getTime(InetAddress host) throws IOException
      {
          return getTime(host, NtpV3Packet.NTP_PORT);
      }
  
      /***
       * Returns the NTP protocol version number that client sets on request packet
       * that is sent to remote host (e.g. 3=NTP v3, 4=NTP v4, etc.)
       *
       * @return  the NTP protocol version number that client sets on request packet.
       * @see #setVersion(int)
       ***/
      public int getVersion()
      {
          return _version;
      }
  
      /***
       * Sets the NTP protocol version number that client sets on request packet
       * communicate with remote host.
       *
       * @param version the NTP protocol version number
       ***/
      public void setVersion(int version)
      {
          _version = version;
      }
  
  }
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ntp/NtpUtils.java
  
  Index: NtpUtils.java
  ===================================================================
  package org.apache.commons.net.ntp;
  /*
   * Copyright 2001-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  /***
   * Common NtpUtils Helper class.
   *
   * @author Jason Mathews, MITRE Corp
   *
   * @version $Revision: 1.1 $ $Date: 2004/09/27 11:21:21 $
   */
  public final class NtpUtils {
  
      /***
        * Returns 32-bit integer address to IPv4 address string "%d.%d.%d.%d" format.
        *
        * @param address  the 32-bit address
        * @return  the raw IP address in a string format.
        */
       public static String getHostAddress(int address)
       {
            return ((address >>> 24) & 0xFF) + "." +
                   ((address >>> 16) & 0xFF) + "." +
                   ((address >>>  8) & 0xFF) + "." +
                   ((address >>>  0) & 0xFF);
       }
  
      /***
       * Returns NTP packet reference identifier as IP address.
       *
       * @param packet  NTP packet
       * @return  the packet reference id (as IP address) in "%d.%d.%d.%d" format.
       */
       public static String getRefAddress(NtpV3Packet packet)
       {
           int address = (packet == null) ? 0 : packet.getReferenceId();
           return getHostAddress(address);
       }
  
      /***
       * Get refId as reference clock string (e.g. GPS, WWV, LCL). If string is
       * invalid (non-ASCII character) then returns empty string "".
       * For details refer to the <A HREF="http://www.eecis.udel.edu/~mills/ntp/html/refclock.html#list">Comprehensive
       * List of Clock Drivers</A>.
       *
       * @param message
       * @return reference clock string if primary NTP server
       */
      public static String getReferenceClock(NtpV3Packet message) {
          if (message == null)
              return "";
          int refId = message.getReferenceId();
          if (refId == 0)
              return "";
          StringBuffer buf = new StringBuffer(4);
          // start at highest-order byte (0x4c434c00 -> LCL)
          for (int shiftBits = 24; shiftBits >= 0; shiftBits -= 8)
          {
              char c = (char) ((refId >>> shiftBits) & 0xff);
              if (c == 0) break; // 0-terminated ASCII string
              if (!Character.isLetterOrDigit(c))
                  return "";
              buf.append(c);
          }
          return buf.toString();
      }
  
      /***
       * Return human-readable name of message mode type (RFC 1305).
       *
       * @param mode
       * @return mode name
       */
      public static String getModeName(int mode)
      {
          switch (mode) {
              case NtpV3Packet.MODE_RESERVED:
                  return "Reserved";
              case NtpV3Packet.MODE_SYMMETRIC_ACTIVE:
                  return "Symmetric Active";
              case NtpV3Packet.MODE_SYMMETRIC_PASSIVE:
                  return "Symmetric Passive";
              case NtpV3Packet.MODE_CLIENT:
                  return "Client";
              case NtpV3Packet.MODE_SERVER:
                  return "Server";
              case NtpV3Packet.MODE_BROADCAST:
                  return "Broadcast";
              case NtpV3Packet.MODE_CONTROL_MESSAGE:
                  return "Control";
              case NtpV3Packet.MODE_PRIVATE:
                  return "Private";
              default:
                  return "Unknown";
          }
      }
  
  }
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ntp/NtpV3Impl.java
  
  Index: NtpV3Impl.java
  ===================================================================
  package org.apache.commons.net.ntp;
  /*
   * Copyright 2001-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  import java.net.DatagramPacket;
  
  /***
   * Implementation of NtpV3Packet with methods converting Java objects to/from
   * the Network Time Protocol (NTP) data message header format described in RFC-1305.
   *
   * @author Naz Irizarry, MITRE Corp
   * @author Jason Mathews, MITRE Corp
   *
   * @version $Revision: 1.1 $ $Date: 2004/09/27 11:21:21 $
   */
  public class NtpV3Impl implements NtpV3Packet
  {
  
      private static final int MODE_INDEX = 0;
      private static final int MODE_SHIFT = 0;
  
      private static final int VERSION_INDEX = 0;
      private static final int VERSION_SHIFT = 3;
  
      private static final int LI_INDEX = 0;
      private static final int LI_SHIFT = 6;
  
      private static final int STRATUM_INDEX = 1;
      private static final int POLL_INDEX = 2;
      private static final int PRECISION_INDEX = 3;
  
      private static final int ROOT_DELAY_INDEX = 4;
      private static final int ROOT_DISPERSION_INDEX = 8;
      private static final int REFERENCE_ID_INDEX = 12;
  
      private static final int REFERENCE_TIMESTAMP_INDEX = 16;
      private static final int ORIGINATE_TIMESTAMP_INDEX = 24;
      private static final int RECEIVE_TIMESTAMP_INDEX = 32;
      private static final int TRANSMIT_TIMESTAMP_INDEX = 40;
  
      private static final int KEY_IDENTIFIER_INDEX = 48;
      private static final int MESSAGE_DIGEST = 54; /* len 16 bytes */
  
      private byte[] buf = new byte[48];
  
      private DatagramPacket dp;
  
      /** Creates a new instance of NtpV3Impl */
      public NtpV3Impl()
      {
      }
  
      /***
       * Returns mode as defined in RFC-1305 which is a 3-bit integer
       * whose value is indicated by the MODE_xxx parameters.
       *
       * @return mode as defined in RFC-1305.
       */
      public int getMode()
      {
          return (ui(buf[MODE_INDEX]) >> MODE_SHIFT) & 0x7;
      }
  
      /***
       * Return human-readable name of message mode type as described in
       * RFC 1305.
       * @return mode name as string.
       */
      public String getModeName()
      {
          return NtpUtils.getModeName(getMode());
      }
  
      /***
       * Set mode as defined in RFC-1305.
       * @param mode
       */
      public void setMode(int mode)
      {
          buf[MODE_INDEX] = (byte) (buf[MODE_INDEX] & 0xF8 | mode & 0x7);
      }
  
      /***
       * Returns leap indicator as defined in RFC-1305 which is a two-bit code:
       *	0=no warning
       *	1=last minute has 61 seconds
       *	2=last minute has 59 seconds
       *	3=alarm condition (clock not synchronized)
       *
       * @return leap indicator as defined in RFC-1305.
       */
      public int getLeapIndicator()
      {
          return (ui(buf[LI_INDEX]) >> LI_SHIFT) & 0x3;
      }
  
      /***
       * Set leap indicator as defined in RFC-1305.
       * @param li leap indicator.
       */
      public void setLeapIndicator(int li)
      {
          buf[LI_INDEX] = (byte) (buf[LI_INDEX] & 0x3F | ((li & 0x3) << LI_SHIFT));
      }
  
      /***
       * Returns poll interval as defined in RFC-1305, which is an eight-bit
       * signed integer indicating the maximum interval between successive
       * messages, in seconds to the nearest power of two (e.g. value of six
       * indicates an interval of 64 seconds. The values that can appear in
       * this field range from NTP_MINPOLL to NTP_MAXPOLL inclusive.
       *
       * @return poll interval as defined in RFC-1305.
       */
      public int getPoll()
      {
          return (int) (buf[POLL_INDEX]);
      }
  
      /***
       * Set poll interval as defined in RFC-1305.
       *
       * @param poll poll interval.
       */
      public void setPoll(int poll)
      {
          buf[POLL_INDEX] = (byte) (poll & 0xFF);
      }
  
      /***
       * Returns precision as defined in RFC-1305 encoded as an 8-bit signed
       * integer (seconds to nearest power of two).
       * Values normally range from -6 to -20.
       *
       * @return precision as defined in RFC-1305.
       */
      public int getPrecision()
      {
          return (int) buf[PRECISION_INDEX];
      }
  
      /***
       * Set precision as defined in RFC-1305.
       * @param precision
       */
      public void setPrecision(int precision)
      {
          buf[PRECISION_INDEX] = (byte) (precision & 0xFF);
      }
  
      /***
       * Returns NTP version number as defined in RFC-1305.
       *
       * @return NTP version number.
       */
      public int getVersion()
      {
          return (ui(buf[VERSION_INDEX]) >> VERSION_SHIFT) & 0x7;
      }
  
      /***
       * Set NTP version as defined in RFC-1305.
       *
       * @param version NTP version.
       */
      public void setVersion(int version)
      {
          buf[VERSION_INDEX] = (byte) (buf[VERSION_INDEX] & 0xC7 | ((version & 0x7) << VERSION_SHIFT));
      }
  
      /***
       * Returns Stratum as defined in RFC-1305, which indicates the stratum level
       * of the local clock, with values defined as follows: 0=unspecified,
       * 1=primary ref clock, and all others a secondary reference (via NTP).
       *
       * @return Stratum level as defined in RFC-1305.
       */
      public int getStratum()
      {
          return ui(buf[STRATUM_INDEX]);
      }
  
      /***
       * Set stratum level as defined in RFC-1305.
       *
       * @param stratum stratum level.
       */
      public void setStratum(int stratum)
      {
          buf[STRATUM_INDEX] = (byte) (stratum & 0xFF);
      }
  
      /***
       * Return root delay as defined in RFC-1305, which is the total roundtrip delay
       * to the primary reference source, in seconds. Values can take positive and
       * negative values, depending on clock precision and skew.
       *
       * @return root delay as defined in RFC-1305.
       */
      public int getRootDelay()
      {
          return getInt(ROOT_DELAY_INDEX);
      }
  
      /***
       * Return root delay as defined in RFC-1305 in milliseconds, which is
       * the total roundtrip delay to the primary reference source, in
       * seconds. Values can take positive and negative values, depending
       * on clock precision and skew.
       *
       * @return root delay in milliseconds
       */
      public double getRootDelayInMillisDouble()
      {
          double l = getRootDelay();
          return l / 65.536;
      }
  
      /***
       * Returns root dispersion as defined in RFC-1305.
       * @return root dispersion.
       */
      public int getRootDispersion()
      {
          return getInt(ROOT_DISPERSION_INDEX);
      }
  
      /***
       * Returns root dispersion (as defined in RFC-1305) in milliseconds.
       *
       * @return root dispersion in milliseconds
       */
      public long getRootDispersionInMillis()
      {
          long l = getRootDispersion();
          return (l * 1000) / 65536L;
      }
  
      /***
       * Returns root dispersion (as defined in RFC-1305) in milliseconds
       * as double precision value.
       *
       * @return root dispersion in milliseconds
       */
      public double getRootDispersionInMillisDouble()
      {
          double l = getRootDispersion();
          return l / 65.536;
      }
  
      /***
       * Set reference clock identifier field with 32-bit unsigned integer value.
       * See RFC-1305 for description.
       *
       * @param refId reference clock identifier.
       */
      public void setReferenceId(int refId)
      {
          for (int i = 3; i >= 0; i--) {
              buf[REFERENCE_ID_INDEX + i] = (byte) (refId & 0xff);
              refId >>>= 8; // shift right one-byte
          }
      }
  
      /***
       * Returns the reference id as defined in RFC-1305, which is
       * a 32-bit integer whose value is dependent on several criteria.
       *
       * @return the reference id as defined in RFC-1305.
       */
      public int getReferenceId()
      {
          return getInt(REFERENCE_ID_INDEX);
      }
  
      /***
       * Returns the reference id string. String cannot be null but
       * value is dependent on the version of the NTP spec supported
       * and stratum level. Value can be an empty string, clock type string,
       * IP address, or a hex string.
       *
       * @return the reference id string.
       */
      public String getReferenceIdString()
      {
          int version = getVersion();
          int stratum = getStratum();
          if (version == VERSION_3 || version == VERSION_4) {
              if (stratum == 0 || stratum == 1) {
                  return idAsString(); // 4-character ASCII string (e.g. GPS, USNO)
              }
              // in NTPv4 servers this is latest transmit timestamp of ref source
              if (version == VERSION_4)
                  return idAsHex();
          }
  
          // Stratum 2 and higher this is a four-octet IPv4 address
          // of the primary reference host.
          if (stratum >= 2) {
              return idAsIPAddress();
          }
          return idAsHex();
      }
  
      /***
       * Returns Reference id as dotted IP address.
       * @return refId as IP address string.
       */
      private String idAsIPAddress()
      {
          return ui(buf[REFERENCE_ID_INDEX]) + "." +
                  ui(buf[REFERENCE_ID_INDEX + 1]) + "." +
                  ui(buf[REFERENCE_ID_INDEX + 2]) + "." +
                  ui(buf[REFERENCE_ID_INDEX + 3]);
      }
  
      private String idAsString()
      {
          String id = "";
          for (int i = 0; i <= 3; i++) {
              char c = (char) buf[REFERENCE_ID_INDEX + i];
              if (c == 0) break; // 0-terminated string
              id = id + c;
          }
          return id;
      }
  
      private String idAsHex()
      {
          return Integer.toHexString(getReferenceId());
      }
  
      /***
       * Returns the transmit timestamp as defined in RFC-1305.
       *
       * @return the transmit timestamp as defined in RFC-1305.
       * Never returns a null object.
       */
      public TimeStamp getTransmitTimeStamp()
      {
          return getTimestamp(TRANSMIT_TIMESTAMP_INDEX);
      }
  
      /***
       * Set transmit time with NTP timestamp.
       * If <code>ts</code> is null then zero time is used.
       *
       * @param ts NTP timestamp
       */
      public void setTransmitTime(TimeStamp ts)
      {
          setTimestamp(TRANSMIT_TIMESTAMP_INDEX, ts);
      }
  
      /***
       * Set originate timestamp given NTP TimeStamp object.
       * If <code>ts</code> is null then zero time is used.
       *
       * @param ts NTP timestamp
       */
      public void setOriginateTimeStamp(TimeStamp ts)
      {
          setTimestamp(ORIGINATE_TIMESTAMP_INDEX, ts);
      }
  
      /***
       * Returns the originate time as defined in RFC-1305.
       *
       * @return the originate time.
       * Never returns null.
       */
      public TimeStamp getOriginateTimeStamp()
      {
          return getTimestamp(ORIGINATE_TIMESTAMP_INDEX);
      }
  
      /***
       * Returns the reference time as defined in RFC-1305.
       *
       * @return the reference time as <code>TimeStamp</code> object.
       * Never returns null.
       */
      public TimeStamp getReferenceTimeStamp()
      {
          return getTimestamp(REFERENCE_TIMESTAMP_INDEX);
      }
  
      /***
       * Set Reference time with NTP timestamp. If <code>ts</code> is null
       * then zero time is used.
       *
       * @param ts NTP timestamp
       */
      public void setReferenceTime(TimeStamp ts)
      {
          setTimestamp(REFERENCE_TIMESTAMP_INDEX, ts);
      }
  
      /***
       * Returns receive timestamp as defined in RFC-1305.
       *
       * @return the receive time.
       * Never returns null.
       */
      public TimeStamp getReceiveTimeStamp()
      {
          return getTimestamp(RECEIVE_TIMESTAMP_INDEX);
      }
  
      /***
       * Set receive timestamp given NTP TimeStamp object.
       * If <code>ts</code> is null then zero time is used.
       *
       * @param ts timestamp
       */
      public void setReceiveTimeStamp(TimeStamp ts)
      {
          setTimestamp(RECEIVE_TIMESTAMP_INDEX, ts);
      }
  
      /***
       * Return type of time packet. The values (e.g. NTP, TIME, ICMP, ...)
       * correspond to the protocol used to obtain the timing information.
       *
       * @return packet type string identifier which in this case is "NTP".
       */
      public String getType()
      {
          return "NTP";
      }
  
      /***
       * @return 4 bytes as 32-bit int
       */
      private int getInt(int index)
      {
          int i = ui(buf[index]) << 24 |
                  ui(buf[index + 1]) << 16 |
                  ui(buf[index + 2]) << 8 |
                  ui(buf[index + 3]);
  
          return i;
      }
  
      /***
       * Get NTP Timestamp at specified starting index.
       *
       * @param index index into data array
       * @return TimeStamp object for 64 bits starting at index
       */
      private TimeStamp getTimestamp(int index)
      {
          return new TimeStamp(getLong(index));
      }
  
      /***
       * Get Long value represented by bits starting at specified index.
       *
       * @return 8 bytes as 64-bit long
       */
      private long getLong(int index)
      {
          long i = ul(buf[index]) << 56 |
                  ul(buf[index + 1]) << 48 |
                  ul(buf[index + 2]) << 40 |
                  ul(buf[index + 3]) << 32 |
                  ul(buf[index + 4]) << 24 |
                  ul(buf[index + 5]) << 16 |
                  ul(buf[index + 6]) << 8 |
                  ul(buf[index + 7]);
          return i;
      }
  
      /***
       * Sets the NTP timestamp at the given array index.
       *
       * @param index index into the byte array.
       * @param t TimeStamp.
       */
      private void setTimestamp(int index, TimeStamp t)
      {
          long ntpTime = (t == null) ? 0 : t.ntpValue();
          // copy 64-bits from Long value into 8 x 8-bit bytes of array
          // one byte at a time shifting 8-bits for each position.
          for (int i = 7; i >= 0; i--) {
              buf[index + i] = (byte) (ntpTime & 0xFF);
              ntpTime >>>= 8; // shift to next byte
          }
          // buf[index] |= 0x80;  // only set if 1900 baseline....
      }
  
      /***
       * Returns the datagram packet with the NTP details already filled in.
       *
       * @return a datagram packet.
       */
      public DatagramPacket getDatagramPacket()
      {
          if (dp == null)
              synchronized(this) {
                  if (dp == null) {
                      dp = new DatagramPacket(buf, buf.length);
                      dp.setPort(NTP_PORT);
                  }
              }
          return dp;
      }
  
      /***
       * Set the contents of this object from source datagram packet.
       *
       * @param srcDp source DatagramPacket to copy contents from.
       */
      public void setDatagramPacket(DatagramPacket srcDp)
      {
          byte[] incomingBuf = srcDp.getData();
          int len = srcDp.getLength();
          if (len > buf.length)
              len = buf.length;
  
          System.arraycopy(incomingBuf, 0, buf, 0, len);
      }
  
      /***
       * Convert byte to unsigned integer.
       * Java only has signed types so we have to do
       * more work to get unsigned ops.
       *
       * @param b
       * @return unsigned int value of byte
       */
      protected final static int ui(byte b)
      {
          int i = b & 0xFF;
          return i;
      }
  
      /***
       * Convert byte to unsigned long.
       * Java only has signed types so we have to do
       * more work to get unsigned ops
       *
       * @param b
       * @return unsigned long value of byte
       */
      protected final static long ul(byte b)
      {
          long i = b & 0xFF;
          return i;
      }
  
      /***
       * Returns details of NTP packet as a string.
       *
       * @return details of NTP packet as a string.
       */
      public String toString()
      {
          return "[" +
                  "version:" + getVersion() +
                  ", mode:" + getMode() +
                  ", poll:" + getPoll() +
                  ", precision:" + getPrecision() +
                  ", delay:" + getRootDelay() +
                  ", dispersion(ms):" + getRootDispersionInMillisDouble() +
                  ", id:" + getReferenceIdString() +
                  ", xmitTime:" + getTransmitTimeStamp().toDateString() +
                  " ]";
      }
  
  }
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ntp/NtpV3Packet.java
  
  Index: NtpV3Packet.java
  ===================================================================
  package org.apache.commons.net.ntp;
  /*
   * Copyright 2001-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  import java.net.DatagramPacket;
  
  /**
   * Interface for a NtpV3Packet with get/set methods corresponding to the fields
   * in the NTP Data Message Header described in RFC 1305.
   *
   * @author Naz Irizarry, MITRE Corp
   * @author Jason Mathews, MITRE Corp
   * @version $Revision: 1.1 $ $Date: 2004/09/27 11:21:21 $
   */
  public interface NtpV3Packet
  {
  
      /**
       * Standard NTP UDP port
       */
      public static final int NTP_PORT = 123;
  
      public static final int LI_NO_WARNING = 0;
      public static final int LI_LAST_MINUTE_HAS_61_SECONDS = 1;
      public static final int LI_LAST_MINUTE_HAS_59_SECONDS = 2;
      public static final int LI_ALARM_CONDITION = 3;
  
      /* mode options */
      public static final int MODE_RESERVED = 0;
      public static final int MODE_SYMMETRIC_ACTIVE = 1;
      public static final int MODE_SYMMETRIC_PASSIVE = 2;
      public static final int MODE_CLIENT = 3;
      public static final int MODE_SERVER = 4;
      public static final int MODE_BROADCAST = 5;
      public static final int MODE_CONTROL_MESSAGE = 6;
      public static final int MODE_PRIVATE = 7;
  
      public static final int NTP_MINPOLL = 4;  // 16 seconds
      public static final int NTP_MAXPOLL = 14; // 16284 seconds
  
      public static final int NTP_MINCLOCK = 1;
      public static final int NTP_MAXCLOCK = 10;
  
      public static final int VERSION_3 = 3;
      public static final int VERSION_4 = 4;
  
      /* possible getType values such that other time-related protocols can
       * have its information represented as NTP packets
       */
      public static final String TYPE_NTP = "NTP";         // RFC-1305/2030
      public static final String TYPE_ICMP = "ICMP";       // RFC-792
      public static final String TYPE_TIME = "TIME";       // RFC-868
      public static final String TYPE_DAYTIME = "DAYTIME"; // RFC-867
  
      /**
       * @return a datagram packet with the NTP parts already filled in
       */
      public DatagramPacket getDatagramPacket();
  
      /**
       * Set the contents of this object from the datagram packet
       */
      public void setDatagramPacket(DatagramPacket dp);
  
      /**
       * @return leap indicator as defined in RFC-1305
       */
      public int getLeapIndicator();
  
      /**
       * Set leap indicator.
       * @param li - leap indicator code
       */
      public void setLeapIndicator(int li);
  
      /**
       * @return mode as defined in RFC-1305
       */
      public int getMode();
  
      /**
       * @return mode as human readable string; e.g. 3=Client
       */
      public String getModeName();
  
      /**
       * Set mode as defined in RFC-1305
       */
      public void setMode(int mode);
  
      /**
       * @return poll interval as defined in RFC-1305.
       * Field range between NTP_MINPOLL and NTP_MAXPOLL.
       */
      public int getPoll();
  
      /**
       * Set poll interval as defined in RFC-1305.
       * Field range between NTP_MINPOLL and NTP_MAXPOLL.
       */
      public void setPoll(int poll);
  
      /**
       * @return precision as defined in RFC-1305
       */
      public int getPrecision();
  
      /**
       * @return root delay as defined in RFC-1305
       */
      public int getRootDelay();
  
      /**
       * @return root delay in milliseconds
       */
      public double getRootDelayInMillisDouble();
  
      /**
       * @return root dispersion as defined in RFC-1305
       */
      public int getRootDispersion();
  
      /**
       * @return root dispersion in milliseconds
       */
      public long getRootDispersionInMillis();
  
      /**
       * @return root dispersion in milliseconds
       */
      public double getRootDispersionInMillisDouble();
  
      /**
       * @return version as defined in RFC-1305
       */
      public int getVersion();
  
      /**
       * Set version as defined in RFC-1305
       */
      public void setVersion(int mode);
  
      /**
       * @return stratum as defined in RFC-1305
       */
      public int getStratum();
  
      /**
       * Set stratum as defined in RFC-1305
       */
      public void setStratum(int stratum);
  
      /**
       * @return the reference id string
       */
      public String getReferenceIdString();
  
      /**
       * @return the reference id (32-bit code) as defined in RFC-1305
       */
      public int getReferenceId();
  
      /**
       * Set reference clock identifier field.
       * @param refId
       */
      public void setReferenceId(int refId);
  
      /**
       * @return the transmit timestamp as defined in RFC-1305
       */
      public TimeStamp getTransmitTimeStamp();
  
      /**
       * @return the reference time as defined in RFC-1305
       */
      public TimeStamp getReferenceTimeStamp();
  
      /**
       * @return the originate time as defined in RFC-1305
       */
      public TimeStamp getOriginateTimeStamp();
  
      /**
       * @return the receive time as defined in RFC-1305
       */
      public TimeStamp getReceiveTimeStamp();
  
      /**
       * Set the transmit timestamp given NTP TimeStamp object.
       * @param ts - timestamp
       */
      public void setTransmitTime(TimeStamp ts);
  
      /**
       * Set the reference timestamp given NTP TimeStamp object.
       * @param ts - timestamp
       */
      public void setReferenceTime(TimeStamp ts);
  
      /**
       * Set originate timestamp given NTP TimeStamp object.
       * @param ts - timestamp
       */
      public void setOriginateTimeStamp(TimeStamp ts);
  
      /**
       * Set receive timestamp given NTP TimeStamp object.
       * @param ts - timestamp
       */
      public void setReceiveTimeStamp(TimeStamp ts);
  
      /**
       * Return type of time packet. The values (e.g. NTP, TIME, ICMP, ...)
       * correspond to the protocol used to obtain the timing information.
       *
       * @return packet type string identifier
       */
      public String getType();
  
  }
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ntp/TimeInfo.java
  
  Index: TimeInfo.java
  ===================================================================
  package org.apache.commons.net.ntp;
  /*
   * Copyright 2001-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  import java.util.List;
  import java.util.ArrayList;
  
  /**
   * Wrapper class to network time packet messages (NTP, etc) that computes
   * related timing info and stats.
   *
   * @author Jason Mathews, MITRE Corp
   *
   * @version $Revision: 1.1 $ $Date: 2004/09/27 11:21:21 $
   */
  public class TimeInfo {
  
      private NtpV3Packet _message;
      private List _comments;
      private Long _delay;
      private Long _offset;
  
      /**
       * time at which time message packet was received by local machine
       */
      private long _returnTime;
  
      /**
       * flag indicating that the TimeInfo details was processed and delay/offset were computed
       */
      private boolean _detailsComputed;
  
      /**
       * Create TimeInfo object with raw packet message and destination time received.
       *
       * @param message NTP message packet
       * @param returnTime  destination receive time
       * @throws IllegalArgumentException if message is null
       */
      public TimeInfo(NtpV3Packet message, long returnTime) {
          this(message, returnTime, null, true);
      }
  
      /**
       * Create TimeInfo object with raw packet message and destination time received.
       *
       * @param message NTP message packet
       * @param returnTime  destination receive time
       * @param comments List of errors/warnings identified during processing
       * @throws IllegalArgumentException if message is null
       */
      public TimeInfo(NtpV3Packet message, long returnTime, List comments)
      {
              this(message, returnTime, comments, true);
      }
  
      /**
       * Create TimeInfo object with raw packet message and destination time received.
       * Auto-computes details if computeDetails flag set otherwise this is delayed
       * until computeDetails() is called. Delayed computation is for fast
       * intialization when sub-millisecond timing is needed.
       *
       * @param msgPacket NTP message packet
       * @param returnTime  destination receive time
       * @param doComputeDetails  flag to pre-compute delay/offset values
       * @throws IllegalArgumentException if message is null
       */
      public TimeInfo(NtpV3Packet msgPacket, long returnTime, boolean doComputeDetails)
      {
              this(msgPacket, returnTime, null, doComputeDetails);
      }
  
      /**
       * Create TimeInfo object with raw packet message and destination time received.
       * Auto-computes details if computeDetails flag set otherwise this is delayed
       * until computeDetails() is called. Delayed computation is for fast
       * intialization when sub-millisecond timing is needed.
       *
       * @param message NTP message packet
       * @param returnTime  destination receive time
       * @param comments  list of comments used to store errors/warnings with message
       * @param doComputeDetails  flag to pre-compute delay/offset values
       * @throws IllegalArgumentException if message is null
       */
      public TimeInfo(NtpV3Packet message, long returnTime, List comments,
                     boolean doComputeDetails)
      {
          if (message == null)
              throw new IllegalArgumentException("message cannot be null");
          this._returnTime = returnTime;
          this._message = message;
          this._comments = comments;
          if (doComputeDetails)
              computeDetails();
      }
  
      /**
       * Add comment (error/warning) to list of comments associated
       * with processing of NTP parameters. If comment list not create
       * then one will be created.
       *
       * @param comment
       */
      public void addComment(String comment)
      {
          if (_comments == null) {
              _comments = new ArrayList();
          }
          _comments.add(comment);
      }
  
      /**
       * Compute and validate details of the NTP message packet. Computed
       * fields include the offset and delay.
       */
      public void computeDetails()
      {
          if (_detailsComputed) {
              return; // details already computed - do nothing
          }
          _detailsComputed = true;
          if (_comments == null) {
              _comments = new ArrayList();
          }
  
          TimeStamp origNtpTime = _message.getOriginateTimeStamp();
          long origTime = origNtpTime.getTime();
  
          // Receive Time is time request received by server (t2)
          TimeStamp rcvNtpTime = _message.getReceiveTimeStamp();
          long rcvTime = rcvNtpTime.getTime();
  
          // Transmit time is time reply sent by server (t3)
          TimeStamp xmitNtpTime = _message.getTransmitTimeStamp();
          long xmitTime = xmitNtpTime.getTime();
  
          /*
           * Round-trip network delay and local clock offset (or time drift) is calculated
           * according to this standard NTP equation:
           *
           * LocalClockOffset = ((ReceiveTimestamp - OriginateTimestamp) +
           *		        (TransmitTimestamp - DestinationTimestamp)) / 2
           *
           * equations from RFC-1305 (NTPv3)
           *      roundtrip delay = (t4 - t1) - (t3 - t2)
           *      local clock offset = ((t2 - t1) + (t3 - t4)) / 2
           *
           * It takes into account network delays and assumes that they are symmetrical.
           *
           * Note the typo in SNTP RFCs 1769/2030 which state that the delay
           * is (T4 - T1) - (T2 - T3) with the "T2" and "T3" switched.
           */
          if (origNtpTime.ntpValue() == 0)
          {
              // without originate time cannot determine when packet went out
              // might be via a broadcast NTP packet...
              if (xmitNtpTime.ntpValue() != 0)
              {
                  _offset = new Long(xmitTime - _returnTime);
                  _comments.add("Error: zero orig time -- cannot compute delay");
              } else
                  _comments.add("Error: zero orig time -- cannot compute delay/offset");
          } else if (rcvNtpTime.ntpValue() == 0 || xmitNtpTime.ntpValue() == 0)
          {
              _comments.add("Warning: zero rcvNtpTime or xmitNtpTime");
              // assert destTime >= origTime since network delay cannot be negative
              if (origTime > _returnTime)
                  _comments.add("Error: OrigTime > DestRcvTime");
              else
              {
                  // without receive or xmit time cannot figure out processing time
                  // so delay is simply the network travel time
                  _delay = new Long(_returnTime - origTime);
              }
              // TODO: is offset still valid if rcvNtpTime=0 || xmitNtpTime=0 ???
              // Could always hash origNtpTime (sendTime) but if host doesn't set it
              // then it's an malformed ntp host anyway and we don't care?
              // If server is in broadcast mode then we never send out a query in first place...
              if (rcvNtpTime.ntpValue() != 0)
              {
                  // xmitTime is 0 just use rcv time
                  _offset = new Long(rcvTime - origTime);
              } else if (xmitNtpTime.ntpValue() != 0)
              {
                  // rcvTime is 0 just use xmitTime time
                  _offset = new Long(xmitTime - _returnTime);
              }
          } else
          {
               long delayValue = _returnTime - origTime;
               // assert xmitTime >= rcvTime: difference typically < 1ms
               if (xmitTime < rcvTime)
               {
                   // server cannot send out a packet before receiving it...
                   _comments.add("Error: xmitTime < rcvTime"); // time-travel not allowed
               } else
               {
                   // subtract processing time from round-trip network delay
                   long delta = xmitTime - rcvTime;
                   // in normal cases the processing delta is less than
                   // the total roundtrip network travel time.
                   if (delta <= delayValue)
                   {
                       delayValue -= delta; // delay = (t4 - t1) - (t3 - t2)
                   } else
                   {
                       // if delta - delayValue == 1 ms then it's a round-off error
                       // e.g. delay=3ms, processing=4ms
                       if (delta - delayValue == 1)
                       {
                           // delayValue == 0 -> local clock saw no tick change but destination clock did
                           if (delayValue != 0)
                           {
                               _comments.add("Info: processing time > total network time by 1 ms -> assume zero delay");
                               delayValue = 0;
                           }
                       } else
                           _comments.add("Warning: processing time > total network time");
                   }
               }
               _delay = new Long(delayValue);
              if (origTime > _returnTime) // assert destTime >= origTime
                  _comments.add("Error: OrigTime > DestRcvTime");
  
              _offset = new Long(((rcvTime - origTime) + (xmitTime - _returnTime)) / 2);
          }
      }
  
      /**
       * Return list of comments (if any) during processing of NTP packet.
       *
       * @return List or null if not yet computed
       */
      public List getComments()
      {
          return _comments;
      }
  
      /**
       * Get round-trip network delay. If null then could not compute the delay.
       *
       * @return Long or null if delay not available.
       */
      public Long getDelay()
      {
          return _delay;
      }
  
      /**
       * Get clock offset needed to adjust local clock to match remote clock. If null then could not
       * compute the offset.
       *
       * @return Long or null if offset not available.
       */
      public Long getOffset()
      {
          return _offset;
      }
  
      /**
       * Returns NTP message packet.
       *
       * @return NTP message packet.
       */
      public NtpV3Packet getMessage()
      {
          return _message;
      }
  
      /**
       * Returns time at which time message packet was received by local machine.
       *
       * @return packet return time.
       */
      public long getReturnTime()
      {
          return _returnTime;
      }
  
  }
  
  
  
  1.1                  jakarta-commons/net/src/java/org/apache/commons/net/ntp/TimeStamp.java
  
  Index: TimeStamp.java
  ===================================================================
  package org.apache.commons.net.ntp;
  /*
   * Copyright 2001-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  
  import java.util.TimeZone;
  import java.util.Date;
  import java.util.Locale;
  import java.lang.ref.SoftReference;
  import java.text.SimpleDateFormat;
  import java.text.DateFormat;
  
  /***
   * TimeStamp class represents the Network Time Protocol (NTP) timestamp
   * as defined in RFC-1305 and SNTP (RFC-2030). It is represented as a
   * 64-bit unsigned fixed-point number in seconds relative to 0-hour on 1-January-1900.
   * The 32-bit low-order bits are the fractional seconds whose precision is
   * about 200 picoseconds. Assumes overflow date when date passes MAX_LONG
   * and reverts back to 0 is 2036 and not 1900. Test for most significant
   * bit: if MSB=0 then 2036 basis is used otherwise 1900 if MSB=1.
   * <p>
   * Methods exist to convert NTP timestamps to and from the equivalent Java date
   * representation, which is the number of milliseconds since the standard base
   * time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
   * </p>
   *
   * @author Jason Mathews, MITRE Corp
   * @version $Revision: 1.1 $ $Date: 2004/09/27 11:21:21 $
   * @see java.util.Date
   */
  public class TimeStamp implements java.io.Serializable, Comparable
  {
  
      /**
       * baseline NTP time if bit-0=0 -> 7-Feb-2036 @ 06:28:16 UTC
       */
      protected static final long msb0baseTime = 2085978496000L;
  
      /**
       *  baseline NTP time if bit-0=1 -> 1-Jan-1900 @ 01:00:00 UTC
       */
      protected static final long msb1baseTime = -2208988800000L;
  
      /**
       * Default NTP date string format. E.g. Fri, Sep 12 2003 21:06:23.860.
       * See <code>java.text.SimpleDateFormat</code> for code descriptions.
       */
      public final static String NTP_DATE_FORMAT = "EEE, MMM dd yyyy HH:mm:ss.SSS";
  
      /*
       * Caches for the DateFormatters used by various toString methods.
       */
      private static SoftReference simpleFormatter = null;
      private static SoftReference utcFormatter = null;
  
      /**
       * NTP timestamp value: 64-bit unsigned fixed-point number as defined in RFC-1305
       * with high-order 32 bits the seconds field and the low-order 32-bits the
       * fractional field.
       */
      private long ntpTime;
  
      private static final long serialVersionUID = 8139806907588338737L;
  
      // initialization of static time bases
      /*
      static {
          TimeZone utcZone = TimeZone.getTimeZone("UTC");
          Calendar calendar = Calendar.getInstance(utcZone);
          calendar.set(1900, Calendar.JANUARY, 1, 0, 0, 0);
          calendar.set(Calendar.MILLISECOND, 0);
          msb1baseTime = calendar.getTime().getTime();
          calendar.set(2036, Calendar.FEBRUARY, 7, 6, 28, 16);
          calendar.set(Calendar.MILLISECOND, 0);
          msb0baseTime = calendar.getTime().getTime();
      }
      */
  
      /***
       * Constructs a newly allocated NTP timestamp object
       * that represents the native 64-bit long argument.
       */
      public TimeStamp(long ntpTime)
      {
          this.ntpTime = ntpTime;
      }
  
      /***
       * Constructs a newly allocated NTP timestamp object
       * that represents the value represented by the string
       * in hexdecimal form (e.g. "c1a089bd.fc904f6d").
       *
       * @throws NumberFormatException - if the string does not contain a parsable timestamp.
       */
      public TimeStamp(String s) throws NumberFormatException
      {
          ntpTime = decodeNtpHexString(s);
      }
  
      /***
       * Constructs a newly allocated NTP timestamp object
       * that represents the Java Date argument.
       *
       * @param d - the Date to be represented by the Timestamp object.
       */
      public TimeStamp(Date d)
      {
          ntpTime = (d == null) ? 0 : toNtpTime(d.getTime());
      }
  
      /***
       * Returns the value of this Timestamp as a long value.
       *
       * @return the 64-bit long value represented by this object.
       */
      public long ntpValue()
      {
          return ntpTime;
      }
  
      /***
       * Returns high-order 32-bits representing the seconds of this NTP timestamp.
       *
       * @return seconds represented by this NTP timestamp.
       */
      public long getSeconds()
      {
          return (ntpTime >>> 32) & 0xffffffffL;
      }
  
      /***
       * Returns low-order 32-bits representing the fractional seconds.
       *
       * @return fractional seconds represented by this NTP timestamp.
       */
      public long getFraction()
      {
          return ntpTime & 0xffffffffL;
      }
  
      /***
       * Convert NTP timestamp to Java standard time.
       *
       * @return NTP Timestamp in Java time
       */
      public long getTime()
      {
          return getTime(ntpTime);
      }
  
      /***
       * Convert NTP timestamp to Java Date object.
       *
       * @return NTP Timestamp in Java Date
       */
      public Date getDate()
      {
          long time = getTime(ntpTime);
          return new Date(time);
      }
  
      /***
       * Convert 64-bit NTP timestamp to Java standard time.
       *
       * Note that java time (milliseconds) by definition has less precision
       * then NTP time (picoseconds) so converting NTP timestamp to java time and back
       * to NTP timestamp loses precision. For example, Tue, Dec 17 2002 09:07:24.810 EST
       * is represented by a single Java-based time value of f22cd1fc8a, but its
       * NTP equivalent are all values ranging from c1a9ae1c.cf5c28f5 to c1a9ae1c.cf9db22c.
       *
       * @param ntpTimeValue
       * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
       * represented by this NTP timestamp value.
       */
      public static long getTime(long ntpTimeValue)
      {
          long seconds = (ntpTimeValue >>> 32) & 0xffffffffL;	// high-order 32-bits
          long fraction = ntpTimeValue & 0xffffffffL;		// low-order 32-bits
  
          // Use round-off on fractional part to preserve going to lower precision
          fraction = Math.round(1000D * fraction / 0x100000000L);
  
          /*
           * If the most significant bit (MSB) on the seconds field is set we use
           * a different time base. The following text is a quote from RFC-2030 (SNTP v4):
           *
           *  If bit 0 is set, the UTC time is in the range 1968-2036 and UTC time
           *  is reckoned from 0h 0m 0s UTC on 1 January 1900. If bit 0 is not set,
           *  the time is in the range 2036-2104 and UTC time is reckoned from
           *  6h 28m 16s UTC on 7 February 2036.
           */
          long msb = seconds & 0x80000000L;
          if (msb == 0) {
              // use base: 7-Feb-2036 @ 06:28:16 UTC
              return msb0baseTime + (seconds * 1000) + fraction;
          } else {
              // use base: 1-Jan-1900 @ 01:00:00 UTC
              return msb1baseTime + (seconds * 1000) + fraction;
          }
      }
  
      /***
       * Helper method to convert Java time to NTP timestamp object.
       * Note that Java time (milliseconds) by definition has less precision
       * then NTP time (picoseconds) so converting Ntptime to Javatime and back
       * to Ntptime loses precision. For example, Tue, Dec 17 2002 09:07:24.810
       * is represented by a single Java-based time value of f22cd1fc8a, but its
       * NTP equivalent are all values from c1a9ae1c.cf5c28f5 to c1a9ae1c.cf9db22c.
       * @param   date   the milliseconds since January 1, 1970, 00:00:00 GMT.
       * @return NTP timestamp object at the specified date.
       */
      public static TimeStamp getNtpTime(long date)
      {
          return new TimeStamp(toNtpTime(date));
      }
  
      /***
       * Constructs a NTP timestamp object and initializes it so that
       * it represents the time at which it was allocated, measured to the
       * nearest millisecond.
       * @return NTP timestamp object set to the current time.
       * @see     java.lang.System#currentTimeMillis()
       */
      public static TimeStamp getCurrentTime()
      {
          return getNtpTime(System.currentTimeMillis());
      }
  
      /***
       * Convert NTP timestamp hexstring (e.g. "c1a089bd.fc904f6d") to the NTP
       * 64-bit unsigned fixed-point number.
       *
       * @return NTP 64-bit timestamp value.
       * @throws NumberFormatException - if the string does not contain a parsable timestamp.
       */
      protected static long decodeNtpHexString(String s)
              throws NumberFormatException
      {
          if (s == null) {
              throw new NumberFormatException("null");
          }
          int ind = s.indexOf('.');
          if (ind == -1) {
              if (s.length() == 0) return 0;
              return Long.parseLong(s, 16) << 32; // no decimal
          }
  
          return Long.parseLong(s.substring(0, ind), 16) << 32 |
                  Long.parseLong(s.substring(ind + 1), 16);
      }
  
      /***
       * Parses the string argument as a NTP hexidecimal timestamp representation string
       * (e.g. "c1a089bd.fc904f6d").
       *
       * @param s - hexstring.
       * @return the Timestamp represented by the argument in hexidecimal.
       * @throws NumberFormatException - if the string does not contain a parsable timestamp.
       */
      public static TimeStamp parseNtpString(String s)
              throws NumberFormatException
      {
          return new TimeStamp(decodeNtpHexString(s));
      }
  
      /***
       * Converts Java time to 64-bit NTP time representation.
       *
       * @param t Java time
       * @return NTP timestamp representation of Java time value.
       */
      protected static long toNtpTime(long t)
      {
          boolean useBase1 = t < msb0baseTime;	// time < Feb-2036
          long baseTime;
          if (useBase1) {
              baseTime = t - msb1baseTime; // dates <= Feb-2036
          } else {
              // if base0 needed for dates >= Feb-2036
              baseTime = t - msb0baseTime;
          }
  
          long seconds = baseTime / 1000;
          long fraction = ((baseTime % 1000) * 0x100000000L) / 1000;
  
          if (useBase1) {
              seconds |= 0x80000000L; // set high-order bit if msb1baseTime 1900 used
          }
  
          long time = seconds << 32 | fraction;
          return time;
      }
  
      /***
       * Computes a hashcode for this Timestamp. The result is the exclusive
       * OR of the two halves of the primitive <code>long</code> value
       * represented by this <code>TimeStamp</code> object. That is, the hashcode
       * is the value of the expression:
       * <blockquote><pre>
       * (int)(this.ntpValue()^(this.ntpValue() >>> 32))
       * </pre></blockquote>
       *
       * @return  a hash code value for this object.
       */
      public int hashCode()
      {
          return (int) (ntpTime ^ (ntpTime >>> 32));
      }
  
      /***
       * Compares this object against the specified object.
       * The result is <code>true</code> if and only if the argument is
       * not <code>null</code> and is a <code>Long</code> object that
       * contains the same <code>long</code> value as this object.
       *
       * @param   obj   the object to compare with.
       * @return  <code>true</code> if the objects are the same;
       *          <code>false</code> otherwise.
       */
      public boolean equals(Object obj)
      {
          if (obj instanceof TimeStamp) {
              return ntpTime == ((TimeStamp) obj).ntpValue();
          }
          return false;
      }
  
      /***
       * Converts this <code>TimeStamp</code> object to a <code>String</code>.
       * The NTP timestamp 64-bit long value is represented as hex string with
       * seconds separated by fractional seconds by a decimal point;
       * e.g. c1a089bd.fc904f6d <=> Tue, Dec 10 2002 10:41:49.986
       *
       * @return NTP timestamp 64-bit long value as hex string with seconds
       * separated by fractional seconds.
       */
      public String toString()
      {
          return toString(ntpTime);
      }
  
      /***
       * Left-pad 8-character hex string with 0's
       *
       * @param buf - StringBuffer which is appended with leading 0's.
       * @param l - a long.
       */
      private static void appendHexString(StringBuffer buf, long l)
      {
          String s = Long.toHexString(l);
          for (int i = s.length(); i < 8; i++)
              buf.append('0');
          buf.append(s);
      }
  
      /***
       * Converts 64-bit NTP timestamp value to a <code>String</code>.
       * The NTP timestamp value is represented as hex string with
       * seconds separated by fractional seconds by a decimal point;
       * e.g. c1a089bd.fc904f6d <=> Tue, Dec 10 2002 10:41:49.986
       *
       * @return NTP timestamp 64-bit long value as hex string with seconds
       * separated by fractional seconds.
       */
      public static String toString(long ntpTime)
      {
          StringBuffer buf = new StringBuffer();
          // high-order second bits (32..63) as hexstring
          appendHexString(buf, (ntpTime >>> 32) & 0xffffffffL);
  
          // low-order fractional seconds bits (0..31) as hexstring
          buf.append('.');
          appendHexString(buf, ntpTime & 0xffffffffL);
  
          return buf.toString();
      }
  
      /***
       * Converts this <code>TimeStamp</code> object to a <code>String</code>
       * of the form:
       * <blockquote><pre>
       * EEE, MMM dd yyyy HH:mm:ss.SSS</pre></blockquote>
       * See java.text.SimpleDataFormat for code descriptions.
       *
       * @return  a string representation of this date.
       */
      public String toDateString()
      {
          DateFormat formatter = null;
          if (simpleFormatter != null) {
              formatter = (DateFormat) simpleFormatter.get();
          }
          if (formatter == null) {
              // No cache yet, or cached formatter GC'd
              formatter = new SimpleDateFormat(NTP_DATE_FORMAT, Locale.US);
              formatter.setTimeZone(TimeZone.getDefault());
              simpleFormatter = new SoftReference(formatter);
          }
          Date ntpDate = getDate();
          synchronized (formatter) {
              return formatter.format(ntpDate);
          }
      }
  
      /***
       * Converts this <code>TimeStamp</code> object to a <code>String</code>
       * of the form:
       * <blockquote><pre>
       * EEE, MMM dd yyyy HH:mm:ss.SSS UTC</pre></blockquote>
       * See java.text.SimpleDataFormat for code descriptions.
       *
       * @return  a string representation of this date in UTC.
       */
      public String toUTCString()
      {
          DateFormat formatter = null;
          if (utcFormatter != null)
              formatter = (DateFormat) utcFormatter.get();
          if (formatter == null) {
              // No cache yet, or cached formatter GC'd
              formatter = new SimpleDateFormat(NTP_DATE_FORMAT + " 'UTC'",
                      Locale.US);
              formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
              utcFormatter = new SoftReference(formatter);
          }
          Date ntpDate = getDate();
          synchronized (formatter) {
              return formatter.format(ntpDate);
          }
      }
  
      /***
       * Compares two Timestamps numerically.
       *
       * @param   anotherTimeStamp - the <code>TimeStamp</code> to be compared.
       * @return  the value <code>0</code> if the argument TimeStamp is equal to
       *          this TimeStamp; a value less than <code>0</code> if this TimeStamp
       *          is numerically less than the TimeStamp argument; and a
       *          value greater than <code>0</code> if this TimeStamp is
       *          numerically greater than the TimeStamp argument
       *		(signed comparison).
       */
      public int compareTo(TimeStamp anotherTimeStamp)
      {
          long thisVal = this.ntpTime;
          long anotherVal = anotherTimeStamp.ntpTime;
          return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
      }
  
      /***
       * Compares this TimeStamp to another Object.  If the Object is a TimeStamp,
       * this function behaves like <code>compareTo(TimeStamp)</code>.  Otherwise,
       * it throws a <code>ClassCastException</code> (as TimeStamps are comparable
       * only to other TimeStamps).
       *
       * @param   o the <code>Object</code> to be compared.
       * @return  the value <code>0</code> if the argument is a TimeStamp
       *		numerically equal to this TimeStamp; a value less than
       *		<code>0</code> if the argument is a TimeStamp numerically
       *		greater than this TimeStamp; and a value greater than
       *		<code>0</code> if the argument is a TimeStamp numerically
       *		less than this TimeStamp.
       * @exception ClassCastException if the argument is not a
       *		  <code>TimeStamp</code>.
       * @see     java.lang.Comparable
       */
      public int compareTo(Object o)
      {
          return compareTo((TimeStamp) o);
      }
  
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


[net]Enabling FTPClient to set bufferSize

Posted by Rory Winston <rw...@eircom.net>.
I have patched FTPClient to enable explicitly setting the buffer size. Can
anyone else on [net] give this a quick once-over? I don't think I have
missed anything, but just in case...


Index: net/src/java/org/apache/commons/net/ftp/FTPClient.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/net/src/java/org/apache/commons/net/ftp/FTPClient.
java,v
retrieving revision 1.41
diff -u -r1.41 FTPClient.java
--- net/src/java/org/apache/commons/net/ftp/FTPClient.java	24 Sep 2004
12:07:07 -0000	1.41
+++ net/src/java/org/apache/commons/net/ftp/FTPClient.java	24 Sep 2004
15:48:46 -0000
@@ -258,6 +258,7 @@
     private boolean __remoteVerificationEnabled;
     private long __restartOffset;
     private FTPFileEntryParserFactory __parserFactory;
+    private int __bufferSize;

     // __systemName is a cached value that should not be referenced
directly
     // except when assigned in getSystemName and __initDefaults.
@@ -297,6 +298,7 @@
         __restartOffset      = 0;
         __systemName         = null;
         __entryParser        = null;
+        __bufferSize 		 = Util.DEFAULT_COPY_BUFFER_SIZE;
     }

     private String __parsePathname(String reply)
@@ -367,16 +369,15 @@
         if ((socket = _openDataConnection_(command, remote)) == null)
             return false;

-        // TODO: Buffer size may have to be adjustable in future to tune
-        // performance.
         output = new BufferedOutputStream(socket.getOutputStream(),
-                                          Util.DEFAULT_COPY_BUFFER_SIZE);
+                                          getBufferSize()
+                                          );
         if (__fileType == ASCII_FILE_TYPE)
             output = new ToNetASCIIOutputStream(output);
         // Treat everything else as binary for now
         try
         {
-            Util.copyStream(local, output, Util.DEFAULT_COPY_BUFFER_SIZE,
+            Util.copyStream(local, output, getBufferSize(),
                             CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
                             false);
         }
@@ -414,7 +415,7 @@
           // own if they want to wrap the SocketOutputStream we return
           // for file types other than ASCII.
           output = new BufferedOutputStream(output,
-                                            Util.DEFAULT_COPY_BUFFER_SIZE);
+                                            getBufferSize());
           output = new ToNetASCIIOutputStream(output);

         }
@@ -1265,16 +1266,14 @@
         if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) ==
null)
             return false;

-        // TODO: Buffer size may have to be adjustable in future to tune
-        // performance.
         input = new BufferedInputStream(socket.getInputStream(),
-                                        Util.DEFAULT_COPY_BUFFER_SIZE);
+                                        getBufferSize());
         if (__fileType == ASCII_FILE_TYPE)
           input = new FromNetASCIIInputStream(input);
         // Treat everything else as binary for now
         try
         {
-            Util.copyStream(input, local, Util.DEFAULT_COPY_BUFFER_SIZE,
+            Util.copyStream(input, local, getBufferSize(),
                             CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
                             false);
         }
@@ -1334,7 +1333,7 @@
           // own if they want to wrap the SocketInputStream we return
           // for file types other than ASCII.
           input = new BufferedInputStream(input,
-                                          Util.DEFAULT_COPY_BUFFER_SIZE);
+                                          getBufferSize());
           input = new FromNetASCIIInputStream(input);
         }
         return new org.apache.commons.net.io.SocketInputStream(socket,
input);
@@ -2599,7 +2598,26 @@

         completePendingCommand();
         return list;
-    }}
+    }
+
+    /**
+     * Set the internal buffer size.
+     *
+     * @param bufSize The size of the buffer
+     */
+    public void setBufferSize(int bufSize) {
+    	__bufferSize = bufSize;
+    }
+
+    /**
+     * Retrieve the current internal buffer size.
+     * @return The current buffer size.
+     */
+    public int getBufferSize() {
+    	return __bufferSize;
+    }
+
+}

 /* Emacs configuration
  * Local variables:        **


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org