void KMP_Matcher(char T[],char P[]) { int n = strlen(T); /* tresc */ int m = strlen(P); /* wzorzec */ int *pi; int i,q=0,licz=0; pi = CPF(P); for ( i = 1 ; i <= n ; i++ ) { while ( q>0 && P[q+1] != T[i] ) /* druga != drugiej */ q = pi[q]; if ( P[q+1] == T[i] ) q = q+1; if ( q+1 == m ) { licz = licz+1; q = pi[q]; } } printf("Wzorzec wystepuje %d razy\n",licz); }
int kmp(char pattern[PATTERN_SIZE], char input[STRING_SIZE], int32_t kmpNext[PATTERN_SIZE], int32_t n_matches[1]) { int32_t i, q; n_matches[0] = 0; CPF(pattern, kmpNext); q = 0; k1 : for(i = 0; i < STRING_SIZE; i++){ k2 : while (q > 0 && pattern[q] != input[i]){ q = kmpNext[q]; } if (pattern[q] == input[i]){ q++; } if (q >= PATTERN_SIZE){ n_matches[0]++; q = kmpNext[q - 1]; } } return 0; }
int kmp(char pattern[PATTERN_SIZE], char input[STRING_SIZE], int kmpNext[PATTERN_SIZE]) { int i, q; int outs; outs = 0; CPF(pattern, kmpNext); q = 0; k1 : for(i = 0; i < STRING_SIZE; i++){ k2 : while (q > 0 && pattern[q] != input[i]){ q = kmpNext[q]; } if (pattern[q] == input[i]){ q++; } if (q >= PATTERN_SIZE){ outs++; q = kmpNext[q - 1]; } } return outs; }
// Read the File Header.... int ReadHeader(V2_FILEHEADER *FileHeader, BYTE *fbuf, int bufsize) { int HeaderLen = 0, HdrOffset; char CreatedByProg[HDR_NAME_LEN +1], CreatedByVersion[HDR_VERS_LEN +1]; ULONG CalcHdrCheck = 0; BYTE *HdrBuf, *bpFileHeader = (BYTE *) FileHeader; // Find and process the Header: This could be a plain sfArk file, a self-extracting file or some other (invalid) file. // Also, it could be a sfArk V1 file, which we can't decompress, but should at least recognise. // We locate the header by looking for the string "sfArk" within the first HEADER_MAX_OFFSET bytes of the file // but because self-extractor code is likely to contain that string, we look for its final occurence // by searching backwards. // To speed things up, we first check at offset 0 (the case for a standard sfArk file) // If we think we've found a (V2) header, we veryify it using the Header checksum. If the checksum fails, // chances are it was a corrupt file, but could conceivably be a non-sfArk file. either way we report it as corrupt. int fbufsize = HEADER_MAX_OFFSET + V2_FILEHEADER_SIZE; // Amount data to read if (fbufsize > bufsize) fbufsize = bufsize; // Buffer too small (should never happen) SetInputFilePosition(0); // set to logical start (maybe a predefined offset) RETURN_ON_ERROR(); ReadInputFile(fbuf, fbufsize); // Read a chunk of data from the start of the file RETURN_ON_ERROR(); int SigFound = 0, SeemsV1 = 0, HdrCheckDone = 0; // Some flags to remember what we're doing for(int TryOffset = 0; TryOffset < HEADER_MAX_OFFSET; TryOffset++) { HdrOffset = (TryOffset == 0)? 0 : HEADER_MAX_OFFSET - TryOffset; // Check offset = 0 first, then backwards from end BYTE *sigpos = fbuf + HdrOffset + HEADER_SIG_POS; if (*sigpos != 's' || memcmp(sigpos, "sfArk", 5) != 0) continue; SigFound = 1; // Set a flag to remember that we at least got this far HdrBuf = fbuf + HdrOffset; if (V2_FILEHEADER_SIZE != sizeof(V2_FILEHEADER)) // Compare structure size to real size { // The compiler has messed with structure (alignment), so copy the data to the structure byte by byte... BYTE *bptr = HdrBuf; // Point to start // Copy all fields... #define CPF(f) memcpy(&(FileHeader->f), bptr, sizeof(FileHeader->f)); bptr += sizeof(FileHeader->f) CPF(Flags); CPF(OriginalSize); CPF(CompressedSize); CPF(FileCheck); CPF(HdrCheck); CPF(ProgVersionNeeded); CPF(ProgVersion); CPF(ProgName); CPF(CompMethod); CPF(FileType); CPF(AudioStart); CPF(PostAudioStart); CPF(FileName); #undef CPF if (bptr != HdrBuf+V2_FILEHEADER_SIZE) return (GlobalErrorFlag = SFARKLIB_ERR_OTHER); // Sanity check } else memcpy(bpFileHeader, HdrBuf, V2_FILEHEADER_SIZE); // Copy entire data block to structure if (FileHeader->CompMethod < COMPRESSION_v2) // Looks like a sfArk V1 file? { SeemsV1 = 1; // set a flag continue; // and keep searching } // Header->FileName is a null-terminated string, we need it's length to calculate actual length of header data... FileHeader->FileName[sizeof(FileHeader->FileName) -1] = '\0'; // Ensure strlen finds a terminator (string may be junk) HeaderLen = V2_FILEHEADER_SIZE - sizeof(FileHeader->FileName) + strlen(FileHeader->FileName) + 1; // If we get this far, there's a good chance we've got the header... /*#ifdef __BIG_ENDIAN__ // FixEndians of all multi-byte integers (currently only relevent to Mac) #define FIXENDIAN(field) FixEndian(&(FileHeader->field), sizeof(FileHeader->field)) FIXENDIAN(Flags); FIXENDIAN(OriginalSize); FIXENDIAN(CompressedSize); FIXENDIAN(FileCheck); FIXENDIAN(HdrCheck); FIXENDIAN(FileType); FIXENDIAN(AudioStart); FIXENDIAN(PostAudioStart); #undef FIXENDIAN #endif*/ // Ok now, we know the HeaderLength and have the FileHeader structure properly populated... #if 0 // debug, display header... printf("Flags %lx OrignalSize %ld CompressedSize %ld\n", FileHeader->Flags, FileHeader->OriginalSize, FileHeader->CompressedSize); printf("FileCheck %lx HdrCheck %lx ProgVersionNeeded %d\n", FileHeader->FileCheck, FileHeader->HdrCheck, FileHeader->ProgVersionNeeded); printf("AudioStart %ld PostAudioStart %ld Orginal filename %s\n", FileHeader->AudioStart, FileHeader->PostAudioStart, FileHeader->FileName); #endif *(uint32_t *)(HdrBuf+HEADER_HDRCHECK_POS) = 0; // Zero-out the HeaderChecksum position in the buffer CalcHdrCheck = adler32(0, HdrBuf, HeaderLen); // and recalculate the header checksum HdrCheckDone = 1; if (CalcHdrCheck == FileHeader->HdrCheck) break; // Check passed: Yes, we've found the header! } // When we get here, see what happened: if (SigFound && HdrCheckDone && CalcHdrCheck == FileHeader->HdrCheck) // Everything Ok! File is V2 and valid ; // Fall through to below (everything else is an error) else if (SeemsV1) // Seems to be a sfArkV1 file { sprintf(MsgTxt, "This file was created with sfArk V1, and this program only handles sfArk V2+ files. Unfortunately sfArk V1 uses a proprietary compression algorithm for the non-audio metadata, so we cannot really support that. You might try running the Windows sfArk program from http://melodymachine.com/sfark.htm under Wine."); msg(MsgTxt, MSG_PopUp); return (GlobalErrorFlag = SFARKLIB_ERR_INCOMPATIBLE); } else if (SigFound) // Apparently a corrupt sfArk file (well, it had "sfArk" in it!) { sprintf(MsgTxt, "File Header fails checksum!%s", CorruptedMsg); msg(MsgTxt, MSG_PopUp); return (GlobalErrorFlag = SFARKLIB_ERR_HEADERCHECK); } else // Either very corrupted, or not a sfArk file { sprintf(MsgTxt, "This does not appear to be a sfArk file!"); msg(MsgTxt, MSG_PopUp); return (GlobalErrorFlag = SFARKLIB_ERR_SIGNATURE); } // Get CreatedBy program name and version number (need null-terminated strings)... strncpy(CreatedByProg, FileHeader->ProgName, HDR_NAME_LEN); // Copy program name CreatedByProg[HDR_NAME_LEN] = 0; // Terminate string strncpy(CreatedByVersion, FileHeader->ProgVersion, HDR_VERS_LEN); // Copy version string CreatedByVersion[HDR_VERS_LEN] = 0; // Terminate string // Check for compatible version... if (FileHeader->ProgVersionNeeded > ProgVersionMaj) { sprintf(MsgTxt, "You need %s version %2.1f (or higher) to decompress this file (your version is %s) %s", ProgName, (float)FileHeader->ProgVersionNeeded/10, ProgVersion, UpgradeMsg); msg(MsgTxt, MSG_PopUp); return (GlobalErrorFlag = SFARKLIB_ERR_INCOMPATIBLE); } // Warn if file was created by a newer version than this version... float fProgVersion = (float) atof(ProgVersion); float fCreatedByVersion = (float) atof(CreatedByVersion); if (fCreatedByVersion > fProgVersion) { sprintf(MsgTxt, "This file was created with %s %s. Your version of %s (%s) can uncompress this file, " "but you might like to obtain the latest version. %s", CreatedByProg, CreatedByVersion, ProgName, ProgVersion, UpgradeMsg); msg(MsgTxt, MSG_PopUp); } SetInputFilePosition(HdrOffset + HeaderLen); // re-wind file to start of post-header data RETURN_ON_ERROR(); return SFARKLIB_SUCCESS; }