[matroska] r787 - in trunk/RbMatroska: . ebml

[email protected]
Newsgroups gmane.comp.multimedia.matroska.cvs
Message-ID <[email protected]>
Author: mosu
Date: 2004-09-12 19:28:30 +0400 (Sun, 12 Sep 2004)
New Revision: 787

Added:
   trunk/RbMatroska/writetest.rb
Modified:
   trunk/RbMatroska/ebml.rb
   trunk/RbMatroska/ebml/binary.rb
   trunk/RbMatroska/ebml/float.rb
   trunk/RbMatroska/ebml/master.rb
   trunk/RbMatroska/ebml/sinteger.rb
   trunk/RbMatroska/ebml/string.rb
   trunk/RbMatroska/ebml/uinteger.rb
Log:
Added basic support for writing. writetest.rb uses this to copy a Matroska file 1:1 (by parsing and writing the elements back again, of course).

Modified: trunk/RbMatroska/ebml/binary.rb
===================================================================
--- trunk/RbMatroska/ebml/binary.rb	2004-09-12 10:07:43 UTC (rev 786)
+++ trunk/RbMatroska/ebml/binary.rb	2004-09-12 15:28:30 UTC (rev 787)
@@ -19,21 +19,26 @@
     attr_accessor :value
 
     def read(ef)
-      @value = ef.io.read(@data_size)
+      @value = ef.io.read(@data_size).unpack("C*")
       raise EOFError if (@value.size < @data_size)
 
       return self
     end
 
-    def to_s
-      @value ||= Array.new
-      return "[Binary size " + @data_size.to_s + "]"
+    def write_data(ef)
+      ef.io.write(@value.pack("C*"))
     end
 
     def update_size
       @data_size = @value.size
       return super
     end
+
+    def to_s
+      @value ||= Array.new
+      return "[Binary size " + @data_size.to_s + "]"
+    end
+
   end                           # class Binary
 
 end                             # module Ebml

Modified: trunk/RbMatroska/ebml/float.rb
===================================================================
--- trunk/RbMatroska/ebml/float.rb	2004-09-12 10:07:43 UTC (rev 786)
+++ trunk/RbMatroska/ebml/float.rb	2004-09-12 15:28:30 UTC (rev 787)
@@ -21,17 +21,21 @@
 
     def initialize(id, pos, data_size, size_length)
       super
-      @double_precision = data_size == 4
+      @double_precision = data_size == 8
     end
 
     def read(ef)
       ins = ef.io.read(@data_size)
       raise EOFError if (ins.size < @data_size)
-      @value = ins.unpack(double_precision ? "g" : "G")[0]
+      @value = ins.unpack(double_precision ? "G" : "g")[0]
 
       return self
     end
 
+    def write_data(ef)
+      ef.io.write([@value].pack(double_precision ? "G" : "g"))
+    end
+
     def to_f
       @value ||= 0.0
       return @value
@@ -42,7 +46,7 @@
     end
 
     def update_size
-      @data_size = double_precision ? 4 : 8
+      @data_size = double_precision ? 8 : 4
       return super
     end
   end                           # class Float

Modified: trunk/RbMatroska/ebml/master.rb
===================================================================
--- trunk/RbMatroska/ebml/master.rb	2004-09-12 10:07:43 UTC (rev 786)
+++ trunk/RbMatroska/ebml/master.rb	2004-09-12 15:28:30 UTC (rev 787)
@@ -42,6 +42,13 @@
       return self
     end
 
+    def write_data(ef)
+      @children.each do |c|
+        c.write_head(ef)
+        c.write_data(ef)
+      end
+    end
+
     def each(filter = Id.none)
       @children.each do |c|
         yield(c) if ((filter == Id.none) or (filter == c.id))

Modified: trunk/RbMatroska/ebml/sinteger.rb
===================================================================
--- trunk/RbMatroska/ebml/sinteger.rb	2004-09-12 10:07:43 UTC (rev 786)
+++ trunk/RbMatroska/ebml/sinteger.rb	2004-09-12 15:28:30 UTC (rev 787)
@@ -34,15 +34,18 @@
       return self
     end
 
-    def to_i
-      @value ||= 0
-      return @value
+    def write_data(ef)
+      a = Array.new
+      shift = ((@data_size - 1) * 8)
+      mask = 0xff << shift
+      @data_size.downto(1) do
+        a.push((@value & mask) >> shift)
+        shift -= 8
+        mask >>= 8
+      end
+      ef.io.write(a.pack("C*"))
     end
 
-    def to_s
-      return to_i.to_s
-    end
-
     def update_size
       @value ||= 0
       if ((@value <= 0x7f) and (@value >= (-0x80)))
@@ -66,6 +69,16 @@
       return super
     end
       
+    def to_i
+      @value ||= 0
+      return @value
+    end
+
+    def to_s
+      return to_i.to_s
+    end
+
   end                           # class SInteger
+
 end                             # module Ebml
 

Modified: trunk/RbMatroska/ebml/string.rb
===================================================================
--- trunk/RbMatroska/ebml/string.rb	2004-09-12 10:07:43 UTC (rev 786)
+++ trunk/RbMatroska/ebml/string.rb	2004-09-12 15:28:30 UTC (rev 787)
@@ -25,9 +25,8 @@
       return self
     end
 
-    def to_s
-      @value ||= ""
-      return @value
+    def write_data(ef)
+      ef.io.write(@value)
     end
 
     def update_size
@@ -35,6 +34,12 @@
       @data_size = @value.size
       return super
     end
+
+    def to_s
+      @value ||= ""
+      return @value
+    end
+
   end                           # class String
 
 end                             # module Ebml

Modified: trunk/RbMatroska/ebml/uinteger.rb
===================================================================
--- trunk/RbMatroska/ebml/uinteger.rb	2004-09-12 10:07:43 UTC (rev 786)
+++ trunk/RbMatroska/ebml/uinteger.rb	2004-09-12 15:28:30 UTC (rev 787)
@@ -28,15 +28,18 @@
       return self
     end
 
-    def to_i
-      @value ||= 0
-      return @value
+    def write_data(ef)
+      a = Array.new
+      shift = ((@data_size - 1) * 8)
+      mask = 0xff << shift
+      @data_size.downto(1) do
+        a.push((@value & mask) >> shift)
+        shift -= 8
+        mask >>= 8
+      end
+      ef.io.write(a.pack("C*"))
     end
 
-    def to_s
-      return to_i.to_s
-    end
-
     def update_size
       @value ||= 0
 
@@ -60,6 +63,16 @@
 
       return super
     end
+
+    def to_i
+      @value ||= 0
+      return @value
+    end
+
+    def to_s
+      return to_i.to_s
+    end
+
   end                           # class UInteger
 
 end                             # module Ebml

Modified: trunk/RbMatroska/ebml.rb
===================================================================
--- trunk/RbMatroska/ebml.rb	2004-09-12 10:07:43 UTC (rev 786)
+++ trunk/RbMatroska/ebml.rb	2004-09-12 15:28:30 UTC (rev 787)
@@ -125,6 +125,41 @@
     def master?
       return false
     end
+
+    def write(f)
+      update_size
+      write_head(f)
+      write_data(f)
+    end
+
+    def write_head(f)
+      raise IdError, "Refusing to write unset EbmlIds." if (id == Id.none)
+
+      a = Array.new
+      shift = (id.size - 1) * 8
+      mask = 0xff << shift
+      id.size.downto(1) do
+        a.push((id.value & mask) >> shift)
+        shift -= 8
+        mask >>= 8
+      end
+      f.io.write(a.pack("C*"))
+
+      length = @size_length
+      length = Ebml.coded_size(@data_size) if (length == -1)
+
+      a = Array.new
+      size_mod = 0x80 >> (length - 1)
+      shift = (length - 1) * 8
+      mask = 0xff << shift
+      length.downto(1) do
+        a.push(((@data_size & mask) >> shift) | size_mod)
+        shift -= 8
+        mask >>= 8
+        size_mod = 0
+      end
+      f.io.write(a.pack("C*"))
+    end
   end
 
   require "ebml/binary"
@@ -207,5 +242,19 @@
       @@id ||= Id.new(0xec, 1)
       return @@id
     end
+
+    def read(ef)
+      skip(ef)
+    end
+
+    def write_data(ef)
+      1.upto(@data_size) do
+        ef.io.write([0].pack("C"))
+      end
+    end
+
+    def update_size
+      return @data_size
+    end
   end                           # class Void
 end

Added: trunk/RbMatroska/writetest.rb
===================================================================
--- trunk/RbMatroska/writetest.rb	2004-09-12 10:07:43 UTC (rev 786)
+++ trunk/RbMatroska/writetest.rb	2004-09-12 15:28:30 UTC (rev 787)
@@ -0,0 +1,40 @@
+#!/usr/bin/ruby
+
+#
+# Distributed under the MIT license
+# see the file COPYING for details
+# or visit http://www.opensource.org/licenses/mit-license.php
+#
+# $Id$
+#
+# Written by Moritz Bunkus <[email protected]>.
+#
+
+require "ebml"
+
+ARGV.each do |name|
+  io = File.new(name)
+  f = Ebml::File.new(io)
+  f.map_ids("Matroska")
+
+  element = f.read_element_head
+  if ((element.class == NilClass) or
+     (element.class.global_id != Ebml::Head.global_id))
+    puts("No EBML file")
+    exit(1)
+  end
+  element.read(f)
+
+  iout = File.new("output.mkv", "w")
+  fout = Ebml::File.new(iout)
+
+  while (true)
+    element.write(fout)
+    element = f.read_element_head
+    break if (element.class == NilClass)
+    element.read(f)
+  end
+
+  io.close
+  iout.close
+end


Property changes on: trunk/RbMatroska/writetest.rb
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.