|
using System;
using System.IO;
using System.Text;
namespace Ranslant.JSON.Linq
{
public class JDocument : JObject
{
public JDocument()
{ }
/// <summary>
/// Creates a new JDocument instance and copies the data from jObject
/// </summary>
/// <param name="jObject">source of the data. The data is copied.</param>
public JDocument(JObject jObject)
{
foreach (JObjectMember jom in jObject.GetMembers())
Add(jom);
}
/// <summary>
/// Creates a new JDocument instance and fills it with the jObjectMembers
/// </summary>
/// <param name="jObjectMembers">a comma separated list of JObjectMember</param>
public JDocument(params JObjectMember[] jObjectMembers): base(jObjectMembers)
{
}
/// <summary>
/// Loads JSON data from a file. An exception is thrown if something goes wrong. The file has to contain nothing but JSON data.
/// </summary>
/// <param name="uri">URI (path) to the file. Must contain only JSON Data</param>
/// <param name="encoding">specific encoding (default is UFT8Encoding)</param>
/// <returns></returns>
public static JDocument Load(string uri, Encoding encoding)
{
if (uri.Length == 0)
throw new Exception("Load: empty file name");
using (FileStream stream = new FileStream(uri, FileMode.Open))
{
JDocument doc = Load(stream, encoding);
stream.Close();
return doc;
}
}
/// <summary>
/// Loads JSON data from a file. An exception is thrown if something goes wrong. The file has to contain nothing but JSON data.
/// The encoding is UTF8Encoding.
/// </summary>
/// <param name="uri">URI (path) to the file. Must contain only JSON Data</param>
/// <returns></returns>
public static JDocument Load(string uri)
{
return Load(uri, new UTF8Encoding());
}
/// <summary>
/// Loads JSON data from a stream. An exception is thrown if something goes wrong. The stream has to contain nothing but JSON data from its current position to its end.
/// </summary>
/// <param name="stream">stream from where to read. The stream object is allowed to not support stream.Length</param>
/// <param name="encoding">specific encoding (default is UTF8Encoding). If you provide 'null' as parameter for the encoding, then Load will try to detect the encoding type based on the ByteOrderMark (currently detected: UTF16(BE and LE), UTF8 and ASCII)</param>
/// <returns></returns>
public static JDocument Load(Stream stream, Encoding encoding)
{
if(stream == null)
throw new ArgumentNullException("stream");
if(!stream.CanRead)
throw new Exception("stream is not readable");
byte[] bytes;
try
{
int length = (int)stream.Length;
bytes = new byte[length];
int read = stream.Read(bytes, 0, length);
if(read != length)
throw new IOException("stream could not be fully read");
}
catch (NotSupportedException)
{
// it may happen that the Stream derived type does not support stream.Length
// in this case we have to read the stream almost byte by byte
const int sizeOfBuffer = 1024;
byte[] buffer = new byte[sizeOfBuffer]; // let's read the stream 1k at a time
int offset = 0;
int readBytes = stream.Read(buffer, offset, sizeOfBuffer);
int totalRead = readBytes;
bytes = new byte[readBytes];
while (readBytes > 0)
{
buffer.CopyTo(bytes, offset);
offset += readBytes;
readBytes = stream.Read(buffer, offset, sizeOfBuffer);
totalRead += readBytes;
if (readBytes > 0)
Array.Resize(ref bytes, totalRead);
}
}
// Load tries to detect the encoding with the BOM
if (encoding == null)
{
encoding = Utilities.TryDetectEncoding(bytes);
}
string text = encoding.GetString(bytes);
return JDocument.Parse(text);
}
/// <summary>
/// Loads JSON data from a stream. An exception is thrown if something goes wrong. The stream has to contain nothing but JSON data from its current position to its end.
/// The encoding is UTF8Encoding.
/// </summary>
/// <param name="stream">stream from where to read</param>
/// <returns></returns>
public static JDocument Load(Stream stream)
{
return Load(stream, new UTF8Encoding());
}
/// <summary>
/// Parses the given text. Only JSON data is expected.
/// An exception is thrown if something goes wrong, for instance if the JSON data is not properly formatted
/// </summary>
/// <param name="text">raw text of the whole JSON data</param>
/// <returns></returns>
public static JDocument Parse(string text)
{
if (text.Length == 0)
throw new Exception("Parse: data is empty");
// When .NET Framework encodes from UTF to UTF (no matter which one), then it adds a ByteOrderMark
// UTF16: http://en.wikipedia.org/wiki/UTF-16#Byte_order_encoding_schemes
// since C# encodes strings as UTF 16 LE, we may need to remove the BOM
if (text[0] == 0xFEFF)
{
text = text.Remove(0, 1);
if (text.Length == 0)
throw new Exception("Parse: data is empty");
}
JParser parser = new JParser();
JDocument jDoc = parser.ParseDocument(text);
return jDoc;
}
/// <summary>
/// Write the JDocument as JObject to the stream. The stream is not closed.
/// An exception is thrown if something goes wrong. Encoding is UTF8Encoding.
/// </summary>
/// <param name="stream">stream where to write</param>
public void Save(Stream stream)
{
Save(stream, new UTF8Encoding(), true);
}
/// <summary>
/// Write the JDocument as JObject to the stream. The stream is not closed.
/// An exception is thrown if something goes wrong.
/// </summary>
/// <param name="stream">stream where to write</param>
/// <param name="encoding">specific encoding (default is UTF8Encoding)</param>
/// <param name="addByteOrderMark">whether or not the Byte Order Mark has to be added to the file</param>
public void Save(Stream stream, Encoding encoding, bool addByteOrderMark)
{
if (stream == null)
throw new ArgumentNullException("stream");
if(encoding == null)
throw new ArgumentNullException("encoding");
if(!stream.CanWrite)
throw new IOException("stream is not writable");
byte[] bytes = encoding.GetBytes(this.ToString(1));
if (addByteOrderMark)
{
if (encoding is UTF8Encoding || encoding is UnicodeEncoding)
{
byte[] byteOrderMark = encoding.GetPreamble();
stream.Write(byteOrderMark, 0, byteOrderMark.Length);
}
}
stream.Write(bytes, 0, bytes.Length);
// the stream is left open, it is not this method's job to close it.
}
/// <summary>
/// Saves the JSON data to a file. Encoding is UTF8Encoding.
/// </summary>
/// <param name="uri">URI (path) of the file. If it already exists, it will be overwritten</param>
public void Save(string uri)
{
Save(uri, new UTF8Encoding(), true);
}
/// <summary>
/// Saves the JSON data to a file.
/// </summary>
/// <param name="uri">URI (path) of the file. If it already exists, it will be overwritten</param>
/// <param name="encoding">specific encoding (default is UTF8Encoding)</param>
/// <param name="addByteOrderMark">whether or not the Byte Order Mark has to be added to the file</param>
public void Save(string uri, Encoding encoding, bool addByteOrderMark)
{
using (FileStream writer = new FileStream(uri, FileMode.Create))
{
this.Save(writer, encoding, addByteOrderMark);
writer.Close();
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.