Tuesday, September 22, 2015

Javascript Dataview to UTF-8 encoding

Javascript DataView comes with more flexibility than TypedArray for working with binary data aka byteArray aka ArrayBuffer. It provides some getter/setter methods to read and write arbitrary data to the buffer. It is very easy to get numeric value using these getter methods like getUint32() or setFloat64() but there is no getter method like getString() , problem will be more complex if the character encoding is any multi-bytes encoding like UTF-8 or UTF-16. UTF-8 is multi-bytes encoding system which means for each character, it may take up to 4 bytes starting from one byte. Thats means minimum number of byte is 1 and maximum numbers of bytes is 4 for UTF-8 encoding.

In this article we will write a function getString()  and add it into DataView prototype so that we can use getString() in the similar way of getUint32(). First look at the UTF-8 binary format of byte sequence.

Binary format of bytes in sequence
1st Byte2nd Byte3rd Byte4th ByteNumber of Free BitsMaximum Expressible Unicode Value
0xxxxxxx7007F hex (127)
110xxxxx10xxxxxx(5+6)=1107FF hex (2047)
1110xxxx10xxxxxx10xxxxxx(4+6+6)=16FFFF hex (65535)
11110xxx10xxxxxx10xxxxxx10xxxxxx(3+6+6+6)=2110FFFF hex (1,114,111)
The value of each individual byte indicates its UTF-8 function, as follows:
  • 00 to 7F hex (0 to 127): first and only byte of a sequence.
  • 80 to BF hex (128 to 191): continuing byte in a multi-byte sequence.
  • C2 to DF hex (194 to 223): first byte of a two-byte sequence.
  • E0 to EF hex (224 to 239): first byte of a three-byte sequence.
  • F0 to FF hex (240 to 255): first byte of a four-byte sequence.
For reading UTF-8 format detail click here

I am not going detail line by line. Here is the final code of getString()
You can download source code from github 


 DataView.prototype.getString = function(offset,length){
        var self = this,bitArray = [], firstByte, highSurrogate, lowSurrogate, codePoint;
        length = length || self.byteLength;
        while( length > 0  ) {
            firstByte = self.getUint8(offset);
            if(self.getUint8(offset) <= 127) {
              bitArray.push(self.getUint8(offset++));
              length--;
            }
            else if(self.getUint8(offset) >= 128 && self.getUint8(offset) <= 223) {
              bitArray.push(((self.getUint8(offset++) & 0x1F) << 6) | (self.getUint8(offset++) & 0x3F));
              length -=2;
            }
            else if(self.getUint8(offset) >= 224 && self.getUint8(offset) <= 239) {
              bitArray.push(((self.getUint8(offset++) & 0x1F) << 12) | ((self.getUint8(offset++) & 0x3F) << 6 | (self.getUint8(offset++) & 0x3F)));
              length -=3;
            }
            else {
               codePoint = ((self.getUint8(offset++) & 0x07) << 18) | (((self.getUint8(offset++) & 0x3F) << 12) | ((self.getUint8(offset++) & 0x3F) << 6 | (self.getUint8(offset++) & 0x3F)));
               codePoint -= 0x10000;
               highSurrogate = (codePoint >> 10) + 0xD800;
               lowSurrogate = (codePoint % 0x400) + 0xDC00;
               bitArray.push(highSurrogate, lowSurrogate);
               length -=4;
            }
        }
        return String.fromCharCode.apply(null,bitArray);
    };

Now we can get UTF-8 encoded string as bellow. I am assuming we have ready buffer from websocket or ajax
 var dataview = new DataView(buffer);  
 dataview.getString(0,100); // get string of 100 lengths from the offset 0 

Saturday, August 15, 2015

Some questions and answers regarding angularjs data binding that all angularjs learner should know


Q. What is two way data binding?
A. In javaScript we can store data either using any primitive data type like number, string etc Or any object like array, json object etc but primitive data type is not suitable for managing sequential collection of data so we normally use object (in javaScript array is also object) instead of the primitive data type most of the cases.  These objects known as Model. We process these objects for presenting to the users through browser screen that we addressed as View.  If we do any changes in our model, angularjs will reflect these to the view. What will happen, if we have a way to change any model properties from the view section? Yes, angularjs permit us to modify model properties from the view. So if we change any model properties from the view, it will also reflect that change in the model. This is called two way data binding.

Q. How does angularjs detect the model changes?
A. In angulars $scope is the mother object for data sharing between model and view.  It let us share any method or properties with view, that means if we want to share any method or properties with view these methods or properties should be member of this $scope object. So angularjs simply watch or observe $scope object in certain cases to check if there any changes that need to be reflected in the view. The process of checking the changes in the $scope object is termed as Dirty Checking as it checks the dirt/mutation of the object. angularjs uses a specially optimised loop for the purpose of Dirty Checking which is called digest cycle.

Q. What is digest cycle?
A.  $scope uses javascript prototypical inheritance for managing sub-scoping.  RootScope is the top of the prototypical chain. Every scope contain a properties watchers which contains a list of angular expressions that need to be observed.  angularjs keeps previous value of the each watcher so that it can check against with new value of the watched expression later. The checking of this old value Vs new value is just specially optimised while loop where angulars iterates each scope watchers until there is no changed value remains Or it exceeds the limit of iteration loop. This iteration continues from a particular scope to its child scope following the prototypical chain. The whole process can take a number of iterations to complete.

Q. How does angulajs add watcher to a scope?
A.  1. All angulajs expressions that have been used in the view will be added to the respective scope's watcher list automatically.
      2. Manually i.e. Whenever $scope.watch() is used.

Q. Is there any permeant observer (i.e. Object.observer() or any timer) set for observing changes in the scope?
A. Is it fair? Definitely not.

Q. How does angularjs know when it needs to be run digest cycle?
A.  When there is a possibility of changing scope. For example, IO operation (e.g. ajax),  event (e.g. click, change). Thats why angularjs bound us to use ng-click instead of onclick, ng-change instead of onchange, $http service instead native ajax call, $timeout service instead settimeOut() so that it can run digest after completing event callback or ajax call or whatever.  Finally you can invoke scope.digest() or scope.apply() to run digest cycle on demands.

Q. Is there any difference between scope.digest() or scope.apply() ?
A. scope.apply() always start digest cycle iteration starting from rootScope whereas scope.digest() start digest cycle iteration starting from invoking scope. So whenever you are sure about scope changes and it won't affect parent scope, use scope.digest() instead of scope.apply() if you are caring about performance.

Use angularjs wisely :)

Friday, May 1, 2015

How to increase max_input_vars in php

 Preparation

First create a info.php and write following line
 <?php  
  echo phpinfo();  
 ?>  


Upload info.php file on the directory of your server for which you want to increase max_input_vars. For example, if you want to increase for the root directory, upload info.php to the root directory. If you want to increase for a sub-directory like admin, then upload info.php to that (e.g. admin) directory.

 Now browse this uploaded file using a  browser http://YOUR_DOMAIN/info.php or http://YOUR_DOMAIN/YOUR_SUB_DIRECTORY/info.php depending on your path.  You will get a page like following:



Approach I



If you php is running on CGI/FastCGI , you can follow this approach

1. Create a file php.ini and upload on the server root directory. If php.ini file is already existed on the server, then don't need to create or upload new php.ini.
2.  Now add following lines in the uploaded php.info and save it
             
       max_input_vars = 10000;
3. if your php running on suhosin security module, you will have to add following lines as well

    suhosin.post.max_vars = 10000
    suhosin.request.max_vars = 10000

4. Run http://YOUR_DOMAIN/info.php again to see if the parameter increased correctly



Approach II

If you php is running on CGI/FastCGI , you can follow this approach as well

1. Create a file .user.ini and upload on the server root directory. If .user.ini file is already existed on the server, then don't need to create or upload new .user.ini
2.  Now add following lines in the uploaded .user.ini and save it
             
       max_input_vars = 10000;

3. if your php running on suhosin security module, you will have to add following lines as well

    suhosin.post.max_vars = 10000
    suhosin.request.max_vars = 10000

4. Run http://YOUR_DOMAIN/info.php again to see if the parameter increased correctly

Approach III

If you php is not running on CGI/FastCGI , you can increase using a .htaccess file

1. Create a file .htaccess and upload on the server root directory. If .htaccess file is already existed on the server, then don't need to create or upload new .htaccess
2.  Now add following lines in the uploaded .htaccess OR in the existing file and save it
             
       php_value max_input_vars 10000

3. Run http://YOUR_DOMAIN/info.php again to see if the parameter increased correctly