tbx  0.7.5
resbase.h
1 /*
2  * tbx RISC OS toolbox library
3  *
4  * Copyright (C) 2010 Alan Buckley All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 #ifndef TBX_RES_RESBASE_H_
26 #define TBX_RES_RESBASE_H_
27 
28 #include <string>
29 #include <iostream>
30 
31 #include "resstruct.h"
32 
33 namespace tbx {
34 
35 namespace res {
36 
38 
42 struct ResRelocationTable
43 {
44  int _size;
45  ResRelocation *_relocs;
46 
47  ResRelocationTable() : _size(0), _relocs(0) {};
48  ResRelocationTable(const ResRelocationTable &other);
49  ~ResRelocationTable() {delete [] _relocs;}
50 
51  ResRelocationTable &operator=(const ResRelocationTable &other);
52 
53  void add(int offset, ResRelocation::Type type);
54  void erase(int offset);
55  void clear();
56 
57  void offsets_to_pointers(char *body, char *strings, char *msgs) const;
58  void pointers_to_offsets(char *body, char *strings, char *msgs) const;
59  void fix_text_pointers(bool string_table, char *body, const char *new_strings, const char *old_strings, const char *from, int by);
60  void fix_all_pointers(char *new_body, const char *old_body, const char *new_strings, const char *old_strings, const char *new_messages, const char *old_messages);
61  void fix_after_insert(char *new_body, const char *old_body, int offset, int count);
62 };
63 
64 //Notes:
65 // Null string or message ref = -1
66 
67 class ResImpl;
68 
74 class ResData
75 {
76  char *_strings;
77  int _strings_size;
78  char *_messages;
79  int _messages_size;
80  ResRelocationTable _reloc_table;
81 
82  friend class ResImpl;
83 
84 public:
85  ResData(ResDataHeader header, char *strings, int num_reloc, ResRelocation *relocs);
86  ResData(const ResData &other);
87  ResData();
88  ~ResData();
89 
90  int reloc_size() const {return _reloc_table._size;}
91  int strings_size() const {return _strings_size;}
92  const char *strings() const {return _strings;}
93  int messages_size() const {return _messages_size;}
94  const char *messages() const {return _messages;}
95 
96  void calculate_string_sizes(const char *body);
97 
98  const char *text(const char *body, int offset) const {return (char *)(*(int *)(body + offset));}
99  int text_len(const char *body, int offset) const;
100  void text(char *body, int offset, const char *new_text, int len, bool is_string);
101  void text(char *body, int offset, std::string msg, bool is_string)
102  {
103  text(body, offset, msg.c_str(), msg.size(), is_string);
104  }
105 
106  int number(const char *body, int offset) const
107  {
108  return *((int *)(body + offset));
109  }
110  void number(char *body, int offset, int value)
111  {
112  *((int *)(body+offset)) = value;
113  }
114 
115  void init_text(char *body, int offset, const char *value, bool is_string);
116  void init_sprite_area_ref(char *body, int offset);
117  void init_object_ref(char *body, int offset);
118 
119  void copy_used(char *body, const char *old_body, const ResRelocationTable &copy_table);
120 
121  //TODO: void object_offset(char *body, int offset);
122  //TODO: void sprite_area(char *body, int offset);
123 
124  void pointers_to_offsets(char *body) const
125  {
126  _reloc_table.pointers_to_offsets(body, _strings, _messages);
127  }
128 
129  void offsets_to_pointers(char *body) const
130  {
131  _reloc_table.offsets_to_pointers(body, _strings, _messages);
132  }
133 
134  ResData *component_data(char *new_body, char *copy_body, int offset, int size) const;
135  void add_data_from(char *body, int offset, const char *from_body, const ResData *from_data);
136  void remove_data(char *body, int offset, int size);
137  void fix_offsets(char *new_body, const char *old_body, int offset, int diff);
138 
139  static ResData *copy_from_read_only(char *new_header, char *readonly_header);
140  static ResData *copy_component_from_read_only(char *new_body, char *readonly_header, int offset, int size);
141 
142  void write(std::ostream &file) const;
143 
144 private:
145  char *remove_chars(char *body, bool string_table, const char *where, int num);
146  char *insert_chars(char *body, bool string_table, const char *where, int num);
147  void copy_strings_and_messages(char *new_body, const char *copy_body);
148 
149 };
150 
151 
152 
160 class ResImpl
161 {
162  int _ref_count; // Reference count or -1 if read only object
163  char *_header;
164  char *_body;
165  int _size;
166  ResData *_data;
167  ResRelocationTable *_type_reloc_table;
168 
169 private:
170  ~ResImpl();
171 
172 public:
173  ResImpl(void *object_header, int body_offset, int size);
174  ResImpl(void *object_header, int body_offset, int size, ResData *data);
175  ResImpl(const ResImpl &other);
176  ResImpl(const ResImpl &other, bool copy_read_only);
177 
178  void add_ref();
179  void release();
180 
181  char *header() {return _header;}
182  const char *header() const {return _header;}
183  char *body() {return _body;}
184  const char *body() const {return _body;}
185  const ResData *data() const {return _data;}
186  int size() const {return _size;}
187 
188  const char *text(int offset) const {return (char *)(*(int *)(_body + offset));}
189  int text_len(int offset) const;
190  void text(int offset, const char *new_text, int len, bool is_string)
191  {
192  if (_data == 0) _data = new ResData();
193  _data->text(_body, offset, new_text, ((new_text == 0) ? 0 : len), is_string);
194  }
195 
196  void text(int offset, std::string msg, bool is_string)
197  {
198  text(offset, msg.c_str(), msg.size(), is_string);
199  }
200 
201  void text_with_length(int offset, const char *new_text, int max_length, bool is_string);
202  void text_with_length(int offset, const std::string &new_text, int max_length, bool is_string)
203  {
204  if (max_length <= (int)new_text.size()) max_length = (int)new_text.size()+1;
205  text_with_length(offset, new_text.c_str(), max_length, is_string);
206  }
207 
208  int int_value(int offset) const;
209  void int_value(int offset, int value);
210  unsigned int uint_value(int offset) const;
211  void uint_value(int offset, unsigned int value);
212 
213  unsigned short ushort_value(int offset) const;
214  void ushort_value(int offset, unsigned short value);
215 
216  unsigned char byte_value(int offset) const;
217  void byte_value(int offset, unsigned char value);
218 
219  bool flag(int offset, int mask) const;
220  void flag(int offset, int mask, bool on);
221 
222  int flag_value(int offset, int mask) const;
223  void flag_value(int offset, int mask, int value);
224 
225  void init_text(int offset, const char *value, bool is_string);
226  void init_sprite_area_ref(int offset);
227  void init_object_ref(int offset);
228 
229  ResData *component_data(char *new_body, int offset, int size) const;
230 
234  bool read_only() const {return (_ref_count == -1);}
235 
239  bool unique() const {return (_ref_count == 1);}
240 
241  void insert(int offset, const ResImpl *insert_impl);
242  void replace(int offset, int old_size, const ResImpl *rep_impl);
243  void erase(int offset, int size);
244 };
245 
247 
248 
252 class ResBase
253 {
254 protected:
255  ResImpl *_impl;
256 
262  ResBase(ResImpl *impl) { _impl = impl ;}
263 
264 public:
265  ResBase(const ResBase &other);
266  virtual ~ResBase();
267 
268  ResBase &operator=(const ResBase &other);
269 
270 protected:
274  virtual void make_writeable() = 0;
275 
276  // Helpers to get and set data in record
277  const char *string(int offset) const;
278  void string(int offset, const char *value);
279  void string(int offset, std::string value);
280  void string_with_length(int offset, const char *value, int length = -1);
281 
290  void string_with_length(int offset, const std::string &value, int length = -1)
291  {
292  string_with_length(offset, value.c_str(), length);
293  }
294  const char *message(int offset) const;
295  void message(int offset, const char *value);
296  void message(int offset, std::string value);
297  void message_with_length(int offset, const char *value, int length = -1);
306  void message_with_length(int offset, const std::string &value, int length = -1)
307  {
308  message_with_length(offset, value.c_str(), length);
309  }
316  int int_value(int offset) const {return _impl->int_value(offset);}
317  void int_value(int offset, int value);
324  unsigned int uint_value(int offset) const {return _impl->uint_value(offset);}
325  void uint_value(int offset, unsigned int value);
326 
333  unsigned char byte_value(int offset) const {return _impl->byte_value(offset);}
334  void byte_value(int offset, unsigned char value);
335 
342  unsigned short ushort_value(int offset) const {return _impl->ushort_value(offset);}
343  void ushort_value(int offset, unsigned short value);
344 
352  bool flag(int offset, int mask) const {return _impl->flag(offset, mask);}
353  void flag(int offset, int mask, bool on);
354 
362  int flag_value(int offset, int mask) const {return _impl->flag_value(offset, mask);}
363  void flag_value(int offset, int mask, int value);
364 
365  void init_string(int offset, const char *value);
366  void init_message(int offset, const char *value);
367  void init_sprite_area_ref(int offset);
368  void init_object_ref(int offset);
369 };
370 
371 
372 }
373 
374 }
375 
376 #endif /* TBX_RES_RESBASE_H_ */
A library for creating RISC OS toolbox applications.
Definition: abouttobeshownlistener.cc:34
Type
Relocation type enumeration.
Definition: resstruct.h:68
std::string message(const std::string &token)
Shortcut to the tbx::app()->messages().message(...)
Definition: message.cc:41
Base class for objects, gadgets and menu items from ressources.
Definition: resbase.h:252
bool flag(int offset, int mask) const
Check if any of the bits in a mask are set.
Definition: resbase.h:352
int flag_value(int offset, int mask) const
Get the bits for the given mask.
Definition: resbase.h:362
unsigned int uint_value(int offset) const
Get an unsigned integer value.
Definition: resbase.h:324
Classes to use/edit toolbox resources in memory.
ResBase(ResImpl *impl)
Create from internal resource implementation.
Definition: resbase.h:262
int int_value(int offset) const
Get an integer value.
Definition: resbase.h:316
void message_with_length(int offset, const std::string &value, int length=-1)
Assign a message where the length is at offset+4.
Definition: resbase.h:306
unsigned short ushort_value(int offset) const
Get a unsigned short value.
Definition: resbase.h:342
void string_with_length(int offset, const std::string &value, int length=-1)
Assign a string where the length is at offset+4.
Definition: resbase.h:290
unsigned char byte_value(int offset) const
Get a byte value.
Definition: resbase.h:333
ResImpl * _impl
Internal Resource implementation.
Definition: resbase.h:255