1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47:
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62:
63: import ;
64: import ;
65: import ;
66: import ;
67:
68:
79: public class FTPConnection
80: {
81:
82:
85: public static final int FTP_PORT = 21;
86:
87:
90: public static final int FTP_DATA_PORT = 20;
91:
92:
93: protected static final String USER = "USER";
94: protected static final String PASS = "PASS";
95: protected static final String ACCT = "ACCT";
96: protected static final String CWD = "CWD";
97: protected static final String CDUP = "CDUP";
98: protected static final String SMNT = "SMNT";
99: protected static final String REIN = "REIN";
100: protected static final String QUIT = "QUIT";
101:
102: protected static final String PORT = "PORT";
103: protected static final String PASV = "PASV";
104: protected static final String TYPE = "TYPE";
105: protected static final String STRU = "STRU";
106: protected static final String MODE = "MODE";
107:
108: protected static final String RETR = "RETR";
109: protected static final String STOR = "STOR";
110: protected static final String STOU = "STOU";
111: protected static final String APPE = "APPE";
112: protected static final String ALLO = "ALLO";
113: protected static final String REST = "REST";
114: protected static final String RNFR = "RNFR";
115: protected static final String RNTO = "RNTO";
116: protected static final String ABOR = "ABOR";
117: protected static final String DELE = "DELE";
118: protected static final String RMD = "RMD";
119: protected static final String MKD = "MKD";
120: protected static final String PWD = "PWD";
121: protected static final String LIST = "LIST";
122: protected static final String NLST = "NLST";
123: protected static final String SITE = "SITE";
124: protected static final String SYST = "SYST";
125: protected static final String STAT = "STAT";
126: protected static final String HELP = "HELP";
127: protected static final String NOOP = "NOOP";
128:
129: protected static final String AUTH = "AUTH";
130: protected static final String PBSZ = "PBSZ";
131: protected static final String PROT = "PROT";
132: protected static final String CCC = "CCC";
133: protected static final String TLS = "TLS";
134:
135: public static final int TYPE_ASCII = 1;
136: public static final int TYPE_EBCDIC = 2;
137: public static final int TYPE_BINARY = 3;
138:
139: public static final int STRUCTURE_FILE = 1;
140: public static final int STRUCTURE_RECORD = 2;
141: public static final int STRUCTURE_PAGE = 3;
142:
143: public static final int MODE_STREAM = 1;
144: public static final int MODE_BLOCK = 2;
145: public static final int MODE_COMPRESSED = 3;
146:
147:
148: private static final String US_ASCII = "US-ASCII";
149:
150:
153: protected Socket socket;
154:
155:
158: protected LineInputStream in;
159:
160:
163: protected CRLFOutputStream out;
164:
165:
168: protected int connectionTimeout;
169:
170:
173: protected int timeout;
174:
175:
178: protected boolean debug;
179:
180:
183: protected DTP dtp;
184:
185:
188: protected int representationType = TYPE_ASCII;
189:
190:
193: protected int fileStructure = STRUCTURE_FILE;
194:
195:
198: protected int transferMode = MODE_STREAM;
199:
200:
203: protected boolean passive = false;
204:
205:
209: public FTPConnection(String hostname)
210: throws UnknownHostException, IOException
211: {
212: this(hostname, -1, 0, 0, false);
213: }
214:
215:
220: public FTPConnection(String hostname, int port)
221: throws UnknownHostException, IOException
222: {
223: this(hostname, port, 0, 0, false);
224: }
225:
226:
234: public FTPConnection(String hostname, int port,
235: int connectionTimeout, int timeout, boolean debug)
236: throws UnknownHostException, IOException
237: {
238: this.connectionTimeout = connectionTimeout;
239: this.timeout = timeout;
240: this.debug = debug;
241: if (port <= 0)
242: {
243: port = FTP_PORT;
244: }
245:
246:
247: socket = new Socket();
248: InetSocketAddress address = new InetSocketAddress(hostname, port);
249: if (connectionTimeout > 0)
250: {
251: socket.connect(address, connectionTimeout);
252: }
253: else
254: {
255: socket.connect(address);
256: }
257: if (timeout > 0)
258: {
259: socket.setSoTimeout(timeout);
260: }
261:
262: InputStream in = socket.getInputStream();
263: in = new BufferedInputStream(in);
264: in = new CRLFInputStream(in);
265: this.in = new LineInputStream(in);
266: OutputStream out = socket.getOutputStream();
267: out = new BufferedOutputStream(out);
268: this.out = new CRLFOutputStream(out);
269:
270:
271: FTPResponse response = getResponse();
272: switch (response.getCode())
273: {
274: case 220:
275: break;
276: default:
277: throw new FTPException(response);
278: }
279: }
280:
281:
289: public boolean authenticate(String username, String password)
290: throws IOException
291: {
292: String cmd = USER + ' ' + username;
293: send(cmd);
294: FTPResponse response = getResponse();
295: switch (response.getCode())
296: {
297: case 230:
298: return true;
299: case 331:
300: break;
301: case 332:
302: case 530:
303: return false;
304: default:
305: throw new FTPException(response);
306: }
307: cmd = PASS + ' ' + password;
308: send(cmd);
309: response = getResponse();
310: switch (response.getCode())
311: {
312: case 230:
313: case 202:
314: return true;
315: case 332:
316: case 530:
317: return false;
318: default:
319: throw new FTPException(response);
320: }
321: }
322:
323:
329: public boolean starttls(boolean confidential)
330: throws IOException
331: {
332: return starttls(confidential, new EmptyX509TrustManager());
333: }
334:
335:
342: public boolean starttls(boolean confidential, TrustManager tm)
343: throws IOException
344: {
345: try
346: {
347:
348:
349: SSLContext context = SSLContext.getInstance("TLS");
350:
351: TrustManager[] trust = new TrustManager[] { tm };
352: context.init(null, trust, null);
353: SSLSocketFactory factory = context.getSocketFactory();
354:
355: send(AUTH + ' ' + TLS);
356: FTPResponse response = getResponse();
357: switch (response.getCode())
358: {
359: case 500:
360: case 502:
361: case 504:
362: case 534:
363: case 431:
364: return false;
365: case 234:
366: break;
367: default:
368: throw new FTPException(response);
369: }
370:
371: String hostname = socket.getInetAddress().getHostName();
372: int port = socket.getPort();
373: SSLSocket ss =
374: (SSLSocket) factory.createSocket(socket, hostname, port, true);
375: String[] protocols = { "TLSv1", "SSLv3" };
376: ss.setEnabledProtocols(protocols);
377: ss.setUseClientMode(true);
378: ss.startHandshake();
379:
380:
381: send(PBSZ + ' ' + Integer.MAX_VALUE);
382: response = getResponse();
383: switch (response.getCode())
384: {
385: case 501:
386: case 503:
387: return false;
388: case 200:
389: break;
390: default:
391: throw new FTPException(response);
392: }
393: send(PROT + ' ' +(confidential ? 'P' : 'C'));
394: response = getResponse();
395: switch (response.getCode())
396: {
397: case 503:
398: case 504:
399: case 536:
400: return false;
401: case 200:
402: break;
403: default:
404: throw new FTPException(response);
405: }
406:
407: if (confidential)
408: {
409:
410: InputStream in = ss.getInputStream();
411: in = new BufferedInputStream(in);
412: in = new CRLFInputStream(in);
413: this.in = new LineInputStream(in);
414: OutputStream out = ss.getOutputStream();
415: out = new BufferedOutputStream(out);
416: this.out = new CRLFOutputStream(out);
417: }
418: return true;
419: }
420: catch (GeneralSecurityException e)
421: {
422: return false;
423: }
424: }
425:
426:
431: public boolean changeWorkingDirectory(String path)
432: throws IOException
433: {
434:
435: if (path.length() == 0)
436: return true;
437: String cmd = CWD + ' ' + path;
438: send(cmd);
439: FTPResponse response = getResponse();
440: switch (response.getCode())
441: {
442: case 250:
443: return true;
444: case 550:
445: return false;
446: default:
447: throw new FTPException(response);
448: }
449: }
450:
451:
455: public boolean changeToParentDirectory()
456: throws IOException
457: {
458: send(CDUP);
459: FTPResponse response = getResponse();
460: switch (response.getCode())
461: {
462: case 250:
463: return true;
464: case 550:
465: return false;
466: default:
467: throw new FTPException(response);
468: }
469: }
470:
471:
476: public void reinitialize()
477: throws IOException
478: {
479: send(REIN);
480: FTPResponse response = getResponse();
481: switch (response.getCode())
482: {
483: case 220:
484: if (dtp != null)
485: {
486: dtp.complete();
487: dtp = null;
488: }
489: break;
490: default:
491: throw new FTPException(response);
492: }
493: }
494:
495:
500: public void logout()
501: throws IOException
502: {
503: send(QUIT);
504: try
505: {
506: getResponse();
507: }
508: catch (IOException e)
509: {
510: }
511: if (dtp != null)
512: {
513: dtp.complete();
514: dtp = null;
515: }
516: try
517: {
518: socket.close();
519: }
520: catch (IOException e)
521: {
522: }
523: }
524:
525:
528: protected void initialiseDTP()
529: throws IOException
530: {
531: if (dtp != null)
532: {
533: dtp.complete();
534: dtp = null;
535: }
536:
537: InetAddress localhost = socket.getLocalAddress();
538: if (passive)
539: {
540: send(PASV);
541: FTPResponse response = getResponse();
542: switch (response.getCode())
543: {
544: case 227:
545: String message = response.getMessage();
546: try
547: {
548: int start = message.indexOf(',');
549: char c = message.charAt(start - 1);
550: while (c >= 0x30 && c <= 0x39)
551: {
552: c = message.charAt((--start) - 1);
553: }
554: int mid1 = start;
555: for (int i = 0; i < 4; i++)
556: {
557: mid1 = message.indexOf(',', mid1 + 1);
558: }
559: int mid2 = message.indexOf(',', mid1 + 1);
560: if (mid1 == -1 || mid2 < mid1)
561: {
562: throw new ProtocolException("Malformed 227: " +
563: message);
564: }
565: int end = mid2;
566: c = message.charAt(end + 1);
567: while (c >= 0x30 && c <= 0x39)
568: {
569: c = message.charAt((++end) + 1);
570: }
571:
572: String address =
573: message.substring(start, mid1).replace(',', '.');
574: int port_hi =
575: Integer.parseInt(message.substring(mid1 + 1, mid2));
576: int port_lo =
577: Integer.parseInt(message.substring(mid2 + 1, end + 1));
578: int port = (port_hi << 8) | port_lo;
579:
580:
582: dtp = new PassiveModeDTP(address, port, localhost,
583: connectionTimeout, timeout);
584: break;
585: }
586: catch (ArrayIndexOutOfBoundsException e)
587: {
588: throw new ProtocolException(e.getMessage() + ": " +
589: message);
590: }
591: catch (NumberFormatException e)
592: {
593: throw new ProtocolException(e.getMessage() + ": " +
594: message);
595: }
596: default:
597: throw new FTPException(response);
598: }
599: }
600: else
601: {
602:
603: int port = socket.getLocalPort() + 1;
604: int tries = 0;
605:
606: while (dtp == null)
607: {
608: try
609: {
610: dtp = new ActiveModeDTP(localhost, port,
611: connectionTimeout, timeout);
612:
613: }
614: catch (BindException e)
615: {
616: port++;
617: tries++;
618: if (tries > 9)
619: {
620: throw e;
621: }
622: }
623: }
624:
625:
626: CPStringBuilder buf = new CPStringBuilder(PORT);
627: buf.append(' ');
628:
629: byte[] address = localhost.getAddress();
630: for (int i = 0; i < address.length; i++)
631: {
632: int a =(int) address[i];
633: if (a < 0)
634: {
635: a += 0x100;
636: }
637: buf.append(a);
638: buf.append(',');
639: }
640: int port_hi =(port & 0xff00) >> 8;
641: int port_lo =(port & 0x00ff);
642: buf.append(port_hi);
643: buf.append(',');
644: buf.append(port_lo);
645: send(buf.toString());
646:
647: FTPResponse response = getResponse();
648: switch (response.getCode())
649: {
650: case 200:
651: break;
652: default:
653: dtp.abort();
654: dtp = null;
655: throw new FTPException(response);
656: }
657: }
658: dtp.setTransferMode(transferMode);
659: }
660:
661:
665: public void setPassive(boolean flag)
666: throws IOException
667: {
668: if (passive != flag)
669: {
670: passive = flag;
671: initialiseDTP();
672: }
673: }
674:
675:
679: public int getRepresentationType()
680: {
681: return representationType;
682: }
683:
684:
688: public void setRepresentationType(int type)
689: throws IOException
690: {
691: CPStringBuilder buf = new CPStringBuilder(TYPE);
692: buf.append(' ');
693: switch (type)
694: {
695: case TYPE_ASCII:
696: buf.append('A');
697: break;
698: case TYPE_EBCDIC:
699: buf.append('E');
700: break;
701: case TYPE_BINARY:
702: buf.append('I');
703: break;
704: default:
705: throw new IllegalArgumentException(Integer.toString(type));
706: }
707:
708:
709: send(buf.toString());
710: FTPResponse response = getResponse();
711: switch (response.getCode())
712: {
713: case 200:
714: representationType = type;
715: break;
716: default:
717: throw new FTPException(response);
718: }
719: }
720:
721:
725: public int getFileStructure()
726: {
727: return fileStructure;
728: }
729:
730:
734: public void setFileStructure(int structure)
735: throws IOException
736: {
737: CPStringBuilder buf = new CPStringBuilder(STRU);
738: buf.append(' ');
739: switch (structure)
740: {
741: case STRUCTURE_FILE:
742: buf.append('F');
743: break;
744: case STRUCTURE_RECORD:
745: buf.append('R');
746: break;
747: case STRUCTURE_PAGE:
748: buf.append('P');
749: break;
750: default:
751: throw new IllegalArgumentException(Integer.toString(structure));
752: }
753: send(buf.toString());
754: FTPResponse response = getResponse();
755: switch (response.getCode())
756: {
757: case 200:
758: fileStructure = structure;
759: break;
760: default:
761: throw new FTPException(response);
762: }
763: }
764:
765:
769: public int getTransferMode()
770: {
771: return transferMode;
772: }
773:
774:
778: public void setTransferMode(int mode)
779: throws IOException
780: {
781: CPStringBuilder buf = new CPStringBuilder(MODE);
782: buf.append(' ');
783: switch (mode)
784: {
785: case MODE_STREAM:
786: buf.append('S');
787: break;
788: case MODE_BLOCK:
789: buf.append('B');
790: break;
791: case MODE_COMPRESSED:
792: buf.append('C');
793: break;
794: default:
795: throw new IllegalArgumentException(Integer.toString(mode));
796: }
797: send(buf.toString());
798: FTPResponse response = getResponse();
799: switch (response.getCode())
800: {
801: case 200:
802: transferMode = mode;
803: if (dtp != null)
804: {
805: dtp.setTransferMode(mode);
806: }
807: break;
808: default:
809: throw new FTPException(response);
810: }
811: }
812:
813:
818: public InputStream retrieve(String filename)
819: throws IOException
820: {
821: if (dtp == null || transferMode == MODE_STREAM)
822: {
823: initialiseDTP();
824: }
825:
840: String cmd = RETR + ' ' + filename;
841: send(cmd);
842: FTPResponse response = getResponse();
843: switch (response.getCode())
844: {
845: case 125:
846: case 150:
847: return dtp.getInputStream();
848: default:
849: throw new FTPException(response);
850: }
851: }
852:
853:
860: public OutputStream store(String filename)
861: throws IOException
862: {
863: if (dtp == null || transferMode == MODE_STREAM)
864: {
865: initialiseDTP();
866: }
867: String cmd = STOR + ' ' + filename;
868: send(cmd);
869: FTPResponse response = getResponse();
870: switch (response.getCode())
871: {
872: case 125:
873: case 150:
874: return dtp.getOutputStream();
875: default:
876: throw new FTPException(response);
877: }
878: }
879:
880:
887: public OutputStream append(String filename)
888: throws IOException
889: {
890: if (dtp == null || transferMode == MODE_STREAM)
891: {
892: initialiseDTP();
893: }
894: String cmd = APPE + ' ' + filename;
895: send(cmd);
896: FTPResponse response = getResponse();
897: switch (response.getCode())
898: {
899: case 125:
900: case 150:
901: return dtp.getOutputStream();
902: default:
903: throw new FTPException(response);
904: }
905: }
906:
907:
914: public void allocate(long size)
915: throws IOException
916: {
917: String cmd = ALLO + ' ' + size;
918: send(cmd);
919: FTPResponse response = getResponse();
920: switch (response.getCode())
921: {
922: case 200:
923: case 202:
924: break;
925: default:
926: throw new FTPException(response);
927: }
928: }
929:
930:
936: public boolean rename(String oldName, String newName)
937: throws IOException
938: {
939: String cmd = RNFR + ' ' + oldName;
940: send(cmd);
941: FTPResponse response = getResponse();
942: switch (response.getCode())
943: {
944: case 450:
945: case 550:
946: return false;
947: case 350:
948: break;
949: default:
950: throw new FTPException(response);
951: }
952: cmd = RNTO + ' ' + newName;
953: send(cmd);
954: response = getResponse();
955: switch (response.getCode())
956: {
957: case 250:
958: return true;
959: case 450:
960: case 550:
961: return false;
962: default:
963: throw new FTPException(response);
964: }
965: }
966:
967:
971: public boolean abort()
972: throws IOException
973: {
974: send(ABOR);
975: FTPResponse response = getResponse();
976:
977: if (dtp != null)
978: {
979: dtp.abort();
980: }
981: switch (response.getCode())
982: {
983: case 226:
984: return false;
985: case 426:
986: response = getResponse();
987: if (response.getCode() == 226)
988: {
989: return true;
990: }
991:
992: default:
993: throw new FTPException(response);
994: }
995: }
996:
997:
1001: public boolean delete(String filename)
1002: throws IOException
1003: {
1004: String cmd = DELE + ' ' + filename;
1005: send(cmd);
1006: FTPResponse response = getResponse();
1007: switch (response.getCode())
1008: {
1009: case 250:
1010: return true;
1011: case 450:
1012: case 550:
1013: return false;
1014: default:
1015: throw new FTPException(response);
1016: }
1017: }
1018:
1019:
1024: public boolean removeDirectory(String pathname)
1025: throws IOException
1026: {
1027: String cmd = RMD + ' ' + pathname;
1028: send(cmd);
1029: FTPResponse response = getResponse();
1030: switch (response.getCode())
1031: {
1032: case 250:
1033: return true;
1034: case 550:
1035: return false;
1036: default:
1037: throw new FTPException(response);
1038: }
1039: }
1040:
1041:
1046: public boolean makeDirectory(String pathname)
1047: throws IOException
1048: {
1049: String cmd = MKD + ' ' + pathname;
1050: send(cmd);
1051: FTPResponse response = getResponse();
1052: switch (response.getCode())
1053: {
1054: case 257:
1055: return true;
1056: case 550:
1057: return false;
1058: default:
1059: throw new FTPException(response);
1060: }
1061: }
1062:
1063:
1066: public String getWorkingDirectory()
1067: throws IOException
1068: {
1069: send(PWD);
1070: FTPResponse response = getResponse();
1071: switch (response.getCode())
1072: {
1073: case 257:
1074: String message = response.getMessage();
1075: if (message.charAt(0) == '"')
1076: {
1077: int end = message.indexOf('"', 1);
1078: if (end == -1)
1079: {
1080: throw new ProtocolException(message);
1081: }
1082: return message.substring(1, end);
1083: }
1084: else
1085: {
1086: int end = message.indexOf(' ');
1087: if (end == -1)
1088: {
1089: return message;
1090: }
1091: else
1092: {
1093: return message.substring(0, end);
1094: }
1095: }
1096: default:
1097: throw new FTPException(response);
1098: }
1099: }
1100:
1101:
1110: public InputStream list(String pathname)
1111: throws IOException
1112: {
1113: if (dtp == null || transferMode == MODE_STREAM)
1114: {
1115: initialiseDTP();
1116: }
1117: if (pathname == null)
1118: {
1119: send(LIST);
1120: }
1121: else
1122: {
1123: String cmd = LIST + ' ' + pathname;
1124: send(cmd);
1125: }
1126: FTPResponse response = getResponse();
1127: switch (response.getCode())
1128: {
1129: case 125:
1130: case 150:
1131: return dtp.getInputStream();
1132: default:
1133: throw new FTPException(response);
1134: }
1135: }
1136:
1137:
1144: public List<String> nameList(String pathname)
1145: throws IOException
1146: {
1147: if (dtp == null || transferMode == MODE_STREAM)
1148: {
1149: initialiseDTP();
1150: }
1151: if (pathname == null)
1152: {
1153: send(NLST);
1154: }
1155: else
1156: {
1157: String cmd = NLST + ' ' + pathname;
1158: send(cmd);
1159: }
1160: FTPResponse response = getResponse();
1161: switch (response.getCode())
1162: {
1163: case 125:
1164: case 150:
1165: InputStream in = dtp.getInputStream();
1166: in = new BufferedInputStream(in);
1167: in = new CRLFInputStream(in);
1168: LineInputStream li = new LineInputStream(in);
1169: ArrayList<String> ret = new ArrayList<String>();
1170: for (String line = li.readLine();
1171: line != null;
1172: line = li.readLine())
1173: {
1174: ret.add(line);
1175: }
1176: li.close();
1177: return ret;
1178: default:
1179: throw new FTPException(response);
1180: }
1181: }
1182:
1183:
1186: public String system()
1187: throws IOException
1188: {
1189: send(SYST);
1190: FTPResponse response = getResponse();
1191: switch (response.getCode())
1192: {
1193: case 215:
1194: String message = response.getMessage();
1195: int end = message.indexOf(' ');
1196: if (end == -1)
1197: {
1198: return message;
1199: }
1200: else
1201: {
1202: return message.substring(0, end);
1203: }
1204: default:
1205: throw new FTPException(response);
1206: }
1207: }
1208:
1209:
1214: public void noop()
1215: throws IOException
1216: {
1217: send(NOOP);
1218: FTPResponse response = getResponse();
1219: switch (response.getCode())
1220: {
1221: case 200:
1222: break;
1223: default:
1224: throw new FTPException(response);
1225: }
1226: }
1227:
1228:
1229:
1230:
1235: protected void send(String cmd)
1236: throws IOException
1237: {
1238: byte[] data = cmd.getBytes(US_ASCII);
1239: out.write(data);
1240: out.writeln();
1241: out.flush();
1242: }
1243:
1244:
1249: protected FTPResponse getResponse()
1250: throws IOException
1251: {
1252: FTPResponse response = readResponse();
1253: if (response.getCode() == 226)
1254: {
1255: if (dtp != null)
1256: {
1257: dtp.transferComplete();
1258: }
1259: response = readResponse();
1260: }
1261: return response;
1262: }
1263:
1264:
1267: protected FTPResponse readResponse()
1268: throws IOException
1269: {
1270: String line = in.readLine();
1271: if (line == null)
1272: {
1273: throw new ProtocolException( "EOF");
1274: }
1275: if (line.length() < 4)
1276: {
1277: throw new ProtocolException(line);
1278: }
1279: int code = parseCode(line);
1280: if (code == -1)
1281: {
1282: throw new ProtocolException(line);
1283: }
1284: char c = line.charAt(3);
1285: if (c == ' ')
1286: {
1287: return new FTPResponse(code, line.substring(4));
1288: }
1289: else if (c == '-')
1290: {
1291: CPStringBuilder buf = new CPStringBuilder(line.substring(4));
1292: buf.append('\n');
1293: while(true)
1294: {
1295: line = in.readLine();
1296: if (line == null)
1297: {
1298: throw new ProtocolException("EOF");
1299: }
1300: if (line.length() >= 4 &&
1301: line.charAt(3) == ' ' &&
1302: parseCode(line) == code)
1303: {
1304: return new FTPResponse(code, line.substring(4),
1305: buf.toString());
1306: }
1307: else
1308: {
1309: buf.append(line);
1310: buf.append('\n');
1311: }
1312: }
1313: }
1314: else
1315: {
1316: throw new ProtocolException(line);
1317: }
1318: }
1319:
1320:
1324: static final int parseCode(String line)
1325: {
1326: char[] c = { line.charAt(0), line.charAt(1), line.charAt(2) };
1327: int ret = 0;
1328: for (int i = 0; i < 3; i++)
1329: {
1330: int digit =((int) c[i]) - 0x30;
1331: if (digit < 0 || digit > 9)
1332: {
1333: return -1;
1334: }
1335:
1336: switch (i)
1337: {
1338: case 0:
1339: ret +=(100 * digit);
1340: break;
1341: case 1:
1342: ret +=(10 * digit);
1343: break;
1344: case 2:
1345: ret += digit;
1346: break;
1347: }
1348: }
1349: return ret;
1350: }
1351:
1352: }