From c78cf71acc1e1d100805f4ed72ba7f7c04c80562 Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Wed, 5 Jun 2019 16:44:11 +0200 Subject: [PATCH] On the fly --- src/engine/Any.cxx | 126 ++++++++++++++++++++++++++++++---------- src/engine/Any.hxx | 3 +- src/engine_swig/pilot.i | 20 +++++++ 3 files changed, 118 insertions(+), 31 deletions(-) diff --git a/src/engine/Any.cxx b/src/engine/Any.cxx index 70458bddc..a3c5cfa6b 100644 --- a/src/engine/Any.cxx +++ b/src/engine/Any.cxx @@ -38,47 +38,113 @@ using namespace std; // forbidden value int=-269488145 double=-1.54947e+231 bool=239 const char SeqAlloc::DFT_CHAR_VAR=-17;//0xEF -std::string YACS::ENGINE::ToBase64(const std::string& bytes) +constexpr unsigned NB_BITS = 6; + +constexpr unsigned char TAB[64]={46, 61, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122}; + +unsigned char BitAtPosSimple(char val, std::size_t bitPos) { - std::string input(bytes); - // The input must be in multiples of 3, otherwise the transformation - // may overflow the input buffer, so pad with zero. - size_t num_pad_chars((3 - input.size() % 3) % 3); - input.append(num_pad_chars, 0); + return (val >> bitPos) & 0x1; +} - // Transform to Base64 with line breaks every 76 characters - using namespace boost::archive::iterators; - typedef insert_linebreaks >, 76> ItBase64T; - std::string output(ItBase64T(input.begin()), ItBase64T(input.end() - num_pad_chars)); +unsigned char BitAtPos(char pt0, char pt1, std::size_t bitPos) +{ + if(bitPos<8) + return BitAtPosSimple(pt0,bitPos); + else + return BitAtPosSimple(pt1,bitPos-8); +} - // Pad blank characters with '=' - output.append(num_pad_chars, '='); +unsigned char ChunkInternal(char pt0, char pt1, std::size_t startBitIdInByte) +{ + unsigned char ret(0); + for(unsigned i = 0; i>= 1; + return ret; +} - return output; +unsigned char ChunkAtPos(const char *pt, std::size_t len, std::size_t posChunk) +{ + std::size_t startByte((posChunk*NB_BITS)/8); + std::size_t startBitIdInByte((posChunk*NB_BITS)%8); + char pt1(startByte!=len-1?pt[startByte+1]:pt[startByte]); + return ChunkInternal(pt[startByte],pt1,startBitIdInByte); } -std::string YACS::ENGINE::FromBase64(const std::string& base64Str) +std::size_t OnOff(std::size_t i) { - std::string input(base64Str); - using namespace boost::archive::iterators; - typedef transform_width >, 8, 6> ItBinaryT; - - try + if(i!=0) + return 1; + return 0; +} + +std::string YACS::ENGINE::ToBase64(const std::string& bytes) +{//64 == 2**6 + const char *bytesPt(bytes.c_str()); + std::size_t input_len(bytes.size()); + std::size_t input_len_bit(input_len*8); + std::size_t nb_chunks( input_len_bit/NB_BITS + OnOff((NB_BITS - input_len_bit%NB_BITS)%NB_BITS) ); + std::string ret(nb_chunks,'\0'); + for(std::size_t i=0;i> 5-bitPos) & 0x1; +} + +char BitAtPosOnChunk(char pt0, char pt1, std::size_t bitPos) +{ + if(bitPos<6) + return BitAtPosSimple2(pt0,bitPos); + else + return BitAtPosSimple2(pt1,bitPos-6); +} + +char ByteInternal(char c0, char c1, std::size_t startBitIdInByte) +{ + unsigned char ret(0); + char ct0(TAB2[(unsigned char)c0]),ct1(TAB2[(unsigned char)c1]); + for(int i = 7; i>=0; --i) { - return std::string(); + ret |= BitAtPosOnChunk(ct0,ct1,startBitIdInByte+i); + if(i!=0) + ret <<= 1; } + return ret; +} + +char ByteAtPos(const char *chunckPt, std::size_t bytePos) +{ + std::size_t startChunk((bytePos*8)/NB_BITS); + std::size_t startBitId((bytePos*8)%NB_BITS); + return ByteInternal(chunckPt[startChunk],chunckPt[startChunk+1],startBitId); +} + +std::string YACS::ENGINE::FromBase64(const std::string& bytes) +{ + std::size_t nb_chunks(bytes.size()); + const char *chunckPt(bytes.c_str()); + std::size_t nb_bytes_output((nb_chunks*NB_BITS)/8); + std::string ret(nb_bytes_output,'\0'); + for(std::size_t i = 0; i