📄 utils.c
字号:
** Reset the enumeration cursor to the beginning of the list.** Returns the newly reset iterator or NULL on error.*/ObxIterator *iobxIteratorReset( ObxIterator *iterator ) { OBXDBGFLOW(("iobxIteratorReset() entry, iterator=0x%08x\n", iterator)); if ( iterator ) { iterator->cursor = NULL; } return iterator;}/*** Free storage associated with the Iterator. Iterator should be considered** invalid after this call.*/void iobxIteratorFree( ObxIterator *iterator ) { OBXDBGFLOW(("iobxIteratorFree() entry, iterator=0x%08x\n", iterator)); if ( iterator ) { free( iterator ); iterator = NULL; }}/*** Requests the next element of data. If at the end of the list, list is empty** or the passed iterator is NULL, NULL is returned.*/void *iobxIteratorNext( ObxIterator *iterator ) { void *data = NULL; ObxListNode *tempListNode = NULL; OBXDBGFLOW(("iobxIteratorNext() entry, iterator=0x%08x\n", iterator)); if ( iterator ) { if ( iterator->cursor ) { iterator->cursor = iterator->cursor->next; if ( iterator->cursor ) { data = iterator->cursor->data; } else { // at end of list, let it return NULL } } else { if ( iterator->list->head ) { tempListNode = iterator->list->head; data = tempListNode->data; iterator->cursor = tempListNode; } else { // nothing in list, let it return null. } } } return data;}/*** Queries the existance of an element beyond the current element in** the list. Returns 0 if one does not exist, non-zero otherwise.*/short iobxIteratorHasNext( ObxIterator *iterator ) { short hasMore = 0; OBXDBGFLOW(("iobxIteratorHasNext() entry, iterator=0x%08x\n", iterator)); if ( iterator->cursor ) { if ( iterator->cursor->next != NULL ) { hasMore = 1; } else { // list not empty, but at the end. } } else { if ( iterator->list->head != NULL ) { hasMore = 1; } else { // list was empty. } } return hasMore;}/* **************************************** *//* **** Misc and Converstion Functions **** *//* **************************************** *//*** Converts the passed unicode buffer to UTF8.** The result is present in the ObxBuffer structure returned.** NULL is returned on error.*/ObxBuffer *iobxUnicodeToUTF8( const unsigned char *unicodeBuffer, int unicodeLength ) { ObxBuffer *buffer = NULL; unsigned char utfchars[3]; int utflen; unsigned char *cursor = (unsigned char *)unicodeBuffer; int length = unicodeLength; int unichar; OBXDBGFLOW(("iobxUnicodeToUTF8() entry\n")); OBXDBGMEM(("iobxUnicodeToUTF8()", (void*)unicodeBuffer, unicodeLength)); /* ** Probable length of required buffer is unicodeLength/2... ** but the buffer will grow if needed. */ if ( (buffer = iobxBufNew( length / 2 )) ) { while ( length ) { /* ** Form a unicode char, advance cursor, reduce remaining length. */ unichar = cursor[0] << 8 | cursor[1]; cursor += 2; length -= 2; /* ** Figure out how many output bytes we need, and convert the Unicode ** character into that many bytes of UTF-8. We assume our unicode ** doesn't contain any chars in the range D800 - DFFF, which are ** really ucs-4 chars mapped to ucs-2. */ if ( unichar < 0x80 ) { utflen = 1; utfchars[0] = unichar; } else if ( unichar < 0x800 ) { utflen = 2; utfchars[0] = 0xC0 | (unichar >> 6); utfchars[1] = 0x80 | (unichar & 0x3F); } else { utflen = 3; utfchars[0] = 0xE0 | (unichar >> 12); utfchars[1] = 0x80 | ((unichar >> 6) & 0x3F); utfchars[2] = 0x80 | (unichar & 0x3F); } /* ** Toss in ObxBuffer */ iobxBufWrite( buffer, utfchars, utflen ); } } return buffer;}/*** Converts the passed buffer, which points to a null terminated** UTF8 string to Unicode. The result is present in the ObxBuffer structure** returned. NULL is returned on error.*/ObxBuffer *iobxUTF8ToUnicode( const unsigned char *utf8Buffer, int utf8Length ) { ObxBuffer *buffer = NULL; int length = utf8Length; unsigned char unibytes[2]; int unichar; unsigned char *cursor = (unsigned char *)utf8Buffer; OBXDBGFLOW(("iobxUTF8ToUnicode() entry\n")); OBXDBGMEM(("iobxUTF8ToUnicode()", (void*)utf8Buffer, utf8Length)); if ( (buffer = iobxBufNew( length * 2 )) ) { while ( length ) { /* ** Clear ucode char */ unichar = 0; /* ** What are we dealing with? */ if ( !(cursor[0] & 0x80) ) { /* single byte */ unichar = cursor[0]; cursor += 1; length -= 1; } else if ( (cursor[0] & 0xE0) == 0xC0 ) { /* double byte */ unichar = ((cursor[0] & 0x1F) << 6) | (cursor[1] & 0x3F); cursor += 2; length -= 2; } else { /* triple byte */ unichar = ((cursor[0] & 0x0F) << 12) | ((cursor[1] & 0x3F) << 6) | (cursor[2] & 0x3F); cursor += 3; length -= 3; } /* ** Toss in ObxBuffer */ unibytes[0] = (unichar >> 8) & 0xFF; unibytes[1] = unichar & 0xFF; iobxBufWrite( buffer, unibytes, sizeof(unibytes) ); } } return buffer;}/*** Parse meta info (stolen from the code base of jph)*/const char *iobxGetMetaInfoValue( const char *metaInformation, const char *tag, size_t *valueLen ) {#define DELIMITERS " \t" const char *p, *vs, *ve; int found = 0; OBXDBGFLOW(("iobxGetMetaInfoValue() entry, meta='%s'\ttag='%s'\n" ,metaInformation, tag )); p = metaInformation; do { const char *ts, *te; // Skip over delimiters (the strspn() function would be handy here) for (ts=p; *ts && strchr(DELIMITERS, *ts); ++ts) ; if (!*ts) break; // We've hit the end of the string // The variable p now points to the start of a tag name. Find the end. // The strpbrk() function would be handy here... for (te=ts; *te && !strchr(DELIMITERS "=", *te); ++te) ; // The variable end now points just beyond the last char of the tag name. // Find the beginning and end of the value (if any). if (*te != '=') { // If the keyword ends with anything but '=', there's no value. p = vs = ve = te; } else { vs = te + 1; // Tolerate a quoted (single or double) string as well for the value if (*vs == '"' || *vs == '\'') { int q = *vs; ve = strchr(++vs, q); if (ve) { p = ve + 1; } else { // Missing end quote is terminated by end of string ve = strchr(vs, '\0'); p = ve; } } else { // No quotes. Find next delimiter (end of word) for (ve=vs; *ve && !strchr(DELIMITERS, *ve); ++ve) ; p = ve; // For next time through the loop } } // See if this is the tag we care about#ifdef _WIN32 // luz %%%: memicmp doesn't exist! //found = te-ts == strlen(tag) && !memicmp(tag, ts, te-ts); found = te-ts == (int) strlen(tag) && !strnicmp(tag, ts, te-ts);#else found = te-ts == strlen(tag) && !strncmp(tag, ts, te-ts); /* TO DO, write case insensitive version */#endif } while (!found && *p); if (!found) return NULL; *valueLen = ve-vs; return vs;}#undef DELIMITERS/*** Load the inbound peerSocket structure (allocated by caller) with the required** info using the provided name.** Returns OBEX_RC_xxxx ( see obexError.h for return codes )** On success, peerSocket structure is filled in.*/ObxRc iobxGetPeerAddr( const char *hostname, struct sockaddr_in *addr ) { ObxRc rc = OBX_RC_OK; struct hostent *host; OBXDBGFLOW(("iobxGetPeerAddr() entry, hostname='%s'\taddr=0x%08x\n", hostname, addr )); if ( hostname && addr ) { // First try translating it as a dotted-decimal IP address addr->sin_addr.s_addr = inet_addr( hostname ); if ( addr->sin_addr.s_addr != INADDR_NONE ) { return OBX_RC_OK; } else { if ( !(host = gethostbyname( hostname )) ) { OBXDBGERR(("[ERROR] iobxGetPeerAddr() gethostbyname() fails.\n")); return OBX_RC_ERR_SOCKET; } addr->sin_addr = *(struct in_addr *) host->h_addr; } } else { OBXDBGERR(("[ERROR] iobxGetPeerAddr() Bad plist on call\n")); rc = OBX_RC_ERR_BADPLIST; } return rc;}/****/#ifdef _WIN32void _initializeSockets( void ) { WORD requestedVersion = MAKEWORD(1, 1); /* Version 1.1 */ WSADATA wsaData; /* Buffer for startup data */ /* If the DLL only supports higher levels than we do, give up */ if ( WSAStartup(requestedVersion, &wsaData) ) { fprintf(stderr, "The available sockets DLL only supports higher" " levels of the WINSOCK API than those supported by us.\n"); exit(1); } /* If the DLL doesn't support the version we requested, give up. */ if ( wsaData.wVersion != requestedVersion ) { WSACleanup(); /* We're "done" using sockets */ fprintf(stderr, "The available sockets DLL does not support the" " WINSOCK API version required by us.\n"); exit(1); }}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -