Как преобразовать массив байтов для строкового представления в языке Common LISP?

Некоторые могут найти ниже полезное:

Я хотел, чтобы клиенты были перенаправлены на страницу входа в систему для любого действия rest, которое отправляется без токена авторизации. Поскольку все мои действия по отдыху основаны на Ajax, мне нужен хороший общий способ перенаправления на страницу входа в систему вместо обработки функции успеха Ajax.

Это то, что я сделал:

В любом запросе Ajax мой сервер вернет ответ Json 200 «НЕОБХОДИМОСТЬ АВТОРИЗАЦИИ» (если клиент должен пройти аутентификацию).

Простой пример в Java (на стороне сервера):

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    private final Logger m_logger = LoggerFactory.getLogger(AuthenticationFilter.class);

    public static final String COOKIE_NAME = "token_cookie"; 

    @Override
    public void filter(ContainerRequestContext context) throws IOException {        
        // Check if it has a cookie.
        try {
            Map<String, Cookie> cookies = context.getCookies();

            if (!cookies.containsKey(COOKIE_NAME)) {
                m_logger.debug("No cookie set - redirect to login page");
                throw new AuthenticationException();
            }
        }
        catch (AuthenticationException e) {
            context.abortWith(Response.ok("\"NEED TO AUTHENTICATE\"").type("json/application").build());
        }
    }
}

В моем Javascript я добавил следующий код:

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    var originalSuccess = options.success;

    options.success = function(data) {
        if (data == "NEED TO AUTHENTICATE") {
            window.location.replace("/login.html");
        }
        else {
            originalSuccess(data);
        }
    };      
});

И это все.

21
задан Ken 1 March 2009 в 16:44
поделиться

6 ответов

FLEXI-ПОТОКИ ( http://weitz.de/flexi-streams/ ) имеют портативную функцию преобразования

(flexi-streams:octets-to-string #(72 101 108 108 111) :external-format :utf-8)

=>

"Hello"

Или, если Вы хотите поток:

(flexi-streams:make-flexi-stream
   (flexi-streams:make-in-memory-input-stream
      #(72 101 108 108 111))
   :external-format :utf-8)

возвратит поток, который читает текст из вектора байта

31
ответ дан 29 November 2019 в 06:16
поделиться

Существует две портативных библиотеки для этого преобразования:

  • flexi-потоки, уже упомянутые в другом ответе.

    Эта библиотека является более старой и имеет больше функций, в особенности расширяемые потоки.

  • Столпотворение, библиотека specificially для кодировки символов и декодирования

    Основным преимуществом Babel по flexi-потокам является скорость.

Для лучшей производительности используйте Babel, если она имеет функции, Вы нуждаетесь и отступаете к flexi-потокам иначе. Ниже (немного ненаучного) микросравнительного теста, иллюстрирующего различие в скорости.

Для этого тестового сценария Babel в 337 раз быстрее и нуждается в в 200 раз меньшей памяти.

(asdf:operate 'asdf:load-op :flexi-streams)
(asdf:operate 'asdf:load-op :babel)

(defun flexi-streams-test (bytes n)
  (loop
     repeat n
     collect (flexi-streams:octets-to-string bytes :external-format :utf-8)))

(defun babel-test (bytes n)
  (loop
     repeat n
     collect (babel:octets-to-string bytes :encoding :utf-8)))

(defun test (&optional (data #(72 101 108 108 111))
                       (n 10000))
  (let* ((ub8-vector (coerce data '(simple-array (unsigned-byte 8) (*))))
         (result1 (time (flexi-streams-test ub8-vector n)))
         (result2 (time (babel-test ub8-vector n))))
    (assert (equal result1 result2))))

#|
CL-USER> (test)
Evaluation took:
  1.348 seconds of real time
  1.328083 seconds of user run time
  0.020002 seconds of system run time
  [Run times include 0.12 seconds GC run time.]
  0 calls to %EVAL
  0 page faults and
  126,402,160 bytes consed.
Evaluation took:
  0.004 seconds of real time
  0.004 seconds of user run time
  0.0 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  635,232 bytes consed.
|#
24
ответ дан 29 November 2019 в 06:16
поделиться

Если Вы не должны волноваться о кодировке UTF-8 (который, по существу, означает "просто ASCII"), можно быть в состоянии использовать MAP:

(карта 'представляют #'code-char в виде строки # (72 101 108 108 111))
15
ответ дан 29 November 2019 в 06:16
поделиться

SBCL поддерживает так называемое Серые Потоки . Это расширяемые потоки на основе классов CLOS и родовых функций. Вы могли создать текстовый потоковый подкласс, который получает символы от массива байтов.

4
ответ дан 29 November 2019 в 06:16
поделиться

Попробуйте эти FORMAT функция. (FORMAT NIL ...) возвраты результаты как строка.

0
ответ дан 29 November 2019 в 06:16
поделиться

I say go with the proposed flexistream or babel solutions.

But just for completeness and the benefit of future googlers arriving at this page I want to mention sbcl's own sb-ext:octets-to-string:

   SB-EXT:OCTETS-TO-STRING is an external symbol in #<PACKAGE "SB-EXT">.
   Function: #<FUNCTION SB-EXT:OCTETS-TO-STRING>
   Its associated name (as in FUNCTION-LAMBDA-EXPRESSION) is
     SB-EXT:OCTETS-TO-STRING.
   The function's arguments are:  (VECTOR &KEY (EXTERNAL-FORMAT DEFAULT) (START 0)
                                          END)
   Its defined argument types are:
     ((VECTOR (UNSIGNED-BYTE 8)) &KEY (:EXTERNAL-FORMAT T) (:START T) (:END T))
   Its result type is:
     *
5
ответ дан 29 November 2019 в 06:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: