Beispiel #1
0
/**
 * Encoding to escape and unescape character to valid CDATA characters
 * -------------------------------------------------------------------
 *  Character  XML escape sequence  name
 * 
 *    '"'        """           quote
 *    '&'        "&"            amp
 *    '\''       "'"           apostrophe
 *    '<'        "&lt;"             lower than
 *    '>'        "&gt;"             greater than
 * -------------------------------------------------------------------
 */

static inline unsigned char* u_set_quot(unsigned char* restrict r)
{
   u_put_unalignedp32(r,   U_MULTICHAR_CONSTANT32('&','q','u','o'));
   u_put_unalignedp16(r+4, U_MULTICHAR_CONSTANT16('t',';'));

   return r + U_CONSTANT_SIZE("&quot;");
}

static inline unsigned char* u_set_amp(unsigned char* restrict r)
{
   u_put_unalignedp32(r, U_MULTICHAR_CONSTANT32('&','a','m','p'));

   r[4] = ';';

   return r + U_CONSTANT_SIZE("&amp;");
}

static inline unsigned char* u_set_apos(unsigned char* restrict r)
Beispiel #2
0
int URDBClientImage::handlerRead()
{
   U_TRACE(0, "URDBClientImage::handlerRead()")

   u_clientimage_flag.u = 0;

   if (UClientImage_Base::genericRead() == false)
      {
      if (U_ClientImage_state == U_PLUGIN_HANDLER_AGAIN) U_RETURN(U_NOTIFIER_OK); // NOT BLOCKING...

      U_INTERNAL_ASSERT_EQUALS(U_ClientImage_state, U_PLUGIN_HANDLER_ERROR)

      U_RETURN(U_NOTIFIER_DELETE);
      }

#ifdef U_LOG_ENABLE
   if (UClientImage_Base::logbuf)
      {
      *UClientImage_Base::request = *UClientImage_Base::rbuffer;

      UClientImage_Base::logRequest();
      }
#endif

   // check for RPC request

   URPC::resetInfo();

   if (URPC::readRequest(UClientImage_Base::socket) == false) U_RETURN(U_NOTIFIER_DELETE);

   UClientImage_Base::wbuffer->setBuffer(U_CAPACITY);

   // Process the RPC message

   int result;
   const char* res = STR_200;
   const char* ptr = UClientImage_Base::rbuffer->data();

   enum {
      RPC_METHOD_FIND               = U_MULTICHAR_CONSTANT32('F','I','N','D'),
      RPC_METHOD_STORE              = U_MULTICHAR_CONSTANT32('S','T','R','0'),
      RPC_METHOD_REPLACE            = U_MULTICHAR_CONSTANT32('S','T','R','1'),
      RPC_METHOD_REMOVE             = U_MULTICHAR_CONSTANT32('R','E','M','V'),
      RPC_METHOD_SUBSTITUTE0        = U_MULTICHAR_CONSTANT32('S','U','B','0'),
      RPC_METHOD_SUBSTITUTE1        = U_MULTICHAR_CONSTANT32('S','U','B','1'),
      RPC_METHOD_PRINT0             = U_MULTICHAR_CONSTANT32('P','R','T','0'),
      RPC_METHOD_PRINT1             = U_MULTICHAR_CONSTANT32('P','R','T','1'),
      RPC_METHOD_REORGANIZE         = U_MULTICHAR_CONSTANT32('R','O','R','G'),
      RPC_METHOD_BEGIN_TRANSACTION  = U_MULTICHAR_CONSTANT32('B','T','R','N'),
      RPC_METHOD_ABORT_TRANSACTION  = U_MULTICHAR_CONSTANT32('A','T','R','N'),
      RPC_METHOD_COMMIT_TRANSACTION = U_MULTICHAR_CONSTANT32('C','T','R','N')
   };

   switch (*(int32_t*)ptr)
      {
      case RPC_METHOD_FIND:
         {
         if (rdb->find((*URPC::rpc_info)[0]))
            {
            // Build the response: 200

            uint32_t size = rdb->data.dsize;

            (void) UClientImage_Base::wbuffer->reserve(U_TOKEN_LN + size);

            UStringExt::buildTokenInt(res = STR_200, size, *UClientImage_Base::wbuffer);

            (void) UClientImage_Base::wbuffer->append((const char*)rdb->data.dptr, size);
            }
         else
            {
            // Build the response: 400

            UStringExt::buildTokenInt(res = STR_400, 0, *UClientImage_Base::wbuffer);
            }
         }
      break;

      case RPC_METHOD_STORE:
      case RPC_METHOD_REPLACE:
         {
         // ------------------------------------------------------
         // Write a key/value pair to a reliable database
         // ------------------------------------------------------
         // RETURN VALUE
         // ------------------------------------------------------
         //  0: Everything was OK
         // -1: flag was RDB_INSERT and this key already existed
         // -3: disk full writing to the journal file
         // ------------------------------------------------------
         // #define RDB_INSERT  0 // Insertion of new entries only
         // #define RDB_REPLACE 1 // Allow replacing existing entries
         // ------------------------------------------------------

         result = rdb->store((*URPC::rpc_info)[0], (*URPC::rpc_info)[1], ptr[3] == '0' ? RDB_INSERT : RDB_REPLACE);

         switch (result)
            {
            case  0: res = STR_200; break; //  0: Everything was OK
            case -1: res = STR_401; break; // -1: flag was RDB_INSERT and this key already existed
            case -3: res = STR_500; break; // -3: disk full writing to the journal file
            }

         UStringExt::buildTokenInt(res, 0, *UClientImage_Base::wbuffer);
         }
      break;

      case RPC_METHOD_REMOVE:
         {
         // ---------------------------------------------------------
         // Mark a key/value as deleted
         // ---------------------------------------------------------
         // RETURN VALUE
         // ---------------------------------------------------------
         //  0: Everything was OK
         // -1: The entry was not in the database
         // -2: The entry was already marked deleted in the hash-tree
         // -3: disk full writing to the journal file
         // ---------------------------------------------------------

         result = rdb->remove((*URPC::rpc_info)[0]);

         switch (result)
            {
            case  0: res = STR_200; break; //  0: Everything was OK
            case -1: res = STR_400; break; // -1: The entry was not in the database
            case -2: res = STR_402; break; // -2: The entry was already marked deleted in the hash-tree
            case -3: res = STR_500; break; // -3: disk full writing to the journal file
            }

         UStringExt::buildTokenInt(res, 0, *UClientImage_Base::wbuffer);
         }
      break;

      case RPC_METHOD_SUBSTITUTE0:
      case RPC_METHOD_SUBSTITUTE1:
         {
         // ----------------------------------------------------------
         // Substitute a key/value with a new key/value (remove+store)
         // ----------------------------------------------------------
         // RETURN VALUE
         // ----------------------------------------------------------
         //  0: Everything was OK
         // -1: The entry was not in the database
         // -2: The entry was marked deleted in the hash-tree
         // -3: disk full writing to the journal file
         // -4: flag was RDB_INSERT and the new key already existed
         // ----------------------------------------------------------

         // #define RDB_INSERT  0 // Insertion of new entries only
         // #define RDB_REPLACE 1 // Allow replacing existing entries

         result = rdb->substitute((*URPC::rpc_info)[0], (*URPC::rpc_info)[1], (*URPC::rpc_info)[2], ptr[3] == '0' ? RDB_INSERT : RDB_REPLACE);

         switch (result)
            {
            case  0: res = STR_200; break; //  0: Everything was OK
            case -1: res = STR_400; break; // -1: The entry was not in the database
            case -2: res = STR_402; break; // -2: The entry was marked deleted in the hash-tree
            case -3: res = STR_500; break; // -3: disk full writing to the journal file
            case -4: res = STR_401; break; // -4: flag was RDB_INSERT and the new key already existed
            }

         UStringExt::buildTokenInt(res, 0, *UClientImage_Base::wbuffer);
         }
      break;

      case RPC_METHOD_PRINT0:
      case RPC_METHOD_PRINT1:
         {
         // Build the response: 200

         UString tmp = (ptr[3] == '0' ? rdb->print() : rdb->printSorted());

         UStringExt::buildTokenInt(res = STR_200, tmp.size(), *UClientImage_Base::wbuffer);

         UClientImage_Base::wbuffer->append(tmp);
         }
      break;

      case RPC_METHOD_REORGANIZE:
         {
         res = (rdb->reorganize() ? STR_200 : STR_500);

         UStringExt::buildTokenInt(res, 0, *UClientImage_Base::wbuffer);
         }
      break;

      case RPC_METHOD_BEGIN_TRANSACTION:
         {
         res = (rdb->beginTransaction() ? STR_200 : STR_500);

         UStringExt::buildTokenInt(res, 0, *UClientImage_Base::wbuffer);
         }
      break;

      case RPC_METHOD_ABORT_TRANSACTION:
         {
         rdb->abortTransaction();

         UStringExt::buildTokenInt(res = STR_200, 0, *UClientImage_Base::wbuffer);
         }
      break;

      case RPC_METHOD_COMMIT_TRANSACTION:
         {
         rdb->commitTransaction();

         UStringExt::buildTokenInt(res = STR_200, 0, *UClientImage_Base::wbuffer);
         }
      break;

      default:
         {
         UStringExt::buildTokenInt(res = STR_500, 0, *UClientImage_Base::wbuffer);
         }
      break;
      }

   U_SRV_LOG_WITH_ADDR("method %.4S return %s for", ptr, res);

   return UClientImage_Base::handlerResponse();
}