215 lines
5.0 KiB
C#
215 lines
5.0 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class JSONStringConverter
|
|
{
|
|
static bool ContainsBackslash( string dataFromFile, int start, int length )
|
|
{
|
|
var end = start + length;
|
|
for ( var i = start; i < end; i++ )
|
|
{
|
|
if ( dataFromFile[ i ] == '\\' ) { return true; }
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static string Read( string dataFromFile )
|
|
{
|
|
var output = new StringBuilder();
|
|
Read( output, dataFromFile, 0, dataFromFile.Length );
|
|
return output.ToString();
|
|
}
|
|
|
|
public static void Read( StringBuilder output, string dataFromFile, int start, int length )
|
|
{
|
|
ReadWithoutQuotes( output, dataFromFile, start + 1, length - 2 );
|
|
}
|
|
|
|
public static void Read( StringBuilder output, string dataFromFile )
|
|
{
|
|
Read( output, dataFromFile, 0, dataFromFile.Length );
|
|
}
|
|
|
|
public static void ReadWithoutQuotes( StringBuilder output, string dataFromFile, int start, int length )
|
|
{
|
|
if ( ! JSONStringConverter.ContainsBackslash( dataFromFile, start, length ) )
|
|
{
|
|
output.Append( dataFromFile.Substring( start, length ) );
|
|
return;
|
|
}
|
|
|
|
|
|
var end = start + length;
|
|
|
|
for ( var i = start ; i < end; i++ )
|
|
{
|
|
var rawCharacter = dataFromFile[ i ];
|
|
|
|
if ( rawCharacter == '\\' )
|
|
{
|
|
if ( i == end - 1 ) { return; }
|
|
|
|
var nextRawCharacter = dataFromFile[ i + 1 ];
|
|
|
|
if ( nextRawCharacter == 'u' )
|
|
{
|
|
var hexStringStart = i + 2;
|
|
var hexString = dataFromFile.Substring( hexStringStart, 4 );
|
|
var unicodeValue = ReadUnicodeFromHexString( hexString );
|
|
|
|
output.Append( unicodeValue );
|
|
|
|
i += 5;
|
|
}
|
|
else
|
|
{
|
|
var escapedCharacter = ReadSingleEscaped( nextRawCharacter );
|
|
output.Append( escapedCharacter );
|
|
|
|
i ++;
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
output.Append( rawCharacter );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
static char ReadSingleEscaped( char character )
|
|
{
|
|
switch ( character )
|
|
{
|
|
case 'b': return '\b';
|
|
case 'f': return '\f';
|
|
case 'n': return '\n';
|
|
case 'r': return '\r';
|
|
case 't': return '\t';
|
|
|
|
default: return character;
|
|
}
|
|
}
|
|
|
|
static char ReadUnicodeFromHexString( string hexString )
|
|
{
|
|
return (char) int.Parse( hexString, System.Globalization.NumberStyles.HexNumber );
|
|
}
|
|
|
|
static readonly char[] ESCAPE_CHARACTERS = new char[]
|
|
{
|
|
'\"', '\\', '/', '\b', '\f', '\n', '\r', '\t'
|
|
};
|
|
|
|
static readonly string[] ESCAPING_SEQUENCES = new string[]
|
|
{
|
|
"\\\"", "\\\\", "\\/", "\\b", "\\f", "\\n", "\\r", "\\t"
|
|
};
|
|
|
|
public static string Write( string dataFromMemory )
|
|
{
|
|
var output = new StringBuilder();
|
|
Write( output, dataFromMemory, 0, dataFromMemory.Length );
|
|
return output.ToString();
|
|
}
|
|
|
|
public static void Write( StringBuilder output, string dataFromMemory, int start, int length )
|
|
{
|
|
output.Append( "\"" );
|
|
WriteWithoutQuotes( output, dataFromMemory, start, length );
|
|
output.Append( "\"" );
|
|
}
|
|
|
|
public static void Write( StringBuilder output, string dataFromMemory )
|
|
{
|
|
Write( output, dataFromMemory, 0, dataFromMemory.Length );
|
|
}
|
|
|
|
|
|
public static void WriteWithoutQuotes( StringBuilder output, string dataFromMemory, int start, int length )
|
|
{
|
|
var end = start + length;
|
|
var index = IndexOfEscapeCharacter( dataFromMemory, start, end );
|
|
|
|
if ( index == -1 )
|
|
{
|
|
output.Append( dataFromMemory.Substring( start, length ) );
|
|
return;
|
|
}
|
|
|
|
|
|
for ( var i = 0; i < end; i++ )
|
|
{
|
|
var intValue = ( int ) dataFromMemory[ i ];
|
|
|
|
if ( intValue > 127 )
|
|
{
|
|
var escapedUnicodeValue = "\\u" + intValue.ToString( "x4" );
|
|
output.Append( escapedUnicodeValue );
|
|
|
|
continue;
|
|
}
|
|
|
|
var escapeIndex = GetEscapeIndex( dataFromMemory[ i ] );
|
|
|
|
if ( escapeIndex != -1 )
|
|
{
|
|
output.Append( ESCAPING_SEQUENCES[ escapeIndex ] );
|
|
}
|
|
else
|
|
{
|
|
output.Append( dataFromMemory[ i ] );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
static int IndexOfEscapeCharacter( string dataFromMemory, int start, int end )
|
|
{
|
|
for ( var i = start; i < end; i++ )
|
|
{
|
|
var intValue = ( int ) dataFromMemory[ i ];
|
|
|
|
if ( intValue > 127 )
|
|
{
|
|
return i;
|
|
}
|
|
|
|
var escapeIndex = GetEscapeIndex( dataFromMemory[ i ] );
|
|
|
|
if ( escapeIndex != -1 )
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int GetEscapeIndex( char c )
|
|
{
|
|
for ( int i = 0; i < ESCAPE_CHARACTERS.Length; i++ )
|
|
{
|
|
if ( ESCAPE_CHARACTERS[ i ] == c )
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
} |