<?php

namespace Helpers\Intuition;

// phpcs:ignoreFile

class iDemarshaling
{
    
    var $the_message;
    
    var $error_message;
    
    var $where_in_message;
    
    var $charset;
    
    function status()
    {
        return $this->error_message;
    }
    
    function __construct(&$charset)
    {
        $this->the_message = '';
        $this->charset = $charset;
    }
    
    function Receive(&$the_socket)
    {
        $read_count = 0;
        $datum = '';
        do {
            $slice = @fread($the_socket, 4 - $read_count);
            $length = strlen($slice);
            if ($length == 0) {
                return false;
            }
                $read_count += $length;
                $datum .= $slice;
        } while ($read_count < 4);
        
        $the_size = (0xff000000 & (ord(substr($datum, 0, 1)) << 24)) | ((ord(substr($datum, 1, 1)) << 16) & 0x00ff0000) | ((ord(substr($datum, 2, 1)) << 8) & 0xff00) | (ord(substr($datum, 3, 1)) & 0xff);
        
        $read_count = 0;
        do {
            $slice = @fread($the_socket, $the_size - $read_count);
            $length = strlen($slice);
            if ($length == 0) {
                break;
            }
                $read_count += $length;
                $this->the_message .= $slice;
        } while ($read_count < $the_size);
        
        $this->where_in_message = 0;
        
        return true;
    }
    
    function &ReadInteger()
    {
        $value = (0xff000000 & (ord(substr($this->the_message, $this->where_in_message, 1)) << 24)) | ((ord(substr($this->the_message, $this->where_in_message + 1, 1)) << 16) & 0x00ff0000) | ((ord(substr($this->the_message, $this->where_in_message + 2, 1)) << 8) & 0xff00) | (ord(substr($this->the_message, $this->where_in_message + 3, 1)) & 0xff);
        
        $this->where_in_message += 4;
        return $value;
    }
    
    function &Unicode2UTF8($str)
    {
        $value = '';
        $b = strlen($str);
        for ($i = 0; $i < $b; $i += 2) {
            $char = ((ord($str[$i]) << 8) & 0xff00) + (ord($str[$i + 1]) & 0xff);
            if ($char < 0x80) {
                $value .= chr($char);
            } elseif ($char < 0x800) {
                    $value .= chr(($char >> 6) | 0xc0) . chr(($char & 0x3f) | 0x80);
            } else {
                $value .= chr(($char >> 12) | 0xe0) . chr((($char >> 6) & 0x3f) | 0x80) . chr(($char & 0x3f) | 0x80);
            }
        }
        return $value;
    }
    
    function &ISO2UTF8($str)
    {
        $value = '';
        $b = strlen($str);
        for ($i = 0; $i < $b; $i ++) {
            $char = ord($str[$i]) & 0xff;
            if ($char < 0x80) {
                $value .= chr($char);
            } elseif ($char < 0x800) {
                    $value .= chr(($char >> 6) | 0xc0) . chr(($char & 0x3f) | 0x80);
            }
        }
        return $value;
    }
    
    function &ReadString()
    {
        $value = '';
        
        $the_size = $this->ReadInteger();
        
        if ($the_size == 0xffffffff) {
            return $value;
        }
            
        if ($the_size & 0x80000000) {
            $the_size &= 0x7fffffff;
            $value = $this->Unicode2UTF8(substr($this->the_message, $this->where_in_message, 2 * $the_size));
            $this->where_in_message += 2 * $the_size;
        } else {
            $value = substr($this->the_message, $this->where_in_message, $the_size);
            if ($this->charset == 1) {
                $value = $this->ISO2UTF8($value);
            }
                $this->where_in_message += $the_size;
        }
            return $value;
    }
    
    function &ReadIntegerArray()
    {
        $value = array();
        $the_size = $this->ReadInteger();
        for ($the_item = 0; $the_item < $the_size; $the_item ++) {
            $value[] = $this->ReadInteger();
        }
            return $value;
    }
    
    function &ReadStringArray()
    {
        $value = array();
        $the_size = $this->ReadInteger();
        for ($the_item = 0; $the_item < $the_size; $the_item ++) {
            $value[] = $this->ReadString();
        }
            return $value;
    }
}
