All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.treesitter.utils.NativeUtils Maven / Gradle / Ivy

The newest version!
package org.treesitter.utils;

import java.io.*;
import java.nio.file.Path;
import java.util.zip.CRC32;
import java.util.zip.Checksum;

public abstract class NativeUtils {
    private static String getFullLibName(String libName){
        String osName = System.getProperty("os.name").toLowerCase();
        String archName = System.getProperty("os.arch").toLowerCase();
        String ext;
        String os;
        String arch;
        if(osName.contains("windows")){
            ext = "dll";
            os = "windows";
        }else if(osName.contains("linux")){
            ext = "so";
            os = "linux-gnu";
        }else if(osName.contains("mac")){
            ext = "dylib";
            os = "macos";
        }else{
            throw new RuntimeException(String.format("Does not support OS: %s", osName));
        }
        if(archName.contains("amd64") || archName.contains("x86_64")){
            arch = "x86_64";
        }else if(archName.contains("aarch64")){
            arch = "aarch64";
        }else{
            throw new RuntimeException(String.format("Does not support arch: %s", archName));
        }
        String[] parts = libName.split("/");
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0; i < parts.length; i++){
            if(i == parts.length - 1){
                stringBuilder.append(String.format("%s-%s-%s.%s", arch, os, parts[i], ext));
            }else{
                stringBuilder.append(parts[i]);
                stringBuilder.append("/");
            }
        }
        return stringBuilder.toString();
    }

    static private Path getLibStorePath(){
        String userDefinedPath = System.getProperty("tree-sitter-lib");
        if(userDefinedPath == null){
            return Path.of(System.getProperty("user.home") ,".tree-sitter");
        }
        return Path.of(userDefinedPath);
    }


    private static long crc32(byte[] bytes) {
        Checksum crc32 = new CRC32();
        crc32.update(bytes, 0, bytes.length);
        return crc32.getValue();
    }

    private static byte[] readFile(File file){
        try(
            InputStream inputStream = new FileInputStream(file);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
        ){
            inputStream.transferTo(outputStream);
            return outputStream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static byte[] readInputStream(InputStream inputStream){
        try(
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
        ){
            inputStream.transferTo(outputStream);
            return outputStream.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static byte[] readLib(String libName){
        String fullLibName = getFullLibName(libName);
        InputStream inputStream = NativeUtils.class.getClassLoader().getResourceAsStream(fullLibName);
        if(inputStream == null){
            throw new RuntimeException(String.format("Can't open %s", fullLibName));
        }
        return readInputStream(inputStream);
    }

    /**
     * Load native lib from class path by name convention.
     *
     * 

Name convention: arch-os-name.ext *

arch *

    *
  1. x64: x86_64
  2. *
  3. arm64: aarch64
  4. *
* @param libName Canonical name of the library. e.g. 'lib/foo', 'bar' */ public static void loadLib(String libName){ String fullLibName = getFullLibName(libName); Path filePath = getLibStorePath().resolve(fullLibName); File file = filePath.toFile(); file.getParentFile().mkdirs(); boolean shouldOverwrite = false; byte[] newFileBytes = null; if(file.exists()){ byte[] oldFileBytes = readFile(file); newFileBytes = readLib(libName); if(crc32(oldFileBytes) != crc32(newFileBytes)){ shouldOverwrite = true; } }else{ shouldOverwrite = true; } if(shouldOverwrite){ if(newFileBytes == null){ newFileBytes = readLib(libName); } try( FileOutputStream outputStream = new FileOutputStream(file) ){ new ByteArrayInputStream(newFileBytes).transferTo(outputStream); } catch (IOException e) { throw new RuntimeException(e); } } System.load(file.getAbsolutePath()); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy