当前位置:  编程技术>移动开发
本页文章导读:
    ▪由一年前的笔试挑动滴感悟 (宠物与主人 demo)        由一年前的笔试引发滴感悟 (宠物与主人 demo)我好像很久都没有认认真真写过blog了,最近很闲,特别闲,到那种地步呢?两个月多没什么大事做,这期间我一直再看框架方面的知识,对很.........
    ▪ 运用DEFLATE的IP有效载荷压缩        使用DEFLATE的IP有效载荷压缩 3. Detailed specification    3.1. Overall conventions In the diagrams below, a box like this:     下面的图形表示一个字节:          +---+          |   | <-- the vertical bar.........
    ▪ C中构造体大小的计算       C中结构体大小的计算     最近研究了一下c语言中结构体大小的计算,根据自己的理解以及参考网上的资料, 想做一点总结。    先介绍一个相关的概念——偏移量。偏移量指的是结构体.........

[1]由一年前的笔试挑动滴感悟 (宠物与主人 demo)
    来源: 互联网  发布时间: 2014-02-18
由一年前的笔试引发滴感悟 (宠物与主人 demo)

我好像很久都没有认认真真写过blog了,最近很闲,特别闲,到那种地步呢?两个月多没什么大事做,这期间我一直再看框架方面的知识,对很多东西都有了新的认识,O(∩_∩)O~~开心。

无意间,想起了多年前(其实也就是一年前(*^__^*)……)我去一家公司面试,一进去给台电脑笔试,用ssh写一个demo,把数据库里面的信息显示在页面上,对于刚毕业的我来说,算是个难点,ssh?前台后台结合?配置文件?怎么跟数据库连接?这一步步都是问题,因为我还没有到水到渠成的时候,一同面试的还有两个前辈,工作一两年了,我尽所能的写出我知道的东西。。

三个小时之后,我们都离开了办公室,所谓筋疲力尽,当时正值中午12点。又饿又累,虽然没做出来,但是确实努力了,我问了问一同面试的两个男生,他们最后做出来了吗?。。。。没有。。。哦,忘了说,我们用来开发的那台电脑,都是干净的什么都没装,开发工具,jdk什么的都没装,要自己安装,配置然后在开发。

写出来的东西尽显的平淡无味,切身体会过,再次回想起来心还是会波动。

我今天也用了一点时间,写了一个小demo,很简单,没什么功能就是把数据库里面的数据显示在页面上,用spring+hibernate +jsp

没用到什么技术,用spring ioc完成bean的配置

使用spring mvc构建表现层  用hibernate数据库操作组件实现数据库数据操作的具体实例,能实现我最基本的功能显示数据就可以了。

写这个blog的目的是为了纪念一年前的那次笔试。无他。

 项目截图:


附加一个:




新建两张表 vet 和master 宠物和主人的表
create table master(
 id int primary key identity(1,1),
 name varchar(30) not null,
 age int not null,
 email varchar(30) not null,
 career varchar(30) not null
)

insert into master values('舒婷',23,'wst1@163.com','java程序員')
insert into master values('ken',33,'ken@163.com','老闆')
insert into master values('herry',43,'herry@163.com','CEO')
insert into master values('baby',53,'baby@163.com','經歷')

create table vet(
 id int primary key identity(1,1),
 name varchar(30) not null,
 age int not null,
 masterid int Default (0),
 species varchar(30) not null
)

insert into vet values('tally',1,0,'cat')
insert into vet(name,age,species) values('jlly',1,'dog')--插入有默認值的數據時,省略有默認值的字段
insert into vet(name,age,masterid,species) values('fmmay',1,1,'dog')-- 加上有默認值的字段,并輸入對應的值.
select * from vet

配置文件
Web.xml 
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <servlet>
		<servlet-name>test</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
				/WEB-INF/applicationConfig/app-config.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

    <servlet-mapping>
		<servlet-name>test</servlet-name>
		<url-pattern>*.action</url-pattern>
   </servlet-mapping>
  
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
 
</web-app>


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

	<!-- Scans the classpath of this application for @Components to deploy as beans -->
	<!-- 規約所有進行掃描的類,以完成Bean創建和自動依賴注入功能  -->
	<!-- 完全取消bean配置的做法就是使用component 但是要指明使用注解的java类 -->
	<context:component-scan base-package="www.com.spring.*" />  
	<!-- <context:annotation-config /> -->
	<!-- Configures the @Controller programming model -->
	<mvc:annotation-driven /> <!-- 使用<mvc:resources/>元素,把mapping的URI注册到SimpleUrlHandlerMapping的urlMap中, -->
	<!-- misc -->
	<bean id="viewResolver" >
	    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
	    <property name="suffix" value=".action"/>
	</bean>
	
	<!-- Configures Hibernate - Database Config -->
	<import resource="db-config.xml" />
</beans>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
  
   <bean id="dataSource" >
        <property name="driverClassName"><value>com.microsoft.sqlserver.jdbc.SQLServerDriver</value></property>
        <property name="url"><value>jdbc:sqlserver://10.1.100.217:8080;DatabaseName=smartclient</value></property>
        <property name="username"><value>000</value></property>
        <property name="password"><value>12345678</value></property>
   </bean>
   <bean id="sessionFactory" >
        <property name="dataSource"><ref local="dataSource"/></property>
        <property name="packagesToScan" value="www.com.spring.*" />
        <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
			<!--  <prop key="hibernate.hbm2ddl.auto">update</prop>-->
			<prop key="hibernate.format_sql">true</prop>
        </props>
        </property>
   </bean>	 
	<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
	<!-- 定义一个事物管理器  -->
	<tx:annotation-driven/>
    <bean id="transactionManager" >
        <property name="sessionFactory"><ref local="sessionFactory"/></property>
        <qualifier value="petclinic"/><!-- 限定词 -->
    </bean>
</beans>


下面是vet实体类:
package www.com.spring.module;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "vet")
public class Vet {
	 private int id;
	 private String name;
	 private int age;
	 private int masterid;
	 private String species;
	 
	 @Id
	 @GeneratedValue
	 @Column(name = "id")
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	@Column(name = "name")
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Column(name = "age")
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Column(name = "masterid")
	public int getMasterid() {
		return masterid;
	}
	public void setMasterid(int masterid) {
		this.masterid = masterid;
	}
	@Column(name = "species")
	public String getSpecies() {
		return species;
	}
	public void setSpecies(String species) {
		this.species = species;
	}
}

Dao层:
package www.com.spring.dao;

import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import www.com.spring.module.Vet;

@Repository
public class VetDao {
	private HibernateTemplate hibernateTemplate;
	@SuppressWarnings("unused")
	@Autowired
	private void setHibernateTemplate (SessionFactory sessionFactory){
		this.hibernateTemplate =new HibernateTemplate(sessionFactory);
	}
	
	public List<Vet> getAllVets(){
		String hql = "from Vet";
		List<Vet> list = this.hibernateTemplate.find(hql);
		return list;
	}
}

业务层service

package www.com.spring.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import www.com.spring.dao.VetDao;
import www.com.spring.module.Vet;
@Service
public class VetService {
	private VetDao vetDao ;
	@Autowired
	public void setVetDao(VetDao vetDao) {
		this.vetDao = vetDao;
	}
	
	@Transactional("petclinic")
	public List<Vet> getAllVets(){
		return this.vetDao.getAllVets();
	}
}

Web层

package www.com.spring.web;

import java.io.IOException;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import www.com.spring.module.Vet;
import www.com.spring.service.VetService;

@Controller
public class VetWeb {
	private VetService vetService;
	@Autowired
	public void setVetService(VetService vetService) {
		this.vetService = vetService;
	}
	
	@RequestMapping(value = "petclinic/getAllVet.action")
	public void getAllVets(HttpServletRequest request,HttpServletResponse response){
		List<Vet> list = this.vetService.getAllVets();
		request.setAttribute("data", list);
		
		RequestDispatcher dispatcher = request.getRequestDispatcher("/vet.jsp");
	  try {
		dispatcher.forward(request, response);
	} catch (ServletException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
	}
}


前台vet.jsp 代码

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="/blog_article/<%=basePath%>/index.html">
    
    <title>宠物信息页面</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
  </head>
  <body>
  <script type="text/javascript" src="/blog_article/js/showPic.js"></script>
  <jsp:include page="head.jsp"></jsp:include>
   <table border="1">
  	<tr><td>宠物编号</td><td>宠物名称</td><td>宠物年龄</td><td>是否被领养</td><td>物种分类</td></tr>
	  <c:forEach var="vet" items="${data}">
	    <tr>
	      <td>${vet.id}</td><td><a href="/blog_article/${vet.name}.html" >${vet.name}</a></td>
	      <td>${vet.age}</td><td>${vet.masterid}</td><td>${vet.species}</td>
	    </tr>
	  </c:forEach>
	</table>
  </body>
</html>


 

    
[2] 运用DEFLATE的IP有效载荷压缩
    来源: 互联网  发布时间: 2014-02-18
使用DEFLATE的IP有效载荷压缩

3. Detailed specification

   3.1. Overall conventions In the diagrams below, a box like this:
  
 下面的图形表示一个字节:
         +---+
         |   | <-- the vertical bars might be missing
         +---+

 下面的图形表示若干字节:
      represents one byte; a box like this:

         +==============+
         |              |
         +==============+
      represents a variable number of bytes.
 
 计算机中所存贮的字节并不存在“位顺序”,因为字节本身被看作是一个单元。
但是,当一个字节被看作是一个0到255之间的整数时,就会有一些最重要的或是最不重
要的位。通常我们会将一个字节中最重要的位写在左边,将几个字节中,最重要的字节
写在左边。在图表中,我们将一个字节中的各位标上序号:位0表示最不重要的位等等:
      Bytes stored within a computer do not have a "bit order", since
      they are always treated as a unit.  However, a byte considered as
      an integer between 0 and 255 does have a most- and least-
      significant bit, and since we write numbers with the most-
      significant digit on the left, we also write bytes with the most-
      significant bit on the left.  In the diagrams below, we number the
      bits of a byte so that bit 0 is the least-significant bit, i.e.,
      the bits are numbered:
         +--------+
         |76543210|
         +--------+
 在计算机中,一个数可能占用几个字节。这里所说的多字节数据都是将不重要的
部分存贮在低地址的字节中,如520被保存为:
      Within a computer, a number may occupy multiple bytes.  All
      multi-byte numbers in the format described here are stored with
      the least-significant byte first (at the lower memory address).
      For example, the decimal number 520 is stored as:
             0        1
         +--------+--------+
         |00001000|00000010|
         +--------+--------+
          ^        ^
          |        |
          |        + more significant byte = 2 x 256
          + less significant byte = 8
      3.1.1. Packing into bytes
 
  这篇文档中没有指明在位连续的传输媒介中,字节中的位顺序。因为这
里所描述的最终数据格式是字节,而不是位。但是,我们设计了下面的压缩块格式,其中
的数据元素是不定长的位序列,而不是字节。因此我们必须指明如何将这些位组合成字节
序列。
         This document does not address the issue of the order in which
         bits of a byte are transmitted on a bit-sequential medium,
         since the final data format described here is byte- rather than

         bit-oriented.  However, we describe the compressed block format
         in below, as a sequence of data elements of various bit
         lengths, not a sequence of bytes.  We must therefore specify
         how to pack these data elements into bytes to form the final
         compressed byte sequence:

   数据元素(位)被打包到字节中时,是以逐渐增加的位序号排列的。
如:以最不重要的位开始。
   数据元素(除了Huffman编码外)以最不重要的位开始。
   Huffman 编码以最重要的位开始。
             * Data elements are packed into bytes in order of
               increasing bit number within the byte, i.e., starting
               with the least-significant bit of the byte.
             * Data elements other than Huffman codes are packed
               starting with the least-significant bit of the data
               element.
             * Huffman codes are packed starting with the most-
               significant bit of the code.

  换句话说,如果想要以字节序列的方式打印压缩数据,从最右边的空白
开始向最左边进行。将每字节中最重要的位放在左边。
         In other words, if one were to print out the compressed data as
         a sequence of bytes, starting with the first byte at the
         *right* margin and proceeding to the *left*, with the most-
         significant bit of each byte on the left as usual, one would be
         able to parse the result from right to left, with fixed-width
         elements in the correct MSB-to-LSB order and Huffman codes in
         bit-reversed order (i.e., with the first bit of the code in the
         relative LSB position).

   3.2. Compressed block format 压缩的块结构


      3.2.1. Synopsis of prefix and Huffman coding

  前缀编码方式描述了一种可以从位序列预知的字母表。每个符号有一个
编码,其特点是不同的符号有不同的长度的位序列。但是解析器可以明白的解析出编码的
内容。
         Prefix coding represents symbols from an apriori known
         alphabet by bit sequences (codes), one code for each symbol, in
         a manner such that different symbols may be represented by bit
         sequences of different lengths, but a parser can always parse
         an encoded string unambiguously symbol-by-symbol.

  我们根据一个二进制树来进行前缀编码。两边的非叶子结点依次的标上
0,1,而叶子结点则一个一人的标记上字母表中的字符。这样,每个字符的编码就是一个
从根结点到叶子结点的0,1的序列了,如:
         We define a prefix code in terms of a binary tree in which the
         two edges descending from each non-leaf node are labeled 0 and
         1 and in which the leaf nodes correspond one-for-one with (are
         labeled with) the symbols of the alphabet; then the code for a
         symbol is the sequence of 0's and 1's on the edges leading from
         the root to the leaf labeled with that symbol.  For example:

                          /\              Symbol    Code
                         0  1             ------    ----
                        /    \                A      00
                       /\     B               B       1
                      0  1                    C     011
                     /    \                   D     010
                    A     /\
                         0  1
                        /    \
                       D      C

  解码器可以解码输入的内容:让输入的流从这个树的根结点走到叶子
结点,每次的前进都选择与流中下一位相同的一边。
         A parser can decode the next symbol from an encoded input
         stream by walking down the tree from the root, at each step
         choosing the edge corresponding to the next input bit.

  给出一个已知使用频率的字母表,Huffman规则允许解释成一个最佳的
前缀编码,这样的编码被称作Huffman 编码。
         Given an alphabet with known symbol frequencies, the Huffman
         algorithm allows the construction of an optimal prefix code
         (one which represents strings with those symbol frequencies
         using the fewest bits of any possible prefix codes for that
         alphabet).  Such a code is called a Huffman code.  (See
         reference [1] in Chapter 5, references for additional
         information on Huffman codes.)

  注意,在"deflate"格式中,Huffman 编码对于不同的字母表来说
不可以超过最大的编码长度。这个规定使得通过使用频率来计算编码长度的算法变得复杂
了。详细内容见第五节。
         Note that in the "deflate" format, the Huffman codes for the
         various alphabets must not exceed certain maximum code lengths.
         This constraint complicates the algorithm for computing code
         lengths from symbol frequencies.  Again, see Chapter 5,
         references for details.

      3.2.2. Use of Huffman coding in the "deflate" format 在"deflate"格式中使用Huffman编码

  在"deflate"格式中,每一个字母表使用的Huffman编码方式都有两条附加规则:
         The Huffman codes used for each alphabet in the "deflate"
         format have two additional rules:

  所有指定了位长度的编码都有相邻值。而且与他们所代表的符号有
相同的顺序。
             * All codes of a given bit length have lexicographically
               consecutive values, in the same order as the symbols
               they represent;
  
  较短的编码在索引时要先于长的编码。
             * Shorter codes lexicographically precede longer codes.

  我们可以依照这些规则来重新编码上面的例子,假定字母表中的
顺序是ABCD:
         We could recode the example above to follow this rule as
         follows, assuming that the order of the alphabet is ABCD:

            Symbol  Code
            ------  ----
            A       10
            B       0
            C       110
            D       111

  0在10的前面,10在11X的前面。110和111是连续的。
         I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
         lexicographically consecutive.

  有了这个规则,我们可以通过按顺序给定字母表中每一个符号的位长度来
为一个字母表定义Huffman编码。在我们的例子中,编码由位长度的序列所完全定义。下面
的算法将编码生成为整数,规定为从最重要的位读向最不重要的位。编码长度为
tree[I].len,编码则存在于tree[I].Code中。
         Given this rule, we can define the Huffman code for an alphabet
         just by giving the bit lengths of the codes for each symbol of
         the alphabet in order; this is sufficient to determine the
         actual codes.  In our example, the code is completely defined
         by the sequence of bit lengths (2, 1, 3, 3).  The following
         algorithm generates the codes as integers, intended to be read
         from most- to least-significant bit.  The code lengths are
         initially in tree[I].Len; the codes are produced in
         tree[I].Code.
  
  为每一个编码长度计算编码的数量。使bl_count[N]为长度为N(N>=1)
的编码的数量。
         1)  Count the number of codes for each code length.  Let
             bl_count[N] be the number of codes of length N, N >= 1.

  在每一个编码长度中找出最小的数值。
         2)  Find the numerical value of the smallest code for each
             code length:

                code = 0;
                bl_count[0] = 0;
                for (bits = 1; bits <= MAX_BITS; bits++) {
                    code = (code + bl_count[bits-1]) << 1;
                    next_code[bits] = code;
                }

  将数值赋给所有的编码:以第二步中找到的(next_code[bits])为基础,为相同长度
的所有编码连续的赋值。不要为永远不使用的编码(一位的0)赋值。
         3)  Assign numerical values to all codes, using consecutive
             values for all codes of the same length with the base
             values determined at step 2. Codes that are never used
             (which have a bit length of zero) must not be assigned a
             value.

                for (n = 0;  n <= max_code; n++) {
                    len = tree[n].Len;
                    if (len != 0) {
                        tree[n].Code = next_code[len];
                        next_code[len]++;
                    }
                }

         Example:
         Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
         3, 2, 4, 4).  After step 1, we have:

            N      bl_count[N]
            -      -----------
            2      1
            3      5
            4      2

         Step 2 computes the following next_code values:

            N      next_code[N]
            -      ------------
            1      0
            2      0
            3      2
            4      14
         Step 3 produces the following code values:

            Symbol Length   Code
            ------ ------   ----
            A       3        010
            B       3        011
            C       3        100
            D       3        101
            E       3        110
            F       2         00
            G       4       1110
            H       4       1111

      3.2.3. Details of block format  块结构的详细资料

  每个压缩数据块都以三个头位开始:
         Each block of compressed data begins with 3 header bits
         containing the following data:

            first bit       BFINAL  第一位
            next 2 bits     BTYPE  下二位

  注意,头位不需要从一个字节的边界开始,因为“块”不需要占据完整
的若干字节。
         Note that the header bits do not necessarily begin on a byte
         boundary, since a block does not necessarily occupy an integral
         number of bytes.

  只有当前块是最后一块的时候,才设置BFINAL位。
         BFINAL is set if and only if this is the last block of the data
         set.
  BTYPE指定了块数据是如何压缩的:
         BTYPE specifies how the data are compressed, as follows:

            00 - no compression    非压缩
            01 - compressed with fixed Huffman codes 用固定的Huffman编码来压缩。
            10 - compressed with dynamic Huffman codes 用动态的Huffman编码来压缩。
            11 - reserved (error)    保留(错误)


  两种压缩方案的唯一不同是:如何定义Huffman编码。
         The only difference between the two compressed cases is how the
         Huffman codes for the literal/length and distance alphabets are
         defined.
  在所有的情况下,解码的方案如下:
         In all cases, the decoding algorithm for the actual data is as
         follows:


 do
  从输入流读入块头部
  if 非压缩存贮
   跳过当前处理的字节中剩余的位
   读入LEN和NLEN(见下一节)
   向输出拷贝LEN字节。
  else
   if 动态的Huffman编码
    读入编码树
   loop(直到块的结尾)
     从输入流解码出文字/长度值
    if value < 256
     向输出拷贝value(文字字节)
    else
     if value = 块的结尾(256)
       break;(跳出loop)
     else (value = 257到285)
      从输入流解码出距离(distance)

       在输出流中,向后(已经解码的部分)跳过distance
      字节,拷贝当前的length字节
      到输出流中。
   end loop
 while 不是最后一块时
  


do        
               read block header from input stream.   
               if stored with no compression    
                  skip any remaining bits in current partially    
                     processed byte 
                  read LEN and NLEN (see next section)  
                  copy LEN bytes of data to output   
               otherwise       
                  if compressed with dynamic Huffman codes   
                     read representation of code trees (see  
                        subsection below) 
                  loop (until end of block code recognized)  
                     decode literal/length value from input stream  
                     if value < 256      
                        copy value (literal byte) to output stream   
                     otherwise       
                        if value = end of block (256)       
                           break from loop      
                        otherwise (value = 257..285)      
                           decode distance from input stream    

                           move backwards distance bytes in the output  
                           stream, and copy length bytes from this   
                           position to the output stream.   
                  end loop       
            while not last block    


  注意,一个复制的参考串可能指向前一个块,如:向后的distnace可能
穿过一个或几个块边界。但是distance不可能越过输出串的开始。(一个使用预先设定的
字母表的应用程序可能会忽略输出流中的一部分,distance可以指出这部分)还要注意,
被参考的串可能会与当前位置重合,如:如果最后的两个字节解码后是X,Y,一个串提
及:<length = 5,distance = 2>,则向输出中增加X,Y,X,Y,X。

         Note that a duplicated string reference may refer to a string
         in a previous block; i.e., the backward distance may cross one
         or more block boundaries.  However a distance cannot refer past
         the beginning of the output stream.  (An application using a

         preset dictionary might discard part of the output stream; a
         distance can refer to that part of the output stream anyway)
         Note also that the referenced string may overlap the current
         position; for example, if the last 2 bytes decoded have values
         X and Y, a string reference with <length = 5, distance = 2>
         adds X,Y,X,Y,X to the output stream.

  现在,我们按顺序说明每种压缩方法。
         We now specify each compression method in turn.

      3.2.4. Non-compressed blocks (BTYPE=00) 非压缩的块

  忽略直到下一个字节边界的所有位,这块中的其它内容包含如下信息:
         Any bits of input up to the next byte boundary are ignored.
         The rest of the block consists of the following information:

              0   1   2   3   4...
            +---+---+---+---+================================+
            |  LEN  | NLEN  |... LEN bytes of literal data...|
            +---+---+---+---+================================+

  LEN是块中的字节数。NLEN是LEN的补码。
         LEN is the number of data bytes in the block.  NLEN is the
         one's complement of LEN.

      3.2.5. Compressed blocks (length and distance codes) 
  被压缩的块(length,distance的编码)

  如前所述,用"deflate"格式所编码的数据块包含一系列的记号来表示
三种概念清楚的字母表:文字字节,值在0至255之间;或<length,distance>对。
length表示3至258之间,distnace在1至32768之间。实际上,文字和长度字母表被合并
到一个字母表中,从0至285。其中的0至255表示文字字节,256表示块的结束,257至285
表示length,见下表(length可能和几个存在于符号编码后面的额外位联合在一起,表示
不同的含义:)
         As noted above, encoded data blocks in the "deflate" format
         consist of sequences of symbols drawn from three conceptually
         distinct alphabets: either literal bytes, from the alphabet of
         byte values (0..255), or <length, backward distance> pairs,
         where the length is drawn from (3..258) and the distance is
         drawn from (1..32,768).  In fact, the literal and length
         alphabets are merged into a single alphabet (0..285), where
         values 0..255 represent literal bytes, the value 256 indicates
         end-of-block, and values 257..285 represent length codes
         (possibly in conjunction with extra bits following the symbol
         code) as follows:

                 Extra               Extra               Extra
            Code Bits Length(s) Code Bits Lengths   Code Bits Length(s)
            ---- ---- ------     ---- ---- -------   ---- ---- -------
             257   0     3       267   1   15,16     277   4   67-82
             258   0     4       268   1   17,18     278   4   83-98
             259   0     5       269   2   19-22     279   4   99-114
             260   0     6       270   2   23-26     280   4  115-130
             261   0     7       271   2   27-30     281   5  131-162
             262   0     8       272   2   31-34     282   5  163-194
             263   0     9       273   3   35-42     283   5  195-226
             264   0    10       274   3   43-50     284   5  227-257
             265   1  11,12      275   3   51-58     285   0    258
             266   1  13,14      276   3   59-66

  额外的位应该被声明成整数,最重要的位在前面,如:1110代表14。
         The extra bits should be interpreted as a machine integer
         stored with the most-significant bit first, e.g., bits 1110
         represent the value 14.


                  Extra           Extra               Extra
             Code Bits Dist  Code Bits   Dist     Code Bits Distance
             ---- ---- ----  ---- ----  ------    ---- ---- --------
               0   0    1     10   4     33-48    20    9   1025-1536
               1   0    2     11   4     49-64    21    9   1537-2048
               2   0    3     12   5     65-96    22   10   2049-3072
               3   0    4     13   5     97-128   23   10   3073-4096
               4   1   5,6    14   6    129-192   24   11   4097-6144
               5   1   7,8    15   6    193-256   25   11   6145-8192
               6   2   9-12   16   7    257-384   26   12  8193-12288
               7   2  13-16   17   7    385-512   27   12 12289-16384
               8   3  17-24   18   8    513-768   28   13 16385-24576
               9   3  25-32   19   8   769-1024   29   13 24577-32768


      3.2.6. Compression with fixed Huffman codes (BTYPE=01)
  用固定的Huffman编码压缩

  两个字母表的Huffman编码是固定的,没有在数据中明确的指出。
文字/length的Huffman编码长度如下:
         The Huffman codes for the two alphabets are fixed, and are not
         represented explicitly in the data.  The Huffman code lengths
         for the literal/length alphabet are:

                   Lit Value    Bits        Codes
                   ---------    ----        -----
                     0 - 143     8          00110000 through
                                            10111111
                   144 - 255     9          110010000 through
                                            111111111
                   256 - 279     7          0000000 through
                                            0010111
                   280 - 287     8          11000000 through
                                            11000111

  上面所述的编码长度足以产生实际的编码。文字/length值286至287
永远不会真正的出现在压缩数据中,但是也存在于编码结构中。
         The code lengths are sufficient to generate the actual codes,
         as described above; we show the codes in the table for added
         clarity.  Literal/length values 286-287 will never actually
         occur in the compressed data, but participate in the code
         construction.

  distance的代码 0-31被表示成5位的编码以及可能存在的附加位,
如上面3.2.5节中的图表所示。注意距离代码30-31不会真正出现在压缩数据中。
         Distance codes 0-31 are represented by (fixed-length) 5-bit
         codes, with possible additional bits as shown in the table
         shown in Paragraph 3.2.5, above.  Note that distance codes 30-
         31 will never actually occur in the compressed data.

      3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
  用动态Huffman编码压缩

  一个块中的Huffman 编码(对两个字母表的编码)存在于头位的后面,
实际压缩内容的前面。第一个是文字/length 编码,第二个是distance编码。每个
编码都被一系列编码长度所定义,见3.2.2节。为了更加简洁,编码长度本身也是经过
了Huffman编码压缩的(这句话十分重要,以前就是由于没有透彻理解这一点才会看不
懂后面的内容--注)。字母表的编码长度如下:

         The Huffman codes for the two alphabets appear in the block
         immediately after the header bits and before the actual
         compressed data, first the literal/length code and then the
         distance code.  Each code is defined by a sequence of code
         lengths, as discussed in Paragraph 3.2.2, above.  For even
         greater compactness, the code length sequences themselves are
         compressed using a Huffman code.  The alphabet for code lengths
         is as follows:

  0 - 15: 表示编码长度为0 - 15
                   16: 复制前面的编码长度3 - 6次,
      下两位指出了复制的次数
                          (0 = 3, ... , 3 = 6)
                         如:编码: 8, 16 (+2 bits 11),16 (+2 bits 10)
    会被扩展为:
                                    12个长度为8 的编码 (12 = 1 + 6 + 5)
                   17: 重复3 - 10 次长度为0
                       (下三位指出了重复次数)
                   18: 重复11 - 138 次长度为0
                       (下7位指出了重复次数)

 

               0 - 15: Represent code lengths of 0 - 15
                   16: Copy the previous code length 3 - 6 times.
                       The next 2 bits indicate repeat length
                             (0 = 3, ... , 3 = 6)
                          Example:  Codes 8, 16 (+2 bits 11),
                                    16 (+2 bits 10) will expand to
                                    12 code lengths of 8 (1 + 6 + 5)
                   17: Repeat a code length of 0 for 3 - 10 times.
                       (3 bits of length)
                   18: Repeat a code length of 0 for 11 - 138 times
                       (7 bits of length)

  编码长度为0表示文字/length或distance不会出现在块中,也就不存在
于Huffman编码中。如果只使用一个distance编码长度,则编码时,使用一位,而不是0
位。
在这种情况下,只有一个编码长度1,和一个不使用的编码。0位的distance编码表示没

distance编码(所有的内容都是文字的)
         A code length of 0 indicates that the corresponding symbol in
         the literal/length or distance alphabet will not occur in the
         block, and should not participate in the Huffman code
         construction algorithm given earlier.  If only one distance
         code is used, it is encoded using one bit, not zero bits; in
         this case there is a single code length of one, with one unused
         code.  One distance code of zero bits means that there are no
         distance codes used at all (the data is all literals).

  现在我们可以定义块的格式了(在某一块中,除了最前面的三个标志位之外,
就是如下的内容了--注):
         We can now define the format of the block:

               5 Bits: HLIT, # 文字/length编码 - 257 (见3.2.5节。
                由于使用了LZ77算法,所以除了文字之外,还要对<length,
                distance>对进行编码。文字和长度字母表被合并到一个字
                母表中,从0至285。其中的0至255表示文字字节,256表示块
                的结束,257至285表示length。但由于不一定要使用所有的
                length, 所以,这里的5位表示本块中所能用到的最大的
                值--是指0到285间的一个值--减去257之后的值----注)
               5 Bits: HDIST, # of Distance 编码 - 1 (同理,这里保存
                的是3.2.5节中描述的在本块中可能用到的distance的最
                大值-1----注)

               4 Bits: HCLEN, # of "编码长度"的编码 - 4    (其实这4
                位中保存的是所能用到的编码长度的种类 - 4,这里的“编
                码长度”是指从0到18的值,其含义在3.2.7节中所定义。换
                句话说,有下面一个数组:16, 17, 18, 0, 8, 7, 9, 6,
                10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,HCLEN+4的值就
                表示了在本块的编码时,都用到了本数组中前几项的长度值,
                而其它的长度值则不被使用争----注)


               5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
               5 Bits: HDIST, # of Distance codes - 1        (1 - 32)
               4 Bits: HCLEN, # of Code Length codes - 4     (4 - 19)


   (HCLEN + 4) x 3 bits: 编码长度表中的编码长度按照如下顺序排列(关键的
                地方在这里。这里3位一组,表示相应位置的长度值在Huffman
                编码中有几位。这句话不好理解,详细解释一下:在前面说过
                了,HCLEN+4表示会使用多少种不同的编码长度值,至于都使
                用哪些长度,则查看下面的数组,其前面的HCLEN+4项中所示
                的值就是本块编码中所要使用的编码长度。于是,在下一部分
                中就要分别指出每个字符的编码长度了 ---- 在Huffman解码
                时,只要知道了每一个字符的编码长度,就可以无误的构造出
                编码时使用的二叉树了。但是目前的问题是,怎样表示出每个
                字符用几位编码。为了获得更大的压缩,Gzip采用了另一个
                huffman树来编码不同的长度值。就在本部分中,每三位表示
                一个值X,这个值X就是指要用X位来编码数组中相应位置的那
                个长度值。----注)
               (HCLEN + 4) x 3 bits: code lengths for the code length
                  alphabet given just above, in the order: 16, 17, 18,
                  0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15

   这些编码的长度被表示成3位的整数(0-7),如前所述,一个编码
的长度为0,意味着相应的符号(文字/length或distance编码长度不被使用)
                  These code lengths are interpreted as 3-bit integers
                  (0-7); as above, a code length of 0 means the
                  corresponding symbol (literal/length or distance code
                  length) is not used.

   用Huffman编码的HLIT+257个编码长度。(这一部分解码后是HLIT+257个值,每
                个值分别依次代表从0到HLIT+257-1的编码长度。至于解码的方法
                则是用从前一部分中所得到的Huffman码。----注)
               HLIT + 257 code lengths for the literal/length alphabet,
                  encoded using the code length Huffman code

   用Huffman编码的HDIST+1的编码长度。(这一部分解码后是HDIST+1个值,依次
                代表<LENGTH,DISTENCE>中的DISTENCE从0到HDIST的编码长度。
                ----注)
               HDIST + 1 code lengths for the distance alphabet,
                  encoded using the code length Huffman code

   实际的压缩数据,使用Huffman编码的文字/length、distance。(用上面两部分
                中所列举的编码长度,可以构造出两个Huffman树,再用它们对
                这部分中的压缩数据进行解码。以上所说的编码长度均是指用
                多少位对数据进行编码----注)
               The actual compressed data of the block,
                  encoded using the literal/length and distance Huffman
                  codes

                最后写入256的Huffman编码,这样解码时,解出值256,就会知道
                已经到块尾了。
               The literal/length symbol 256 (end of data),
                  encoded using the literal/length Huffman code

         The code length repeat codes can cross from HLIT + 257 to the
         HDIST + 1 code lengths.  In other words, all code lengths form
         a single sequence of HLIT + HDIST + 258 values.

   3.3. Compliance

      A compressor may limit further the ranges of values specified in
      the previous section and still be compliant; for example, it may
      limit the range of backward pointers to some value smaller than
      32K.  Similarly, a compressor may limit the size of blocks so that
      a compressible block fits in memory.

      A compliant decompressor must accept the full range of possible
      values defined in the previous section, and must accept blocks of
      arbitrary size.


作者Blog:http://blog.csdn.net/prettynacl/


    
[3] C中构造体大小的计算
    来源: 互联网  发布时间: 2014-02-18
C中结构体大小的计算

    最近研究了一下c语言中结构体大小的计算,根据自己的理解以及参考网上的资料,

想做一点总结。

   先介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体

变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。

由于存储变量时地址对齐的要求,编译器在编译程序时会遵循两条原则:

一、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)

二、结构体大小必须是所有成员大小的整数倍。

 

这是一种说法,还有一种说法:

 

结构体默认的字节对齐一般满足三个准则:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

 2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,

如有需要编译器会在成员之间加上填充字节(internal adding);

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末

一个成员之后加上填充字节。

 

我自己写了三个结构体测试了一下,代码如下:

输出结果是:

12

8

20

 

先看第一个结构体,第一个成员a的偏移量为0。第二个成员b的偏移量是第一个成员的偏移量加上第一个成员的大小(0+4),其值为4;第三个成员c的偏移量是第二个成员的偏移量加上第二个成员的大小(4+1),其值为5。上面的例子中前两个成员的偏移量都满足要求,但第三个成员的偏移量为5,并不是自身(int)大小的整数倍。编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成8。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。偏移量8加上最后一个成员c自身的大小,即为9,9不能被最宽基本类型成员大小整除,所以这里编译器会在最后补齐3个字节,得出12。

  至于第二个结构体,大小等于最后一个成员的偏移量加上其大小,上面的例子中计算出来的大小为8,满足要求。

       按照上述的计算规则,结构体一和结构体二都可以计算出与输出一致的结果,可是结构体三有点不明白。

 

        偏移量              填充字节                    成员自身大小

           0                                                        4

           4                                                        1

           5                      1                                2

           8                                                        8

           16                                                      4 

最后一个成员的偏移量加上自身大小,得出20,20不能整除最宽成员偏移量大小,我觉得应该补齐4个字节,可是这里为什么输出结果是20呢?我表示不理解!

望大神指教一二!!!不胜感激。

 

 

2楼mdx200724194天前 09:18我在ubuntu下采用gcc编译,运行结果确实是201楼stsw20464天前 20:48s3的大小是24。a占byte(0)~byte(3),b占byte(4),c占byte(6)~byte(7),d占byte(8)~byte(15),f占byte(16)~byte(19),结构体最大元素为8byte,故需填充至byte(23),所以结构体大小为24byte。

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3