//this requires a seekable stream for now public void Write(Type type, Array val) { Type elemType = type.GetElementType(); //TODO: more fast paths for primitive arrays if (elemType == typeof(byte)) { Write((uint)val.Length); stream.Write((byte[])val, 0, val.Length); return; } Write((uint)0); long lengthPos = stream.Position - 4; //advance to the alignment of the element WritePad(Protocol.GetAlignment(Signature.TypeToDType(elemType))); long startPos = stream.Position; foreach (object elem in val) { Write(elemType, elem); } long endPos = stream.Position; stream.Position = lengthPos; Write((uint)(endPos - startPos)); stream.Position = endPos; }
//this requires a seekable stream for now public void WriteArray(object obj, Type elemType) { Array val = (Array)obj; //TODO: more fast paths for primitive arrays if (elemType == typeof(byte)) { if (val.Length > Protocol.MaxArrayLength) { throw new Exception("Array length " + val.Length + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes"); } Write((uint)val.Length); stream.Write((byte[])val, 0, val.Length); return; } long origPos = stream.Position; Write((uint)0); //advance to the alignment of the element WritePad(Protocol.GetAlignment(Signature.TypeToDType(elemType))); long startPos = stream.Position; foreach (object elem in val) { Write(elemType, elem); } long endPos = stream.Position; uint ln = (uint)(endPos - startPos); stream.Position = origPos; if (ln > Protocol.MaxArrayLength) { throw new Exception("Array length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes"); } Write(ln); stream.Position = endPos; }
//this could be made generic to avoid boxing public void GetValue(Type type, out Array val) { Type elemType = type.GetElementType(); uint ln; GetValue(out ln); //TODO: more fast paths for primitive arrays if (elemType == typeof(byte)) { byte[] valb = new byte[ln]; Array.Copy(data, pos, valb, 0, (int)ln); val = valb; pos += (int)ln; return; } //advance to the alignment of the element ReadPad(Protocol.GetAlignment(Signature.TypeToDType(elemType))); int endPos = pos + (int)ln; //List<T> vals = new List<T> (); System.Collections.ArrayList vals = new System.Collections.ArrayList(); //while (stream.Position != endPos) while (pos < endPos) { object elem; //GetValue (Signature.TypeToDType (elemType), out elem); GetValue(elemType, out elem); vals.Add(elem); } if (pos != endPos) { throw new Exception("Read pos " + pos + " != ep " + endPos); } val = vals.ToArray(elemType); //val = Array.CreateInstance (elemType.UnderlyingSystemType, vals.Count); }
//this could be made generic to avoid boxing public Array ReadArray(Type elemType) { uint ln = ReadUInt32(); if (ln > Protocol.MaxArrayLength) { throw new Exception("Array length " + ln + " exceeds maximum allowed " + Protocol.MaxArrayLength + " bytes"); } //TODO: more fast paths for primitive arrays if (elemType == typeof(byte)) { byte[] valb = new byte[ln]; Array.Copy(data, pos, valb, 0, (int)ln); pos += (int)ln; return(valb); } //advance to the alignment of the element ReadPad(Protocol.GetAlignment(Signature.TypeToDType(elemType))); int endPos = pos + (int)ln; //List<T> vals = new List<T> (); System.Collections.ArrayList vals = new System.Collections.ArrayList(); //while (stream.Position != endPos) while (pos < endPos) { vals.Add(ReadValue(elemType)); } if (pos != endPos) { throw new Exception("Read pos " + pos + " != ep " + endPos); } return(vals.ToArray(elemType)); }