maplib

 

ulis, 2006-02-02. Un format de librairie pour les maps.

  maplib vs2.lmap -xtract *

Pourquoi

Pour rassembler par exemple toutes les maps associées à un style visuel.


Comment

Une librairie contient des maps compressées et un index. Un utilitaire permet de gérer la librairie.


Utilisation

  libmap libfile [operation [arg]...]...
  # libfile : le nom du fichier contenant la librairie
  # operation : ajout, remplacement, suppression, listage des maps
  #   ajout (la map ne doit pas exister dans la librairie) :
  #     -add [pattern]...
  #        pattern : un nom générique de fichier utilisable par la commande [glob]
  #   remplacement (la map peut exister dans la librairie) :
  #     -replace [pattern]...
  #   suppression (la map doit exister dans la librairie)
  #     -delete [pattern]...
  #   extraction (la map doit exister dans la librairie)
  #     -extract [pattern]...
  #     -xtract [pattern]...
  #   extraction avec décompression (la map doit exister dans la librairie)
  #     -uncompress [pattern]...
  #   listage de toutes les maps de la librairie
  #     -list

Exemples :

  # create the vs2 lib
  maplib vs2.lmap -a *.map
  # list all maps
  maplist vs2.lmap -l
  # delete a map
  maplib vs2.lmap -d test.map
  # extract + uncompress a map
  maplib vs2.lmap -u active-button.map

L'utilitaire

  # map lib

  proc maplib {file args} \
  {
    set rc [catch \
    {
      array set {} {}
      if {[file exists $file]} \
      {
        # read header into memory
        set fp [open $file]
        fconfigure $fp -translation binary
        if {[read $fp 4] != "UML\0"} \
        { error "$file is not a map lib" }
        set hsize [string trimleft [read $fp 4] 0]
        if {$hsize == ""} { set hsize 0 }
        if {![string is integer -strict $hsize]} \
        { error "$file is corrupted" }
        set header [split [read $fp $hsize] \0]
        close $fp
        foreach line $header \
        {
          foreach {name offset size} [split $line *] \
          {
            set ($name:n) $name
            set ($name:o) $offset
            set ($name:s) $size
          }
        }
      }
      # do actions
      set update 0
      set argc [llength $args]
      set argn 0
      set action ""
      set check 0
      set uncompress 0
      while {$argc > 0} \
      {
        set arg [lindex $args $argn]
        incr argn
        if {[string match -* $arg]} \
        {
          switch -glob -- $arg \
          {
            -a*     { set action replace; set check 1 }
            -d*     { set action delete }
            -e*     { set action extract; set uncompress 0 }
            -l*     { set action list }
            -r*     { set action replace; set check 0 }
            -u*     { set action extract; set uncompress 1 }
            -x*     { set action extract; set uncompress 0 }
            default \
            { error "unknown action '$arg' for $file" }
          }
          if {$action == "list"} \
          {
            set names [lsort [array names {} *:n]]
            puts "maplib $file: [llength $names] map(s)"
            foreach name $names \
            {
              set fn $($name)
              puts "\t$fn\t$($fn:s) bytes"
            }
            set action ""
          }
        } \
        else \
        {
          switch $action \
          {
            delete  \
            {
              set names [array names {} $arg:n]
              if {$names == ""} \
              { error "$file: can't find '$arg' in lib" }
              array unset {} $arg:*
              set update 1
            }
            extract \
            {
              set names [array names {} $arg:n]
              if {$names == ""} \
              { error "$file: can't find '$arg' in lib" }
              foreach name $names \
              {
                set name $($name)
                if {[info exists ($name:m)]} \
                {
                  # external file
                  set map [split $($name:m) \0]
                } \
                else \
                {
                  # already in lib
                  set fp [open $file]
                  fconfigure $fp -translation binary
                  seek $fp [expr {8 + $hsize + $($name:o)}] start
                  set map [split [read $fp $($name:s)] \0]
                  close $fp
                }
                if {$uncompress} \
                { set map [uncompress $map] }
                map2file $map _$name
                file rename -force _$name $name
              }
            }
            replace \
            {
              set rc [catch { set names [glob $arg] }]
              if {$rc == 1} { error "can't find '$arg" }
              foreach name $names \
              {
                if {$check && [info exists ($name:n)]} \
                { error "$file: can't add '$name', already in lib" }
                set ($name:n) $name
                set ($name:m) [join [compress [file2map $name]] \0]
                set ($name:s) [string length $($name:m)]
              }
              set update 1
            }
          }
        }
        incr argc -1
      }
      if {$update} \
      {
        # save the lib
        # build a new file
        set ofn _$file
        set ofp [open $ofn w]
        fconfigure $ofp -translation binary
        # put magic name
        puts -nonewline $ofp "UML\0"
        # build header
        set header ""
        set members [list]
        set offset 0
        foreach name [array names {} *:n] \
        {
          lappend members $($name)
          set fn $($name)
          set size $($fn:s)
          set line [list $fn $offset $size]
          append header "[join $line *]\0"
          incr offset $size
        }
        # put header size
        set hsize [string length $header]
        puts -nonewline $ofp [format %4.4d $hsize]
        # put header
        puts -nonewline $ofp $header
        # put members
        foreach member $members \
        {
          if {[info exists ($member:m)]} \
          {
            # get member from external file
            puts -nonewline $ofp $($member:m)
          } \
          else \
          {
            # get member from old library
            set fp [open $file]
            fconfigure $fp -translation binary
            seek $fp [expr {8 + $hsize + $($member:o)}] start
            set map [read $fp $($member:s)]
            close $fp
            puts -nonewline $ofp $map
          }
        }
        close $ofp
        # rename the file
        file rename -force $ofn $file
      }
    } err]
    if {$rc == 1} { return -code error "maplib: $err" }
  }

Voir aussi


Discussion


Catégorie Exemple | Catégorie Traitement d'image