Re: NSPipe or NSFileHandle buffering?
Re: NSPipe or NSFileHandle buffering?
- Subject: Re: NSPipe or NSFileHandle buffering?
- From: Christian Brunschen <email@hidden>
- Date: Sun, 1 Dec 2002 16:29:39 +0000
On Sunday, Dec 1, 2002, at 16:09 Europe/London, mw wrote:
Hello,
I wrote a Perl backend for a program I plan on writing. I just finished
writing a (very, very simple) frontend to the program to make sure it
works
okay with Cocoa over pipes. The Perl program first takes 6 values via
STDIN
(they are all in a row).
chomp($pop3host = <STDIN>);
chomp($filter_type = <STDIN>);
chomp($filter_match = <STDIN>);
chomp($username = <STDIN>);
chomp($password = <STDIN>);
chomp($delete = <STDIN>);
This will read the values from one line each.
So I figured that in my Cocoa program, I should be able to have 6
method
calls in a row to write all of this information to the Perl program
(entered
in text fields).
[writeHandle writeData: [NSData dataWithBytes:[popServer cString]
length:[popServer cStringLength]]];
[writeHandle writeData: [NSData dataWithBytes:[filterField cString]
length:[filterField cStringLength]]];
[writeHandle writeData: [NSData dataWithBytes:[filterFieldValue
cString]
length:[filterFieldValue cStringLength]]];
[writeHandle writeData: [NSData dataWithBytes:[username cString]
length:[username cStringLength]]];
[writeHandle writeData: [NSData dataWithBytes:[password cString]
length:[password cStringLength]]];
[writeHandle writeData: [NSData dataWithBytes:[delete cString]
length:[delete cStringLength]]];
[writeHandle closeFile];
NSFileHandle's -writeData: writes _precisely_ the data you give it. In
the code above, you write the different strings one after the other -
but you never separate them with newlines, which is what the Perl code
expects.
Further, the canonical way to get an NSData from an NSString is to use
NSString's -dataUsingEncoding:allowLossyConversion: method (or its
cousin -dataUsingEncoding:), which will simplify your code. So taken
all in all together, your code should probably look like
/* let's get an NSData with a newline character, which we can reuse */
NSData *newlineData = [@"\n" dataUsingEncoding:NSASCIIStringEncoding];
[writeHandle write
Data:[popServer
dataUsingEncoding:NSASCIIStringEncoding]];
[writeHandle write
Data:newlineData];
[writeHandle write
Data:[filterField
dataUsingEncoding:NSASCIIStringEncoding]];
[writeHandle write
Data:newlineData];
[writeHandle write
Data:[filterFieldValue
dataUsingEncoding:NSASCIIStringEncoding]];
[writeHandle write
Data:newlineData];
[writeHandle write
Data:[username
dataUsingEncoding:NSASCIIStringEncoding]];
[writeHandle write
Data:newlineData];
[writeHandle write
Data:[password
dataUsingEncoding:NSASCIIStringEncoding]];
[writeHandle write
Data:newlineData];
[writeHandle write
Data:[delete
dataUsingEncoding:NSASCIIStringEncoding]];
[writeHandle write
Data:newlineData];
[writeHandle closeFile];
The NSTask and everything else is working okay, so no debugging there
is
needed :-).
Now, in the Perl program, it kept not connecting to the POP3 server
and I
was baffled. So I put some debugging code in there to simply print out
all
of the values that were inputted by the first chunk of code I
presented, and
I had \n after each of the values to make it readable. But for some
reason,
they were all printed back to the Cocoa program in one line.
The reason for this is simple: You aren't printing any newlines!
NSFileHandle's -writeData: method only writes precisely the data you
give it; there is no automatic insertion of newlinesor similar. You
have to put the there yourself, such as in the example above.
This baffled me
even further, so I removed all of the debugging code in the Perl
program
except for the first line (which was supposed to print back the name
of the
POP3 server that was entered). This printed back ALL OF THE VALUES
THAT HAD
BEEN SENT OVER. That answered a lot of questions.
So it seems that when I am writing information from the Cocoa program
to the
Perl program, it buffers everything somewhere between the two programs
in
the "pipes", and then writes everything to a single variable, leaving
all of
the other Perl variables undefined or empty.
I tried using this code in the perl program to turn off buffering for
STDIN:
select STDIN;
$|=1;
as recommended by several websites, but that does nothing since I am
not
technically inputting data from the terminal.
Does anybody have any idea what is going on here, and how to turn it
off (if
it really is buffering like I think)??? I have looked everywhere and
there
is nothing on this. I have no idea whether the information is being
buffered
on the Cocoa end or on the Perl end either.
Everything is performing exactly to spec; you just have to put the
newlines into the data you are transmitting yourself, rather than
expecting them to magically appear.
TIA,
mw
Best wishes,
// Christian Brunschen
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.