NSIS-ka
A free C++ implementation of NSIS protocols

Changeset 4588


Ignore:
Timestamp:
Oct 20, 2009, 2:00:25 PM (8 years ago)
Author:
roehricht
Message:
  • Adaptations of QSPEC's Common Header format according to draft version 21
  • Some code beautifications
  • Modified SVN keywords to yield also Rev
File:
1 edited

Legend:

Unmodified
Added
Removed
  • qspec/branches/20091020-qspec-to-v21/src/qspec_pdu.cpp

    • Property svn:keywords changed from Id HeadURL to Id HeadURL Rev
    r3236 r4588  
    138138 *
    139139 * Extract the QSPEC type from a raw header. The header
    140  * is expected to be in host byte order already.
     140 * is expected to be in host byte order already according to
     141 *
     142 *  0                   1                   2                   3
     143 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     144 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     145 * |  Vers.|I|QSPECType|r|r|  QSPEC Proc.  |        Length         |
     146 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    141147 *
    142148 * @param header_raw 32 bits from a NetMsg
     
    144150 */
    145151uint16 qspec_pdu::extract_qspec_type(uint32 header_raw) throw () {
    146         return ( (header_raw >> 24) & 0x0F );
     152        return ((header_raw >> 22) & 0x1F);
    147153}
    148154
     
    151157 * Initialize the object from the given NetMsg.
    152158 *
    153  * The object returns itself if the deserializing was successful. No new
    154  * object is created.
     159 * The object returns itself if the deserialization was successful. No
     160 * new object is created.
    155161 *
    156162 * Note: QSPEC Template doesn't contain a length field for the whole
     
    165171
    166172#ifdef BIG_HACK
    167         int i;
    168173        hack_len = msg.get_bytes_left();
    169174        hack_buf = new uint8[hack_len];
    170         i = 0;
    171         Log(ERROR_LOG, LOG_CRIT, "BIG", "HACK " << hack_len);
     175        int i = 0;
     176        ERRCLog("BIG", "HACK " << hack_len);
    172177        while (msg.get_bytes_left()) {
    173178                hack_buf[i++] = msg.decode8();
     
    179184
    180185        /*
    181          * Parse the QSPEC header.
     186         * Parse the QSPEC header
     187         *   0                   1                   2                   3
     188         *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     189         *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     190         *  |  Vers.|I|QSPECType|r|r|  QSPEC Proc.  |        Length         |
     191         *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    182192         */
    183193        uint32 header_raw;
     
    185195        try {
    186196                header_raw = msg.decode32();
    187         }
    188         catch ( NetMsgError ) {
     197        } catch (NetMsgError) {
    189198                catch_bad_alloc( errorlist.put(
    190                         new IEMsgTooShort(coding, get_category(), start_pos)) );
    191 
    192                 return ( skip ? this : NULL ); // We can't go on from here.
    193         }
    194 
    195         set_version( header_raw >> 28 );
    196 
    197         set_qspec_type( extract_qspec_type(header_raw) );
    198 
    199         set_msg_sequence( (header_raw >> 20) & 0xF );
    200         set_obj_combination( (header_raw >> 16) & 0xF );
     199                        new IEMsgTooShort(coding, get_category(), start_pos)));
     200                return (skip ? this : NULL); // We can't go on from here
     201        }
     202
     203        set_version(header_raw >> 28);
     204
     205        set_qspec_type(extract_qspec_type(header_raw));
     206
     207        /*
     208         * QSPEC procedure is split into
     209         *  0 1 2 3 4 5 6 7
     210         * +-+-+-+-+-+-+-+-+
     211         * |Mes.Sq |Obj.Cmb|
     212         * +-+-+-+-+-+-+-+-+
     213         */
     214        set_msg_sequence((header_raw >> 16) & 0xF);
     215        set_obj_combination((header_raw >> 12) & 0xF);
    201216
    202217        // check for I flag
    203         local_QSPEC= ( header_raw & (1 << 15)) ? true : false;
     218        local_QSPEC = (header_raw & (1 << 27)) ? true : false;
    204219
    205220        // length in units of 32-bit words excluding the common header
    206         uint16 qspec_total_len= header_raw & 0xFFF;
    207         uint32 qspec_total_len_bytes= 4 * qspec_total_len;
     221        uint16 qspec_total_len = header_raw & 0xFFF;
     222        uint32 qspec_total_len_bytes = 4 * qspec_total_len;
    208223
    209224        // TODO: check msg_sequence and obj_combination
     
    213228
    214229        /*
    215          * Read as many objects from the body as possible.
     230         * Read as many objects from the body as possible
    216231         */
    217232        IEManager *mgr = QSPEC_IEManager::instance();
    218         uint32 obj_bytes_read= 0;
     233        uint32 obj_bytes_read = 0;
    219234        uint32 saved_pos = msg.get_pos();
    220         while ( (msg.get_bytes_left() > 0) && (qspec_total_len_bytes > 0) ) {
     235        while ((msg.get_bytes_left() > 0) && (qspec_total_len_bytes > 0)) {
    221236                saved_pos = msg.get_pos();
    222237
     
    224239                                errorlist, obj_bytes_read, skip);
    225240
    226                 // Deserializing failed.
    227                 if ( ie == NULL )
     241                // Deserializing failed
     242                if (ie == NULL)
    228243                        return NULL;
    229244
     
    231246
    232247                /*
    233                  * Error: no qspec_object returned.
     248                 * Error: no qspec_object returned
    234249                 */
    235                 if ( obj == NULL ) {
    236                         Log(ERROR_LOG, LOG_CRIT, "qspec_pdu",
    237                                 "deserialize() returned object of type "
     250                if (obj == NULL) {
     251                        ERRCLog("qspec_pdu", "deserialize() returned object of type "
    238252                                << ie->get_ie_name()
    239253                                << " but type qspec_object expected. "
     
    244258
    245259                // test for duplicate object
    246                 if ( get_object( obj->get_object_id() ) != NULL ) {
    247                         catch_bad_alloc( errorlist.put(
     260                if (get_object( obj->get_object_id() ) != NULL) {
     261                        catch_bad_alloc(errorlist.put(
    248262                                new PDUSyntaxError(coding, get_category(),
    249263                                        obj->get_object_id(), 0,
    250                                         saved_pos, "Duplicate object")) );
    251 
    252                         if ( ! skip )
     264                                        saved_pos, "Duplicate object")));
     265
     266                        if (!skip)
    253267                                return NULL;
    254268                }
     
    260274        } // end while
    261275
    262         if ( qspec_total_len_bytes != 0  )
     276        if (qspec_total_len_bytes != 0)
    263277          ERRCLog("qspec_pdu", "deserialize(): qspec length mismatch, bytes left=" << qspec_total_len_bytes
    264278                  << ", total length from PDU=" << 4 * qspec_total_len);
    265279
    266280        // empty QSPECs are not allowed
    267         if ( get_num_objects() == 0 ) {
    268                 catch_bad_alloc( errorlist.put(
     281        if (get_num_objects() == 0) {
     282                catch_bad_alloc(errorlist.put(
    269283                        new PDUSyntaxError(coding, get_category(), 0, 0,
    270                                 start_pos, "QSPEC may not be empty")) );
    271 
    272                 if ( ! skip )
     284                                start_pos, "QSPEC may not be empty")));
     285
     286                if (!skip)
    273287                        return NULL;
    274288        }
    275289
    276290        // this would be an implementation error
    277         if ( bytes_read != msg.get_pos() - start_pos )
    278           ERRCLog("qspec_pdu", "deserialize(): byte count mismatch, bytes_read=" << bytes_read << " buffer pos read:" << msg.get_pos() - start_pos);
     291        if (bytes_read != msg.get_pos() - start_pos)
     292          ERRCLog("qspec_pdu", "deserialize(): byte count mismatch, bytes_read="
     293                          << bytes_read << " buffer pos read:"
     294                          << msg.get_pos() - start_pos);
    279295#endif
    280296
     
    307323                        bytes_written++;
    308324                }
    309                 Log(ERROR_LOG, LOG_CRIT, "BIG", "HACK " << hack_len <<
     325                ERRCLog("BIG", "HACK " << hack_len <<
    310326                        ", " << bytes_written);
    311327                return;
     
    321337
    322338        /*
    323          * Write QSPEC header.
     339         * Write QSPEC header
    324340         *    0                   1                   2                   3
    325341         *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    326342         *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    327          *   |  Vers.|Q.Type |  QSPEC Proc.  |I|R|R|R|      Length           |
     343         *   |  Vers.|I|QSPECType|r|r|  QSPEC Proc.  |        Length         |
    328344         *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    329          *
     345         *                           +-+-+-+-+-+-+-+-+
     346         * QSPEC procedure           |Mes.Sq |Obj.Cmb|
     347         *                           +-+-+-+-+-+-+-+-+
    330348         */
    331         uint32 header_raw = (get_version() << 28) | (get_qspec_type() << 24)
    332                 | (get_msg_sequence() << 20) | (get_obj_combination() << 16)
    333                 | (is_local_qspec() << 15);
     349        uint32 header_raw = (get_version() << 28) | (get_qspec_type() << 23)
     350                | (get_msg_sequence() << 16) | (get_obj_combination() << 12)
     351                | (is_local_qspec() << 27);
    334352
    335353        // encode qspec pdu length as number of 32-bit words, excluding the common header
    336         uint32 qspec_pdu_length= get_serialized_size(protocol_v1);
     354        uint32 qspec_pdu_length = get_serialized_size(protocol_v1);
    337355        // substract header length
    338356        if (qspec_pdu_length >= qspec_pdu::HEADER_LENGTH)
    339           qspec_pdu_length -= qspec_pdu::HEADER_LENGTH;
     357                qspec_pdu_length -= qspec_pdu::HEADER_LENGTH;
    340358        // encode length
    341         if ( (qspec_pdu_length / 4) > 0xFFF )
    342           ERRCLog("qspec_pdu", "serialize(): length too large for 12 bit" << qspec_pdu_length / 4);
    343 
    344         header_raw |= ( (qspec_pdu_length / 4) & 0xFFF );
     359        if ((qspec_pdu_length / 4) > 0xFFF)
     360                ERRCLog("qspec_pdu", "serialize(): length too large for 12 bit "
     361                                << qspec_pdu_length / 4);
     362
     363        header_raw |= ((qspec_pdu_length / 4) & 0xFFF);
    345364
    346365        try {
    347366                msg.encode32(header_raw);
    348367                bytes_written += 4;
    349         }
    350         catch (NetMsgError) {
     368        } catch (NetMsgError) {
    351369                throw IEMsgTooShort(coding, get_category(), msg.get_pos());
    352370        }
     
    354372
    355373        /*
    356          * Write the body: Serialize each object.
     374         * Write the body: Serialize each object
    357375         */
    358         for ( obj_iter i = objects.begin(); i != objects.end(); i++ ) {
     376        for (obj_iter i = objects.begin(); i != objects.end(); i++) {
    359377                const IE *obj = i->second;
    360378
     
    366384
    367385        // this would be an implementation error
    368         if ( bytes_written != msg.get_pos() - start_pos )
    369           ERRCLog("qspec_pdu", "serialize(): byte count mismatch, bytes_written=" << bytes_written << " buffer pos written=" << msg.get_pos() - start_pos);
     386        if (bytes_written != msg.get_pos() - start_pos)
     387          ERRCLog("qspec_pdu", "serialize(): byte count mismatch, bytes_written="
     388                          << bytes_written << " buffer pos written="
     389                          << msg.get_pos() - start_pos);
    370390}
    371391
     
    375395       
    376396        // Error: no objects available or invalid IDs
    377         if ( objects.size() == 0 || (get_qspec_type() & ~0xF) != 0
     397        if (objects.size() == 0 || (get_qspec_type() & ~0xF) != 0
    378398                        || (get_msg_sequence() & ~0xF) != 0
    379                         || (get_obj_combination() & ~0xF) != 0 )
     399                        || (get_obj_combination() & ~0xF) != 0)
    380400                return false;
    381401
    382402        // Check all objects for errors.
    383         for ( obj_iter i = objects.begin(); i != objects.end(); i++ ) {
     403        for (obj_iter i = objects.begin(); i != objects.end(); i++) {
    384404                const IE *obj = i->second;
    385405
    386                 if ( obj->check() == false )
     406                if (obj->check() == false)
    387407                        return false;
    388408        }
Note: See TracChangeset for help on using the changeset viewer.