package org.yi.happy.archive.block;

import java.util.Map;

import org.yi.happy.annotate.ExternalValue;
import org.yi.happy.archive.Bytes;

/**
 * a data block is a set of simple headers and a body, with a very simple
 * format. The upper size of any block in use is just over 1 MiB.
 */
public interface Block {
    /**
     * The first byte of the end of line sequence.
     */
    @ExternalValue
    public static final byte CR = '\r';
    /**
     * The second byte of the end of line sequence.
     */
    @ExternalValue
    public static final byte LF = '\n';
    /**
     * The first byte of the header separator sequence.
     */
    @ExternalValue
    public static final byte COLON = ':';
    /**
     * The second byte of the header separator sequence.
     */
    @ExternalValue
    public static final byte SPACE = ' ';

    /**
     * The terminator of a header and the separator between the headers and body
     * (CR LF). Parsers should be flexible and accept any combination of the
     * bytes in this sequence (either, both, reverse).
     */
    @ExternalValue
    public static final Bytes ENDL = new Bytes(CR, LF);

    /**
     * The separator of a header name and the value of the header (COLON SPACE).
     * Parsers should be flexible and accept the first byte by itself in
     * addition to the full sequence.
     */
    @ExternalValue
    public static final Bytes SEPARATOR = new Bytes(COLON, SPACE);

    /**
     * get the meta data (headers).
     * 
     * @return a possibly ordered map of the meta data fields.
     */
    public Map<String, String> getMeta();

    /**
     * get the body of the block.
     * 
     * @return the body of the block.
     */
    public Bytes getBody();

    /**
     * convert the block to bytes.
     * 
     * @return the block as bytes.
     */
    public byte[] asBytes();

    /**
     * When implementing this method, it is expected that two different
     * implementations of Block which have the same meta-data and body are
     * equal.
     * 
     * @param obj
     *            the object to compare to.
     * @return true if the objects are equivalent, false otherwise.
     * @see AbstractBlock
     */
    @Override
    public boolean equals(Object obj);

    /**
     * When implementing this method, it is expected that two different
     * implementations of Block which have the same meta-data and body are
     * equal.
     * 
     * @param obj
     *            the object to compare to.
     * @return true if the objects are equivalent, false otherwise.
     * @see AbstractBlock
     */
    @Override
    public int hashCode();
}

@@ -355,34 +355,41 @@
 of line sequence
+ ('%5Cr')
 .%0A
-
      */%0A    @Ext
@@ -439,16 +439,17 @@
 = '%5Cr';%0A
+%0A
     /**%0A
@@ -490,32 +490,39 @@
 of line sequence
+ ('%5Cn')
 .%0A     */%0A    @E
@@ -574,16 +574,17 @@
 = '%5Cn';%0A
+%0A
     /**%0A
@@ -629,32 +629,38 @@
 parator sequence
+ (':')
 .%0A     */%0A    @E
@@ -714,24 +714,25 @@
  = ':';%0A
+%0A
     /**%0A
      * T
@@ -715,32 +715,32 @@
 = ':';%0A%0A    /**%0A
-
      * The secon
@@ -770,32 +770,38 @@
 parator sequence
+ (' ')
 .%0A     */%0A    @E

update the documentation on the Block external values.