Čo je zlé na uzavretých súborových formátoch?

Ak ste už niekedy dostali e-mail od niekoho, kto nepoužíva Windows (väčšinou sa jedná o skúsených počítačových používateľov :), pravdepodobne ste sa v jeho hlavičke či texte mohli dočítať, že neprijíma poštu v „proprietary file formats“. Čo vlastne znamená slovíčko „proprietary“ a čo vedie týchto ľudí k takému odporu voči týmto formátom?

Termín „uzavreté súborové formáty“ je nie úplne výstižný preklad anglického „proprietary file formats“. Anglické slovo „proprietary“ podľa definície znamená „chránený ochrannou známkou, patentom alebo autorskými právami“, výstižnejšie povedané „vlastnený konkrétnou osobou (fyzickou alebo právnickou)“. Tento pojem sa nepoužíva iba na súborové formáty ale aj na akýkoľvek softvér, komunikačné protokoly, a podobne až po ľubovoľné dátové súbory. (To sa týka samozrejme iba počítačovej oblasti, ináč ho možno použiť takmer na čokoľvek, čo môže byť predmetom vlastníctva.)

A čo vyplýva z vlastníctva nejakého formátu? Ak je nejaká osoba jediným vlastníkom niečoho, má plné a výhradné právo o tom rozhodovať. V prípade súborového formátu napríklad môže a nemusí jeho popis zverejniť, aby ho bolo možné používať aj v iných programoch. Môže v jeho nových verziách urobiť spätne nekompatibilné zmeny a tak napríklad prinútiť užívateľov prejsť na novú verziu nejakého programu (keďže nový formát vo svojej neprečítajú). V praxi je to žiaľ aj veľmi častý postup. Najžiarivejším príkladom je asi formát DOC pre Microsoft Word, ale nie je ani zďaleka jediným.

Vlastníctvo formátu teoreticky umožňuje aj vyžadovať platby za jeho vytváranie a/alebo používanie, ale k tomu sa odváži iba málokto. Asi najznámejším takýmto prípadom je GIF (platiť musia výrobcovia softvéru, ktorý ho umožňuje vytvárať).

Keďže firmy chcú v prvom rade dosiahnuť zisk, logicky k tomu využívajú aj vlastné formáty. Ak nezverejnia popis formátu, je možné ho prečítať iba programom od autorskej firmy (ktorý si treba samozrejme kúpiť). Čím rozšírejší je daný formát, tým viac ľudí je nútených si zakúpiť program na prácu s ním. Navyše je tu ešte jeden problém: aj keď si to väčšina tých, ktorí sa všade stretávajú iba s Windows, vôbec neuvedomuje, operačných systémov existuje veľké množstvo. Za všetky možno spomenúť napríklad Mac OS, Linux a množstvo ďalších UNIXových systémov. Väčšina výrobcov softvéru ale vytvorí programy pracujúce s ich formátmi len pre Windows, maximálne ešte tak pre Mac. Ak ale niekto robí v UNIXe, jednoducho nemá možnosť s takým formátom pracovať, aj keby bol hneď ochotný za príslušný program zaplatiť.

Opakom uzavretých formátov sú formáty otvorené. Ich popis je zverejnený a prakticky ktokoľvek si môže vytvoriť vlastný softvér na prácu s nimi. Vďaka tomu nie je užívateľ nútený si kúpiť jeden konkrétny program, ale môže si vybrať z ponuky ten, ktorý mu najlepšie vyhovuje. Vo väčšine oblastí navyše už existujú aj programy dostupné zadarmo, často patriace medzi slobodný softvér.

Takmer vo všetkých oblastiach už existujú otvorené formáty, ktoré plne nahradia ich uzavreté ekvivalenty. Asi najtypickejšími príkladmi sú HTML a PNG (ktorého animovaná verzia, MNG, sa žiaľ ešte príliš neujala). Do budúcnosti je veľmi nádejným formátom XML, ktorý už dnes podporuje značné množstvo softvéru, vrátane databázových systémov.

Firmou, ktorá z presadzovania uzavretých formátov ťaží najviac, je pochopiteľne Microsoft. Ten nemá záujem ani vytvárať svoj Office pre UNIXové systémy. Nech si len všetci kúpia Windows, na ktorých tiež zarobí práve Microsoft. Mnohí považujú takéto správanie za monopolistické, pre niektorých je to dokonca dôvod pre nenávisť voči Microsoftu (ako to už v takýchto prípadoch býva, nie je ich veľa, ale najlepšie ich vidno). Ono to ale vôbec nie je až také podstatné, nakoniec nikto by nemal mať právo prikazovať komerčnej firme, čo má a čo nemá robiť, pokiaľ neporušuje zákon. Úplne stačí, aby väčšina ľudí pochopila, že je pre nich výhodnejšie používať otvorené formáty. Microsoft by potom rýchlo stratil svoju súčasnú pozíciu, respektíve by sa tomu musel prispôsobiť.

Pbatenghyngvbaf Lbh ner n bofreinag jro unpxre Vs Lbh jnag n wbo va bhe pbzcnal cyrnfr znvy gb gbhtuthl ng ci2p qbg fx Unir n avpr qnl
Birth, copulation and death.
That's all the facts when you come to brass tacks;
Birth, copulation and death.
		-- T.S. Elliot, "Sweeney Agonistes"
    function perr($msg, $level)
    {
        echo $msg;
    }

    function readcsv_get_entity($fh, $sep = ';')
    {
        $entity = array();
        $attr = '';
        $eoe = false;

        while((! feof($fh)) && (! $eoe))
        {
            $ch = fgetc($fh);
            switch($ch)
            {
                case "\r":
                    break;
                case "\n":
                    $eoe = true;
                case $sep:
                    array_push($entity, $attr);
                    $attr = '';
                    break;
                case '"':
                    $ch = '';
                    while((! feof($fh)) && $ch != '"')
                    {
                        $ch = fgetc($fh);
                        $attr .= $ch;
                    }
                    $attr = rtrim($attr, '"');
                    break;
                default:
                    $attr .= $ch;
            }
        }

        if(feof($fh) && ($entity || $attr))
        {
            array_push($entity, $attr);
        }
        elseif(feof($fh))
        {
            $entity = false;
        }

        return $entity;
    }

    function readcsv_parsecsv($filename)
    {
        $ret = false;
        $sep = ';';
        $line = '';
        $line_num = 0;
        $cells = array();
        $names = array();

        $fh = fopen($filename, 'r');
        if(! $fh)
        {
            perr('Failed to open file \''
                . $file . "'\n", 8);
        }
        else
        {
        $line = '';
        while(! feof($fh))
        {
        $entity = readcsv_get_entity($fh, $sep);

        if($entity)
        {
        if($line_num == 0)
        {
        foreach($entity as $name)
        {
            array_push($names, trim($name, '"'));
        }
        }
        else
        {
        foreach($entity as $index => $val)
        {
        if(isset($names[$index]))
        {
            $cells[$line_num][$names[$index]]
                = trim($val, '"');
        }
        else
        {
            array_push($cells[$line_num],
                trim($val, '"'));
        }                            
        }
        }
        $line_num ++;
        }
        }
        fclose($fh);
        }

        return $ret;
    }
        
    function perr($msg, $level)
    {
        echo $msg;
    }

    function readcsv_get_entity($fh, $sep = ';')
    {
        $entity = array();
        $attr = '';
        $eoe = false;

        while((! feof($fh)) && (! $eoe))
        {
            $ch = fgetc($fh);
            switch($ch)
            {
                case "\r":
                    break;
                case "\n":
                    $eoe = true;
                case $sep:
                    array_push($entity, $attr);
                    $attr = '';
                    break;
                case '"':
                    $ch = '';
                    while((! feof($fh)) && $ch != '"')
                    {
                        $ch = fgetc($fh);
                        $attr .= $ch;
                    }
                    $attr = rtrim($attr, '"');
                    break;
                default:
                    $attr .= $ch;
            }
        }

        if(feof($fh) && ($entity || $attr))
        {
            array_push($entity, $attr);
        }
        elseif(feof($fh))
        {
            $entity = false;
        }

        return $entity;
    }

    function readcsv_parsecsv($filename)
    {
        $ret = false;
        $sep = ';';
        $line = '';
        $line_num = 0;
        $cells = array();
        $names = array();

        $fh = fopen($filename, 'r');
        if(! $fh)
        {
            perr('Failed to open file \''
                . $file . "'\n", 8);
        }
        else
        {
        $line = '';
        while(! feof($fh))
        {
        $entity = readcsv_get_entity($fh, $sep);

        if($entity)
        {
        if($line_num == 0)
        {
        foreach($entity as $name)
        {
            array_push($names, trim($name, '"'));
        }
        }
        else
        {
        foreach($entity as $index => $val)
        {
        if(isset($names[$index]))
        {
            $cells[$line_num][$names[$index]]
                = trim($val, '"');
        }
        else
        {
            array_push($cells[$line_num],
                trim($val, '"'));
        }                            
        }
        }
        $line_num ++;
        }
        }
        fclose($fh);
        }

        return $ret;
    }