Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

Forums:

Hi All,

I have to decode a JSON response from the server.Can anybody guide me to solve this problem? Its urgent plzzzz..

Regards
Priya

I can copy you peaces of JSON parser in C++ code I did by translating it from Java. You need to translate this into C. I will also paste you another portions of code.
void JSONObject::fromTokener(JSONTokener &x)
{
char c;
String key;
if (x.nextClean() != '{')
{
// syntaxError("A JSONObject text must begin with '{'"));
return
}
while (true)
{
c = x.nextClean();
switch (c)
{
case 0:
// syntaxError("A JSONObject text must end with '}'"));
case '}':
return;
default:
x.back();
key = x.nextValue().toString();
}
/*
* The key is followed by ':'. We will also tolerate '=' or '=>'.
*/
c = x.nextClean();
if (c == '=')
{
if (x.next() != '>')
{
x.back();
}
}
else if (c != ':')
{
// syntaxError("Expected a ':' after a key"));
}
put(key, x.nextValue()); // Store key, value
/*
* Pairs are separated by ','. We will also tolerate ';'.
*/
switch (x.nextClean())
{
case ';':
case ',':
if (x.nextClean() == '}')
{
return;
}
x.back();
break;
case '}':
return;
default:
// syntaxError("Expected a ',' or '}'"));
}
}

I can copy you peaces of JSON parser in C++ code I did by translating it from Java. You need to translate this into C. I will also paste you another portions of code.
void JSONObject::fromTokener(JSONTokener &x)
{
char c;
String key;
if (x.nextClean() != '{')
{
// syntaxError("A JSONObject text must begin with '{'"));
return
}
while (true)
{
c = x.nextClean();
switch (c)
{
case 0:
// syntaxError("A JSONObject text must end with '}'"));
case '}':
return;
default:
x.back();
key = x.nextValue().toString();
}
/*
* The key is followed by ':'. We will also tolerate '=' or '=>'.
*/
c = x.nextClean();
if (c == '=')
{
if (x.next() != '>')
{
x.back();
}
}
else if (c != ':')
{
// syntaxError("Expected a ':' after a key"));
}
put(key, x.nextValue()); // Store key, value
/*
* Pairs are separated by ','. We will also tolerate ';'.
*/
switch (x.nextClean())
{
case ';':
case ',':
if (x.nextClean() == '}')
{
return;
}
x.back();
break;
case '}':
return;
default:
// syntaxError("Expected a ',' or '}'"));
}
}

Tokener:

/**
* The index of the next character.
*/
int32 m_index = 0;

/**
* The source string being tokenized.
*/
String m_source = sourceString;

/**
* Back up one character. This provides a sort of lookahead capability,
* so that you can test for a digit or letter before attempting to parse
* the next number or identifier.
*/
void JSONTokener::back()
{
if (m_index > 0)
{
m_index--;
}
}

/**
* Get the hex value of a character (base16).
* @param c A character between '0' and '9' or between 'A' and 'F' or
* between 'a' and 'f'.
* @return An int between 0 and 15, or -1 if c was not a hex digit.
*/
int32 JSONTokener::dehexchar(char c)
{
if (c >= '0' && c <= '9')
{
return c - '0';
}
if (c >= 'A' && c <= 'F')
{
return c - ('A' - 10);
}
if (c >= 'a' && c <= 'f')
{
return c - ('a' - 10);
}
return -1;
}

/**
* Determine if the source string still contains characters that next()
* can consume.
* @return true if not yet at the end of the source.
*/
bool JSONTokener::more()
{
return m_index < m_source.length();
}

/**
* Get the next character in the source string.
*
* @return The next character, or 0 if past the end of the source string.
*/
char JSONTokener::next()
{
if (more())
{
char c = m_source.charAt(m_index);
m_index++;
return c;
}
return 0;
}

/**
* Consume the next character, and check that it matches a specified
* character.
* @param c The character to match.
* @return The character.
* @throws JSONException if the character does not match.
*/
char JSONTokener::next(char c)
{
char n = next();
if (n != c)
{
// syntaxError("Expected '" + String(c) + "' and instead saw '" +
String(n) + "'."));
return 0;

}
return n;
}

/**
* Get the next n characters.
*
* @param n The number of characters to take.
* @return A string of n characters.
* @throws JSONException
* Substring bounds error if there are not
* n characters remaining in the source string.
*/
String JSONTokener::next(int32 n)
{
int32 i = m_index;
int32 j = i + n;
if (j >= m_source.length())
{
// syntaxError("Substring bounds error"));
return emptyString;
}
m_index += n;
return m_source.substring(i, j);
}

/**
* Get the next char in the string, skipping whitespace
* and comments (slashslash, slashstar, and hash).
* @throws JSONException
* @return A character, or 0 if there are no more characters.
*/
char JSONTokener::nextClean()
{
while(true)
{
char c = next();
if (c == '/')
{
switch (next())
{
case '/':
do
{
c = next();
} while (c != '\n' && c != '\r' && c != 0);
break;
case '*':
while(true)
{
c = next();
if (c == 0)
{
// syntaxError("Unclosed comment.");
return 0;
}
if (c == '*')
{
if (next() == '/')
{
break;
}
back();
}
}
break;
default:
back();
return '/';
}
}
else if (c == '#')
{
do
{
c = next();
} while (c != '\n' && c != '\r' && c != 0);
}
else if (c == 0 || c > ' ')
{
return c;
}
}
}

/**
* Return the characters up to the next close quote character.
* Backslash processing is done. The formal JSON format does not
* allow strings in single quotes, but an implementation is allowed to
* accept them.
* @param quote The quoting character, either
* " (double quote) or
* ' (single quote).
* @return A String.
* @throws JSONException Unterminated string.
*/
String JSONTokener::nextString(char quote)
{
char c;
String sb;
while (true)
{
c = next();
switch (c)
{
case 0:
case '\n':
case '\r':
// syntaxError("Unterminated string");
return emptyString;
case '\\':
c = next();
switch (c)
{
case 'b':
sb.append('\b');
break;
case 't':
sb.append('\t');
break;
case 'n':
sb.append('\n');
break;
case 'f':
sb.append('\f');
break;
case 'r':
sb.append('\r');
break;
case 'u':
sb.append((char)StringHelper::toInt(next((int32)4), 16));
break;
case 'x' :
sb.append((char)StringHelper::toInt(next((int32)2,), 16));
break;
default:
sb.append(c);
}
break;
default:
if (c == quote)
{
return sb;
}
sb.append(c);
break;
}
}
}

/**
* Get the text up but not including the specified character or the
* end of line, whichever comes first.
* @param d A delimiter character.
* @return A string.
*/
String JSONTokener::nextTo(char d)
{
String sb;
while (true)
{
char c = next();
if (c == d || c == 0 || c == '\n' || c == '\r')
{
if (c != 0)
{
back();
}
return StringHelper::trim(sb);
}
sb.append(c);
}
}

/**
* Get the text up but not including one of the specified delimeter
* characters or the end of line, whichever comes first.
* @param delimiters A set of delimiter characters.
* @return A string, trimmed.
*/
String JSONTokener::nextTo(const String& delimiters)
{
char c;
String sb;
while (true)
{
c = next();
if (delimiters.indexOf(c) >= 0 || c == 0 ||
c == '\n' || c == '\r')
{
if (c != 0)
{
back();
}
return StringHelper::trim(sb);
}
sb.append(c);
}
}

/**
* Get the next value. The value can be a Boolean, Double, Integer,
* JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
* @throws JSONException If syntax error.
*
* @return An object.
*/
Variant JSONTokener::nextValue()
{
char c = nextClean();

switch (c)
{
case '"':
case '\'':
return nextString(c);
case '{':
back();
return Variant(new JSONObject(*this));
case '[':
back();
return Variant(new JSONArray(*this, ex));
}

/*
* Handle unquoted text. This could be the values true, false, or
* null, or it can be a number. An implementation (such as this one)
* is allowed to also accept non-standard forms.
*
* Accumulate characters until we reach the end of the text or a
* formatting character.
*/

String s;
String sb;
String sSep(",:]}/\\\"[{;=#");
char b = c;
while (c >= ' ' && sSep.indexOf(c) == String::OutOfRange)
{
sb.append(c);
c = next();
}
back();

/*
* If it is true, false, or null, return the proper value.
*/

s = StringHelper::trim(sb);
if (s.isEmpty())
{
// (syntaxError("Missing value."));
return emptyString;
}
if (StringHelper::toLowerCase(s) == "true")
{
return Variant(true);
}
if (StringHelper::toLowerCase(s) == "false")
{
return Variant(false);
}
if (StringHelper::toLowerCase(s) == "null")
{
return Variant();
}

/*
* If it might be a number, try converting it. We support the 0- and 0x-
* conventions. If a number cannot be produced, then the value will just
* be a string. Note that the 0-, 0x-, plus, and implied string
* conventions are non-standard. A JSON parser is free to accept
* non-JSON forms as long as it accepts all correct JSON forms.
*/

if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+')
{
bool hasDot = (s.indexOf('.') != UCString::OutOfRange);
if (b == '0')
{
if (s.length() > 2 &&
(s.charAt(1) == 'x' || s.charAt(1) == 'X'))
{
int32 iVal = StringHelper::toInt(s.substring(2), 16); return Variant(iVal);
}
else if (!hasDot)
{
int32 iVal = StringHelper::toInt(s, 8);
return Variant(iVal);
}
}
if (!hasDot)
{
int32 iVal = StringHelper::toInt(s);
return iVal;
}
else
{
double dVal = StringHelper::toDouble(s);
return dVal;
}
}
return s;
}

/**
* Skip characters until the next character is the requested character.
* If the requested character is not found, no characters are skipped.
* @param to A character to skip to.
* @return The requested character, or zero if the requested character
* is not found.
*/
char JSONTokener::skipTo(char to)
{
char c;
int32 index = m_index;
do
{
c = next();
if (c == 0)
{
m_index = index;
return c;
}
} while (c != to);
back();
return c;
}

/**
* Skip characters until past the requested string.
* If it is not found, we are left at the end of the source.
* @param to A string to skip past.
*/
void JSONTokener::skipPast(const String& to)
{
m_index = m_source.indexOf(to, m_index);
if (m_index < 0)
{
m_index = m_source.length();
}
else
{
m_index += to.length();
}
}

Am not sure if this helps or not. Please let me know. I guess this code is pretty much close to one in Java, and you can proceed there.

Tokener:

/**
* The index of the next character.
*/
int32 m_index = 0;

/**
* The source string being tokenized.
*/
String m_source = sourceString;

/**
* Back up one character. This provides a sort of lookahead capability,
* so that you can test for a digit or letter before attempting to parse
* the next number or identifier.
*/
void JSONTokener::back()
{
if (m_index > 0)
{
m_index--;
}
}

/**
* Get the hex value of a character (base16).
* @param c A character between '0' and '9' or between 'A' and 'F' or
* between 'a' and 'f'.
* @return An int between 0 and 15, or -1 if c was not a hex digit.
*/
int32 JSONTokener::dehexchar(char c)
{
if (c >= '0' && c <= '9')
{
return c - '0';
}
if (c >= 'A' && c <= 'F')
{
return c - ('A' - 10);
}
if (c >= 'a' && c <= 'f')
{
return c - ('a' - 10);
}
return -1;
}

/**
* Determine if the source string still contains characters that next()
* can consume.
* @return true if not yet at the end of the source.
*/
bool JSONTokener::more()
{
return m_index < m_source.length();
}

/**
* Get the next character in the source string.
*
* @return The next character, or 0 if past the end of the source string.
*/
char JSONTokener::next()
{
if (more())
{
char c = m_source.charAt(m_index);
m_index++;
return c;
}
return 0;
}

/**
* Consume the next character, and check that it matches a specified
* character.
* @param c The character to match.
* @return The character.
* @throws JSONException if the character does not match.
*/
char JSONTokener::next(char c)
{
char n = next();
if (n != c)
{
// syntaxError("Expected '" + String(c) + "' and instead saw '" +
String(n) + "'."));
return 0;

}
return n;
}

/**
* Get the next n characters.
*
* @param n The number of characters to take.
* @return A string of n characters.
* @throws JSONException
* Substring bounds error if there are not
* n characters remaining in the source string.
*/
String JSONTokener::next(int32 n)
{
int32 i = m_index;
int32 j = i + n;
if (j >= m_source.length())
{
// syntaxError("Substring bounds error"));
return emptyString;
}
m_index += n;
return m_source.substring(i, j);
}

/**
* Get the next char in the string, skipping whitespace
* and comments (slashslash, slashstar, and hash).
* @throws JSONException
* @return A character, or 0 if there are no more characters.
*/
char JSONTokener::nextClean()
{
while(true)
{
char c = next();
if (c == '/')
{
switch (next())
{
case '/':
do
{
c = next();
} while (c != '\n' && c != '\r' && c != 0);
break;
case '*':
while(true)
{
c = next();
if (c == 0)
{
// syntaxError("Unclosed comment.");
return 0;
}
if (c == '*')
{
if (next() == '/')
{
break;
}
back();
}
}
break;
default:
back();
return '/';
}
}
else if (c == '#')
{
do
{
c = next();
} while (c != '\n' && c != '\r' && c != 0);
}
else if (c == 0 || c > ' ')
{
return c;
}
}
}

/**
* Return the characters up to the next close quote character.
* Backslash processing is done. The formal JSON format does not
* allow strings in single quotes, but an implementation is allowed to
* accept them.
* @param quote The quoting character, either
* " (double quote) or
* ' (single quote).
* @return A String.
* @throws JSONException Unterminated string.
*/
String JSONTokener::nextString(char quote)
{
char c;
String sb;
while (true)
{
c = next();
switch (c)
{
case 0:
case '\n':
case '\r':
// syntaxError("Unterminated string");
return emptyString;
case '\\':
c = next();
switch (c)
{
case 'b':
sb.append('\b');
break;
case 't':
sb.append('\t');
break;
case 'n':
sb.append('\n');
break;
case 'f':
sb.append('\f');
break;
case 'r':
sb.append('\r');
break;
case 'u':
sb.append((char)StringHelper::toInt(next((int32)4), 16));
break;
case 'x' :
sb.append((char)StringHelper::toInt(next((int32)2,), 16));
break;
default:
sb.append(c);
}
break;
default:
if (c == quote)
{
return sb;
}
sb.append(c);
break;
}
}
}

/**
* Get the text up but not including the specified character or the
* end of line, whichever comes first.
* @param d A delimiter character.
* @return A string.
*/
String JSONTokener::nextTo(char d)
{
String sb;
while (true)
{
char c = next();
if (c == d || c == 0 || c == '\n' || c == '\r')
{
if (c != 0)
{
back();
}
return StringHelper::trim(sb);
}
sb.append(c);
}
}

/**
* Get the text up but not including one of the specified delimeter
* characters or the end of line, whichever comes first.
* @param delimiters A set of delimiter characters.
* @return A string, trimmed.
*/
String JSONTokener::nextTo(const String& delimiters)
{
char c;
String sb;
while (true)
{
c = next();
if (delimiters.indexOf(c) >= 0 || c == 0 ||
c == '\n' || c == '\r')
{
if (c != 0)
{
back();
}
return StringHelper::trim(sb);
}
sb.append(c);
}
}

/**
* Get the next value. The value can be a Boolean, Double, Integer,
* JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
* @throws JSONException If syntax error.
*
* @return An object.
*/
Variant JSONTokener::nextValue()
{
char c = nextClean();

switch (c)
{
case '"':
case '\'':
return nextString(c);
case '{':
back();
return Variant(new JSONObject(*this));
case '[':
back();
return Variant(new JSONArray(*this, ex));
}

/*
* Handle unquoted text. This could be the values true, false, or
* null, or it can be a number. An implementation (such as this one)
* is allowed to also accept non-standard forms.
*
* Accumulate characters until we reach the end of the text or a
* formatting character.
*/

String s;
String sb;
String sSep(",:]}/\\\"[{;=#");
char b = c;
while (c >= ' ' && sSep.indexOf(c) == String::OutOfRange)
{
sb.append(c);
c = next();
}
back();

/*
* If it is true, false, or null, return the proper value.
*/

s = StringHelper::trim(sb);
if (s.isEmpty())
{
// (syntaxError("Missing value."));
return emptyString;
}
if (StringHelper::toLowerCase(s) == "true")
{
return Variant(true);
}
if (StringHelper::toLowerCase(s) == "false")
{
return Variant(false);
}
if (StringHelper::toLowerCase(s) == "null")
{
return Variant();
}

/*
* If it might be a number, try converting it. We support the 0- and 0x-
* conventions. If a number cannot be produced, then the value will just
* be a string. Note that the 0-, 0x-, plus, and implied string
* conventions are non-standard. A JSON parser is free to accept
* non-JSON forms as long as it accepts all correct JSON forms.
*/

if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+')
{
bool hasDot = (s.indexOf('.') != UCString::OutOfRange);
if (b == '0')
{
if (s.length() > 2 &&
(s.charAt(1) == 'x' || s.charAt(1) == 'X'))
{
int32 iVal = StringHelper::toInt(s.substring(2), 16); return Variant(iVal);
}
else if (!hasDot)
{
int32 iVal = StringHelper::toInt(s, 8);
return Variant(iVal);
}
}
if (!hasDot)
{
int32 iVal = StringHelper::toInt(s);
return iVal;
}
else
{
double dVal = StringHelper::toDouble(s);
return dVal;
}
}
return s;
}

/**
* Skip characters until the next character is the requested character.
* If the requested character is not found, no characters are skipped.
* @param to A character to skip to.
* @return The requested character, or zero if the requested character
* is not found.
*/
char JSONTokener::skipTo(char to)
{
char c;
int32 index = m_index;
do
{
c = next();
if (c == 0)
{
m_index = index;
return c;
}
} while (c != to);
back();
return c;
}

/**
* Skip characters until past the requested string.
* If it is not found, we are left at the end of the source.
* @param to A string to skip past.
*/
void JSONTokener::skipPast(const String& to)
{
m_index = m_source.indexOf(to, m_index);
if (m_index < 0)
{
m_index = m_source.length();
}
else
{
m_index += to.length();
}
}

Am not sure if this helps or not. Please let me know. I guess this code is pretty much close to one in Java, and you can proceed there.

Hi Master,
Thanks for your response.I will definitly try this code on Monday once i go to office and get back to you with the response.
Thanks for your help.
Regards
Priya

Hi Master,
Thanks for your response.I will definitly try this code on Monday once i go to office and get back to you with the response.
Thanks for your help.
Regards
Priya

Hi Master,
I have gone through your code but unable to understand how to use in my programme.I can't also find the JSON encoded rersponse string.can u plz give some steps to decode my json encoded string??
Thanks in advance.
Regards
Priya

Hi Master,
I have gone through your code but unable to understand how to use in my programme.I can't also find the JSON encoded rersponse string.can u plz give some steps to decode my json encoded string??
Thanks in advance.
Regards
Priya

Hi Master,
I have gone through your code but unable to understand .I think you have also used some JAVA supported JSON classes in your code. So can u guide me write in simple C as u know BREW does not have any JSON support so i need to write in simple C only.
Thanks in advance.
Regards
Priya

Hi Master,
I have gone through your code but unable to understand .I think you have also used some JAVA supported JSON classes in your code. So can u guide me write in simple C as u know BREW does not have any JSON support so i need to write in simple C only.
Thanks in advance.
Regards
Priya