Skip to content

Commit c1a8582

Browse files
committed
Turn marshal into a proper module
1 parent 3770178 commit c1a8582

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

marshal/marshal.go

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
)
1313

1414
const (
15+
MARSHAL_VERSION = 2
1516
TYPE_NULL = '0'
1617
TYPE_NONE = 'N'
1718
TYPE_FALSE = 'F'
@@ -361,3 +362,169 @@ func ReadPyc(r io.Reader) (obj py.Object, err error) {
361362
// fmt.Printf("header = %v\n", header)
362363
return ReadObject(r)
363364
}
365+
366+
const dump_doc = `dump(value, file[, version])
367+
368+
Write the value on the open file. The value must be a supported type.
369+
The file must be an open file object such as sys.stdout or returned by
370+
open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').
371+
372+
If the value has (or contains an object that has) an unsupported type, a
373+
ValueError exception is raised — but garbage data will also be written
374+
to the file. The object will not be properly read back by load()
375+
376+
The version argument indicates the data format that dump should use.`
377+
378+
func marshal_dump(self py.Object, args py.Tuple) py.Object {
379+
/*
380+
// XXX Quick hack -- need to do this differently
381+
PyObject *x;
382+
PyObject *f;
383+
int version = Py_MARSHAL_VERSION;
384+
PyObject *s;
385+
PyObject *res;
386+
_Py_IDENTIFIER(write);
387+
388+
if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
389+
return NULL;
390+
s = PyMarshal_WriteObjectToString(x, version);
391+
if (s == NULL)
392+
return NULL;
393+
res = _PyObject_CallMethodId(f, &PyId_write, "O", s);
394+
Py_DECREF(s);
395+
return res;
396+
*/
397+
panic("dump not implemented")
398+
}
399+
400+
const load_doc = `load(file)
401+
402+
Read one value from the open file and return it. If no valid value is
403+
read (e.g. because the data has a different Python version’s
404+
incompatible marshal format), raise EOFError, ValueError or TypeError.
405+
The file must be an open file object opened in binary mode ('rb' or
406+
'r+b').
407+
408+
Note: If an object containing an unsupported type was marshalled with
409+
dump(), load() will substitute None for the unmarshallable type.`
410+
411+
func marshal_load(self, f py.Object) py.Object {
412+
/*
413+
PyObject *data, *result;
414+
_Py_IDENTIFIER(read);
415+
RFILE rf;
416+
417+
// Make a call to the read method, but read zero bytes.
418+
// This is to ensure that the object passed in at least
419+
// has a read method which returns bytes.
420+
data = _PyObject_CallMethodId(f, &PyId_read, "i", 0);
421+
if (data == NULL)
422+
return NULL;
423+
if (!PyBytes_Check(data)) {
424+
PyErr_Format(PyExc_TypeError,
425+
"f.read() returned not bytes but %.100s",
426+
data->ob_type->tp_name);
427+
result = NULL;
428+
}
429+
else {
430+
rf.depth = 0;
431+
rf.fp = NULL;
432+
rf.readable = f;
433+
rf.current_filename = NULL;
434+
result = read_object(&rf);
435+
}
436+
Py_DECREF(data);
437+
return result;
438+
*/
439+
panic("load not implemented")
440+
}
441+
442+
const dumps_doc = `dumps(value[, version])
443+
444+
Return the string that would be written to a file by dump(value, file).
445+
The value must be a supported type. Raise a ValueError exception if
446+
value has (or contains an object that has) an unsupported type.
447+
448+
The version argument indicates the data format that dumps should use.`
449+
450+
func marshal_dumps(self py.Object, args py.Tuple) py.Object {
451+
/*
452+
PyObject *x;
453+
int version = Py_MARSHAL_VERSION;
454+
if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
455+
return NULL;
456+
return PyMarshal_WriteObjectToString(x, version);
457+
*/
458+
panic("dumps not implemented")
459+
}
460+
461+
const loads_doc = `loads(bytes)
462+
463+
Convert the bytes object to a value. If no valid value is found, raise
464+
EOFError, ValueError or TypeError. Extra characters in the input are
465+
ignored.`
466+
467+
func marshal_loads(self py.Object, args py.Tuple) py.Object {
468+
/*
469+
RFILE rf;
470+
Py_buffer p;
471+
char *s;
472+
Py_ssize_t n;
473+
PyObject* result;
474+
if (!PyArg_ParseTuple(args, "y*:loads", &p))
475+
return NULL;
476+
s = p.buf;
477+
n = p.len;
478+
rf.fp = NULL;
479+
rf.readable = NULL;
480+
rf.current_filename = NULL;
481+
rf.ptr = s;
482+
rf.end = s + n;
483+
rf.depth = 0;
484+
result = read_object(&rf);
485+
PyBuffer_Release(&p);
486+
return result;
487+
*/
488+
panic("loads not implemented")
489+
}
490+
491+
const module_doc = `This module contains functions that can read and write Python values in
492+
a binary format. The format is specific to Python, but independent of
493+
machine architecture issues.
494+
495+
Not all Python object types are supported; in general, only objects
496+
whose value is independent from a particular invocation of Python can be
497+
written and read by this module. The following types are supported:
498+
None, integers, floating point numbers, strings, bytes, bytearrays,
499+
tuples, lists, sets, dictionaries, and code objects, where it
500+
should be understood that tuples, lists and dictionaries are only
501+
supported as long as the values contained therein are themselves
502+
supported; and recursive lists and dictionaries should not be written
503+
(they will cause infinite loops).
504+
505+
Variables:
506+
507+
version -- indicates the format that the module uses. Version 0 is the
508+
historical format, version 1 shares interned strings and version 2
509+
uses a binary format for floating point numbers.
510+
511+
Functions:
512+
513+
dump() -- write value to a file
514+
load() -- read value from a file
515+
dumps() -- write value to a string
516+
loads() -- read value from a string`
517+
518+
// Initialise the module
519+
func init() {
520+
methods := []*py.Method{
521+
py.NewMethod("dump", marshal_dump, 0, dump_doc),
522+
py.NewMethod("load", marshal_load, 0, load_doc),
523+
py.NewMethod("dumps", marshal_dumps, 0, dumps_doc),
524+
py.NewMethod("loads", marshal_loads, 0, loads_doc),
525+
}
526+
globals := py.StringDict{
527+
"version": py.Int(MARSHAL_VERSION),
528+
}
529+
py.NewModule("marshal", module_doc, methods, globals)
530+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy