Source Code Cross Referenced for struct.java in  » Scripting » jython » org » python » modules » 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 » Scripting » jython » org.python.modules 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1999 Finn Bock.
0003:         *
0004:         * This program contains material copyrighted by:
0005:         * Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
0006:         * The Netherlands.
0007:         */
0008:
0009:        package org.python.modules;
0010:
0011:        import org.python.core.Py;
0012:        import org.python.core.PyException;
0013:        import org.python.core.PyFloat;
0014:        import org.python.core.PyInteger;
0015:        import org.python.core.PyList;
0016:        import org.python.core.PyLong;
0017:        import org.python.core.PyObject;
0018:        import org.python.core.PyString;
0019:        import org.python.core.PyTuple;
0020:        import org.python.core.__builtin__;
0021:
0022:        import java.math.BigInteger;
0023:
0024:        /**
0025:         * This module performs conversions between Python values and C
0026:         * structs represented as Python strings.  It uses <i>format strings</i>
0027:         * (explained below) as compact descriptions of the lay-out of the C
0028:         * structs and the intended conversion to/from Python values.
0029:         *
0030:         * <P>
0031:         * The module defines the following exception and functions:
0032:         *
0033:         * <P>
0034:         * <dl><dt><b><tt>error</tt></b>
0035:         * <dd>
0036:         *   Exception raised on various occasions; argument is a string
0037:         *   describing what is wrong.
0038:         * </dl>
0039:         *
0040:         * <P>
0041:         * <dl><dt><b><tt>pack</tt></b> (<var>fmt, v1, v2,  ...</var>)
0042:         * <dd>
0043:         *   Return a string containing the values
0044:         *   <tt><i>v1</i>, <i>v2</i>,  ...</tt> packed according to the given
0045:         *   format.  The arguments must match the values required by the format
0046:         *   exactly.
0047:         * </dl>
0048:         *
0049:         * <P>
0050:         * <dl><dt><b><tt>unpack</tt>></b> (<var>fmt, string</var>)
0051:         * <dd>
0052:         *   Unpack the string (presumably packed by <tt>pack(<i>fmt</i>,
0053:         *    ...)</tt>) according to the given format.  The result is a
0054:         *   tuple even if it contains exactly one item.  The string must contain
0055:         *   exactly the amount of data required by the format (i.e.
0056:         *   <tt>len(<i>string</i>)</tt> must equal <tt>calcsize(<i>fmt</i>)</tt>).
0057:         * </dl>
0058:         *
0059:         * <P>
0060:         * <dl><dt><b><tt>calcsize</tt></b> (<var>fmt</var>)
0061:         * <dd>
0062:         *   Return the size of the struct (and hence of the string)
0063:         *   corresponding to the given format.
0064:         * </dl>
0065:         *
0066:         * <P>
0067:         * Format characters have the following meaning; the conversion between
0068:         * C and Python values should be obvious given their types:
0069:         *
0070:         * <P>
0071:         * <table border align=center>
0072:         *   <tr><th><b>Format</b></th>
0073:         *       <th align=left><b>C Type</b></th>
0074:         *       <th align=left><b>Python</b></th>
0075:         *   <tr><td align=center><samp>x</samp></td>
0076:         *       <td>pad byte</td>
0077:         *       <td>no value</td>
0078:         *   <tr><td align=center><samp>c</samp></td>
0079:         *       <td><tt>char</tt></td>
0080:         *       <td>string of length 1</td>
0081:         *   <tr><td align=center><samp>b</samp></td>
0082:         *       <td><tt>signed char</tt></td>
0083:         *       <td>integer</td>
0084:         *   <tr><td align=center><samp>B</samp></td>
0085:         *       <td><tt>unsigned char</tt></td>
0086:         *       <td>integer</td>
0087:         *   <tr><td align=center><samp>h</samp></td>
0088:         *       <td><tt>short</tt></td>
0089:         *       <td>integer</td>
0090:         *   <tr><td align=center><samp>H</samp></td>
0091:         *       <td><tt>unsigned short</tt></td>
0092:         *       <td>integer</td>
0093:         *   <tr><td align=center><samp>i</samp></td>
0094:         *       <td><tt>int</tt></td>
0095:         *       <td>integer</td>
0096:         *   <tr><td align=center><samp>I</samp></td>
0097:         *       <td><tt>unsigned int</tt></td>
0098:         *       <td>integer</td>
0099:         *   <tr><td align=center><samp>l</samp></td>
0100:         *       <td><tt>long</tt></td>
0101:         *       <td>integer</td>
0102:         *   <tr><td align=center><samp>L</samp></td>
0103:         *       <td><tt>unsigned long</tt></td>
0104:         *       <td>integer</td>
0105:         *   <tr><td align=center><samp>f</samp></td>
0106:         *       <td><tt>float</tt></td>
0107:         *       <td>float</td>
0108:         *   <tr><td align=center><samp>d</samp></td>
0109:         *       <td><tt>double</tt></td>
0110:         *       <td>float</td>
0111:         *   <tr><td align=center><samp>s</samp></td>
0112:         *       <td><tt>char[]</tt></td>
0113:         *       <td>string</td>
0114:         *   <tr><td align=center><samp>p</samp></td>
0115:         *       <td><tt>char[]</tt></td>
0116:         *       <td>string</td>
0117:         * </table>
0118:         *
0119:         * <P>
0120:         * A format character may be preceded by an integral repeat count;
0121:         * e.g. the format string <tt>'4h'</tt> means exactly the same as
0122:         * <tt>'hhhh'</tt>.
0123:         *
0124:         * <P>
0125:         * Whitespace characters between formats are ignored; a count and its
0126:         * format must not contain whitespace though.
0127:         *
0128:         * <P>
0129:         * For the "<tt>s</tt>" format character, the count is interpreted as the
0130:         * size of the string, not a repeat count like for the other format
0131:         * characters; e.g. <tt>'10s'</tt> means a single 10-byte string, while
0132:         * <tt>'10c'</tt> means 10 characters.  For packing, the string is
0133:         * truncated or padded with null bytes as appropriate to make it fit.
0134:         * For unpacking, the resulting string always has exactly the specified
0135:         * number of bytes.  As a special case, <tt>'0s'</tt> means a single, empty
0136:         * string (while <tt>'0c'</tt> means 0 characters).
0137:         *
0138:         * <P>
0139:         * The "<tt>p</tt>" format character can be used to encode a Pascal
0140:         * string.  The first byte is the length of the stored string, with the
0141:         * bytes of the string following.  If count is given, it is used as the
0142:         * total number of bytes used, including the length byte.  If the string
0143:         * passed in to <tt>pack()</tt> is too long, the stored representation
0144:         * is truncated.  If the string is too short, padding is used to ensure
0145:         * that exactly enough bytes are used to satisfy the count.
0146:         *
0147:         * <P>
0148:         * For the "<tt>I</tt>" and "<tt>L</tt>" format characters, the return
0149:         * value is a Python long integer.
0150:         *
0151:         * <P>
0152:         * By default, C numbers are represented in the machine's native format
0153:         * and byte order, and properly aligned by skipping pad bytes if
0154:         * necessary (according to the rules used by the C compiler).
0155:         *
0156:         * <P>
0157:         * Alternatively, the first character of the format string can be used to
0158:         * indicate the byte order, size and alignment of the packed data,
0159:         * according to the following table:
0160:         *
0161:         * <P>
0162:         * <table border align=center>
0163:         *
0164:         *   <tr><th><b>Character</b></th>
0165:         *       <th align=left><b>Byte order</b></th>
0166:         *       <th align=left><b>Size and alignment</b></th>
0167:         *   <tr><td align=center><samp>@</samp></td>
0168:         *       <td>native</td>
0169:         *       <td>native</td>
0170:         *   <tr><td align=center><samp>=</samp></td>
0171:         *       <td>native</td>
0172:         *       <td>standard</td>
0173:         *   <tr><td align=center><samp>&lt;</samp></td>
0174:         *       <td>little-endian</td>
0175:         *       <td>standard</td>
0176:         *   <tr><td align=center><samp>&gt;</samp></td>
0177:         *       <td>big-endian</td>
0178:         *       <td>standard</td>
0179:         *   <tr><td align=center><samp>!</samp></td>
0180:         *       <td>network (= big-endian)</td>
0181:         *       <td>standard</td>
0182:         *
0183:         * </table>
0184:         *
0185:         * <P>
0186:         * If the first character is not one of these, "<tt>@</tt>" is assumed.
0187:         *
0188:         * <P>
0189:         * Native byte order is big-endian or little-endian, depending on the
0190:         * host system (e.g. Motorola and Sun are big-endian; Intel and DEC are
0191:         * little-endian).
0192:         *
0193:         * <P>
0194:         * Native size and alignment are defined as follows: <tt>short</tt> is
0195:         * 2 bytes; <tt>int</tt> and <tt>long</tt> are 4 bytes; <tt>float</tt>
0196:         * are 4 bytes and <tt>double</tt> are 8 bytes. Native byte order is
0197:         * chosen as big-endian.
0198:         *
0199:         * <P>
0200:         * Standard size and alignment are as follows: no alignment is required
0201:         * for any type (so you have to use pad bytes); <tt>short</tt> is 2 bytes;
0202:         * <tt>int</tt> and <tt>long</tt> are 4 bytes.  <tt>float</tt> and
0203:         * <tt>double</tt> are 32-bit and 64-bit IEEE floating point numbers,
0204:         * respectively.
0205:         *
0206:         * <P>
0207:         * Note the difference between "<tt>@</tt>" and "<tt>=</tt>": both use
0208:         * native byte order, but the size and alignment of the latter is
0209:         * standardized.
0210:         *
0211:         * <P>
0212:         * The form "<tt>!</tt>" is available for those poor souls who claim they
0213:         * can't remember whether network byte order is big-endian or
0214:         * little-endian.
0215:         *
0216:         * <P>
0217:         * There is no way to indicate non-native byte order (i.e. force
0218:         * byte-swapping); use the appropriate choice of "<tt>&lt;</tt>" or
0219:         * "<tt>&gt;</tt>".
0220:         *
0221:         * <P>
0222:         * Examples (all using native byte order, size and alignment, on a
0223:         * big-endian machine):
0224:         *
0225:         * <P>
0226:         * <dl><dd><pre>
0227:         * &gt;&gt;&gt; from struct import *
0228:         * &gt;&gt;&gt; pack('hhl', 1, 2, 3)
0229:         * '\000\001\000\002\000\000\000\003'
0230:         * &gt;&gt;&gt; unpack('hhl', '\000\001\000\002\000\000\000\003')
0231:         * (1, 2, 3)
0232:         * &gt;&gt;&gt; calcsize('hhl')
0233:         * 8
0234:         * &gt;&gt;&gt;
0235:         * </pre></dl>
0236:         *
0237:         * <P>
0238:         * Hint: to align the end of a structure to the alignment requirement of
0239:         * a particular type, end the format with the code for that type with a
0240:         * repeat count of zero, e.g. the format <tt>'llh0l'</tt> specifies two
0241:         * pad bytes at the end, assuming longs are aligned on 4-byte boundaries.
0242:         * This only works when native size and alignment are in effect;
0243:         * standard size and alignment does not enforce any alignment.
0244:         *
0245:         * For the complete documentation on the struct module, please see the
0246:         * "Python Library Reference"
0247:         * <p><hr><p>
0248:         *
0249:         * The module is based on the original structmodule.c except that all
0250:         * mistakes and errors are my own. Original author unknown.
0251:         * <p>
0252:         * @author Finn Bock, bckfnn@pipmail.dknet.dk
0253:         * @version struct.java,v 1.6 1999/04/17 12:04:34 fb Exp
0254:         */
0255:        public class struct {
0256:
0257:            /**
0258:             * Exception raised on various occasions; argument is a
0259:             * string describing what is wrong.
0260:             */
0261:            public static PyString error = new PyString("struct.error");
0262:
0263:            public static String __doc__ = "Functions to convert between Python values and C structs.\n"
0264:                    + "Python strings are used to hold the data representing the C\n"
0265:                    + "struct and also as format strings to describe the layout of\n"
0266:                    + "data in the C struct.\n"
0267:                    + "\n"
0268:                    + "The optional first format char indicates byte ordering and\n"
0269:                    + "alignment:\n"
0270:                    + " @: native w/native alignment(default)\n"
0271:                    + " =: native w/standard alignment\n"
0272:                    + " <: little-endian, std. alignment\n"
0273:                    + " >: big-endian, std. alignment\n"
0274:                    + " !: network, std (same as >)\n"
0275:                    + "\n"
0276:                    + "The remaining chars indicate types of args and must match\n"
0277:                    + "exactly; these can be preceded by a decimal repeat count:\n"
0278:                    + " x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n"
0279:                    + " h:short; H:unsigned short; i:int; I:unsigned int;\n"
0280:                    + " l:long; L:unsigned long; f:float; d:double.\n"
0281:                    + "Special cases (preceding decimal count indicates length):\n"
0282:                    + " s:string (array of char); p: pascal string (w. count byte).\n"
0283:                    + "Whitespace between formats is ignored.\n"
0284:                    + "\n"
0285:                    + "The variable struct.error is an exception raised on errors.";
0286:
0287:            static class FormatDef {
0288:                char name;
0289:                int size;
0290:                int alignment;
0291:
0292:                FormatDef init(char name, int size, int alignment) {
0293:                    this .name = name;
0294:                    this .size = size;
0295:                    this .alignment = alignment;
0296:                    return this ;
0297:                }
0298:
0299:                void pack(ByteStream buf, PyObject value) {
0300:                }
0301:
0302:                Object unpack(ByteStream buf) {
0303:                    return null;
0304:                }
0305:
0306:                int doPack(ByteStream buf, int count, int pos, PyObject[] args) {
0307:                    if (pos + count > args.length)
0308:                        throw StructError("insufficient arguments to pack");
0309:
0310:                    int cnt = count;
0311:                    while (count-- > 0)
0312:                        pack(buf, args[pos++]);
0313:                    return cnt;
0314:                }
0315:
0316:                void doUnpack(ByteStream buf, int count, PyList list) {
0317:                    while (count-- > 0)
0318:                        list.append(Py.java2py(unpack(buf)));
0319:                }
0320:
0321:                int get_int(PyObject value) {
0322:                    try {
0323:                        return ((PyInteger) value.__int__()).getValue();
0324:                    } catch (PyException ex) {
0325:                        throw StructError("required argument is not an integer");
0326:                    }
0327:                }
0328:
0329:                long get_long(PyObject value) {
0330:                    if (value instanceof  PyLong) {
0331:                        Object v = value.__tojava__(Long.TYPE);
0332:                        if (v == Py.NoConversion)
0333:                            throw Py
0334:                                    .OverflowError("long int too long to convert");
0335:                        return ((Long) v).longValue();
0336:                    } else
0337:                        return get_int(value);
0338:                }
0339:
0340:                BigInteger get_ulong(PyObject value) {
0341:                    if (value instanceof  PyLong) {
0342:                        BigInteger v = (BigInteger) value
0343:                                .__tojava__(BigInteger.class);
0344:                        if (v.compareTo(PyLong.maxULong) > 0) {
0345:                            throw Py
0346:                                    .OverflowError("unsigned long int too long to convert");
0347:                        }
0348:                        return v;
0349:                    } else
0350:                        return BigInteger.valueOf(get_int(value));
0351:                }
0352:
0353:                double get_float(PyObject value) {
0354:                    if (!(value instanceof  PyFloat))
0355:                        throw StructError("required argument is not an float");
0356:                    return value.__float__().getValue();
0357:                }
0358:
0359:                void BEwriteInt(ByteStream buf, int v) {
0360:                    buf.writeByte((int) (v >>> 24) & 0xFF);
0361:                    buf.writeByte((int) (v >>> 16) & 0xFF);
0362:                    buf.writeByte((int) (v >>> 8) & 0xFF);
0363:                    buf.writeByte((int) (v >>> 0) & 0xFF);
0364:                }
0365:
0366:                void LEwriteInt(ByteStream buf, int v) {
0367:                    buf.writeByte((int) (v >>> 0) & 0xFF);
0368:                    buf.writeByte((int) (v >>> 8) & 0xFF);
0369:                    buf.writeByte((int) (v >>> 16) & 0xFF);
0370:                    buf.writeByte((int) (v >>> 24) & 0xFF);
0371:                }
0372:
0373:                int BEreadInt(ByteStream buf) {
0374:                    int b1 = buf.readByte();
0375:                    int b2 = buf.readByte();
0376:                    int b3 = buf.readByte();
0377:                    int b4 = buf.readByte();
0378:                    return ((b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0));
0379:                }
0380:
0381:                int LEreadInt(ByteStream buf) {
0382:                    int b1 = buf.readByte();
0383:                    int b2 = buf.readByte();
0384:                    int b3 = buf.readByte();
0385:                    int b4 = buf.readByte();
0386:                    return ((b1 << 0) + (b2 << 8) + (b3 << 16) + (b4 << 24));
0387:                }
0388:            }
0389:
0390:            static class ByteStream {
0391:                char[] data;
0392:                int len;
0393:                int pos;
0394:
0395:                ByteStream() {
0396:                    data = new char[10];
0397:                    len = 0;
0398:                    pos = 0;
0399:                }
0400:
0401:                ByteStream(String s) {
0402:                    int l = s.length();
0403:                    data = new char[l];
0404:                    s.getChars(0, l, data, 0);
0405:                    len = l;
0406:                    pos = 0;
0407:                }
0408:
0409:                int readByte() {
0410:                    return data[pos++] & 0xFF;
0411:                }
0412:
0413:                void read(char[] buf, int pos, int len) {
0414:                    System.arraycopy(data, this .pos, buf, pos, len);
0415:                    this .pos += len;
0416:                }
0417:
0418:                String readString(int l) {
0419:                    char[] data = new char[l];
0420:                    read(data, 0, l);
0421:                    return new String(data);
0422:                }
0423:
0424:                private void ensureCapacity(int l) {
0425:                    if (pos + l >= data.length) {
0426:                        char[] b = new char[(pos + l) * 2];
0427:                        System.arraycopy(data, 0, b, 0, pos);
0428:                        data = b;
0429:                    }
0430:                }
0431:
0432:                void writeByte(int b) {
0433:                    ensureCapacity(1);
0434:                    data[pos++] = (char) (b & 0xFF);
0435:                }
0436:
0437:                void write(char[] buf, int pos, int len) {
0438:                    ensureCapacity(len);
0439:                    System.arraycopy(buf, pos, data, this .pos, len);
0440:                    this .pos += len;
0441:                }
0442:
0443:                void writeString(String s, int pos, int len) {
0444:                    char[] data = new char[len];
0445:                    s.getChars(pos, len, data, 0);
0446:                    write(data, 0, len);
0447:                }
0448:
0449:                int skip(int l) {
0450:                    pos += l;
0451:                    return pos;
0452:                }
0453:
0454:                int size() {
0455:                    return pos;
0456:                }
0457:
0458:                public String toString() {
0459:                    return new String(data, 0, pos);
0460:                }
0461:            }
0462:
0463:            static class PadFormatDef extends FormatDef {
0464:                int doPack(ByteStream buf, int count, int pos, PyObject[] args) {
0465:                    while (count-- > 0)
0466:                        buf.writeByte(0);
0467:                    return 0;
0468:                }
0469:
0470:                void doUnpack(ByteStream buf, int count, PyList list) {
0471:                    while (count-- > 0)
0472:                        buf.readByte();
0473:                }
0474:            }
0475:
0476:            static class StringFormatDef extends FormatDef {
0477:                int doPack(ByteStream buf, int count, int pos, PyObject[] args) {
0478:                    PyObject value = args[pos];
0479:
0480:                    if (!(value instanceof  PyString))
0481:                        throw StructError("argument for 's' must be a string");
0482:
0483:                    String s = value.toString();
0484:                    int len = s.length();
0485:                    buf.writeString(s, 0, Math.min(count, len));
0486:                    if (len < count) {
0487:                        count -= len;
0488:                        for (int i = 0; i < count; i++)
0489:                            buf.writeByte(0);
0490:                    }
0491:                    return 1;
0492:                }
0493:
0494:                void doUnpack(ByteStream buf, int count, PyList list) {
0495:                    list.append(Py.newString(buf.readString(count)));
0496:                }
0497:            }
0498:
0499:            static class PascalStringFormatDef extends StringFormatDef {
0500:                int doPack(ByteStream buf, int count, int pos, PyObject[] args) {
0501:                    PyObject value = args[pos];
0502:
0503:                    if (!(value instanceof  PyString))
0504:                        throw StructError("argument for 'p' must be a string");
0505:
0506:                    buf.writeByte(Math.min(0xFF, Math.min(value.toString()
0507:                            .length(), count - 1)));
0508:                    return super .doPack(buf, count - 1, pos, args);
0509:                }
0510:
0511:                void doUnpack(ByteStream buf, int count, PyList list) {
0512:                    int n = buf.readByte();
0513:                    if (n >= count)
0514:                        n = count - 1;
0515:                    super .doUnpack(buf, n, list);
0516:                    buf.skip(Math.max(count - n - 1, 0));
0517:                }
0518:            }
0519:
0520:            static class CharFormatDef extends FormatDef {
0521:                void pack(ByteStream buf, PyObject value) {
0522:                    if (!(value instanceof  PyString) || value.__len__() != 1)
0523:                        throw StructError("char format require string of length 1");
0524:                    buf.writeByte(value.toString().charAt(0));
0525:                }
0526:
0527:                Object unpack(ByteStream buf) {
0528:                    return Py.newString((char) buf.readByte());
0529:                }
0530:            }
0531:
0532:            static class ByteFormatDef extends FormatDef {
0533:                void pack(ByteStream buf, PyObject value) {
0534:                    buf.writeByte(get_int(value));
0535:                }
0536:
0537:                Object unpack(ByteStream buf) {
0538:                    int b = buf.readByte();
0539:                    if (b > Byte.MAX_VALUE)
0540:                        b -= 0x100;
0541:                    return Py.newInteger(b);
0542:                }
0543:            }
0544:
0545:            static class UnsignedByteFormatDef extends ByteFormatDef {
0546:                Object unpack(ByteStream buf) {
0547:                    return Py.newInteger(buf.readByte());
0548:                }
0549:            }
0550:
0551:            static class LEShortFormatDef extends FormatDef {
0552:                void pack(ByteStream buf, PyObject value) {
0553:                    int v = get_int(value);
0554:                    buf.writeByte(v & 0xFF);
0555:                    buf.writeByte((v >> 8) & 0xFF);
0556:                }
0557:
0558:                Object unpack(ByteStream buf) {
0559:                    int v = buf.readByte() | (buf.readByte() << 8);
0560:                    if (v > Short.MAX_VALUE)
0561:                        v -= 0x10000;
0562:                    return Py.newInteger(v);
0563:                }
0564:            }
0565:
0566:            static class LEUnsignedShortFormatDef extends LEShortFormatDef {
0567:                Object unpack(ByteStream buf) {
0568:                    int v = buf.readByte() | (buf.readByte() << 8);
0569:                    return Py.newInteger(v);
0570:                }
0571:            }
0572:
0573:            static class BEShortFormatDef extends FormatDef {
0574:                void pack(ByteStream buf, PyObject value) {
0575:                    int v = get_int(value);
0576:                    buf.writeByte((v >> 8) & 0xFF);
0577:                    buf.writeByte(v & 0xFF);
0578:                }
0579:
0580:                Object unpack(ByteStream buf) {
0581:                    int v = (buf.readByte() << 8) | buf.readByte();
0582:                    if (v > Short.MAX_VALUE)
0583:                        v -= 0x10000;
0584:                    return Py.newInteger(v);
0585:                }
0586:            }
0587:
0588:            static class BEUnsignedShortFormatDef extends BEShortFormatDef {
0589:                Object unpack(ByteStream buf) {
0590:                    int v = (buf.readByte() << 8) | buf.readByte();
0591:                    return Py.newInteger(v);
0592:                }
0593:            }
0594:
0595:            static class LEIntFormatDef extends FormatDef {
0596:                void pack(ByteStream buf, PyObject value) {
0597:                    LEwriteInt(buf, get_int(value));
0598:                }
0599:
0600:                Object unpack(ByteStream buf) {
0601:                    int v = LEreadInt(buf);
0602:                    return Py.newInteger(v);
0603:                }
0604:            }
0605:
0606:            static class LEUnsignedIntFormatDef extends FormatDef {
0607:                void pack(ByteStream buf, PyObject value) {
0608:                    LEwriteInt(buf, (int) (get_long(value) & 0xFFFFFFFF));
0609:                }
0610:
0611:                Object unpack(ByteStream buf) {
0612:                    long v = LEreadInt(buf);
0613:                    if (v < 0)
0614:                        v += 0x100000000L;
0615:                    return new PyLong(v);
0616:                }
0617:            }
0618:
0619:            static class BEIntFormatDef extends FormatDef {
0620:                void pack(ByteStream buf, PyObject value) {
0621:                    BEwriteInt(buf, get_int(value));
0622:                }
0623:
0624:                Object unpack(ByteStream buf) {
0625:                    return Py.newInteger(BEreadInt(buf));
0626:                }
0627:            }
0628:
0629:            static class BEUnsignedIntFormatDef extends FormatDef {
0630:                void pack(ByteStream buf, PyObject value) {
0631:                    BEwriteInt(buf, (int) (get_long(value) & 0xFFFFFFFF));
0632:                }
0633:
0634:                Object unpack(ByteStream buf) {
0635:                    long v = BEreadInt(buf);
0636:                    if (v < 0)
0637:                        v += 0x100000000L;
0638:                    return new PyLong(v);
0639:                }
0640:            }
0641:
0642:            static class LEUnsignedLongFormatDef extends FormatDef {
0643:                void pack(ByteStream buf, PyObject value) {
0644:                    BigInteger bi = get_ulong(value);
0645:                    if (bi.compareTo(BigInteger.valueOf(0)) < 0) {
0646:                        throw StructError("can't convert negative long to unsigned");
0647:                    }
0648:                    long lvalue = bi.longValue(); // underflow is OK -- the bits are correct
0649:                    int high = (int) ((lvalue & 0xFFFFFFFF00000000L) >> 32);
0650:                    int low = (int) (lvalue & 0x00000000FFFFFFFFL);
0651:                    LEwriteInt(buf, low);
0652:                    LEwriteInt(buf, high);
0653:                }
0654:
0655:                Object unpack(ByteStream buf) {
0656:                    long low = (LEreadInt(buf) & 0X00000000FFFFFFFFL);
0657:                    long high = (LEreadInt(buf) & 0X00000000FFFFFFFFL);
0658:                    java.math.BigInteger result = java.math.BigInteger
0659:                            .valueOf(high);
0660:                    result = result.multiply(java.math.BigInteger
0661:                            .valueOf(0x100000000L));
0662:                    result = result.add(java.math.BigInteger.valueOf(low));
0663:                    return new PyLong(result);
0664:                }
0665:            }
0666:
0667:            static class BEUnsignedLongFormatDef extends FormatDef {
0668:                void pack(ByteStream buf, PyObject value) {
0669:                    BigInteger bi = get_ulong(value);
0670:                    if (bi.compareTo(BigInteger.valueOf(0)) < 0) {
0671:                        throw StructError("can't convert negative long to unsigned");
0672:                    }
0673:                    long lvalue = bi.longValue(); // underflow is OK -- the bits are correct
0674:                    int high = (int) ((lvalue & 0xFFFFFFFF00000000L) >> 32);
0675:                    int low = (int) (lvalue & 0x00000000FFFFFFFFL);
0676:                    BEwriteInt(buf, high);
0677:                    BEwriteInt(buf, low);
0678:                }
0679:
0680:                Object unpack(ByteStream buf) {
0681:                    long high = (BEreadInt(buf) & 0X00000000FFFFFFFFL);
0682:                    long low = (BEreadInt(buf) & 0X00000000FFFFFFFFL);
0683:                    java.math.BigInteger result = java.math.BigInteger
0684:                            .valueOf(high);
0685:                    result = result.multiply(java.math.BigInteger
0686:                            .valueOf(0x100000000L));
0687:                    result = result.add(java.math.BigInteger.valueOf(low));
0688:                    return new PyLong(result);
0689:                }
0690:            }
0691:
0692:            static class LELongFormatDef extends FormatDef {
0693:                void pack(ByteStream buf, PyObject value) {
0694:                    long lvalue = get_long(value);
0695:                    int high = (int) ((lvalue & 0xFFFFFFFF00000000L) >> 32);
0696:                    int low = (int) (lvalue & 0x00000000FFFFFFFFL);
0697:                    LEwriteInt(buf, low);
0698:                    LEwriteInt(buf, high);
0699:                }
0700:
0701:                Object unpack(ByteStream buf) {
0702:                    long low = LEreadInt(buf) & 0x00000000FFFFFFFFL;
0703:                    long high = ((long) (LEreadInt(buf)) << 32) & 0xFFFFFFFF00000000L;
0704:                    long result = (high | low);
0705:                    return new PyLong(result);
0706:                }
0707:            }
0708:
0709:            static class BELongFormatDef extends FormatDef {
0710:                void pack(ByteStream buf, PyObject value) {
0711:                    long lvalue = get_long(value);
0712:                    int high = (int) ((lvalue & 0xFFFFFFFF00000000L) >> 32);
0713:                    int low = (int) (lvalue & 0x00000000FFFFFFFFL);
0714:                    BEwriteInt(buf, high);
0715:                    BEwriteInt(buf, low);
0716:                }
0717:
0718:                Object unpack(ByteStream buf) {
0719:                    long high = ((long) (BEreadInt(buf)) << 32) & 0xFFFFFFFF00000000L;
0720:                    long low = BEreadInt(buf) & 0x00000000FFFFFFFFL;
0721:                    long result = (high | low);
0722:                    return new PyLong(result);
0723:                }
0724:            }
0725:
0726:            static class LEFloatFormatDef extends FormatDef {
0727:                void pack(ByteStream buf, PyObject value) {
0728:                    int bits = Float.floatToIntBits((float) get_float(value));
0729:                    LEwriteInt(buf, bits);
0730:                }
0731:
0732:                Object unpack(ByteStream buf) {
0733:                    int v = LEreadInt(buf);
0734:                    return Py.newFloat(Float.intBitsToFloat(v));
0735:                }
0736:            }
0737:
0738:            static class LEDoubleFormatDef extends FormatDef {
0739:                void pack(ByteStream buf, PyObject value) {
0740:                    long bits = Double.doubleToLongBits(get_float(value));
0741:                    LEwriteInt(buf, (int) (bits & 0xFFFFFFFF));
0742:                    LEwriteInt(buf, (int) (bits >>> 32));
0743:                }
0744:
0745:                Object unpack(ByteStream buf) {
0746:                    long bits = (LEreadInt(buf) & 0xFFFFFFFFL)
0747:                            + (((long) LEreadInt(buf)) << 32);
0748:                    return Py.newFloat(Double.longBitsToDouble(bits));
0749:                }
0750:            }
0751:
0752:            static class BEFloatFormatDef extends FormatDef {
0753:                void pack(ByteStream buf, PyObject value) {
0754:                    int bits = Float.floatToIntBits((float) get_float(value));
0755:                    BEwriteInt(buf, bits);
0756:                }
0757:
0758:                Object unpack(ByteStream buf) {
0759:                    int v = BEreadInt(buf);
0760:                    return Py.newFloat(Float.intBitsToFloat(v));
0761:                }
0762:            }
0763:
0764:            static class BEDoubleFormatDef extends FormatDef {
0765:                void pack(ByteStream buf, PyObject value) {
0766:                    long bits = Double.doubleToLongBits(get_float(value));
0767:                    BEwriteInt(buf, (int) (bits >>> 32));
0768:                    BEwriteInt(buf, (int) (bits & 0xFFFFFFFF));
0769:                }
0770:
0771:                Object unpack(ByteStream buf) {
0772:                    long bits = (((long) BEreadInt(buf)) << 32)
0773:                            + (BEreadInt(buf) & 0xFFFFFFFFL);
0774:                    return Py.newFloat(Double.longBitsToDouble(bits));
0775:                }
0776:            }
0777:
0778:            private static FormatDef[] lilendian_table = {
0779:                    new PadFormatDef().init('x', 1, 0),
0780:                    new ByteFormatDef().init('b', 1, 0),
0781:                    new UnsignedByteFormatDef().init('B', 1, 0),
0782:                    new CharFormatDef().init('c', 1, 0),
0783:                    new StringFormatDef().init('s', 1, 0),
0784:                    new PascalStringFormatDef().init('p', 1, 0),
0785:                    new LEShortFormatDef().init('h', 2, 0),
0786:                    new LEUnsignedShortFormatDef().init('H', 2, 0),
0787:                    new LEIntFormatDef().init('i', 4, 0),
0788:                    new LEUnsignedIntFormatDef().init('I', 4, 0),
0789:                    new LEIntFormatDef().init('l', 4, 0),
0790:                    new LEUnsignedIntFormatDef().init('L', 4, 0),
0791:                    new LELongFormatDef().init('q', 8, 8),
0792:                    new LEUnsignedLongFormatDef().init('Q', 8, 8),
0793:                    new LEFloatFormatDef().init('f', 4, 0),
0794:                    new LEDoubleFormatDef().init('d', 8, 0), };
0795:
0796:            private static FormatDef[] bigendian_table = {
0797:                    new PadFormatDef().init('x', 1, 0),
0798:                    new ByteFormatDef().init('b', 1, 0),
0799:                    new UnsignedByteFormatDef().init('B', 1, 0),
0800:                    new CharFormatDef().init('c', 1, 0),
0801:                    new StringFormatDef().init('s', 1, 0),
0802:                    new PascalStringFormatDef().init('p', 1, 0),
0803:                    new BEShortFormatDef().init('h', 2, 0),
0804:                    new BEUnsignedShortFormatDef().init('H', 2, 0),
0805:                    new BEIntFormatDef().init('i', 4, 0),
0806:                    new BEUnsignedIntFormatDef().init('I', 4, 0),
0807:                    new BEIntFormatDef().init('l', 4, 0),
0808:                    new BEUnsignedIntFormatDef().init('L', 4, 0),
0809:                    new BELongFormatDef().init('q', 8, 8),
0810:                    new BEUnsignedLongFormatDef().init('Q', 8, 8),
0811:                    new BEFloatFormatDef().init('f', 4, 0),
0812:                    new BEDoubleFormatDef().init('d', 8, 0), };
0813:
0814:            private static FormatDef[] native_table = {
0815:                    new PadFormatDef().init('x', 1, 0),
0816:                    new ByteFormatDef().init('b', 1, 0),
0817:                    new UnsignedByteFormatDef().init('B', 1, 0),
0818:                    new CharFormatDef().init('c', 1, 0),
0819:                    new StringFormatDef().init('s', 1, 0),
0820:                    new PascalStringFormatDef().init('p', 1, 0),
0821:                    new BEShortFormatDef().init('h', 2, 2),
0822:                    new BEUnsignedShortFormatDef().init('H', 2, 2),
0823:                    new BEIntFormatDef().init('i', 4, 4),
0824:                    new BEUnsignedIntFormatDef().init('I', 4, 4),
0825:                    new BEIntFormatDef().init('l', 4, 4),
0826:                    new BEUnsignedIntFormatDef().init('L', 4, 4),
0827:                    new BELongFormatDef().init('q', 8, 8),
0828:                    new BEUnsignedLongFormatDef().init('Q', 8, 8),
0829:                    new BEFloatFormatDef().init('f', 4, 4),
0830:                    new BEDoubleFormatDef().init('d', 8, 8), };
0831:
0832:            private static FormatDef[] whichtable(String pfmt) {
0833:                char c = pfmt.charAt(0);
0834:                switch (c) {
0835:                case '<':
0836:                    return lilendian_table;
0837:                case '>':
0838:                case '!':
0839:                    // Network byte order is big-endian
0840:                    return bigendian_table;
0841:                case '=':
0842:                    return bigendian_table;
0843:                case '@':
0844:                default:
0845:                    return native_table;
0846:                }
0847:            }
0848:
0849:            private static FormatDef getentry(char c, FormatDef[] f) {
0850:                for (int i = 0; i < f.length; i++) {
0851:                    if (f[i].name == c)
0852:                        return f[i];
0853:                }
0854:                throw StructError("bad char in struct format");
0855:            }
0856:
0857:            private static int align(int size, FormatDef e) {
0858:                if (e.alignment != 0) {
0859:                    size = ((size + e.alignment - 1) / e.alignment)
0860:                            * e.alignment;
0861:                }
0862:                return size;
0863:            }
0864:
0865:            private static int calcsize(String format, FormatDef[] f) {
0866:                int size = 0;
0867:
0868:                int len = format.length();
0869:                for (int j = 0; j < len; j++) {
0870:                    char c = format.charAt(j);
0871:                    if (j == 0
0872:                            && (c == '@' || c == '<' || c == '>' || c == '=' || c == '!'))
0873:                        continue;
0874:                    if (Character.isWhitespace(c))
0875:                        continue;
0876:                    int num = 1;
0877:                    if (Character.isDigit(c)) {
0878:                        num = Character.digit(c, 10);
0879:                        while (++j < len
0880:                                && Character.isDigit((c = format.charAt(j)))) {
0881:                            int x = num * 10 + Character.digit(c, 10);
0882:                            if (x / 10 != num)
0883:                                throw StructError("overflow in item count");
0884:                            num = x;
0885:                        }
0886:                        if (j >= len)
0887:                            break;
0888:                    }
0889:
0890:                    FormatDef e = getentry(c, f);
0891:
0892:                    int itemsize = e.size;
0893:                    size = align(size, e);
0894:                    int x = num * itemsize;
0895:                    size += x;
0896:                    if (x / itemsize != num || size < 0)
0897:                        throw StructError("total struct size too long");
0898:                }
0899:                return size;
0900:            }
0901:
0902:            /**
0903:             * Return the size of the struct (and hence of the string)
0904:             * corresponding to the given format.
0905:             */
0906:            static public int calcsize(String format) {
0907:                FormatDef[] f = whichtable(format);
0908:                return calcsize(format, f);
0909:            }
0910:
0911:            /**
0912:             * Return a string containing the values v1, v2, ... packed according
0913:             * to the given format. The arguments must match the
0914:             * values required by the format exactly.
0915:             */
0916:            static public String pack(PyObject[] args) {
0917:                if (args.length < 1)
0918:                    Py
0919:                            .TypeError("illegal argument type for built-in operation");
0920:
0921:                String format = args[0].toString();
0922:
0923:                FormatDef[] f = whichtable(format);
0924:                int size = calcsize(format, f);
0925:
0926:                ByteStream res = new ByteStream();
0927:
0928:                int i = 1;
0929:                int len = format.length();
0930:                for (int j = 0; j < len; j++) {
0931:                    char c = format.charAt(j);
0932:                    if (j == 0
0933:                            && (c == '@' || c == '<' || c == '>' || c == '=' || c == '!'))
0934:                        continue;
0935:                    if (Character.isWhitespace(c))
0936:                        continue;
0937:                    int num = 1;
0938:                    if (Character.isDigit(c)) {
0939:                        num = Character.digit(c, 10);
0940:                        while (++j < len
0941:                                && Character.isDigit((c = format.charAt(j))))
0942:                            num = num * 10 + Character.digit(c, 10);
0943:                        if (j >= len)
0944:                            break;
0945:                    }
0946:
0947:                    FormatDef e = getentry(c, f);
0948:
0949:                    // Fill padd bytes with zeros
0950:                    int nres = align(res.size(), e) - res.size();
0951:                    while (nres-- > 0)
0952:                        res.writeByte(0);
0953:                    i += e.doPack(res, num, i, args);
0954:                }
0955:
0956:                if (i < args.length)
0957:                    throw StructError("too many arguments for pack format");
0958:
0959:                return res.toString();
0960:            }
0961:
0962:            /**
0963:             * Unpack the string (presumably packed by pack(fmt, ...)) according
0964:             * to the given format. The result is a tuple even if it contains
0965:             * exactly one item.
0966:             * The string must contain exactly the amount of data required by
0967:             * the format (i.e. len(string) must equal calcsize(fmt)).
0968:             */
0969:            public static PyTuple unpack(String format, String string) {
0970:                int len = string.length();
0971:
0972:                FormatDef[] f = whichtable(format);
0973:                int size = calcsize(format, f);
0974:
0975:                if (size != len)
0976:                    throw StructError("unpack str size does not match format");
0977:
0978:                PyList res = new PyList();
0979:
0980:                ByteStream str = new ByteStream(string);
0981:
0982:                int flen = format.length();
0983:                for (int j = 0; j < flen; j++) {
0984:                    char c = format.charAt(j);
0985:                    if (j == 0
0986:                            && (c == '@' || c == '<' || c == '>' || c == '=' || c == '!'))
0987:                        continue;
0988:                    if (Character.isWhitespace(c))
0989:                        continue;
0990:                    int num = 1;
0991:                    if (Character.isDigit(c)) {
0992:                        num = Character.digit(c, 10);
0993:                        while (++j < flen
0994:                                && Character.isDigit((c = format.charAt(j))))
0995:                            num = num * 10 + Character.digit(c, 10);
0996:                        if (j > flen)
0997:                            break;
0998:                    }
0999:
1000:                    FormatDef e = getentry(c, f);
1001:
1002:                    str.skip(align(str.size(), e) - str.size());
1003:
1004:                    e.doUnpack(str, num, res);
1005:                }
1006:                return __builtin__.tuple(res);
1007:            }
1008:
1009:            private static PyException StructError(String explanation) {
1010:                return new PyException(error, explanation);
1011:            }
1012:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.