/*
Some stolen php.net code to safely convert multidimensional complex arrays into UTF8 safe stuff to json_encode
496850
public static function encodeArrayUTF($d)
    {
        if (is_array($d)) {
            foreach ($d as $k => $v) {
                $d[$k] = \Metaclassing\Utility::encodeArrayUTF($v);
            }
        } elseif (is_string($d)) {
            return utf8_encode($d);
        }

        return $d;
    }
1225340
public function sanitize(array $input, array $fields = array(), $utf8_encode = true)
    {
        $magic_quotes = (bool) get_magic_quotes_gpc();

        if (empty($fields)) {
            $fields = array_keys($input);
        }

        $return = array();

        foreach ($fields as $field) {
            if (!isset($input[$field])) {
                continue;
            } else {
                $value = $input[$field];
                if (is_array($value)) {
                    $value = $this->sanitize($value);
                }
                if (is_string($value)) {
                    if ($magic_quotes === true) {
                        $value = stripslashes($value);
                    }

                    if (strpos($value, "\r") !== false) {
                        $value = trim($value);
                    }

                    if (function_exists('iconv') && function_exists('mb_detect_encoding') && $utf8_encode) {
                        $current_encoding = mb_detect_encoding($value);

                        if ($current_encoding != 'UTF-8' && $current_encoding != 'UTF-16') {
                            $value = iconv($current_encoding, 'UTF-8', $value);
                        }
                    }

                    $value = filter_var($value, FILTER_SANITIZE_STRING);
                }

                $return[$field] = $value;
            }
        }

        return $return;
    }
914874
public function toJson()
    {
        $array = array();
        foreach ($this->disclose() as $key => $disclosure) {
            $values = $disclosure->toArray();
            foreach ($values as &$value) {
                $value = utf8_encode($value);
            }
            $array[$key] = $values;
        }
        return json_encode($array);
    }
444103
public static function iconv_fallback_utf8_iso88591($string) {
		if (function_exists('utf8_decode')) {
			return utf8_decode($string);
		}
		// utf8_decode() unavailable, use getID3()'s iconv_fallback() conversions (possibly PHP is compiled without XML support)
		$newcharstring = '';
		$offset = 0;
		$stringlength = strlen($string);
		while ($offset < $stringlength) {
			if ((ord($string{$offset}) | 0x07) == 0xF7) {
				// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
						   ((ord($string{($offset + 1)}) & 0x3F) << 12) &
						   ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
							(ord($string{($offset + 3)}) & 0x3F);
				$offset += 4;
			} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
				// 1110bbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
						   ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
							(ord($string{($offset + 2)}) & 0x3F);
				$offset += 3;
			} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
				// 110bbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
							(ord($string{($offset + 1)}) & 0x3F);
				$offset += 2;
			} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
				// 0bbbbbbb
				$charval = ord($string{$offset});
				$offset += 1;
			} else {
				// error? throw some kind of warning here?
				$charval = false;
				$offset += 1;
			}
			if ($charval !== false) {
				$newcharstring .= (($charval < 256) ? chr($charval) : '?');
			}
		}
		return $newcharstring;
	}
529105
function utf8Encode(str) {
  var bytes = [], offset = 0, length, char;

  str = encodeURI(str);
  length = str.length;

  while (offset < length) {
    char = str.charAt(offset);
    offset += 1;

    if (char !== '%') {
      bytes.push(char.charCodeAt(0));
    } else {
      char = str.charAt(offset) + str.charAt(offset + 1);
      bytes.push(parseInt(char, 16));
      offset += 2;
    }
  }

  return bytes;
}
14247
static function vcard_encode($data)
    {
        foreach ((array)$data as $type => $entries) {
            // valid N has 5 properties
            while ($type == "N" && is_array($entries[0]) && count($entries[0]) < 5) {
                $entries[0][] = "";
            }

            // make sure FN is not empty (required by RFC2426)
            if ($type == "FN" && empty($entries)) {
                $entries[0] = $data['EMAIL'][0][0];
            }

            foreach ((array)$entries as $entry) {
                $attr = '';
                if (is_array($entry)) {
                    $value = array();
                    foreach ($entry as $attrname => $attrvalues) {
                        if (is_int($attrname)) {
                            if (!empty($entry['base64']) || $entry['encoding'] == 'B') {
                                $attrvalues = base64_encode($attrvalues);
                            }
                            $value[] = $attrvalues;
                        }
                        else if (is_bool($attrvalues)) {
                            // true means just a tag, not tag=value, as in PHOTO;BASE64:...
                            if ($attrvalues) {
                                // vCard v3 uses ENCODING=b (#1489183)
                                if ($attrname == 'base64') {
                                    $attr .= ";ENCODING=b";
                                }
                                else {
                                    $attr .= strtoupper(";$attrname");
                                }
                            }
                        }
                        else {
                            foreach ((array)$attrvalues as $attrvalue) {
                                $attr .= strtoupper(";$attrname=") . self::vcard_quote($attrvalue, ',');
                            }
                        }
                    }
                }
                else {
                    $value = $entry;
                }

                // skip empty entries
                if (self::is_empty($value)) {
                    continue;
                }

                $vcard .= self::vcard_quote($type) . $attr . ':' . self::vcard_quote($value) . self::$eol;
            }
        }

        return 'BEGIN:VCARD' . self::$eol . 'VERSION:3.0' . self::$eol . $vcard . 'END:VCARD';
    }
32494
private function safe_encode($data) {
    if (is_array($data)) {
      return array_map(array($this, 'safe_encode'), $data);
    } else if (is_scalar($data)) {
      return str_ireplace(
        array('+', '%7E'),
        array(' ', '~'),
        rawurlencode($data)
      );
    } else {
      return '';
    }
  }
1051731
function encode2UTF8(charCode){
    if(charCode <= 0x7f){
      return [charCode];
    }else if(charCode <= 0x7ff){
      return [0xc0|(charCode>>6), 0x80|(charCode & 0x3f)];
    }else{
      return [0xe0|(charCode>>12), 0x80|((charCode & 0xfc0)>>6), 0x80|(charCode & 0x3f)];
    }
  }
1040289
private function phpEncodeArray(array $array)
    {
        $isPlainArray = function (array $value) {
            return ((count($value) === 0)
                || (
                    (array_keys($value) === range(0, count($value) - 1))
                    && (0 === count(array_filter(array_keys($value), 'is_string'))))
            );
        };

        if ($isPlainArray($array)) {
            return '['.implode(', ', array_map([$this, 'phpEncodeValue'], $array)).']';
        }

        return '['.implode(', ', array_map(function ($key) use ($array) {
            return $this->phpEncodeValue($key).' => '.$this->phpEncodeValue($array[$key]);
        }, array_keys($array))).']';
    }
997393
static function special_unicode_to_utf8($str)
    {
        $str = preg_replace('#\\\/#', '/', $str);
        return preg_replace_callback("/\\\u([[:xdigit:]]{4})/i", function($matches){
            $ewchar = $matches[1];
            $binwchar = hexdec($ewchar);
            $wchar = chr(($binwchar >> 8) & 0xFF) . chr(($binwchar) & 0xFF);
            return iconv("unicodebig", "utf-8", $wchar);
        }, $str);
    }
292090
public static function utf8Encode($data) {
		if (is_string($data)) {
			return utf8_encode($data);

		} else if (is_array($data)) {
			foreach ($data as $key => $value) {
				$data[utf8_encode($key)] = self::utf8Encode($value);
			}

		} else if (is_object($data)) {
			foreach ($data as $key => $value) {
				$data->{$key} = self::utf8Encode($value);
			}
		}

		return $data;
	}
374891
function utf8_to_entities($str) {
		$strLen = strlen($str);
		$outStr = '';
		$buf = '';
		for ($a = 0; $a < $strLen; $a++) { // Traverse each char in UTF-8 string.
			$chr = substr($str, $a, 1);
			$ord = ord($chr);
			if ($ord > 127) { // This means multibyte! (first byte!)
				if ($ord & 64) { // Since the first byte must have the 7th bit set we check that. Otherwise we might be in the middle of a byte sequence.
					$buf = $chr; // Add first byte
					for ($b = 0; $b < 8; $b++) { // for each byte in multibyte string...
						$ord = $ord << 1; // Shift it left and ...
						if ($ord & 128) { // ... and with 8th bit - if that is set, then there are still bytes in sequence.
							$a++; // Increase pointer...
							$buf .= substr($str, $a, 1); // ... and add the next char.
						} else {
							break;
						}
					}

					$outStr .= '&#' . $this->utf8CharToUnumber($buf, 1) . ';';
				} else {
					$outStr .= chr($this->noCharByteVal);
				} // No char exists (MIDDLE of MB sequence!)
			} else {
				$outStr .= $chr;
			} // ... otherwise it's just ASCII 0-127 and one byte. Transparent
		}

		return $outStr;
	}
863124
public function encode($d)
	{
		if (is_array($d)) {
			$def = 'd';
			$s = '';

			// If first array key is an integer, assume list.
			$list = false;
			if (is_int(array_keys($d)[0])) {
				$list = true;
				$def = 'l';
			}

			ksort($d, SORT_STRING);

			foreach ($d as $key => $value) {
				if (is_string($key)) {
					if ($list) {
						throw new Exception('Invalid bencode data.', 1);
					}
					$s .= strlen($key) . ':' . $key;
				}
				if (is_int($value) || is_float($value)) {
					$s .= 'i' . $value . 'e';
				} elseif (is_string($value)) {
					$s .= strlen($value) . ':' . $value;
				} else {
					$s .= $this->encode($value);
				}
			}

			return $def . $s . 'e';
		} elseif (is_int($d)) {
			return 'i' . $d . 'e';
		} elseif (is_string($d)) {
			return strlen($d) . ':' . $d;
		} else {
			throw new Exception('Invalid data provided to Bencode.', 1);
		}
	}
1354139
public function _encode()
    {
        $out = array();
        if ($this->objectId)
        {
            $out['objectId'] = $this->objectId;
        }
        if ($this->createdAt)
        {
            $out['createdAt'] = $this->createdAt;
        }
        if ($this->updatedAt)
        {
            $out['updatedAt'] = $this->updatedAt;
        }
        foreach ($this->serverData as $key => $value)
        {
            $out[$key] = $value;
        }
        foreach ($this->estimatedData as $key => $value)
        {
            if (is_object($value) && $value instanceof \Avos\Internal\Encodable)
            {
                $out[$key] = $value->_encode();
            } else if (is_array($value))
            {
                $out[$key] = array();
                foreach ($value as $item)
                {
                    if (is_object($item) && $item instanceof \Avos\Internal\Encodable)
                    {
                        $out[$key][] = $item->_encode();
                    } else
                    {
                        $out[$key][] = $item;
                    }
                }
            } else
            {
                $out[$key] = $value;
            }
        }

        return json_encode($out);
    }
1188064
private static function utf8_encode(&$mixed)
    {
        if (is_array($mixed) || is_object($mixed)) {
            foreach ($mixed as &$value) {
                self::utf8_encode($value);
            }
        } else {
            if (is_string($mixed)) {
                $mixed = utf8_encode($mixed);
            }
        }
    }
132054
private static function superEncode($array)
    {
        if (is_array($array) && !empty($array)) {
            foreach ($array as $key => $value) {
                if (is_array($value)) {
                    $array[$key] = self::superEncode($value);
                } else {
                    $array[$key] = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
                }
            }
        }

        return $array;
    }
749147
function __decode_utf8(buffer) {

        var text = "";

        var bytes = new Uint8Array(buffer);
        for (var i=0; i<bytes.length; i++) {

            // Get current byte
            var value = bytes[i];

            // Start new codepoint if nothing yet read
            if (bytes_remaining === 0) {

                // 1 byte (0xxxxxxx)
                if ((value | 0x7F) === 0x7F)
                    text += String.fromCharCode(value);

                // 2 byte (110xxxxx)
                else if ((value | 0x1F) === 0xDF) {
                    codepoint = value & 0x1F;
                    bytes_remaining = 1;
                }

                // 3 byte (1110xxxx)
                else if ((value | 0x0F )=== 0xEF) {
                    codepoint = value & 0x0F;
                    bytes_remaining = 2;
                }

                // 4 byte (11110xxx)
                else if ((value | 0x07) === 0xF7) {
                    codepoint = value & 0x07;
                    bytes_remaining = 3;
                }

                // Invalid byte
                else
                    text += "\uFFFD";

            }

            // Continue existing codepoint (10xxxxxx)
            else if ((value | 0x3F) === 0xBF) {

                codepoint = (codepoint << 6) | (value & 0x3F);
                bytes_remaining--;

                // Write codepoint if finished
                if (bytes_remaining === 0)
                    text += String.fromCharCode(codepoint);

            }

            // Invalid byte
            else {
                bytes_remaining = 0;
                text += "\uFFFD";
            }

        }

        return text;

    }