반응형

버스 내릴 때, 많은 이들이 교통카드를 찍고 내립니다.

우워어어어 모든 이들이 다 환승을 위해 찍는 것인가??

아마도 다른사람도 찍는데 나도 찍어야지 라는 막연한 생각에 ㅋㅋㅋ

찍는 분들 계실꺼에요.

환승을 하지 않는 것 이라면 찍을 이유가 없답니다. 하지만 거리비례 때문에 찍습니다.

거리비례(승차 하차의 구간차이를 적용하여)가 적용되고 있는 곳은 서울을 비롯한,

거진 수도권중심으로 알고 있습니다. 지방은 안 그런 것으로 알고 있어요.

여튼, 서울기준으로는 거리에 따라 요금이 변동되는 경우,
 
내릴 때 찍지 않으면, 짧은거리를 탔음에도 더 부과된다는 거라네요.


그리고, 후에 노선 변경 시, 참고자료로 사용되기 위함이라네요.

뭐 여튼, 내릴 때 기왕이면 찍습니다만, 거리비례는 둘째치고,

환승(2번째 탄 버스)차량에서 내릴 때 안 찍으면 체감상 2배가량 돈 찍혔던 기억이 있습니다.

즉, 내릴 때는 기왕 찍고 내려야 하고, 환승차량인 경우에는 필히 내릴 때 찍어야 됩니다.

오늘 Daily 끝~
반응형
Posted by Rainfly
l
반응형


어떤 API를 C에서 Java로 포팅중이다. 자바는 Call by value, Call by Ref.. 이다 마다... 에 따라서
여튼... Out Parameter를 어떻게 넘기냐라는 고민을 특히 C개발자분이라면 해보셨을 것 같다.
아마 이 페이지를 들어오신 분도 그런 분들이실테고,,,
앞서 포스팅 중인 저는 초보개발자이며, 단순 제 생각을 적었다는 것을 말씀드립니다.

구체적 예시는 'byte[]'를 함수내에서 받아오는 방법을 나열할 것 이고,
방법은 4가지로 나누었습니다. 그 방법에 들의 대한 키워드와 쏘스는 아래와 같습니다.
Application.java : Main함수
Interface.java : API

1. C style  

# Application.java
public class Application{
 public static void main(String[] argv) throws Exception
 {
  Interface api = new Interface();
 
  int nRet = -1;
  byte[] buffer = new byte[4096];
  byte[] len = new byte[4];

  byte[] ReturnData = null;
  nRet = api.GetMSG(buffer, len);  
  if(nRet != 0)
  {
   system.out.println("Error");   
  } 
  else
  {
   ReturnData = new byte[api.ByteToInt(len)];
   system.arraycopy(buffer, 0, ReturnData, 0, ReturnData.length);   
  } 
 } 
}
# Interface.java
public class Interface{
 public int GetMSG(byte[] buffer, byte[] len) throws Exception
 {
  String strTest = "Test Message";
  byte[] byTest = strTest.getBytes();
  
  if(byTest.length > buffer.length)
  {
   return -1; //버퍼크기가 작습니다.
  }
  System.arraycopy(IntToByte(byTest.length), 0, len, 0, 4);
  System.arraycopy(byTest, 0, buffer, 0, byTest.length);   
  return 0;
 } 
}
# IntToByte & ByteToInt

static public byte[] IntToByte(int nNum)
{
  byte[] abNum = new byte[4];
  abNum[3] = (byte) (nNum);
  abNum[2] = (byte) ((nNum >> 8));
  abNum[1] = (byte) ((nNum >> 16));
  abNum[0] = (byte) ((nNum >> 24));
  return abNum;
}
 
static public int ByteToInt(byte[] abNum)
{
  int datasize = 0;
  
        if (abNum.length == 4) {
            datasize =
                    (( (int) abNum[0] & 0xFF) << 24) +
                            ( (int) (abNum[1] & 0xFF) << 16) +
                            ( (int) (abNum[2] & 0xFF) << 8) +
                            ( (int) (abNum[3] & 0xFF) << 0);             
        } else {
            datasize =
                    ((abNum[0] & 0xFF) << 8) +
                            ((abNum[1] & 0xFF) << 0);
        }
        return datasize;       


2. Class

# Application.java
public class Application{
 public static void main(String[] argv) throws Exception
 {
  Interface api = new Interface();
 
  int nRet = -1;
  Data buffer = new Data(new byte[4096]);
  byte[] ReturnData = null;
  nRet = api.GetMSG(buffer);  
  if(nRet != 0)
  {
   system.out.println("Error");   
  } 
  else
  {
   ReturnData = buffer.getData();      
  } 
 } 
}

# Interface.java
public class Interface{
 public int GetMSG(Data buffer)
 {
  String strTest = "Test Message";
  byte[] byTest = strTest.getBytes();
  
  if(byTest.length > buffer.getLen())
  {
   return -1; //버퍼크기가 작습니다.
  }
  buffer.setData(byTest, byTest.length);
  return 0;
 } 
}


# Data Class

 public class Data{
 private byte[] abData = null;
 private int nLen = 0;
 
 public Data() {}
 public Data(byte[] InputData)
 {
  this.abData = new byte[InputData.length];
  this.nLen = InputData.length;
 } 
 
 public void SetData(byte[] InputData, int Len)
 {
  System.arraycopy(InputData, 0, this.abData, 0, Len);
  this.nLen = Len;
 }


 public byte[] GetData()
 {
  byte[] buffer = new byte[this.nLen];
  System.arraycopy(abData, 0, buffer, 0, this.nLen);
  return buffer;
 }
 
 public int GetLen()
 {
  return this.nLen;
 } 
}


3. Return


# Application.java
public class Application{
 public static void main(String[] argv) throws Exception
 {
  Interface api = new Interface();
 
  int nRet = -1;  
  byte[] ReturnData = null;
  try
  {
   ReturnData = api.GetMSG();  
  }
  catch(Exception e)
  {
   throw new Exception(e.getMessage());
  }   
 } 
}

# Interface.java
public class Interface{
 public byte[] GetMSG() throws Exception
 {
  nRet = -1;
  try
  {
   String strTest = "Test Message"; 
  }
  catch(Exception e)
  {   
   nRet = xxx;
   throw new Exception("ErrCode : " + nRet); //try에서 어떤작업에 대한 Error처리시
  }    
  return strTest.getBytes();
 } 
}


4. Get Function


# Application.java
public class Application{
 public static void main(String[] argv) throws Exception
 {
  Interface api = new Interface();
 
  int nRet = -1;
  Data buffer = new Data(new byte[4096]);
  byte[] ReturnData = null;
  nRet = api.GetMSG();  
  if(nRet != 0)
  {
   system.out.println("Error");   
  } 
  else
  {
   ReturnData = api.getOutParam("GetMSG");      
  
 } 
}

# Interface.java
public class Interface{
 byte[] m_byTest = null;
 public int GetMSG()
 {
  String strTest = "Test Message";
  byte[] byTest = strTest.getBytes();
  
  m_byTest = new byte[byTest.length];
  system.arraycopy(byTest, 0, m_byTest, 0, byTest.length);
  return 0;
 } 
 
 public byte[] getOutParam(String FuncName)
 {
  if(FuncName.equals("GetMSG")
   return m_byTest;
  
  return "잘못된 함수이름입니다.".getByte();
 }
}


5. ArrayList


# Application.java
public class Application{
 public static void main(String[] argv) throws Exception
 {
  Interface api = new Interface();
 
  int nRet = -1;  
  ArrayList<Object> arList = new ArrayList<Object>();
  try
  {
   arList = api.GetMSG();  
  }
  catch(Exception e)
  {
   throw new Exception(e.getMessage());
  } 
  byte[] output = null;
  if(arList.size() > 0)   output = (byte[])arList.get(0);

   
 } 
}


# Interface.java
public class Interface{
 public ArrayList<Object> GetMSG() throws Exception
 {
  nRet = -1;
  ArrayList<byte[]> outBuffer = new ArrayList<byte[]>();

  try
  {
   String strTest = "Test Message"; 
  }
  catch(Exception e)
  {   
   nRet = xxx;
   throw new Exception("ErrCode : " + nRet); //try에서 어떤작업에 대한 Error처리시
  }    
  outBuffer.add(0, strTest.getBytes());

  return outBuffer;
 } 
}






응용 프로그래머가 볼 때, 종합적으로 살펴서 비교하면 다음과 같습니다.

              버퍼할당  //  에러처리    //  추가작업  //  객체갯수
1. Cstyle   :    O      //  Err Code   // ByteToInt  //     3(Buffer, BufferLen, Output)
2. Class    :    O      //  Err Code   //   Class     //     2(Class, Output)
3. Return   :    X      //  Exception  //     X         //     1(Output)
4. GetFunc :    X      //  Err Code   // get func    //     1(Output)
5. ArrayList :   X      //  anyway  //    get        //     1(Output)
- 여기서 버퍼할당은 객체할당이 아닌 직접적 byte[xxx]를 말하는 것임.


1. C Style
null로 초기화를 한다던지가 아니고, 버퍼를 할당하는 이유는 당연히,
응용단에서 인스턴스화 하지 않으면, 함수를 수행하고 난 뒤에 바뀌는 것이 하나도 없기 때문이다.
하지만 정확히 공간을 어느정도 설정해야할지 모르기 때문에,
여유롭게 주는 것 이고, 길이값을 인티저 객체를 쓰는 방법도 있지만, 오로지 byte[]를 이용했다.
그래서 함수 수행 후, 그 길이만큼만 사용한다. 결론은 번거롭다. 자바스럽지 않다.
번외로, 큰 여유버퍼를 예를 들어서 4096을 계속 쓰면 낭비일 수도 있는데,
메모리의 지역성이 반면 높아져서 불규칙한 버퍼크기보단, 같은 버퍼크기가 더 낫다고도 한다.

2 Class
C 스타일과 비슷하다. C에서 구조체를 대신 사용한다고 생각하면 된다.
다만 응용단에서 볼 때, 작업량이 좀 줄어든다고 할 수 있다.

3. Return
제일 자바스럽다. Exception 기능도 살리고, 응용단이든 인터페이스단이든
모든 부분에서 라인수도 크게 줄어든다.
파라미터 2개이상을 Out 시켜야 한다면, 메세지를 만들고 파싱을 하는 작업을 따로 한다던지.
전용 Get함수를 만들던지 알아서 해결해야 한다. 5번 ArrayList를 활용해도 좋다.
단순 Text를 넘기다보니, Exception 처리에 대한 예제는 그냥 형식상으로 남겨두었다.

4. Get Func
이것 또한 자바스러운 방법 중에 하나이며, 에러코드와 Exception 처리 모두 가능하다.
라인 수 또한 줄어드는 편이다.
데이타를 받는 것은, 여러 API가 생성될 것을 생각하여
메쏘드에 함수이름을 인자로 받아, 경우에 따라서 다른 전역변수를 리턴하도록 하였다. 

컴파일을 해본 것은 아니니, 오타는 있을 수 있다.
하지만 방법론에 있어서 저 4가지방식으로 실제 해보았다.
필자의 팀장은 3번 방향으로 가길 추천하였다.

5. ArrayList
import java.util.ArrayList; 를 하여 ArrayList 인스턴스화 하여, 리턴값 받으면 된다.
자바스럽다. 자바독을 봐서, 용법에 대해서 조금 알아본 뒤에 적절하게 맞게 사용하길 추천,
호출해서 add 하고 리턴받으면, size 체크하여 get만 하면 문제없다.
3번처럼 Return형식과 비슷하다.

궁금한 것이 있다면, 댓글을 남겨주세요.
성심 성의 것 ,, 답이 아닌 제 생각을 달아드리리다....
얻어간 것이 있다면, 저 또한 감사합니다. 클릭클릭

반응형
Posted by Rainfly
l
반응형

Java에서
File Dialog, File Open, File Read, File Save, File Excute를 하기 위한 Import는 아래와 같다.

import java.awt.FileDialog;
import java.awt.Frame;

1. Dialog창을 띄워서, File Open하여 File Read하는 부분의 쏘스이다. 

   Frame f = new Frame();
   FileDialog dial = new FileDialog(f, "Open", FileDialog.LOAD);
      
   dial.setFile("*.*");
   dial.setVisible(true);   
   String DirName = dial.getDirectory();
   String FileName = dial.getFile();   
   if(m_Debug == true) System.out.println(DirName + FileName);
   
   String strName = DirName + FileName;
   
   // File Load
   byte[] abData = FileUtil.read(strName);

  
2.1. byte[]형식의 데이타를, String의 Path에 저장하는 함수이다.
 

public static boolean save(final String str, final byte[] by)
  {
   try
   {
    final FileOutputStream fos = new FileOutputStream(str);
    fos.write(by);
    fos.close();
    return true;
   }
   catch (Exception e)
   {
    return false;
   }
  }   


2.2 위 함수를 이용하여, 파일로 Save하고 Excute하는 부분의 쏘스이다.

  byte[] abCert = signVerify.ParseSignedData(abPureSignData);
   
   //File Save
   UFilePlus.save("D:/test.der", abCert);
   
   //Run
   String cmd[] = {"cmd", "/c", "start", "D:/test.der"};   
   Runtime.getRuntime().exec(cmd);





Java 관련 글

[Java] 자바 Jar Source보기 (역컴파일?) Jar Class Source View (jd-gui-0.3.3.windows)

[Java] 이클립스 Jar파일 보기, jadclipse Plug-In 설치하기

[Java] byte[] 아웃 파라미터 주고받기(Out Parameter) ByteToInt, IntToByte, ByteToHex



반응형
Posted by Rainfly
l
반응형
이 방법에 대한 업데이트가 이루어졌습니다.
2011/11/21 - [I.T/Programming] - [Java]byte[] OutParameter, 리턴 값 다수(Return Data) 등의 방법 모색(Final)


왜 byte[]를 아웃파라미터로 주고받냐?
Return해서 받으면 되지 -_-?? 실무에서는 리턴값을 에러코드로 쓰기 쉽상이고,
받아올 데이터가 2개이상이면, 구조체로 포맷을 만들어서 여러 변수를 끌고다니거나 해야한다.
그러니.. 가독성이나, 응용단에서 쓰기 쉽게 하기 위해 인터페이스를 정의 하는 사람들로서는
이런 작업을 해주어야 한다.

정의된 인터페이스를 응용단에서 잘 쓰기위해서는 파라미터의 형이 되도록

통일 되어야하고, String이나 StringBuffer 보단 byte[]로 주고받는 것이 현명한 선택이라고 알고 있다.
C에서는 Data는 *char, char[]를 통해서
길이는 int*를 주어서 하면 되었으나...

Java는 포인터가 없으니 =_=.. 그러나 원리적인 부분은 비슷하다. ;ㅁ;
그럼 Java에서 byte[]를 아웃파라미터로 넘기고 받는 부분을 살펴보겠다.

쏘스 보잡~

1. Main함수에서 Hash 함수를 콜한다.


 public static void main(String[] agrv) throws Exception
 {  
  String strData = "전자서명 할 처방데이터입니다.";
  abBuffer = new byte[512];  // 여유롭게 빈공간 할당에서 아웃파라미터로 준다
  abLen = new byte[4];    // 길이를 Int가 아닌 byte[] 배열로 4공간을 할당.
  nRet = API.Hash("SHA1", strData.getBytes(), abBuffer, abLen); //함수호출
  if( nRet != 0 )
  {
   System.out.println("Hash Fail. ");
  }
  byte[] abHashedData = new byte[UtilManager.ByteToInt(abLen)];     
  //빈공간만큼 실제 아웃풋데이터 선언 및 할당
  System.arraycopy(abBuffer, 0, abHashedData, 0, UtilManager.ByteToInt(abLen)); 
  //길이만큼 복사
  
  System.out.println("Original Message : " + strData);
  System.out.println("HashedData SHA1 : " + new String(abHashedData));
  System.out.println("HashedData SHA1(HEX) : "
                             + HexUtil.byteToHex(abHashedData).toUpperCase());
 }  

2. 매인에서 불렀던 Hash 함수

 public int Hash(String strAlg, byte[] abData, byte[] abHashedData, byte[] abHashedDataLength )throws Exception
 {  
  
  byte[] abBuffer = null;
  try{   
   
   abBuffer = Hash.MakeHash(strAlg, abData); // 더욱 밑단의 함수 해쉬수행 결과가 byte[]형태로 리턴된다.
   int length = abBuffer.length;
   
   //Out Param save
   System.arraycopy(UtilManager.intToByte(length), 0, abHashedDataLength, 0, 4);  //결과값 길이를 byte[4]화 하여 복사
   System.arraycopy(abBuffer, 0, abHashedData, 0, length); //그 길이만큼 여유많은 빈공간에 복사.
         
  }     
     catch (Exception e)
  {   
   throw new Exception(" Hash Fail " + e.toString());
  }
     return 0;
     
 }

3. UtilManager의 byteToHex // intToByte // BytetoInt

 static public int ByteToInt(byte[] abNum)
 {
  int datasize = 0;
  
        if (abNum.length == 4) {
            datasize =
                    (( (int) abNum[0] & 0xFF) << 24) +
                            ( (int) (abNum[1] & 0xFF) << 16) +
                            ( (int) (abNum[2] & 0xFF) << 8) +
                            ( (int) (abNum[3] & 0xFF) << 0);
             /*(
              ((int)abNum[0] << 24 ) & 0xFF+
              ((int)abNum[1] << 16 ) & 0xFF+
              ((int)abNum[2] <<  8 ) & 0xFF+
              ((int)abNum[3] <<  4 ) & 0xFF
              );*/
        } else {
            datasize =
                    ((abNum[0] & 0xFF) << 8) +
                            ((abNum[1] & 0xFF) << 0);
        }
        return datasize;
       
 }
 
 static public byte[] intToByte(int nNum)
 {
  byte[] abNum = new byte[4];
  abNum[3] = (byte) (nNum);
  abNum[2] = (byte) ((nNum >> 8));
  abNum[1] = (byte) ((nNum >> 16));
  abNum[0] = (byte) ((nNum >> 24));

  return abNum;
 }
 
public static String byteToHex(byte[] buf)
     {
   char[] HEX_CHARS = "0123456789abcdef".toCharArray();
   char[] chars = new char[2 * buf.length]; 
 
   for (int i = 0; i < buf.length; ++i) 
         { 
             chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4]; 
    chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
   } 
 
   return new String(chars); 
     } 
 


보충 설명을 하자면,..

1. 응용단에서 넉넉한 여유공간을 할당에서 선언한 byte[]를 아웃파라미터로 넘겨 함수를 콜한다.
   - Data에 해당되는 넉넉한 byte[]와, 길이에 해당되는 byte[4]를 쌍으로 넘기도록 한다.
// 이러면 호출전 응용단에서 할일은 끝이다.

2. 함수 내부에서든, 더 밑단까지 갔다오든 응용단에 넘겨줄 데이터가 생성된다.
3. 함수 내부에서 생성된 데이터의 길이를 IntToByte 한다. (4byte)
4. 길이를 아웃파라미터(Length)에 arraycopy한다.
5. 그 길이만큼 아웃파라미터(Data)에 arraycopy한다. 
// 이러면 호출 된 함수내부에서의 할일은 끝이다.

6. 응용단에서는 받아온 Length(byte[4])를 ByteToInt하여 그 길이만큼 실제 변수를 선언, 할당한다.
7. 그 길이만큼 Data를 Arraycopy한다.
// 이러면 넉넉한 여유공간의 버퍼에서, 실제 딱 맞는 사이즈의 OutData가 만들어진 것이다.


간단하고 쉬운 것이다, 구글에서 찾을 땐 없다. 초보적인 항목이긴하나..
난 애좀 먹었었다. StringBuffer 써보고 =_= 막....


이 방법에 대한 업데이트가 이루어졌습니다.
2011/11/21 - [I.T/Programming] - [Java]byte[] OutParameter, 리턴 값 다수(Return Data) 등의 방법 모색(Final)













반응형
Posted by Rainfly
l
반응형

 

[Java] 이클립스 Jar파일 보기, jadclipse Plug-In 설치하기

Jar파일의 클래스 페이지를 보게되면, 알수없는 문자들이 주루룩 나오게 된다.
jadclipse 라는 플러그인은 그 페이지들이 쏘스파일형태로 보여지게 되는 것이다.

우선 아래 2파일을 다운 받아서, zip파일 압축을 풀어 패쓰를 기억해둔다.(jad.exe파일임)


아래 jar파일은 플러그인이고, 이클립스 플러그인폴더에 복사하여, 이클립스 재실행하면 설치는 끝이다.


이클립스의 Windows의 Preferences 들어가면,
그림과같은 화면에서 jad.exe파일의 패쓰를 지정해주면 완료이다.

별도로 jar 쏘스를 볼 수있는 뷰어는 아래글을 참고하세용.

[Java] 자바 Jar Source보기 (역컴파일?) Jar Class Source View (jd-gui-0.3.3.windows)
반응형
Posted by Rainfly
l