Skip to content

Commit

Permalink
* base64 decode
Browse files Browse the repository at this point in the history
* PeerNote class for representing return Message from ListPeerNotes and ModifyPeerNote



git-svn-id: file:///home/toad/git-migration/temprepository/trunk/apps/CppFCPLib@14308 67a373e5-eb02-0410-a15c-ee090a768436
  • Loading branch information
mkolar committed Jul 24, 2007
1 parent 3a7b5e1 commit ee75741
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 41 deletions.
123 changes: 123 additions & 0 deletions Base64.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@

#include "Base64.h"

using FCPLib::Base64;
using FCPLib::IllegalBase64Exception;

const char Base64::base64Alphabet[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '~', '-'};

const char Base64::base64Dealphabet[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62,
255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, 255, 255, 255, 255, 255, 255, 255, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 255, 255, 255, 255, 255 };


std::string
Base64::base64Encode(const unsigned char *in, int len)
{
std::string out(((len+2)/3)*4, '=');
int o = 0;
for (int i = 0; i < len;) {
int val = (in[i++] & 0xFF) << 16;
if (i < len)
val |= (in[i++] & 0xFF) << 8;
if (i < len)
val |= (in[i++] & 0xFF);
out[o++] = base64Alphabet[(val>>18) & 0x3F];
out[o++] = base64Alphabet[(val>>12) & 0x3F];
out[o++] = base64Alphabet[(val>>6) & 0x3F];
out[o++] = base64Alphabet[val & 0x3F];
}
return out;
}

std::string
Base64::base64Decode(const std::string inStr)
{
const char *in = inStr.c_str();
int inLength = inStr.size();

// Strip trailing equals signs.
while ((inLength > 0) && (in[inLength-1] == '='))
inLength--;

// check if all characters are valid
for (int i = 0; i < inLength; ++i)
if( !( isalpha(in[i]) || isdigit(in[i]) || in[i] == '~' || in[i] == '-' ) )
throw IllegalBase64Exception("illegal Base64 character");

int blocks = inLength/4;
int remainder = inLength & 3;
// wholeInLen and wholeOutLen are the the length of the input and output
// sequences respectively, not including any partial block at the end.
int wholeInLen = blocks*4;
int wholeOutLen = blocks*3;
int outLen = wholeOutLen;
switch (remainder) {
case 1: throw IllegalBase64Exception("illegal Base64 length");
case 2: outLen = wholeOutLen+1; break;
case 3: outLen = wholeOutLen+2; break;
default: outLen = wholeOutLen;
}
std::string out(outLen, ' ');
int o = 0;
int i;
for (i = 0; i < wholeInLen;) {
int in1 = base64Dealphabet[(int)in[i]];
int in2 = base64Dealphabet[(int)in[i+1]];
int in3 = base64Dealphabet[(int)in[i+2]];
int in4 = base64Dealphabet[(int)in[i+3]];
int orValue = in1|in2|in3|in4;
if ((orValue & 0x80) != 0)
throw IllegalBase64Exception("illegal Base64 character");
int outVal = (in1 << 18) | (in2 << 12) | (in3 << 6) | in4;
out[o] = (char) (outVal>>16);
out[o+1] = (char) (outVal>>8);
out[o+2] = (char) outVal;
i += 4;
o += 3;
}
int orValue = 0;
switch (remainder) {
case 2:
{
int in1 = base64Dealphabet[(int)in[i]];
int in2 = base64Dealphabet[(int)in[i+1]];
orValue = in1|in2;
int outVal = (in1 << 18) | (in2 << 12);
out[o] = (char) (outVal>>16);
}
break;
case 3:
{
int in1 = base64Dealphabet[(int)in[i]];
int in2 = base64Dealphabet[(int)in[i+1]];
int in3 = base64Dealphabet[(int)in[i+2]];
orValue = in1|in2|in3;
int outVal = (in1 << 18) | (in2 << 12) | (in3 << 6);
out[o] = (char) (outVal>>16);
out[o+1] = (char) (outVal>>8);
}
break;
}
if ((orValue & 0x80) != 0)
throw IllegalBase64Exception("illegal Base64 character");
return out;
}
42 changes: 11 additions & 31 deletions Base64.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,23 @@
#define BASE64_H_INCLUDED

#include <string>
#include <stdexcept>

namespace FCPLib {

class Base64 {
static char base64Alphabet[];

class IllegalBase64Exception : public std::logic_error {
public:
static std::string base64Encode(unsigned char *, int);
IllegalBase64Exception(std::string str) : std::logic_error(str) {}
};

char Base64::base64Alphabet[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '~', '-'};

std::string
Base64::base64Encode(unsigned char *in, int len)
{
std::string out(((len+2)/3)*4, '=');
int o = 0;
for (int i = 0; i < len;) {
int val = (in[i++] & 0xFF) << 16;
if (i < len)
val |= (in[i++] & 0xFF) << 8;
if (i < len)
val |= (in[i++] & 0xFF);
out[o++] = base64Alphabet[(val>>18) & 0x3F];
out[o++] = base64Alphabet[(val>>12) & 0x3F];
out[o++] = base64Alphabet[(val>>6) & 0x3F];
out[o++] = base64Alphabet[val & 0x3F];
}
return out;
}
class Base64 {
const static char base64Alphabet[];
const static char base64Dealphabet[];
public:
static std::string base64Encode(const unsigned char *, int);
static std::string base64Decode(const std::string);
};

}

Expand Down
1 change: 1 addition & 0 deletions FCPLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@

#include "Node.h"
#include "FCPResult.h"


#endif // FCPLIB_H_INCLUDED
44 changes: 44 additions & 0 deletions FCPResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
#include <vector>
#include <string>
#include <algorithm>
#include <boost/lexical_cast.hpp>

#include "JobTicket.h"
#include "Base64.h"

namespace FCPLib {

Expand Down Expand Up @@ -51,6 +53,26 @@ class TestDDAResponse {
bool writeDirectory;
};

class PeerNote {
public:
PeerNote( Message::Ptr m )
: nodeIdentifier( m->getField("NodeIdentifier") ),
noteText( Base64::base64Decode( m->getField("NoteText") ) ),
peerNoteType( boost::lexical_cast<int>(m->getField("PeerNoteType")) )
{}
std::string nodeIdentifier;
std::string noteText;
int peerNoteType;

std::string toString() const {
return "NodeIdentifier="+nodeIdentifier+"\n"+
"NodeText="+noteText+"\n"+
"PeerNoteType="+boost::lexical_cast<std::string>(peerNoteType)+"\n";
}
};

typedef std::vector<PeerNote> PeerNoteContainer;

///////////

struct GetMessage {
Expand Down Expand Up @@ -105,6 +127,28 @@ struct TestDDAReplyConverter {
}
};

struct PeerNotesConverter {
PeerNoteContainer
operator()( Response &resp )
{
PeerNoteContainer ret;
int size = resp.size() - 1;
Response::iterator end = resp.begin() + size;
for (Response::iterator it = resp.begin(); it != end; ++it)
ret.push_back( PeerNote( (*it)->getMessage() ) );
return ret;
}
};

struct PeerNoteConverter {
PeerNote
operator()( Response &resp )
{
return PeerNote( resp.front()->getMessage() );
}
};


//////////

template<typename ReturnT, typename ConverterT>
Expand Down
10 changes: 5 additions & 5 deletions Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Node::listPeers(const AdditionalFields& fields)
return createResult<MessagePtrContainer, VectorWithoutLastConverter>( resp );
}

MessagePtrContainer
PeerNoteContainer
Node::listPeerNotes(const std::string& identifier)
{
Message::Ptr m = Message::factory( std::string("ListPeerNotes") );
Expand All @@ -126,7 +126,7 @@ Node::listPeerNotes(const std::string& identifier)
// ProtocolError or UnknownNodeIdentifier
checkProtocolError(resp); // throws

return createResult<MessagePtrContainer, VectorWithoutLastConverter>( resp );
return createResult<PeerNoteContainer, PeerNotesConverter>( resp );
}

Message::Ptr
Expand Down Expand Up @@ -193,15 +193,15 @@ Node::modifyPeer(const std::string & nodeIdentifier,
return createResult<Message::Ptr, MessageConverter>( resp );
}

Message::Ptr
PeerNote
Node::modifyPeerNote(const std::string & nodeIdentifier,
const std::string & noteText,
int peerNoteType = 1)
{
Message::Ptr m = Message::factory( std::string("ModifyPeerNote") );

m->setField("NodeIdentifier", nodeIdentifier);
m->setField("NoteText", noteText);
m->setField("NoteText", Base64::base64Encode((const unsigned char*)noteText.c_str(), noteText.size()));
m->setField("PeerNoteType", "1"); // TODO: change to peerNoteType once it is used

JobTicket::Ptr job = JobTicket::factory( "", m, false);
Expand All @@ -214,7 +214,7 @@ Node::modifyPeerNote(const std::string & nodeIdentifier,
// ProtocolError or UnknownNodeIdentifier
checkProtocolError(resp); // throws

return createResult<Message::Ptr, MessageConverter>( resp );
return createResult<PeerNote, PeerNoteConverter>( resp );
}

Message::Ptr
Expand Down
4 changes: 2 additions & 2 deletions Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ class Node {

Message::Ptr listPeer(const std::string &);
MessagePtrContainer listPeers(const AdditionalFields& = AdditionalFields());
MessagePtrContainer listPeerNotes(const std::string&);
PeerNoteContainer listPeerNotes(const std::string&);
Message::Ptr addPeer(const std::string &, bool isURL);
Message::Ptr addPeer(const std::map<std::string, std::string> &message);
Message::Ptr modifyPeer(const std::string &, const AdditionalFields& = AdditionalFields());
Message::Ptr modifyPeerNote(const std::string &, const std::string &, int);
PeerNote modifyPeerNote(const std::string &, const std::string &, int);
Message::Ptr removePeer(const std::string &);
Message::Ptr getNode(const AdditionalFields& = AdditionalFields());
Message::Ptr getConfig(const AdditionalFields& = AdditionalFields());
Expand Down
6 changes: 3 additions & 3 deletions examples/list_peer_notes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ int main( int argc, char* argv[]) {

Node n("List Peer Notes Test", "", -1);

MessagePtrContainer peer_notes = n.listPeerNotes(argv[1]);
PeerNoteContainer peer_notes = n.listPeerNotes(argv[1]);

for (MessagePtrContainer::iterator it = peer_notes.begin();
for (PeerNoteContainer::iterator it = peer_notes.begin();
it != peer_notes.end();
++it) {
std::cout << (*it)->toString() << std::endl;
std::cout << it->toString() << std::endl;
std::cout << std::endl;
}
n.shutdown();
Expand Down

0 comments on commit ee75741

Please sign in to comment.