Comments (8)
I'm not sure if BinData is the right tool for what you want.
BinData is used to read/write/modify a well defined structured-binary-format. Your description indicates that you just want some sort of serialization mechanism and don't really care about the underlying binary representation. Yaml or Marshal might suit you better.
from bindata.
Well, actually I do care about underlying binary representation as I'm trying to write a network protocol client, whose protocol is similar to the Minecraft NBT example code. I am just trying to make the resulting object more comfortable to work with from Ruby code. Consider this definition in BinData format:
class MyString < BinData::Primitive
endian :big
int16 :len, :value => lambda { data.length }
string :data, :read_length => :len
def get
self.data
end
def set(v)
self.data = v
end
end
class Term < BinData::Record; end
class MyArray < BinData::Record
endian :big
int16 :len, :value => lambda { data.length }
array :data, :type => :term, :initial_length => :len
end
class MyObject < BinData::Record
endian :big
int16 :len, :value => lambda { items.length }
array :items, :initial_length => :len do
my_string :tag
term :item
end
end
class Term < BinData::Record
endian :big
uint8 :type
choice :payload, :selection => :type do
int8 1
int8 2
int16 3
int32 4
int64 5
float 6
double 7
my_string 8
my_array 9
my_object 10
end
end
The resulting object parsed using this definition will look something like the following:
{
:type=>10, // object
:payload=> {
:len=>3,
:items=>[
{:tag=>"a", :item=>{:type=>3, :payload=>1}},
{:tag=>"c", :item=>{:type=>2, :payload=>0}},
{:tag=>"p",
:item=>{
:type=>10, // object
:payload=>{
:len=>4,
:items=>[
{:tag=>"key1", :item=>{:type=>8, :payload=>"value1"}}, // string
{:tag=>"key2", :item=>{:type=>8, :payload=>"value2"}} // string
]
}
}
}
]
}
}
This is a well-defined structured binary format. However, in such form it's not very convenient to manipulate the objects. Since in the definition above MyObject actually looks like a Hash, it would be easier if it was possible to manipulate the key-value pairs as Hash in Ruby, not as Array. For some of the Term choice types, it is also possible to derive type information from Ruby class (e.g. String value can be unambiguously mapped to choice (tag id) 8.
So, what I want to achieve here is MyObject being represented as Hash in Ruby, and it's len
property being automatically managed according to the number of keys. The Hash interface should transparently allow access to the internal items
array, with tag
being the hash key.
from bindata.
Okay, I understand now.
So if I have code like
foo = MyObject.new
foo["a"] = 3
what is the type
of the term? It could be 1, 2, 3, 4, 5, 6 or 7.
from bindata.
In case of ambiguous types (like numeric types) you could perhaps do something like:
foo["a"] = Term.new(4, 424242)
Other types could be assigned without such ambiguity:
foo["b"] = "some string"
bar = MyObject.new
bar["a"] = "other string"
foo["c"] = bar
foo["d"] = ["array", Term(4, 8888)]
A possible upper layer of abstraction (not a part of BinData) could also have knowledge of which keys contain which types of values. Reading values could also be implemented as reading Hash-like object:
foo["b"]
=> "some string"
foo["a"]
=> 3
from bindata.
I think you've answered your own question. You can implement some syntactic sugar so a Record appears like a Hash.
class MyObject < BinData::Primitive
Don't use Primitive. MyObject is compound, not primitive.
Take your original attempt and derive from Record, rather than Primitive.
Instead of defining get
and set
, define []
and []=
. You may need to define other methods from Hash
if you use them on the ruby side.
Your []
code will look like your get
method.
Your []=
method will likely contain a large case statement that converts the ruby object into a Term and then appends (or replaces) to the items array.
from bindata.
Thanks. I will try to implement it in the way you suggested, I just thought there might be some built-in support for what I am trying to do.
from bindata.
Apparently overriding []
and []=
in BinData::Record
breaks the implementation in BinData::Struct
. Just found it when trying to serialize a nested MyObject
. Will see if there's any way around it.
from bindata.
Everything works now. Closing question.
from bindata.
Related Issues (20)
- Support for varint HOT 3
- nbit and bit based integer HOT 2
- parse ole file err HOT 2
- Arrays are fully allocated before checking to see if they can be read HOT 3
- Customize record Bindata name HOT 2
- List example references Fixnum which is deprecated in Ruby 2.4 HOT 1
- ActiveSupport 7 compatibility - Enumerable now contains a method called maximum HOT 1
- Help: use endian to report an error, why is this?I'm using bindata in the process of writing a plugin for logstash HOT 3
- DelayedIO ignores onlyif HOT 4
- Rename parameter 'assert' as it shadows an existing method. HOT 11
- Rename parameter 'assert' as it shadows an existing method. (Linked to Closed issue-#141) HOT 2
- Calculating offsets for the delayed_io directory example HOT 2
- test failures with ruby3.1
- Dependency on Ruby 2.4 added
- Calling auto_call_delayed_io twice breaks delayed io HOT 2
- Dynamic integer HOT 1
- Question: High memory usage HOT 2
- Heterogenous array of absolutely positioned items HOT 2
- EOFError when reading unaligned little endian bit integers HOT 5
- How can I read 2 bytes (little endian) and then interpret that value as a bit field? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bindata.