UTILS.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:14k
源码类别:
Windows编程
开发平台:
Visual C++
- /******************************************************************************
- * This is a part of the Microsoft Source Code Samples.
- * Copyright (C) 1993-1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- ******************************************************************************/
- /****************************** Module Header *******************************
- * Module Name: UTILS.C
- *
- * standard file-reading utilities.
- *
- * Functions:
- *
- * readfile_new()
- * readfile_next()
- * readfile_delete()
- * utils_CompPath()
- * has_string()
- * utils_isblank()
- * StringInput()
- * dodlg_stringin()
- *
- * Comments:
- *
- ****************************************************************************/
- #include <windows.h>
- #include <stdlib.h>
- #include <string.h>
- #include "gutils.h"
- #include "gutilsrc.h"
- /*
- * we need an instance handle. this should be the dll instance
- */
- extern HANDLE hLibInst;
- /*
- * -- forward declaration of procedures -----------------------------------
- */
- int FAR PASCAL dodlg_stringin(HWND hDlg, UINT message, UINT wParam, LONG lParam);
- /*-- readfile: buffered line input ------------------------------*/
- /*
- * set of functions to read a line at a time from a file, using
- * a buffer to read a block at a time from the file
- *
- */
- /*
- * a FILEBUFFER handle is a pointer to a struct filebuffer
- */
- struct filebuffer {
- int fh; /* open file handle */
- PSTR start; /* offset within buffer of next character */
- PSTR last; /* offset within buffer of last valid char read in */
- char buffer[512];
- };
- /***************************************************************************
- * Function: readfile_new
- *
- * Purpose:
- *
- * Initialise a filebuffer and return a handle to it
- */
- FILEBUFFER APIENTRY
- readfile_new(int fh)
- {
- FILEBUFFER fbuf;
- fbuf = (FILEBUFFER) LocalLock(LocalAlloc(LHND, sizeof(struct filebuffer)));
- if (fbuf == NULL) {
- return(NULL);
- }
- fbuf->fh = fh;
- fbuf->start = fbuf->buffer;
- fbuf->last = fbuf->buffer;
- /* return file pointer to beginning of file */
- _llseek(fh, 0, 0);
- return(fbuf);
- }
- /***************************************************************************
- * Function: readfile_next
- *
- * Purpose:
- *
- * Get the next line from a file. Returns a pointer to the line
- * in the buffer - so copy it before changing it.
- *
- * The line is *not* null-terminated. *plen is set to the length of the
- * line.
- */
- LPSTR APIENTRY
- readfile_next(FILEBUFFER fbuf, int FAR * plen)
- {
- PSTR cstart;
- /* look for an end of line in the buffer we have*/
- for (cstart = fbuf->start; cstart < fbuf->last; cstart++) {
- if (*cstart == 'n') {
- *plen = (cstart - fbuf->start) + 1;
- cstart = fbuf->start;
- fbuf->start += *plen;
- return(cstart);
- }
- }
- /* no cr in this buffer - this buffer contains a partial line.
- * copy the partial up to the beginning of the buffer, and
- * adjust the pointers to reflect this move
- */
- Old_strncpy(fbuf->buffer, fbuf->start, fbuf->last - fbuf->start);
- fbuf->last = &fbuf->buffer[fbuf->last - fbuf->start];
- fbuf->start = fbuf->buffer;
- /* read in to fill the block */
- fbuf->last += _lread(fbuf->fh, fbuf->last,
- &fbuf->buffer[sizeof(fbuf->buffer)] - fbuf->last);
- /* look for an end of line in the newly filled buffer */
- for (cstart = fbuf->start; cstart < fbuf->last; cstart++) {
- if (*cstart == 'n') {
- *plen = (cstart - fbuf->start) + 1;
- cstart = fbuf->start;
- fbuf->start += *plen;
- return(cstart);
- }
- }
- /* still no end of line. either the buffer is empty -
- * because of end of file - or the line is longer than
- * the buffer. in either case, return all that we have
- */
- *plen = fbuf->last - fbuf->start;
- { // for JAPAN (nChars != nBytes)
- PSTR ptr;
- for(ptr=fbuf->start;ptr<fbuf->last;ptr++) ;
- if(ptr!=fbuf->last && *plen) {
- --(*plen);
- --(fbuf->last);
- _llseek(fbuf->fh,-1,1);
- }
- }
- cstart = fbuf->start;
- fbuf->start += *plen;
- if (*plen == 0) {
- return(NULL);
- } else {
- return(cstart);
- }
- }
- /***************************************************************************
- * Function: readfile_delete
- *
- * Purpose:
- *
- * Delete a FILEBUFFER - close the file handle and free the buffer
- */
- void APIENTRY
- readfile_delete(FILEBUFFER fbuf)
- {
- _lclose(fbuf->fh);
- LocalUnlock(LocalHandle( (PSTR) fbuf));
- LocalFree(LocalHandle( (PSTR) fbuf));
- }
- /* ----------- things for strings-------------------------------------*/
- /*
- * Compare two pathnames, and if not equal, decide which should come first.
- * Both path names should be lower cased by AnsiLowerBuff before calling.
- *
- * Returns 0 if the same, -1 if left is first, and +1 if right is first.
- *
- * The comparison is such that all filenames in a directory come before any
- * file in a subdirectory of that directory.
- *
- * Given directthisfile v. directsubdirthatfile, we take
- * thisfile < thatfile even though it is second alphabetically.
- * We do this by picking out the shorter path
- * (fewer path elements), and comparing them up till the last element of that
- * path (in the example: compare the 'dir' in both cases.)
- * If they are the same, then the name with more path elements is
- * in a subdirectory, and should come second.
- *
- * We have had trouble with apparently multiple collating sequences and
- * the position of in the sequence. To eliminate this trouble
- * a. EVERYTHING is mapped to lower case first (actually this is done
- * before calling this routine).
- * b. All comparison is done by using lstrcmpi with two special cases.
- * 1. Subdirs come after parents as noted above
- * 2. must compare low so that fred2x > fredx in the same way
- * that fred2 < fred. Unfortunately in ANSI '2' < '\'
- *
- */
- int APIENTRY
- utils_CompPath(LPSTR left, LPSTR right)
- {
- int compval; // provisional value of comparison
- if (left==NULL) return -1; // empty is less than anything else
- else if (right==NULL) return 1; // anything is greater than empty
- for (; ; ) {
- if (*left==' ' && *right==' ') return 0;
- if (*left==' ') return -1;
- if (*right==' ') return 1;
- if (IsDBCSLeadByte(*left) || IsDBCSLeadByte(*right)) {
- if (*right != *left) {
- compval = (*left - *right);
- break;
- }
- ++left;
- ++right;
- if (*right != *left) {
- compval = (*left - *right);
- break;
- }
- ++left;
- ++right;
- } else {
- if (*right==*left) {++left; ++right; continue;}
- if (*left=='\') {compval = -1; break;}
- if (*right=='\') {compval = 1; break;}
- compval = (*left - *right);
- break;
- }
- }
- /* We have detected a difference. If the rest of one
- of the strings (including the current character) contains
- some characters, but the other one does not, then all
- elements up to the last element of the one with the fewer
- elements are equal and so the other one lies in a subdir
- and so compares greater i.e. xyf > xf
- Otherwise compval tells the truth.
- */
- left = strchr(left, '\');
- right = strchr(right, '\');
- if (left && !right) return 1;
- if (right && !left) return -1;
- return compval;
- } /* utils_CompPath */
- /***************************************************************************
- * Function: hash_string
- *
- * Purpose:
- *
- * Generate a hashcode for a null-terminated ascii string.
- *
- * If bIgnoreBlanks is set, then ignore all spaces and tabs in calculating
- * the hashcode.
- *
- * Multiply each character by a function of its position and sum these.
- * The function chosen is to multiply the position by successive
- * powers of a large number.
- * The large multiple ensures that anagrams generate different hash
- * codes.
- */
- DWORD APIENTRY
- hash_string(LPSTR string, BOOL bIgnoreBlanks)
- {
- #define LARGENUMBER 6293815
- DWORD sum = 0;
- DWORD multiple = LARGENUMBER;
- int index = 1;
- while (*string != ' ') {
- if (bIgnoreBlanks) {
- while ( (*string == ' ') || (*string == 't')) {
- string = CharNext(string);
- }
- }
- sum += multiple * index++ * (*string++);
- multiple *= LARGENUMBER;
- }
- return(sum);
- }
- /***************************************************************************
- * Function: utils_isblank
- *
- * Purpose:
- *
- * Return TRUE iff the string is blank. Blank means the same as
- * the characters which are ignored in hash_string when ignore_blanks is set
- */
- BOOL APIENTRY
- utils_isblank(LPSTR string)
- {
- while ( (*string == ' ') || (*string == 't')) {
- string = CharNext(string);
- }
- /* having skipped all the blanks, do we see the end delimiter? */
- return (*string == ' ' || *string == 'r' || *string == 'n');
- }
- /* --- simple string input -------------------------------------- */
- /*
- * static variables for communication between function and dialog
- */
- LPSTR dlg_result;
- int dlg_size;
- LPSTR dlg_prompt, dlg_default, dlg_caption;
- /***************************************************************************
- * Function: StringInput
- *
- * Purpose:
- *
- * Input of a single text string, using a simple dialog.
- *
- * Returns TRUE if ok, or FALSE if error or user canceled. If TRUE,
- * puts the string entered into result (up to resultsize characters).
- *
- * Prompt is used as the prompt string, caption as the dialog caption and
- * default as the default input. All of these can be null.
- */
- int APIENTRY
- StringInput(LPSTR result, int resultsize, LPSTR prompt, LPSTR caption,
- LPSTR def_input)
- {
- DLGPROC lpProc;
- BOOL fOK;
- /* copy args to static variable so that winproc can see them */
- dlg_result = result;
- dlg_size = resultsize;
- dlg_prompt = prompt;
- dlg_caption = caption;
- dlg_default = def_input;
- lpProc = (DLGPROC)MakeProcInstance((WNDPROC)dodlg_stringin, hLibInst);
- fOK = DialogBox(hLibInst, "StringInput", GetFocus(), lpProc);
- FreeProcInstance((WNDPROC)lpProc);
- return(fOK);
- }
- /***************************************************************************
- * Function: dodlg_stringin
- *
- */
- int FAR PASCAL
- dodlg_stringin(HWND hDlg, UINT message, UINT wParam, LONG lParam)
- {
- switch(message) {
- case WM_INITDIALOG:
- if (dlg_caption != NULL) {
- SendMessage(hDlg, WM_SETTEXT, 0, (LONG) dlg_caption);
- }
- if (dlg_prompt != NULL) {
- SetDlgItemText(hDlg, IDD_LABEL, dlg_prompt);
- }
- if (dlg_default) {
- SetDlgItemText(hDlg, IDD_FILE, dlg_default);
- }
- return(TRUE);
- case WM_COMMAND:
- switch(GET_WM_COMMAND_ID(wParam, lParam)) {
- case IDCANCEL:
- EndDialog(hDlg, FALSE);
- return(TRUE);
- case IDOK:
- GetDlgItemText(hDlg, IDD_FILE, dlg_result, dlg_size);
- EndDialog(hDlg, TRUE);
- return(TRUE);
- }
- }
- return (FALSE);
- }
- /***************************************************************************
- * Function: My_mbschr
- *
- * Purpose:
- *
- * DBCS version of strchr
- *
- */
- unsigned char * _CRTAPI1 My_mbschr(
- unsigned char *psz, unsigned short uiSep)
- {
- while (*psz != ' ' && *psz != uiSep) {
- psz = CharNext(psz);
- }
- return *psz == uiSep ? psz : NULL;
- }
- /***************************************************************************
- * Function: My_mbsncpy
- *
- * Purpose:
- *
- * DBCS version of strncpy
- *
- */
- unsigned char * _CRTAPI1 My_mbsncpy(
- unsigned char *psz1, const unsigned char *psz2, size_t Length)
- {
- int nLen = (int)Length;
- unsigned char *pszSv = psz1;
- while (0 < nLen) {
- if (*psz2 == ' ') {
- *psz1++ = ' ';
- nLen--;
- } else if (IsDBCSLeadByte(*psz2)) {
- if (nLen == 1) {
- *psz1 = ' ';
- } else {
- *psz1++ = *psz2++;
- *psz1++ = *psz2++;
- }
- nLen -= 2;
- } else {
- *psz1++ = *psz2++;
- nLen--;
- }
- }
- return pszSv;
- }
- /***************************************************************************
- * Function: LoadRcString
- *
- * Purpose: Loads a resource string from string table and returns a pointer
- * to the string.
- *
- * Parameters: wID - resource string id
- *
- */
- LPTSTR APIENTRY LoadRcString(UINT wID)
- {
- static TCHAR szBuf[512];
- LoadString((HANDLE)GetModuleHandle(NULL),wID,szBuf,sizeof(szBuf));
- return szBuf;
- }
- LPTSTR APIENTRY LoadRcString2(UINT wID)
- {
- static TCHAR szBuf[512];
- LoadString((HANDLE)GetModuleHandle(NULL),wID,szBuf,sizeof(szBuf));
- return szBuf;
- }