ecma_string_get_char_at_pos (const ecma_string_t *string_p, /**< ecma-string */
                             lit_utf8_size_t index) /**< index of character */
{
  JERRY_ASSERT (index < ecma_string_get_length (string_p));

  lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];

  if (ECMA_IS_DIRECT_STRING (string_p))
  {
    switch (ECMA_GET_DIRECT_STRING_TYPE (string_p))
    {
      case ECMA_DIRECT_STRING_MAGIC:
      {
        uint32_t id = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p);

        if (JERRY_LIKELY (id < LIT_MAGIC_STRING__COUNT))
        {
          /* All magic strings must be ascii strings. */
          const lit_utf8_byte_t *data_p = lit_get_magic_string_utf8 (id);

          return (ecma_char_t) data_p[index];
        }

        return ecma_external_string_get_char_at_pos (id, index);
      }
      default:
      {
        JERRY_ASSERT (ECMA_GET_DIRECT_STRING_TYPE (string_p) == ECMA_DIRECT_STRING_UINT);
        uint32_t uint32_number = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p);

        ecma_uint32_to_utf8_string (uint32_number, uint32_to_string_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);

        return (ecma_char_t) uint32_to_string_buffer[index];
      }
    }
  }

  JERRY_ASSERT (string_p->refs_and_container >= ECMA_STRING_REF_ONE);

  switch (ECMA_STRING_GET_CONTAINER (string_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      ecma_short_string_t *short_string_p = (ecma_short_string_t *) string_p;
      lit_utf8_size_t size = short_string_p->size;
      const lit_utf8_byte_t *data_p = ECMA_SHORT_STRING_GET_BUFFER (string_p);

      if (JERRY_LIKELY (size == short_string_p->length))
      {
        return (ecma_char_t) data_p[index];
      }

      return lit_utf8_string_code_unit_at (data_p, size, index);
    }
    case ECMA_STRING_CONTAINER_LONG_OR_EXTERNAL_STRING:
    {
      ecma_long_string_t *long_string_p = (ecma_long_string_t *) string_p;
      lit_utf8_size_t size = long_string_p->size;
      const lit_utf8_byte_t *data_p = long_string_p->string_p;

      if (JERRY_LIKELY (size == long_string_p->length))
      {
        return (ecma_char_t) data_p[index];
      }

      return lit_utf8_string_code_unit_at (data_p, size, index);
    }
    case ECMA_STRING_CONTAINER_HEAP_ASCII_STRING:
    {
      const lit_utf8_byte_t *data_p = ECMA_ASCII_STRING_GET_BUFFER (string_p);
      return (ecma_char_t) data_p[index];
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      ecma_uint32_to_utf8_string (string_p->u.uint32_number,
                                  uint32_to_string_buffer,
                                  ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);

      return (ecma_char_t) uint32_to_string_buffer[index];
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);
      return ecma_external_string_get_char_at_pos (string_p->u.magic_string_ex_id, index);
    }
  }
} /* ecma_string_get_char_at_pos */
ecma_string_get_char_at_pos (const ecma_string_t *string_p,  
                             lit_utf8_size_t index)  
{
  JERRY_ASSERT (index < ecma_string_get_length (string_p));

  lit_utf8_byte_t uint32_to_string_buffer[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];

  if (ECMA_IS_DIRECT_STRING (string_p))
  {
    switch (ECMA_GET_DIRECT_STRING_TYPE (string_p))
    {
      case ECMA_DIRECT_STRING_MAGIC:
      {
        uint32_t id = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p);

        if (JERRY_LIKELY (id < LIT_MAGIC_STRING__COUNT))
        {
           
          const lit_utf8_byte_t *data_p = lit_get_magic_string_utf8 (id);

          return (ecma_char_t) data_p[index];
        }

        return ecma_external_string_get_char_at_pos (id, index);
      }
      default:
      {
        JERRY_ASSERT (ECMA_GET_DIRECT_STRING_TYPE (string_p) == ECMA_DIRECT_STRING_UINT);
        uint32_t uint32_number = (uint32_t) ECMA_GET_DIRECT_STRING_VALUE (string_p);

        ecma_uint32_to_utf8_string (uint32_number, uint32_to_string_buffer, ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);

        return (ecma_char_t) uint32_to_string_buffer[index];
      }
    }
  }

  JERRY_ASSERT (string_p->refs_and_container >= ECMA_STRING_REF_ONE);

  switch (ECMA_STRING_GET_CONTAINER (string_p))
  {
    case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
    {
      ecma_short_string_t *short_string_p = (ecma_short_string_t *) string_p;
      lit_utf8_size_t size = short_string_p->size;
      const lit_utf8_byte_t *data_p = ECMA_SHORT_STRING_GET_BUFFER (string_p);

      if (JERRY_LIKELY (size == short_string_p->length))
      {
        return (ecma_char_t) data_p[index];
      }

      return lit_utf8_string_code_unit_at (data_p, size, index);
    }
    case ECMA_STRING_CONTAINER_LONG_OR_EXTERNAL_STRING:
    {
      ecma_long_string_t *long_string_p = (ecma_long_string_t *) string_p;
      lit_utf8_size_t size = long_string_p->size;
      const lit_utf8_byte_t *data_p = long_string_p->string_p;

      if (JERRY_LIKELY (size == long_string_p->length))
      {
        return (ecma_char_t) data_p[index];
      }

      return lit_utf8_string_code_unit_at (data_p, size, index);
    }
    case ECMA_STRING_CONTAINER_HEAP_ASCII_STRING:
    {
      const lit_utf8_byte_t *data_p = ECMA_ASCII_STRING_GET_BUFFER (string_p);
      return (ecma_char_t) data_p[index];
    }
    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
    {
      ecma_uint32_to_utf8_string (string_p->u.uint32_number,
                                  uint32_to_string_buffer,
                                  ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);

      return (ecma_char_t) uint32_to_string_buffer[index];
    }
    default:
    {
      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);
      return ecma_external_string_get_char_at_pos (string_p->u.magic_string_ex_id, index);
    }
  }
}  