//
//   Copyright 2016  Cityzen Data
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//

package io.warp10.script.functions;

import io.warp10.continuum.gts.UnsafeString;
import io.warp10.script.NamedWarpScriptFunction;
import io.warp10.script.WarpScriptStackFunction;
import io.warp10.script.WarpScriptException;
import io.warp10.script.WarpScriptStack;

import org.bouncycastle.util.encoders.Hex;

import com.google.common.base.Charsets;
import com.google.common.io.BaseEncoding;

/**
 * Decode a String in binary and immediately encode it as hexadecimal
 */
public class BINTOHEX extends NamedWarpScriptFunction implements WarpScriptStackFunction {
  
  public BINTOHEX(String name) {
    super(name);
  }
  
  @Override
  public Object apply(WarpScriptStack stack) throws WarpScriptException {
    Object o = stack.pop();
    
    if (!(o instanceof String)) {
      throw new WarpScriptException(getName() + " operates on a String.");
    }
    
    String bin = o.toString();
    
    if (bin.length() % 8 != 0) {
      bin = "0000000".substring(7 - (bin.length() % 8)) + bin;
    }
    
    char[] chars = UnsafeString.getChars(bin);
    
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < bin.length(); i += 4) {
      String nibble = new String(chars, 0, 4);
      
      if ("0000".equals(nibble)) {
        sb.append("0");
      } else if ("0001".equals(nibble)) {
        sb.append("1");        
      } else if ("0010".equals(nibble)) {
        sb.append("2");        
      } else if ("0011".equals(nibble)) {
        sb.append("3");        
      } else if ("0100".equals(nibble)) {
        sb.append("4");        
      } else if ("0101".equals(nibble)) {
        sb.append("5");        
      } else if ("0110".equals(nibble)) {
        sb.append("6");        
      } else if ("0111".equals(nibble)) {
        sb.append("7");        
      } else if ("1000".equals(nibble)) {
        sb.append("8");        
      } else if ("1001".equals(nibble)) {
        sb.append("9");        
      } else if ("1010".equals(nibble)) {
        sb.append("A");        
      } else if ("1011".equals(nibble)) {
        sb.append("B");        
      } else if ("1100".equals(nibble)) {
        sb.append("C");        
      } else if ("1101".equals(nibble)) {
        sb.append("D");        
      } else if ("1110".equals(nibble)) {
        sb.append("E");        
      } else if ("1111".equals(nibble)) {
        sb.append("F");        
      }
    }

    stack.push(sb.toString());
    
    return stack;
  }
}

@@ -769,33 +769,29 @@
 t.WarpScript
-StackFunc
+Excep
 tion;%0Aimport
@@ -814,33 +814,29 @@
 t.WarpScript
-Exception
+Stack
 ;%0Aimport io.
@@ -868,135 +868,16 @@
 tack
-;%0A%0Aimport org.bouncycastle.util.encoders.Hex;%0A%0Aimport com.google.common.base.Charsets;%0Aimport com.google.common.io.BaseEncoding
+Function
 ;%0A%0A/
@@ -1044,18 +1044,16 @@
 ction %7B%0A
-  
 %0A  publi
@@ -1099,18 +1099,16 @@
 e);%0A  %7D%0A
-  
 %0A  @Over
@@ -1210,28 +1210,24 @@
 tack.pop();%0A
-    
 %0A    if (!(o
@@ -1326,28 +1326,24 @@
 g.%22);%0A    %7D%0A
-    
 %0A    String 
@@ -1362,20 +1362,16 @@
 ring();%0A
-    
 %0A    if 
@@ -1465,20 +1465,16 @@
 ;%0A    %7D%0A
-    
 %0A    cha
@@ -1513,20 +1513,16 @@
 s(bin);%0A
-    
 %0A    Str
@@ -1651,21 +1651,15 @@
 rs, 
-0
+i
 , 4);%0A
-      
 %0A   
@@ -1779,24 +1779,16 @@
 nd(%221%22);
-        
 %0A      %7D
@@ -1845,24 +1845,16 @@
 nd(%222%22);
-        
 %0A      %7D
@@ -1911,24 +1911,16 @@
 nd(%223%22);
-        
 %0A      %7D
@@ -1977,24 +1977,16 @@
 nd(%224%22);
-        
 %0A      %7D
@@ -2043,24 +2043,16 @@
 nd(%225%22);
-        
 %0A      %7D
@@ -2109,24 +2109,16 @@
 nd(%226%22);
-        
 %0A      %7D
@@ -2175,24 +2175,16 @@
 nd(%227%22);
-        
 %0A      %7D
@@ -2241,24 +2241,16 @@
 nd(%228%22);
-        
 %0A      %7D
@@ -2307,24 +2307,16 @@
 nd(%229%22);
-        
 %0A      %7D
@@ -2373,24 +2373,16 @@
 nd(%22A%22);
-        
 %0A      %7D
@@ -2439,24 +2439,16 @@
 nd(%22B%22);
-        
 %0A      %7D
@@ -2505,24 +2505,16 @@
 nd(%22C%22);
-        
 %0A      %7D
@@ -2571,24 +2571,16 @@
 nd(%22D%22);
-        
 %0A      %7D
@@ -2637,24 +2637,16 @@
 nd(%22E%22);
-        
 %0A      %7D
@@ -2703,24 +2703,16 @@
 nd(%22F%22);
-        
 %0A      %7D
@@ -2750,20 +2750,16 @@
 ing());%0A
-    
 %0A    ret

Fix BINTOHEX function : stop iterating on the same nibble