quinta-feira, 19 de março de 2009

Sobre APIs

Umas das coisas mais importantes em programação, sem a qual ninguém consegue desevolver, é API.

API – Interface de Programação de Aplicativos – é o conjunto de recursos de que o programador dispõe para desenvolver suas aplicações.

Este artigo faz uma comparação – na verdade, mais uma demonstração – de cinco APIs muito usadas: IEEE 1003, STL, OpenStep, GLib e Java.

Para a demonstração será usado um trecho de código para ler a primeira linha de um arquivo.

Por que não a API do Windows?


Antes de começar, é preciso esclarecer por que não a API do Windows.

O objetivo de uma API é oferecer um ambiente homogêneo de programação, para que o programador não seja obrigado a reaprender a mesma coisa diversas vezes. Para facilitar isso, muitas APIs ainda podem ser usadas em diversas linguagens diferentes, outras em apenas uma.

No entanto uma API que funciona apenas em um único sistema operacional – ou ainda no grupo de sistemas operacionais de uma única empresa – não está fazendo seu trabalho, por mais usado que esse(s) sistema(s) possa ser.

Assim a API do Windows não faz mais do que se espera da interface de um sistema operacional.

É claro que é necessário que o Windows possua uma API, mesmo que seja exclusivamente para conexão de outras APIs mais universais.

IEEE 1003 (POSIX)


O padrão POSIX, definido pela IEEE, oferece uma interface completa para sistemas compatíveis com UNIX. Alguns exemplos são IBM AIX, Solaris, GNU (e daí também Linux), BSD, Mac OS X, MS Xenix e muitos outros.

O trecho de código em C para ler a primeira linha de um arquivo:
FILE *fd = fopen(filename, "r");

if (fd) {
while (!eof(fd)) {
char buf;
fread(&buf, sizeof(char), 1, fd);
printf("%c", buf);
if (buf == '\n')
break;
}

fclose(fd);
}


Observação1: é preciso incluir o cabeçalho stdio.h ou, em C++, cstdio:
#include <stdio.h>


Observação2: a variável filename é do tipo const char *.

Observação3: foi preciso procurar ocorrência do carácter \n pois POSIX não ofereça uma função de alto nível para ler uma linha.

Observação4: o padrão POSIX é completamente procedimental – as demais APIs citadas aqui são orientadas a objetos –, sendo um pouco desajeitado para algumas operações.

STL


A linguagem de programação C++ possui uma biblioteca padrão própria bastante completa chamada STL – Standard Library.

Para o exemplo, é preciso incluir o cabeçalho fstream para a manipulação de arquivo e o cabeçalho iostream para a exibição dos dados na tela:
std::ifstream fd(filename);

if (fd.is_open()) {
char buf[1024];
fd.getline(buf, 1023);

std::cout << buf << std::endl;
fd.close();
}


Observação1: como citado acima, é preciso incluir pelo menos o cabeçalho fstream ao manipular arquivos:
#include <fstream>


Observação2: a variável filename precisa ser do tipo const char *std::ifstream não suporta std::string.

OpenStep


A empresa NeXT de Steve Jobs, ora adquirida pela Apple, abriu a API de seu sistema operacional em 1992 num acordo com a SUN Microsystems, sob o nome de OpenStep, o que permitiu, além da criação de aplicações de terceiros para NeXTSTEP, também o desenvolvimento de outros sistemas operacionais compatíveis com sua API e APIs de programação para sistemas já existentes, tornando-os compatíveis com OpenStep.

Exemplos de sistemas compatíveis com essa API são Mac OS X e GNUstep (portável para Windows e qualquer plataforma compatível com POSIX).

A API OpenStep funciona exclusivamente em Objective-C, apesar de haver alguns portes para outras linguagens, como C++, Smalltalk e Guile Scheme.

Vamos ao exemplo em Objective-C:
id fd = [NSFileHandle fileHandleForReadingAtPath: filename];

if (fd != nil) {
char buf = 0;
[fd seekToEndOfFile];
unsigned long long eof = [fd offsetFile];
[fd seekToFileOffset: 0];

while (([fd offsetInFile] < eof) && (buf != '\n')) {
[[fd readDataOfLength: 1] getBytes: &buf length: 1];
printf("%c", buf);
}

[fd closeFile];
}


Observação1: é preciso importar o cabeçalho Foundation.h:
#import <Foundation/Foundation.h>


Observação2: a variável filename precisa ser do tipo NSString.

Observação3: eu não conheço um método para ler uma linha de um arquivo em OpenStep, portanto usei um esquema similar ao usado acima em POSIX.

GLib


A GLib começou como parte do toolkit gráfico Gtk+ na versão 2.0, tendo evoluído para se tornar uma API multiplataforma orientada a objetos completa e independente da interface gráfica.

Você pode usar GLib em qualquer sistema POSIX e em Windows.

A maior curiosidade da GLib é que ela deixa explícita o equívoco – ou a falácia – de quem crê que não seja possível programar orientado a objetos em uma linguagem não orientada a objetos: é escrita em C e completamente orientada a objetos.

Aliás a base da GLib é o GObject que, curiosamente, não é compatível com a estrutura de orientação a objetos de C++ e outras linguagens clássicas, apesar de haver portes para C++ e outras.

O exemplo a seguir é um trecho de código em Vala, linguagem criada expecificamente para a GLib:
var file = File.new_for_path(filename);

if (file.query_exists(null)) {
try {
var fd = new DataInputStream(file.read(null));
stdout.printf("%s\n", fd.read_line(null, null));
fd.close(null);
} catch (Error e) {
// Ignora exceções
}
}


[update 2009-03-19]Faltou o close.[/update]

Observação1: é preciso «usar» GLib:
using GLib;


Observação2: a variável filename é do tipo string – equivalente em C a GString e gchar *.

Observação3: é preciso usar o pacote (--pkg) gio-2.0, que importa GIO, recursos de I/O da GLib.

Java


Em sua linguagem de programação, a SUN Microsystems optou por criar uma API própria (bem complicada e verborrágica em relação às demais, diga-se).
BufferedReader fd = null;
try {
fd = new BufferedReader(new FileReader(filename));
System.out.println(fd.readLine());

} catch (Exception e) {
// Ignora exceções

} finally {
try {
if (fd != null)
fd.close();
} catch (IOException e) {
// Ignora exceções
}
}


Observação1: as classes usadas estão no pacote java.io:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;


Observação2: a variável filename é do tipo String.


**

Fica aqui a dica de três APIs interessantes.

[]'s
Cacilhas, La Batalema
blog comments powered by Disqus