<?php


class Files {


    public static function editText($file, $callback) {
        // Create if not exists
        if(!file_exists($file))
            touch($file);
        
        // Open
        $f = fopen($file, "r+");
        self::lock($f);
        $content = stream_get_contents($f);

        // Run
        $content = $callback($content);

        // Close
        fseek($f, 0);
        ftruncate($f, strlen($content));
        fwrite($f, $content);
        self::unlock($f);
        fclose($f);
    }


    public static function editStream($file, $callback) {
        // Create if not exists
        if(!file_exists($file))
            touch($file);

        // Open
        $f = fopen($file, "r+");
        self::lock($f);

        // Run
        $callback($f);

        // Close
        self::unlock($f);
        fclose($f);
    }

    public static function get($file, $maxLen = -1) {
        if(!file_exists($file)) return $file;
        
        $f = fopen($file, "r");
        self::lock($f);
        if($maxLen == -1)
            $content = stream_get_contents($f);
        else
            $content = stream_get_contents($f, $maxLen);
        self::unlock($f);
        fclose($f);

        return $content;
    }

    public static function put($file, $content) {
        $f = fopen($file, "r+");
        self::lock($f);
        ftruncate($f, strlen($content));
        fwrite($f, $content);
        self::unlock($f);
        fclose($f);
    }

    public static function append($file, $content) {
        $f = fopen($file, "a");
        self::lock($f);
        fwrite($f, $content);
        self::unlock($f);
        fclose($f);
    }

    public static function lock($f, $maxTry = 100000) {
        if($maxTry == -1) {
            while(!flock($f, LOCK_EX|LOCK_NB));
        }
        else {
            $try = 0;
            while(!flock($f, LOCK_EX|LOCK_NB) && ++$try < $maxTry);
        }
    }

    public static function unlock($f) {
        flock($f, LOCK_UN);
    }

}
