Source Code Cross Referenced for BinaryPListParser.java in  » Swing-Library » jide-common » com » jidesoft » plaf » aqua » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Swing Library » jide common » com.jidesoft.plaf.aqua 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)BinaryPListParser.java  1.0  2005-11-06
003:         *
004:         * Copyright (c) 2005 Werner Randelshofer
005:         * Staldenmattweg 2, Immensee, CH-6405, Switzerland.
006:         * All rights reserved.
007:         *
008:         * This software is the confidential and proprietary information of
009:         * Werner Randelshofer. ("Confidential Information").  You shall not
010:         * disclose such Confidential Information and shall use it only in
011:         * accordance with the terms of the license agreement you entered into
012:         * with Werner Randelshofer.
013:         */
014:
015:        package com.jidesoft.plaf.aqua;
016:
017:        import com.jidesoft.utils.Base64;
018:        import com.jidesoft.utils.SecurityUtils;
019:
020:        import java.io.*;
021:        import java.text.DateFormat;
022:        import java.text.SimpleDateFormat;
023:        import java.util.ArrayList;
024:        import java.util.Date;
025:        import java.util.HashMap;
026:
027:        /**
028:         * Reads a binary PList file and returns it as a NanoXML XMLElement.
029:         * <p/>
030:         * The NanoXML XMLElement returned by this reader is equivalent to the
031:         * XMLElement returned, if a PList file in XML format is parsed with
032:         * NanoXML.
033:         * <p/>
034:         * Description about property list taken from <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/PropertyLists/index.html#//apple_ref/doc/uid/10000048i">
035:         * Apple's online documentation</a>:
036:         * <p/>
037:         * "A property list is a data representation used by Mac OS X Cocoa and Core
038:         * Foundation as a convenient way to store, organize, and access standard object
039:         * types. Frequently called a Òplist,Ó a property list is an object of one of
040:         * several certain Cocoa or Core Foundation types, including  arrays,
041:         * dictionaries, strings, binary data, numbers, dates, and Boolean values. If
042:         * the object is a container (an array or dictionary), all objects contained
043:         * within it must also be supported property list objects. (Arrays and
044:         * dictionaries can contain objects not supported by the architecture, but are
045:         * then not property lists, and cannot be saved and restored with the various
046:         * property list methods.)"
047:         * <p/>
048:         * XXX - This implementation can not read date values. Date values will always
049:         * have the current date.
050:         *
051:         * @author Werner Randelshofer
052:         * @version 0.1 June 18, 2005 Created.
053:         * @see XMLElement
054:         */
055:        class BinaryPListParser {
056:            /* Description of the binary plist format derived from
057:             * http://cvs.opendarwin.org/cgi-bin/cvsweb.cgi/~checkout~/src/CoreFoundation/Parsing.subproj/CFBinaryPList.c?rev=1.1.1.3&content-type=text/plain
058:             *
059:             * EBNF description of the file format:
060:             * <pre>
061:             * bplist ::= header objectTable offsetTable trailer
062:             *
063:             * header ::= magicNumber fileFormatVersion
064:             * magicNumber ::= "bplist"
065:             * fileFormatVersion ::= "00"
066:             *
067:             * objectTable ::= { null | bool | fill | number | date | data |
068:             *                 string | uid | array | dict }
069:             *
070:             * null  ::= 0b0000 0b0000
071:             *
072:             * bool  ::= false | true
073:             * false ::= 0b0000 0b1000
074:             * true  ::= 0b0000 0b1001
075:             *
076:             * fill  ::= 0b0000 0b1111         // fill byte
077:             *
078:             * number ::= int | real
079:             * int    ::= 0b0001 0bnnnn byte*(2^nnnn)  // 2^nnnn big-endian bytes
080:             * real   ::= 0b0010 0bnnnn byte*(2^nnnn)  // 2^nnnn big-endian bytes
081:             *
082:             * date   ::= 0b0011 0b0011 byte*8       // 8 byte float big-endian bytes
083:             *
084:             * data   ::= 0b0100 0bnnnn [int] byte*  // nnnn is number of bytes
085:             *                                       // unless 0b1111 then a int
086:             *                                       // variable-sized object follows
087:             *                                       // to indicate the number of bytes
088:             *
089:             * string ::= asciiString | unicodeString
090:             * asciiString   ::= 0b0101 0bnnnn [int] byte*
091:             * unicodeString ::= 0b0110 0bnnnn [int] short*
092:             *                                       // nnnn is number of bytes
093:             *                                       // unless 0b1111 then a int
094:             *                                       // variable-sized object follows
095:             *                                       // to indicate the number of bytes
096:             *
097:             * uid ::= 0b1000 0bnnnn byte*           // nnnn+1 is # of bytes
098:             *
099:             * array ::= 0b1010 0bnnnn [int] objref* //
100:             *                                       // nnnn is number of objref
101:             *                                       // unless 0b1111 then a int
102:             *                                       // variable-sized object follows
103:             *                                       // to indicate the number of objref
104:             *
105:             * dict ::= 0b1010 0bnnnn [int] keyref* objref* 
106:             *                                       // nnnn is number of keyref and 
107:             *                                       // objref pairs
108:             *                                       // unless 0b1111 then a int
109:             *                                       // variable-sized object follows
110:             *                                       // to indicate the number of pairs
111:             *
112:             * objref = byte | short                 // if refCount
113:             *                                       // is less than 256 then objref is
114:             *                                       // an unsigned byte, otherwise it
115:             *                                       // is an unsigned big-endian short
116:             *
117:             * keyref = byte | short                 // if refCount
118:             *                                       // is less than 256 then objref is
119:             *                                       // an unsigned byte, otherwise it
120:             *                                       // is an unsigned big-endian short
121:             *
122:             * unused ::= 0b0111 0bxxxx | 0b1001 0bxxxx |
123:             *            0b1011 0bxxxx | 0b1100 0bxxxx |
124:             *            0b1110 0bxxxx | 0b1111 0bxxxx
125:             *
126:             *
127:             * offsetTable ::= { int }               // list of ints, byte size of which 
128:             *                                       // is given in trailer
129:             *                                       // these are the byte offsets into
130:             *                                       // the file
131:             *                                       // number of these is in the trailer
132:             *
133:             * trailer ::= refCount offsetCount objectCount topLevelOffset
134:             *
135:             * refCount ::= byte*8                  // unsigned big-endian long
136:             * offsetCount ::= byte*8               // unsigned big-endian long
137:             * objectCount ::= byte*8               // unsigned big-endian long
138:             * topLevelOffset ::= byte*8            // unsigned big-endian long
139:             * </pre>
140:             */
141:
142:            /**
143:             * Total count of objrefs and keyrefs.
144:             */
145:            private int refCount;
146:            /**
147:             * Total count of ofsets.
148:             */
149:            private int offsetCount;
150:            /**
151:             * Total count of objects.
152:             */
153:            private int objectCount;
154:            /**
155:             * Offset in file of top level offset in offset table.
156:             */
157:            private int topLevelOffset;
158:
159:            /**
160:             * Object table.
161:             * We gradually fill in objects from the binary PList object table into
162:             * this list.
163:             */
164:            private ArrayList objectTable;
165:
166:            /**
167:             * Holder for a binary PList array element.
168:             */
169:            private static class BPLArray {
170:                ArrayList objectTable;
171:                int[] objref;
172:
173:                public Object getValue(int i) {
174:                    return objectTable.get(objref[i]);
175:                }
176:
177:                @Override
178:                public String toString() {
179:                    StringBuffer buf = new StringBuffer("Array{");
180:                    for (int i = 0; i < objref.length; i++) {
181:                        if (i > 0) {
182:                            buf.append(',');
183:                        }
184:                        if (objectTable.size() > objref[i]
185:                                && objectTable.get(objref[i]) != this ) {
186:                            buf.append(objectTable.get(objref[i]));
187:                        } else {
188:                            buf.append("*" + objref[i]);
189:                        }
190:                    }
191:                    buf.append('}');
192:                    return buf.toString();
193:                }
194:            }
195:
196:            /**
197:             * Holder for a binary PList dict element.
198:             */
199:            private static class BPLDict {
200:                ArrayList objectTable;
201:                int[] keyref;
202:                int[] objref;
203:
204:                public String getKey(int i) {
205:                    return objectTable.get(keyref[i]).toString();
206:                }
207:
208:                public Object getValue(int i) {
209:                    return objectTable.get(objref[i]);
210:                }
211:
212:                @Override
213:                public String toString() {
214:                    StringBuffer buf = new StringBuffer("BPLDict{");
215:                    for (int i = 0; i < keyref.length; i++) {
216:                        if (i > 0) {
217:                            buf.append(',');
218:                        }
219:                        if (keyref[i] < 0 || keyref[i] >= objectTable.size()) {
220:                            buf.append("#" + keyref[i]);
221:                        } else if (objectTable.get(keyref[i]) == this ) {
222:                            buf.append("*" + keyref[i]);
223:                        } else {
224:                            buf.append(objectTable.get(keyref[i]));
225:                            //buf.append(keyref[i]);
226:                        }
227:                        buf.append(":");
228:                        if (objref[i] < 0 || objref[i] >= objectTable.size()) {
229:                            buf.append("#" + objref[i]);
230:                        } else if (objectTable.get(objref[i]) == this ) {
231:                            buf.append("*" + objref[i]);
232:                        } else {
233:                            buf.append(objectTable.get(objref[i]));
234:                            //buf.append(objref[i]);
235:                        }
236:                    }
237:                    buf.append('}');
238:                    return buf.toString();
239:                }
240:            }
241:
242:            /**
243:             * Creates a new instance.
244:             */
245:            public BinaryPListParser() {
246:            }
247:
248:            /**
249:             * Parses a binary PList file and turns it into a XMLElement.
250:             * The XMLElement is equivalent with a XML PList file parsed using
251:             * NanoXML.
252:             *
253:             * @param file A file containing a binary PList.
254:             * @return Returns the parsed XMLElement.
255:             */
256:            public XMLElement parse(File file) throws IOException {
257:                RandomAccessFile raf = null;
258:                byte[] buf = null;
259:                try {
260:                    raf = new RandomAccessFile(file, "r");
261:
262:                    // Parse the HEADER
263:                    // ----------------
264:                    //  magic number ("bplist")
265:                    //  file format version ("00")
266:                    int bpli = raf.readInt();
267:                    int st00 = raf.readInt();
268:                    if (bpli != 0x62706c69 || st00 != 0x73743030) {
269:                        throw new IOException(
270:                                "parseHeader: File does not start with 'bplist00' magic.");
271:                    }
272:
273:                    // Parse the TRAILER
274:                    // ----------------
275:                    //	byte size of offset ints in offset table
276:                    //      byte size of object refs in arrays and dicts
277:                    //      number of offsets in offset table (also is number of objects)
278:                    //      element # in offset table which is top level object
279:                    raf.seek(raf.length() - 32);
280:                    //	count of offset ints in offset table
281:                    offsetCount = (int) raf.readLong();
282:                    //  count of object refs in arrays and dicts
283:                    refCount = (int) raf.readLong();
284:                    //  count of offsets in offset table (also is number of objects)
285:                    objectCount = (int) raf.readLong();
286:                    //  element # in offset table which is top level object
287:                    topLevelOffset = (int) raf.readLong();
288:                    buf = new byte[topLevelOffset - 8];
289:                    raf.seek(8);
290:                    raf.readFully(buf);
291:                } finally {
292:                    if (raf != null) {
293:                        raf.close();
294:                    }
295:                }
296:
297:                // Parse the OBJECT TABLE
298:                // ----------------------
299:                objectTable = new ArrayList();
300:                DataInputStream in = null;
301:                try {
302:                    in = new DataInputStream(new ByteArrayInputStream(buf));
303:                    parseObjectTable(in);
304:                } finally {
305:                    if (in != null) {
306:                        in.close();
307:                    }
308:                }
309:
310:                // Convert the object table to XML and return it
311:                XMLElement root = new XMLElement(new HashMap(), false, false);
312:                root.setName("plist");
313:                root.setAttribute("version", "1.0");
314:                convertObjectTableToXML(root, objectTable.get(0));
315:                return root;
316:            }
317:
318:            /**
319:             * Converts the object table in the binary PList into an XMLElement.
320:             */
321:            private void convertObjectTableToXML(XMLElement parent,
322:                    Object object) {
323:                XMLElement elem = parent.createAnotherElement();
324:                if (object instanceof  BPLDict) {
325:                    BPLDict dict = (BPLDict) object;
326:                    elem.setName("dict");
327:                    for (int i = 0; i < dict.keyref.length; i++) {
328:                        XMLElement key = parent.createAnotherElement();
329:                        key.setName("key");
330:                        key.setContent(dict.getKey(i));
331:                        elem.addChild(key);
332:                        convertObjectTableToXML(elem, dict.getValue(i));
333:                    }
334:                } else if (object instanceof  BPLArray) {
335:                    BPLArray arr = (BPLArray) object;
336:                    elem.setName("array");
337:                    for (int i = 0; i < arr.objref.length; i++) {
338:                        convertObjectTableToXML(elem, arr.getValue(i));
339:                    }
340:
341:                } else if (object instanceof  String) {
342:                    elem.setName("string");
343:                    elem.setContent((String) object);
344:                } else if (object instanceof  Integer) {
345:                    elem.setName("integer");
346:                    elem.setContent(object.toString());
347:                } else if (object instanceof  Long) {
348:                    elem.setName("integer");
349:                    elem.setContent(object.toString());
350:                } else if (object instanceof  Float) {
351:                    elem.setName("real");
352:                    elem.setContent(object.toString());
353:                } else if (object instanceof  Double) {
354:                    elem.setName("real");
355:                    elem.setContent(object.toString());
356:                } else if (object instanceof  Boolean) {
357:                    elem.setName("boolean");
358:                    elem.setContent(object.toString());
359:                } else if (object instanceof  byte[]) {
360:                    elem.setName("data");
361:                    elem.setContent(Base64.encodeBytes((byte[]) object));
362:                } else if (object instanceof  Date) {
363:                    elem.setName("date");
364:                    DateFormat format = new SimpleDateFormat(
365:                            "yyyy-MM-dd'T'HH:mm:ss'Z'");
366:                    elem.setContent(format.format((Date) object));
367:                } else {
368:                    elem.setName("unsupported");
369:                    elem.setContent(object.toString());
370:                }
371:                parent.addChild(elem);
372:            }
373:
374:            /**
375:             * Object Formats (marker byte followed by additional info in some cases)
376:             * null	0000 0000
377:             * bool	0000 1000			// false
378:             * bool	0000 1001			// true
379:             * fill	0000 1111			// fill byte
380:             * int	0001 nnnn	...		// # of bytes is 2^nnnn, big-endian bytes
381:             * real	0010 nnnn	...		// # of bytes is 2^nnnn, big-endian bytes
382:             * date	0011 0011	...		// 8 byte float follows, big-endian bytes
383:             * data	0100 nnnn	[int]	...	// nnnn is number of bytes unless 1111 then int count follows, followed by bytes
384:             * string	0101 nnnn	[int]	...	// ASCII string, nnnn is # of chars, else 1111 then int count, then bytes
385:             * string	0110 nnnn	[int]	...	// Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte shorts
386:             * 0111 xxxx			// unused
387:             * uid	1000 nnnn	...		// nnnn+1 is # of bytes
388:             * 1001 xxxx			// unused
389:             * array	1010 nnnn	[int]	objref*	// nnnn is count, unless '1111', then int count follows
390:             * 1011 xxxx			// unused
391:             * 1100 xxxx			// unused
392:             * dict	1101 nnnn	[int]	keyref* objref*	// nnnn is count, unless '1111', then int count follows
393:             * 1110 xxxx			// unused
394:             * 1111 xxxx			// unused
395:             */
396:            private void parseObjectTable(DataInputStream in)
397:                    throws IOException {
398:                int marker;
399:                while ((marker = in.read()) != -1) {
400:                    //System.out.println("parseObjectTable "+objectTable.size()+": marker="+Integer.toHexString(marker));
401:                    switch ((marker & 0xf0) >> 4) {
402:                    case 0: {
403:                        parsePrimitive(in, marker & 0xf);
404:                        break;
405:                    }
406:                    case 1: {
407:                        int count = 1 << (marker & 0xf);
408:                        parseInt(in, count);
409:                        break;
410:                    }
411:                    case 2: {
412:                        int count = 1 << (marker & 0xf);
413:                        parseReal(in, count);
414:                        break;
415:                    }
416:                    case 3: {
417:                        if ((marker & 0xf) != 3) {
418:                            throw new IOException(
419:                                    "parseObjectTable: illegal marker "
420:                                            + Integer.toBinaryString(marker));
421:                        }
422:                        parseDate(in);
423:                        break;
424:                    }
425:                    case 4: {
426:                        int count = marker & 0xf;
427:                        if (count == 15) {
428:                            count = readCount(in);
429:                        }
430:                        parseData(in, count);
431:                        break;
432:                    }
433:                    case 5: {
434:                        int count = marker & 0xf;
435:                        if (count == 15) {
436:                            count = readCount(in);
437:                        }
438:                        parseAsciiString(in, count);
439:                        break;
440:                    }
441:                    case 6: {
442:                        int count = marker & 0xf;
443:                        if (count == 15) {
444:                            count = readCount(in);
445:                        }
446:                        parseUnicodeString(in, count);
447:                        break;
448:                    }
449:                    case 7: {
450:                        System.out.println("parseObjectTable: illegal marker "
451:                                + Integer.toBinaryString(marker));
452:                        return;
453:                        // throw new IOException("parseObjectTable: illegal marker "+Integer.toBinaryString(marker));
454:                        //break;
455:                    }
456:                    case 8: {
457:                        int count = (marker & 0xf) + 1;
458:                        System.out.println("uid " + count);
459:                        break;
460:                    }
461:                    case 9: {
462:                        throw new IOException(
463:                                "parseObjectTable: illegal marker "
464:                                        + Integer.toBinaryString(marker));
465:                        //break;
466:                    }
467:                    case 10: {
468:                        int count = marker & 0xf;
469:                        if (count == 15) {
470:                            count = readCount(in);
471:                        }
472:                        if (refCount > 255) {
473:                            parseShortArray(in, count);
474:                        } else {
475:                            parseByteArray(in, count);
476:                        }
477:                        break;
478:                    }
479:                    case 11: {
480:                        throw new IOException(
481:                                "parseObjectTable: illegal marker "
482:                                        + Integer.toBinaryString(marker));
483:                        //break;
484:                    }
485:                    case 12: {
486:                        throw new IOException(
487:                                "parseObjectTable: illegal marker "
488:                                        + Integer.toBinaryString(marker));
489:                        //break;
490:                    }
491:                    case 13: {
492:                        int count = marker & 0xf;
493:                        if (count == 15) {
494:                            count = readCount(in);
495:                        }
496:                        if (refCount > 256) {
497:                            parseShortDict(in, count);
498:                        } else {
499:                            parseByteDict(in, count);
500:                        }
501:                        break;
502:                    }
503:                    case 14: {
504:                        throw new IOException(
505:                                "parseObjectTable: illegal marker "
506:                                        + Integer.toBinaryString(marker));
507:                        //break;
508:                    }
509:                    case 15: {
510:                        throw new IOException(
511:                                "parseObjectTable: illegal marker "
512:                                        + Integer.toBinaryString(marker));
513:                        //break;
514:                    }
515:                    }
516:                    // System.out.println(objectTable.get(objectTable.size() - 1));
517:                }
518:            }
519:
520:            /**
521:             * Reads a count value from the object table. Count values are encoded
522:             * using the following scheme:
523:             * <p/>
524:             * int	0001 nnnn   ...     // # of bytes is 2^nnnn, big-endian bytes
525:             */
526:            private int readCount(DataInputStream in) throws IOException {
527:                int marker = in.read();
528:                if (marker == -1) {
529:                    throw new IOException(
530:                            "variableLengthInt: Illegal EOF in marker");
531:                }
532:                if (((marker & 0xf0) >> 4) != 1) {
533:                    throw new IOException("variableLengthInt: Illegal marker "
534:                            + Integer.toBinaryString(marker));
535:                }
536:                int count = 1 << (marker & 0xf);
537:                int value = 0;
538:                for (int i = 0; i < count; i++) {
539:                    int b = in.read();
540:                    if (b == -1) {
541:                        throw new IOException(
542:                                "variableLengthInt: Illegal EOF in value");
543:                    }
544:                    value = (value << 8) | b;
545:                }
546:                return value;
547:            }
548:
549:            /**
550:             * null	0000 0000
551:             * bool	0000 1000			// false
552:             * bool	0000 1001			// true
553:             * fill	0000 1111			// fill byte
554:             */
555:            private void parsePrimitive(DataInputStream in, int primitive)
556:                    throws IOException {
557:                switch (primitive) {
558:                case 0:
559:                    objectTable.add(null);
560:                    break;
561:                case 8:
562:                    objectTable.add(Boolean.FALSE);
563:                    break;
564:                case 9:
565:                    objectTable.add(Boolean.TRUE);
566:                    break;
567:                case 15:
568:                    // fill byte: don't add to object table
569:                    break;
570:                default:
571:                    throw new IOException("parsePrimitive: illegal primitive "
572:                            + Integer.toBinaryString(primitive));
573:                }
574:            }
575:
576:            /**
577:             * array	1010 nnnn	[int]	objref*	// nnnn is count, unless '1111', then int count follows
578:             */
579:            private void parseByteArray(DataInputStream in, int count)
580:                    throws IOException {
581:                BPLArray arr = new BPLArray();
582:                arr.objectTable = objectTable;
583:                arr.objref = new int[count];
584:
585:                for (int i = 0; i < count; i++) {
586:                    arr.objref[i] = in.readByte() & 0xff;
587:                    if (arr.objref[i] == -1) {
588:                        throw new IOException(
589:                                "parseByteArray: illegal EOF in objref*");
590:                    }
591:                }
592:
593:                objectTable.add(arr);
594:            }
595:
596:            /**
597:             * array	1010 nnnn	[int]	objref*	// nnnn is count, unless '1111', then int count follows
598:             */
599:            private void parseShortArray(DataInputStream in, int count)
600:                    throws IOException {
601:                BPLArray arr = new BPLArray();
602:                arr.objectTable = objectTable;
603:                arr.objref = new int[count];
604:
605:                for (int i = 0; i < count; i++) {
606:                    arr.objref[i] = in.readShort() & 0xffff;
607:                    if (arr.objref[i] == -1) {
608:                        throw new IOException(
609:                                "parseShortArray: illegal EOF in objref*");
610:                    }
611:                }
612:
613:                objectTable.add(arr);
614:            }
615:
616:            /*
617:             * data	0100 nnnn	[int]	...	// nnnn is number of bytes unless 1111 then int count follows, followed by bytes
618:             */
619:            private void parseData(DataInputStream in, int count)
620:                    throws IOException {
621:                byte[] data = new byte[count];
622:                in.readFully(data);
623:                objectTable.add(data);
624:            }
625:
626:            /**
627:             * byte dict	1101 nnnn keyref* objref*	// nnnn is less than '1111'
628:             */
629:            private void parseByteDict(DataInputStream in, int count)
630:                    throws IOException {
631:                BPLDict dict = new BPLDict();
632:                dict.objectTable = objectTable;
633:                dict.keyref = new int[count];
634:                dict.objref = new int[count];
635:
636:                for (int i = 0; i < count; i++) {
637:                    dict.keyref[i] = in.readByte() & 0xff;
638:                }
639:                for (int i = 0; i < count; i++) {
640:                    dict.objref[i] = in.readByte() & 0xff;
641:                }
642:                objectTable.add(dict);
643:            }
644:
645:            /**
646:             * short dict	1101 ffff int keyref* objref*	// int is count
647:             */
648:            private void parseShortDict(DataInputStream in, int count)
649:                    throws IOException {
650:                BPLDict dict = new BPLDict();
651:                dict.objectTable = objectTable;
652:                dict.keyref = new int[count];
653:                dict.objref = new int[count];
654:
655:                for (int i = 0; i < count; i++) {
656:                    dict.keyref[i] = in.readShort() & 0xffff;
657:                }
658:                for (int i = 0; i < count; i++) {
659:                    dict.objref[i] = in.readShort() & 0xffff;
660:                }
661:                objectTable.add(dict);
662:            }
663:
664:            /**
665:             * string	0101 nnnn	[int]	...	// ASCII string, nnnn is # of chars, else 1111 then int count, then bytes
666:             */
667:            private void parseAsciiString(DataInputStream in, int count)
668:                    throws IOException {
669:                byte[] buf = new byte[count];
670:                in.readFully(buf);
671:                String str = new String(buf, "ASCII");
672:                objectTable.add(str);
673:            }
674:
675:            /**
676:             * int	0001 nnnn	...		// # of bytes is 2^nnnn, big-endian bytes
677:             */
678:            private void parseInt(DataInputStream in, int count)
679:                    throws IOException {
680:                if (count > 8) {
681:                    throw new IOException("parseInt: unsupported byte count:"
682:                            + count);
683:                }
684:                long value = 0;
685:                for (int i = 0; i < count; i++) {
686:                    int b = in.read();
687:                    if (b == -1) {
688:                        throw new IOException("parseInt: Illegal EOF in value");
689:                    }
690:                    value = (value << 8) | b;
691:                }
692:                objectTable.add(value);
693:            }
694:
695:            /**
696:             * real	0010 nnnn	...		// # of bytes is 2^nnnn, big-endian bytes
697:             */
698:            private void parseReal(DataInputStream in, int count)
699:                    throws IOException {
700:                switch (count) {
701:                case 4:
702:                    objectTable.add(in.readFloat());
703:                    break;
704:                case 8:
705:                    objectTable.add(in.readDouble());
706:                    break;
707:                default:
708:                    throw new IOException("parseReal: unsupported byte count:"
709:                            + count);
710:                }
711:            }
712:
713:            /**
714:             * date	0011 0011	...		// 8 byte float follows, big-endian bytes
715:             */
716:            private void parseDate(DataInputStream in) throws IOException {
717:                // XXX - This does not yield a date :(
718:                double date = in.readDouble();
719:                //objectTable.add(new Date((long) date));
720:                objectTable.add(new Date());
721:            }
722:
723:            /**
724:             * string	0110 nnnn	[int]	...	// Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte shorts
725:             */
726:            private void parseUnicodeString(DataInputStream in, int count)
727:                    throws IOException {
728:                char[] buf = new char[count];
729:                for (int i = 0; i < count; i++) {
730:                    buf[i] = in.readChar();
731:                }
732:                String str = new String(buf);
733:                objectTable.add(str);
734:            }
735:
736:            public static void main(String[] args) {
737:
738:                try {
739:                    File[] list = new File(SecurityUtils.getProperty(
740:                            "user.home", ""), "Library/Preferences")
741:                            .listFiles();
742:                    /*
743:                    File[] list = {
744:                        //new File(QuaquaManager.getProperty("user.home"), "Documents/BPList/date.plist")
745:                        new File(QuaquaManager.getProperty("user.home"), "Library/Preferences/ChristopheGlobalPreferences.plist")
746:                    };*/
747:                    for (int i = 0; i < list.length; i++) {
748:                        String name = list[i].getName();
749:                        if (list[i].isDirectory()
750:                                //|| name.startsWith(".")
751:                                || !name.endsWith(".plist")
752:                                || name.endsWith("internetconfig.plist")) {
753:                            continue;
754:                        }
755:                        try {
756:                            System.out.println(list[i]);
757:                            BinaryPListParser bplr = new BinaryPListParser();
758:                            XMLElement xml = bplr.parse(list[i]);
759:                            System.out.println(xml);
760:                        } catch (IOException e) {
761:                            if (e.getMessage() != null
762:                                    && (e.getMessage()
763:                                            .startsWith("parseHeader") || e
764:                                            .getMessage().startsWith(
765:                                                    "parseTrailer"))) {
766:                                System.out.println(e);
767:
768:                                continue;
769:                            } else {
770:                                throw e;
771:                            }
772:                        }
773:                    }
774:                } catch (Throwable e) {
775:                    e.printStackTrace();
776:                }
777:            }
778:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.