Java замена для макросов C - PullRequest
1 голос
/ 18 марта 2011

Недавно я провел рефакторинг кода хэш-функции стороннего производителя с C ++ на C. Процесс был относительно безболезненным, с некоторыми изменениями. Теперь я хочу написать ту же функцию на Java, и у меня возникла небольшая проблема.

В коде C / C ++ есть макрос препроцессора C, который принимает несколько целочисленных имен переменных в качестве аргументов и выполняет несколько побитовых операций со своим содержимым и несколькими константами. Этот макрос используется в нескольких разных местах, поэтому его присутствие позволяет избежать частого дублирования кода.

Однако в Java нет аналога для препроцессора Си. Также нет никакого способа повлиять на любой базовый тип, передаваемый в качестве аргумента методу - даже автобокс создает неизменяемые объекты. В связи с тем, что методы Java возвращают одно значение, я не могу найти простой способ переписать макрос.

Проспекты, которые я рассматривал:

  • Разверните макрос вручную везде: Это будет работать, но дублирование кода может сделать вещи интересными в долгосрочной перспективе.

  • Напишите метод, который возвращает массив: Это также будет работать, но это будет неоднократно приводить к коду, подобному этому:

    long tmp[] = bitops(k, l, m, x, y, z);
    
    k = tmp[0];
    l = tmp[1];
    m = tmp[2];
    x = tmp[3];
    y = tmp[4];
    z = tmp[5];
    
  • Напишите метод, который принимает массив в качестве аргумента : это будет означать, что все имена переменных будут сокращены до ссылок на элементы массива - было бы довольно сложно отследить, какой индекс соответствует к какой переменной.

  • Создайте отдельный класс, например State с открытыми полями соответствующего типа и использовать это в качестве аргумента метода : Это мое текущее решение. Это позволяет методу изменять переменные, сохраняя их имена. Однако недостатком является то, что класс State будет становиться все более и более сложным по мере добавления большего количества макросов и переменных, чтобы избежать копирования значений назад и вперед среди различных State объектов.

Как бы вы переписали такой макрос C в Java? Есть ли более подходящий способ справиться с этим, используя средства, предоставляемые стандартным Java 6 Development Kit (т.е. без сторонних библиотек или отдельного препроцессора)?

Ответы [ 2 ]

3 голосов
/ 18 марта 2011

Вариант 3, создайте свой собственный класс-оболочку MutableInteger.

struct MutableInteger{
  public MutableInteger(int v) { this.value = value;}
  public int value;
}

public void swap3( MutableInteger k, MutableInteger l, MutableInteger m) {
  int t = m.value;
  m.value = l.value
  l.value=k.value;
  k.value=t;
}
1 голос
/ 18 марта 2011

Создайте отдельный класс, например State с открытыми полями соответствующего типа, и используйте его в качестве аргумента для метода

Это, но в качестве промежуточного шага.Затем продолжите рефакторинг - в идеале класс State должен иметь private полей.Замените макросы методами для обновления этого состояния.Затем замените весь остальной код на методы, которые обновляют состояние, пока в конечном итоге ваша программа не будет выглядеть следующим образом:

System.out.println(State(System.in).hexDigest());

Наконец, переименуйте State в SHA1 или что-то еще; -)

...