#region Copyright 2011-2014 by Roger Knapp, Licensed under the Apache License, Version 2.0
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#endregion
using System;
using System.IO;
namespace CSharpTest.Net.Serialization
{
///
/// Reads the same variant prefixed string and byte[] but with a hard-limit on size
///
public class LimitedSerializer : ISerializer, ISerializer
{
private readonly int _maxLength;
///
/// Constructs a limited length-prefix data reader/writer
///
public LimitedSerializer(int maxLength)
{
_maxLength = maxLength;
}
/// Reads up to 1024 length-prefixed byte array
public static readonly ISerializer Bytes1024 = new LimitedSerializer(1024);
/// Reads up to 2048 length-prefixed byte array
public static readonly ISerializer Bytes2048 = new LimitedSerializer(2048);
/// Reads up to 4092 length-prefixed byte array
public static readonly ISerializer Bytes4092 = new LimitedSerializer(4092);
/// Reads up to 8196 length-prefixed byte array
public static readonly ISerializer Bytes8196 = new LimitedSerializer(8196);
/// Reads up to 256 length-prefixed string
public static readonly ISerializer String256 = new LimitedSerializer(256);
/// Reads up to 512 length-prefixed string
public static readonly ISerializer String512 = new LimitedSerializer(512);
/// Reads up to 1024 length-prefixed string
public static readonly ISerializer String1024 = new LimitedSerializer(1024);
/// This is the only class with read/write prefixed data
internal static readonly LimitedSerializer Unlimited = new LimitedSerializer(int.MaxValue);
#region ISerializer Members
void ISerializer.WriteTo(string value, Stream stream)
{
if (value == null)
{
VariantNumberSerializer.Int32.WriteTo(int.MinValue, stream);
}
else
{
Check.Assert(value.Length <= _maxLength);
VariantNumberSerializer.Int32.WriteTo(value.Length, stream);
foreach (char ch in value)
VariantNumberSerializer.Int32.WriteTo(ch, stream);
}
}
string ISerializer.ReadFrom(Stream stream)
{
unchecked
{
int sz = VariantNumberSerializer.Int32.ReadFrom(stream);
if (sz == 0) return string.Empty;
if (sz == int.MinValue)
return null;
Check.Assert(sz >= 0 && sz <= _maxLength);
char[] chars = new char[sz];
for (int i = 0; i < sz; i++)
chars[i] = (char)VariantNumberSerializer.Int32.ReadFrom(stream);
return new String(chars);
}
}
#endregion
#region ISerializer Members
void ISerializer.WriteTo(byte[] value, Stream stream)
{
if (value == null)
{
VariantNumberSerializer.Int32.WriteTo(int.MinValue, stream);
}
else
{
Check.Assert(value.Length <= _maxLength);
VariantNumberSerializer.Int32.WriteTo(value.Length, stream);
foreach (byte b in value)
stream.WriteByte(b);
}
}
byte[] ISerializer.ReadFrom(Stream stream)
{
int sz = VariantNumberSerializer.Int32.ReadFrom(stream);
if (sz == int.MinValue)
return null;
Check.Assert(sz >= 0 && sz <= _maxLength);
byte[] bytes = new byte[sz];
int pos = 0, len;
while (0 != (len = stream.Read(bytes, pos, sz - pos)))
pos += len;
Check.Assert(pos == sz);
return bytes;
}
#endregion
}
}