root/trunk/lua/buffer.d

Revision 314, 5.7 kB (checked in by xammy, 3 weeks ago)

Bugfixes for LuaLib (package library, thread destruction)

Line 
1 /*******************************************************************************
2
3     copyright:      Copyright (c) 2008 Matthias Walter. All rights reserved
4
5     authors:        Matthias Walter, Andreas Hollandt
6
7 *******************************************************************************/
8
9 module lua.buffer;
10
11 private import lua.state;
12 private import lua.lauxlib;
13
14 /*******************************************************************************
15
16     LuaBuffer wraps a Lua string buffer which allows building strings
17     piecemeal, as in the following example:
18     
19     ---
20     // create a lua state
21     auto L = new LuaState ();
22
23     // create a buffer for this state
24     auto buffer = L.createBuffer ();
25
26     // Add char by char
27     buffer.addChar ('C').addChar ('h').addChar ('a').addChar ('r');
28
29     // Add a complete string
30     buffer.addString ("String");
31
32     // Push a number onto the stack and add its string representation
33     L.pushNumber (2.1);
34     buffer.addValue ();
35
36     // Get the char-pointer of the current buffer position and manually
37     // modify it. When finished, you correct the size accordingly.
38     auto buf = buffer.prepare ();
39     buf[0] = 'B';
40     buf[1] = 'u';
41     buf[2] = 'f';
42     buf[3] = 'f';
43     buf[4] = 'e';
44     buf[5] = 'r';
45     buffer.addSize (6);
46
47     // When finished, push the result "CharString2.1Buffer" onto the stack.
48     buffer.pushResult ();
49     ---
50
51     During its normal operation, a string buffer uses a variable number of
52     stack slots. So, while using a buffer, you cannot assume that you know
53     where the top of the stack is. You can use the stack between successive
54     calls to buffer operations as long as that use is balanced; that is,
55     when you call a buffer operation, the stack is at the same level it was
56     immediately after the previous buffer operation. (The only exception to
57     this rule is the addValue method) After calling pushResult the stack is
58     back to its level when the buffer was initialized, plus the final string
59     on its top.
60
61 *******************************************************************************/
62
63 class LuaBuffer
64 {
65     /// Associated state
66     private LuaState state_;
67
68     /// Wrapped lua buffer
69     private luaL_Buffer buffer_;
70
71     /*******************************************************************************
72
73         Constructs a buffer, attaching it to a state.
74         
75         Params:
76         state = Lua state to attach the buffer to.
77         
78         Remarks:
79         Replaces luaL_buffinit.
80     
81     *******************************************************************************/
82
83     public this (LuaState state)
84     {
85         this.state_ = state;
86         luaL_buffinit (this.state_.state, &this.buffer_);
87     }
88
89     /*******************************************************************************
90
91         Appends a character to the buffer.
92     
93         Params:
94         c = Character to append.
95         
96         Remarks:
97         Replaces luaL_addchar.
98
99     *******************************************************************************/
100
101     public LuaBuffer addChar (char c)
102     {
103         luaL_addchar (&this.buffer_, c);
104
105         return this;
106     }
107
108     /*******************************************************************************
109
110         Appends a string to the buffer.
111
112         Params:
113         string = String to append.
114     
115         Remarks:
116         Replaces luaL_addstring and luaL_addlstring.
117
118     *******************************************************************************/
119
120     public LuaBuffer addString (char[] string)
121     {
122         luaL_addlstring (&this.buffer_, string.ptr, string.length);
123
124         return this;
125     }
126
127     /*******************************************************************************
128
129         Appends a value on top of stack to the buffer and pops it.
130
131         Remarks:
132         Replaces luaL_addvalue.
133
134     *******************************************************************************/
135
136     public LuaBuffer addValue ()
137     {
138         luaL_addvalue (&this.buffer_);
139
140         return this;
141     }
142
143     /*******************************************************************************
144         
145         Returns an address to a space of size LUAL_BUFFERSIZE where you can copy
146         a string to be added to the buffer B. After copying the string into this
147         space you must call addSize with the size of the string to actually add
148         it to the buffer.
149
150         Remarks:
151         Replaces luaL_prepbuffer
152
153     *******************************************************************************/
154
155     public char* prepare ()
156     {
157         return luaL_prepbuffer (&this.buffer_);
158     }
159
160     /*******************************************************************************
161
162         Adds to the buffer a string of length size previously copied to the
163         buffer area returned by prepare.
164
165         Remarks:
166         Replaces luaL_addsize
167
168     *******************************************************************************/
169
170     public LuaBuffer addSize (uint size)
171     {
172         luaL_addsize (&this.buffer_, size);
173
174         return this;
175     }
176
177     /*******************************************************************************
178
179         Finishes the use of the buffer leaving the final string on the top of
180         the stack.
181
182         Remarks:
183         Replaces luaL_pushresult
184
185     *******************************************************************************/
186
187     public LuaState pushResult ()
188     {
189         luaL_pushresult (&this.buffer_);
190
191         return state_;
192     }
193 }
194
195 unittest
196 {
197
198     char[] output = "";
199
200     void write (char[] data)
201     {
202         output ~= data;
203     }
204
205     LuaState L = new LuaState (&write);
206
207     auto buffer = L.createBuffer ();
208     buffer.addChar ('C').addChar ('h').addChar ('a').addChar ('r');
209     buffer.addString ("String");
210     L.pushNumber (2.1);
211     buffer.addValue ();
212
213     auto buf = buffer.prepare ();
214     buf[0] = 'B';
215     buf[1] = 'u';
216     buf[2] = 'f';
217     buf[3] = 'f';
218     buf[4] = 'e';
219     buf[5] = 'r';
220     buffer.addSize (6);
221
222     buffer.pushResult ();
223    
224     assert (L.popString () == "CharString2.1Buffer");
225 }
Note: See TracBrowser for help on using the browser.