>lcString = STRTOFILE('somefile') >FOR xj = 1 TO LEN(lcString) > lcChar = SUBSTR(lcString,xj,1) > IF lcChar = 'Z' > && dosomething > ENDIF >ENDFOR >>
>#define MAX_DECOMPRESS_BUFFER 4096 >#define HEX_DIGIT(cChar) (cChar >= 'A' ? cChar - 'A' + 11 : cChar - '0') >void _fastcall Decompress_AL3(ParamBlk *parm) >{ > FCHAN hSource = -1, hDest = -1; > int nFileSize, nSize, nBuffSize, nCount, nErrorNo = 0, xj = 0; > BOOL bCallback = FALSE; > unsigned char *pInputBuff, *pOutputBuff, *pOutputPtr, *pInputPtr; > unsigned char cExpandChar; > VALUE(vContinue); > char aCallback[1024], aProgress[1024]; > > if (!NULLTERMINATE(p1) || !NULLTERMINATE(p2)) > RAISEERROR(E_INSUFMEMORY); > > if (PCOUNT() == 3 && !NULLTERMINATE(p3)) > RAISEERROR(E_INSUFMEMORY); > >// callback function may not be longer than 768 chars > if (PCOUNT() == 3 && p3.ev_length >= 768) > RAISEERROR(E_INVALIDPARAMS); > > LOCKHAND(p1); > LOCKHAND(p2); > if (PCOUNT() == 3) > { > LOCKHAND(p3); > // build callback command > strcpy(aCallback,HANDTOPTR(p3)); > strcat(aCallback,"(%I)"); > bCallback = TRUE; > } > > vContinue.ev_length = TRUE; > > hSource = _FOpen(HANDTOPTR(p1),FO_READONLY); > if (hSource == -1) > { > nErrorNo = _FError(); > goto ErrorOut; > } > > hDest = _FCreate(HANDTOPTR(p2),FC_NORMAL); > if (hDest == -1) > { > nErrorNo = _FError(); > goto ErrorOut; > } > > nFileSize = nSize = _FSeek(hSource,0,FS_FROMEOF); > _FSeek(hSource,0,FS_FROMBOF); > > pInputBuff = malloc(MAX_DECOMPRESS_BUFFER); > pOutputBuff = malloc(MAX_DECOMPRESS_BUFFER / 4 * 256); > // maximum uncompressed size of MAX_DECOMPRESS_BUFFER bytes is: > // MAX_DECOMPRESS_BUFFER / 4 bytes (CHR(250) + 2 hexchars + chartoexpand) * maximum expansion of one char (256) > > if (!pInputBuff || !pOutputBuff) > { > nErrorNo = E_INSUFMEMORY; > goto ErrorOut; > } > > while (nSize) > { > if (nSize > MAX_DECOMPRESS_BUFFER) > nBuffSize = MAX_DECOMPRESS_BUFFER; > else > nBuffSize = nSize; > > nSize -= nBuffSize; > > nBuffSize = _FRead(hSource,pInputBuff,nBuffSize); > > pInputPtr = pInputBuff; > pOutputPtr = pOutputBuff; > > while (nBuffSize--) > { > if (*pInputPtr == 250) > { > // we need the next 3 chars at least to decompress > if (nBuffSize >= 3) > { > pInputPtr++; > nCount = HEX_DIGIT(*pInputPtr) * 16; > pInputPtr++; > nCount += HEX_DIGIT(*pInputPtr); > pInputPtr++; > cExpandChar = *pInputPtr++; > pOutputPtr = ReplicateEx(pOutputPtr,cExpandChar,nCount); > nBuffSize -= 3; > } > else > { > if (nSize) > { > // special case when the buffer contains an incomplete decompression command at the end > // seek back to beginning of decompression command > nBuffSize++; // inc nBuffSize cause it contains 1 less (while (nBuffSize--)) > _FSeek(hSource,-nBuffSize,FS_RELATIVE); > nSize += nBuffSize; // add the bytes to the remaining size > nBuffSize = 0; // set to 0 to stop while loop > } > else > { > // file contained incomplete decompression command at the end. raise some error > nErrorNo = E_INVALIDPARAMS; > goto ErrorOut; > } > } > } > else > *pOutputPtr++ = *pInputPtr++; > } > > _FWrite(hDest,pOutputBuff,pOutputPtr-pOutputBuff); > > // flush after each 10th buffer > if (++xj % 10 == 0) > _FFlush(hDest); > > if (bCallback) > { > sprintfex(aProgress,aCallback,nFileSize-nSize); > if (nErrorNo = EVALUATE(vContinue,aProgress)) > goto ErrorOut; > > if (!vContinue.ev_length) > break; > } > } > > _FClose(hSource); > _FClose(hDest); > free(pInputBuff); > free(pOutputBuff); > UNLOCKHAND(p1); > UNLOCKHAND(p2); > if (PCOUNT() == 3) > UNLOCKHAND(p3); > RET_LOGICAL(vContinue.ev_length); > return; > > ErrorOut: > UNLOCKHAND(p1); > UNLOCKHAND(p2); > if (PCOUNT() == 3) > UNLOCKHAND(p3); > if (hSource != -1) > _FClose(hSource); > if (hDest != -1) > _FClose(hDest); > if (pInputBuff) > free(pInputBuff); > if (pOutputBuff) > free(pOutputBuff); > RAISEERROR(nErrorNo); >} > >char * _stdcall ReplicateEx(char *pBuffer, char pExpr, int nCount) >{ > while (nCount--) > *pBuffer++ = pExpr; > return pBuffer; >} >>