xref: /aosp_15_r20/external/mtools/swap.c (revision d5c9a868b113e0ec0db2f27bc2ce8a253e77c4b0)
1 /*  Copyright 2021 Alain Knaff.
2  *  This file is part of mtools.
3  *
4  *  Mtools is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Mtools is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  * filter to support byte-swapped filesystems
18  */
19 
20 #include "sysincludes.h"
21 #include "msdos.h"
22 #include "mtools.h"
23 #include "swap.h"
24 
25 typedef struct Swap_t {
26 	struct Stream_t head;
27 } Swap_t;
28 
swap_buffer(char * buf,size_t len)29 static void swap_buffer(char *buf, size_t len)
30 {
31 	unsigned int i;
32 	for (i=0; i<len; i+=2) {
33 		char temp = buf[i];
34 		buf[i] = buf[i+1];
35 		buf[i+1] = temp;
36 	}
37 }
38 
39 
swap_pread(Stream_t * Stream,char * buf,mt_off_t where,size_t len)40 static ssize_t swap_pread(Stream_t *Stream, char *buf,
41 			  mt_off_t where, size_t len)
42 {
43 	DeclareThis(Swap_t);
44 
45 	ssize_t result = PREADS(This->head.Next, buf, where, len);
46 	if(result < 0)
47 		return result;
48 	swap_buffer( buf, (size_t) result);
49 	return result;
50 }
51 
swap_pwrite(Stream_t * Stream,char * buf,mt_off_t where,size_t len)52 static ssize_t swap_pwrite(Stream_t *Stream, char *buf,
53 			  mt_off_t where, size_t len)
54 {
55 	DeclareThis(Swap_t);
56 
57 	ssize_t result;
58 	char *swapping = malloc( len );
59 	memcpy( swapping, buf, len );
60 	swap_buffer( swapping, len );
61 
62 	result = PWRITES(This->head.Next, swapping, where, len);
63 
64 	free(swapping);
65 	return result;
66 }
67 
68 
69 static Class_t SwapClass = {
70 	0,
71 	0,
72 	swap_pread,
73 	swap_pwrite,
74 	0, /* flush */
75 	0, /* free */
76 	set_geom_pass_through, /* set_geom */
77 	0, /* get_data */
78 	0, /* pre-allocate */
79 	get_dosConvert_pass_through, /* dos convert */
80 	0, /* discard */
81 };
82 
OpenSwap(Stream_t * Next)83 Stream_t *OpenSwap(Stream_t *Next) {
84 	Swap_t *This;
85 
86 	This = New(Swap_t);
87 	if (!This){
88 		printOom();
89 		return 0;
90 	}
91 	memset((void*)This, 0, sizeof(Swap_t));
92 	init_head(&This->head, &SwapClass, Next);
93 
94 	return &This->head;
95 }
96