Duff's device construction in C/C++/Java/PHP/Javascript

В 1983 году Томас Дуглас Дафф из Торонто во время оптимизации раскрутки одного цикла открыл необычную конструкцию на C:

switch(count%8){
case 0: do{ *to = *from++;
case 7:  *to = *from++;
case 6:  *to = *from++;
case 5:  *to = *from++;
case 4:  *to = *from++;
case 3:  *to = *from++;
case 2:  *to = *from++;
case 1:  *to = *from++;
  }while(--n>0);

Он обнаружил, что с выражением switch можно выделывать весьма хитрые фокусы. Пока вы соблюдаете синтаксис, вы можете вкладывать в выражение switch различные выражения выбора или итерации, что позволяет эффективно переходить в любую функцию или выходить из нее. Здесь можно ознакомиться с перепиской Даффа, где он рассказывает о своем открытии

Вот пара примеров:

// первая итерация начинается с определенной метки case
switch (num % 5) {
            case 0: do { i++;
            case 4:         i++;
            case 3:         i++;
            case 2:         i++;
            case 1:         i++;
                        }     while (--n > 0);

}

или так

switch (num % 2) {
    case 0:   do { std::cout << "num = " << num << std::endl;;
    case 1:           std::cout << "num = " << num << std::endl;;
                 }       while (--num > 0);

}

Причем все они компилируются и работают. Я встречал использование такого трюка в примерах написания так называемых сопрограмм, определяемых в макросах. Вот пример - msdn.
Стоит отметить, что данная особенность - при отсутствии break, управление внутри блока передаётся «вниз и насквозь» от инструкции, стоящей под одной меткой case, к инструкции, стоящей под следующей меткой case - характерна только для С и С++, в остальных языках мы будем получать предупреждения о синтаксической ошибке. Например, в Java компилятор будет ругаться на первой же метке case, так же ведет себя интерпретатор Javascript. Попытка проверки на PHP тоже завершилась сообщением интерпретатора об ошибке - Parse error: syntax error, unexpected 'case' (T_CASE).
Целесообразность и эффективность использования такой конструкции ставится под сомнение, сам Дафф в своей переписке - см. выше - указывает на ряд ограничений и слабой целесообразности такой конструкции. Но тем не менее, есть источники, указывающие на присутствие в коде реализации такой конструкции в протоколе SSH.
Think about it! 

NASM. Generate programms for DOS and Windows x86 OS

Ниже представлены примеры создания программ для таких систем как DOS и Windows x86 на ассемблере NASM. Создание приложения под DOS.
1. Cоздаем исходник hello.asm

SECTION .text

org 0x100

mov ah, 0x9
mov dx, hello
int 0x21

mov ah, 0x4c
mov al, 0
int 0x21

SECTION .data

hello db "Hello, world!", 0xd, 0xa, '$'

2. запускаем компилятор NASM nasm -f bin -o hello.com hello.asm
На выходе получаем hello.com, при запуске которого на консоль выведется всем нам привычное сообщение - Hello, world!


Создание приложения под Windows x86
1. Cоздаем исходник msgbox.asm

;подключение заголовочного файла (определяющий типы аргументов функций WinAPI)
%include "win32n.inc"

;объявление внешней функции MessageBoxA (идентификатор)
EXTERN MessageBoxA

;связывание объявленной функции с соответствующей динамической библиотекой
IMPORT MessageBoxA user32.dll

;объявление внешней функции ExitProcess
EXTERN ExitProcess

;связывание объявленной функции с соответствующей динамической библиотекой
IMPORT ExitProcess kernel32.dll

;секция (сегмент) кода
SECTION CODE USE32 CLASS=CODE ;метка для компоновщика, указывающая на точку входа

;передача аргументов производится согласно соглашению STDCAL
;аргументы передаются через стек в порядке справа налево (так же, как и в C)
;очистка стека входит в обязанности вызванной функции (аналогично языку Pascal)

;помещение в стек последнего аргумента отвечающего за тип окна (с единственной кнопкой - OK)
push UINT MB_OK

;помещение в стек указателя (адрес нуль-завершенной строки) на строку заголовка
push LPCTSTR title

;помещение в стек указателя на строку сообщения
push LPCTSTR banner

;помещение в стек аргумента указывающего на родительское окно в нашем случае оно отсутствует
push HWND NULL

;вызов функции Windows API - MessageBoxA 
call [MessageBoxA]

;аргумент ExitProcess - код возврата
push UINT NULL

;завершение процесса
call [ExitProcess] 

;секция статических данных
SECTION DATA USE32 CLASS=DATA

;строка сообщения с символом EOL
banner db 'Hello, world!', 0xD, 0xA, 0

;строка заголовка
title db 'Hello', 0
2. запускаем компилятор

nasm -fobj msgbox.asm

В результате получим объектный файл msgbox.obj, который нужно передать компоновщику alink

alink -oPE msgbox

Параметр -o определяет тип исполняемого файла (родным для Windows является тип PE). Как итог - на выходе исполняемый exe-файл - msgbox.exe




На последок немного дополнительной информации. Создание исполняемого файла состоит из двух этапов: компиляция и компоновка. На первом этапе - компиляция (трансляция) исходного кода программы в некоторый объектный формат. Объектный формат содержит машинный код программы, но символы (переменные и другие идентификаторы) в объектном файле пока не привязаны к адресам памяти. На втором этапе, который называется компоновкой или линковкой (linking), из одного или нескольких объектных файлов создается исполняемый файл. Процедура компоновки состоит в том, что компоновщик связывает символы, определенные в основной программе, с символами, которые определены в ее модулях (учитываются директивы EXTERN и GLOBAL), после чего каждому символу назначается окончательный адрес памяти или обеспечивается его динамическое вычисление.

Для выполнения данных примеров необходимо обратиться к следующим ресурсам:

https://sourceforge.net/projects/nasm - NASM ассемблер
http://alink.sourceforge.net/ - alink компоновщик
win32n.inc - подключаемый заголовочный файл, для вызовов Win API-функций

Всем хорошего дня, вечера или ночи ;)

PHP. Генератор случайных строковых значений

Здесь один нюанс: mt_rand() раза в 4 быстрее rand()

function generateRandomString($length = 10) {
        $randomString = "";
        $characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $min = 0;
        $max = strlen($characters) - 1;
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[mt_rand($min, $max)];
        }
        return $randomString;

}

PHP4/5. Works with directories

Ниже представлен небольшой пример, как можно получить внутреннюю структуру каталога. Для этого можно воспользоваться стандартным классом Directory:

function getCatalogStruct($path, array &$list) {
        $d = dir($path);
        while (false !== ($entry = $d->read())) {
            if (is_file($path."/".$entry)) {
                $list[] = $entry;
            }
            if (is_dir($path."/".$entry) && $entry !== "." && $entry !== "..") {
                $list[$entry] = array();
                getCatalogStruct($path."/".$entry."/", $list[$entry]);
            }
        }
        $d->close();
    }
   
    $catalogStruct = array();
    $path = "./debugMsg/";
   
    getCatalogStruct($path, $catalogStruct);
   
    echo "<pre>";
    print_r($catalogStruct);
    echo "</pre>";


Вот такая структурка на выходе:

Array
(
    [dir1] => Array
        (
            [subdir1] => Array
                (
                )

            [0] => subTestFile1.txt
            [1] => subTestFile2.txt
        )

    [dir2] => Array
        (
            [0] => subTestFile2.txt
        )

    [0] => testFile1.txt
    [1] => testFile2.txt
    [2] => testFile3.txt
    [3] => testFile4.txt
)

Jquery. Work with hidden iframes. Interaction between parent window and child iframes

Во время веб-разработки приходится решать различного рода задачи, во время решения некоторых из них прибегают к использованию так называемых фреймов - <iframe></iframe>
Внутри этих фреймов можно либо создать свои дополнительные DOM-элементы, например - добавить формы:

$(document).ready(function() {

    $('body').after('<iframe id="testIframe" width="1" height="1" align="center"></iframe>');
   
    $('#testIframe').load(function() {
        var form =     '<form id="testForm" action="test.php" method="post">' +
                        '<input type="text" name="testInput" value="testValue"/>' +
                    '</form>';
        $(this).contents().find('body').html(form);
    });
   
});


Здесь стоит оговориться: в Opera и Chrome этот пример не прокатит - форма так и не будет добавлена, нужно сразу же после создания фрейма добавлять свою форму (видимо это связано с тем, что в данном случае внутри фрейма документ пуст, ведь мы не указали через тег src на источник, поэтому метод $('#testIframe').load() не отработает должным образом)
Либо загружать другие документы. При этом не засоряется текущая структура документа. В большинстве случаев эти фреймы делают скрытыми, скрывая от глаз пользователей побочную работу веб-приложения. Но при этом встает вопрос: как можно общаться с дочерними фреймами. Если бы повсеместно использовался HTML5, то вопрос этот бы отпал, так как там есть методы для этих целей (window.postMessage). Но в настоящее время ситуация другая. Можно воспользоваться вот таким нехитрым способом. Во-первых, нам понадобится библиотека - jquery и дополнительный плагин к нему - jquery.form. А далее внутри создать форму, которая может обращаться к серверу. Перед отправкой данных на сервер необходимо передать эту форму методу упомянутого выше плагина ajaxForm. Этот метод позволит нам создать обработчик ответов сервера, что я и сделал, к тому же он доступен родительскому окну, точнее - документу. Так достигается своего рода общение между родительским документом и дочерними скрытыми фреймами:

$('#testButton').click(function(){
    var ref = $('#testIframe').contents().find('#testForm');
    // обработчик на стороне дочернего фрейма
    ref.ajaxForm(function(response) {
        if (response == 'catched') {
            // взаимодействие с "родителем"
            $('#result').html('<p>from testIframe1</p>');
        }
    });
    ref.submit();
}); 


В данных примерах я использую метод $('#testIframe').load(), который удобен тем, что в нем можно использовать свой callback, который будет вызываться только после полной загрузки документа внутри этого фрейма.    

Источник тестовых данных. Частотный список английских слов (7998)

На днях нужен был источник данных для проведения теста приложения. Казалось бы, можно было для этого воспользоваться списком английских слов из какого-либо справочника. Но так сразу найти его не удалось. Но все же такой источник был найден. Это список наиболее употребимых в речи и писменности английских слов. Всего слов - 7998. Источник представляет собой текстовый файлик с построчным распределением слов. Вот ссылка - download. Всем удачи :)