1# 2# Copyright (c) 2014 Gilles Chehade <gilles@poolp.org> 3# 4# Permission to use, copy, modify, and distribute this software for any 5# purpose with or without fee is hereby granted, provided that the above 6# copyright notice and this permission notice appear in all copies. 7# 8# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15# 16 17import random 18import tempfile 19# import time 20import os 21 22queue = {} 23 24 25def generate_msgid(): 26 while True: 27 msgid = random.randint(1, 0xffffffff) 28 if msgid not in queue: 29 return msgid 30 31 32def generate_evpid(msgid): 33 if msgid not in queue: 34 return 0 35 while True: 36 evpid = random.randint(1, 0xffffffff) 37 if evpid not in queue[msgid]: 38 return (msgid << 32) | evpid 39 40 41# message_create must allocate a message entry and return a stricly positive 42# 32-bit unique message identifier. 43# 44def message_create(): 45 msgid = generate_msgid() 46 queue[msgid] = {'envelopes': {}, 'message': None} 47 return msgid 48 49 50# message_commit must write content of "path" into message and return 51# either 0 for failure, or 1 for success. 52# 53def message_commit(msgid, path): 54 queue[msgid]['message'] = open(path, 'rb').read() 55 os.unlink(path) 56 return 1 57 58 59# message_delete must remove a message and all associate envelopes, 60# returns either 0 for failure, or 1 for success 61# 62def message_delete(msgid): 63 del queue[msgid] 64 return 1 65 66 67# message_fd_r must return a readable file descriptor pointing to the 68# content of the message, or -1 in case of failure 69# 70def message_fd_r(msgid): 71 tmp = tempfile.TemporaryFile(mode="w+") 72 tmp.write(queue[msgid]['message']) 73 tmp.flush() 74 tmp.seek(0, os.SEEK_SET) 75 return os.dup(tmp.fileno()) 76 77 78def message_corrupt(): 79 return 1 80 81 82# envelope_create must create an envelope within a message and return a 83# 64-bit unique envelope identifier where upper 32-bit == msgid 84# 85def envelope_create(msgid, envelope): 86 evpid = generate_evpid(msgid) 87 if evpid == 0: 88 return 0 89 queue[msgid]['envelopes'][evpid] = envelope 90 return evpid 91 92 93def envelope_delete(evpid): 94 msgid = (evpid >> 32) & 0xffffffff 95 del queue[msgid]['envelopes'][evpid] 96 if len(queue[msgid]['envelopes']) == 0: 97 del queue[msgid] 98 return 1 99 100 101# envelope_update must create an envelope within a message and return a 102# 64-bit unique envelope identifier where upper 32-bit == msgid 103# 104def envelope_update(evpid, envelope): 105 queue[(evpid >> 32) & 0xffffffff]['envelopes'][evpid] = envelope 106 return 1 107 108 109def envelope_load(evpid): 110 msgid = (evpid >> 32) & 0xffffffff 111 if msgid not in queue: 112 return 0 113 if evpid not in queue[msgid]['envelopes']: 114 return 0 115 return queue[msgid]['envelopes'][evpid] 116 117 118def envelope_walk(): 119 return -1 120