-
Notifications
You must be signed in to change notification settings - Fork 4
Encoding & Decoding User Objects
In this tutorial we are going to create a JBB profile for encoding custom objects. The we will use the JBB API to encode some these objects into a bundle and then read them back.
You will need Node.js 3.0 installed. Then you will need to install a few more packages:
npm install jbb gulp gulp-jbb-profile
First of all, we are going to define the objects we are going to use. We are going to put them in a separate file called objects.js in order to refer to them when needed.
For our test, we are going to create two objects. a Color object that contains the 3 components of a color (red, green, blue) and a User that contains some simple properties:
var Objects = {};
// A simple User object
Objects.User = function( name, age, color ) {
this.name = name;
this.age = age;
this.color = color;
}
Objects.User.prototype.sayHello = function() {
console.log("Hello, I am "+this.name+", "+this.age+" years old and my favourite color is "+this.color.toHex());
}
// A simple Color object
Objects.User = function( red, green, blue ) {
this.red = red;
this.green = green;
this.blue = blue;
this.color = (blue << 16) | (green << 8) | red;
}
Objects.User.prototype.toHex = function() {
return "#" + this.red.toString(16) + this.green.toString(16) + this.blue.toString(16);
}
// Expose the `Objects variable
module.exports = ObjectsNow that we know our objects, we are going to create a specifications file for our profile, that will be processed by gulp-jbb-profile to compile our profile files.
Create a new file called specs.yaml. This is just a plain YAML file that defines which properties of which object are of interest for JBB.
First, we need to define some metadata, starting with the profile ID. Each profile has a unique 16-bit number that uniquely identifies it. Since the space is limited, the numbers 0x001 to 0x7FF are reserved for public profiles. Numbers 0x800 to 0xFFF are available for private use.
For our example, we are going to use the ID 0x801 (2049):
@uuid: 2049
@revision: 1Then, we should start defining our objects, but first we must first define the Objects refer to the objects we previously created:
# Load `Objects` from objects.js
@require:
Objects: ./objects
# The user object
Objects.User:
properties:
- name
- age
- color
# The color object
Objects.Color:
properties:
- red
- green
- blue
- colorNow that we have our specifications file we can compile it into a profile. To do so, we are going to use gulp and the gulp-jbb-profile plug-in. The following gulpfile.js performs this task:
var gulp = require('gulp');
var jbb_profile = require('gulp-jbb-profile');
// Compile specs.yaml to profile-*.js
gulp.task('default', function() {
return gulp
.src([ './specs.yaml' ])
.pipe(jbb_profile({
'name': 'profile'
}))
.pipe(gulp.dest('.'));
});Now if you just run gulp the profile compiler should create two new files:
~$ gulp
[00:36:31] Using gulpfile ~/gulpfile.js
[00:36:31] Starting 'default'...
[00:36:31] Finished 'default' after 38 ms
~$ ls
...
-rw-r--r-- 1 user staff 266B Jun 6 00:36 specs.yaml
-rw-r--r-- 1 user staff 1.0K Jun 6 00:36 profile-decode.js
-rw-r--r-- 1 user staff 572B Jun 6 00:36 profile-encode.js
The two new scripts profile-encode.js and profile-decode.js were generated based on your specifications. If you want you can have a look to understand how profiles work. You can also refer to the Introduction to Profiles for more information.
Now that we have our profile we can try encoding some data. Let's create a new file called encode.js, and let's start by getting a reference to the JBB encoder, to our objects and to our new encoding profile.
var Encoder = require('jbb/encoder');
var Objects = require('./objects');
var ObjectsProfile = require('./profile-encode');We are going to create a new bundle in the same way we did in the Encoding & Decoding a Simple Object, but this time we are going to add our profile to the encoder:
// Open a new bundle
var bundle = new Encoder("custom.jbb");
// Add a profile for our custom objects
bundle.addProfile( ObjectsProfile );And then we are going to add some objects
// Add some people
bundle.encode(new Objects.User(
"Bob Doe", 46, new Objects.Color(0xAA, 0xBB, 0xCC)
), "users/bob");
bundle.encode(new Objects.User(
"Mike Johanson", 36, new Objects.Color(0x13, 0xFF, 0x45)
), "users/mike");And finally we must close the bundle.
// Don't forget to close the bundle
bundle.close();Likewise, on the decode.js we are going to start getting a reference to the JBB decoder and to our decoding profile:
var Decoder = require('jbb/decoder');
var ObjectsProfile = require('./profile-decode');Then, just like the Encoding & Decoding a Simple Object Tutorial we are creating a new decoder:
// Open a decoder and point it to the base directory
// were the bundle is loaded
var decoder = new Decoder("./");
// Add our decoding profile
decoder.addProfile( ObjectsProfile );And finally we are calling the add function to specify the bundle to load and then the load function to actually load it:
// Add bundle to load
decoder.add("custom.jbb");
// Load it
decoder.load(function( err, db ) {
});Now, you can verify that the objects in the bundle are indeed of our custom type:
db['custom/users/bob'].sayHello();
db['custom/users/mike'].sayHello();Now we can test your scripts:
~$ node encode.js
~$ ls
...
-rw-r--r-- 1 user staff 152B Jun 6 02:09 custom.jbb
~$ node decode.js
Hello, I am Bob Doe, 46 years old and my favourite color is #aabbcc
Hello, I am Mike Johanson, 36 years old and my favourite color is #13ff45
Contents of specs.yaml:
@uuid: 2049
@revision: 1
# Load `Objects` from objects.js
@require:
Objects: ./objects
# The user object
Objects.User:
properties:
- name
- age
- color
# The color object
Objects.Color:
properties:
- red
- green
- blue
- colorContents of objects.js:
var Objects = {};
// A simple User object
Objects.User = function( name, age, color ) {
this.name = name;
this.age = age;
this.color = color;
}
Objects.User.prototype.sayHello = function() {
console.log("Hello, I am "+this.name+", "+this.age+" years old and my favourite color is "+this.color.toHex());
}
// A simple Color object
Objects.Color = function( red, green, blue ) {
this.red = red;
this.green = green;
this.blue = blue;
this.color = (blue << 16) | (green << 8) | red;
}
Objects.Color.prototype.toHex = function() {
return "#" + this.red.toString(16) + this.green.toString(16) + this.blue.toString(16);
}
// Expose the `Objects variable
module.exports = Objects;Contents of encode.js:
var Encoder = require('jbb/encoder');
var Objects = require('./objects');
var ObjectsProfile = require('./profile-encode');
// Open a new bundle
var bundle = new Encoder("custom.jbb");
// Add a profile for our custom objects
bundle.addProfile( ObjectsProfile );
// Add some people
bundle.encode(new Objects.User(
"Bob Doe", 46, new Objects.Color(0xAA, 0xBB, 0xCC)
), "users/bob");
bundle.encode(new Objects.User(
"Mike Johanson", 36, new Objects.Color(0x13, 0xFF, 0x45)
), "users/mike");
// Don't forget to close the bundle
bundle.close();Contents of decode.js:
var Decoder = require('jbb/decoder');
var ObjectsProfile = require('./profile-decode');
// Open a decoder and point it to the base directory
// were the bundle is loaded
var decoder = new Decoder("./");
// Add our decoding profile
decoder.addProfile( ObjectsProfile );
// Add bundle to load
decoder.add("custom.jbb");
// Load it
decoder.load(function( err, db ) {
db['custom/users/bob'].sayHello();
db['custom/users/mike'].sayHello();
});