📄 napi.c
字号:
/********************************************************************* FILE: WWW.c** DESCRIPTION: INetLib Wrapper** VERSION: 1.0* NOTE: Portions of this code taken from Palm, Inc's InetLib-1* InetLow.c sample code and refactored to fit our * interfaces.**********************************************************************/#include <PalmOS.h>#include <PalmCompatibility.h>#include <INetMgr.h>#include <CTP.h>#include "Utils.h"#include "nAPI.h"#include "nAPIrsrc.h"#include "nAPIpriv.h"struct _WWWinstance wwwInstance;// Panel sizeconst RectangleType configRect = { 0, 80, 160, 80 };// status text messagesChar *wwwStatusMsg[] = { "Huh?", "Opening...", "Connecting...", "Downloading...", "Complete.", "Error..." };/*********************************************************************** * * The INETLIB Interface * ***********************************************************************//*********************************************************************** * * FUNCTION: INetStart * * DESCRIPTION: This routine starts and initializes the INetLib, after * first checking for the presence of INetLib. * * PARAMETERS: void * * RETURNED: An error or 0 if all went well. * * REVISION HISTORY: * ***********************************************************************/static Err INetStart(void){ Err error = 0; UInt16 libRefNum = 0; // Reference # of the loaded INet lib. Handle inetH = 0; // Handle set from INetLibOpen. UInt32 value = 0; // Value of the feature requested.// Check if INetLib is installed: error = FtrGet(inetLibFtrCreator, inetFtrNumVersion, &value);// Find the INet library reference number: if (!error && value) // Note: A non-zero error means the INetLib isn't loaded. error = SysLibFind("INet.lib", &libRefNum);// Open and initialize INetLib: if (!error) {// Set the configuration values: INetConfigNameType cfgName = { inetCfgNameCTPDefault }; // Same as used by Clipper. UInt16 cfgIndex = 0; // Just an initialization.// Use wireline if we're asked to. if ( WWWUseWireline() ) { MemMove( &cfgName, &inetCfgNameCTPWireline, sizeof( INetConfigNameType ) ); }// Get the configuration index to pass to INetLibOpen(): error = INetLibConfigIndexFromName(libRefNum, &cfgName, &cfgIndex); if (error)// Couldn't find the requested configuration, so ...// Note: error code is:// inetErrConfigNotFound ;// Open INetLib: error = INetLibOpen(libRefNum, cfgIndex, 0, // Flags not used. NULL, // Not using a cache. 0, // Max cache size of 0 (no cache). &inetH); if (error)// Hmmm, so ...// Note: error codes are:// inetErrTooManyClients - Too many clients opened// already.// inetErrIncompatibleInterface - The net library is// already open with an// incompatible interface. ; // Initialize the INetLib: error = INetInit(libRefNum, &inetH); if (error)// Hmmm... ; } return error;} // End INetStart(void)/*********************************************************************** * * FUNCTION: INetInit * * DESCRIPTION: This routine is used to initialize the INetLib opened by * INetLibOpen. * * PARAMETERS: libRefNum - The INetLib reference number. * inetHP - Pointer to the INetLib handle. * * RETURNED: A value of 0 if all went well. * * REVISION HISTORY: * ***********************************************************************/static Err INetInit(UInt16 libRefNum, Handle* inetHP){ Err error = 0; INetLowInfoType inetInfoBlock;// Initialize the inet information block:// Note: MemSet always returns 0, but perhaps it will someday// return an error value. error = MemSet(&inetInfoBlock, sizeof(inetInfoBlock), 0); if (inetHP != NULL) {// Initialize the inet information store: inetInfoBlock.inetRefNum = libRefNum; inetInfoBlock.inetHan = *inetHP; inetInfoBlock.inetSockH = 0; inetInfoBlock.downloadSize = MAX_RESPONSE_SIZE; // Max response size accepted. inetInfoBlock.includeHeaders = false; // Default is not to include the response headers. inetInfoBlock.inetLowConvAlgorithm = ctpConvNone; // Default. // No translation of data // coming from destination // server as default. error = INetInfo(&inetInfoBlock, MESG_SET);// Set the max download size if (!error) error = INetLibSettingSet(inetInfoBlock.inetRefNum, inetInfoBlock.inetHan, inetSettingMaxRspSize, (BytePtr)&inetInfoBlock.downloadSize, sizeof(inetInfoBlock.downloadSize)); if (!error)// Set the default conversion algorithm: error = INetLibSettingSet(inetInfoBlock.inetRefNum, inetInfoBlock.inetHan, inetSettingConvAlgorithm, (BytePtr)&inetInfoBlock.inetLowConvAlgorithm, sizeof(inetInfoBlock.inetLowConvAlgorithm)); } else// Set to an informative error code or manage the error in some// way: error = 1; return (error);} // End INetInit(UInt16,Handle*)/*********************************************************************** * FUNCTION: INetShowIndicator * * DESCRIPTION: Shows the wireless indicator * * RETURNED: noErr on success, or error code. * ***********************************************************************/void INetShowIndicator( void){// Initialization of the wireless strength indicator: INetLowInfoType inetInfoBlock; INetInfo(&inetInfoBlock, MESG_GET); INetLibWiCmd(inetInfoBlock.inetRefNum, wiCmdInit, 0, 0); INetLibWiCmd(inetInfoBlock.inetRefNum, wiCmdSetLocation, DIALOG_WIN_X, DIALOG_WIN_Y); INetLibWiCmd(inetInfoBlock.inetRefNum, wiCmdSetEnabled, true, 0);}/*********************************************************************** * FUNCTION: INetHideIndicator * * DESCRIPTION: Shows the wireless indicator * * RETURNED: noErr on success, or error code. * ***********************************************************************/void INetHideIndicator( void){// Hide the wireless strength indicator: INetLowInfoType inetInfoBlock; INetInfo(&inetInfoBlock, MESG_GET); INetLibWiCmd(inetInfoBlock.inetRefNum, wiCmdSetEnabled, false, 0);}/*********************************************************************** * * FUNCTION: INetInfo * * DESCRIPTION: This routine is used to retain the INetLib handle and * reference number provided by INetLibOpen, the socket * handle provided by INetLibSockOpen, and various other * info related to use of the INetLib. * * PARAMETERS: Note: A zero (0) or NULL argument means not to perform * the requested action on that datum. * * inetInfoP - Pointer to a structure holding the INetLow * information, such as the INetLib reference * number, INetLib handle, INetLib socket * handle, etc. * message - The message by which the action to take is * determined. Accepted messages: * get * set * * RETURNED: An error or 0 if all went well. * * REVISION HISTORY: * ***********************************************************************/static Err INetInfo(INetLowInfoPtr inetInfoP, Mesg message){ Err error = 0; static Boolean firstRun = true; // For initializing struct only once. static INetLowInfoType inetInfo;// Initialize the store with zeros (0) only on first call of function: if (firstRun && inetInfoP != NULL) {// Note: MemSet always returns 0, but perhaps it will someday// return an error value. error = MemSet(&inetInfo, sizeof(INetLowInfoType), 0); firstRun = false; }// Perform required action - (get or set some data): switch ( message ) { case MESG_GET: if (inetInfoP) { inetInfoP->inetRefNum = inetInfo.inetRefNum; inetInfoP->inetHan = inetInfo.inetHan; inetInfoP->inetSockH = inetInfo.inetSockH; inetInfoP->downloadSize = inetInfo.downloadSize; inetInfoP->requestSize = inetInfo.requestSize; inetInfoP->inetLowConvAlgorithm = inetInfo.inetLowConvAlgorithm; inetInfoP->includeHeaders = inetInfo.includeHeaders; } break; case MESG_SET: if (inetInfoP) { inetInfo.inetRefNum = inetInfoP->inetRefNum; inetInfo.inetHan = inetInfoP->inetHan; inetInfo.inetSockH = inetInfoP->inetSockH; inetInfo.downloadSize = inetInfoP->downloadSize; inetInfo.requestSize = inetInfoP->requestSize; inetInfo.inetLowConvAlgorithm = inetInfoP->inetLowConvAlgorithm; inetInfo.includeHeaders = inetInfoP->includeHeaders; } break; case MESG_INVALID: default: error = MESG_INVALID; } return error;} // End INetInfo(INetLowInfoPtr,CharPtr)/*********************************************************************** * * FUNCTION: INetGo * * DESCRIPTION: This routine performs the primary connection function for * sending a request. * * PARAMETERS: Note: A zero (0) or NULL argument means not to perform the * requested action on that datum. * * urlP - Pointer to the URL string to use for sending * a request. * dataP - Pointer to any data to be included as part of * the POST body. * timeout - The time in seconds to wait for a response * before giving up. * * RETURNED: An error, or 0 if all went well. * * REVISION HISTORY: * ***********************************************************************/static Err INetGo(CharPtr urlP, CharPtr dataP, Int32 timeout){ INetURLType url; INetLowInfoType inetInfoBlock; UInt16 inetFlags = 0; // Won't use this, but you could set to use the cache, etc. CharPtr methodP = NULL; UInt32 dwSize = sizeof(UInt32); UInt16 attrIndex = 0; UInt16 flags = 0; UInt32 sockScheme = 0; UInt16 sockFlags = 0; UInt16 sockSchemeL = sizeof(sockScheme); UInt16 sockFlagsL = sizeof(sockFlags); Err error = 0; // Initialize the inet information block: MemSet(&inetInfoBlock, sizeof(inetInfoBlock), 0);// Initialze the URL variable: MemSet(&url, sizeof(url), 0);// Get the library ref number, inet handle, socket handle, and// flags from storage: error = INetInfo(&inetInfoBlock, MESG_GET ); if (!error && inetInfoBlock.inetRefNum && inetInfoBlock.inetHan && urlP) {// Clean-up from any previous request: if (inetInfoBlock.inetSockH) { error = INetEndTransaction(); inetInfoBlock.inetSockH = 0; } /* This section of code can be used instead of the calls as indicated in the commentary for INetLibURLOpen(), to include the setting of the methodP, as INetLibURLOpen() can only be used with the GET method. One might wish to use INetLibURLOpen() when using the protocols mailto, file, palm, and palmcall, or simply when there is no need for the using POST method and there isn't a need for some of the finer control offered by using the lower level calls. // For simplistic GET method you can use INetLibURLOpen(): // INetLibURLOpen() does the following: // INetLibURLCrack() // INetLibSockOpen() // INetLibHTTPReqCreate() - using GET method // INetLibHTTPReqSend() error = INetLibURLOpen( inetInfoBlock.inetRefNum, inetInfoBlock.inetHan, (BytePtr) urlP, NULL, // don't need to index in cache &inetInfoBlock.inetSockH, -1, flags); // Save the socket handle for later use: if (!error) error = INetInfo(&inetInfoBlock, "set"); */ if (!error) {// Set the conversion algorithm error = INetLibSettingSet(inetInfoBlock.inetRefNum, inetInfoBlock.inetHan, inetSettingConvAlgorithm, (BytePtr)&inetInfoBlock.inetLowConvAlgorithm, sizeof(inetInfoBlock.inetLowConvAlgorithm)); }// Set the HTTP(S) method: if (!dataP) methodP = "GET"; else methodP = "POST"; // Break the given URL into components: if (!error) error = INetLibURLCrack(inetInfoBlock.inetRefNum, (BytePtr)urlP, &url); if (!error) error = (Err)(url.hostnameP == NULL);// Open a socket (remember a max of 4 is allowed open at any time): if (!error) error = INetLibSockOpen(inetInfoBlock.inetRefNum, inetInfoBlock.inetHan, url.schemeEnum, &inetInfoBlock.inetSockH);// Save the socket handle for later use: if (!error) error = INetInfo(&inetInfoBlock, MESG_SET);// Set the socket flags: if (!error) error = INetLibSockSettingSet(inetInfoBlock.inetRefNum, inetInfoBlock.inetSockH, inetSockSettingFlags, (VoidPtr)&inetFlags, sizeof(inetFlags));// Create an HTTP request: if (!error) error = INetLibSockHTTPReqCreate(inetInfoBlock.inetRefNum, inetInfoBlock.inetSockH, (BytePtr)methodP, (BytePtr)urlP, // url.hostnameP 0); // cacheIndexURLP);// Set the socket to include the HTTP headers in the response to// this request: if (!error && url.schemeEnum != inetSchemeHTTPS) { error = INetLibSockHTTPAttrSet(inetInfoBlock.inetRefNum, inetInfoBlock.inetSockH, inetHTTPAttrIncHTTP, attrIndex, (Byte*)&inetInfoBlock.includeHeaders, sizeof(inetInfoBlock.includeHeaders), flags); }// Initiate the sending of the HTTP request message:// Note: It is not necessary to have called INetLibSockConnect()// prior to calling INetLibSockHTTPReqSend(), as the latter// makes the call to the former for you.// Note: Instead of a timeout as the secs_to_wait * SysTicksPerSecond(),// you could also pass a wait forever ( -1 ). if (!error) error = INetLibSockHTTPReqSend(inetInfoBlock.inetRefNum, inetInfoBlock.inetSockH, (VoidPtr)dataP, dataP ? StrLen(dataP) : 0, // 0 if GET timeout);// Get the size of the request message as number of bytes: if (!error) error = INetLibSockHTTPAttrGet(inetInfoBlock.inetRefNum, inetInfoBlock.inetSockH, inetHTTPAttrReqSize, 0, (VoidPtr)&inetInfoBlock.requestSize, &dwSize);// Save the number of bytes sent for later use: if (!error) error = INetInfo(&inetInfoBlock,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -