android - Analizza i caratteri ASCII con Erlang





xmpp apple-push-notifications ejabberd (2)


Le cose di cui preoccuparsi qui sono molte e hanno a che fare sia con la codifica desiderata che con la struttura dati. In Erlang, il testo viene gestito in uno dei seguenti modi:

  1. liste di byte ( [0..255, ...] )
    • Questo è ciò che ottieni se ascolti un socket e i dati vengono restituiti come un elenco.
    • La VM non assume alcuna codifica . Sono byte e significano poco di più.
    • La VM può comunque interpretarli come stringhe (ad esempio in io:format("~s~n", [List]) ). Quando ciò accade (con il flag ~s particolare), la VM assume che la codifica sia latin-1 (ISO-8859-1).
  2. elenchi di codepoint Unicode ( [0..1114111, ...] ).
    • È possibile ottenere quelli da file che vengono letti come unicode e come un elenco.
    • Puoi usarli in output quando hai un formattatore come io:format("~ts~n", [List]) dove ~ts è come ~s ma come unicode.
    • Queste liste rappresentano i codepoints che vedi nello standard unicode, senza alcuna codifica (non sono UTF-x )
    • Questo può funzionare in combinazione con gli elenchi di caratteri latin-1 perché i codepoint Unicode e i caratteri latin1 hanno gli stessi numeri di sequenza sotto 255.
  3. Binaries ( <<0..255, ...>> )
    • Questo è ciò che ottieni ascoltando o leggendo da qualsiasi cosa sotto un formato binary .
    • Si può dire che la VM assuma molte cose:
      1. Sono sequenze di byte ( 0..255 ) senza significato specifico ( <<Bin/binary>> )
      2. Sono sequenze codificate utf-8 ( <<Bin/utf-8>> )
      3. Sono sequenze codificate utf-16 ( <<Bin/utf-16>> )
      4. Sono sequenze codificate utf-32 ( <<Bin/utf-32>> )
    • io:format("~s~n", [Bin]) supporrà che ogni sequenza sia una sequenza latin-1; io:format("~ts~n", [Bin]) assumerà solo UTF-8 .
  4. Un elenco misto di entrambi gli elenchi Unicode e binari con codifica UTF (noto come iodata() ), utilizzato esclusivamente per l'output.

Quindi in sintesi:

  • liste di byte
  • liste di caratteri latini-1
  • liste di codepoint Unicode
  • binario di byte
  • binario utf-8
  • utf-16 binario
  • utf-32 binario
  • elenchi di molti di questi per l'output che è rapidamente concatenato

Inoltre, fino alla versione 17.0, tutti i file sorgente di Erlang erano solo in latino-1. 17.0 ha aggiunto un'opzione per fare in modo che il compilatore legga il tuo file sorgente come unicode aggiungendo questa intestazione:

%% -*- coding: utf-8 -*-

Il prossimo fattore è che JSON, per specifica, suppone UTF-8 come una codifica per tutto ciò che possiede. Inoltre, le librerie JSON in Erlang tendono ad assumere che un binario è una stringa e che gli elenchi sono matrici JSON.

Ciò significa che se si desidera che l'output sia adeguato, è necessario utilizzare i binari codificati UTF-8 per rappresentare qualsiasi JSON.

Se quello che hai è:

  • Un elenco di byte che rappresentano una stringa con codifica utf, quindi list_to_binary(List) per ottenere la corretta rappresentazione binaria
  • Una lista di codepoint, quindi usa unicode:characters_to_binary(List, unicode, utf8) per ottenere un binario codificato utf-8
  • Un binario che rappresenta una stringa latin-1: unicode:characters_to_binary(Bin, latin1, utf8)
  • Un binario di qualsiasi altra codifica UTF: unicode:characters_to_binary(Bin, utf16 | utf32, utf8)

Prendi il binario UTF-8 e invialo alla libreria JSON. Se la libreria JSON è corretta e il client la analizza correttamente, dovrebbe essere corretta.

Confuso con ciò che deve essere fatto l'analisi e con quale client / server finale.

When i send an Umlaut 'Ö' to my ejabberd, 
it is received by ejabberd as <<"195, 150">>

A seguito di questo invio questo al mio cliente come notifiche push (via GCM / APNS in silenzio). Da lì, il client costruisce mediante decodifica UTF-8 su ogni numero uno per uno (questo è sbagliato).

i.e. 195 is first decoded to gibberish character � and so on.

Questa ricostruzione necessita di identificazione se due byte devono essere intrattenuti o 3 o più. Questo varia con la lingua delle lettere (tedesco qui ad esempio).

Come potrebbe il cliente identificare quale lingua verrà ricostruita (numero di byte da decodificare in una volta sola)?

Per aggiungere altro

lists:flatten(mochijson2:encode({struct,[{registration_ids,[Reg_id]},{data ,[{message,Message},{type,Type},{enum,ENUM},{groupid,Groupid},{groupname,Groupname},{sender,Sender_list},{receiver,Content_list}]},{time_to_live,2419200}]})).

Prodotto il json come:

"{\"registration_ids\":[\"APA91bGLjnkhqZlqFEp7mTo9p1vu9s92_A0UIzlUHnhl4xdFTaZ_0HpD5SISB4jNRPi2D7_c8D_mbhUT_k-T2Bo_i_G3Jt1kIqbgQKrFwB3gp1jeGatrOMsfG4gAJSEkClZFFIJEEyow\"],\"data\":{\"message\":[104,105],\"type\":[71,82,79,85,80],\"enum\":2001,\"groupid\":[71,73,68],\"groupname\":[71,114,111,117,112,78,97,109,101],\"sender\":[49,64,100,101,118,108,97,98,47,115,100,115],\"receiver\":[97,115,97,115]},\"time_to_live\":2419200}"

dove avevo dato "ciao" come messaggio e mochijson mi ha dato i valori ASCII [104,105].

The groupname field was given the value "Groupname",
the ASCIIs are also correct after json creation i.e. 71,114,111,117,112,78,97,109,101

Tuttavia quando uso http://www.unit-conversion.info/texttools/ascii/

It is decodes as Ǎo��me and not "Groupname".

Quindi, chi dovrebbe fare l'analisi? Come dovrebbe essere gestito lo stesso.

Il mio messaggio ricostruito è tutto gibberesco quando l'ASCII viene ricostruito.

Grazie




Questo codice è perfetto per me, spero che possa aiutarti anche tu.

item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="1dip" >
    <TextView
        android:id="@+id/spinnerItem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="2dp"
        android:textSize="12sp" >
    </TextView>
</RelativeLayout>

details.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginBottom="20dp"
        android:background="#FF00FF">   
    <Spinner
            android:id="@+id/dropStatus"
            android:layout_width="250dp"
            android:layout_height="30dp"
            android:layout_marginBottom="7dp"
            android:drawSelectorOnTop="true"/> 
</LinearLayout>

Classe adattatore:

import java.util.ArrayList;

import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class StatusAdapter extends ArrayAdapter<StatusBean> {

    private Context context;
    private ArrayList<StatusBean> statuses;
    public Resources res;
    StatusBean currRowVal = null;
    LayoutInflater inflater;

    public StatusAdapter(Context context,
            int textViewResourceId, ArrayList<StatusBean> statuses,
            Resources resLocal) {
        super(context, textViewResourceId, statuses);
        this.context = context;
        this.statuses = statuses;
        this.res = resLocal;        
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }

    public View getCustomView(int position, View convertView, ViewGroup parent) {
        View row = inflater.inflate(R.layout.status_item, parent, false);
        currRowVal = null;
        currRowVal = (StatusBean) statuses.get(position);
        TextView label = (TextView) row.findViewById(R.id.spinnerItem);
        if (position == 0) {
            label.setText("Please select status");
        } else {
            label.setText(currRowVal.getStatus());
        }

        return row;
    }
}

Classe StatusBean:

public class StatusBean {

    private String status;
    private String statusCode;

    public StatusBean() {
    }

    public StatusBean(String status,
            String statusCode) {
        this.status = status;
        this.statusCode = statusCode;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status =  status;
    }

    public String getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(String statusCode) {
        this.statusCode = statusCode;
    }
}

Classe di attività

All'interno dei methos onCreate:

static ArrayList<StatusBean> STATUS_LIST = new ArrayList<StatusBean>();

for(int i=0;i<=10;i++) {
STATUS_LIST.add(new StatusBean(“Status ”+i, “Stattus ”+i));
}

final Spinner  dropStatus = (Spinner)findViewById(R.id.dropStatus);
            Resources res = getResources(); 
            StatusAdapter adapter = new StatusAdapter(this, R.layout.item, SessionData. STATUS_LIST, res);
            dropStatus.setAdapter(adapter);






android erlang xmpp apple-push-notifications ejabberd