Last active
April 7, 2017 01:19
-
-
Save pascaldekloe/b54326e6b7c5e9f036911a8cbea6ccbf to your computer and use it in GitHub Desktop.
Demo Java Compilation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.demo; | |
// Code generated by colf(1); DO NOT EDIT. | |
import static java.lang.String.format; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.io.ObjectStreamException; | |
import java.io.OutputStream; | |
import java.io.Serializable; | |
import java.nio.charset.StandardCharsets; | |
import java.util.InputMismatchException; | |
import java.nio.BufferOverflowException; | |
import java.nio.BufferUnderflowException; | |
/** | |
* Data bean with built-in serialization support. | |
* Course is the grounds where the game of golf is played. | |
* @author generated by colf(1) | |
* @see <a href="https://github.com/pascaldekloe/colfer">Colfer's home</a> | |
*/ | |
@javax.annotation.Generated(value="colf(1)", comments="Colfer from schema file demo.colf") | |
public class Course extends com.example.BeanParent implements Serializable { | |
/** The upper limit for serial byte sizes. */ | |
public static int colferSizeMax = 2 * 1024; | |
/** The upper limit for the number of elements in a list. */ | |
public static int colferListMax = 99; | |
public long ID; | |
public String name; | |
public Hole[] holes; | |
public byte[] image; | |
public String[] tags; | |
/** Default constructor */ | |
public Course() { | |
init(); | |
} | |
private static final byte[] _zeroBytes = new byte[0]; | |
private static final Hole[] _zeroHoles = new Hole[0]; | |
private static final String[] _zeroTags = new String[0]; | |
/** Colfer zero values. */ | |
private void init() { | |
name = ""; | |
holes = _zeroHoles; | |
image = _zeroBytes; | |
tags = _zeroTags; | |
} | |
/** | |
* {@link #reset(InputStream) Reusable} deserialization of Colfer streams. | |
*/ | |
public static class Unmarshaller { | |
/** The data source. */ | |
protected InputStream in; | |
/** The read buffer. */ | |
public byte[] buf; | |
/** The {@link #buf buffer}'s data start index, inclusive. */ | |
protected int offset; | |
/** The {@link #buf buffer}'s data end index, exclusive. */ | |
protected int i; | |
/** | |
* @param in the data source or {@code null}. | |
* @param buf the initial buffer or {@code null}. | |
*/ | |
public Unmarshaller(InputStream in, byte[] buf) { | |
// TODO: better size estimation | |
if (buf == null || buf.length == 0) | |
buf = new byte[Math.min(Course.colferSizeMax, 2048)]; | |
this.buf = buf; | |
reset(in); | |
} | |
/** | |
* Reuses the marshaller. | |
* @param in the data source or {@code null}. | |
* @throws IllegalStateException on pending data. | |
*/ | |
public void reset(InputStream in) { | |
if (this.i != this.offset) throw new IllegalStateException("colfer: pending data"); | |
this.in = in; | |
this.offset = 0; | |
this.i = 0; | |
} | |
/** | |
* Deserializes the following object. | |
* @return the result or {@code null} when EOF. | |
* @throws IOException from the input stream. | |
* @throws SecurityException on an upper limit breach defined by either {@link #colferSizeMax} or {@link #colferListMax}. | |
* @throws InputMismatchException when the data does not match this object's schema. | |
*/ | |
public Course next() throws IOException { | |
if (in == null) return null; | |
while (true) { | |
if (this.i > this.offset) { | |
try { | |
Course o = new Course(); | |
this.offset = o.unmarshal(this.buf, this.offset, this.i); | |
return o; | |
} catch (BufferUnderflowException e) { | |
} | |
} | |
// not enough data | |
if (this.i <= this.offset) { | |
this.offset = 0; | |
this.i = 0; | |
} else if (i == buf.length) { | |
byte[] src = this.buf; | |
// TODO: better size estimation | |
if (offset == 0) this.buf = new byte[Math.min(Course.colferSizeMax, this.buf.length * 4)]; | |
System.arraycopy(src, this.offset, this.buf, 0, this.i - this.offset); | |
this.i -= this.offset; | |
this.offset = 0; | |
} | |
assert this.i < this.buf.length; | |
int n = in.read(buf, i, buf.length - i); | |
if (n < 0) { | |
if (this.i > this.offset) | |
throw new InputMismatchException("colfer: pending data with EOF"); | |
return null; | |
} | |
assert n > 0; | |
i += n; | |
} | |
} | |
} | |
/** | |
* Serializes the object. | |
* All {@code null} elements in {@link #holes} will be replaced with a {@code new} value. | |
* All {@code null} elements in {@link #tags} will be replaced with {@code ""}. | |
* @param out the data destination. | |
* @param buf the initial buffer or {@code null}. | |
* @return the final buffer. When the serial fits into {@code buf} then the return is {@code buf}. | |
* Otherwise the return is a new buffer, large enough to hold the whole serial. | |
* @throws IOException from {@code out}. | |
* @throws IllegalStateException on an upper limit breach defined by either {@link #colferSizeMax} or {@link #colferListMax}. | |
*/ | |
public byte[] marshal(OutputStream out, byte[] buf) throws IOException { | |
// TODO: better size estimation | |
if (buf == null || buf.length == 0) | |
buf = new byte[Math.min(Course.colferSizeMax, 2048)]; | |
while (true) { | |
int i; | |
try { | |
i = marshal(buf, 0); | |
} catch (BufferOverflowException e) { | |
buf = new byte[Math.min(Course.colferSizeMax, buf.length * 4)]; | |
continue; | |
} | |
out.write(buf, 0, i); | |
return buf; | |
} | |
} | |
/** | |
* Serializes the object. | |
* All {@code null} elements in {@link #holes} will be replaced with a {@code new} value. | |
* All {@code null} elements in {@link #tags} will be replaced with {@code ""}. | |
* @param buf the data destination. | |
* @param offset the initial index for {@code buf}, inclusive. | |
* @return the final index for {@code buf}, exclusive. | |
* @throws BufferOverflowException when {@code buf} is too small. | |
* @throws IllegalStateException on an upper limit breach defined by either {@link #colferSizeMax} or {@link #colferListMax}. | |
*/ | |
public int marshal(byte[] buf, int offset) { | |
int i = offset; | |
try { | |
if (this.ID != 0) { | |
long x = this.ID; | |
if ((x & ~((1L << 49) - 1)) != 0) { | |
buf[i++] = (byte) (0 | 0x80); | |
buf[i++] = (byte) (x >>> 56); | |
buf[i++] = (byte) (x >>> 48); | |
buf[i++] = (byte) (x >>> 40); | |
buf[i++] = (byte) (x >>> 32); | |
buf[i++] = (byte) (x >>> 24); | |
buf[i++] = (byte) (x >>> 16); | |
buf[i++] = (byte) (x >>> 8); | |
buf[i++] = (byte) (x); | |
} else { | |
buf[i++] = (byte) 0; | |
while (x > 0x7fL) { | |
buf[i++] = (byte) (x | 0x80); | |
x >>>= 7; | |
} | |
buf[i++] = (byte) x; | |
} | |
} | |
if (! this.name.isEmpty()) { | |
buf[i++] = (byte) 1; | |
int start = ++i; | |
String s = this.name; | |
for (int sIndex = 0, sLength = s.length(); sIndex < sLength; sIndex++) { | |
char c = s.charAt(sIndex); | |
if (c < '\u0080') { | |
buf[i++] = (byte) c; | |
} else if (c < '\u0800') { | |
buf[i++] = (byte) (192 | c >>> 6); | |
buf[i++] = (byte) (128 | c & 63); | |
} else if (c < '\ud800' || c > '\udfff') { | |
buf[i++] = (byte) (224 | c >>> 12); | |
buf[i++] = (byte) (128 | c >>> 6 & 63); | |
buf[i++] = (byte) (128 | c & 63); | |
} else { | |
int cp = 0; | |
if (++sIndex < sLength) cp = Character.toCodePoint(c, s.charAt(sIndex)); | |
if ((cp >= 1 << 16) && (cp < 1 << 21)) { | |
buf[i++] = (byte) (240 | cp >>> 18); | |
buf[i++] = (byte) (128 | cp >>> 12 & 63); | |
buf[i++] = (byte) (128 | cp >>> 6 & 63); | |
buf[i++] = (byte) (128 | cp & 63); | |
} else | |
buf[i++] = (byte) '?'; | |
} | |
} | |
int size = i - start; | |
if (size > Course.colferSizeMax) | |
throw new IllegalStateException(format("colfer: com/example/demo.course.name size %d exceeds %d UTF-8 bytes", size, Course.colferSizeMax)); | |
int ii = start - 1; | |
if (size > 0x7f) { | |
i++; | |
for (int x = size; x >= 1 << 14; x >>>= 7) i++; | |
System.arraycopy(buf, start, buf, i - size, size); | |
do { | |
buf[ii++] = (byte) (size | 0x80); | |
size >>>= 7; | |
} while (size > 0x7f); | |
} | |
buf[ii] = (byte) size; | |
} | |
if (this.holes.length != 0) { | |
buf[i++] = (byte) 2; | |
Hole[] a = this.holes; | |
int x = a.length; | |
if (x > Course.colferListMax) | |
throw new IllegalStateException(format("colfer: com/example/demo.course.holes length %d exceeds %d elements", x, Course.colferListMax)); | |
while (x > 0x7f) { | |
buf[i++] = (byte) (x | 0x80); | |
x >>>= 7; | |
} | |
buf[i++] = (byte) x; | |
for (int ai = 0; ai < a.length; ai++) { | |
Hole o = a[ai]; | |
if (o == null) { | |
o = new Hole(); | |
a[ai] = o; | |
} | |
i = o.marshal(buf, i); | |
} | |
} | |
if (this.image.length != 0) { | |
buf[i++] = (byte) 3; | |
int size = this.image.length; | |
if (size > Course.colferSizeMax) | |
throw new IllegalStateException(format("colfer: com/example/demo.course.image size %d exceeds %d bytes", size, Course.colferSizeMax)); | |
int x = size; | |
while (x > 0x7f) { | |
buf[i++] = (byte) (x | 0x80); | |
x >>>= 7; | |
} | |
buf[i++] = (byte) x; | |
int start = i; | |
i += size; | |
System.arraycopy(this.image, 0, buf, start, size); | |
} | |
if (this.tags.length != 0) { | |
buf[i++] = (byte) 4; | |
String[] a = this.tags; | |
int x = a.length; | |
if (x > Course.colferListMax) | |
throw new IllegalStateException(format("colfer: com/example/demo.course.tags length %d exceeds %d elements", x, Course.colferListMax)); | |
while (x > 0x7f) { | |
buf[i++] = (byte) (x | 0x80); | |
x >>>= 7; | |
} | |
buf[i++] = (byte) x; | |
for (int ai = 0; ai < a.length; ai++) { | |
String s = a[ai]; | |
if (s == null) { | |
s = ""; | |
a[ai] = s; | |
} | |
int start = ++i; | |
for (int sIndex = 0, sLength = s.length(); sIndex < sLength; sIndex++) { | |
char c = s.charAt(sIndex); | |
if (c < '\u0080') { | |
buf[i++] = (byte) c; | |
} else if (c < '\u0800') { | |
buf[i++] = (byte) (192 | c >>> 6); | |
buf[i++] = (byte) (128 | c & 63); | |
} else if (c < '\ud800' || c > '\udfff') { | |
buf[i++] = (byte) (224 | c >>> 12); | |
buf[i++] = (byte) (128 | c >>> 6 & 63); | |
buf[i++] = (byte) (128 | c & 63); | |
} else { | |
int cp = 0; | |
if (++sIndex < sLength) cp = Character.toCodePoint(c, s.charAt(sIndex)); | |
if ((cp >= 1 << 16) && (cp < 1 << 21)) { | |
buf[i++] = (byte) (240 | cp >>> 18); | |
buf[i++] = (byte) (128 | cp >>> 12 & 63); | |
buf[i++] = (byte) (128 | cp >>> 6 & 63); | |
buf[i++] = (byte) (128 | cp & 63); | |
} else | |
buf[i++] = (byte) '?'; | |
} | |
} | |
int size = i - start; | |
if (size > Course.colferSizeMax) | |
throw new IllegalStateException(format("colfer: com/example/demo.course.tags[%d] size %d exceeds %d UTF-8 bytes", ai, size, Course.colferSizeMax)); | |
int ii = start - 1; | |
if (size > 0x7f) { | |
i++; | |
for (int y = size; y >= 1 << 14; y >>>= 7) i++; | |
System.arraycopy(buf, start, buf, i - size, size); | |
do { | |
buf[ii++] = (byte) (size | 0x80); | |
size >>>= 7; | |
} while (size > 0x7f); | |
} | |
buf[ii] = (byte) size; | |
} | |
} | |
buf[i++] = (byte) 0x7f; | |
return i; | |
} catch (ArrayIndexOutOfBoundsException e) { | |
if (i - offset > Course.colferSizeMax) | |
throw new IllegalStateException(format("colfer: com/example/demo.course exceeds %d bytes", Course.colferSizeMax)); | |
if (i > buf.length) throw new BufferOverflowException(); | |
throw e; | |
} | |
} | |
/** | |
* Deserializes the object. | |
* @param buf the data source. | |
* @param offset the initial index for {@code buf}, inclusive. | |
* @return the final index for {@code buf}, exclusive. | |
* @throws BufferUnderflowException when {@code buf} is incomplete. (EOF) | |
* @throws SecurityException on an upper limit breach defined by either {@link #colferSizeMax} or {@link #colferListMax}. | |
* @throws InputMismatchException when the data does not match this object's schema. | |
*/ | |
public int unmarshal(byte[] buf, int offset) { | |
return unmarshal(buf, offset, buf.length); | |
} | |
/** | |
* Deserializes the object. | |
* @param buf the data source. | |
* @param offset the initial index for {@code buf}, inclusive. | |
* @param end the index limit for {@code buf}, exclusive. | |
* @return the final index for {@code buf}, exclusive. | |
* @throws BufferUnderflowException when {@code buf} is incomplete. (EOF) | |
* @throws SecurityException on an upper limit breach defined by either {@link #colferSizeMax} or {@link #colferListMax}. | |
* @throws InputMismatchException when the data does not match this object's schema. | |
*/ | |
public int unmarshal(byte[] buf, int offset, int end) { | |
if (end > buf.length) end = buf.length; | |
int i = offset; | |
try { | |
byte header = buf[i++]; | |
if (header == (byte) 0) { | |
long x = 0; | |
for (int shift = 0; true; shift += 7) { | |
byte b = buf[i++]; | |
if (shift == 56 || b >= 0) { | |
x |= (b & 0xffL) << shift; | |
break; | |
} | |
x |= (b & 0x7fL) << shift; | |
} | |
this.ID = x; | |
header = buf[i++]; | |
} else if (header == (byte) (0 | 0x80)) { | |
this.ID = (buf[i++] & 0xffL) << 56 | (buf[i++] & 0xffL) << 48 | (buf[i++] & 0xffL) << 40 | (buf[i++] & 0xffL) << 32 | |
| (buf[i++] & 0xffL) << 24 | (buf[i++] & 0xffL) << 16 | (buf[i++] & 0xffL) << 8 | (buf[i++] & 0xffL); | |
header = buf[i++]; | |
} | |
if (header == (byte) 1) { | |
int size = 0; | |
for (int shift = 0; true; shift += 7) { | |
byte b = buf[i++]; | |
size |= (b & 0x7f) << shift; | |
if (shift == 28 || b >= 0) break; | |
} | |
if (size < 0 || size > Course.colferSizeMax) | |
throw new SecurityException(format("colfer: com/example/demo.course.name size %d exceeds %d UTF-8 bytes", size, Course.colferSizeMax)); | |
int start = i; | |
i += size; | |
this.name = new String(buf, start, size, StandardCharsets.UTF_8); | |
header = buf[i++]; | |
} | |
if (header == (byte) 2) { | |
int length = 0; | |
for (int shift = 0; true; shift += 7) { | |
byte b = buf[i++]; | |
length |= (b & 0x7f) << shift; | |
if (shift == 28 || b >= 0) break; | |
} | |
if (length < 0 || length > Course.colferListMax) | |
throw new SecurityException(format("colfer: com/example/demo.course.holes length %d exceeds %d elements", length, Course.colferListMax)); | |
Hole[] a = new Hole[length]; | |
for (int ai = 0; ai < length; ai++) { | |
Hole o = new Hole(); | |
i = o.unmarshal(buf, i, end); | |
a[ai] = o; | |
} | |
this.holes = a; | |
header = buf[i++]; | |
} | |
if (header == (byte) 3) { | |
int size = 0; | |
for (int shift = 0; true; shift += 7) { | |
byte b = buf[i++]; | |
size |= (b & 0x7f) << shift; | |
if (shift == 28 || b >= 0) break; | |
} | |
if (size < 0 || size > Course.colferSizeMax) | |
throw new SecurityException(format("colfer: com/example/demo.course.image size %d exceeds %d bytes", size, Course.colferSizeMax)); | |
this.image = new byte[size]; | |
int start = i; | |
i += size; | |
System.arraycopy(buf, start, this.image, 0, size); | |
header = buf[i++]; | |
} | |
if (header == (byte) 4) { | |
int length = 0; | |
for (int shift = 0; true; shift += 7) { | |
byte b = buf[i++]; | |
length |= (b & 0x7f) << shift; | |
if (shift == 28 || b >= 0) break; | |
} | |
if (length < 0 || length > Course.colferListMax) | |
throw new SecurityException(format("colfer: com/example/demo.course.tags length %d exceeds %d elements", length, Course.colferListMax)); | |
String[] a = new String[length]; | |
for (int ai = 0; ai < length; ai++) { | |
int size = 0; | |
for (int shift = 0; true; shift += 7) { | |
byte b = buf[i++]; | |
size |= (b & 0x7f) << shift; | |
if (shift == 28 || b >= 0) break; | |
} | |
if (size < 0 || size > Course.colferSizeMax) | |
throw new SecurityException(format("colfer: com/example/demo.course.tags[%d] size %d exceeds %d UTF-8 bytes", ai, size, Course.colferSizeMax)); | |
int start = i; | |
i += size; | |
a[ai] = new String(buf, start, size, StandardCharsets.UTF_8); | |
} | |
this.tags = a; | |
header = buf[i++]; | |
} | |
if (header != (byte) 0x7f) | |
throw new InputMismatchException(format("colfer: unknown header at byte %d", i - 1)); | |
} finally { | |
if (i > end && end - offset < Course.colferSizeMax) throw new BufferUnderflowException(); | |
if (i < 0 || i - offset > Course.colferSizeMax) | |
throw new SecurityException(format("colfer: com/example/demo.course exceeds %d bytes", Course.colferSizeMax)); | |
if (i > end) throw new BufferUnderflowException(); | |
} | |
return i; | |
} | |
// {@link Serializable} version number. | |
private static final long serialVersionUID = 5L; | |
// {@link Serializable} Colfer extension. | |
private void writeObject(ObjectOutputStream out) throws IOException { | |
// TODO: better size estimation | |
byte[] buf = new byte[1024]; | |
int n; | |
while (true) try { | |
n = marshal(buf, 0); | |
break; | |
} catch (BufferUnderflowException e) { | |
buf = new byte[4 * buf.length]; | |
} | |
out.writeInt(n); | |
out.write(buf, 0, n); | |
} | |
// {@link Serializable} Colfer extension. | |
private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException { | |
init(); | |
int n = in.readInt(); | |
byte[] buf = new byte[n]; | |
in.readFully(buf); | |
unmarshal(buf, 0); | |
} | |
// {@link Serializable} Colfer extension. | |
private void readObjectNoData() throws ObjectStreamException { | |
init(); | |
} | |
/** | |
* Gets com/example/demo.course.ID. | |
* @return the value. | |
*/ | |
public long getID() { | |
return this.ID; | |
} | |
/** | |
* Sets com/example/demo.course.ID. | |
* @param value the replacement. | |
*/ | |
public void setID(long value) { | |
this.ID = value; | |
} | |
/** | |
* Gets com/example/demo.course.name. | |
* @return the value. | |
*/ | |
public String getName() { | |
return this.name; | |
} | |
/** | |
* Sets com/example/demo.course.name. | |
* @param value the replacement. | |
*/ | |
public void setName(String value) { | |
this.name = value; | |
} | |
/** | |
* Gets com/example/demo.course.holes. | |
* @return the value. | |
*/ | |
public Hole[] getHoles() { | |
return this.holes; | |
} | |
/** | |
* Sets com/example/demo.course.holes. | |
* @param value the replacement. | |
*/ | |
public void setHoles(Hole[] value) { | |
this.holes = value; | |
} | |
/** | |
* Gets com/example/demo.course.image. | |
* @return the value. | |
*/ | |
public byte[] getImage() { | |
return this.image; | |
} | |
/** | |
* Sets com/example/demo.course.image. | |
* @param value the replacement. | |
*/ | |
public void setImage(byte[] value) { | |
this.image = value; | |
} | |
/** | |
* Gets com/example/demo.course.tags. | |
* @return the value. | |
*/ | |
public String[] getTags() { | |
return this.tags; | |
} | |
/** | |
* Sets com/example/demo.course.tags. | |
* @param value the replacement. | |
*/ | |
public void setTags(String[] value) { | |
this.tags = value; | |
} | |
@Override | |
public final int hashCode() { | |
int h = 1; | |
h = 31 * h + (int)(this.ID ^ this.ID >>> 32); | |
if (this.name != null) h = 31 * h + this.name.hashCode(); | |
for (Hole o : this.holes) h = 31 * h + (o == null ? 0 : o.hashCode()); | |
for (byte b : this.image) h = 31 * h + b; | |
for (String o : this.tags) h = 31 * h + (o == null ? 0 : o.hashCode()); | |
return h; | |
} | |
@Override | |
public final boolean equals(Object o) { | |
return o instanceof Course && equals((Course) o); | |
} | |
public final boolean equals(Course o) { | |
if (o == null) return false; | |
if (o == this) return true; | |
return o.getClass() == Course.class | |
&& this.ID == o.ID | |
&& (this.name == null ? o.name == null : this.name.equals(o.name)) | |
&& java.util.Arrays.equals(this.holes, o.holes) | |
&& java.util.Arrays.equals(this.image, o.image) | |
&& java.util.Arrays.equals(this.tags, o.tags); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.demo; | |
// Code generated by colf(1); DO NOT EDIT. | |
import static java.lang.String.format; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.ObjectInputStream; | |
import java.io.ObjectOutputStream; | |
import java.io.ObjectStreamException; | |
import java.io.OutputStream; | |
import java.io.Serializable; | |
import java.util.InputMismatchException; | |
import java.nio.BufferOverflowException; | |
import java.nio.BufferUnderflowException; | |
/** | |
* Data bean with built-in serialization support. | |
* @author generated by colf(1) | |
* @see <a href="https://github.com/pascaldekloe/colfer">Colfer's home</a> | |
*/ | |
@javax.annotation.Generated(value="colf(1)", comments="Colfer from schema file demo.colf") | |
public class Hole extends com.example.BeanParent implements Serializable { | |
/** The upper limit for serial byte sizes. */ | |
public static int colferSizeMax = 2 * 1024; | |
/** | |
* Lat is the latitude of the cup. | |
*/ | |
public double lat; | |
/** | |
* Lon is the longitude of the cup. | |
*/ | |
public double lon; | |
/** | |
* Par is the difficulty index. | |
*/ | |
public byte par; | |
/** | |
* Water marks the presence of water. | |
*/ | |
public boolean water; | |
/** | |
* Sand marks the presence of sand. | |
*/ | |
public boolean sand; | |
/** Default constructor */ | |
public Hole() { | |
init(); | |
} | |
/** Colfer zero values. */ | |
private void init() { | |
} | |
/** | |
* {@link #reset(InputStream) Reusable} deserialization of Colfer streams. | |
*/ | |
public static class Unmarshaller { | |
/** The data source. */ | |
protected InputStream in; | |
/** The read buffer. */ | |
public byte[] buf; | |
/** The {@link #buf buffer}'s data start index, inclusive. */ | |
protected int offset; | |
/** The {@link #buf buffer}'s data end index, exclusive. */ | |
protected int i; | |
/** | |
* @param in the data source or {@code null}. | |
* @param buf the initial buffer or {@code null}. | |
*/ | |
public Unmarshaller(InputStream in, byte[] buf) { | |
// TODO: better size estimation | |
if (buf == null || buf.length == 0) | |
buf = new byte[Math.min(Hole.colferSizeMax, 2048)]; | |
this.buf = buf; | |
reset(in); | |
} | |
/** | |
* Reuses the marshaller. | |
* @param in the data source or {@code null}. | |
* @throws IllegalStateException on pending data. | |
*/ | |
public void reset(InputStream in) { | |
if (this.i != this.offset) throw new IllegalStateException("colfer: pending data"); | |
this.in = in; | |
this.offset = 0; | |
this.i = 0; | |
} | |
/** | |
* Deserializes the following object. | |
* @return the result or {@code null} when EOF. | |
* @throws IOException from the input stream. | |
* @throws SecurityException on an upper limit breach defined by {@link #colferSizeMax}. | |
* @throws InputMismatchException when the data does not match this object's schema. | |
*/ | |
public Hole next() throws IOException { | |
if (in == null) return null; | |
while (true) { | |
if (this.i > this.offset) { | |
try { | |
Hole o = new Hole(); | |
this.offset = o.unmarshal(this.buf, this.offset, this.i); | |
return o; | |
} catch (BufferUnderflowException e) { | |
} | |
} | |
// not enough data | |
if (this.i <= this.offset) { | |
this.offset = 0; | |
this.i = 0; | |
} else if (i == buf.length) { | |
byte[] src = this.buf; | |
// TODO: better size estimation | |
if (offset == 0) this.buf = new byte[Math.min(Hole.colferSizeMax, this.buf.length * 4)]; | |
System.arraycopy(src, this.offset, this.buf, 0, this.i - this.offset); | |
this.i -= this.offset; | |
this.offset = 0; | |
} | |
assert this.i < this.buf.length; | |
int n = in.read(buf, i, buf.length - i); | |
if (n < 0) { | |
if (this.i > this.offset) | |
throw new InputMismatchException("colfer: pending data with EOF"); | |
return null; | |
} | |
assert n > 0; | |
i += n; | |
} | |
} | |
} | |
/** | |
* Serializes the object. | |
* @param out the data destination. | |
* @param buf the initial buffer or {@code null}. | |
* @return the final buffer. When the serial fits into {@code buf} then the return is {@code buf}. | |
* Otherwise the return is a new buffer, large enough to hold the whole serial. | |
* @throws IOException from {@code out}. | |
* @throws IllegalStateException on an upper limit breach defined by {@link #colferSizeMax}. | |
*/ | |
public byte[] marshal(OutputStream out, byte[] buf) throws IOException { | |
// TODO: better size estimation | |
if (buf == null || buf.length == 0) | |
buf = new byte[Math.min(Hole.colferSizeMax, 2048)]; | |
while (true) { | |
int i; | |
try { | |
i = marshal(buf, 0); | |
} catch (BufferOverflowException e) { | |
buf = new byte[Math.min(Hole.colferSizeMax, buf.length * 4)]; | |
continue; | |
} | |
out.write(buf, 0, i); | |
return buf; | |
} | |
} | |
/** | |
* Serializes the object. | |
* @param buf the data destination. | |
* @param offset the initial index for {@code buf}, inclusive. | |
* @return the final index for {@code buf}, exclusive. | |
* @throws BufferOverflowException when {@code buf} is too small. | |
* @throws IllegalStateException on an upper limit breach defined by {@link #colferSizeMax}. | |
*/ | |
public int marshal(byte[] buf, int offset) { | |
int i = offset; | |
try { | |
if (this.lat != 0.0) { | |
buf[i++] = (byte) 0; | |
long x = Double.doubleToRawLongBits(this.lat); | |
buf[i++] = (byte) (x >>> 56); | |
buf[i++] = (byte) (x >>> 48); | |
buf[i++] = (byte) (x >>> 40); | |
buf[i++] = (byte) (x >>> 32); | |
buf[i++] = (byte) (x >>> 24); | |
buf[i++] = (byte) (x >>> 16); | |
buf[i++] = (byte) (x >>> 8); | |
buf[i++] = (byte) (x); | |
} | |
if (this.lon != 0.0) { | |
buf[i++] = (byte) 1; | |
long x = Double.doubleToRawLongBits(this.lon); | |
buf[i++] = (byte) (x >>> 56); | |
buf[i++] = (byte) (x >>> 48); | |
buf[i++] = (byte) (x >>> 40); | |
buf[i++] = (byte) (x >>> 32); | |
buf[i++] = (byte) (x >>> 24); | |
buf[i++] = (byte) (x >>> 16); | |
buf[i++] = (byte) (x >>> 8); | |
buf[i++] = (byte) (x); | |
} | |
if (this.par != 0) { | |
buf[i++] = (byte) 2; | |
buf[i++] = this.par; | |
} | |
if (this.water) { | |
buf[i++] = (byte) 3; | |
} | |
if (this.sand) { | |
buf[i++] = (byte) 4; | |
} | |
buf[i++] = (byte) 0x7f; | |
return i; | |
} catch (ArrayIndexOutOfBoundsException e) { | |
if (i - offset > Hole.colferSizeMax) | |
throw new IllegalStateException(format("colfer: com/example/demo.hole exceeds %d bytes", Hole.colferSizeMax)); | |
if (i > buf.length) throw new BufferOverflowException(); | |
throw e; | |
} | |
} | |
/** | |
* Deserializes the object. | |
* @param buf the data source. | |
* @param offset the initial index for {@code buf}, inclusive. | |
* @return the final index for {@code buf}, exclusive. | |
* @throws BufferUnderflowException when {@code buf} is incomplete. (EOF) | |
* @throws SecurityException on an upper limit breach defined by {@link #colferSizeMax}. | |
* @throws InputMismatchException when the data does not match this object's schema. | |
*/ | |
public int unmarshal(byte[] buf, int offset) { | |
return unmarshal(buf, offset, buf.length); | |
} | |
/** | |
* Deserializes the object. | |
* @param buf the data source. | |
* @param offset the initial index for {@code buf}, inclusive. | |
* @param end the index limit for {@code buf}, exclusive. | |
* @return the final index for {@code buf}, exclusive. | |
* @throws BufferUnderflowException when {@code buf} is incomplete. (EOF) | |
* @throws SecurityException on an upper limit breach defined by {@link #colferSizeMax}. | |
* @throws InputMismatchException when the data does not match this object's schema. | |
*/ | |
public int unmarshal(byte[] buf, int offset, int end) { | |
if (end > buf.length) end = buf.length; | |
int i = offset; | |
try { | |
byte header = buf[i++]; | |
if (header == (byte) 0) { | |
long x = (buf[i++] & 0xffL) << 56 | (buf[i++] & 0xffL) << 48 | (buf[i++] & 0xffL) << 40 | (buf[i++] & 0xffL) << 32 | |
| (buf[i++] & 0xffL) << 24 | (buf[i++] & 0xffL) << 16 | (buf[i++] & 0xffL) << 8 | (buf[i++] & 0xffL); | |
this.lat = Double.longBitsToDouble(x); | |
header = buf[i++]; | |
} | |
if (header == (byte) 1) { | |
long x = (buf[i++] & 0xffL) << 56 | (buf[i++] & 0xffL) << 48 | (buf[i++] & 0xffL) << 40 | (buf[i++] & 0xffL) << 32 | |
| (buf[i++] & 0xffL) << 24 | (buf[i++] & 0xffL) << 16 | (buf[i++] & 0xffL) << 8 | (buf[i++] & 0xffL); | |
this.lon = Double.longBitsToDouble(x); | |
header = buf[i++]; | |
} | |
if (header == (byte) 2) { | |
this.par = buf[i++]; | |
header = buf[i++]; | |
} | |
if (header == (byte) 3) { | |
this.water = true; | |
header = buf[i++]; | |
} | |
if (header == (byte) 4) { | |
this.sand = true; | |
header = buf[i++]; | |
} | |
if (header != (byte) 0x7f) | |
throw new InputMismatchException(format("colfer: unknown header at byte %d", i - 1)); | |
} finally { | |
if (i > end && end - offset < Hole.colferSizeMax) throw new BufferUnderflowException(); | |
if (i < 0 || i - offset > Hole.colferSizeMax) | |
throw new SecurityException(format("colfer: com/example/demo.hole exceeds %d bytes", Hole.colferSizeMax)); | |
if (i > end) throw new BufferUnderflowException(); | |
} | |
return i; | |
} | |
// {@link Serializable} version number. | |
private static final long serialVersionUID = 5L; | |
// {@link Serializable} Colfer extension. | |
private void writeObject(ObjectOutputStream out) throws IOException { | |
// TODO: better size estimation | |
byte[] buf = new byte[1024]; | |
int n; | |
while (true) try { | |
n = marshal(buf, 0); | |
break; | |
} catch (BufferUnderflowException e) { | |
buf = new byte[4 * buf.length]; | |
} | |
out.writeInt(n); | |
out.write(buf, 0, n); | |
} | |
// {@link Serializable} Colfer extension. | |
private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException { | |
init(); | |
int n = in.readInt(); | |
byte[] buf = new byte[n]; | |
in.readFully(buf); | |
unmarshal(buf, 0); | |
} | |
// {@link Serializable} Colfer extension. | |
private void readObjectNoData() throws ObjectStreamException { | |
init(); | |
} | |
/** | |
* Gets com/example/demo.hole.lat. | |
* @return the value. | |
*/ | |
public double getLat() { | |
return this.lat; | |
} | |
/** | |
* Sets com/example/demo.hole.lat. | |
* @param value the replacement. | |
*/ | |
public void setLat(double value) { | |
this.lat = value; | |
} | |
/** | |
* Gets com/example/demo.hole.lon. | |
* @return the value. | |
*/ | |
public double getLon() { | |
return this.lon; | |
} | |
/** | |
* Sets com/example/demo.hole.lon. | |
* @param value the replacement. | |
*/ | |
public void setLon(double value) { | |
this.lon = value; | |
} | |
/** | |
* Gets com/example/demo.hole.par. | |
* @return the value. | |
*/ | |
public byte getPar() { | |
return this.par; | |
} | |
/** | |
* Sets com/example/demo.hole.par. | |
* @param value the replacement. | |
*/ | |
public void setPar(byte value) { | |
this.par = value; | |
} | |
/** | |
* Gets com/example/demo.hole.water. | |
* @return the value. | |
*/ | |
public boolean getWater() { | |
return this.water; | |
} | |
/** | |
* Sets com/example/demo.hole.water. | |
* @param value the replacement. | |
*/ | |
public void setWater(boolean value) { | |
this.water = value; | |
} | |
/** | |
* Gets com/example/demo.hole.sand. | |
* @return the value. | |
*/ | |
public boolean getSand() { | |
return this.sand; | |
} | |
/** | |
* Sets com/example/demo.hole.sand. | |
* @param value the replacement. | |
*/ | |
public void setSand(boolean value) { | |
this.sand = value; | |
} | |
@Override | |
public final int hashCode() { | |
int h = 1; | |
long _latBits = Double.doubleToLongBits(this.lat); | |
h = 31 * h + (int) (_latBits ^ _latBits >>> 32); | |
long _lonBits = Double.doubleToLongBits(this.lon); | |
h = 31 * h + (int) (_lonBits ^ _lonBits >>> 32); | |
h = 31 * h + (this.par & 0xff); | |
h = 31 * h + (this.water ? 1231 : 1237); | |
h = 31 * h + (this.sand ? 1231 : 1237); | |
return h; | |
} | |
@Override | |
public final boolean equals(Object o) { | |
return o instanceof Hole && equals((Hole) o); | |
} | |
public final boolean equals(Hole o) { | |
if (o == null) return false; | |
if (o == this) return true; | |
return o.getClass() == Hole.class | |
&& (this.lat == o.lat || (this.lat != this.lat && o.lat != o.lat)) | |
&& (this.lon == o.lon || (this.lon != this.lon && o.lon != o.lon)) | |
&& this.par == o.par | |
&& this.water == o.water | |
&& this.sand == o.sand; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Code generated by colf(1); DO NOT EDIT. | |
// The compiler used schema file demo.colf. | |
/** | |
* Package demo offers a demonstration. | |
* These comment lines will end up in the generated code. | |
*/ | |
package com.example.demo; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment