mirror of
				https://github.com/gnh1201/welsonjs.git
				synced 2025-10-31 04:51:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			75 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // lz77.js
 | |
| // Copyright 2019-2025, Namhyeon Go <gnh1201@catswords.re.kr> and the WelsonJS contributors.
 | |
| // SPDX-License-Identifier: GPL-3.0-or-later
 | |
| // https://github.com/gnh1201/welsonjs
 | |
| // 
 | |
| function compress(input) {
 | |
|     var compressed = '';
 | |
|     var searchBufferIndex = 0;
 | |
| 
 | |
|     while (searchBufferIndex < input.length) {
 | |
|         var longestMatchLength = 0;
 | |
|         var longestMatchOffset = 0;
 | |
| 
 | |
|         // Search for the longest match in the look-ahead buffer
 | |
|         for (var i = 0; i < searchBufferIndex; i++) {
 | |
|             var matchLength = 0;
 | |
|             while (matchLength < input.length - searchBufferIndex && input.charAt(i + matchLength) === input.charAt(searchBufferIndex + matchLength)) {
 | |
|                 matchLength++;
 | |
|             }
 | |
| 
 | |
|             if (matchLength > longestMatchLength) {
 | |
|                 longestMatchLength = matchLength;
 | |
|                 longestMatchOffset = searchBufferIndex - i;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Output the token (offset, length)
 | |
|         if (longestMatchLength > 0) {
 | |
|             compressed += '(' + longestMatchOffset + ',' + longestMatchLength + ')';
 | |
|             searchBufferIndex += longestMatchLength;
 | |
|         } else {
 | |
|             compressed += '(0,' + input.charAt(searchBufferIndex) + ')';
 | |
|             searchBufferIndex++;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return compressed;
 | |
| }
 | |
| 
 | |
| function decompress(compressedData) {
 | |
|     var decompressed = '';
 | |
|     var currentIndex = 0;
 | |
| 
 | |
|     while (currentIndex < compressedData.length) {
 | |
|         if (compressedData.charAt(currentIndex) === '(') {
 | |
|             // Match case
 | |
|             var commaIndex = compressedData.indexOf(',', currentIndex);
 | |
|             var offset = parseInt(compressedData.substring(currentIndex + 1, commaIndex), 10);
 | |
|             var closingParenIndex = compressedData.indexOf(')', commaIndex);
 | |
|             var length = parseInt(compressedData.substring(commaIndex + 1, closingParenIndex), 10);
 | |
| 
 | |
|             for (var i = 0; i < length; i++) {
 | |
|                 var copyIndex = decompressed.length - offset;
 | |
|                 decompressed += decompressed.charAt(copyIndex);
 | |
|             }
 | |
| 
 | |
|             currentIndex = closingParenIndex + 1;
 | |
|         } else {
 | |
|             // Literal case
 | |
|             decompressed += compressedData.charAt(currentIndex);
 | |
|             currentIndex++;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return decompressed;
 | |
| }
 | |
| 
 | |
| exports.compress = compress;
 | |
| exports.decompress = decompress;
 | |
| 
 | |
| exports.VERSIONINFO = "LZ77 (MsCompress) algorithm implementation version 0.1";
 | |
| exports.AUTHOR = "gnh1201@catswords.re.kr";
 | |
| exports.global = global;
 | |
| exports.require = global.require;
 |