forked from cellularmitosis/ADC-reference-library-2009-july
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlisting1.html
More file actions
executable file
·596 lines (469 loc) · 19.1 KB
/
Copy pathlisting1.html
File metadata and controls
executable file
·596 lines (469 loc) · 19.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<!-- BEGIN META TAG INFO -->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="home" href="http://developer.apple.com/">
<link rel="find" href="http://developer.apple.com/search/">
<link rel="stylesheet" type="text/css" href="../../documentation/css/adcstyle.css" title="fonts">
<script language="JavaScript" src="../../documentation/js/adc.js" type="text/javascript"></script>
<!-- END META TAG INFO -->
<!-- BEGIN TITLE -->
<title>NoCopyReceives - /NoCopyReceives.c</title>
<!-- END TITLE -->
<script language="JavaScript">
function JumpToNewPage() {
window.location=document.scpopupmenu.gotop.value;
return true;
}
</script>
</head>
<!-- BEGIN BODY OPEN -->
<body>
<!--END BODY OPEN -->
<!-- START CENTER OPEN -->
<center>
<!-- END CENTER OPEN -->
<!-- BEGIN LOGO AND SEARCH -->
<!--#include virtual="/includes/adcnavbar"-->
<!-- END LOGO AND SEARCH -->
<!-- START BREADCRUMB -->
<div id="breadcrumb">
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td scope="row"><img width="340" height="10" src="images/1dot.gif" alt=""></td>
<td><img width="340" height="10" src="images/1dot.gif" alt=""></td>
</tr>
<tr valign="middle">
<td align="left" colspan="2">
<a href="http://developer.apple.com/">ADC Home</a> > <a href="../../referencelibrary/index.html">Reference Library</a> > <a href="../../samplecode/index.html">Sample Code</a> > <a href="../../samplecode/Carbon/index.html">Carbon</a> > <a href="../../samplecode/Carbon/idxNetworking-date.html">Networking</a> > <A HREF="javascript:location.replace('index.html');">NoCopyReceives</A> >
</td>
</tr>
<tr>
<td colspan="2" scope="row"><img width="680" height="35" src="images/1dot.gif" alt=""></td>
</tr>
</table>
</div>
<!-- END BREADCRUMB -->
<!-- START MAIN CONTENT -->
<!-- START TITLE GRAPHIC AND INTRO-->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td><h1><div id="pagehead">NoCopyReceives</div></h1></td>
</tr>
</table>
<!-- END TITLE GRAPHIC AND INTRO -->
<!-- START WIDE COLUMN -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr align="left" valign="top">
<td id="scdetails">
<h2>/NoCopyReceives.c</h2>
<form name="scpopupmenu" onSubmit="return false;" method=post>
<p><strong>View Source Code:</strong>
<select name="gotop" onChange="JumpToNewPage();" style="width:340px"><option selected value="ingnore">Select File</option>
<option value="listing1.html">/NoCopyReceives.c</option>
<option value="listing2.html">/NoCopyReceives_Output.txt</option></select>
</p>
</form>
<p><strong><a href="NoCopyReceives.zip">Download Sample</a></strong> (“NoCopyReceives.zip”, 57.2K)<BR>
<strong><a href="NoCopyReceives.dmg">Download Sample</a></strong> (“NoCopyReceives.dmg”, 120.8K)</p>
<!--
<p><strong><a href="#">Download Sample</a></strong> (“filename.sit”, 500K)</p>
-->
</td>
</tr>
<tr>
<td scope="row"><img width="680" height="10" src="images/1dot.gif" alt=""><br>
<img height="1" width="680" src="images/1dot_919699.gif" alt=""><br>
<img width="680" height="20" src="images/1dot.gif" alt=""></td>
</tr>
<tr>
<td scope="row">
<!--googleon: index -->
<pre class="sourcecodebox">/* File: NoCopyReceives.c Contains: Minimal sample to demo no-copy receives under OT. Written by: Quinn "The Eskimo!" Copyright: Copyright © 1997-2001 by Apple Computer, Inc., All Rights Reserved. You may incorporate this Apple sample source code into your program(s) without restriction. This Apple sample source code has been provided "AS IS" and the responsibility for its operation is yours. You are not permitted to redistribute this Apple sample source code as "Apple sample source code" after having made changes. If you're going to re-distribute the source, we require that you make it clear in the source that the code was descended from Apple sample source code, but that you've made changes. Change History (most recent first): 2/18/2001 Chad Jones Updated for Codewarrior IDE 4.1 and Carbonized for OSX 7/22/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 *//////////////////////////////////////////////////////////////////////// Need to include to be carbonized #if defined(__MWERKS__)# include <carbon.h>/////////////////////////////////////////////////////////////////////// Pick up all the standard OT stuff.# include <Events.h># include <Files.h># include <OpenTransport.h># include <OpenTptInternet.h># include <OpenTptClient.h># include <SIOUX.h>#else# include <CoreServices/CoreServices.h>#endif# include <stdio.h>/////////////////////////////////////////////////////////////////////// OTDebugStr is not defined in any OT header files, but it is// exported by the libraries, so we define the prototype here.extern pascal void OTDebugStr(const char* str);/////////////////////////////////////////////////////////////////////// More Assert replaces OTAssert in carbonized code because OTAssert // does not exist // // We usually want asserions and other debugging code // turned on, but you can turn it all off if you like // by setting MORE_DEBUG to 0. //#ifndef MORE_DEBUG# define MORE_DEBUG 1#endif // // Our assertion macros compile down to nothing if // MORE_DEBUG is not true. MoreAssert produces a // value indicating whether the assertion succeeded // or failed. MoreAssertQ is Quinn's flavor of // MoreAssert which does not produce a value. //#if MORE_DEBUG# define MoreAssert(x) \ ((x) ? true : (DebugStr ("\pMoreAssert failure: " #x), false))# define MoreAssertQ(x) \ do { if (!(x)) DebugStr ("\pMoreAssertQ failure: " #x); } while (false)#else# define MoreAssert(x) (true)# define MoreAssertQ(x)#endif/////////////////////////////////////////////////////////////////////static UInt32 gLastPrinted = 0;static pascal void YieldingNotifier(void* contextPtr, OTEventCode code, OTResult result, void* cookie){ #pragma unused(contextPtr) #pragma unused(result) #pragma unused(cookie) switch (code) { case kOTSyncIdleEvent: if ( TickCount() > gLastPrinted + 60 ) { printf("."); fflush(stdout); gLastPrinted = TickCount(); } break; default: // do nothing break; }}/////////////////////////////////////////////////////////////////////enum { kTransferBufferSize = 1024};static char gTransferBuffer[kTransferBufferSize];static OSStatus NoCopyReceiveUsingOTReadBuffer(EndpointRef ep, SInt16 destFileRefNum) // Reads data from the endpoint using no-copy receive. The data // is then copied out of the OTBuffer chain using the OTReadBuffer utility // function. This method is useful if you need to look at a small chunk of // data (which you can copy out using OTReadBuffer) to decide what to do with // the rest.{ OSStatus err; OTResult result; OTBuffer *receivedBuffer; OTBufferInfo bufferInfo; OTFlags junkFlags; UInt32 bytesRemaining; OTByteCount bytesThisTime; //This is a UInt32 SInt32 count; // Prepare for failure. err = noErr; receivedBuffer = nil; // Read the data. Use the constant kOTNetbufDataIsOTBufferStar to // indicate that you want to do a no-copy receive. result = OTRcv(ep, &receivedBuffer, kOTNetbufDataIsOTBufferStar, &junkFlags); if (result >= 0) { // Use the OT utility function OTBufferDataSize to calculate // how much data OT returned. bytesRemaining = OTBufferDataSize(receivedBuffer); // Initialise the bufferInfo data structure. bufferInfo.fOffset = 0; bufferInfo.fBuffer = receivedBuffer; // Write that data to the file. We do this in chunks, // copying each chunk of data out of the OTBuffer chain // and into our transfer buffer using the OTReadBuffer function, // then writing each chunk of data, until there is no // more data left in the buffer chain. This is not a // particularly efficient method (see below for something // better) but it does demonstrate the use of OTReadBuffer. while (err == noErr && bytesRemaining > 0) { if (bytesRemaining > kTransferBufferSize) { bytesThisTime = kTransferBufferSize; } else { bytesThisTime = bytesRemaining; } (void) OTReadBuffer(&bufferInfo, gTransferBuffer, &bytesThisTime); count = bytesThisTime; err = FSWrite(destFileRefNum, &count, gTransferBuffer); bytesRemaining -= bytesThisTime; } err = noErr; } else { err = result; } // Clean up. We *must* release the OTBuffer chain back to OT // so that it can reuse it. Also, OTReleaseBuffer is not tolerant of // the parameter being nil, so we check for that case first. if (receivedBuffer != nil) { OTReleaseBuffer(receivedBuffer); } return err;}/////////////////////////////////////////////////////////////////////static OSStatus NoCopyReceiveWalkingBufferChain(EndpointRef ep, SInt16 destFileRefNum) // Reads data from the endpoint using no-copy receive. We walk // the resulting buffer chain, writing out chunks of data // directly to the file from the buffers returned to us by OT.{ OSStatus err; OTResult result; OTBufferInfo bufferInfo; OTBuffer *thisBuffer; OTFlags junkFlags; SInt32 count; err = noErr; // Initialise the bufferInfo data structure. bufferInfo.fOffset = 0; bufferInfo.fBuffer = nil; // Read the data. Use the constant kOTNetbufDataIsOTBufferStar to // indicate that you want to do a no-copy receive. result = OTRcv(ep, &bufferInfo.fBuffer, kOTNetbufDataIsOTBufferStar, &junkFlags); if (result >= 0) { // Now walk the returned buffer chain, writing out each // chunk of data to the file. thisBuffer = bufferInfo.fBuffer; while (err == noErr && thisBuffer != nil) { count = thisBuffer->fLen; err = FSWrite(destFileRefNum, &count, thisBuffer->fData); thisBuffer = thisBuffer->fNext; } } else { err = result; } // Clean up. We *must* release the OTBuffer chain back to OT // so that it can reuse it. Also, OTReleaseBuffer is not tolerant of // the parameter being nil, so we check for that case first. if (bufferInfo.fBuffer != nil) { OTReleaseBuffer(bufferInfo.fBuffer); } return err;}/////////////////////////////////////////////////////////////////////enum { kUsingOTReadBuffer = 0, kUseWalkingBufferChain};static OSStatus TestNoCopyReceive(UInt8 method, SInt16 destFileRefNum) // Test the above two no-copy receive functions by connecting // to "www.apple.com" and downloading the root HTTP object.{ OSStatus err; OSStatus junk; EndpointRef ep; DNSAddress hostDNSAddress; TCall sndCall; OTResult bytesSent; char httpGetCommand[256]; // Create a TCP endpoint. ep = OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err,nil); // Set up the endpoint. if (err == noErr) { // Establish the modes of operation. This sample uses // sync/blocking mode, with sync idle events that yield // time using the Thread Manager. junk = OTSetSynchronous(ep); MoreAssert(junk == noErr);//Triggers if: TestNoCopyReceive: OTSetSynchronous failed junk = OTSetBlocking(ep); MoreAssert(junk == noErr);//Triggers if: TestNoCopyReceive: OTSetBlocking failed junk = OTInstallNotifier(ep, NewOTNotifyUPP(YieldingNotifier), nil); MoreAssert(junk == noErr);//Triggers if: TestNoCopyReceive: OTInstallNotifier failed junk = OTUseSyncIdleEvents(ep, true); MoreAssert(junk == noErr);//Triggers if: TestNoCopyReceive: OTUseSyncIdleEvents failed // Bind the endpoint. Because we're an outgoing connection, // we don't have to bind it to a specific address. err = OTBind(ep, nil, nil); } // Initialise the sndCall structure and call OTConnect. We nil // out most of the fields in the sndCall structure because // we don't want any special options or connection data. // The important field of the sndCall is the addr TNetBuf, // which we initialise to the address "www.apple.com:80" // (port 80 is the HTTP port). if (err == noErr) { OTMemzero(&sndCall, sizeof(TCall)); sndCall.addr.buf = (UInt8 *) &hostDNSAddress; sndCall.addr.len = OTInitDNSAddress(&hostDNSAddress, "www.apple.com:80"); err = OTConnect(ep, &sndCall, nil); } // Send the HTTP command to the web server. if (err == noErr) { (void) sprintf(httpGetCommand, "GET / HTTP/1.0%c%c%c%c", 13, 10, 13, 10); bytesSent = OTSnd(ep, (void *) httpGetCommand, OTStrLength(httpGetCommand), 0); // OTSnd returns the number of bytes sent. Because we're in // synchronous mode, it won't return until it's sent all the // bytes, or it gets an error. if (bytesSent > 0) { err = noErr; } else { err = bytesSent; } } // Now receive the response from the server and write it to the // destination file. if (err == noErr) { // No-copy receive does not really make sense in sync/blocking // mode, so we switch the endpoint to sync/non-blocking before. // proceeding. This is reasonable because you should not be using // no-copy receives unless you're looking for maximum speed, // and if you're looking for maximum speed you should be using // async/blocking mode, and doing everything in your notifier. // In this case, I'm just trying to demonstrate it's use, so // I make do with sync/non-blocking mode. junk = OTSetNonBlocking(ep); MoreAssert(junk == noErr);//Triggers if: TestNoCopyReceive: OTSetNonBlocking failed do { // Depending on which method we were asked to use, // call the relevant receive function. switch (method) { case kUsingOTReadBuffer: err = NoCopyReceiveUsingOTReadBuffer(ep, destFileRefNum); break; case kUseWalkingBufferChain: err = NoCopyReceiveWalkingBufferChain(ep, destFileRefNum); break; default: //OTDebugBreak("TestNoCopyReceive: What method?"); MoreAssert(false);//Triggers if: Get to this error path err = -1; break; } // If we get kOTNoDataErr, that means we're still waiting for data, // so we just clear the error and continue looping. if (err == kOTNoDataErr) { YieldingNotifier(nil, kOTSyncIdleEvent, noErr, nil); err = noErr; } } while (err == noErr); // We will eventually leave the above loop with a kOTLookErr // because the endpoint received either a T_ORDREL or T_DISCONNECT // event. Either way, the data transfer is finished, so // we can just clear the error code and continue. if (err == kOTLookErr) { err = noErr; } } // I'm not going to bother cleaning up the endpoint cleanly. // This is the subject of another sample. For this sample, force // closing the endpoint is good enough. // \x82lean up. if (ep != kOTInvalidEndpointRef) { junk = OTCloseProvider(ep); MoreAssert(junk == noErr);//Triggers if: TestNoCopyReceive: OTCloseProvider failed } return err;}/////////////////////////////////////////////////////////////////////int main(void) // The main line of the sample program. It creates // a file in the same directory as the sample called // "NoCopyReceive Test Output" and puts two copies // of the root HTTP object from "www.apple.com" into // that file.{ OSStatus err; OSStatus junk; FSSpec fss; SInt16 destFileRefNum; #if defined(__MWERKS__) SIOUXSettings.autocloseonquit = FALSE; // don't close the SIOUX window on program termination SIOUXSettings.asktosaveonclose = FALSE; // don't offer to save on a close#endif printf("NoCopyReceives\n"); printf("-- Download a URL using no-copy receives\n"); printf("\n"); err = InitOpenTransportInContext(kInitOTForApplicationMask, nil); if (err == noErr) { // Create and open the output file. (void) FSMakeFSSpec(0, 0, "\pNoCopyReceives_Output.txt", &fss); (void) FSpCreate(&fss, 'R*ch', 'TEXT', 0); err = FSpOpenDF(&fss, fsRdWrPerm, &destFileRefNum); // Download two copies of the URL, one using the OTReadBuffer // method, the other by the buffer walking method. if (err == noErr) { printf("Downloading using OTReadBuffer method"); err = TestNoCopyReceive(kUsingOTReadBuffer, destFileRefNum); printf("\n\n"); if (err == noErr) { printf("Downloading using 'walk the buffer chain' method"); err = TestNoCopyReceive(kUseWalkingBufferChain, destFileRefNum); printf("\n\n"); } // Close the file. junk = FSClose(destFileRefNum); MoreAssert(junk == noErr);//Triggers if: TestNoCopyReceive: FSClose failed } CloseOpenTransportInContext(nil); } if (err == noErr) { printf("Success.\n"); } else { printf("Failed with error %ld.\n", err); } printf("Done.\n"); return(0);}</pre>
<!--googleoff: index -->
</td>
</tr>
</table>
<!-- END WIDE COLUMN -->
<!-- END MAIN CONTENT -->
<table width="680" border="0" cellpadding="0" cellspacing="0">
<tr>
<td><div style="width: 100%; height: 1px; background-color: #919699; margin-top: 5px; margin-bottom: 15px"></div></td>
</tr>
<tr>
<td align="center"><br/>
<table border="0" cellpadding="0" cellspacing="0" class="graybox">
<tr>
<th>Did this document help you?</th>
</tr>
<tr>
<td>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=1&url=/samplecode/NoCopyReceives/listing1.html%3Fid%3DDTS10000704-1.0&media=dvd" target=_new>Yes</a>: Tell us what works for you.</div>
<div style="margin-bottom: 8px"><a href="http://developer.apple.com/feedback/?v=2&url=/samplecode/NoCopyReceives/listing1.html%3Fid%3DDTS10000704-1.0&media=dvd" target=_new>It’s good, but:</a> Report typos, inaccuracies, and so forth.</div>
<div><a href="http://developer.apple.com/feedback/?v=3&url=/samplecode/NoCopyReceives/listing1.html%3Fid%3DDTS10000704-1.0&media=dvd" target=_new>It wasn’t helpful</a>: Tell us what would have helped.</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- START BOTTOM APPLE NAVIGATION -->
<!--#include virtual="/includes/footer"-->
<!-- END BOTTOM APPLE NAVIGATION -->
<!-- START CENTER CLOSE -->
</center>
<!-- END CENTER CLOSE -->
</body>
</html>