반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

지난 글까지는 pdf 의 내용을 바이너리로 받아서 이걸 obj별로 나누고 다시 stream 별로 나눈 값을 getObjectOptions() 로 보내서 그 값을 다시 여러 정규식으로 나누고 공백으로 나누고 뭐 그런 처리를 한 값을 return 하는 것까지 했습니다.


이제 getObjectOptions() 함수에서 던져준 값을 adf2text() 함수내에서 받아서 어떤 처리를 해 줘야 할 텐데요.

여기서는 받은 값으로 맨 처음 Length1, Type, Subtype 요소가 그 안에 있는지 여부를 체크합니다.

PHP 의 empty() 함수를 이용해서 체크하네요.

Length1, Type, Subtype 값들은 맨 처음 글에서 본 Hello World PDF 의 바이너리 파일에서 보면 <<, >> 안에 들어있는 텍스트 입니다.

여기서 continue; 를 사용했는데요. 예제를 보고 이해해 보죠.


<?php
for ($i 0$i 5; ++$i) {
    if (
$i == 2)
        continue
    print 
"$i\n";
}
?>


이렇게 하면 뭐가 나올까요? 정답은 2 입니다.

if 문에서 true 가 아니면 그 아래는 실행하지 않고 다시 loop 문으로 갑니다.

그러니까 우리가 공부하는 소스의 내용을 보면 Length1 과 Type 이 비어있지 않고 Subtype 이 비어있는 경우에만 아래 내용을 실행하고 그렇지 않으면 이 값은 무시되서 for 루프문으로 돌아갑니다.

아마 Length1 과 Type 이 있고 Subtype 이 없는 경우가 실제 Text 로 처리할 내용인가 봅니다.

이렇게 해서 얻어진 값을 getDecodedStream() 함수로 보냅니다.

실제 Text 로 처리할 내용만 담았으니까 이제 이것을 바이너리에서 사람이 읽을 수 있는 형식으로 바꿔야 겠죠. 그 작업을 하는 함수가 getDecodedStream() 인가 봅니다.

이 함수에는 파라미터로 $stream 과 $options 를 던져 줍니다.

$stream 은 pdf2text() 함수에서 만든 값이고 $options 는 이전 글인 getObjectOptions() 함수에서 만든 값이죠?

이 두 값을 getDecodedStream()으로 보내는데  이 함수에서는 구체적으로 무엇을 할까요?


Twilight O.S.T 인 Decode 를 부른 Paramore 입니다. :)


function getDecodedStream($stream, $options) {
    $data = "";
    if (empty($options["Filter"]))
        $data = $stream;
    else {
        $length = !empty($options["Length"]) ? $options["Length"] : strlen($stream);
        $_stream = substr($stream, 0, $length);

        foreach ($options as $key => $value) {
            if ($key == "ASCIIHexDecode")
                $_stream = decodeAsciiHex($_stream);
            if ($key == "ASCII85Decode")
                $_stream = decodeAscii85($_stream);
            if ($key == "FlateDecode")
                $_stream = decodeFlate($_stream);
        }
        $data = $_stream;
    }
    return $data;
}


여기서는 우선 $options["Filter"] 를 체크해서 없으면 $data 에 $stream 을 넣습니다.

이 $data 가 나중에 return 할 값입니다.

그리고 Filter 가 있으면 else 구문을 실행하는데요.

$options["Length"] 가 있으면 $options["Length"] 를 없으면 $stream 의 길이를 $length 에 넣습니다.

여기서 Length 는 데이터의 길이이고 이미 PDF 바이너리 파일 안에 있습니다.

그 다음에 문자열을 다룰 때 가장 많이 사용되는 substr() 함수가 나오는데요.
아래 예제를 보시면 금방 이해가 되실 겁니다.


<?php
echo substr('abcdef'1);     // bcdef
echo substr('abcdef'13);  // bcd
echo substr('abcdef'04);  // abcd
echo substr('abcdef'08);  // abcdef
echo substr('abcdef', -11); // f

// Accessing single characters in a string
// can also be achieved using "square brackets"
$string 'abcdef';
echo 
$string[0];                 // a
echo $string[3];                 // d
echo $string[strlen($string)-1]; // f

?>


설명은 굳이 달지 않을께요. 아주 자주 쓰이고 또 쉬운거니까요.



다시 공부하던 소스로 돌아가면 $stream 을 처음부터 $length 까지만 잘라서 $_stream 에 넣네요. 즉 딱 데이터 부분만 $_stream 에 담는 겁니다.

그 다음에는 $options 배열 수만큼 foreach 문을 돌리는데요.

이 값이 ASCIIHexDecode 이면 decodeAsciiHex() 메소드를 사용하고 ASCII85Decode 이면 decodeAscii85() 메소드를 사용하고 FlateDecode 이면 decodeFlate() 메소드를 사용해서 $_stream 을 디코딩 하는 겁니다.


지금까지 한 일은 이 디코딩 메소드로 데이터를 돌려서 사람이 읽을 수 있는 텍스트로 뽑아내기 위해서 딱 그 데이터 부분만 분리하는 작업을 한 겁니다.


이제 본격적으로 데이터를 디코딩 하는 함수를 볼 차레네요.

이 부분은 집중해서 자세히 보고 싶군요.

다음 글에서 하나하나 분석해 보도록 하겠습니다.


그래서 제가 저희 회사 식당 Menu PDF 에 있는 데이터를 제대로 필요한 내용만 추출해서 어떻게 사용할 수 있는지 찾아낼 수 있도록요.

이 식당 Menu PDF 가 한가지만 있으면 좋은데 텍사스, 켄터키, 메사추세츠 등 등 여러 지역에 또 여러 도시에 나눠져 있어서 10개가 넘거든요.

각 빌딩의 chef 들이 조금씩 편집을 해서 올리기 때문에 어떤 공통된 패턴을 찾아내기가 어렵더라구요.


하여간 다음 글에서 이 바이너리 파일을 디코딩하는 소스를 세밀하게 분석해 보겠습니다.


반응형