[질문] 소스의 이해 ^^

naisr00t의 이미지


typedef unsigned char     M_Uint8;
typedef unsigned short    M_Uint16;
typedef unsigned int      M_Uint32;
typedef char     M_Int8;
typedef short    M_Int16;
typedef int      M_Int32;


#define READ16(ptr, pos)	(M_Int16)(*((M_Uint8*)ptr+pos) | (*((M_Uint8*)ptr+pos+1) << 8))
#define READ32(ptr, pos)	(M_Int32)(*((M_Uint8*)ptr+pos) | (*((M_Uint8*)ptr+pos+1) << 8) | (*((M_Uint8*)ptr+pos+2) << 16) | (*((M_Uint8*)ptr+pos+3) << 24))


int JarFile_getJarInfo(int fd, char* name, int* offset, int* compressed_size, int* uncompressd_size, int* compress_meth)
{
    char buf[22];
    char fileName[256];
    char* cBuf;
    int cDirSize, cDirOff, entryCount;
    int i , res, fnLen ;
    
    if ( lseek(fd, -22, SEEK_END) < 0 ) {
        return(-1);
    }

    read(fd, buf, 22);

    if (READ32(buf, 0) != 0x06054b50 ) {
        return(-1);
    }

    ...
    ...
    ... 

    for ( i = 0; i < entryCount ; i++ ) {
        *compress_meth = READ16(cBuf, 10);
        *compressed_size = READ32(cBuf, 20);
        *uncompressd_size = READ32(cBuf, 24);
    ...
    ...
    ...
    }

     ...
     ...
}

위의 코드가 있을 때, 이해가 도저히 안가는 부분이
READ16, READ32 함수를 부를 때 입니다. 어떻게 연산이 되는지 알려주시면 고맙겠습니다.

sodomau의 이미지

READ16과 READ32의 매크로 정의 부분을 보시면
됩니다.

간단히 READ16만 보면

#define READ16(ptr, pos)   (M_Int16)(*((M_Uint8*)ptr+pos) | (*((M_Uint8*)ptr+pos+1) << 8)) 

여기서 보면 ptr 포인터에서부터 pos번째 바이트와 그 다음 번째 바이트를 16 shift시킨 값을 | (or) operator로 16비트짜리 숫자로 합쳐버리는 작용을 하네요.

(M_Int16) (ptr+pos 위치의 바이트) | (ptr+pos+1 번째 바이트<<8)

코드는 리틀엔디안 기준이군요.

dyks의 이미지

sodomau wrote:
코드는 리틀엔디안 기준이군요.

리틀 엔디안 기준은 아니지 않나요?
빅 엔디안 <-> 리틀 엔디안 으로 바꾸는 매크로 같은데요.

원래 스트림이 빅 엔디안이면 리틀 엔디안으로, 반대의 경우엔 역시 반대로 바꾸는 매크로 아닌가요?

newmania의 이미지

endian 문제를 극복할 수 있도록 만들어둔 매크로라고 생각할 수 있겠네요.

sodomau의 이미지

C 코딩을 해 본지 하도 오래되어서-_-
테스트 함 해 봤습니다 -_-;;

$ cat test2.c
#include<stdio.h>

char buff[]={0x1,0x7f};
void main()
{
        printf("%d\n",*(short *)buff);
        printf("%d\n",(short)(buff[0] | buff[1]<<8));
}

sodomau@somakido ~
$ ./test2
32513
32513

little endian 기준이 맞습니다;

수정;;;;

어제밤에 하도 정신이 없어서;;

리틀 엔디안 기준이 아니라...
버퍼에 담겨있는 스트림만 리틀 엔디안이고
코드 자체는 빅엔디안이나 리틀 엔디안에서 모두 동일한 결과를
갖도록 사용가능하게 되어 있네요;

음;; 코딩 해 본지 정말 오래된 것 같은...;;

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.