대사 스크립터기 작업을 꽤 미루고 미루다가 다시 손을 댔다.
음 1주일 정도 만에 다시 잡은 것 같다.
바로 메모리 공간과 길이 때문이였다.
한글hex(가칭) 창은 일본어 기준으로 메모리가 확보되어 있는 곳이다.
예를 들어 100 이라고 가정을 해보자.
이 100개 중에서 3번~10번 이 곳을 고처야 된다고 할때, 공간은 7 이다.
그렇징 -_-??;; 당연히 여기에는 일본어로 모라고 써있을 껏이다.
물론 그 길이(공간)은 7이다.
이를테면 "01あうz" 이런식으로 말이다. 일본어는 2Byte를 먹는다. 한글도 마찬가지로 2Byte를 먹는다. 영문과 숫자, 공백은 1Byte이다. 이건 컴터쪽에 관심이 조금만 있어도 다 아는 거지??
그런데 저 부분을 "안녕하세요" 라고 고처야 된다고 치자 ㅡㅡ;; (너무 억지인가)
"안녕하세요" 은 10Byte가 필요하다. 위에서 말했다시피 여기에 할당된 공간은 7이다.
그럼 3Byte가 모질라다. -_-;; 그러면 어떻게 해야 될까??
어떻게 하긴...끼어 넣어야지.. ㅡㅡ;;
쉽게 예를 들면, 사람들이 길게 줄을 서있다. 그 중간에 친구가 있다.
나는 친구 뒤로 낑겨서 들어간다. 그럼 어떻게 될까??
사람들은 모두 한두발 정도 뒤로 물러날 것이다.
왜냐면 내가 친구 뒤쪽으로 들어가면 그 만큼 뒤로 밀려나가지 않는가
그럼 이걸 숫자로 보자. 3~10 사이라고 했다. 여기에 "10" 을 낑겨 넣으면
[ 3~13 ] 이렇게 바뀌겠지??
그런데 아쉽게도, 컴퓨터는 이렇게 못한다. 낑겨넣는건 못하고 "덮어씌우기" 만 할 뿐이다.
그렇다면 다른 데이터를 침범하게 된다. 그것도 3Byte씩이나...
데이터를 옆으로 밀어주려면 엄청나게 골치 아프다.
컴퓨터는 한번에 한가지 일 밖에 못한다.
그러므로 데이터를 뒤로 밀려면 너무 엽기적이다. ㅡㅡ;; 위에서 100번까지 있다고 했다.
100번 데이터를 101번으로 카피한다.
99번 데이터를 100번으로 카피한다.
98번 데이터를 99번으로 카피한다.
97번 데이터를 98번으로 카피한다.
96번 데이터를 97번으로 카피한다.
.
.
.
미친짓이다. ㅡ_ㅡ;; 실제로 이렇게 데이터 카피를 하는 사람은 없을 것이다.
물론 소량에 데이터라 한다면 저렇게 해도 크게 무리가 없겠지만...
어쨌든 이런 이유로 나는 잠시간 대사 스크립트 작업에 손을 안 대고 있었다.
뭐 기획서도 써야 했고....오늘은 한숨 자고 일어나자마자 시작했다.
7시부터 11시까지 했으니 꽤 했지??
내가 생각한 알고리즘은 이러하다.
1. 현재 공간과, 수정된 공간을 비교한다. 비교해서 두 공간이 같을 경우
그대로 카피한다. (이런 일은 거의 없겠지만 혹시나 해서-_-)
2. 수정된 공간이 현재 공간보다 크다면 -> 뒤쪽 공간을 제서 다시 카피한다.
3. 수정된 공간이 현재 공간보다 작다면 -> 마찬가지로 뒤쪽 공간을 제서 당겨준다.
지금은 "크다면" 처리 밖에 못했다. 이거 처리도 완전히 끝낸 상태는 아니다.
그럭저럭 돌아가지만 몇가지 버그가 있다. 그걸 내일 수정해야 된담.
공간의 길이를 제고 밀고 당기는 알고리즘은 이러하다.
수정해야될 부분을 중심으로 앞/뒤를 나눈다.
"앞/수정해야될부분/뒤" 이런 모습이 된다.
이렇게 3등분 한 후에 "앞/수정한 데이터/뒤" 이렇게 바꾸어 주는 것이다.
앞+수정한데이터의 길이를 젠다.
그리고 원래데이터 - (앞+수정해야될부분)을 하게 되면 "뒤" 부분의 길이가 나온다.
그럼 이제 새로운 메모리 공간을 잡는다. 각각의 길이를 모두 구했으니 메모리를 효율적으로
정확하게 잡을 수 있다. 앞+수정한데이터를 먼저 집에 넣고,
그 뒤에 "뒤" 데이터를 이어 붙인다.
이렇게 한 뒤에 마지막으로 중요한 것이 하나 있다.
지금 새로운 메모리 공간을 만들었다. 그걸 New라고 하고 그 전에 수정되기 전 데이터를 가지고 있던 원본을 Old라고 해두자.
이 Old는 전역 변수이다. 그렇기 때문에 다른 곳에서는 이 Old가 중심이 된다.
즉 현재 수정이 끝난 데이터는 New에 들어가 있다.
하지만 이 New는 함수의 지역변수이다.
그렇다고 이걸 리턴해주어봤자 Old에 이걸 카피해줘야 한다. 그런데 여기서 내가 살짝 쿵
생각을 바꾸었다. 워낙 위에서 메모리 카피를 너무 많이 한것 같아서...-_-;;
포인터 체인지를 하는 쪽을 생각했다.
Old 이 녀석이나 New나 모두 포인터 변수이다.
그렇다면 Old -> New를 가르키고 New는 NULL줘서 없에버리면 될꺼 아닌가?
포인터로써 메모리 카피 없이 처리를 끝냈다.