<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8084037628342188612</id><updated>2014-10-12T15:00:49.356-07:00</updated><category term="Java"/><category term="Uncategorized"/><category term="Maven"/><category term="Preon"/><category term="scala"/><category term="DocBook"/><category term="Spring"/><category term="Xebia"/><category term="WADL"/><category term="IT"/><category term="Java ME"/><category term="Unix"/><category term="sbt"/><category term="JavaOne"/><category term="clojure"/><category term="ensime"/><category term="snoop"/><category term="xml"/><category term="AtRule"/><category term="Erlang"/><category term="Google Protocol Buffers"/><category term="JRockit"/><category term="JUnit"/><category term="Lua"/><category term="Oracle"/><category term="Regex"/><category term="SOA"/><category term="SunMicrosystems"/><category term="Wicket"/><category term="Xeger"/><category term="android"/><category term="compression"/><category term="dci"/><category term="emacs"/><category term="ethernet"/><category term="hamcrest"/><category term="haml"/><category term="implicit conversion"/><category term="less"/><category term="lifehacker gtd archive"/><category term="middleman"/><category term="monkeyman"/><category term="oopsla"/><category term="reStructuredText markdown"/><category term="relaxng"/><category term="schema"/><category term="solaris"/><category term="solr"/><category term="static site generator"/><category term="units"/><title type='text'>Distributed Reflections of the Third Kind</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/-/Preon'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/search/label/Preon'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-1663960191517822576</id><published>2010-09-16T10:44:00.001-07:00</published><updated>2010-09-16T10:45:20.063-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Limbo Overview</title><content type='html'>&lt;p&gt;It was already sitting on my hard drive, partially completed, but then here it is. An overview of Limbo, the expression language used in Preon to define dependencies between bound fields:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a title=&quot;View Limbo Overview on Scribd&quot; href=&quot;http://www.scribd.com/doc/37300444/Limbo-Overview&quot; style=&quot;margin: 12px auto 6px auto; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; display: block; text-decoration: underline;&quot;&gt;Limbo Overview&lt;/a&gt; &lt;object id=&quot;doc_191882036727184&quot; name=&quot;doc_191882036727184&quot; height=&quot;600&quot; width=&quot;100%&quot; type=&quot;application/x-shockwave-flash&quot; data=&quot;http://d1.scribdassets.com/ScribdViewer.swf&quot; style=&quot;outline:none;&quot; &gt;  &lt;param name=&quot;movie&quot; value=&quot;http://d1.scribdassets.com/ScribdViewer.swf&quot;&gt;&lt;param name=&quot;wmode&quot; value=&quot;opaque&quot;&gt;&lt;param name=&quot;bgcolor&quot; value=&quot;#ffffff&quot;&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;param name=&quot;allowScriptAccess&quot; value=&quot;always&quot;&gt;&lt;param name=&quot;FlashVars&quot; value=&quot;document_id=37300444&amp;access_key=key-11m5nmoxzki4rbs56gjg&amp;page=1&amp;viewMode=list&quot;&gt;&lt;embed id=&quot;doc_191882036727184&quot; name=&quot;doc_191882036727184&quot; src=&quot;http://d1.scribdassets.com/ScribdViewer.swf?document_id=37300444&amp;access_key=key-11m5nmoxzki4rbs56gjg&amp;page=1&amp;viewMode=list&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; height=&quot;600&quot; width=&quot;100%&quot; wmode=&quot;opaque&quot; bgcolor=&quot;#ffffff&quot;&gt;&lt;/embed&gt;  &lt;/object&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/1663960191517822576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=1663960191517822576' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/1663960191517822576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/1663960191517822576'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2010/09/limbo-overview.html' title='Limbo Overview'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-7492199460344082815</id><published>2010-08-23T08:37:00.000-07:00</published><updated>2010-09-01T23:59:42.614-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon repository cloned</title><content type='html'>This weekend, I found out that the Preon repository wasn&#39;t available for anonymous access. That&#39;s just awful. In order to make sure everybody has access, I also started pushing to &lt;a href=&quot;http://github.com/wspringer/preon&quot;&gt;Github&lt;/a&gt;. That way, you can get the latest versions, if you need to. If you agree with me that this is suboptimal, please raise a vote &lt;a href=&quot;http://jira.codehaus.org/browse/HAUS-1995&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Update: the issue with the Codehaus repository has been fixed. I will continue pushing to both Github and Codehaus for a while, but the blessed repository is the one on Codehaus.&lt;/i&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/7492199460344082815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=7492199460344082815' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/7492199460344082815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/7492199460344082815'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2010/08/preon-repository-cloned.html' title='Preon repository cloned'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-1254491743592562145</id><published>2010-08-08T07:12:00.000-07:00</published><updated>2010-08-08T07:12:21.444-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon updates</title><content type='html'>During the last couple of days, I continued working on &lt;a href=&quot;http://preon.codehaus.org/&quot;&gt;Preon&lt;/a&gt; again. I can easily see it fit in some of the NoSQL solutions that are gaining traction these days.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, in order to make things a little bit more manageable, I will no longer be able to retain the compatibility with previous versions, so version 1.1 will probably be renamed to version 2.0 before its release.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Maven groupId changed to org.codehaus.preon.&lt;/li&gt;&lt;li&gt;Limbo was moved into the Preon codebase, and renamed to preon-el.&lt;/li&gt;&lt;li&gt;Some things I am thinking about: Codec interface is probably going to be changed into a class incorporating all (convenience) methods for encoding and decoding. As a consequence, I will need a new name for the abstraction currently called Codec. It hasn&#39;t been done yet, but I think the API gets better if I move away from having to use Codecs all over the place. (See Joshua Bloch&#39;s bumper sticker API design.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/1254491743592562145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=1254491743592562145' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/1254491743592562145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/1254491743592562145'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2010/08/preon-updates.html' title='Preon updates'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-1537859063255746350</id><published>2010-06-20T08:31:00.000-07:00</published><updated>2010-06-20T11:40:40.237-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Supporting Maps in Preon</title><content type='html'>Just a quick write-up of some ideas that are floating around in my head since some time. I lately tried to use Preon to decode BSON files. Now, BSON is just a binary representation of a data model that is a superset of JSON. And if you think about JSON, then you can probably figure out what the most likely Java representation of the data model would be: that would clearly be a map, potentially containing other maps. However, Preon doesn&#39;t support Maps yet. So I started to wonder how to weave that in.&lt;br /&gt;&lt;br /&gt;I started thinking about different ways how Maps could be encoded on disk, and realized that it most cases they are actually encoded as lists of entries. It is not necessarily the only or most efficient way, but it&#39;s the way things are done in many cases. Let&#39;s take JSON as an example:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:javascript&quot;&gt;{&lt;br /&gt;  &quot;firstName&quot;:&quot;John&quot;,&lt;br /&gt;  &quot;lastName&quot;:&quot;Smith&quot;,&quot;&lt;br /&gt;  &quot;age&quot;:25&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;As you can see, it&#39;s actually not the internal representation of the map that is encoded here. In that case, you would most likely see a binary tree type of representation. Instead, the entire associative array is encoded as list of key-value pairs.&lt;br /&gt;&lt;br /&gt;BSON is no exception to that rule. So we need a way to decode a Map by decoding individual entries and store them in the result Map, one by one.&lt;br /&gt;&lt;br /&gt;I have been hacking around for a little while, and got this working:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;public static class Sample {&lt;br /&gt;&lt;br /&gt;    @BoundList(type= SampleEntry.class)&lt;br /&gt;    public Map&amp;lt;String,Integer&amp;gt; data;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static class SampleEntry implements Map.Entry&amp;lt;String,Integer&amp;gt; {&lt;br /&gt;&lt;br /&gt;    @BoundNumber(size=&quot;8&quot;)&lt;br /&gt;    private int keyLength;&lt;br /&gt;&lt;br /&gt;    @BoundString(size = &quot;keyLength&quot;)&lt;br /&gt;    private String key;&lt;br /&gt;&lt;br /&gt;    @BoundNumber(size=&quot;8&quot;)&lt;br /&gt;    private Integer value;&lt;br /&gt;&lt;br /&gt;    public String getKey() {&lt;br /&gt;        return key;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Integer getValue() {&lt;br /&gt;        return value;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public Integer setValue(Integer value) {&lt;br /&gt;        Integer originalValue = value;&lt;br /&gt;        this.value = value;&lt;br /&gt;        return originalValue;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;In the example above, the Sample class has an attribute called &#39;data&#39;, mapping Strings to Integer values. The @BoundList annotation might seem a little out of place on this element, at first. However, in this particular case, the key value pairs are essentially encoded as a sequence of entries. So, in that sense, it might not be all that out of place at all.&lt;br /&gt;&lt;br /&gt;The new CodecFactory that as added to Preon will be triggered by Map type of attributes that have an @BoundList annotation with the type of element set to a subtype of Map.Entry. Behind the scenes, it will first use the @BoundList annotation to create a Codec capable of decoding the List, and then copy each of the key value pairs into the result Map.&lt;br /&gt;&lt;br /&gt;The critical question of course is how the Codec responsible for reading all entries should know how to decode these entries. The answer is simple, and pretty obvious: you just do it the regular way, by making sure there is a class representing the entry with the Preon annotations set correctly. This gives you the flexibility to encode sequences of map entries any way you like. In the sample case, every entry contains of a unsigned byte stating the size of the key (in number of characters) followed by the actual key encoded in US-ASCII, followed by the value encoded as an unsigned byte.&lt;br /&gt;&lt;br /&gt;All in all, it seems to be work pretty well. There are a couple of gotchas though. When implementing this example, it turned out that we still suffer from the &lt;a href=&quot;http://kenai.com/jira/browse/PREON-9&quot;&gt;PREON-9&lt;/a&gt; bug. That&#39;s annoying. As a result, there are some things that cannot show yet.</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/1537859063255746350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=1537859063255746350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/1537859063255746350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/1537859063255746350'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2010/06/supporting-maps-in-preon.html' title='Supporting Maps in Preon'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-6227628343355691661</id><published>2010-03-19T05:54:00.000-07:00</published><updated>2010-03-19T05:55:03.846-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon Going Codehaus</title><content type='html'>There have been quite a lot of changes in Preon during the last couple of weeks. Not so much in terms of source code, but rather in where we are planning to go (project hosting) and who&#39;s going to work on it.&lt;br /&gt;&lt;br /&gt;First of all, I&#39;m happy to say that Samuli Saarinen joined the project. He already fixed numerous bugs, so I&#39;m happy to welcome him aboard.&lt;br /&gt;&lt;br /&gt;Next to that, we also decided to move Preon to Codehaus. This is going to affect Preon in a number of ways:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;All project resources will be hosted at a single location. So no more searching on Kenai, Sourceforge, Atlassian, etc.&amp;nbsp;(I&#39;m sure that&#39;s a relief for many people.)&amp;nbsp;&lt;/li&gt;&lt;li&gt;I expect the package and Maven artifact names will change at some point to reflect the new location.&lt;/li&gt;&lt;li&gt;We might move from Subversion to Git.&amp;nbsp;&lt;/li&gt;&lt;li&gt;The existing mailing lists will probably go away to be replaced by Codehaus mailing lists.&lt;/li&gt;&lt;li&gt;We will have a continuous integration build hosted at Codehaus.&amp;nbsp;&lt;/li&gt;&lt;li&gt;The SNAPSHOT repositories will move somewhere else.&lt;/li&gt;&lt;li&gt;Limbo and Pecia might be moved back into Preon, to ease further development.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;There is a chance that you will be affected by these changes. We will try to do our best to make it as least disruptive as possible though. So don&#39;t expect any big changes before an upfront announcement.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In summary, I just want to say that I think this is all excellent news. Sure, it will take some time before it stabilizes, but once the entire migration is done, we will have an environment that will help us to grow Preon in a healthy way in the future.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/6227628343355691661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=6227628343355691661' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/6227628343355691661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/6227628343355691661'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2010/03/preon-going-codehaus.html' title='Preon Going Codehaus'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-6983467755333603909</id><published>2010-01-21T08:49:00.000-08:00</published><updated>2010-01-29T05:12:11.845-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>OOPSLA slides uploaded</title><content type='html'>&lt;div style=&quot;width:425px;text-align:left&quot; id=&quot;__ss_2664186&quot;&gt;&lt;a style=&quot;font:14px Helvetica,Arial,Sans-serif;display:block;margin:0px 0 3px 0;text-decoration:underline;&quot; href=&quot;http://www.slideshare.net/springerw/oopsla-talk-on-preon&quot; title=&quot;OOPSLA Talk on Preon&quot;&gt;OOPSLA Talk on Preon&lt;/a&gt;&lt;object style=&quot;margin:0px&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=preon-oopsla-final-091207013254-phpapp02&amp;stripped_title=oopsla-talk-on-preon&quot; /&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;/&gt;&lt;param name=&quot;allowScriptAccess&quot; value=&quot;always&quot;/&gt;&lt;embed src=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=preon-oopsla-final-091207013254-phpapp02&amp;stripped_title=oopsla-talk-on-preon&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style=&quot;font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;&quot;&gt;View more &lt;a style=&quot;text-decoration:underline;&quot; href=&quot;http://www.slideshare.net/&quot;&gt;documents&lt;/a&gt; from &lt;a style=&quot;text-decoration:underline;&quot; href=&quot;http://www.slideshare.net/springerw&quot;&gt;Wilfred Springer&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/6983467755333603909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=6983467755333603909' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/6983467755333603909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/6983467755333603909'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2010/01/oopsla-slides-uploaded.html' title='OOPSLA slides uploaded'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-2111042791410174563</id><published>2010-01-11T23:04:00.000-08:00</published><updated>2010-01-16T05:59:20.720-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>The Size of the Slice</title><content type='html'>&lt;div style=&quot;text-align: left; &quot;&gt;During the last couple of months, I have been going back and forward on how to deal with slicing while encoding. If it comes to clearing your mind, nothing helps as explaining it to others (well, perhaps there are some things that help even better), so here goes nothing:&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;b&gt;Slicing&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;First question: what is slicing anyway? In Preon, slicing is basically creating a partial view on a BitBuffer. If you happen to have a BitBuffer with 512 bits, and you slice it, what you get is a new BitBuffer. If your current position is on bit 9, and you create a slice of 16 bits (hardly realistic, but it&#39;s just easier to work with smaller numbers), then you get a BitBuffer that contains 16 bits. On position 0, it will have the value of position 9 in the original BitBuffer, and so on.&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;b&gt;Use of Slices&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;Slices are useful in situations in 1) you have a collection of things and 2) you can&#39;t predict how many items it has, but you can predict how much space it occupies in total. Basically, if you first slice the BitBuffer, you can basically just keep reading until you the end of the BitBuffer. In reality, the BitBuffer can contain way more data, but you can never read beyond the end of the slice.&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;b&gt;The Size of the Slice&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;There are essentially two different ways to define the size of the slice: the size of the slice could either be a static value, or it can be defined in terms of data read upstream. As an example of the second case: there might be a situation in which the size of the slice is defined by a value encoded as an int &lt;i&gt;right in front of the start of the actual slice&lt;/i&gt;.&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;b&gt;Ways to Define a Slice&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;Out of the box, Preon provides two different ways to define a slice. There&#39;s a &#39;@Slice&#39; annotation, and a &#39;@LengthPrefix annotation. The second annotation existed before the first one, and is not as powerful as the first one. So while I was thinking about all of this, I did consider dropping @LengthPrefix entirely.&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;b&gt;So how does it work?&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;The @Slice annotatation is defined like this: @Slice(size=&quot;...&quot;). In this case the size is a Limbo expression, so it can either be a static value or an expression that incorporates data read upstream.&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;The @LengthPrefix annotation is defined like this: @LengthPrefix(size=&quot;...&quot;, endian={ByteOrder}). In this case, the size is not the size of the actual slice, but the size of a value represented as an integer that &lt;i&gt;holds&lt;/i&gt; the size of the slice. (See the example below.)&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://1.bp.blogspot.com/_S3C3xc3P7WU/S0-BY8Uk7aI/AAAAAAAAAH0/OlQEoldiML0/s1600-h/slices.png&quot;&gt;&lt;img src=&quot;http://1.bp.blogspot.com/_S3C3xc3P7WU/S0-BY8Uk7aI/AAAAAAAAAH0/OlQEoldiML0/s400/slices.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5426698341514014114&quot; style=&quot;cursor: pointer; width: 400px; height: 355px; &quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;So, you could say that with @Slice you can do everything that can be done with @LengthPrefix and a little more, but not the other way around. So far, there doesn&#39;t seem to be a reason to keep @LengthPrefix any longer; it seems we can just deprecate it. But there is a little more to that. Read on.&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;b&gt;Encoding&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;Encoding a slice is in a way more complicated than decoding it. Suppose that the slice is defined to have a fixed size. In that case, the size of the data to be encoded within that slice should not be bigger than the size of the slice itself. &lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;In case the size of the slice is a function of data read upstream, then it becomes even more complicated. If the data within the slice requires a certain amount of bits, then that function needs to result in that number of bits. Consequently, the variables used in that function need to have proper values, but since those variables are read from bits upstream, those bits need to have the proper value as well. So, the space required by downstream data requires upstream bits to have a certain value. &lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;It&#39;s imported to note that this is a specific case of some challenge that has been reported before, in a previous post. The @LengthPrefix shines a different light on it though. &lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;The following two snippets are essentially the same:&lt;/div&gt;&lt;pre class=&quot;brush:java&quot;&gt;// Example 1:&lt;br /&gt;@BoundNumber(size=&quot;8&quot;) int size;&lt;br /&gt;@Slice(size=&quot;size&quot;) @BoundList byte[];&lt;br /&gt;&lt;br /&gt;// Example 2:&lt;br /&gt;@LengthPrefix(size=&quot;8&quot;) @BoundList byte[];&lt;br /&gt;&lt;/pre&gt;&lt;div style=&quot;text-align: left; &quot;&gt;The Codecs generated by Preon will be almost identical. The main difference is that, in the first case, the size attribute is something that is accessible by the client. In the second case, it is data that will be read from the BitBuffer, but it will &lt;i&gt;never be exposed to the Preon user&lt;/i&gt;. &lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;Because of the information hiding in case of @LengthPrefix, it will be easier to preserve the dependency between the size attribute and the actual size of the slice. Encoding the slice in case of @LengthPrefix could work like this:&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;ul&gt;&lt;li&gt;Determine if the size of data structure from the slice can be determined before it is encoded. In case it can, simply write the size of the slice to the BitChannel first, and then continue writing the data structure that needs to be encoded.&lt;/li&gt;&lt;li&gt;Otherwise, write the entire data structure to a temporary BitChannel backed by an in memory buffer. Then, before flushing the contents of this buffer into the target BitChannel, determine the required size of the buffer, and write that value to the target channel first. Then write the contents of the temporary buffer into the BitChannel.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;So, this will guarantee that the encoded representation will &lt;i&gt;always be correct&lt;/i&gt;. Something that is currently impossible when using @Slice. For @Slice, we it is possible to write to a temporary buffer, and determine the required size, but then there is not much we can do with that information, since it&#39;s data that could have been changed. (And having the ability to preserve dependencies between fields that can be changed is currently deliberately left out of the Preon roadmap.) &lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;Trying to summarize my thoughts. Although there is some benefit in using @LengthPrefix when encoding, I&#39;m still considering taking it out. @LenghtPrefix is only going to be a benefit in a few cases, whereas the problem that manifests itself when using @Slice exposes a challenge that 1) is way harder to solve, but also 2) much more awarding to solve. &lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;If I take that route, then there will not be a reason for having the ability to write the slice to a temporary buffer to determine it&#39;s size. It&#39;s possible to write to a BitChannel directly, and then throw an exception if the number of bits required exceeds the size defined by the slice. &lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left; &quot;&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/2111042791410174563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=2111042791410174563' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/2111042791410174563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/2111042791410174563'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2010/01/size-of-slice.html' title='The Size of the Slice'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_S3C3xc3P7WU/S0-BY8Uk7aI/AAAAAAAAAH0/OlQEoldiML0/s72-c/slices.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-7198126699730853302</id><published>2009-10-28T19:07:00.001-07:00</published><updated>2009-10-28T20:12:51.127-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="JRockit"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon on JRockit</title><content type='html'>After my Preon talk earlier today, Alex Buckley warned me that reflection is not going to guarantee that the fields will always be returned in the same order. Preon currently relies on the fields to be returned in the order in which they were defined, to some extent.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That is, if this is the data structure you defined:&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;public class Image {&lt;br /&gt;@Bound int width;&lt;br /&gt;@Bound int height;&lt;br /&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Then Preon will expect that the reflection API will also return the fields in this order. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think I sort of knew this in the back of my head, but it never failed any of the tests, so I stopped worrying about it. So, the question is, should I start worrying now? It&#39;s clearly undesirable to depend on some coincidental properties of a Java VM, but are there actually VMs that will return a different field ordering? With IBMs VM being based on Sun&#39;s VM, it&#39;s unlikely they will differ. So that leaves us with JRockit.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the end, I figured it would be wise to have an automated test that at least guarantees that the current setup also wors on JRockit. It doesn&#39;t solve the problem, but it does provide some degree of guarantee that the problem will usually not manifest itself. And it turns out, &lt;a href=&quot;http://os.xebia.com/bamboo/browse/PREON-JROCKIT&quot;&gt;the test succeeds&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/7198126699730853302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=7198126699730853302' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/7198126699730853302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/7198126699730853302'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/10/preon-on-jrockit.html' title='Preon on JRockit'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-3711684003645886185</id><published>2009-10-15T12:17:00.000-07:00</published><updated>2009-10-15T12:19:36.629-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Maven Archetype for Simple Preon Project</title><content type='html'>It&#39;s there. Just got to &lt;a href=&quot;http://preon.flotsam.nl/getting-started.html&quot;&gt;http://preon.flotsam.nl/getting-started.html&lt;/a&gt; and follow the instructions. This is by far the easiest way to get started.</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/3711684003645886185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=3711684003645886185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/3711684003645886185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/3711684003645886185'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/10/maven-archetype-for-simple-preon.html' title='Maven Archetype for Simple Preon Project'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-6422789388076610751</id><published>2009-10-13T12:14:00.001-07:00</published><updated>2009-10-13T13:05:32.787-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon Encoding Roadmap</title><content type='html'>In my &lt;a href=&quot;http://blog.flotsam.nl/2009/10/inserting-data-using-preon.html&quot;&gt;previous post&lt;/a&gt;, I highlighted some of the challenges and questions to be answered before Preon can be made to support encoding as well. The main problem is not so much that it is hard to understand &lt;em&gt;how&lt;/em&gt; the data should be encoded. That&#39;s all pretty clear. The meta data gathered by Preon provides sufficient detail to make that fairly easy to do. No, the real problem is in preserving consistency.&lt;br /&gt;&lt;br /&gt;If you really try to imagine the ultimate goal, then it&#39;s immediately clear that it will be close to impossible to get there in one step.  So what do you do? You break things up in phases. That&#39;s what I tried to do tonight:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://1.bp.blogspot.com/_S3C3xc3P7WU/StTc-LZ-Y4I/AAAAAAAAAF8/NjlqCGD_ZYg/s1600-h/stages.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 305px; height: 351px;&quot; src=&quot;http://1.bp.blogspot.com/_S3C3xc3P7WU/StTc-LZ-Y4I/AAAAAAAAAF8/NjlqCGD_ZYg/s400/stages.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5392177614641062786&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The picture above depicts the different stages for getting closer to where I want Preon to be. Read it from the bottom up. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Phase 1: Writing all data to a stream&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Currently, the Codec only defines a decode operation. We clearly need an encode operation as well. The decode operation is going to take the object passed in and write it to the output channel. Period. By adding this operation, you &lt;i&gt;will&lt;/i&gt; be able to encode data, however when you actually make changes to the data, you&#39;re basically on your own. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are some of the complications that could occur if you change the data:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;In case Preon loaded an instance of its own LazyLoadingList, then trying to modify that list is going to throw exceptions.&lt;/li&gt;&lt;li&gt;If you replace the value of an attribute that is used in Limbo expressions, there&#39;s not only a chance that you write corrupted data, but there&#39;s also a chance that you will not even be able to continue to read the data any longer. Remember, Preon is decoding lazily. It might not even have read the data that you are about to write. By changing the attributes that Preon uses in calculating the starting point of a section of data to read, you might get in trouble.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;b&gt;Phase 2: Binding to public accessors&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We need to be able to understand when code outside of Preon is making changes to an object that was loaded using Preon, because if it does, then we can no longer afford to drop a cached version of that instance. However, currently Preon only binds to fields, and not to bean-type accessors. It&#39;s going to be close to impossible to track changes to those private fields, but it will be possible to track changes to those fields if Preon binds to the accessor methods rather than the fields. So, we will probably need that feature to be there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Phase 3: Copy on change&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Maybe this is not the right term. In some cases, all we need to do is make sure that we hold on to a cached copy indefinitely, until data is persisted. In other cases, we will need to make sure that we actually replace the entire copy of an existing object and replace it by something else. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Phase 4: Consistency checks while writing&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As I said, making sure that we preserve consistency over the entire file is going to be one of the biggest challenges. The previous step has made sure that we can actually change the file and write it again, but it&#39;s not going to guarantee that whatever is going to be written is consistent. For that, we need something else. This phase is about adding a feature that will check consistency while writing. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(Consequently, data early in the file will always prevail over data later on in the file. If the file first contains an integer denoting the size of a list following, and that value is greater than the actual size of the list when the list needs to be written, the list either needs to be truncated or grow, or an exception will have to be thrown. &lt;i&gt;This phase is about making sure an exception is thrown.&lt;/i&gt;)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Phase 5: Rewrite only if required&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In many cases, it&#39;s not going to be required to first load data into an object and then write it to output again. If the object encoded did not change, then we can just stream the from the original source. (In this case, the BitBuffer.) This is - hopefully - going to be an optimization that is going to pay off big time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Phase 6: Autocorrecting&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In phase 4, I already said that there will be cases in which you ideally want the list of elements to grow or shrink if the attribute that denotes the number of item in the list is updated. This phase is about considering solutions like these. It will probably be quite hard, if not impossible at all, but it&#39;s worth to take it into consideration.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Phase 7, 8, 9, 10, ... &lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;O man, if only I would have time.&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/6422789388076610751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=6422789388076610751' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/6422789388076610751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/6422789388076610751'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/10/preon-encoding-roadmap.html' title='Preon Encoding Roadmap'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_S3C3xc3P7WU/StTc-LZ-Y4I/AAAAAAAAAF8/NjlqCGD_ZYg/s72-c/stages.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-4624512842268370817</id><published>2009-10-11T12:45:00.000-07:00</published><updated>2009-10-11T23:47:26.623-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Inserting Data Using Preon</title><content type='html'>&lt;div&gt;I started work on supporting encoding data the other day. There are quite a few complications, and I noticed that just jotting them down is not going to help or anyone else to come up with some solutions. First I need a better description of the problem.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I decided I would add a couple of examples that are slightly more detailed, in order to be able to highlight the problems, and explain the solutions that I&#39;m currently thinking of.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first example is about a simple image format. (I&#39;m just so grateful we have images. Where would I have been without them. They always seem to serve as be the best examples in cases like this.) It only defines a slot for the number of pixels and then defines the color values for those pixels. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://4.bp.blogspot.com/_S3C3xc3P7WU/StI3Pv5ZbnI/AAAAAAAAAFk/_i0Ai35fEZI/s1600-h/image-before.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 284px;&quot; src=&quot;http://4.bp.blogspot.com/_S3C3xc3P7WU/StI3Pv5ZbnI/AAAAAAAAAFk/_i0Ai35fEZI/s400/image-before.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5391432447610678898&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;The example above illustrates an instance of this model, based on a 400 pixel image. The orange region highlights the first pixel value in the byte stream. It shows the relation between the object instance and the corresponding location in the byte stream.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, if the above would have been decoded using Preon, then the code would have probably looked a little like this:&lt;/div&gt;&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;class Image {&lt;br /&gt;@Bound int nrPixels;&lt;br /&gt;@BoundList(size=&quot;nrPixels&quot;) List&amp;lt;Color&amp;gt; pixels;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Color {&lt;br /&gt;@Bound byte red;&lt;br /&gt;@Bound byte green;&lt;br /&gt;@Bound byte blue;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;It clearly shows the link between the nrPixels attribute and the pixels attribute. Now, suppose that Preon would allow you to modify the data and then encode the data. What would that look like in this case? The image below is trying to capture it:&lt;/div&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://3.bp.blogspot.com/_S3C3xc3P7WU/StI5XW9NhpI/AAAAAAAAAFs/Ll2x37-Peg0/s1600-h/image-after.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 354px; height: 400px;&quot; src=&quot;http://3.bp.blogspot.com/_S3C3xc3P7WU/StI5XW9NhpI/AAAAAAAAAFs/Ll2x37-Peg0/s400/image-after.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5391434777377998482&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;So, only inserting a single pixel would already require quite some changes. In fact, it would basically require a rewrite of the entire byte stream.&lt;/div&gt;&lt;ul&gt;&lt;li&gt;The nrPixels attribute would change from 0x190 to 0x191. (See pink region.)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The entire pixel array would have to be shifted to the right in order to allocate space for the new pixel to be inserted.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;That new pixel would have to be inserted. (See orange region.)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;The question that I&#39;m trying to answer myself is how Preon should deal with this. There are a couple of challenges, given the way Preon works.&lt;/div&gt;&lt;ul&gt;&lt;li&gt;If the List&lt;color&gt; pixel &#39;array&#39; would have supported the insert operation, then the &#39;nrPixels&#39; attribute is not automatically updated if you would insert a new pixel.&lt;/color&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Changing the nrPixels attribute would not automatically allocate a new element in the list of pixels.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Given the fact that Preon writes to private fields of objects, it&#39;s going to be pretty hard to notice updates to any of these fields at all.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Now, that&#39;s quite a few challenges. My first thoughts on this:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Since the List&lt;color&gt; pixels attribute will cause Preon to insert an instance of its own List class, it should be possible to intercept changes to that list. If the size of the list is based on an attribute value read upstream, then it should be possible to update that value with every change to the pixels list.&lt;/color&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;However, this would &lt;em&gt;only&lt;/em&gt; work in case that attribute value is &lt;em&gt;only&lt;/em&gt; defining an encoding/decoding attribute for &lt;em&gt;that&lt;/em&gt; specific List. If there are other data elements read downstream that are based on that same attribute value, it would be &lt;em&gt;impossible&lt;/em&gt; to update it automatically.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In cases like these, Preon could still be able to check the dependencies as a constraint and abort the encoding process if the constraints are violated.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/4624512842268370817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=4624512842268370817' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/4624512842268370817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/4624512842268370817'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/10/inserting-data-using-preon.html' title='Inserting Data Using Preon'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_S3C3xc3P7WU/StI3Pv5ZbnI/AAAAAAAAAFk/_i0Ai35fEZI/s72-c/image-before.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-7722826673856947034</id><published>2009-10-10T02:56:00.001-07:00</published><updated>2009-10-10T03:04:37.770-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Changing Preon Modules</title><content type='html'>I know this could be painful, but I will go ahead and do it anyway. The last couple of weeks I spent some of my sparetime to work on a capability for outputting data from Preon. And I planned to support streaming output first. Now, that requires a couple of new abstractions that I first added to a module called preon-bitchannel. But I think I&#39;m going to collapse preon-bitbuffer and preon-bitchannel into one new module: preon-io. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The two abstractions for reading bit&#39;stream&#39; type of content are just so intertwined that it hardly makes sense to have two different modules for it. For instance, one of the capabilities that will turn up in BitBuffer is the capability to &#39;stream&#39; content directly to an output channel. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, why is this important? It&#39;s a little hard to explain, but I will give it a go. First of all, you should be aware of the fact that Preon is loading data lazily. That means that - in some cases - rather than loading data aggressively, it will keep a pointer to a position in the BitBuffer, and only start reading from that position if the application is actually accessing that data. Now, if you would be able to update data, but you would leave that specific segment untouched, then encoding would be as simple as writing from the BitBuffer directly to the output channel. And an implementation could do that extremely efficiently if the buffer and channel abstractions are designed to work with each other. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Any way, a code example probably would help a lot in this case. Sit tight. Something is coming.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/7722826673856947034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=7722826673856947034' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/7722826673856947034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/7722826673856947034'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/10/changing-preon-modules.html' title='Changing Preon Modules'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-6576211501041531879</id><published>2009-09-26T00:46:00.001-07:00</published><updated>2009-09-26T01:05:17.826-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Lua"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Parameterized Byte Order</title><content type='html'>I started checking out Lua byte code a minute ago. (Thanks to &lt;a href=&quot;http://stackoverflow.com/questions/1480678/luas-bytecode-specification&quot;&gt;Stackoverflow&lt;/a&gt; for finding its location.) Now, I haven&#39;t started reading all of the details yet, but there is one section that already is proving to be troublesome. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p style=&quot;margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica&quot;&gt;&lt;b&gt;1 byte &lt;/b&gt;Endianness flag (default 1)&lt;/p&gt; &lt;p style=&quot;margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica&quot;&gt;• 0=big endian, 1=little endian&lt;/p&gt; &lt;p style=&quot;margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica&quot;&gt;&lt;b&gt;1 byte &lt;/b&gt;Size of int (in bytes) (default 4)&lt;/p&gt; &lt;p style=&quot;margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica&quot;&gt;&lt;b&gt;1 byte &lt;/b&gt;Size of size_t (in bytes) (default 4)&lt;/p&gt; &lt;p style=&quot;margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica&quot;&gt;&lt;b&gt;1 byte &lt;/b&gt;Size of Instruction (in bytes) (default 4)&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It&#39;s the byte order. It means that - if I would try to decode Lua bytecode using Preon - I would have to make some changes to the annotations. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Currently, the annotations for decoding numeric data look like this:&lt;/div&gt;&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;@BoundNumber(byteOrder=LittleEndian)&lt;br /&gt;@BoundNumber(byteOrder=BigEndian)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;... but now that byteOrder needs to be defined by something read before.  I guess there are a couple of ways to deal with it:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Option 1: Have the ability to change the &#39;global&#39; default byte order setting as a consequence of reading a value&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, global doesn&#39;t really need to be global. It might be good enough if it would be a default for the current &#39;lexical scope&#39;. So basically, if you would read a block of data that would indicate a change in the byte order, then Preon could basically respect those changes for anything read within that block.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Option 2: Have the ability to refer to ByteOrder enum values read previously from @BoundNumber annotations&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now this is harder. Not undoable, because this is exactly what you can already do for reading the number of bits for instance:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;@BoundNumber(size=&quot;header.numberOfBits&quot;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;For byte order, it could be similar:&lt;/div&gt;&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;@BoundNumber(byteOrder=&quot;header.byteOrder&quot;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;However, this would mean that instead of typing byteOrder as an enum value of type ByteOrder, it would be a String. That would be less compile time safe.  And it would require an incredible number of complex pointers pointing to that header attribute. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But maybe there is a third option. Add a new ByteOrder enum value called Default, basically indicating that the ByteOrder is defined somewhere else. Currently, the default is LittleEndian. But maybe that default needs to be set as an annotation as well.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, there is a lot to think about. I will see if I can answer this one today.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/6576211501041531879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=6576211501041531879' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/6576211501041531879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/6576211501041531879'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/09/parameterized-byte-order.html' title='Parameterized Byte Order'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-4784465415513832707</id><published>2009-09-22T11:59:00.000-07:00</published><updated>2009-09-22T12:13:46.643-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon Encoding Started</title><content type='html'>I started work on supporting Preon the other day. One of the first things I will have to do is to define the interface that will be used to write data. Picking that interface is not trivial. One of the ideas that I suggested last year is &lt;i&gt;not&lt;/i&gt; to try to keep Preon symmetrical; that is, it probably makes sense &lt;i&gt;not&lt;/i&gt; to preserve the random access type of access to the data when writing data, but write to a streaming type of interface instead. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are a couple of reasons why that would make sense:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;In-place editing is just going to be way to painful: if you would a couple of elements to a List, you would need to move blocks of data around. I can hardly imagine what that would look like, and it&#39;s probably not going to be very efficient. &lt;/li&gt;&lt;li&gt;Now, regardless on what the repercussions would be in terms of moving blocks of data around in memory and on disk, it would also imply changing all pointers that still have a reference to other places in that buffer of bytes. So, suppose that you would have two lazy loading lists after each other. Then in order to be able to lookup elements of the second list on the fly, that list will keep a reference to its starting point. That reference will be based on the offset of the start of its content relatively to the beginning of the file. Now, inserting elements in the &lt;i&gt;first&lt;/i&gt; list &lt;i&gt;also&lt;/i&gt; needs to result in updating those references. &lt;/li&gt;&lt;li&gt;Preon aims to be threadsafe.  That complicates matters further. As a result of adding an element to a list, thousands of pointers might potentially require an update, but from the perspective of the client consistency would need to be preserved during that transaction. This calls for an STM type-of solution. &lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I&#39;m still not sure if it would be totally ridiculous to even support in-place editing, but it&#39;s just going to be to hard at this stage. Having the ability to 1) process changes, and 2) to persist all of those changes to disk in a single snapshot would already be quite a challenge, but it would be an awesome feature.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tomorrow, I will try to add some thoughts on the shape of the interface that I am currently considering. &lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/4784465415513832707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=4784465415513832707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/4784465415513832707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/4784465415513832707'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/09/preon-encoding-started.html' title='Preon Encoding Started'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-925325351277467947</id><published>2009-08-30T06:39:00.000-07:00</published><updated>2009-08-30T06:44:22.873-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="oopsla"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon Presentation at OOPSLA 2009</title><content type='html'>&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;I will present &lt;a href=&quot;http://preon.flotsam.nl/&quot;&gt;Preon&lt;/a&gt; at &lt;a href=&quot;http://www.oopsla.org/oopsla2009/&quot;&gt;OOPSLA 2009&lt;/a&gt;. That&#39;s going to be fun. I have been wondering if it would be possible to squeeze in encoding before October 25.&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 217px; height: 133px;&quot; src=&quot;http://4.bp.blogspot.com/_S3C3xc3P7WU/SpqCKn9ZJ6I/AAAAAAAAAFU/YUzogKhv1ng/s400/Picture+9.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5375752224256894882&quot; /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/925325351277467947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=925325351277467947' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/925325351277467947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/925325351277467947'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/08/preon-presentation-at-oopsla-2009.html' title='Preon Presentation at OOPSLA 2009'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_S3C3xc3P7WU/SpqCKn9ZJ6I/AAAAAAAAAFU/YUzogKhv1ng/s72-c/Picture+9.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-5956817951370866646</id><published>2009-08-13T01:36:00.000-07:00</published><updated>2009-08-13T10:33:22.420-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ethernet"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><category scheme="http://www.blogger.com/atom/ns#" term="snoop"/><title type='text'>Getting the Ethernet Frame</title><content type='html'>A couple of days ago, I &lt;a href=&quot;http://blog.flotsam.nl/2009/08/snoop-using-preon.html&quot;&gt;blogged about&lt;/a&gt; using &lt;a href=&quot;http://preon.flotsam.nl/&quot;&gt;Preon&lt;/a&gt; to take a Snoop file apart. It&#39;s interesting that it actually worked, but then again, it hardly retrieved any valuable data. Given that most of the data floating around on our networks is actually ethernet based, it would be nice if Preon would actually be able to take apart the data sections as well.&lt;br /&gt;&lt;br /&gt;Obviously, I wouldn&#39;t be telling you all of this, if Preon would not be able to do that. So let me show you how. The full code is listed below.&lt;br /&gt;&lt;br /&gt;The important bits are in line 60.&lt;br /&gt;&lt;br /&gt;The code that we used to have there was this:&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;@Slice(size=&quot;(packetRecordLength - 24) * 8&quot;)&lt;br /&gt;@BoundList(size=&quot;includedLength&quot;)&lt;br /&gt;private byte[] packetData;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the new version of SnoopFile, that changed into:&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;@Slice(size = &quot;(packetRecordLength - 24) * 8&quot;)&lt;br /&gt;@BoundObject(selectFrom = @Choices(alternatives =&lt;br /&gt; @Choice(condition = &quot;outer.header.datalinkType==DatalinkType.ETHERNET&quot;, type = EthernetFrame.class))&lt;br /&gt;)&lt;br /&gt;private Object packetData;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Basically, instead of decoding the packet data into a byte array, it&#39;s now immediately turned into an object. An object that actually has the relevant data already decoded. Now, don&#39;t be alarmed by the type of packetData. In the new code it&#39;s declared to be of type java.lang.Object. That&#39;s just to make sure that it will be able to cover for all of the types of packet data that you could possibly encounter. In the common case, it will be ethernet frames. But Snoop is able to capture data for other data link types as well, and it&#39;s fairly unlikely that these different types of packet data would have commonalities to be captured in a base class.&lt;br /&gt;&lt;br /&gt;So, even thought he type of packetData is java.lang.Object, Preon will actually decode packet data in objects of a particular type, based on the data link type. The selectFrom attribute on @BoundObject contains the rules for picking the appropriate type of object. Currently, it only covers for Ethernet packages. It basically reads: if the data link type read as part of the header is Ethernet, then decode the data into an instance of EthernetFrame.&lt;br /&gt;&lt;br /&gt;The EthernetFrame itself is defined like this:&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;public static class EthernetFrame {&lt;br /&gt;&lt;br /&gt;   @BoundList(size = &quot;6&quot;)&lt;br /&gt;   private byte[] destinationAddress;&lt;br /&gt;  &lt;br /&gt;   @BoundList(size = &quot;6&quot;)&lt;br /&gt;   private byte[] sourceAddress;&lt;br /&gt;&lt;br /&gt;   @BoundNumber(size = &quot;16&quot;)&lt;br /&gt;   private int type;&lt;br /&gt;&lt;br /&gt;   @BoundList(size=&quot;outer.includedLength - (6 + 6 + 2)&quot;)&lt;br /&gt;   private byte[] data;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Not much to explain here. It&#39;s pretty much straightforward Preon code. Note that the number of bytes is calculated based on an attribute of the packet record. Since the EthernetFrame is read as part of the PacketRecord, you *can* actually refer to the &#39;outer&#39; context, and reference attributes of that outer context.&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;public class SnoopFile {&lt;br /&gt;&lt;br /&gt;@Bound&lt;br /&gt;private FileHeader header;&lt;br /&gt;&lt;br /&gt;@BoundList(type = PacketRecord.class)&lt;br /&gt;private List&amp;lt;PacketRecord&gt; records;&lt;br /&gt;&lt;br /&gt;public FileHeader getHeader() {&lt;br /&gt; return header;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public List&amp;lt;PacketRecord&gt; getRecords() {&lt;br /&gt; return records;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static class FileHeader {&lt;br /&gt;&lt;br /&gt; @BoundBuffer(match = { 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0x00, 0x00, 0x00 })&lt;br /&gt; private byte[] identificationPattern;&lt;br /&gt;&lt;br /&gt; @BoundNumber(byteOrder = ByteOrder.BigEndian)&lt;br /&gt; private int versionNumber;&lt;br /&gt;&lt;br /&gt; @BoundNumber(size = &quot;32&quot;, byteOrder = ByteOrder.BigEndian)&lt;br /&gt; private DatalinkType datalinkType;&lt;br /&gt;&lt;br /&gt; public int getVersionNumber() {&lt;br /&gt;  return versionNumber;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public DatalinkType getDatalinkType() {&lt;br /&gt;  return datalinkType;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@ImportStatic(DatalinkType.class)&lt;br /&gt;public static class PacketRecord {&lt;br /&gt;&lt;br /&gt; @BoundNumber(byteOrder = ByteOrder.BigEndian, size = &quot;32&quot;)&lt;br /&gt; private long originalLength;&lt;br /&gt;&lt;br /&gt; @BoundNumber(byteOrder = ByteOrder.BigEndian, size = &quot;32&quot;)&lt;br /&gt; private long includedLength;&lt;br /&gt;&lt;br /&gt; @BoundNumber(byteOrder = ByteOrder.BigEndian, size = &quot;32&quot;)&lt;br /&gt; private long packetRecordLength;&lt;br /&gt;&lt;br /&gt; @BoundNumber(byteOrder = ByteOrder.BigEndian, size = &quot;32&quot;)&lt;br /&gt; private long cumulativeDrops;&lt;br /&gt;&lt;br /&gt; @BoundNumber(byteOrder = ByteOrder.BigEndian, size = &quot;32&quot;)&lt;br /&gt; private long timestampSeconds;&lt;br /&gt;&lt;br /&gt; @BoundNumber(byteOrder = ByteOrder.BigEndian, size = &quot;32&quot;)&lt;br /&gt; private long timestampMicroseconds;&lt;br /&gt;&lt;br /&gt; @Slice(size = &quot;(packetRecordLength - 24) * 8&quot;)&lt;br /&gt; @BoundObject(selectFrom = @Choices(alternatives = @Choice(condition = &quot;outer.header.datalinkType==DatalinkType.ETHERNET&quot;, type = EthernetFrame.class)))&lt;br /&gt; private Object packetData;&lt;br /&gt;&lt;br /&gt; public long getOriginalLength() {&lt;br /&gt;  return originalLength;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public long getIncludedLength() {&lt;br /&gt;  return includedLength;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public long getPacketRecordLength() {&lt;br /&gt;  return packetRecordLength;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public long getCumulativeDrops() {&lt;br /&gt;  return cumulativeDrops;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public long getTimestampSeconds() {&lt;br /&gt;  return timestampSeconds;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public long getTimestampMicroseconds() {&lt;br /&gt;  return timestampMicroseconds;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object getPacketData() {&lt;br /&gt;  return packetData;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static class EthernetFrame {&lt;br /&gt;&lt;br /&gt;  @BoundList(size = &quot;6&quot;)&lt;br /&gt;  private byte[] destinationAddress;&lt;br /&gt;&lt;br /&gt;  @BoundList(size = &quot;6&quot;)&lt;br /&gt;  private byte[] sourceAddress;&lt;br /&gt;&lt;br /&gt;  @BoundNumber(size = &quot;16&quot;)&lt;br /&gt;  private int type;&lt;br /&gt;&lt;br /&gt;  @BoundList(size=&quot;outer.includedLength - (6 + 6 + 2)&quot;)&lt;br /&gt;  private byte[] data;&lt;br /&gt;&lt;br /&gt;  public String getDestinationAddress() {&lt;br /&gt;   return render(destinationAddress);&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  public String getSourceAddress() {&lt;br /&gt;   return render(sourceAddress);&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  private String render(byte[] address) {&lt;br /&gt;   StringBuilder builder = new StringBuilder();&lt;br /&gt;   for (int i = 0; i &amp;lt; address.length; i++) {&lt;br /&gt;    if (i != 0) {&lt;br /&gt;     builder.append(&#39;:&#39;);&lt;br /&gt;    }&lt;br /&gt;    builder.append(Integer.toHexString(0xff&amp;amp;address[i]));&lt;br /&gt;   }&lt;br /&gt;   return builder.toString();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static enum DatalinkType {&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(0)&lt;br /&gt; IEEE_802_3,&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(1)&lt;br /&gt; IEEE_802_4_TOKEN_BUS,&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(2)&lt;br /&gt; IEEE_802_5_TOKEN_RING,&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(3)&lt;br /&gt; IEEE_802_6_METRO_NET,&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(4)&lt;br /&gt; ETHERNET,&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(5)&lt;br /&gt; HLDC,&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(6)&lt;br /&gt; CHARACTER_SYNCHRONOUS,&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(7)&lt;br /&gt; IBM_CHANNEL_TO_CHANNEL,&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(8)&lt;br /&gt; FDDI,&lt;br /&gt;&lt;br /&gt; @BoundEnumOption(9)&lt;br /&gt; OTHER,&lt;br /&gt;&lt;br /&gt; UNASSIGNED&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/5956817951370866646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=5956817951370866646' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/5956817951370866646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/5956817951370866646'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/08/getting-ethernet-frame.html' title='Getting the Ethernet Frame'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-3526054868850245793</id><published>2009-08-12T07:10:00.001-07:00</published><updated>2009-08-12T07:19:44.696-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Enums in Preon</title><content type='html'>&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;You might have noticed in my previous entry that I introduced a new annotation to map enum values to their encoded representation. I already thought about that a couple of times, but never found time to do it. Now I introduced it, I notice that there is actually something missing here. Question is: will it be possible to introduce it without overhauling the entire framework? I think it is possible.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Problem&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;So what is actually missing here? Well, with the latest addition of @BoundEnumOption, you can easily map an enum value to its encoded representation. That&#39;s nice; now you can have a typed collection of enum values instead of arbitrary integer values. &lt;br /&gt;&lt;br /&gt;However, there is a gotcha. What will you will see &lt;i&gt;a lot&lt;/i&gt; is that the enum value read influences the way you are supposed to read the remainder of the file. In the snoop example, this is no different. Currently, the example doesn&#39;t do anything with the actual data packets, but if it did, then it would have to decode it differently depending on the value of datalinkType. &lt;br /&gt;&lt;br /&gt;In the past, you could easily use @If or @Switch and refer to the value of datalinkType, as long as it was an integer, String or boolean. However, now you need to compare that value to another enum value, and that&#39;s something that wasn&#39;t supported yet.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Requirements&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;We want to be able to do something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;@BoundNumber(size=&quot;8&quot;)&lt;br /&gt;private DatalinkType datalinkType;&lt;br /&gt;…&lt;br /&gt;@If(&quot;datalinkType == DatalinkType.ETHERNET&quot;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This means that Preon needs to be able to compare enums, and that it also needs to be able to resolve references to enum values.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Challenge&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Having the ability to compare enums doesn&#39;t look like a huge problem. In fact, I just wrote an additional test in LimboTest, and it seems to be working fine:&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;    public void testComparingEnums() {&lt;br /&gt;        EasyMock.expect(defs.getType(&quot;a&quot;)).andReturn(Direction.class).anyTimes();&lt;br /&gt;        EasyMock.expect(defs.getType(&quot;b&quot;)).andReturn(Direction.class).anyTimes();&lt;br /&gt;        EasyMock.expect(resolver.get(&quot;a&quot;)).andReturn(Direction.LEFT).anyTimes();&lt;br /&gt;        EasyMock.expect(resolver.get(&quot;b&quot;)).andReturn(Direction.RIGHT).anyTimes();&lt;br /&gt;        EasyMock.replay(defs, resolver);&lt;br /&gt;        assertTrue(condition(context, resolver, &quot;a == a&quot;));&lt;br /&gt;        assertFalse(condition(context, resolver, &quot;a == b&quot;));&lt;br /&gt;        assertTrue(condition(context, resolver, &quot;b == b&quot;));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public static enum Direction {&lt;br /&gt;        LEFT,&lt;br /&gt;        RIGHT;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The difficulty is somewhere else: it&#39;s in resolving the enum values. Problem is Direction.LEFT is not something Limbo is capable of dereferencing; it&#39;s just not in lexical scope. So, the question is, do we need another version of Limbo now? One that is capable of resolving enum value references? The good new is: no, you don&#39;t.&lt;br /&gt;&lt;br /&gt;The reason for that is that Limbo is extensible. It defines something called a ReferenceContext that needs to be implemented to allow Limbo to execute in a context.&lt;br /&gt;&lt;br /&gt;Let&#39;s look at an example to clear things up a little. Let&#39;s assume that you want to evaluate &quot;foo.bar + 3&quot;. When you feed this expression to Limbo, it will first try to see if this expression makes sense at all. So it will check if it *will* actually be able to resolve something named &#39;foo&#39;, and if that thing has an attribute called &#39;bar&#39;. If it doesn&#39;t then it will just fail directly.  Now, in order to check if there is something called &#39;foo&#39; in its context, it will simply call selectAttribute(&quot;foo&quot;) on the current ReferenceContext. If that ReferenceContext decides that something like that is referenceable, it will return a Reference object representing the &quot;foo&quot; reference. Next, Limbo will check if there is actually an attribute &quot;bar&quot; on the type of object referenced by the Reference just created. If so, then it will return a Reference to that property.&lt;br /&gt;&lt;br /&gt;The important thing to note here is that - whatever Limbo is trying to do - all requests always hit the ReferenceContext first. Once the References are &#39;linked&#39;, it will call resolve(…) on the references to resolve the values on an instance of that context.&lt;br /&gt;&lt;br /&gt;So, if we want to put the enums into lexical scope, all we need to do is rewrite the ReferenceContext. And our ReferenceContext is defined by Preon, so we don&#39;t have to rewrite Limbo; we just need to write a small adjustment in Preon, in order to integrate Limbo slightly differently.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Solution&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The actual code required to make this work is a little bit more than I&#39;m willing to list here. (It turns out you need a decorator for RefenceContext, and then two additional Reference implementations. One to refer to Classes, and one to reference static fields on a class. The solution works in the same way as outlined above. The only thing that you need to add is an @ImportStatic annotation, at the top of the class from which you are referencing the enum values:&lt;br /&gt;&lt;pre class=&quot;brush:java&quot;&gt;&lt;br /&gt;@ImportStatic(DatalinkType.class)&lt;br /&gt;public class SnoopFile {&lt;br /&gt;&lt;br /&gt;  @BoundNumber(size=&quot;8&quot;)&lt;br /&gt;  private DatalinkType datalinkType;&lt;br /&gt;  …&lt;br /&gt;  @If(&quot;datalinkType == DatalinkType.ETHERNET&quot;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/3526054868850245793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=3526054868850245793' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/3526054868850245793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/3526054868850245793'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/08/enums-in-preon.html' title='Enums in Preon'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-8297451250839108366</id><published>2009-08-10T04:03:00.000-07:00</published><updated>2009-08-10T05:10:18.143-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><category scheme="http://www.blogger.com/atom/ns#" term="snoop"/><category scheme="http://www.blogger.com/atom/ns#" term="solaris"/><title type='text'>Snoop Using Preon</title><content type='html'>Just before my holiday started, &lt;a href=&quot;http://www.linkedin.com/pub/adriaan-thomas/0/50a/2bb&quot;&gt;Adriaan Thomas&lt;/a&gt; sent me an email, asking me about using Preon for decoding Solaris snoop files. That sounded like an interesting challenge. So, this weekend, in my spare hours, I wrote some code to see what that would look like. The code required is given below, and based on&lt;a href=&quot;http://www.rfc-archive.org/getrfc.php?rfc=1761&quot;&gt; RFC 1761&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;div&gt;Now, if you want to decode a snoop file, that&#39;s pretty easy: you just create the Codec, and then pass that Codec to one of Codecs decode operations:&lt;/div&gt;&lt;pre class=&quot;brush:java&quot;&gt;Codec&amp;lt;SnoopFile&gt; codec = Codecs.createCodec(SnoopFile.class);&lt;br /&gt;SnoopFile capture = Codecs.decode(codec, ...);&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;This is the definition of the SnoopFile class.&lt;/div&gt;&lt;pre class=&quot;brush:java&quot;&gt;public class SnoopFile {&lt;br /&gt;&lt;br /&gt;@Bound&lt;br /&gt;private FileHeader header;&lt;br /&gt;&lt;br /&gt;@BoundList(type=PacketRecord.class)&lt;br /&gt;private List&amp;lt;PacketRecord&gt; records;&lt;br /&gt;&lt;br /&gt;public FileHeader getHeader() {&lt;br /&gt;return header;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public List&amp;lt;PacketRecord&gt; getRecords() {&lt;br /&gt;return records;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static class FileHeader {&lt;br /&gt;&lt;br /&gt;@BoundBuffer(match = { 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0x00, 0x00, 0x00 })&lt;br /&gt;private byte[] identificationPattern;&lt;br /&gt;&lt;br /&gt;@BoundNumber(byteOrder=ByteOrder.BigEndian)&lt;br /&gt;private int versionNumber;&lt;br /&gt;&lt;br /&gt;@BoundNumber(size=&quot;32&quot;, byteOrder=ByteOrder.BigEndian)&lt;br /&gt;private DatalinkType datalinkType;&lt;br /&gt;&lt;br /&gt;public int getVersionNumber() {&lt;br /&gt; return versionNumber;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public DatalinkType getDatalinkType() {&lt;br /&gt; return datalinkType;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static class PacketRecord {&lt;br /&gt;&lt;br /&gt;@BoundNumber(byteOrder = ByteOrder.BigEndian, size=&quot;32&quot;)&lt;br /&gt;private long originalLength;&lt;br /&gt;&lt;br /&gt;@BoundNumber(byteOrder = ByteOrder.BigEndian, size=&quot;32&quot;)&lt;br /&gt;private long includedLength;&lt;br /&gt;&lt;br /&gt;@BoundNumber(byteOrder = ByteOrder.BigEndian, size=&quot;32&quot;)&lt;br /&gt;private long packetRecordLength;&lt;br /&gt;&lt;br /&gt;@BoundNumber(byteOrder = ByteOrder.BigEndian, size=&quot;32&quot;)&lt;br /&gt;private long cumulativeDrops;&lt;br /&gt;&lt;br /&gt;@BoundNumber(byteOrder = ByteOrder.BigEndian, size=&quot;32&quot;)&lt;br /&gt;private long timestampSeconds;&lt;br /&gt;&lt;br /&gt;@BoundNumber(byteOrder = ByteOrder.BigEndian, size=&quot;32&quot;)&lt;br /&gt;private long timestampMicroseconds;&lt;br /&gt;&lt;br /&gt;@Slice(size=&quot;(packetRecordLength - 24) * 8&quot;)&lt;br /&gt;@BoundList(size=&quot;includedLength&quot;)&lt;br /&gt;private byte[] packetData;&lt;br /&gt;&lt;br /&gt;public long getOriginalLength() {&lt;br /&gt; return originalLength;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public long getIncludedLength() {&lt;br /&gt; return includedLength;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public long getPacketRecordLength() {&lt;br /&gt; return packetRecordLength;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public long getCumulativeDrops() {&lt;br /&gt; return cumulativeDrops;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public long getTimestampSeconds() {&lt;br /&gt; return timestampSeconds;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public long getTimestampMicroseconds() {&lt;br /&gt; return timestampMicroseconds;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public byte[] getPacketData() {&lt;br /&gt; return packetData;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static enum DatalinkType {&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(0)&lt;br /&gt;IEEE_802_3,&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(1)&lt;br /&gt;IEEE_802_4_TOKEN_BUS,&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(2)&lt;br /&gt;IEEE_802_5_TOKEN_RING,&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(3)&lt;br /&gt;IEEE_802_6_METRO_NET,&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(4)&lt;br /&gt;ETHERNET,&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(5)&lt;br /&gt;HLDC,&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(6)&lt;br /&gt;CHARACTER_SYNCHRONOUS,&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(7)&lt;br /&gt;IBM_CHANNEL_TO_CHANNEL,&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(8)&lt;br /&gt;FDDI,&lt;br /&gt;&lt;br /&gt;@BoundEnumOption(9)&lt;br /&gt;OTHER,&lt;br /&gt;&lt;br /&gt;UNASSIGNED&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/8297451250839108366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=8297451250839108366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/8297451250839108366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/8297451250839108366'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/08/snoop-using-preon.html' title='Snoop Using Preon'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-2623493799706348969</id><published>2009-03-29T23:58:00.000-07:00</published><updated>2009-03-30T00:23:44.509-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon Class File Format</title><content type='html'>A couple of weeks ago, I blogged a little about Preon&#39;s CodecDescriptor, and that it should be changed. This weekend, I completed the new interface, and made sure the entire documentation generation process is now using that interface. I&#39;m quite pleased with the result, although I noticed one area where it can be improved. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The description below is what the new setup produces for the Java Classfile Codec produced from the POJO classes &lt;a href=&quot;http://fisheye3.atlassian.com/browse/preon/trunk/preon-samples/preon-sample-bytecode/src/main/java/nl/flotsam/preon/sample/bytecode/ClassFile.java?r=39&quot;&gt;here&lt;/a&gt;. Note that the output is a little messy, but that&#39;s mostly Blogger.com&#39;s style. The actual output looks a little better and can be downloaded &lt;a href=&quot;http://preon.flotsam.nl/test.html&quot;&gt;here&lt;/a&gt;. The same goes for the hyperlinks. The hyperlinks down below don&#39;t work. But they do work &lt;a href=&quot;http://preon.flotsam.nl/test.html&quot;&gt;in the original source document&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h1&gt;Class file&lt;/h1&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding0&quot;&gt;Magic&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding0&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding1&quot;&gt;Minor version&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding1&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding2&quot;&gt;Major version&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding2&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding3&quot;&gt;Constant pool count&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding3&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding19&quot;&gt;Constant pool&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding19&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a list of elements.&lt;/p&gt;&lt;p&gt;The number of elements in the list is the difference between &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding3&quot;&gt;Constant pool count&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; and 1.&lt;/p&gt;&lt;p&gt; The particular choice is based on a 8-bit  value preceeding the actual encoded value. If 7, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_cp_info&quot;&gt;Class cp info&lt;/a&gt; will be choosen. If 6, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Double_cp_info&quot;&gt;Double cp info&lt;/a&gt; will be choosen. If 9, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Field_ref_cp_info&quot;&gt;Field ref cp info&lt;/a&gt; will be choosen. If 4, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Float_cp_info&quot;&gt;Float cp info&lt;/a&gt; will be choosen. If 3, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Integer_cp_info&quot;&gt;Integer cp info&lt;/a&gt; will be choosen. If 11, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Interface_method_ref_cp_info&quot;&gt;Interface method ref cp info&lt;/a&gt; will be choosen. If 10, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Method_ref_cp_info&quot;&gt;Method ref cp info&lt;/a&gt; will be choosen. If 12, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Name_and_type_cp_info&quot;&gt;Name and type cp info&lt;/a&gt; will be choosen. If 8, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#String_cp_info&quot;&gt;String cp info&lt;/a&gt; will be choosen. If 1, then &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Utf8_cp_info&quot;&gt;Utf8 cp info&lt;/a&gt; will be choosen.&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;(unknown)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding20&quot;&gt;Access flags&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding20&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding21&quot;&gt;This class&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding21&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding22&quot;&gt;Super class&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding22&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding23&quot;&gt;Interfaces count&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding23&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding24&quot;&gt;Interfaces&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding24&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (little endian).&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding23&quot;&gt;Interfaces count&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt;.&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding23&quot;&gt;Interfaces count&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; times 32&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding25&quot;&gt;Field count&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding25&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding35&quot;&gt;Fields&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding35&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Field_info&quot;&gt;Field info&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding25&quot;&gt;Field count&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt;.&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;(unknown)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding36&quot;&gt;Method count&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding36&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding66&quot;&gt;Methods&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding66&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Method_info&quot;&gt;Method info&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding36&quot;&gt;Method count&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt;.&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;(unknown)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding67&quot;&gt;Attribute count&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding67&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding70&quot;&gt;Attributes&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding70&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Source_file&quot;&gt;Source file&lt;/a&gt; or &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Deprecated&quot;&gt;Deprecated&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding67&quot;&gt;Attribute count&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The particular type of data structure is selected based on the value of 16 leading bits. These bits are interpreted as an unsigned int. The table below lists the conditions, and the data structure assumed when these conditions are met.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Condition&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Data structure&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;SourceFile&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Source_file&quot;&gt;Source file&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;Deprecated&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Deprecated&quot;&gt;Deprecated&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;(unknown)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Class_cp_info&quot;&gt;&lt;h2&gt;Class cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_cp_info&quot;&gt;Class cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding4&quot;&gt;Name index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding4&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Double_cp_info&quot;&gt;&lt;h2&gt;Double cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Double_cp_info&quot;&gt;Double cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding5&quot;&gt;Value&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding5&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  64-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;64 (8 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Field_ref_cp_info&quot;&gt;&lt;h2&gt;Field ref cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Field_ref_cp_info&quot;&gt;Field ref cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding6&quot;&gt;Class index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding6&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding7&quot;&gt;Name and type index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding7&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Float_cp_info&quot;&gt;&lt;h2&gt;Float cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Float_cp_info&quot;&gt;Float cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding8&quot;&gt;Value&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding8&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Integer_cp_info&quot;&gt;&lt;h2&gt;Integer cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Integer_cp_info&quot;&gt;Integer cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding9&quot;&gt;Value&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding9&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Interface_method_ref_cp_info&quot;&gt;&lt;h2&gt;Interface method ref cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Interface_method_ref_cp_info&quot;&gt;Interface method ref cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding10&quot;&gt;Class index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding10&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding11&quot;&gt;Name and type index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding11&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Method_ref_cp_info&quot;&gt;&lt;h2&gt;Method ref cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Method_ref_cp_info&quot;&gt;Method ref cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding12&quot;&gt;Class index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding12&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding13&quot;&gt;Name and type index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding13&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Name_and_type_cp_info&quot;&gt;&lt;h2&gt;Name and type cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Name_and_type_cp_info&quot;&gt;Name and type cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding14&quot;&gt;Name index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding14&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding15&quot;&gt;Descriptor index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding15&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;String_cp_info&quot;&gt;&lt;h2&gt;String cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#String_cp_info&quot;&gt;String cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding16&quot;&gt;String index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding16&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Utf8_cp_info&quot;&gt;&lt;h2&gt;Utf8 cp info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Utf8_cp_info&quot;&gt;Utf8 cp info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding17&quot;&gt;Length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding17&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding18&quot;&gt;Value&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding18&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;A sequence of characters, encoded in ASCII.&lt;/p&gt;&lt;p&gt;The number of characters of the string is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding17&quot;&gt;Length&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Utf8_cp_info&quot;&gt;Utf8 cp info&lt;/a&gt;.&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;8 times &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding17&quot;&gt;Length&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Utf8_cp_info&quot;&gt;Utf8 cp info&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Constant_value&quot;&gt;&lt;h2&gt;Constant value&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Constant_value&quot;&gt;Constant value&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding30&quot;&gt;Attribute length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding30&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding31&quot;&gt;Constant value index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding31&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Synthetic&quot;&gt;&lt;h2&gt;Synthetic&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Synthetic&quot;&gt;Synthetic&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding32&quot;&gt;Attribute length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding32&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Deprecated&quot;&gt;&lt;h2&gt;Deprecated&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Deprecated&quot;&gt;Deprecated&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding33&quot;&gt;Attribute length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding33&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Field_info&quot;&gt;&lt;h2&gt;Field info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Field_info&quot;&gt;Field info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding26&quot;&gt;Access flags&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding26&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding27&quot;&gt;Name index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding27&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding28&quot;&gt;Descriptor index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding28&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding29&quot;&gt;Attributes count&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding29&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding34&quot;&gt;Attributes&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding34&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Constant_value&quot;&gt;Constant value&lt;/a&gt;, &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Synthetic&quot;&gt;Synthetic&lt;/a&gt; or &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Deprecated&quot;&gt;Deprecated&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding29&quot;&gt;Attributes count&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Field_info&quot;&gt;Field info&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The particular type of data structure is selected based on the value of 16 leading bits. These bits are interpreted as an unsigned int. The table below lists the conditions, and the data structure assumed when these conditions are met.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Condition&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Data structure&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;ConstantValue&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Constant_value&quot;&gt;Constant value&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;Synthetic&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Synthetic&quot;&gt;Synthetic&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;Deprecated&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Deprecated&quot;&gt;Deprecated&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;(unknown)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Line_number_table_entry&quot;&gt;&lt;h2&gt;Line number table entry&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Line_number_table_entry&quot;&gt;Line number table entry&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding50&quot;&gt;Start pc&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding50&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding51&quot;&gt;Line number&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding51&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Line_number_table&quot;&gt;&lt;h2&gt;Line number table&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Line_number_table&quot;&gt;Line number table&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding48&quot;&gt;Attribute length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding48&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding49&quot;&gt;Line number table length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding49&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding52&quot;&gt;Line number table&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding52&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Line_number_table_entry&quot;&gt;Line number table entry&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding49&quot;&gt;Line number table length&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Line_number_table&quot;&gt;Line number table&lt;/a&gt;.&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding49&quot;&gt;Line number table length&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Line_number_table&quot;&gt;Line number table&lt;/a&gt; times 32&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Local_variable_table_entry&quot;&gt;&lt;h2&gt;Local variable table entry&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Local_variable_table_entry&quot;&gt;Local variable table entry&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding55&quot;&gt;Start pc&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding55&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding56&quot;&gt;Length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding56&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding57&quot;&gt;Name index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding57&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding58&quot;&gt;Descriptor index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding58&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding59&quot;&gt;Index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding59&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Local_variable_table&quot;&gt;&lt;h2&gt;Local variable table&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Local_variable_table&quot;&gt;Local variable table&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding53&quot;&gt;Attribute length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding53&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding54&quot;&gt;Local variable table length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding54&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding60&quot;&gt;Local variable table&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding60&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Local_variable_table_entry&quot;&gt;Local variable table entry&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding54&quot;&gt;Local variable table length&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Local_variable_table&quot;&gt;Local variable table&lt;/a&gt;.&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding54&quot;&gt;Local variable table length&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Local_variable_table&quot;&gt;Local variable table&lt;/a&gt; times 80&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Code&quot;&gt;&lt;h2&gt;Code&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Code&quot;&gt;Code&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding41&quot;&gt;Attribute length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding41&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding42&quot;&gt;Max stack&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding42&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding43&quot;&gt;Max locals&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding43&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding44&quot;&gt;Code length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding44&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding45&quot;&gt;Code&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding45&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  8-bit integer value (little endian).&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding44&quot;&gt;Code length&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Code&quot;&gt;Code&lt;/a&gt;.&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding44&quot;&gt;Code length&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Code&quot;&gt;Code&lt;/a&gt; times 8&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding46&quot;&gt;Exception table length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding46&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding47&quot;&gt;Attributes count&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding47&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding61&quot;&gt;Attributes&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding61&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Line_number_table&quot;&gt;Line number table&lt;/a&gt; or &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Local_variable_table&quot;&gt;Local variable table&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding47&quot;&gt;Attributes count&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Code&quot;&gt;Code&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The particular type of data structure is selected based on the value of 16 leading bits. These bits are interpreted as an unsigned int. The table below lists the conditions, and the data structure assumed when these conditions are met.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Condition&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Data structure&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;LineNumberTable&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Line_number_table&quot;&gt;Line number table&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;LocalVariableTable&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Local_variable_table&quot;&gt;Local variable table&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;(unknown)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Exceptions&quot;&gt;&lt;h2&gt;Exceptions&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Exceptions&quot;&gt;Exceptions&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding62&quot;&gt;Attribute length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding62&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding63&quot;&gt;Number of exceptions&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding63&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding64&quot;&gt;Exception index table&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding64&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (little endian).&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding63&quot;&gt;Number of exceptions&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Exceptions&quot;&gt;Exceptions&lt;/a&gt;.&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding63&quot;&gt;Number of exceptions&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Exceptions&quot;&gt;Exceptions&lt;/a&gt; times 32&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Method_info&quot;&gt;&lt;h2&gt;Method info&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Method_info&quot;&gt;Method info&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding37&quot;&gt;Access flags&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding37&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding38&quot;&gt;Name index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding38&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding39&quot;&gt;Descriptor index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding39&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding40&quot;&gt;Attributes count&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding40&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding65&quot;&gt;Attributes&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding65&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a data structure selected from a list of 4.&lt;/p&gt;&lt;p&gt;The number of elements in the list is &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding40&quot;&gt;Attributes count&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Method_info&quot;&gt;Method info&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The particular type of data structure is selected based on the value of 16 leading bits. These bits are interpreted as an unsigned int. The table below lists the conditions, and the data structure assumed when these conditions are met.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Condition&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Data structure&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;Code&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Code&quot;&gt;Code&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;Exceptions&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Exceptions&quot;&gt;Exceptions&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;Synthetic&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Synthetic&quot;&gt;Synthetic&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;the value (a String) of the nth element of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#binding19&quot;&gt;Constant pool&lt;/a&gt; of &lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Class_file&quot;&gt;Class file&lt;/a&gt; (with n being the difference between the value of the first 16 bits and 1) equals the String &quot;Deprecated&quot;&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Deprecated&quot;&gt;Deprecated&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;(unknown)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;a name=&quot;Source_file&quot;&gt;&lt;h2&gt;Source file&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://www.blogger.com/post-create.g?blogID=8084037628342188612#Source_file&quot;&gt;Source file&lt;/a&gt; is composed out of several other smaller elements. The table below provides an overview.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;&lt;th&gt;&lt;p&gt;Size (in bits)&lt;/p&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding68&quot;&gt;Attribute length&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding68&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  32-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;32 (4 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;p&gt;&lt;a name=&quot;binding69&quot;&gt;Source file index&lt;/a&gt;&lt;/p&gt;&lt;a name=&quot;binding69&quot;&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;a  16-bit integer value (big endian).&lt;/p&gt;&lt;/td&gt;&lt;td&gt;&lt;p&gt;16 (2 bytes)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/2623493799706348969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=2623493799706348969' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/2623493799706348969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/2623493799706348969'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/03/preon-update.html' title='Preon Class File Format'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-8052767483751562253</id><published>2009-03-24T00:35:00.000-07:00</published><updated>2009-03-24T00:46:07.383-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon changes</title><content type='html'>The last couple of weeks, I spend most of my commuting time on redesiging the &lt;a href=&quot;http://fisheye3.atlassian.com/browse/preon/trunk/preon-binding/src/main/java/nl/flotsam/preon/CodecDescriptor.java?r=43&quot;&gt;CodecDescriptor&lt;/a&gt; in Preon. And I think I&#39;m getting there. Find the results below. I am currently trying to work this into the different existing Codecs. Not even halfway yet, but I think I will be able to get there this week. &lt;br /&gt;&lt;br /&gt;Now, one of the important changes that this new CodecDescriptor introduces is the Documenter. I want to rename that into something a little bit more sensible. Anybody with a good idea on that, please send your suggestions. ;-)&lt;br /&gt;&lt;br /&gt;The Documenter has been in Pecia for a while, but you could only use it in a paragraph context. I am making changes to Pecia now to use it all over the place. It would be good to have another name for it though. (Did I already mention that?)&lt;br /&gt;&lt;br /&gt;Anyway, the Documenter - or whatever its name is going to be - is an object that is capable of rendering itself into a certain context. It works like a callback. If you pass the Documenter to - say - a paragraph, then the paragraph will turn around and ask the Documenter to render itself. &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package nl.flotsam.preon;&lt;br /&gt;&lt;br /&gt;import nl.flotsam.pecia.Contents;&lt;br /&gt;import nl.flotsam.pecia.Documenter;&lt;br /&gt;import nl.flotsam.pecia.ParaContents;&lt;br /&gt;&lt;br /&gt;public interface CodecDescriptor {&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * An enumeration with different adjectives.&lt;br /&gt;    */&lt;br /&gt;   public enum Adjective {&lt;br /&gt;       A, THE, NONE;&lt;br /&gt;      &lt;br /&gt;       public String asTextPreferA() {&lt;br /&gt;           switch(this) {&lt;br /&gt;               case A: return &quot;a &quot;;&lt;br /&gt;               case THE: return &quot;the &quot;;&lt;br /&gt;               default: return &quot;&quot;;&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       public String asTextPreferAn() {&lt;br /&gt;           switch(this) {&lt;br /&gt;               case A: return &quot;an &quot;;&lt;br /&gt;               case THE: return &quot;the &quot;;&lt;br /&gt;               default: return &quot;&quot;;&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;      &lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Returns an object capable of writing a one-line summary of the data&lt;br /&gt;    * structure. Expect the summary to be printed at the beginning of a&lt;br /&gt;    * paragraph, but make sure the paragraph is ended in such a way that more&lt;br /&gt;    * lines might be appended to that paragraph, if required, by some other&lt;br /&gt;    * component. I.e. make sure you end with a dot-space. (&quot;. &quot;) Typically&lt;br /&gt;    * starts with {@link Adjective#A}. &lt;br /&gt;    *&lt;br /&gt;    */&lt;br /&gt;   &amp;lt;C extends ParaContents&amp;lt;?&amp;gt;&amp;gt; Documenter&amp;lt;C&amp;gt; summary();&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Returns an object capable of rendering a short reference to the type of&lt;br /&gt;    * data for which the Codec provides the decoder. This reference should&lt;br /&gt;    * &amp;lt;em&amp;gt;at least&amp;lt;/em&amp;gt; include a reference to the type of data decoded by&lt;br /&gt;    * &#39;sub&#39;-Codecs. The {@link Adjective} argument allows the implementor to&lt;br /&gt;    * generate a correct reference, such as &#39;a list&#39; instead of &#39;an list&#39;.&lt;br /&gt;    *&lt;br /&gt;    * &amp;lt;p&amp;gt;&lt;br /&gt;    * Note that implementers should assume that the particular piece of data&lt;br /&gt;    * that is going to be referenced here will be detailed further along the&lt;br /&gt;    * road. Unless {@link #requiresDedicatedSection()} returns&lt;br /&gt;    * &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, that could be within the same section.&lt;br /&gt;    * &amp;lt;/p&amp;gt;&lt;br /&gt;    *&lt;br /&gt;    * @param adjective&lt;br /&gt;    *            The adjective to use; &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; if no adjective should&lt;br /&gt;    *            be used.&lt;br /&gt;    */&lt;br /&gt;   &amp;lt;C extends ParaContents&amp;lt;?&amp;gt;&amp;gt; Documenter&amp;lt;C&amp;gt; reference(Adjective adjective);&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Returns an object capable of writing detailed information on the format&lt;br /&gt;    * to the document section passed in. Typically implemented by writing a&lt;br /&gt;    * (couple of) paragraph(s), and forwarding to the CodecDescriptor of a&lt;br /&gt;    * nested {@linkplain Codec}. Note that - while forwarding - the descriptor&lt;br /&gt;    * has the option to replace the way the buffer is referenced.&lt;br /&gt;    *&lt;br /&gt;    * @param bufferReference&lt;br /&gt;    *            A String based human readable reference to the encoded data.&lt;br /&gt;    */&lt;br /&gt;   &amp;lt;C extends Contents&amp;lt;?&amp;gt;&amp;gt; Documenter&amp;lt;C&amp;gt; details(String bufferReference);&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Returns a boolean indicating if the type of data for which the Codec&lt;br /&gt;    * provides the decoder should be documented in a dedicated section.&lt;br /&gt;    *&lt;br /&gt;    * @return A boolean indicating if the type of data for which the Codec&lt;br /&gt;    *         provides the decoder should be documented in a dedicated section:&lt;br /&gt;    *         &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; if it does; &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; if it doesn&#39;t.&lt;br /&gt;    */&lt;br /&gt;   boolean requiresDedicatedSection();&lt;br /&gt;&lt;br /&gt;   /**&lt;br /&gt;    * Returns the title of the section to be rendered, in case&lt;br /&gt;    * {@link #requiresDedicatedSection()} returns &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;.&lt;br /&gt;    *&lt;br /&gt;    * @return The title of the section to be rendered, in case&lt;br /&gt;    *         {@link #requiresDedicatedSection()} returns &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;.&lt;br /&gt;    */&lt;br /&gt;   String getTitle();&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/8052767483751562253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=8052767483751562253' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/8052767483751562253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/8052767483751562253'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/03/preon-changes.html' title='Preon changes'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-9109034950352758140</id><published>2009-03-02T09:39:00.001-08:00</published><updated>2009-03-02T09:50:02.459-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Codec Descriptors in Preon</title><content type='html'>&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;The sole purpose of this entry is get my head around something that has been laying there rotting for quite a while now, and it&#39;s about time I get rid of it. I just haven&#39;t figured out how to do it yet. So, this is a note to self. Not only reminding me to make some changes (hurry up man!), but also to explain myself what the situation is a like right now, and how I feel I could get rid of it.&lt;br /&gt;&lt;br /&gt;First of all, what is a CodecDescriptor. A CodecDescriptor is an interface. It&#39;s the interface that needs to be implemented by all Codecs. That is, all Codecs need to be able to return an implementation. It may be implemented by the Codec itself, but it might also be implemented by something else, outside of the codec.&lt;br /&gt;&lt;br /&gt;Now, why do we even have an interface like that? The answer is simple. A Codec needs to be able to describe itself. This is just because of the way Preon works. If you construct a Codec for a certain type of data structure, then you essentially create a Codec that delegates to other Codecs, until you hit some of the elementary types defined by the framework. One of the ambitions of Preon is to have something that prevents you from having to maintain documentation on the encoding format. That documentation is generated by the Codecs themselves. They describe themselves, and - if they depend on other Codecs for realizing part of the work - they will delegate generation of documentation to other Codecs.&lt;br /&gt;&lt;br /&gt;This approach has been the subject of quite some debate in the past. People argued that using something like a template language would have been good enough. I doubt it.&lt;/div&gt;&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;First of all, the inner workings of a particular type of Codec might be quite involved. Externalizing the bits responsible for generating documentation would break the encapsulation big time. Logic that is closely related is now spread across two different places.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Second, the Codec will often depend on a number of parameters. For instance, the Codec decoding numeric values requires to have the number of bits set, the byte order, the target data type, etc. All of that is also required for the documentation. Consequently, the template would require access to all of this data, and therefore the Codec would need to publically expose all of this, again breaking the encapsulation.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;So you don&#39;t want to loose encapsulation, but you do want polymorfism. Whenever a Codec of lists needs to document itself, it needs the ability to say something about the type of elements it&#39;s decoding. In terms of Preon, that&#39;s just another Codec. When the Codec of lists is documenting itself, it should be able to just ask the element Codec to state something about itself, without being required to understand what that Codec is actually doing. (If you break that restriction, you are going to end up with a kazillion marker interfaces, and a lot of additional code in the Codec of lists.) So, if polymorfism is what you want, the object oriented approach makes a lot of sense.&lt;/li&gt;&lt;li&gt;In many cases, you would render things differently in a different context. In fact, one way of rendering might be ok in one context, but totally ridiculous in another context. If would for instance make perfect sense to generate a list item in a list, but it would be ridiculous to generate a list item in an image. With all of this, compile time checks come in handy. Not a strong case for template languages.&lt;/li&gt;&lt;/ul&gt;&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;br /&gt;&lt;/div&gt;Now, as you may have noticed, I&#39;ve drifted away from the question why a Codec needs a separate CodecDescriptor. After all, if they share so much in common - as I argue above - then why not have it al included in one class? In all honesty, I am not sure if I will be able to answer this question. The only thing I can say for sure is that the CodecDescriptor interface has had a comletely different lifecycle than the Codec so far. In many cases, if I didn&#39;t care about the actual description yet, I had the Codec return a general purpose Codec descriptor. Maybe not all that sensible, but it allowed me to continue on the important bits, without focusing too much on continuosly implementing boilerplate code.&lt;br /&gt;&lt;br /&gt;Anyhow, enough about that. Let&#39;s take a look at the actual interface itself. This is it:&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;public interface CodecDescriptor {&lt;br /&gt;    &amp;lt;T&amp;gt; void writeReference(ParaContents&amp;lt;T&amp;gt; contents);&lt;br /&gt;    String getLabel();&lt;br /&gt;    &amp;lt;T, V extends ParaContents&amp;lt;T&amp;gt;&amp;gt; V putOneLiner(V para);&lt;br /&gt;    boolean hasFullDescription();&lt;br /&gt;    &amp;lt;T&amp;gt; Contents&amp;lt;T&amp;gt; putFullDescription(Contents&amp;lt;T&amp;gt; contents);&lt;br /&gt;    String getSize();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;Doesn&#39;t look all that complicated, does it? The problem is that the operations are not documented. Not here, and not in the actual source code. There are processing expectations however. So I will try to capture those by looking at the operations one by one:&lt;/div&gt;&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;dl&gt;&lt;dt&gt;void writeReference(ParaContents contents)&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;I think that this operation is expected to do is to generate a reference to the type of data structure it is supporting into the target document.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;String getLabel()&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;I think what this operation is expected to do is to generate a refeference to the type of data structure it is supporting. However, since all this operation is capable of doing is return a String, that basically prevents it from generating a real link. (A link in the Pecia definition of the word. That is, something that eventually will be rendered into an HTML anchor tag, or a DocBook xref.)&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;ParaContents putOneLiner(ParaContents para)&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;I think what this operation is expected to do is to genenerate a single short description of itself into the output document. As far as I remember, this was done to allow you to generate a short description in a table for a field, and then make sure it includes a reference to something defined in detail elsewhere. Sort of similar to the way JavaDoc works.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;boolean hasFullDescription()&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Called to check if the next operation is implemented in a meaningful way.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Contents putFullDescription(Contents contents)&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Similar to putOneLiner. However, in putOneLiner, it would be impossible to write outside a single paragraph. In putFullDescription, you can basically write a number of paragraphs, include tables, images, etc.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;String getSize()&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;I think it is expected to return a human readable description of the size. Is it still required? That&#39;s hard to tell. Probably not, now we have getSizeExpr() on Codec.&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;So, as you can see, the contract is quite fragile. And there are a couple of other problems:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;In some cases, you want the references to be inlined. In other cases, you want them to be part of the start of a sentence. Do you need to start whatever is generated with a capital? Or do you expect the framework to recognize when to change whatever you are generating into something starting with a capital?&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;As you can see, there is quite a bit of stuff that needs to be clarified or redefined. Question is, how? I will start to take a look at it tonight, and see if I can slowly refactor this to something that makes a little bit more sense, and is a little bit more helpful.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;zemanta-pixie&quot;&gt;&lt;img src=&quot;http://img.zemanta.com/pixy.gif?x-id=0d38f40e-f03c-457a-bde1-da4db5188da0&quot; class=&quot;zemanta-pixie-img&quot; /&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/9109034950352758140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=9109034950352758140' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/9109034950352758140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/9109034950352758140'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/03/codec-descriptors-in-preon.html' title='Codec Descriptors in Preon'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-2579303848543880489</id><published>2009-03-01T12:21:00.001-08:00</published><updated>2009-03-01T12:31:10.184-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Writing a Java byte code decoder without actually writing it</title><content type='html'>During my talk about &lt;a href=&quot;http://devoxx.com/display/JV08/Preon+-+Binary+Encoding+for+Dummies&quot;&gt;Preon at Devoxx&lt;/a&gt; last year, I mentioned that I was working on capturing Java&#39;s class file format in Preon. This weekend, I took another shot at it, and it&#39;s starting to come together quite well. :-)&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The source code itself is too much to publish here (what else would you expect from something capable of reading byte code), but if you&#39;re interested, I suggest you check out the latest version &lt;a href=&quot;http://fisheye3.atlassian.com/browse/preon/trunk/preon-samples/preon-sample-bytecode/src/main/java/nl/flotsam/preon/sample/bytecode/ClassFile.java&quot;&gt;here&lt;/a&gt;. And as you will see, it does not actual contain any Java code reading byte code; it&#39;s all done in the Preon declarative way. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/2579303848543880489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=2579303848543880489' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/2579303848543880489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/2579303848543880489'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/03/writing-java-byte-code-decoder-without.html' title='Writing a Java byte code decoder without actually writing it'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-5908567846604060579</id><published>2009-02-24T12:24:00.000-08:00</published><updated>2009-02-24T23:46:40.940-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Bit Syntax for Java (I)</title><content type='html'>Erlang&#39;s bit syntax is pretty cool. Now, &lt;a href=&quot;http://preon.flotsam.nl/&quot;&gt;Preon&lt;/a&gt; is aiming to provide something with similar ease of use. Which one is easier? You decide.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the examples in the excellent &lt;a href=&quot;http://www.pragprog.com/titles/jaerlang/programming-erlang&quot;&gt;Erlang book&lt;/a&gt; shows how to decode an MPEG header, using Erlang&#39;s bit syntax. This is what it looks like:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;decode_header(&amp;lt;&amp;lt;2#11111111111:11,B:2,C:2,_D:1,E:4,F:2,G:1,Bits:9&amp;gt;&amp;gt;) -&amp;gt;&lt;br /&gt;Vsn = case B of&lt;br /&gt;    0 -&amp;gt; {2,5};&lt;br /&gt;    1 -&amp;gt; exit(badVsn);&lt;br /&gt;    2 -&amp;gt; 2;&lt;br /&gt;    3 -&amp;gt; 1&lt;br /&gt;end,&lt;br /&gt;Layer = case C of&lt;br /&gt;0 -&amp;gt; exit(badLayer);&lt;br /&gt;1 -&amp;gt; 3;&lt;br /&gt;2 -&amp;gt; 2;&lt;br /&gt;3 -&amp;gt; 1&lt;br /&gt;  end,&lt;br /&gt;%% Protection = D,&lt;br /&gt;BitRate = bitrate(Vsn, Layer, E) * 1000,&lt;br /&gt;SampleRate = samplerate(Vsn, F),&lt;br /&gt;Padding = G,&lt;br /&gt;FrameLength = framelength(Layer, BitRate, SampleRate, Padding),&lt;br /&gt;if&lt;br /&gt;FrameLength &amp;lt; 21 -&amp;gt;&lt;br /&gt;  exit(frameSize);&lt;br /&gt;true -&gt;&lt;br /&gt;  {ok, FrameLength, {Layer,BitRate,SampleRate,Vsn,Bits}}&lt;br /&gt;end;&lt;br /&gt;decode_header(_) -&amp;gt;&lt;br /&gt;exit(badHeader).&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;This is the same code, but then in Java, using Preon:&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;public class MpegHeader {&lt;br /&gt;&lt;br /&gt;@BoundNumber(size=&quot;11&quot;, match=&quot;0b11111111111&quot;)&lt;br /&gt;private int frameSync;&lt;br /&gt;&lt;br /&gt;@BoundNumber(size=&quot;2&quot;)&lt;br /&gt;private int mpegAudioVersionId;&lt;br /&gt;&lt;br /&gt;@BoundNumber(size=&quot;2&quot;)&lt;br /&gt;private int layerDescription;&lt;br /&gt;&lt;br /&gt;@Bound&lt;br /&gt;private boolean crcProtected;&lt;br /&gt;&lt;br /&gt;@BoundNumber(size=&quot;4&quot;)&lt;br /&gt;private int bitRateIndex;&lt;br /&gt;&lt;br /&gt;@BoundNumber(size=&quot;2&quot;)&lt;br /&gt;private int sampleRateFrequencyIndex;&lt;br /&gt;&lt;br /&gt;@Bound&lt;br /&gt;private boolean padded;&lt;br /&gt;&lt;br /&gt;@Bound&lt;br /&gt;private boolean privateBit;&lt;br /&gt;&lt;br /&gt;@BoundNumber(size=&quot;2&quot;)&lt;br /&gt;private int channelMode;&lt;br /&gt;&lt;br /&gt;@BoundNumber(size=&quot;2&quot;)&lt;br /&gt;private int modeExtension;&lt;br /&gt;&lt;br /&gt;@Bound&lt;br /&gt;private boolean copyright;&lt;br /&gt;&lt;br /&gt;@Bound&lt;br /&gt;private boolean original;&lt;br /&gt;&lt;br /&gt;@BoundNumber(size=&quot;2&quot;)&lt;br /&gt;private int emphasis;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Codec&lt;mpegheader&gt; codec = new Codecs.create(MpegHeader.class);&lt;br /&gt;Codecs.decode(codec, buffer);&lt;/mpegheader&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Now, there are obviously a lot of differences. The Erlang example also includes calls to functions defined elsewhere to determine the bitrate and frame lenght. The Preon example does not have that. If you would need it, you could imagine implementing it as methods of the MpegHeader class.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Also note that the example &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-style: italic;&quot;&gt;does&lt;/span&gt; match on the first 11 bits, expecting them to be ones only, similar to the Erlang example. The notation &lt;code&gt;@BoundNumber(size=&quot;11&quot;, match=&quot;0b11111111111&quot;)&lt;/code&gt; basically says that this field will be decoded from 11 input bits, as long as it matches the bit pattern &quot;11111111111&quot;. Or to be more precise, as long as it matches the numeric value of 11 &quot;1&quot; bits, interpreted as an integer. If that criterion isn&#39;t met, the Codec will throw a DecodingException.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I will try to work the other examples into Java with Preon examples as well, but it&#39;s interesting to see how the two approaches compare. What would you prefer? And why?&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/5908567846604060579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=5908567846604060579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/5908567846604060579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/5908567846604060579'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/02/bit-syntax-for-java-i.html' title='Bit Syntax for Java (I)'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8084037628342188612.post-4788857746683811064</id><published>2009-01-15T01:13:00.000-08:00</published><updated>2009-01-15T01:15:29.168-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Google Protocol Buffers"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Preon"/><title type='text'>Preon versus Google Protocol Buffers</title><content type='html'>&lt;a href=&quot;http://preon.flotsam.nl/&quot;&gt;Preon&lt;/a&gt; was mentioned in &lt;a href=&quot;http://n2.nabble.com/-JBoss-JIRA--Created%3A-%28NETTY-97%29-Google-Protocol-Buffer-codec-tp1667561p1667561.html&quot;&gt;a discussion about implementing Google Protocol Buffers in JBoss&lt;/a&gt;. The author considers Preon to be slightly off-topic, but perhaps interesting. It makes you wonder if Preon actually bears some similarity with Google Protocol Buffers. Let&#39;s take a look at that.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Preon like Google Protocol Buffers is about marshalling between the in-memory representation of a data structure, and its binary encoded representation. In that way, they are similar.&lt;/li&gt;&lt;li&gt;Google Protocol Buffers is not just about encoding and decoding data: it also defines an RPC model. Preon does not; it&#39;s about the binary encoded representation only. That way, they are different.&lt;/li&gt;&lt;li&gt;Google Protocol Buffers already has encoding implemented. For Preon, it&#39;s clear how it should be done, but since it is not backed by a large corporation yet (anyone?), I haven&#39;t been able to work on encoding yet. In that sense, they are different.&lt;/li&gt;&lt;li&gt;Google Protocol Buffers relies on &lt;a href=&quot;http://code.google.com/apis/protocolbuffers/docs/proto.html&quot;&gt;.proto&lt;/a&gt; files for defining the data structure. Preon doesn&#39;t. Preon allows you to define the mapping from a Java class to its binary encoded representation inside the class itself, relying on annotations. In that sense, they are different.&lt;/li&gt;&lt;li&gt;Google Protocol Buffers generates source code. Preon doesn&#39;t. Preon builds the entire Codec at runtime. In Preon, the only objects that you have to deal with are the objects you wrote yourself. In that sense, Google Protocol Buffers and Preon are different.&lt;br /&gt; &lt;/li&gt;&lt;li&gt;Google Protocol Buffers supports multiple languages. Now this is an interesting one. Since the Codec constructed by Preon captures exactly how the data is represented in a binary way, it should be fairly straightforward to generate code from it for different languages. Now, that would of course be a little unusual, but nevertheless doable. It that sense, they are currently different.&lt;/li&gt;&lt;li&gt;Google Protocol Buffers is &lt;i&gt;not extensible&lt;/i&gt;. Well, it is extensible, but not in the way Preon is extensible. It does not allow you to use other types of compression techniques, unless you do that in the application layer. (Let&#39;s just say, accept a byte array, and interpret that byte array at he compressed representation of something else.) Preon is extensible. It&#39;s like allowing the protocol buffer language to be extended to support new types. In Preon, you can create your own &lt;a href=&quot;http://preon.flotsam.nl/preon-binding/apidocs/nl/flotsam/preon/CodecFactory.html&quot;&gt;CodecFactory&lt;/a&gt;, and hook that up with the framework. From that point on, sky is the limit. In that sense, they are different.&lt;/li&gt;&lt;li&gt;Google Protocol Buffers supports decoding the full data structure all at once, in a single pass. Preon was designed to decode data &lt;i&gt;just in time&lt;/i&gt;, only if we need it. That was done deliberately. Preon originates from decoding map data. You don&#39;t want to decode a full map into memory all at once. It would blow up the heap, if you need to stay within the boundaries of a Java 32-bit VM. So Preon will try really hard not to decode all data all at once. In that sense, Google Protocol Buffers and Preon are completely different animals.&lt;/li&gt;&lt;li&gt;Preon allows you to define dependencies between different fields, and have that influence the way data is decoded. In that sense, it&#39;s different from pretty much anything else out there - apart from the &lt;a href=&quot;http://flavor.sourceforge.net/&quot;&gt;Flavor&lt;/a&gt; derivatives. So if you first read a numeric attribute, then you can reuse that attribute further along down the road, for instance by interpreting it as the number of elements in an array Preon has to read. For media content, this is fairly common. In typical serialization mechanisms, this is pretty uncommon. The expressions you can use to define these dependencies can be as complicated as you like. In that sense, Google Protocol Buffers and Preon are totally different.   &lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;In summary, Google Protocol Buffers and Preon are quite different, and address different needs. Preon is better suited for decoding existing media types. Google Protocol Buffers is better suited for integration projects.</content><link rel='replies' type='application/atom+xml' href='http://blog.flotsam.nl/feeds/4788857746683811064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8084037628342188612&amp;postID=4788857746683811064' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/4788857746683811064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8084037628342188612/posts/default/4788857746683811064'/><link rel='alternate' type='text/html' href='http://blog.flotsam.nl/2009/01/preon-versus-google-protocol-buffers.html' title='Preon versus Google Protocol Buffers'/><author><name>Wilfred Springer</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://1.bp.blogspot.com/_S3C3xc3P7WU/SVpDBYQbq6I/AAAAAAAAAAM/icLCl4-GDcw/S220/n1015179002_163730_2054.jpg'/></author><thr:total>1</thr:total></entry></feed>