What characters should I encode always? - c++

Trying to encode the URL before the HTTP call but getting no response from the server (response code 0). Without encoding things working fine.
Requirement:
Need to encode special characters in URL. Specifically, I need to encode the below characters plus any other such characters:
! * ' ( ) ; : # & = + $ , / ? % # [ ]
This is my understanding of Url Encoding:
Only alphanumeric and a few special characters ("-", ".", "_", "~")  may be used unencoded within a URL. The rest of the characters transmitted as part of the URL, whether in the query string or path segment, must always be encoded. Reference.
I am doubtful on "*", as in Android this can also go unencoded. Reference
I tried encoding the whole URL, as well as individual params, but I'm getting the same result.
Below is my encoding function:
void Url::escape(String& str)
{
if(str.isEmpty())
{
return;
}
uint32_t i = 0;
unsigned char in;
char hexbuf[4];
while(i < str.size())
{
in = static_cast<unsigned char>(str[i]);
switch(in)
{
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': case '~': case '.': case '-':
break;
default:
str[i] = '%';
snprintf(hexbuf, 3, "%02X", in);
str.insert(hexbuf, i + 1);
i += 2;
break;
}
++i;
}
}
Am I missing anything here? I want clarity on below as well:
Can I call Url::escape() on the whole input url String, or should I encode individual query params only?
What characters can/should I omit in encoding (is Url::escape() correct or not)?
I referred to multiple references here, but I could not find any concrete solution.

Can I call Url::escape() on whole input url String or should I go by encoding indivisual query param only?
You must encode individual components of the url, not just the query params.
What characters I can/should omit in encoding (is Url::escape() is correct or not)?
Different components have different rules of what characters need to be encoded and which ones do not.
RFC 3986: Uniform Resource Identifier (URI): Generic Syntax outlines the basic rules that all URLs have to conform to. However, there are lots of URL schemes, many of which provide additional rules/restrictions on top of this syntax for scheme-specific components, and have their own RFCs.

Related

Error: break statement not within loop or switch

I wrote this part of code and a series of error are being shown. The above mentioned error being the first. What is wrong in the code?
void direction(char ch)
{
switch(ch)
case 'w': if(dirn!=3){dirn=1;}
break;
case 'a': if(dirn!=2){dirn=4;}
break;
case 's': if(dirn!=1){dirn=3;}
break;
case 'd': if(dirn!=4){dirn=2;}
break;
You can choose to omit the opening and closing braces for a switch statement only when you have only one case in your switch block as shown below:
void direction(char ch)
{
switch(ch)
case 'w': if(dirn!=3){dirn=1;}
}
But, if you have got multiple cases to deal with like in your case then you must enclose them inside a pair of opening and closing braces to create a code block for the switch statement as shown below:
void direction(char ch)
{
switch(ch)
{//opening brace for starting of statement block
case 'w': if(dirn!=3){dirn=1;}
break;
case 'a': if(dirn!=2){dirn=4;}
break;
case 's': if(dirn!=1){dirn=3;}
break;
case 'd': if(dirn!=4){dirn=2;}
break;
}//closing brace for closing of statement block
So you will have to either remove all the cases but one OR add the pair of braces to create statement block. In all other cases your code won't compile successfully.
You have forgotten the switch braces :
void direction(char ch)
{
switch(ch)
{
case 'w': if(dirn!=3){dirn=1;}
break;
case 'a': if(dirn!=2){dirn=4;}
break;
case 's': if(dirn!=1){dirn=3;}
break;
case 'd': if(dirn!=4){dirn=2;}
break;
}
}
switch statement requires braces block, where all labels including default one should be:
switch(ch)
{
case 'w': if(dirn!=3) dirn=1;
break;
case 'a': if(dirn!=2) dirn=4;
break;
case 's': if(dirn!=1) dirn=3;
break;
case 'd': if(dirn!=4) dirn=2;
break;
default:
break;
}
The statement after switch must be a compound statement to contain case, default and break. Break got a special meaning here, different from loops. If brace was omitted only next line after switch is part of its statement.

Weird output using a switch-statement [duplicate]

What is wrong with this code:
switch (n)
{
case 0: strcpy(resultString, "Zero");
case 1: strcpy(resultString, "One");
case 2: strcpy(resultString, "Two");
case 3: strcpy(resultString, "Three");
case 4: strcpy(resultString, "Four");
case 5: strcpy(resultString, "Five");
case 6: strcpy(resultString, "Six");
case 7: strcpy(resultString, "Seven");
case 8: strcpy(resultString, "Eight");
case 9: strcpy(resultString, "Nine");
}
printf("%s", resultString);
It always prints "Nine" no matter the value of n. What am I doing wrong??
You need a break statement at the end of each case. Otherwise control falls straight through to the next case.
Change your code to:
switch (n)
{
case 0: strcpy(resultString, "Zero");
break;
case 1: strcpy(resultString, "One");
break;
case 2: strcpy(resultString, "Two");
break;
case 3: strcpy(resultString, "Three");
break;
case 4: strcpy(resultString, "Four");
break;
case 5: strcpy(resultString, "Five");
break;
case 6: strcpy(resultString, "Six");
break;
case 7: strcpy(resultString, "Seven");
break;
case 8: strcpy(resultString, "Eight");
break;
case 9: strcpy(resultString, "Nine");
break;
}
printf("%s", resultString);
You can find the switch statement documented here or in any book on the C language.
You need to break after each case.
case 0:
do soemthing;
break;
case 1:
do something;
break;
In many managed languages, it won't let "one case fall through to another," and throws an error. But C loves to let you do whatever you want!
You missed break; after each case
Example :
case 0: strcpy(resultString, "Zero");break;
..
..
case 8: .... ; break;
..
From the standard :
6.4.2 The switch statement [stmt.switch]
case and default labels in themselves do not alter the flow of control, which continues unimpeded across such labels. To exit from a switch, see break (6.6.1).
6.6.1 The break statement [stmt.break]
The break statement shall occur only in an iteration-statement or a switch statement and causes termination of the smallest enclosing iteration-statement or switch statement; control passes to the statement following the terminated statement, if any.
That means that is you don't use break after each case, you program will enter in the first case who matches the condition and will continue executing every line of the switch until the end.
You should just do something like :
switch( n )
{
case 0:
// ...
break; // <- Note the break
//...
default:
// ...
}

Case Label Does Not reduce to integer constant

I'm not understanding why my switch statement is not working.
I've chopped it up since it was rather long, but the user is supposed to input a character to "selection1' & "selection2" and then I pass those as a parameter to my validSelection() function. The validSelection function is supposed to test the characters for the valid entries and deny all others by returning a boolean.
bool validSelection(char selection)
{
switch (selection)
{
case "R":
case "r":
case "P":
case "p":
case "S":
case "s":
return true;
default:
return false;
}
}
cin >> selection1;
cin >> selection2;
if (validSelection(selection1) && validSelection(selection2))
selection1 and selection2 both are char data types.
As #CaptainObvlious has already pointed out, anything between double-quotes "" is considered as string. However, you ant to pass the integer value to the switch. For the same, you have to put the characters inside single-quotes ''.
You may need to change our code as below.
bool validSelection(char selection)
{
switch (selection)
{
case 'R':
case 'r':
case 'P':
case 'p':
case 'S':
case 's':
return true;
default:
return false;
}
}

An if statement within a switch statement?

I'm having difficulties seeing why one way works and way doesn't.
I have;
switch (key)
{
//If Game over Label is visible, enable the m and e buttons
if(mGameOverLabel->GetVisible())
{
case 'm': case 'M':
ResetScreen();
break;
case 'e': case 'E':
// //Exit the game
Stop();
break;
} else {
case ' ':
mSpaceship->Shoot();
break;
default:
break;
}
For the case of the m and e, even though mGameOverLabel is set to false at this current time, I can still press M and E and these will react according to the methods, but If I change it to this for M it will then only work when I need it too. Am I missing something here?!
switch (key)
{
//If Game over Label is visible, enable the m and e buttons
case 'm': case 'M':
if(mGameOverLabel->GetVisible()) ResetScreen();
break;
}
The switch basically does a goto to the appropriate case label. Any logic above the case will not be executed.

simple cross-platform c++ GUI console -- how to?

I'm writing a game and I'm wound up in needing a console for simple text input; filenames and simple values.
Using SDL, my console looks the following at it's simplest:
class Console
{
public:
typedef std::list<String> InputList;
enum Result
{
NOTHING = 0,
ENTERED,
ESCAPED
};
static const String& GetInput() { return input; }
static Result Query(SDLKey lastKey)
{
if(lastResult == ENTERED || lastResult == ESCAPED)
{
input.clear();
}
switch (lastKey)
{
case SDLK_a:
case SDLK_b:
case SDLK_c:
case SDLK_d:
case SDLK_e:
case SDLK_f:
case SDLK_g:
case SDLK_h:
case SDLK_i:
case SDLK_j:
case SDLK_k:
case SDLK_l:
case SDLK_m:
case SDLK_n:
case SDLK_o:
case SDLK_p:
case SDLK_q:
case SDLK_r:
case SDLK_s:
case SDLK_t:
case SDLK_u:
case SDLK_v:
case SDLK_w:
case SDLK_x:
case SDLK_y:
case SDLK_z:
case SDLK_0:
case SDLK_1:
case SDLK_2:
case SDLK_3:
case SDLK_4:
case SDLK_5:
case SDLK_6:
case SDLK_7:
case SDLK_8:
case SDLK_9:
case SDLK_SLASH:
case SDLK_BACKSLASH:
case SDLK_PERIOD:
case SDLK_COMMA:
case SDLK_SPACE:
case SDLK_UNDERSCORE:
case SDLK_MINUS:
input += static_cast<char> (lastKey);
lastResult = NOTHING;
break;
case SDLK_RETURN:
lastResult = ENTERED;
break;
case SDLK_ESCAPE:
lastResult = ESCAPED;
break;
}
return lastResult;
}
protected:
static Result lastResult;
static String input;
};
This would be called from the application's main event loop, if the console is active and the last event was a keypress, then the result of the input is processed at a state where it's necessary.
Of course, it looks incredibly awkward... What's a better way to implement a simple console that can be easily rendered in my game's window? (Not going anywhere near to highly unportable solutions like having to reroute std::cout or writing code to bring up a UNIX console etc.)
One suggestion I would offer is to use if statements instead of a switch in this case:
if(lastKey == SDLK_RETURN)
lastResult = ENTERED;
else if(lastKey == SDLK_ESCAPE)
lastResult = ESCAPED;
else if(lastKey >= SDLK_SPACE && lastKey <= SDLK_z)
{
input += static_cast<char> (lastKey);
lastResult = NOTHING;
}
I took some liberties and included some characters that you didn't have in your code above, such as the ampersand, quotes, parentheses, brackets, etc. If you don't want those keys, you can add a few more if statements to break it down a bit more.
This assumes that the enum for the keys doesn't change a lot. If it does change a lot you may be better off with what you had.