Data::Sofu - Perl extension for Sofu data

- NAME
- Synopsis
- Synopsis - oo-style
- DESCRIPTION
- SYNTAX
- FUNCTIONS

- `getSofucomments()`
- `writeSofu(FILE,DATA,[COMMENTS])`
- `readSofu(FILE)`
- `loadSofu(FILE)`
- `packSofu(DATA,[COMMENTS])`
- `unpackSofu(SOFU STRING)`
- `writeSofuBinary(FILE, DATA, [Comments, [Encoding, [ByteOrder, [SofuMark]]]])`
- `writeSofuML(FILE, DATA, [COMMENTS,[HEADER]])`

- CLASS-METHODS

- `loadFile(FILE)`

- METHODS (OO)

- `new()`
- `setIndent(INDENT)`
- `setWarnings( 1/0 )`
- `comments()`
- `write(FILE,DATA,[COMMENTS])`
- `read(FILE)`
- `pack(DATA,[COMMENTS])`
- `unpack(SOFU STRING)`
- `load(FILE)`
- `toObjects(DATA, [COMMENTS])`
- `writeBinary(FILE, DATA, [Comments, [Encoding, [ByteOrder, [SofuMark]]]])`
- `writeML(FILE, DATA, [COMMENTS,[HEADER]])`
- packML (DATA, COMMENTS,[HEADER])

- CHANGES
- BUGS
- NOTE on Unicode
- SEE ALSO

# NAME

Data::Sofu - Perl extension for Sofu data

# Synopsis

            use Data::Sofu;
            %hash=readSofu("file.sofu");
            ...
            writeSofu("file.sofu",\%hash);

    Or a litte more complex:
            use Data::Sofu qw/packSofu unpackSofu/;
            %hash=readSofu("file.sofu");
            $comments=getSofucomments;
            open fh,">:UTF16-LE","file.sofu";
            writeSofu(\*fh,\$hash,$comments);
            close fh;
            $texta=packSofu($arrayref);
            $texth=packSofu($hashref);
            $arrayref=unpackSofu($texta);
            $arrayhash=unpackSofu($texth);

# Synopsis - oo-style

            require Data::Sofu;
            my $sofu=new Sofu;
            %hash=$sofu->read("file.sofu");
            $comments=$sofu->comments;
            $sofu->write("file.sofu",$hashref);
            open fh,">:UTF16-LE",file.sofu";
            $sofu->write(\*fh,$hashref,$comments);
            close fh;
            $texta=$sofu->pack($arrayref);
            $texth=$sofu->pack($hashref);
            $arrayref=$sofu->unpack($texta);
            $arrayhash=$sofu->unpack($texth);

# DESCRIPTION

This Module provides the ability to read and write sofu files of the versions 0.1 and 0.2. Visit http://sofu.sf.net for a description about sofu.

It can also read not-so-wellformed sofu files and correct their errors.

Additionally it provides the ability to pack HASHes and ARRAYs to sofu strings and unpack those.

The comments in a sofu file can be preserved if they're saved with $sofu->comment or getSofucomments or if loadFile/load is used.

It also provides a compatibility layer for sofud via Data::Sofu::Object and Data::Sofu->loadFile();

Data::Sofu::Binary provides an experimental interface to Binary Sofu (.bsofu) files and streams.

# SYNTAX

This module can either be called using object-orientated notation or using the funtional interface.

Some features are only avaiable when using OO.

# FUNCTIONS

## `getSofucomments()`

Gets the comments of the last file read

## `writeSofu(FILE,DATA,[COMMENTS])`

Writes a sofu file with the name FILE.

FILE can be:

A reference to a filehandle with the right encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

An existing file of this name will be overwritten.

DATA can be a scalar, a hashref or an arrayref.

The top element of sofu files must be a hash, so any other datatype is converted to {Value=>DATA}.

            @a=(1,2,3);
            $sofu->write("Test.sofu",\@a);
            %data=$sofu->read("Test.sofu");
            @a=@{$data->{Value}}; # (1,2,3)

COMMENTS is a reference to hash with comments like the one retuned by `comments()`

## `readSofu(FILE)`

Reads the sofu file FILE and returns a hash with the data.

FILE can be:

A reference to a filehandle with the right encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

These methods are not exported by default:

## `loadSofu(FILE)`

Reads a .sofu file and converts it to Sofud compatible objects

FILE can be:

A reference to a filehandle with the right encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

Returns a `Data::Sofu::Object`

## `packSofu(DATA,[COMMENTS])`

Packs DATA to a sofu string.

DATA can be a scalar, a hashref or an arrayref.

This is different from a normal write(), because the lines are NOT indented and there will be placed brackets around the topmost element. (Which is not Sofu 0.2 conform, please use `write(\$scalar,$data)` instead).

COMMENTS is a reference to hash with comments like the one retuned by comments().

## `unpackSofu(SOFU STRING)`

This function unpacks SOFU STRING and returns a scalar, which can be either a string or a reference to a hash or a reference to an array.

Can read Sofu and SofuML files but not binary Sofu files

Note you can also read packed Data with readSofu(\<packed Data string>):

            my $packed = packSofu($tree,$comments);
            my $tree2 = unpackSofu($packed);
            my $tree3 = readSofu(\$packed);
            # $tree2 has the same data as $tree3 (and $tree of course)

## `writeSofuBinary(FILE, DATA, [Comments, [Encoding, [ByteOrder, [SofuMark]]]])`

Writes the Data as a binary file.

FILE can be:

A reference to a filehandle with raw encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

DATA has to be a reference to a Hash or Data::Sofu::Object

COMMENTS is a reference to hash with comments like the one retuned by comments

More info on the other parameters in Data::Sofu::Binary

To write other Datastructures use this:

            writeSofuBinary("1.sofu",{Value=>$data});

## `writeSofuML(FILE, DATA, [COMMENTS,[HEADER]])`

Writes the Data as an XML file (for postprocessing with XSLT or CSS)

FILE can be:

A reference to a filehandle with some encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

DATA has to be a reference to a Hash or Data::Sofu::Object

COMMENTS is a reference to hash with comments like the one retuned by comments, only used when DATA is not a Data::Sofu::Object

HEADER can be an costum file header, (defaults to `qq(<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<!DOCTYPE Sofu SYSTEM "http://sofu.sf.net/Sofu.dtd">\n)` );

Default output (when given a filename) is UTF-8.

# CLASS-METHODS

## `loadFile(FILE)`

Reads a .sofu file and converts it to Sofud compatible objects.

FILE can be:

A reference to a filehandle with the right encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

Returns a `Data::Sofu::Object`

            my $tree=Data::Sofu->loadFile("1.sofu");
            print $tree->list("Foo")->value(5);
            $tree->list("Foo")->appendElement(new Data::Sofu::Value(8));
            $tree->write("2.sofu");

# METHODS (OO)

## `new()`

Creates a new Data::Sofu object.

## `setIndent(INDENT)`

Sets the indent to INDENT. Default indent is ``\t''.

## `setWarnings( 1/0 )`

Enables/Disables sofu syntax warnings.

## `comments()`

Gets/sets the comments of the last file read

## `write(FILE,DATA,[COMMENTS])`

Writes a sofu file with the name FILE.

FILE can be:

A reference to a filehandle with the right encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

An existing file of this name will be overwritten.

DATA can be a scalar, a hashref or an arrayref.

The top element of sofu files must be a hash, so any other datatype is converted to {Value=>DATA}.

            @a=(1,2,3);
            $sofu->write("Test.sofu",\@a);
            %data=$sofu->read("Test.sofu");
            @a=@{$data->{Value}}; # (1,2,3)

COMMENTS is a reference to hash with comments like the one retuned by `comments()`

## `read(FILE)`

Reads the sofu file FILE and returns a hash with the data.

FILE can be:

A reference to a filehandle with the right encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

## `pack(DATA,[COMMENTS])`

Packs DATA to a sofu string.

DATA can be a scalar, a hashref or an arrayref.

COMMENTS is a reference to hash with comments like the one retuned by comments

This is different from a normal write(), because the lines are NOT indented and there will be placed brackets around the topmost element. (Which is not Sofu 0.2 conform, please use `write(\$scalar,$data)` instead).

## `unpack(SOFU STRING)`

This function unpacks SOFU STRING and returns a scalar, which can be either a string or a reference to a hash or a reference to an array.

## `load(FILE)`

Reads a .sofu file and converts it to Sofud compatible objects

FILE can be:

A reference to a filehandle with the right encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

Returns a `Data::Sofu::Object`

## `toObjects(DATA, [COMMENTS])`

Builds a Sofu Object Tree from a perl data structure

DATA can be a scalar, a hashref or an arrayref.

COMMENTS is a reference to hash with comments like the one retuned by comments

Returns a `Data::Sofu::Object`

## `writeBinary(FILE, DATA, [Comments, [Encoding, [ByteOrder, [SofuMark]]]])`

Writes the Data as a binary file.

FILE can be:

A reference to a filehandle with raw encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

DATA has to be a reference to a Hash or Data::Sofu::Object

COMMENTS is a reference to hash with comments like the one retuned by comments

More info on the other parameters in `Data::Sofu::Binary`

To write other Datastructures use this:

            $sofu->writeBinary("1.sofu",{Value=>$data});

## `writeML(FILE, DATA, [COMMENTS,[HEADER]])`

Writes the Data as an XML file (for postprocessing with XSLT or CSS)

FILE can be:

A reference to a filehandle with some encoding set or

a filename or

a reference to a scalar (Data will be read from a scalar)

DATA has to be a reference to a Hash or Data::Sofu::Object

COMMENTS is a reference to hash with comments like the one retuned by comments, only used when DATA is not a Data::Sofu::Object

HEADER can be an costum file header, (defaults to `qq(<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<!DOCTYPE Sofu SYSTEM "http://sofu.sf.net/Sofu.dtd">\n)` );

Default output (when given a filename) is UTF-8.

## packML (DATA, COMMENTS,[HEADER])

Returns DATA as an XML file (for postprocessing with XSLT or CSS) with no Indentation

DATA has to be a reference to a Hash or Data::Sofu::Object

COMMENTS is a reference to hash with comments like the one retuned by comments, only used when DATA is not a Data::Sofu::Object

HEADER can be an costum file header, (defaults to `qq(<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<!DOCTYPE Sofu SYSTEM "http://sofu.sf.net/Sofu.dtd">\n)` );

Those are not (quite) the same:

            $string = $sofu->packML($tree,$comments) #Will not indent.
            $sofu->writeML(\$string,$tree,$comments)# Will indent.

# CHANGES

Kyes are now automatically escaped according to the new sofu specification.

Double used references will now be converted to Sofu-References.

read, load, readSofu, loadSofu and Data::Sofu::loaFile now detect binary sofu (and load Data::Sofu::Binary)

read, load, readSofu, loadSofu, Data::Sofu::loaFile, unpackSofu and unpack detect SofuML (and load Data::Sofu::SofuML)

# BUGS

Comments written after an object will be rewritten at the top of an object:

            foo = { # Comment1
                    Bar = "Baz"
            } # Comment2

will get to:

            foo = { # Comment1
            # Comment 2
                    Bar = "Baz"
            }

# NOTE on Unicode

Sofu File are normally written in a Unicode format. `Data::Sofu` is trying to guess which format to read (usually works, thanks to Encode::Guess).

On the other hand the output defaults to UTF-16 (UNIX) (like SofuD). If you need other encoding you will have to prepare the filehandle yourself and give it to the `write()` funktions...

            open my $fh,">:encoding(latin1)","out.sofu";
            writeSofu($fh,$data);

Warning: UTF32 BE is not supported without BOM (looks too much like Binary);

Notes:

As for Encodings under Windows you should always have a :raw a first layer, but to make them compatible with Windows programs you will have to access special tricks:

            open my $fh,">:raw:encoding(UTF-16):crlf:utf8","out.sofu" #Write Windows UTF-16 Files
            open my $fh,">:raw:encoding(UTF-16)","out.sofu" #Write Unix UTF-16 Files
            #Same goes for UTF32

            #UTF-8: Don't use :utf8 or :raw:utf8 alone here,
            #Perl has a different understanding of utf8 and UTF-8 (utf8 allows some errors).
            open my $fh,">:raw:encoding(UTF-8)","out.sofu" #Unix style UTF-8
            open my $fh,">:raw:encoding(UTF-8):crlf:utf8","out.sofu" #Windows style UTF-8

            #And right after open():
            print $fh chr(65279); #Print UTF-8 Byte Order Mark (Some programs want it, some programs die on it...)

    One last thing:

            open my $out,">:raw:encoding(UTF-16BE):crlf:utf8","out.sofu";
            print $out chr(65279); #Byte Order Mark
            #Now you can write out UTF16 with BOM in BigEndian (even if you machine in Little Endian)

# SEE ALSO

perl(1),http://sofu.sf.net

For Sofud compatible Object Notation: the Data::Sofu::Object manpage

For Sofu Binary: the Data::Sofu::Binary manpage

For SofuML the Data::Sofu::SofuML manpage