The source is now being hosted at both GitHub and my personal TsundereGit.
https://github.com/Frederick888/php-bencode
https://git.tsundere.moe/Frederick888/php-bencode

From Wikipedia
Bencode is the encoding used by the peer-to-peer file sharing system BitTorrent for storing and transmitting loosely structured data.

Apart from the “torrent” files, it is also used to store local data in some BitTorrent clients instead of other lightweight databases such as SQLite. However, if one gets hundreds of torrents, decoding the file would be extremely slow by some pure PHP libraries. This is why I decided to implement a PHP extension to boost the process.

There is an existed extension on Google Code, which you can also find an exportation to GitHub with some patches. But it seems that it can only parse a Bencode into plain array or convert an array back which may cause data loss during the conversion, e.g. empty arrays or lists.

Bencode should be handled by objects. But I can hardly find any introductions about handling objects in a PHP extension (reading the header file may be a better choice but it may cost a little long). Then I found PHP-CPP, which is quite friendly to new PHP extension developers. It’s a pity that it cannot be packed as a PECL package but it would be easy to build a binary package instead.

The development is not finished yet and I’m considering adding more useful features. Also, there may be lots of redundant codes to clean up 😉

“vcgencmd” is a useful command on Raspberry Pi provided by Raspbian.

By taking advantage of this command, users can easily get the temperature of Pi, check the frequency of CPU and etc. There’re many options for this command but it lacks a bash completion script. So I wrote one based on the document by elinux.

Here it is. Place it under /etc/bash_completion.d/. (Download: vcgencmd-complete.zip)

_vcgencmd () {
    local cur prev commands opts_clock opts_volts opts_codec opts_config opts_mem opts_display
    commands=$(vcgencmd commands)
    commands=${commands:10:${#commands}-11}
    commands="${commands//,} commands"
    opts_clock="arm core h264 isp v3d uart pwm emmc pixel vec hdmi dpi "
    opts_clock="45  1    28   42  43  22   25  47   29    10  9    4 ""$opts_clock"
    opts_volts="core sdram_c sdram_i sdram_p"
    opts_codec="H264 MPG2 WVC1 MJPG WMV9"
    opts_config="int str
        arm_freq
        config_hdmi_boost
        core_freq
        disable_commandline_tags
        disable_l2cache
        emmc_pll_core
        force_eeprom_read
        force_pwm_open
        framebuffer_ignore_alpha
        framebuffer_swap
        hdmi_force_cec_address
        over_voltage
        over_voltage_avs
        overscan_bottom
        overscan_left
        overscan_right
        overscan_top
        pause_burst_frames
        program_serial_random
        sdram_freq
        temp_limit"
    opts_mem="arm gpu"
    opts_display="0 1"

    COMPREPLY=()
    cur=$(_get_cword)
    prev=${COMP_WORDS[COMP_CWORD-1]}

    case "$prev" in
        "vcgencmd")
            COMPREPLY=($(compgen -W "$commands" "$cur"))
            ;;
        "measure_clock")
            COMPREPLY=($(compgen -W "$opts_clock" "$cur"))
            ;;
        "measure_volts")
            COMPREPLY=($(compgen -W "$opts_volts" "$cur"))
            ;;
        "codec_enabled")
            COMPREPLY=($(compgen -W "$opts_codec" "$cur"))
            ;;
        "get_config")
            COMPREPLY=($(compgen -W "$opts_config" "$cur"))
            ;;
        "get_mem")
            COMPREPLY=($(compgen -W "$opts_mem" "$cur"))
            ;;
        "display_power")
            COMPREPLY=($(compgen -W "$opts_display" "$cur"))
            ;;
    esac

    return 0
}
complete -F _vcgencmd vcgencmd