2009-10-11 6 views
8

C#BinaryReader a une fonction qui, selon MSDN, lit un entier codé en "sept bits entier", puis lit une chaîne avec la longueur de cet entier . Y a-t-il une documentation claire pour le format entier à sept bits (j'ai cru comprendre que le MSB ou le LSB marque s'il y a plus d'octets à lire, et les bits restants sont les données, mais je serai content pour quelque chose de plus exact).Encodage d'un entier au format 7 bits de C# BinaryReader.ReadString

Encore mieux, existe-t-il une implémentation C pour lire et écrire des nombres dans ce format?

Répondre

10

Eh bien, la documentation BinaryReader.Read7BitEncodedInt dit déjà, qu'il attend la valeur à écrire avec BinaryWriter.Write7BitEncodedInt et que la documentation de méthode précise le format:

L'entier du paramètre de valeur est écrite sur sept bits à une temps, en commençant par les sept bits les moins significatifs. Le bit haut d'un octet indique s'il y a plus d'octets à écrire après celui-ci.

Si la valeur tient dans sept bits, cela prend seulement un octet d'espace. Si la valeur ne tient pas dans sept bits, le bit haut est placé sur le premier octet et écrit. La valeur est ensuite décalée de sept bits et l'octet suivant est écrit. Ce processus est répété jusqu'à ce que tout l'entier ait été écrit.

Ainsi, le nombre entier 1259551277, en binaire 1001011000100110011101000101101 seront converties en ce format 7 bits comme suit:

Remaining integer     encoded bytes 
1001011000100110011101000101101 
100101100010011001110100   00101101 
10010110001001100     10101101 01110100 
1001011000      10101101 11110100 01001100 
100        10101101 11110100 11001100 01011000 
0         10101101 11110100 11001100 11011000 00000100 

Je ne suis pas confiant dans mes compétences en C en ce moment pour fournir une implémentation fonctionnelle , bien que. Mais ce n'est pas très difficile à faire, sur la base de cette description.

2

La méthode Write7BitEncodedInt contient la description suivante: Les 7 bits les plus faibles de chaque octet codent les 7 bits suivants du nombre. Le bit le plus élevé est défini lorsqu'il y a un autre octet suivant.

4

je devais explorer ce format 7 bits également. Dans un de mes projets, je compile des données dans des fichiers en utilisant BinaryWriter de C#, puis je le décompresse à nouveau avec BinaryReader, ce qui fonctionne bien.

Plus tard, j'ai également dû implémenter un lecteur pour les fichiers compressés de ce projet pour Java. Java a une classe nommée DataInputStream (dans le paquet java.io), qui a des méthodes similaires. Malheureusement, l'interprétation des données de DataInputStream est très différente de celle de C#.

Pour résoudre mon problème, j'ai porté moi-même le BinaryReader de C# sur Java en écrivant une classe qui étend java.io.DataInputStream. Voici la méthode que j'ai écrit, ce qui fait exactement la même chose que C# 's BinaryReader.readString():

public String csReadString() throws IOException { 
    int stringLength = 0; 
    boolean stringLengthParsed = false; 
    int step = 0; 
    while(!stringLengthParsed) { 
     byte part = csReadByte(); 
     stringLengthParsed = (((int)part >> 7) == 0); 
     int partCutter = part & 127; 
     part = (byte)partCutter; 
     int toAdd = (int)part << (step*7); 
     stringLength += toAdd; 
     step++; 
    } 
    char[] chars = new char[stringLength]; 
    for(int i = 0; i < stringLength; i++) { 
     chars[i] = csReadChar(); 
    } 
    return new String(chars); 
} 
+1

Parfait. Exactement ce que je cherchais. – ains

2
/* 
* Parameters: plOutput[out] - The decoded integer 
*    pbyInput[in] - Buffer containing encoded integer 
* Returns:  Number of bytes used to encode the integer 
*/ 
int SevenBitEncodingToInteger(int *plOutput, char *pbyInput) 
{ 
    int lSize = 0; 
    int lTemp = 0; 
    while(true) 
    { 
     lTemp += pbyInput[lSize] & 0x7F; 
     if(pbyInput[lSize++] > 127) 
      lTemp <<= 7; 
     else 
      break; 
    } 
    *plOutput = lTemp; 
    return lSize; 
}