hotspot/agent/src/os/win32/IOBuf.hpp
changeset 10864 17307b96ae38
parent 10779 5037da29fa26
parent 10762 cc1f5ce8e504
child 10865 7f8dd1713604
equal deleted inserted replaced
10779:5037da29fa26 10864:17307b96ae38
     1 /*
       
     2  * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #ifndef _IO_BUF_
       
    26 #define _IO_BUF_
       
    27 
       
    28 // This file is currently used for os/solaris/agent/ too.  At some point in time
       
    29 // the source will be reorganized to avoid these ifdefs.
       
    30 // Note that this class can read/write from a file as well as a socket.  This
       
    31 // file capability is only implemented on win32.
       
    32 
       
    33 #ifdef WIN32
       
    34   #include <winsock2.h>
       
    35 #else
       
    36   #include <sys/types.h>
       
    37   #include <sys/socket.h>
       
    38   // These are from win32 winsock2.h
       
    39   typedef unsigned int SOCKET;
       
    40   typedef void * HANDLE;
       
    41   typedef unsigned long DWORD;
       
    42   #define INVALID_SOCKET (SOCKET)(~0)
       
    43 #endif
       
    44 
       
    45 #include <vector>
       
    46 #include "Buffer.hpp"
       
    47 
       
    48 /** Manages an input/output buffer pair for a socket or file handle. */
       
    49 class IOBuf {
       
    50 public:
       
    51   IOBuf(int inBufLen, int outBufLen);
       
    52   ~IOBuf();
       
    53 
       
    54   enum ReadLineResult {
       
    55     RL_GOT_DATA,
       
    56     RL_NO_DATA,
       
    57     RL_ERROR
       
    58   };
       
    59 
       
    60   /** Change the socket with which this buffer is associated */
       
    61   void setSocket(SOCKET sock);
       
    62 
       
    63   // Reading/writing files is only supported on windows.
       
    64 #ifdef WIN32
       
    65   /** Change the output file handle with which this buffer is
       
    66       associated. Currently IOBufs can not be used to read from a file
       
    67       handle. */
       
    68   void setOutputFileHandle(HANDLE handle);
       
    69 #endif
       
    70 
       
    71   /** Reset the input and output buffers, without flushing the output
       
    72       data to the socket */
       
    73   void reset();
       
    74 
       
    75   /** Try to read a line of data from the given socket without
       
    76       blocking. If was able to read a complete line of data, returns a
       
    77       character pointer to the beginning of the (null-terminated)
       
    78       string. If not, returns NULL, but maintains enough state that
       
    79       subsequent calls to tryReadLine() will not ignore the data
       
    80       already read. NOTE: this skips end-of-line characters (typically
       
    81       CR/LF) as defined by "isEOL()". When switching back and forth
       
    82       between binary and text modes, to be sure no data is lost, pad
       
    83       the beginning and end of the binary transmission with bytes
       
    84       which can not be confused with these characters. */
       
    85   ReadLineResult tryReadLine();
       
    86 
       
    87   /** Read a line of data from the given socket, blocking until a
       
    88       line, including EOL, appears.  Return the line, or NULL if
       
    89       something goes wrong. */
       
    90   char *readLine();
       
    91 
       
    92   /** Get the pointer to the beginning of the (null-terminated) line.
       
    93       This should only be called if tryReadLine() has returned
       
    94       RL_GOT_DATA. This sets the "parsing cursor" to the beginning of
       
    95       the line. */
       
    96   char* getLine();
       
    97 
       
    98   // NOTE: any further data-acquisition routines must ALWAYS call
       
    99   // fixupData() at the beginning!
       
   100 
       
   101   //----------------------------------------------------------------------
       
   102   // Output routines
       
   103   //
       
   104 
       
   105   /** Flush the output buffer to the socket. Returns true if
       
   106       succeeded, false if write error occurred. */
       
   107   bool flush();
       
   108 
       
   109   /** Write the given string to the output buffer. May flush if output
       
   110       buffer becomes too full to store the data. Not guaranteed to
       
   111       work if string is longer than the size of the output buffer.
       
   112       Does not include the null terminator of the string. Returns true
       
   113       if succeeded, false if write error occurred. */
       
   114   bool writeString(const char* str);
       
   115 
       
   116   /** Write the given int to the output buffer. May flush if output
       
   117       buffer becomes too full to store the data. Returns true if
       
   118       succeeded, false if write error occurred. */
       
   119   bool writeInt(int val);
       
   120 
       
   121   /** Write the given unsigned int to the output buffer. May flush if
       
   122       output buffer becomes too full to store the data. Returns true
       
   123       if succeeded, false if write error occurred. */
       
   124   bool writeUnsignedInt(unsigned int val);
       
   125 
       
   126   /** Write the given boolean to the output buffer. May flush if
       
   127       output buffer becomes too full to store the data. Returns true
       
   128       if succeeded, false if write error occurred. */
       
   129   bool writeBoolAsInt(bool val);
       
   130 
       
   131   /** Write the given address to the output buffer. May flush if
       
   132       output buffer becomes too full to store the data. Returns true
       
   133       if succeeded, false if write error occurred. */
       
   134   bool writeAddress(void* val);
       
   135 
       
   136   /** Writes a space to the output buffer. May flush if output buffer
       
   137       becomes too full to store the data. Returns true if succeeded,
       
   138       false if write error occurred. */
       
   139   bool writeSpace();
       
   140 
       
   141   /** Writes an end-of-line sequence to the output buffer. May flush
       
   142       if output buffer becomes too full to store the data. Returns
       
   143       true if succeeded, false if write error occurred. */
       
   144   bool writeEOL();
       
   145 
       
   146   /** Writes a binary character to the output buffer. */
       
   147   bool writeBinChar(char c);
       
   148 
       
   149   /** Writes a binary unsigned short in network (big-endian) byte
       
   150       order to the output buffer. */
       
   151   bool writeBinUnsignedShort(unsigned short i);
       
   152 
       
   153   /** Writes a binary unsigned int in network (big-endian) byte order
       
   154       to the output buffer. */
       
   155   bool writeBinUnsignedInt(unsigned int i);
       
   156 
       
   157   /** Writes a binary buffer to the output buffer. */
       
   158   bool writeBinBuf(char* buf, int size);
       
   159 
       
   160 #ifdef WIN32
       
   161   enum FillState {
       
   162     DONE = 1,
       
   163     MORE_DATA_PENDING = 2,
       
   164     FAILED = 3
       
   165   };
       
   166 
       
   167   /** Very specialized routine; fill the output buffer from the given
       
   168       file handle. Caller is responsible for ensuring that there is
       
   169       data to be read on the file handle. */
       
   170   FillState fillFromFileHandle(HANDLE fh, DWORD* numRead);
       
   171 #endif
       
   172 
       
   173   /** Binary utility routine (for poke) */
       
   174   static bool isBinEscapeChar(char c);
       
   175 
       
   176 private:
       
   177   IOBuf(const IOBuf&);
       
   178   IOBuf& operator=(const IOBuf&);
       
   179 
       
   180   // Returns -1 if non-blocking and no data available
       
   181   int readChar(bool block);
       
   182   // Line-oriented reading
       
   183   std::vector<char> curLine;
       
   184   bool gotDataLastTime;
       
   185 
       
   186   ReadLineResult doReadLine(bool);
       
   187 
       
   188   bool flushImpl(bool moreDataToCome);
       
   189 
       
   190   SOCKET fd;
       
   191   HANDLE outHandle;
       
   192   bool usingSocket;
       
   193 
       
   194   // Buffers
       
   195   Buffer* inBuf;
       
   196   Buffer* outBuf;
       
   197 
       
   198   // Simple finite-state machine to handle binary data
       
   199   enum State {
       
   200     TEXT_STATE,
       
   201     BIN_STATE,
       
   202     EOL_STATE
       
   203   };
       
   204   enum Action {
       
   205     NO_ACTION,
       
   206     GOT_LINE,     // TEXT_STATE -> EOL_STATE transition
       
   207     SKIP_EOL_CHAR // EOL_STATE -> EOL_STATE transition
       
   208   };
       
   209 
       
   210   State state;
       
   211   Action processChar(char c);
       
   212 
       
   213   // Handling incoming binary buffers (poke command)
       
   214   int   binPos;    // Number of binary characters read so far;
       
   215                    // total number to read is binLength + 4
       
   216   int   binLength; // Number of binary characters in message;
       
   217                    // not valid until binPos >= 4
       
   218 
       
   219   bool isEOL(char c);
       
   220 };
       
   221 
       
   222 #endif  // #defined _IO_BUF_