#include <cstdlib>
#include <vector>
#include <unordered_map>
#include <string>
#include <algorithm>
#include <iostream>
int main (void)
{
/* Even if a std::string was used, a string literal would not work, because
the fake packet contains '\0'. */
//const std::vector<char> msg{"add@/sys/devices\0SUBSYSTEM=block\0DEVTYPE=partition"};
const std::vector<char> msg{
'a','d','d','@','/','s','y','s','/','d','e','v','i','c','e','s','\0',
'S','U','B','S','Y','S','T','E','M','=','b','l','o','c','k','\0','D',
'E','V','T','Y','P','E','=','p','a','r','t','i','t','i','o','n','\0'
};
std::unordered_map<std::string , std::string> hotplug_event_variables;
auto it1 = std::find( msg.begin() , msg.end() , '@' );
if ( it1 != msg.end() )
{
/* As per the kernel documentation, the piece before the '@' token is
the implicit "ACTION" event variable. */
hotplug_event_variables.emplace( std::piecewise_construct , std::forward_as_tuple("ACTION") , std::forward_as_tuple(msg.begin(),it1) );
/* It points to the '@'; increment it. */
++it1;
auto it2 = std::find( it1 , msg.end() , '\0' );
if ( it2 != msg.end() )
{
/* As with the previous event variable, DEVPATH is implicit. */
hotplug_event_variables.emplace( std::piecewise_construct , std::forward_as_tuple("DEVPATH") , std::forward_as_tuple(it1,it2) );
/* It points to the '\0'; increment it. */
++it2;
/*
* An example packet:
*
* Pass of the loop
* |$ACTION@$DEVPATH0·····=·····0······=······0|
* ^^ ^^ ^ ^^ ^ ^
* it1 it2 | || | |
* #1 it2 it3 it4 | |
* #2 it2 it3 it4
*/
for ( auto it3 = std::find( it2 , msg.end() , '=' ) , it4 = std::find( it3+1 , msg.end() , '\0') ; it2 != msg.end() , it3 != msg.end() , it4 != msg.end() ; it2 = it4+1 , it3 = std::find( it2 , msg.end() , '=' ) , it4 = std::find( it3 , msg.end() , '\0' ) )
{
/* While playing with the fake packet, I found that empty pairs
could made it into the map. */
if ( std::distance(it2,it3) > 0 && std::distance(it3+1,it4) > 0 )
{
hotplug_event_variables.emplace( std::piecewise_construct , std::forward_as_tuple(it2,it3) , std::forward_as_tuple(it3+1,it4) );
}
}
/*
* Expected output:
*
* "ACTION" = "add"
* "DEVPATH" = "/sys/devices"
* "SUBSYSTEM" = "block"
* "DEVTYPE" = "partition"
*/
for ( const auto & x : hotplug_event_variables )
{
std::cout << '"' << x.first << "\" = \"" << x.second << "\"\n";
}
}
}
return EXIT_SUCCESS;
}
I2luY2x1ZGUgPGNzdGRsaWI+CgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKCmludCBtYWluICh2b2lkKQp7CgkvKiBFdmVuIGlmIGEgc3RkOjpzdHJpbmcgd2FzIHVzZWQsIGEgc3RyaW5nIGxpdGVyYWwgd291bGQgbm90IHdvcmssIGJlY2F1c2UKCXRoZSBmYWtlIHBhY2tldCBjb250YWlucyAnXDAnLiAqLwoJLy9jb25zdCBzdGQ6OnZlY3RvcjxjaGFyPiBtc2d7ImFkZEAvc3lzL2RldmljZXNcMFNVQlNZU1RFTT1ibG9ja1wwREVWVFlQRT1wYXJ0aXRpb24ifTsKCWNvbnN0IHN0ZDo6dmVjdG9yPGNoYXI+IG1zZ3sKCQknYScsJ2QnLCdkJywnQCcsJy8nLCdzJywneScsJ3MnLCcvJywnZCcsJ2UnLCd2JywnaScsJ2MnLCdlJywncycsJ1wwJywKCQknUycsJ1UnLCdCJywnUycsJ1knLCdTJywnVCcsJ0UnLCdNJywnPScsJ2InLCdsJywnbycsJ2MnLCdrJywnXDAnLCdEJywKCQknRScsJ1YnLCdUJywnWScsJ1AnLCdFJywnPScsJ3AnLCdhJywncicsJ3QnLCdpJywndCcsJ2knLCdvJywnbicsJ1wwJwoJfTsKCQoJc3RkOjp1bm9yZGVyZWRfbWFwPHN0ZDo6c3RyaW5nICwgc3RkOjpzdHJpbmc+IGhvdHBsdWdfZXZlbnRfdmFyaWFibGVzOwoJCglhdXRvIGl0MSA9IHN0ZDo6ZmluZCggbXNnLmJlZ2luKCkgLCBtc2cuZW5kKCkgLCAnQCcgKTsKCWlmICggaXQxICE9IG1zZy5lbmQoKSApCgl7CgkJLyogQXMgcGVyIHRoZSBrZXJuZWwgZG9jdW1lbnRhdGlvbiwgdGhlIHBpZWNlIGJlZm9yZSB0aGUgJ0AnIHRva2VuIGlzCgkJdGhlIGltcGxpY2l0ICJBQ1RJT04iIGV2ZW50IHZhcmlhYmxlLiAqLwoJCWhvdHBsdWdfZXZlbnRfdmFyaWFibGVzLmVtcGxhY2UoIHN0ZDo6cGllY2V3aXNlX2NvbnN0cnVjdCAsIHN0ZDo6Zm9yd2FyZF9hc190dXBsZSgiQUNUSU9OIikgLCBzdGQ6OmZvcndhcmRfYXNfdHVwbGUobXNnLmJlZ2luKCksaXQxKSApOwoJCQoJCS8qIEl0IHBvaW50cyB0byB0aGUgJ0AnOyBpbmNyZW1lbnQgaXQuICovCgkJKytpdDE7CgkJCgkJYXV0byBpdDIgPSBzdGQ6OmZpbmQoIGl0MSAsIG1zZy5lbmQoKSAsICdcMCcgKTsKCQlpZiAoIGl0MiAhPSBtc2cuZW5kKCkgKQoJCXsKCQkJLyogQXMgd2l0aCB0aGUgcHJldmlvdXMgZXZlbnQgdmFyaWFibGUsIERFVlBBVEggaXMgaW1wbGljaXQuICovCgkJCWhvdHBsdWdfZXZlbnRfdmFyaWFibGVzLmVtcGxhY2UoIHN0ZDo6cGllY2V3aXNlX2NvbnN0cnVjdCAsIHN0ZDo6Zm9yd2FyZF9hc190dXBsZSgiREVWUEFUSCIpICwgc3RkOjpmb3J3YXJkX2FzX3R1cGxlKGl0MSxpdDIpICk7CgkJCQoJCQkvKiBJdCBwb2ludHMgdG8gdGhlICdcMCc7IGluY3JlbWVudCBpdC4gKi8KCQkJKytpdDI7CgkJCQoJCQkvKgoJCQkgKiBBbiBleGFtcGxlIHBhY2tldDoKCQkJICoKCQkJICogUGFzcyBvZiB0aGUgbG9vcAoJCQkgKiAgICAgICAgICAgICAgICAgICB8JEFDVElPTkAkREVWUEFUSDDCt8K3wrfCt8K3PcK3wrfCt8K3wrcwwrfCt8K3wrfCt8K3PcK3wrfCt8K3wrfCtzB8CgkJCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgXl4gICAgICAgXl4gICAgXiAgICAgXl4gICAgIF4gICAgICBeCgkJCSAqICAgICAgICAgICAgICAgICAgICAgICAgICBpdDEgICAgICBpdDIgICAgfCAgICAgfHwgICAgIHwgICAgICB8CgkJCSAqICMxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdDIgICBpdDMgICBpdDQgICAgIHwgICAgICB8CgkJCSAqICMyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQyICAgaXQzICAgIGl0NAoJCQkqLwoJCQlmb3IgKCBhdXRvIGl0MyA9IHN0ZDo6ZmluZCggaXQyICwgbXNnLmVuZCgpICwgJz0nICkgLCBpdDQgPSBzdGQ6OmZpbmQoIGl0MysxICwgbXNnLmVuZCgpICwgJ1wwJykgOyBpdDIgIT0gbXNnLmVuZCgpICwgaXQzICE9IG1zZy5lbmQoKSAsIGl0NCAhPSBtc2cuZW5kKCkgOyBpdDIgPSBpdDQrMSAsIGl0MyA9IHN0ZDo6ZmluZCggaXQyICwgbXNnLmVuZCgpICwgJz0nICkgLCBpdDQgPSBzdGQ6OmZpbmQoIGl0MyAsIG1zZy5lbmQoKSAsICdcMCcgKSApCgkJCXsKCQkJCS8qIFdoaWxlIHBsYXlpbmcgd2l0aCB0aGUgZmFrZSBwYWNrZXQsIEkgZm91bmQgdGhhdCBlbXB0eSBwYWlycwoJCQkJY291bGQgbWFkZSBpdCBpbnRvIHRoZSBtYXAuICovCgkJCQlpZiAoIHN0ZDo6ZGlzdGFuY2UoaXQyLGl0MykgPiAwICYmIHN0ZDo6ZGlzdGFuY2UoaXQzKzEsaXQ0KSA+IDAgKQoJCQkJewoJCQkJCWhvdHBsdWdfZXZlbnRfdmFyaWFibGVzLmVtcGxhY2UoIHN0ZDo6cGllY2V3aXNlX2NvbnN0cnVjdCAsIHN0ZDo6Zm9yd2FyZF9hc190dXBsZShpdDIsaXQzKSAsIHN0ZDo6Zm9yd2FyZF9hc190dXBsZShpdDMrMSxpdDQpICk7CgkJCQl9CgkJCX0KCQkJCgkJCS8qCgkJCSAqIEV4cGVjdGVkIG91dHB1dDoKCQkJICoKCQkJICogIkFDVElPTiIgICAgPSAiYWRkIgoJCQkgKiAiREVWUEFUSCIgICA9ICIvc3lzL2RldmljZXMiCgkJCSAqICJTVUJTWVNURU0iID0gImJsb2NrIgoJCQkgKiAiREVWVFlQRSIgICA9ICJwYXJ0aXRpb24iCgkJCSovCgkJCWZvciAoIGNvbnN0IGF1dG8gJiB4IDogaG90cGx1Z19ldmVudF92YXJpYWJsZXMgKQoJCQl7CgkJCQlzdGQ6OmNvdXQgPDwgJyInIDw8IHguZmlyc3QgPDwgIlwiID0gXCIiIDw8IHguc2Vjb25kIDw8ICJcIlxuIjsKCQkJfQoJCX0KCX0KCQoJcmV0dXJuIEVYSVRfU1VDQ0VTUzsKfQ==