本文整理汇总了C#中System.IO.StringReader.ReadSpecifiedLength方法的典型用法代码示例。如果您正苦于以下问题:C# StringReader.ReadSpecifiedLength方法的具体用法?C# StringReader.ReadSpecifiedLength怎么用?C# StringReader.ReadSpecifiedLength使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类System.IO.StringReader
的用法示例。
在下文中一共展示了StringReader.ReadSpecifiedLength方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: ParseAsync
/// <summary>
/// Starts parsing FETCH response.
/// </summary>
/// <param name="imap">IMAP cleint.</param>
/// <param name="line">Initial FETCH response line.</param>
/// <param name="callback">Callback to be called when fetch completed.</param>
/// <exception cref="ArgumentNullException">Is raised when <b>imap</b>,<b>line</b> or <b>callback</b> is null reference.</exception>
internal void ParseAsync(IMAP_Client imap,string line,EventHandler<EventArgs<Exception>> callback)
{
if(imap == null){
throw new ArgumentNullException("imap");
}
if(line == null){
throw new ArgumentNullException("line");
}
if(callback == null){
throw new ArgumentNullException("callback");
}
/* RFC 3501 7.4.2. FETCH Response.
Example: S: * 23 FETCH (FLAGS (\Seen) RFC822.SIZE 44827)
*/
StringReader r = new StringReader(line);
// Eat '*'
r.ReadWord();
// Parse seqNo
m_MsgSeqNo = Convert.ToInt32(r.ReadWord());
// Eat 'FETCH'
r.ReadWord();
// Eat '(', if list of fetch data-items.
r.ReadToFirstChar();
if(r.StartsWith("(")){
r.ReadSpecifiedLength(1);
}
ParseDataItems(imap,r,callback);
}
示例2: ParseDate
//.........这里部分代码省略.........
StringReader s = new StringReader(date);
//--- Pase date --------------------------------------------------------------------//
try{
day = Convert.ToInt32(s.ReadWord(true,new char[]{'.','-',' '},true));
}
catch{
throw new Exception("Invalid date value '" + date + "', invalid day value !");
}
try{
month = Convert.ToInt32(s.ReadWord(true,new char[]{'.','-',' '},true));
}
catch{
throw new Exception("Invalid date value '" + date + "', invalid month value !");
}
try{
year = Convert.ToInt32(s.ReadWord(true,new char[]{'.','-',' '},true));
}
catch{
throw new Exception("Invalid date value '" + date + "', invalid year value !");
}
//----------------------------------------------------------------------------------//
//--- Parse time -------------------------------------------------------------------//
// Time is optional, so parse it if its included.
if(s.Available > 0){
try{
hour = Convert.ToInt32(s.ReadWord(true,new char[]{':'},true));
}
catch{
throw new Exception("Invalid date value '" + date + "', invalid hour value !");
}
try{
minute = Convert.ToInt32(s.ReadWord(true,new char[]{':'},false));
}
catch{
throw new Exception("Invalid date value '" + date + "', invalid minute value !");
}
s.ReadToFirstChar();
if(s.StartsWith(":")){
s.ReadSpecifiedLength(1);
try{
string secondString = s.ReadWord(true,new char[]{' '},true);
// Milli seconds specified, remove them.
if(secondString.IndexOf('.') > -1){
secondString = secondString.Substring(0,secondString.IndexOf('.'));
}
second = Convert.ToInt32(secondString);
}
catch{
throw new Exception("Invalid date value '" + date + "', invalid second value !");
}
}
s.ReadToFirstChar();
if(s.Available > 3){
string timezone = s.SourceString.Replace(":","");
if(timezone.StartsWith("+") || timezone.StartsWith("-")){
bool utc_add_time = timezone.StartsWith("+");
// Remove +/- sign
timezone = timezone.Substring(1);
// padd time zone to 4 symbol. For example 200, will be 0200.
while(timezone.Length < 4){
timezone = "0" + timezone;
}
try{
// time zone format hours|minutes
int h = Convert.ToInt32(timezone.Substring(0,2));
int m = Convert.ToInt32(timezone.Substring(2));
if(utc_add_time){
zoneMinutes = 0 - ((h * 60) + m);
}
else{
zoneMinutes = (h * 60) + m;
}
}
catch{ // Just skip time zone, if can't parse
}
}
}
}
//---------------------------------------------------------------------------------//
// Convert time to UTC
if(hour != -1 && minute != -1 && second != -1){
DateTime d = new DateTime(year,month,day,hour,minute,second).AddMinutes(zoneMinutes);
return new DateTime(d.Year,d.Month,d.Day,d.Hour,d.Minute,d.Second,DateTimeKind.Utc).ToLocalTime();
}
else{
return new DateTime(year,month,day);
}
}
示例3: Fetch
//.........这里部分代码省略.........
}
}
// This isn't valid sequnce-set value
catch
{
this.TcpStream.WriteLine(string.Format("{0} BAD Invalid <sequnce-set> value '{1}' Syntax: {{<command-tag> FETCH <sequnce-set> (<fetch-keys>)}}!", cmdTag, args[0]));
return;
}
// Replace macros
string fetchItems = args[1].ToUpper();
fetchItems = fetchItems.Replace("ALL", "FLAGS INTERNALDATE RFC822.SIZE ENVELOPE");
fetchItems = fetchItems.Replace("FAST", "FLAGS INTERNALDATE RFC822.SIZE");
fetchItems = fetchItems.Replace("FULL", "FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY");
// If UID FETCH and no UID, we must implicity add it, it's required
if (uidFetch && fetchItems.ToUpper().IndexOf("UID") == -1)
{
fetchItems += " UID";
}
// Start parm parsing from left to end in while loop while params parsed or bad param found
ArrayList fetchFlags = new ArrayList();
StringReader argsReader = new StringReader(fetchItems.Trim());
while (argsReader.Available > 0)
{
argsReader.ReadToFirstChar();
#region BODYSTRUCTURE
// BODYSTRUCTURE
if (argsReader.StartsWith("BODYSTRUCTURE"))
{
argsReader.ReadSpecifiedLength("BODYSTRUCTURE".Length);
fetchFlags.Add(new object[] { "BODYSTRUCTURE" });
messageItems |= IMAP_MessageItems_enum.BodyStructure;
}
#endregion
#region BODY, BODY[<section>]<<partial>>, BODY.PEEK[<section>]<<partial>>
// BODY, BODY[<section>]<<partial>>, BODY.PEEK[<section>]<<partial>>
else if (argsReader.StartsWith("BODY"))
{
// Remove BODY
argsReader.ReadSpecifiedLength("BODY".Length);
bool peek = false;
// BODY.PEEK
if (argsReader.StartsWith(".PEEK"))
{
// Remove .PEEK
argsReader.ReadSpecifiedLength(".PEEK".Length);
peek = true;
}
// [<section>]<<partial>>
if (argsReader.StartsWith("["))
{
// Read value between []
string section = "";
try
{
示例4: DecodeWords
/// <summary>
/// Decodes "encoded-word"'s from the specified text. For more information see RFC 2047.
/// </summary>
/// <param name="text">Text to decode.</param>
/// <returns>Returns decoded text.</returns>
public static string DecodeWords(string text)
{
if(text == null){
return null;
}
/* RFC 2047 2. Syntax of encoded-words.
An 'encoded-word' is defined by the following ABNF grammar. The
notation of RFC 822 is used, with the exception that white space
characters MUST NOT appear between components of an 'encoded-word'.
encoded-word = "=?" charset "?" encoding "?" encoded-text "?="
charset = token ; see section 3
encoding = token ; see section 4
token = 1*<Any CHAR except SPACE, CTLs, and especials>
especials = "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "
<"> / "/" / "[" / "]" / "?" / "." / "="
encoded-text = 1*<Any printable ASCII character other than "?" or SPACE>
; (but see "Use of encoded-words in message headers", section 5)
Both 'encoding' and 'charset' names are case-independent. Thus the
charset name "ISO-8859-1" is equivalent to "iso-8859-1", and the
encoding named "Q" may be spelled either "Q" or "q".
An 'encoded-word' may not be more than 75 characters long, including
'charset', 'encoding', 'encoded-text', and delimiters. If it is
desirable to encode more text than will fit in an 'encoded-word' of
75 characters, multiple 'encoded-word's (separated by CRLF SPACE) may
be used.
IMPORTANT: 'encoded-word's are designed to be recognized as 'atom's
by an RFC 822 parser. As a consequence, unencoded white space
characters (such as SPACE and HTAB) are FORBIDDEN within an
'encoded-word'. For example, the character sequence
=?iso-8859-1?q?this is some text?=
would be parsed as four 'atom's, rather than as a single 'atom' (by
an RFC 822 parser) or 'encoded-word' (by a parser which understands
'encoded-words'). The correct way to encode the string "this is some
text" is to encode the SPACE characters as well, e.g.
=?iso-8859-1?q?this=20is=20some=20text?=
*/
StringReader r = new StringReader(text);
StringBuilder retVal = new StringBuilder();
// We need to loop all words, if encoded word, decode it, othwerwise just append to return value.
bool lastIsEncodedWord = false;
while(r.Available > 0){
string whiteSpaces = r.ReadToFirstChar();
// Probably is encoded-word, we try to parse it.
if(r.StartsWith("=?") && r.SourceString.IndexOf("?=") > -1){
StringBuilder encodedWord = new StringBuilder();
string decodedWord = null;
try{
// NOTE: We can't read encoded word and then split !!!, we need to read each part.
// Remove =?
encodedWord.Append(r.ReadSpecifiedLength(2));
// Read charset
string charset = r.QuotedReadToDelimiter('?');
encodedWord.Append(charset + "?");
// Read encoding
string encoding = r.QuotedReadToDelimiter('?');
encodedWord.Append(encoding + "?");
// Read text
string encodedText = r.QuotedReadToDelimiter('?');
encodedWord.Append(encodedText + "?");
// We must have remaining '=' here
if(r.StartsWith("=")){
encodedWord.Append(r.ReadSpecifiedLength(1));
Encoding c = Encoding.GetEncoding(charset);
if(encoding.ToLower() == "q"){
decodedWord = Core.QDecode(c,encodedText);
}
else if(encoding.ToLower() == "b"){
decodedWord = c.GetString(Core.Base64Decode(Encoding.Default.GetBytes(encodedText)));
}
}
}
catch{
// Not encoded-word or contains unknwon charset/encoding, so leave
// encoded-word as is.
}
/* RFC 2047 6.2.
//.........这里部分代码省略.........
示例5: ReadString
/// <summary>
/// Reads IMAP string-literal/string/astring/nstring/utf8-quoted from string reader.
/// </summary>
/// <param name="reader">String reader.</param>
/// <returns>Returns IMAP string.</returns>
/// <exception cref="ArgumentNullException">Is raised when <b>reader</b> is null reference.</exception>
public static string ReadString(StringReader reader)
{
if(reader == null){
throw new ArgumentNullException("reader");
}
reader.ReadToFirstChar();
// We have string-literal.
if(reader.SourceString.StartsWith("{")){
int literalSize = Convert.ToInt32(reader.ReadParenthesized());
// Literal has CRLF ending, skip it.
reader.ReadSpecifiedLength(2);
return reader.ReadSpecifiedLength(literalSize);
}
// utf8-quoted old rfc 5738
else if(reader.StartsWith("*\"")){
reader.ReadSpecifiedLength(1);
return reader.ReadWord();
}
// string/astring/nstring
else{
string word = reader.ReadWord();
// nstring
if(string.Equals(word,"NIL",StringComparison.InvariantCultureIgnoreCase)){
return null;
}
return word;
}
}
示例6: FetchMessage
/// <summary>
/// Gets specified message from server and stores to specified stream.
/// </summary>
/// <param name="uid">Message UID which to get.</param>
/// <param name="storeStream">Stream where to store message.</param>
/// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
/// <exception cref="InvalidOperationException">Is raised when IMAP client is not connected,not authenticated and folder not selected.</exception>
public void FetchMessage(int uid, Stream storeStream)
{
if (this.IsDisposed)
{
throw new ObjectDisposedException(this.GetType().Name);
}
if (!this.IsConnected)
{
throw new InvalidOperationException("You must connect first.");
}
if (!this.IsAuthenticated)
{
throw new InvalidOperationException("The command is only valid in authenticated state.");
}
if (m_SelectedFolder.Length == 0)
{
throw new InvalidOperationException("The command is only valid in selected state.");
}
// Send fetch command line to server.
// mwa fix for gmail change, message was being marked as read automatically without the PEEK modifier
string line = GetNextCmdTag() + " UID FETCH " + uid + " BODY.PEEK[]";
int countWritten = this.TcpStream.WriteLine(line);
LogAddWrite(countWritten, line);
// Read un-tagged response lines while we get final response line.
while (true)
{
line = this.ReadLine();
// We have un-tagged resposne.
if (line.StartsWith("*"))
{
if (IsStatusResponse(line))
{
ProcessStatusResponse(line);
}
else if (line.ToUpper().ToString().IndexOf("BODY[") > -1)
{
if (line.IndexOf('{') > -1)
{
StringReader r = new StringReader(line);
while (r.Available > 0 && !r.StartsWith("{"))
{
r.ReadSpecifiedLength(1);
}
int sizeOfData = Convert.ToInt32(r.ReadParenthesized());
this.TcpStream.ReadFixedCount(storeStream, sizeOfData);
LogAddRead(sizeOfData, "Readed " + sizeOfData + " bytes.");
line = this.ReadLine();
}
}
}
else
{
break;
}
}
if (!RemoveCmdTag(line).ToUpper().StartsWith("OK"))
{
throw new IMAP_ClientException(line);
}
}
示例7: FetchMessages
//.........这里部分代码省略.........
byte[] data = null;
IMAP_MessageFlags flags = IMAP_MessageFlags.Recent;
string envelope = "";
string bodystructure = "";
string internalDate = "";
// Remove *
line = RemoveCmdTag(line);
// Get message number
no = Convert.ToInt32(line.Substring(0, line.IndexOf(" ")));
// Get rid of FETCH and parse params. Reply:* 1 FETCH (UID 12 BODY[] ...)
line = line.Substring(line.IndexOf("FETCH (") + 7);
StringReader r = new StringReader(line);
// Loop fetch result fields
while (r.Available > 0)
{
r.ReadToFirstChar();
// Fetch command closing ) parenthesis
if (r.SourceString == ")")
{
break;
}
#region UID <value>
// UID <value>
else if (r.StartsWith("UID", false))
{
// Remove UID word from reply
r.ReadSpecifiedLength("UID".Length);
r.ReadToFirstChar();
// Read <value>
string word = r.ReadWord();
if (word == null)
{
throw new Exception("IMAP server didn't return UID <value> !");
}
else
{
uid = Convert.ToInt32(word);
}
}
#endregion
#region RFC822.SIZE <value>
// RFC822.SIZE <value>
else if (r.StartsWith("RFC822.SIZE", false))
{
// Remove RFC822.SIZE word from reply
r.ReadSpecifiedLength("RFC822.SIZE".Length);
r.ReadToFirstChar();
// Read <value>
string word = r.ReadWord();
if (word == null)
{
throw new Exception("IMAP server didn't return RFC822.SIZE <value> !");
}
else
示例8: GetFilters
public byte[] GetFilters()
{
if (IsDisposed)
{
throw new ObjectDisposedException(GetType().Name);
}
if (!IsConnected)
{
throw new InvalidOperationException("You must connect first.");
}
if (!IsAuthenticated)
{
throw new InvalidOperationException("The command is only valid in authenticated state.");
}
if (m_SelectedFolder.Length == 0)
{
throw new InvalidOperationException("The command is only valid in selected state.");
}
// Send fetch command line to server.
string line = GetNextCmdTag() + " X-GET-FILTER ";
int countWritten = TcpStream.WriteLine(line);
LogAddWrite(countWritten, line);
using (MemoryStream store = new MemoryStream())
{
// Read un-tagged response lines while we get final response line.
while (true)
{
line = ReadLine();
// We have un-tagged resposne.
if (line.StartsWith("*"))
{
if (IsStatusResponse(line))
{
ProcessStatusResponse(line);
}
else if (line.ToUpper().IndexOf("FILTER") > -1)
{
if (line.IndexOf('{') > -1)
{
StringReader r = new StringReader(line);
while (r.Available > 0 && !r.StartsWith("{"))
{
r.ReadSpecifiedLength(1);
}
int sizeOfData = Convert.ToInt32(r.ReadParenthesized());
TcpStream.ReadFixedCount(store, sizeOfData);
LogAddRead(sizeOfData, "Readed " + sizeOfData + " bytes.");
line = ReadLine();
}
}
}
else
{
break;
}
}
if (!RemoveCmdTag(line).ToUpper().StartsWith("OK"))
{
throw new IMAP_ClientException(line);
}
byte[] buffer = store.GetBuffer();
if (buffer.Length>0)
{
return Convert.FromBase64String(Encoding.UTF8.GetString(buffer));
}
else
{
return null;
}
}
}
示例9: GetList
//.........这里部分代码省略.........
if(!response[0].StartsWith("1")){
throw new FTP_ClientException(response[0]);
}
MemoryStream ms = new MemoryStream();
m_pDataConnection.ReadAll(ms);
response = ReadResponse();
if(!response[0].StartsWith("2")){
throw new FTP_ClientException(response[0]);
}
ms.Position = 0;
SmartStream listStream = new SmartStream(ms,true);
string[] winDateFormats = new string[]{"M-d-yy h:mmtt"};
string[] unixFormats = new string[]{"MMM d H:mm","MMM d yyyy"};
SmartStream.ReadLineAsyncOP args = new SmartStream.ReadLineAsyncOP(new byte[8000],SizeExceededAction.JunkAndThrowException);
while(true){
listStream.ReadLine(args,false);
if(args.Error != null){
throw args.Error;
}
else if(args.BytesInBuffer == 0){
break;
}
string line = args.LineUtf8;
// Dedect listing.
string listingType = "unix";
if(line != null){
StringReader r = new StringReader(line);
DateTime modified;
if(DateTime.TryParseExact(r.ReadWord() + " " + r.ReadWord(),new string[]{"MM-dd-yy hh:mmtt"},System.Globalization.DateTimeFormatInfo.InvariantInfo,System.Globalization.DateTimeStyles.None,out modified)){
listingType = "win";
}
}
try{
// Windows listing.
if(listingType == "win"){
// MM-dd-yy hh:mm <DIR> directoryName
// MM-dd-yy hh:mm size fileName
StringReader r = new StringReader(line);
// Read date
DateTime modified = DateTime.ParseExact(r.ReadWord() + " " + r.ReadWord(),winDateFormats,System.Globalization.DateTimeFormatInfo.InvariantInfo,System.Globalization.DateTimeStyles.None);
r.ReadToFirstChar();
// We have directory.
if(r.StartsWith("<dir>",false)){
r.ReadSpecifiedLength(5);
r.ReadToFirstChar();
retVal.Add(new FTP_ListItem(r.ReadToEnd(),0,modified,true));
}
// We have file
else{
// Read file size
long size = Convert.ToInt64(r.ReadWord());
r.ReadToFirstChar();
retVal.Add(new FTP_ListItem(r.ReadToEnd(),size,modified,false));
}
}
// Unix listing
else{
// "d"directoryAtttributes xx xx xx 0 MMM d HH:mm/yyyy directoryName
// fileAtttributes xx xx xx fileSize MMM d HH:mm/yyyy fileName
StringReader r = new StringReader(line);
string attributes = r.ReadWord();
r.ReadWord();
r.ReadWord();
r.ReadWord();
long size = Convert.ToInt64(r.ReadWord());
DateTime modified = DateTime.ParseExact(r.ReadWord() + " " + r.ReadWord() + " " + r.ReadWord(),unixFormats,System.Globalization.DateTimeFormatInfo.InvariantInfo,System.Globalization.DateTimeStyles.None);
r.ReadToFirstChar();
string name = r.ReadToEnd();
if(name != "." && name != ".."){
if(attributes.StartsWith("d")){
retVal.Add(new FTP_ListItem(name,0,modified,true));
}
else{
retVal.Add(new FTP_ListItem(name,size,modified,false));
}
}
}
}
catch{
// Skip unknown entries.
}
}
}
#endregion
return retVal.ToArray();
}
示例10: ReadString
/// <summary>
/// Reads IMAP string/astring/nstring/utf8-quoted from string reader.
/// </summary>
/// <param name="reader">String reader.</param>
/// <returns>Returns IMAP string.</returns>
/// <exception cref="ArgumentNullException">Is raised when <b>reader</b> is null reference.</exception>
internal static string ReadString(StringReader reader)
{
if(reader == null){
throw new ArgumentNullException("reader");
}
reader.ReadToFirstChar();
// utf8-quoted
if(reader.StartsWith("*\"")){
reader.ReadSpecifiedLength(1);
return reader.ReadWord();
}
// string/astring/nstring
else{
string word = reader.ReadWord();
// nstring
if(string.Equals(word,"NIL",StringComparison.InvariantCultureIgnoreCase)){
return null;
}
return word;
}
}
示例11: FetchMessages
//.........这里部分代码省略.........
int no = 0;
int uid = 0;
int size = 0;
byte[] data = null;
IMAP_MessageFlags flags = IMAP_MessageFlags.Recent;
string envelope = "";
string bodystructure = "";
string internalDate = "";
// Remove *
reply = reply.Substring(1).TrimStart();
// Get message number
no = Convert.ToInt32(reply.Substring(0,reply.IndexOf(" ")));
// Get rid of FETCH and parse params. Reply:* 1 FETCH (UID 12 BODY[] ...)
reply = reply.Substring(reply.IndexOf("FETCH (") + 7);
StringReader r = new StringReader(reply);
// Loop fetch result fields
while(r.Available > 0){
r.ReadToFirstChar();
// Fetch command closing ) parenthesis
if(r.SourceString == ")"){
break;
}
#region UID <value>
// UID <value>
else if(r.StartsWith("UID",false)){
// Remove UID word from reply
r.ReadSpecifiedLength("UID".Length);
r.ReadToFirstChar();
// Read <value>
string word = r.ReadWord();
if(word == null){
throw new Exception("IMAP server didn't return UID <value> !");
}
else{
uid = Convert.ToInt32(word);
}
}
#endregion
#region RFC822.SIZE <value>
// RFC822.SIZE <value>
else if(r.StartsWith("RFC822.SIZE",false)){
// Remove RFC822.SIZE word from reply
r.ReadSpecifiedLength("RFC822.SIZE".Length);
r.ReadToFirstChar();
// Read <value>
string word = r.ReadWord();
if(word == null){
throw new Exception("IMAP server didn't return RFC822.SIZE <value> !");
}
else{
try{
size = Convert.ToInt32(word);
}
catch{
示例12: FetchMessage
/// <summary>
/// Gets specified message from server and stores to specified stream.
/// </summary>
/// <param name="uid">Message UID which to get.</param>
/// <param name="storeStream">Stream where to store message.</param>
public void FetchMessage(int uid,Stream storeStream)
{
if(!m_Connected){
throw new Exception("You must connect first !");
}
if(!m_Authenticated){
throw new Exception("You must authenticate first !");
}
if(m_SelectedFolder.Length == 0){
throw new Exception("You must select folder first !");
}
m_pSocket.WriteLine("a1 UID FETCH " + uid + " BODY[]");
string reply = m_pSocket.ReadLine(50000);
// Read multiline response
while(reply.StartsWith("*")){
// Fetch may return status response there, skip them
if(IsStatusResponse(reply)){
// Read next server response
reply = m_pSocket.ReadLine(50000);
continue;
}
reply = RemoveCmdTag(reply);
// We must get here: BODY[] {sizeOfData}
if(reply.ToUpper().ToString().IndexOf("BODY[") > - 1){
if(reply.IndexOf('{') > -1){
StringReader r = new StringReader(reply);
while(r.Available > 0 && !r.StartsWith("{")){
r.ReadSpecifiedLength(1);
}
int sizeOfData = Convert.ToInt32(r.ReadParenthesized());
m_pSocket.ReadSpecifiedLength(sizeOfData,storeStream);
m_pSocket.ReadLine();
}
}
// Read next server response
reply = m_pSocket.ReadLine(50000);
}
// We must get OK or otherwise there is error
if(!RemoveCmdTag(reply).ToUpper().StartsWith("OK")){
if(!reply.ToUpper().StartsWith("NO")){
throw new Exception("Server returned:" + reply);
}
}
}