bug-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Q] NSFileHandle -readDataOfLength behaviour


From: Vaisburd, Haim
Subject: RE: [Q] NSFileHandle -readDataOfLength behaviour
Date: Fri, 13 Apr 2007 12:03:11 -0700

Richard Frith-Macdonald [mailto:richard@tiptree.demon.co.uk] wrote:

> Tima Vaisburd wrote:

> > RFM> this method should block until it reads the specified amount of
data
> > RFM> (or eof).
>
> > but for my stream class I need exactly what read() does, since the 
> > whole idea was to read byte after byte until the record ends (which
is 
> > determined by the structure of the incoming byte stream, not by the 
> > length passed in the header).
>

> Maybe availableData is what you want. 

-availableData does not have a limit. I might be able to use it,
but what I would really want is -readDataOfLength that would not block
until it gets all the length but would return what's available,
blocking only until the first byte comes ( i.e. like read() ).

I hoped that that's what it should do and was a little disappointed
when you said "block". Since I cannot test on Mac right now (I have one
recently but haven't programmed on it yet) I searched the web for
the proof. Could not find one but I found two other open source
implementations that do what I want and not what you say (see below).

Of course they are not a proof of anything, but raise a concern in my
mind.

Could you, please, test the behavior on Mac OSX or just confirm that
you've
done it before?



1.

http://svn.opengroupware.org/SOPE/trunk/libFoundation/Foundation/NSConcr
eteFileHandle.m :

/*
   NSConcreteFileHandle.m

   Copyright (C) 1995, 1996, 1997 Ovidiu Predescu and Mircea Oancea.
   All rights reserved.

   Author: Ovidiu Predescu <ovidiu@net-community.com>
   Date: May 1997

   This file is part of libFoundation.
   [...]
*/

@implementation NSConcreteFileHandle

- (NSData *)readDataOfLength:(unsigned int)length
{
    [...]
    else if (type == NSFileHandleSocket) {
        void *buffer;
        int  howMany;

        /* Force the compiler to allocate `buffer' on stack */
        *&buffer = MallocAtomic(length);

        howMany = read(fd, buffer, length);
        if (howMany == -1) {
            lfFree(buffer);
            [[[NSFileHandleOperationException alloc]
                      initWithFileHandle:self
                      operation:@"Error while reading from socket!"]
raise];
        }
        if (howMany < (int)length)
            buffer = Realloc(buffer, howMany);
        data = [NSData dataWithBytesNoCopy:buffer length:howMany];
    }
    [...]
}


2.

http://www.quantum-step.com/download/sources/mySTEP/Foundation/Sources/N
SFileHandle.m

/* 
   NSFileHandle.m

   Implementation of NSFileHandle for mySTEP

   Copyright (C) 1997 Free Software Foundation, Inc.

   Author:  Richard Frith-Macdonald <richard@brainstorm.co.uk>
   Date:        1997

   Complete rewrite based on NSStream:
   Dr. H. Nikolaus Schaller <hns@computer.org>
   Date: Jan 2006
 
   This file is part of the mySTEP Library [...]
*/

@implementation NSFileHandle

- (NSData *) readDataOfLength:(unsigned int) length;
{
        unsigned char *buffer;
        unsigned int len;
        if([_inputStream getBuffer:&buffer length:&len])
                return [NSData dataWithBytes:buffer length:MIN(len,
length)];       // buffer is directly available
        if(!(buffer=objc_malloc(length)))
                return nil;     // can't allocate large enough buffer
        len=[_inputStream read:buffer maxLength:length];        // fetch
get as much as possible
        if(len < 0)
                {
                objc_free(buffer);
                [NSException raise:NSFileHandleOperationException
format:@"failed to read data from NSFileHandle - %s", strerror(errno)]; 
                return nil;
                }
        buffer=objc_realloc(buffer, len);       // free unused buffer
space
        return [NSData dataWithBytesNoCopy:buffer length:len
freeWhenDone:YES];      // take over responsibility for buffer
}




> If you really want to read an individual byte at a time, NSStream is
probably better than NSFileHandle ...
> but that's a shockingly inefficient way to do I/O

Do you refer to NSStream or "byte at a time" as being shockingly
inefficient?
Of course I meant "byte at a time" in the way getc() macro of standard
IO library does it:
read a block with a system call, scan it with something fast.

With comminucation channel though the last read() call may give me the
end of some record
( "}}}}}" , 5 bytes ) and the server might not send anything else until
further request from the client.
In the client I need to get these five bytes, if everyting works OK the
last '}' will be
the end of the record, I'll process it and send another request.

Thank you,
Tima




reply via email to

[Prev in Thread] Current Thread [Next in Thread]