public ResponseDecoder(TsTtbResp response) { using (var s = new OtpInputStream(response.Response)) { byte tag = s.Read1(); if (tag != OtpExternal.VersionTag) { string msg = string.Format( "Expected OTP input stream to start with {0}, got {1}", OtpExternal.VersionTag, tag); throw new InvalidOperationException(msg); } tag = s.Peek(); switch (tag) { case OtpExternal.AtomTag: string atom = s.ReadAtom(); decodedResponse = ParseAtomResult(atom); break; case OtpExternal.SmallTupleTag: case OtpExternal.LargeTupleTag: decodedResponse = ParseTupleResult(s); break; default: throw new InvalidOperationException("Expected an atom or tuple."); } } }
/* * Create an Erlang port from a stream containing a port encoded in * Erlang external format. * * @param buf the stream containing the encoded port. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang port. **/ public Port(OtpInputStream buf) { Port p = buf.read_port(); this._node = p.node(); this._id = p.id(); this._creation = p.creation(); }
/* * Create an Erlang PID from a stream containing a PID encoded in * Erlang external format. * * @param buf the stream containing the encoded PID. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang PID. **/ public Pid(OtpInputStream buf) { Pid p = buf.read_pid(); this._node = p.node(); this._id = p.id(); this._serial = p.serial(); this._creation = p.creation(); }
/* * Create an Erlang ref from a stream containing a ref encoded in * Erlang external format. * * @param buf the stream containing the encoded ref. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang ref. **/ public Ref(OtpInputStream buf) { Ref r = buf.read_ref(); this._node = r.node(); this._creation = r.creation(); this._ids = r.ids(); }
public void Read_Long(byte[] buf, long want) { long got = 0; using (var s = new OtpInputStream(buf)) { got = s.ReadLong(); } Assert.AreEqual(want, got); }
public void Can_Peek(byte[] buf, bool want) { using (var s = new OtpInputStream(buf)) { byte b = s.Read1(); Assert.AreEqual(OtpExternal.VersionTag, b); b = s.Peek(); Assert.AreEqual(OtpExternal.AtomTag, b); string atom = s.ReadAtom(); Assert.AreEqual(want.ToString().ToLowerInvariant(), atom); } }
public void Read_Zero_Throws_At_End() { byte[] inbuf = { 0, 1, 2, 3 }; byte[] outbuf = new byte[1]; using (var s = new OtpInputStream(inbuf)) { s.ReadN(outbuf); s.ReadN(outbuf); s.ReadN(outbuf); s.ReadN(outbuf); Assert.Throws(typeof(Exception), () => s.ReadN(outbuf, 0, 0)); } }
/* * Create a tuple from a stream containing an tuple encoded in Erlang * external format. * * @param buf the stream containing the encoded tuple. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang tuple. **/ public Tuple(OtpInputStream buf) { int arity = buf.read_tuple_head(); if (arity > 0) { this.elems = new Object[arity]; for (int i = 0; i < arity; i++) { elems[i] = buf.read_any(); } } }
public void Read_Binary(string want) { byte[] buf = null; using (var os = new OtpOutputStream()) { os.WriteStringAsBinary(want); buf = os.ToArray(); } using (var s = new OtpInputStream(buf)) { string got = s.ReadBinaryAsString(); Assert.AreEqual(want, got); } }
private static Row[] ParseRows(OtpInputStream s, Column[] cols) { int rowCount = s.ReadListHead(); Row[] rows = new Row[rowCount]; for (int i = 0; i < rowCount; i++) { rows[i] = ParseRow(s, cols); } if (rowCount > 0) { s.ReadNil(); } return(rows); }
/* * Create a list from a stream containing an list encoded in Erlang * external format. * * @param buf the stream containing the encoded list. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang list. **/ public List(OtpInputStream buf) { this.elems = null; int arity = buf.read_list_head(); if (arity > 0) { this.elems = new Object[arity]; for (int i = 0; i < arity; i++) { elems[i] = buf.read_any(); } /*discard the terminating nil (empty list) */ buf.read_nil(); } }
private static Row ParseRow(OtpInputStream s, Column[] cols) { int cellCount = s.ReadTupleHead(); if (cellCount != cols.Length) { string msg = string.Format( "Expected cell count {0} to equal column count {1}", cellCount, cols.Length); throw new InvalidOperationException(msg); } Cell[] cells = new Cell[cellCount]; for (int i = 0; i < cellCount; i++) { cells[i] = ParseCell(s, i, cols); } return(new Row(cells)); }
public override void OnSuccess(RiakResp response) { if (usingTtb) { var ttbresp = (TsTtbResp)response; using (var s = new OtpInputStream(ttbresp.Response)) { s.ReadTupleHead(); string atom = s.ReadAtom(); if (atom.Equals(TsPutRespAtom) == false) { throw new InvalidDataException( string.Format("Expected {0}, got {1}", TsPutRespAtom, atom)); } } } else { Response = new StoreResponse(); } }
private static DecodedResponse ParseTupleResult(OtpInputStream s) { // Response is: // {'tsgetresp', {ColNames, ColTypes, Rows}} // {'tsqueryresp', {ColNames, ColTypes, Rows}} int arity = s.ReadTupleHead(); if (arity != 2) { throw new InvalidOperationException("Expected response to be a 2-tuple"); } string msg; string atom = s.ReadAtom(); switch (atom) { case TsGetRespAtom: case TsQueryRespAtom: arity = s.ReadTupleHead(); if (arity != 3) { msg = string.Format( "Second item in {0} response tuple must be a 3-tuple.", atom); throw new InvalidOperationException(msg); } Column[] cols = ParseColumns(s); Row[] rows = ParseRows(s, cols); return(new DecodedResponse(cols, rows)); default: msg = string.Format( "Expected tsgetresp or tsqueryresp atom, got {0}", atom); throw new InvalidOperationException(msg); } }
/* * Create a boolean from a stream containing an atom encoded in * Erlang external format. The value of the boolean will be true if * the atom represented by the stream is "true" without regard to * case. For other atom values, the boolean will have the value * false. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang atom. **/ public Boolean(OtpInputStream buf) { this.value = buf.read_boolean(); }
private static Column[] ParseColumns(OtpInputStream s) { int colNameCount = s.ReadListHead(); string[] columnNames = new string[colNameCount]; for (int i = 0; i < colNameCount; i++) { columnNames[i] = s.ReadBinaryAsString(); } if (colNameCount > 0) { s.ReadNil(); } int colTypeCount = s.ReadListHead(); ColumnType[] columnTypes = new ColumnType[colTypeCount]; for (int i = 0; i < colTypeCount; i++) { string a = s.ReadAtom(); columnTypes[i] = (ColumnType)Enum.Parse(typeof(ColumnType), a, true); } if (colTypeCount > 0) { s.ReadNil(); } return columnNames.Zip(columnTypes, (cname, ctype) => new Column(cname, ctype)).ToArray(); }
/* * Create an atom from a stream containing an atom encoded in Erlang * external format. * * @param buf the stream containing the encoded atom. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang atom. **/ public Atom(OtpInputStream buf) { this.atom = buf.read_atom(); }
/* * Create an Erlang integer from a stream containing an integer * encoded in Erlang external format. * * @param buf the stream containing the encoded value. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang integer. **/ public Long(OtpInputStream buf) { val = buf.read_long(); }
private static DecodedResponse ParseTupleResult(OtpInputStream s) { // Response is: // {'tsgetresp', {ColNames, ColTypes, Rows}} // {'tsqueryresp', {ColNames, ColTypes, Rows}} int arity = s.ReadTupleHead(); if (arity != 2) { throw new InvalidOperationException("Expected response to be a 2-tuple"); } string msg; string atom = s.ReadAtom(); switch (atom) { case TsGetRespAtom: case TsQueryRespAtom: arity = s.ReadTupleHead(); if (arity != 3) { msg = string.Format( "Second item in {0} response tuple must be a 3-tuple.", atom); throw new InvalidOperationException(msg); } Column[] cols = ParseColumns(s); Row[] rows = ParseRows(s, cols); return new DecodedResponse(cols, rows); default: msg = string.Format( "Expected tsgetresp or tsqueryresp atom, got {0}", atom); throw new InvalidOperationException(msg); } }
private static Row[] ParseRows(OtpInputStream s, Column[] cols) { int rowCount = s.ReadListHead(); Row[] rows = new Row[rowCount]; for (int i = 0; i < rowCount; i++) { rows[i] = ParseRow(s, cols); } if (rowCount > 0) { s.ReadNil(); } return rows; }
/* * Create an Erlang string from a stream containing a string encoded in * Erlang external format. * * @param buf the stream containing the encoded string. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang string. **/ public String(OtpInputStream buf) { str = buf.read_string(); }
/* * Create an Erlang integer from a stream containing an integer * encoded in Erlang external format. * * @param buf the stream containing the encoded value. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang integer. * * @exception RangeException if the value is too large to * be represented as a byte. **/ public Byte(OtpInputStream buf) : base(buf) { sbyte i = byteValue(); }
private static Row ParseRow(OtpInputStream s, Column[] cols) { int cellCount = s.ReadTupleHead(); if (cellCount != cols.Length) { string msg = string.Format( "Expected cell count {0} to equal column count {1}", cellCount, cols.Length); throw new InvalidOperationException(msg); } Cell[] cells = new Cell[cellCount]; for (int i = 0; i < cellCount; i++) { cells[i] = ParseCell(s, i, cols); } return new Row(cells); }
/* * Read binary data in the Erlang external format, and produce a * corresponding Erlang data type object. This method is normally * used when Erlang terms are received in messages, however it * can also be used for reading terms from disk. * * @param buf an input stream containing one or more encoded Erlang * terms. * * @return an object representing one of the Erlang data * types. * * @exception DecodeException if the stream does not * contain a valid representation of an Erlang term. **/ public static Object decode(OtpInputStream buf) { return(buf.read_any()); }
private static Cell ParseCell(OtpInputStream s, int i, Column[] cols) { string msg; Column col = cols[i]; byte tag = s.Peek(); switch (tag) { case OtpExternal.NilTag: tag = s.Read1(); // NB: actually consume the byte return(new Cell()); case OtpExternal.BinTag: if (col.Type == ColumnType.Varchar || col.Type == ColumnType.Blob) { return(new Cell(s.ReadBinaryAsString())); } else { throw OnBadTag(tag, col, ColumnType.Varchar, ColumnType.Blob); } case OtpExternal.SmallIntTag: case OtpExternal.IntTag: case OtpExternal.SmallBigTag: case OtpExternal.LargeBigTag: long val = s.ReadLong(); switch (col.Type) { case ColumnType.SInt64: return(new Cell(val, isUnixTimestamp: false)); case ColumnType.Timestamp: return(new Cell(val, isUnixTimestamp: true)); default: throw OnBadTag(tag, col, ColumnType.SInt64, ColumnType.Timestamp); } case OtpExternal.FloatTag: case OtpExternal.NewFloatTag: if (col.Type != ColumnType.Double) { throw OnBadTag(tag, col, ColumnType.Double); } return(new Cell(s.ReadDouble())); case OtpExternal.AtomTag: if (col.Type != ColumnType.Boolean) { throw OnBadTag(tag, col, ColumnType.Boolean); } return(new Cell(s.ReadBoolean())); case OtpExternal.ListTag: int arity = s.ReadNil(); if (arity == 0) { // null cell return(new Cell()); } else { msg = string.Format( "Expected nil list, got one with arity {0}", arity); throw new InvalidOperationException(msg); } default: msg = string.Format( "Unknown cell type encountered, tag {0}, '{1}:{2}'", tag, col.Name, col.Type); throw new InvalidOperationException(msg); } }
private static Cell ParseCell(OtpInputStream s, int i, Column[] cols) { string msg; Column col = cols[i]; byte tag = s.Peek(); switch (tag) { case OtpExternal.NilTag: tag = s.Read1(); // NB: actually consume the byte return new Cell(); case OtpExternal.BinTag: if (col.Type == ColumnType.Varchar || col.Type == ColumnType.Blob) { return new Cell(s.ReadBinaryAsString()); } else { throw OnBadTag(tag, col, ColumnType.Varchar, ColumnType.Blob); } case OtpExternal.SmallIntTag: case OtpExternal.IntTag: case OtpExternal.SmallBigTag: case OtpExternal.LargeBigTag: long val = s.ReadLong(); switch (col.Type) { case ColumnType.SInt64: return new Cell(val, isUnixTimestamp: false); case ColumnType.Timestamp: return new Cell(val, isUnixTimestamp: true); default: throw OnBadTag(tag, col, ColumnType.SInt64, ColumnType.Timestamp); } case OtpExternal.FloatTag: case OtpExternal.NewFloatTag: if (col.Type != ColumnType.Double) { throw OnBadTag(tag, col, ColumnType.Double); } return new Cell(s.ReadDouble()); case OtpExternal.AtomTag: if (col.Type != ColumnType.Boolean) { throw OnBadTag(tag, col, ColumnType.Boolean); } return new Cell(s.ReadBoolean()); case OtpExternal.ListTag: int arity = s.ReadNil(); if (arity == 0) { // null cell return new Cell(); } else { msg = string.Format( "Expected nil list, got one with arity {0}", arity); throw new InvalidOperationException(msg); } default: msg = string.Format( "Unknown cell type encountered, tag {0}, '{1}:{2}'", tag, col.Name, col.Type); throw new InvalidOperationException(msg); } }
/* * Create an Erlang float from a stream containing a double encoded * in Erlang external format. * * @param buf the stream containing the encoded value. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang float. **/ public Double(OtpInputStream buf) { this.d = buf.read_double(); //System.Diagnostics.Debug.WriteLine("Double: " + this.d ); }
/* * Read binary data in the Erlang external format, and produce a * corresponding Erlang data type object. This method is normally * used when Erlang terms are received in messages, however it * can also be used for reading terms from disk. * * @param buf an input stream containing one or more encoded Erlang * terms. * * @return an object representing one of the Erlang data * types. * * @exception DecodeException if the stream does not * contain a valid representation of an Erlang term. **/ public static Object decode(OtpInputStream buf) { return buf.read_any(); }
/* * Create a boolean from a stream containing an atom encoded in * Erlang external format. The value of the boolean will be true if * the atom represented by the stream is "true" without regard to * case. For other atom values, the boolean will have the value * false. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang atom. **/ public Boolean(OtpInputStream buf) : base(buf) { }
/* * Create an Erlang integer from a stream containing an integer * encoded in Erlang external format. * * @param buf the stream containing the encoded value. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang integer. * * @exception RangeException if the value is too large to * be represented as an int. **/ public Int(OtpInputStream buf) : base(buf) { int j = intValue(); }
/* * Create an Erlang integer from a stream containing an integer * encoded in Erlang external format. * * @param buf the stream containing the encoded value. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang integer. * * @exception RangeException if the value is too large to * be represented as a char. **/ public Char(OtpInputStream buf) : base(buf) { char i = charValue(); }
/* * Create an Erlang integer from a stream containing an integer * encoded in Erlang external format. * * @param buf the stream containing the encoded value. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang integer. * * @exception RangeException if the value is too large to * be represented as a char. **/ public Char(OtpInputStream buf):base(buf) { char i = charValue(); }
/* * Create an Erlang integer from a stream containing an integer * encoded in Erlang external format. * * @param buf the stream containing the encoded value. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang integer. * * @exception RangeException if the value is too large to * be represented as a short. **/ public Short(OtpInputStream buf) : base(buf) { short j = shortValue(); }
/* * Create an Erlang integer from a stream containing an integer * encoded in Erlang external format. * * @param buf the stream containing the encoded value. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang integer. * * @exception RangeException if the value is too large to * be represented as a short, or the value is negative. **/ public UShort(OtpInputStream buf):base(buf) { short j = uShortValue(); }
/* * Create a binary from a stream containinf a binary encoded in * Erlang external format. * * @param buf the stream containing the encoded binary. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang binary. **/ public Binary(OtpInputStream buf) { this.bin = buf.read_binary(); }
/* * Create an Erlang integer from a stream containing an integer encoded * in Erlang external format. * * @param buf the stream containing the encoded value. * * @exception DecodeException if the buffer does not * contain a valid external representation of an Erlang integer. * * @exception RangeException if the value is too large to * be represented as an int, or the value is negative. **/ public UInt(OtpInputStream buf):base(buf) { int j = uIntValue(); }
// send has receiver pid but no sender information internal OtpMsg(OtpErlangPid to, OtpInputStream paybuf) { Type = sendTag; ToPid = to; Stream = paybuf; }