XDR: External Data Representation

簡介

XDR全稱爲External Data Representation,是一個描述和編碼數據的標準。1987年由Sun公司(Sun Microsystems, Inc)發明。html

XDR同時是一門語言,主要用來描述協議的數據格式,如RPCNFS等協議就是使用它來描述自身的數據格式。編程

XDR語言只能用於描述協議的數據格式,不具備編程功能。該語言具備如下特色:數組

  • 相似於C語言
  • 描述複雜的數據格式時,相比圖形描述,其更簡潔

XDR語法

分號;

XDR語言中,分號是語句結束符。也就是說,每一個語句必須以分號結束。它代表一個邏輯實體的結束。例如:bash

int a;
int b;
複製代碼

保留字

下表列出了XDR語言中的保留字。這些保留字不能做爲常量名、變量名或其餘標識符名稱。ide

關鍵字 說明
int 聲明整型變量
hyper 聲明長整型變量
unsigned 聲明無符號類型變量
float 聲明浮點型變量
double 聲明雙精度浮點型變量
enum 聲明枚舉類型
bool 聲明布爾類型
opaque 聲明字節流數組類型
string 聲明字符串類型
struct 聲明結構體類型
union 聲明共用體類型
switch 聲明共用體類型和用於開關語句
case 開關語句分支
typedef 用以給數據類型取別名
void 聲明空值,聲明無返回值或無參數的操做

註釋

XDR語言有2種註釋方法:ui

  • 使用//註釋編碼

    // 單行註釋
    複製代碼
  • 使用/* */註釋spa

    /* 單行註釋 */
    
    /* 多行註釋 多行註釋 ... */
    複製代碼

定義變量

定義變量的語法以下:指針

type-name variable_name = value;
複製代碼

XDR數據類型

XDR語言提供了多種數據類型來幫助描述協議的數據格式,下面將會一一展開介紹。code

整數類型

XDR語言提供的整數類型有:

類型 存儲大小
int(整型) 4字節
unsigned int(無符號整型) 4字節
hyper(長整型) 8字節
unsigned hyper(無符號長整型) 8字節

各個整數類型定義變量的語法以下:

int a;
unsigned int b;
hyper c;
unsigned hyper d;
複製代碼

實例演示:

int a = 10;
unsigned hyper d = 10000;
複製代碼

浮點數類型

XDR語言提供的浮點數類型有:

類型 存儲大小 精度
float(單精度浮點型) 4字節 6 位小數
double(雙進度浮點型) 8字節 15 位小數

XDR語言的浮點數類型使用的是IEEE 754標準

各個浮點數類型定義變量的語法以下:

float a;
double b;
複製代碼

實例演示:

float a = 1.2;
double b = 3.402823E+38;
複製代碼

枚舉類型

XDR使用enum定義枚舉類型,語法以下:

enum identifier { name-identifier = constant, ... } ;
複製代碼

注意:枚舉成員的值的類型爲int類型;每一個枚舉成員的值都是惟一的。

實例演示:經過枚舉描述紅綠藍3種顏色

enum color_type { 
    RED = 1, 
    GREEN = 2, 
    BLUE = 3 
} ;

color_type color = RED;
複製代碼

布爾類型

XDR使用bool定義布爾類型變量,語法以下:

bool identifier;
複製代碼

布爾類型只有2個值:FALSE 或者 TRUE

實例演示:

bool a = TRUE;
複製代碼

Opaque Data類型

Opaque Data類型主要用來描述字節流數組,它有2種類型:定長和變長Opaque Data類型。

XDR使用opaque聲明Opaque Data類型。

定長Opaque Data類型

定長Opaque Data類型定義變量的語法以下:

opaque identifier[n];
複製代碼

其中,n是一個整數常量,用於聲明數組的長度。

若是n不是4的倍數,程序應對數組進行補齊操做,即在第n個字節後添加r(r 取值範圍爲:[0,3])個值爲0的字節,使得(n+r) mod 4 = 0

定長Opaque Data類型的數據格式以下圖所示:

0        1     ...
+--------+--------+...+--------+--------+...+--------+
| byte 0 | byte 1 |...|byte n-1|    0   |...|    0   |
+--------+--------+...+--------+--------+...+--------+
|<-----------n bytes---------->|<------r bytes------>|
|<-----------n+r (where (n+r) mod 4 = 0)------------>|
                                             FIXED-LENGTH OPAQUE
複製代碼

實例演示:

opaque byteBox[128];
複製代碼

變長Opaque Data類型

變長Opaque Data類型定義變量的語法以下:

opaque identifier<m>;
// or
opaque identifier<>;
複製代碼

其中,m是一個整數常量,用於聲明數組的最大長度。

若經過第二種方式(不明確聲明數組的最大長度)聲明定義變量,則數組默認最大長度爲:(2^32) - 1

若是m不是4的倍數,程序應對數組進行補齊操做,即在第m個字節後添加r(r 取值範圍爲:[0,3])個值爲0的字節,使得(m+r) mod 4 = 0

變長Opaque Data類型的數據格式以下圖所示:

0     1     2     3     4     5   ...
+-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
|        length n       |byte0|byte1|...| n-1 |  0  |...|  0  |
+-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
|<-------4 bytes------->|<------n bytes------>|<---r bytes--->|
                        |<----n+r (where (n+r) mod 4 = 0)---->|
                                                  VARIABLE-LENGTH OPAQUE
複製代碼

其中,數組前4個字節聲明瞭數組的真實長度(有效數據長度)。

實例演示:

opaque byteBox<>;
複製代碼

字符串類型

字符串類型主要用來描述ASCII字符數組,它是變長數據類型。

XDR使用string定義字符串類型變量,語法以下:

string object<m>;
//or
string object<>;
複製代碼

其中,m是一個整數常量,用於聲明數組的最大長度。

若經過第二種方式(不明確聲明數組的最大長度)定義字符串類型變量,則數組默認最大長度爲:(2^32) - 1

若是m不是4的倍數,程序應對數組進行補齊操做,即在第m個字節後添加r(r 取值範圍爲:[0,3])個值爲0的字節,使得(m+r) mod 4 = 0

字符串類型的數據格式以下圖所示:

0     1     2     3     4     5   ...
+-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
|        length n       |byte0|byte1|...| n-1 |  0  |...|  0  |
+-----+-----+-----+-----+-----+-----+...+-----+-----+...+-----+
|<-------4 bytes------->|<------n bytes------>|<---r bytes--->|
                        |<----n+r (where (n+r) mod 4 = 0)---->|
                                                         STRING
複製代碼

其中,數組前4個字節聲明瞭數組的真實長度(有效數據長度)。

實例演示:

string asciiBox<>;
複製代碼

數組類型

數組類型主要用來描述已知的數據類型的元素數組,它有2種類型:定長和變長數組類型。

在數組中,每一個元素的長度都是4的倍數。

數組每一個元素的數據類型相同,可是它們的長度卻不必定相同,好比字符串數組。

定長數組類型

定長數組類型定義變量的語法以下:

type-name identifier[n];
複製代碼

其中,n是一個整數常量,用於聲明數組的長度。

定長數組類型的數據格式以下圖所示:

+---+---+---+---+---+---+---+---+...+---+---+---+---+
 |   element 0   |   element 1   |...|  element n-1  |
 +---+---+---+---+---+---+---+---+...+---+---+---+---+
 |<--------------------n elements------------------->|
                                      FIXED-LENGTH ARRAY
複製代碼

實例演示:

string strList[10];
複製代碼

變長數組類型

變長數組類型定義變量的語法以下:

type-name identifier<m>;
// or
type-name identifier<>;
複製代碼

其中,m是一個整數常量,用於聲明數組的最大長度。

若經過第二種方式(不明確聲明數組的最大長度)定義變量,則數組默認最大長度爲:(2^32) - 1

變長數組類型的數據格式以下圖所示:

0  1  2  3
+--+--+--+--+--+--+--+--+--+--+--+--+...+--+--+--+--+
|     n     | element 0 | element 1 |...|element n-1|
+--+--+--+--+--+--+--+--+--+--+--+--+...+--+--+--+--+
|<-4 bytes->|<--------------n elements------------->|
                                                COUNTED ARRAY
複製代碼

其中,數組前4個字節聲明瞭數組的真實長度(有效數據長度)。

實例演示:

string strList<>;
複製代碼

結構體類型

結構體類型主要用於描述自定義的數據對象類型。

XDR使用struct定義結構體類型,語法以下:

struct identifier {
   component-declaration-A;
   component-declaration-B;
   ...
};
複製代碼

注意:結構體中的成員能夠是不一樣的數據類型,可是成員的長度都應該是4的倍數。

實例演示:

struct msg {
   unsigned int id;
   string body<>;
};
``
複製代碼

共用體類型

共用體類型主要用於描述「根據不一樣條件返回不一樣數據類型」的數據類型。

XDR使用union switch定義共用體類型,語法以下:

union switch (discriminant-declaration) {
 case discriminant-value-A:
    arm-declaration-A;
 case discriminant-value-B:
    arm-declaration-B;
 ...
 default: default-declaration;
 } identifier;
複製代碼

注意:每一個case關鍵字後面都須要跟着一個合法的判斷值。default語句是可選的。

實例演示:根據顏色返回字節流數組或者結構體或者空的數據類型。

union switch (color_type color) {
    case RED:
       opaque results[0];
    case BLUE:
       struct {
       	unsigned int hex;
       } info;
    default:
       void;
 } 
複製代碼

Void

XDR使用void表明空。用於描述無值的狀況,或者用於描述不接受數據做爲輸入或不接受數據做爲輸出的操做。

Constant

XDR使用const爲字面量定義一個符號名稱,語法以下:

const name-identifier = n;
複製代碼

實例演示:在下面的例子中,pi這個符號常量等同於整數常量3.14159。

const pi = 3.14159;
複製代碼

Typedef

XDR使用typedef爲已聲明的數據類型定義一個新標識符。

須要注意的是,在不一樣場景下,爲已聲明的數據類型定義一個新標識符會有不一樣的語法:

  • structunionenum數據類型定義新標識符

    typedef <<struct, union, or enum definition>> identifier;
    複製代碼

    實例演示:例如定義bool類型。

    typedef enum {    /* using typedef */
              FALSE = 0,
              TRUE = 1
           } bool;
    
    // or
    
    enum bool {       /* preferred alternative */
      FALSE = 0,
      TRUE = 1
    };
    複製代碼
  • 爲數組類型定義新標識符

    typedef type_name identifier[n];
    複製代碼

    實例演示:定義一個int數組。

    typedef int byteBox[1024]; 
    複製代碼

    這時候,下面定義kb變量2種方式都是能夠的。

    byteBox kb;
    // or
    int    kb[1024];
    複製代碼
  • 爲其餘數據數據類型定義新標識符

    typedef type_name identifier;
    複製代碼

    實例演示:定義一個byte類型。

    typedef int byte; 
    複製代碼

Optional-data類型

Optional-data類型用於描述值可能爲空(void)的數據類型。它至關於C語言中的指針。

Optional-data類型定義變量的語法以下:

type-name *identifier;
複製代碼

使用XDR描述協議

下面將會經過一個小案例演示XDR是如何描述協議的數據格式的。

下圖爲以太網協議中「幀」的數據格式:

咱們如今使用XDR描述進行描述:

struct frame {
	opaque d_mac[6];
	opaque s_mac[6];
	opaque type[2];
	opaque data<1500>;
	opaque fcs[4];
}
複製代碼
相關文章
相關標籤/搜索