/** NSNonBlockingFileHandle.m - <title>GSWeb: NSNonBlockingFileHandle</title>

   Copyright (C) 1999-2002 Free Software Foundation, Inc.
  
   Written by:	Manuel Guesdon <mguesdon@orange-concept.com>
   Date: 		Jan 1999
   
   $Revision: 25027 $
   $Date: 2007-04-13 13:32:02 -0500 (Fri, 13 Apr 2007) $

   This file is part of the GNUstep Web Library.
   
   <license>
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
   
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.
   
   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   </license>
**/

#include <time.h>
#include <sys/time.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

#include <sys/file.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#ifdef SOLARIS
#include <sys/filio.h>
#include <limits.h>
#endif
#include <Foundation/Foundation.h>
#include "NSNonBlockingFileHandle.h"
#include "GSWeb.h"
#include "GSWUtils.h"

@implementation NSFileHandle (CFRNonBlockingIO)


//Returns an NSData object containing all of the currently available data. 
// Does not block if there is no data; returns nil instead.
-(NSData*)availableDataNonBlocking
{
  NSData* data=nil;

  data=[self readDataOfLengthNonBlocking: UINT_MAX];

  return data;
};

// Returns an NSData object containing all of the currently available data. 
//  Does not block if there is no data; returns nil instead. 
//  Cover for #{-availableDataNonBlocking}.
-(NSData*)readDataToEndOfFileNonBlocking
{
  NSData* data=nil;

  data=[self readDataOfLengthNonBlocking: UINT_MAX];

  return data;
};


-(unsigned int)_availableByteCountNonBlocking
{
  int numBytes=0;
  int fd = 0;

  fd=[self fileDescriptor];

  if (ioctl(fd, FIONREAD, (char *) &numBytes) == -1)
    {
      LOGException0(@"NSFileHandleOperationException ioctl() Err");
      [NSException raise: NSFileHandleOperationException
                   format: @"ioctl() Err # %d", (int)errno];
    };

  return numBytes;
};

// Reads up to length bytes of data from the file handle. 
// If no data is available, returns nil. Does not block.
-(NSData*)readDataOfLengthNonBlocking:(unsigned int)length
{
  NSData* data=nil;
  unsigned int readLength=0;

  readLength = [self _availableByteCountNonBlocking];
  readLength = (readLength < length) ? readLength : length;
  
  if (readLength>0)
    {
      data=[self readDataOfLength: readLength];
    };

  return data;
}

@end
