javaStruct - 通讯协议的解封包第三方库--(二)官方文档二

原文链接

https://code.google.com/archive/p/javastruct/

翻译用工具

翻译使用的是个人免费版Transmate

译文

简介
当与嵌入式设备和其他使用C语言样式的结构体的应用协同工作时,结构体类能非常简便地用于Java应用的网络协议编程。

不需要手动编解码消息,JavaStruct允许开发者对待java类就像C结构体。
JavaStruct使用Java5声明以将类或成员变量标记为结构体。JavaStruct 并不是第一种尝试提供类结构体功能的。Jean-Marie Dautelle 的 Javolution 库也是一个优秀的结构体实现。但是区别于Javolution使用特定类,JavaStruct是要用更简单的POJO方式。

一般性的使用
JavaStruct 装饰类用于封包和解包结构体类。下面是一个测试结构体类的简单的单元测试。结构体字段有一个顺序值,因为Java JVM的规范中并没有关于类成员顺序的信息。在Sun公司的实现中是按照他们的出现顺序,但是在其他JVM中则不一定。所以每一个结构体字段需要给定一个顺序值。

@StructClass 
public class Foo{ 
  @StructField(order = 0) 
  public byte b; 
  @StructField(order = 1) 
  public int i; 
} 
try{ 
  // Pack the class as a byte buffer 
  Foo f = new Foo(); 
  f.b = (byte)1; 
  f.i = 1; 
  byte[] b = JavaStruct.pack(f); 
  
  // Unpack it into an object 
  Foo f2 = new Foo(); 
  JavaStruct.unpack(f2, b); 
} catch(StructException e){ } 

如果有任何错误,结构体操作将抛出一个StructException异常。

结构体类也能被流直接使用。请参考Photoshop ACB文件阅读器例子

public void read(String acbFile){ 
  try { 
    FileInputStream fis = new FileInputStream(new File(acbFile));
    header = new ACBHeader(); 
    StructUnpacker up = JavaStruct.getUnpacker(fis, ByteOrder.BIG_ENDIAN); 
    up.readObject(header); ... 

基本类型
使用基本类型。注意私有(private)域和受保护(protected)域需要合适的getter和setter方法。临时字段(transient fields)将被自动排除。

@StructClass 
public class PublicPrimitives implements Serializable { 
  @StructField(order = 0) 
  public byte b; 

  @StructField(order = 1) 
  public char c; 

  @StructField(order = 2) 
  public short s; 

  @StructField(order = 3) 
  public int i; 

  @StructField(order = 4) 
  public long lo; 

  @StructField(order = 5) 
  protected float f; 

  @StructField(order = 6) 
  private double d; 

  transient int blah; 
  transient double foo; 

  public float getF() { 
    return f; 
  } 

  public void setF(float f) { 
    this.f = f; 
  } 

  public double getD() { 
    return d; 
  } 

  public void setD(double d) { 
    this.d = d; 
  } 

  public boolean equals(Object o) { 
    PublicPrimitives other = (PublicPrimitives)o; 
    return (this.b == other.b 
        && this.c == other.c 
        && this.s == other.s 
        && this.i == other.i 
        && this.lo == other.lo 
        && this.f == other.f 
        && this.d == other.d); 
  } 
}

数组
数组有一些先决条件。当解包时,数组中需要有足够的空间。仅仅数组在解包时自动分配,其长度可以是null由其他字段使用数组长度标记(ArrayLengthMarker)定义(见下面章节)。除此之外数组不能是空和未初始化。

@StructClass 
public class PublicPrimitiveArrays{
  @StructField(order = 0)
  public byte[] b = new byte[5]; 

  @StructField(order = 1) 
  public char[] c = new byte[10]; 

  @StructField(order = 2) 
  public short[] s; 

  @StructField(order = 3) 
  public int[] i; 
}

数组长度标记
数组长度标记对于那些自身长度由其他字段定义的字段非常有用,看如下例子。这是一个特别的字符串结构体,其有一个长度字段,长度值16 bit 字母随其后。
±-------±----------------------//----------------------------------------+ | Length | UTF-16 Characters \ | ±-------±----------------------//----------------------------------------+
为处理它,我们要构建一个结构体类来表示这些字符串,姑且叫它 A 结构体。长度字段应该使用“数组长度标记”声明。这样在解封包操作过程中处理数组字段时,javastruct能自动使用长度字段里的值。

@StructClass 
public class AString { 
  @StructField (order = 0) 
  @ArrayLengthMarker (fieldName = "chars") 
  public int length; 

  @StructField (order = 1) 
  public char[] chars; 

  public AString(String content) { 
    this.length = content.length(); 
    this.chars = content.toCharArray(); 
  } 
... 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值